<commit_before>goog.provide('annotorious.plugin');

goog.require('goog.array');
goog.require('goog.net.XhrIo');

/**
 * A simple storage connector to the ElasticSearch REST interface.
 * Note: work in progress!
 * 
 * @param {yuma.modules.Module} module the module
 * @constructor
 */
annotorious.plugin['ElasticSearchStorage'] = function(opt_config_options) {
  /** @private **/
  this._STORE_URI = opt_config_options['base_url'];
}

annotorious.plugin['ElasticSearchStorage'].prototype.initPlugin = function(anno) {
  var self = this;
  anno.addHandler(annotorious.events.EventType.ANNOTATION_EDIT_SAVE, function(event) {
    self._create(event.annotation);
  });

  anno.addHandler(annotorious.events.EventType.POPUP_BTN_DELETE, function(event) {
    self._delete(event.annotation);
  });
  
  this._loadAnnotations(anno);  
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._showError = function(error) {
  // TODO proper error handling
  window.alert('ERROR');
  console.log(error);
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._loadAnnotations = function(anno) {
  // TODO need to restrict search to the URL of the annotated
  
  var self = this;
  goog.net.XhrIo.send(this._STORE_URI + '_search?query=*:*', function(data) {
    try {
      var hits = data.target.getResponseJson()['hits']['hits'];
      goog.array.forEach(hits, function(hit, idx, array) {
        var annotation = hit['_source'];
        annotation.id = hit['_id'];
        anno.addAnnotation(annotation);
      });
    } catch (e) {
      self._showError(e);
    }
  });
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._create = function(annotation) {
  var self = this;
  goog.net.XhrIo.send(this._STORE_URI + 'annotation/', function(response) {
    // TODO error handling if response status != 201 (CREATED)

    var id = response.target.getResponseJson()['_id'];
    annotation.id = id;
  }, 'POST', goog.json.serialize(annotation));
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._delete = function(annotation) {
  goog.net.XhrIo.send(this._STORE_URI + 'annotation/' + annotation.id, function(response) {
    // TODO error handling
  }, 'DELETE');  
}
<commit_msg>Experiment: 'realtime' updates for ElasticSearch plugin<commit_after>goog.provide('annotorious.plugin');

goog.require('goog.array');
goog.require('goog.net.XhrIo');

/**
 * A simple storage connector to the ElasticSearch REST interface.
 * Note: work in progress!
 * 
 * @param {yuma.modules.Module} module the module
 * @constructor
 */
annotorious.plugin['ElasticSearchStorage'] = function(opt_config_options) {
  /** @private **/
  this._STORE_URI = opt_config_options['base_url'];

  /** @private **/
  this._annotations = [];
}

annotorious.plugin['ElasticSearchStorage'].prototype.initPlugin = function(anno) {
  var self = this;
  anno.addHandler(annotorious.events.EventType.ANNOTATION_EDIT_SAVE, function(event) {
    self._create(event.annotation);
  });

  anno.addHandler(annotorious.events.EventType.POPUP_BTN_DELETE, function(event) {
    self._delete(event.annotation);
  });
  
  // this._loadAnnotations(anno);  
  self._loadAnnotations(anno);
  window.setInterval(function() { self._loadAnnotations(anno); }, 2000);
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._showError = function(error) {
  // TODO proper error handling
  window.alert('ERROR');
  console.log(error);
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._loadAnnotations = function(anno) {
  // TODO need to restrict search to the URL of the annotated
  var self = this;
  goog.net.XhrIo.send(this._STORE_URI + '_search?query=*:*', function(data) {
    try {
      var hits = data.target.getResponseJson()['hits']['hits'];
      goog.array.forEach(hits, function(hit, idx, array) {
        var annotation = hit['_source'];
        annotation.id = hit['_id'];
        if (!goog.array.contains(self._annotations, annotation.id)) {
          self._annotations.push(annotation.id);
          anno.addAnnotation(annotation);
        }
      });
    } catch (e) {
      self._showError(e);
    }
  });
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._create = function(annotation) {
  var self = this;
  goog.net.XhrIo.send(this._STORE_URI + 'annotation/', function(response) {
    // TODO error handling if response status != 201 (CREATED)

    var id = response.target.getResponseJson()['_id'];
    annotation.id = id;
  }, 'POST', goog.json.serialize(annotation));
}

/**
 * @private
 */
annotorious.plugin['ElasticSearchStorage'].prototype._delete = function(annotation) {
  goog.net.XhrIo.send(this._STORE_URI + 'annotation/' + annotation.id, function(response) {
    // TODO error handling
  }, 'DELETE');  
}

{'fraction_non_alphanumeric': 0.1566439346972515, 'fraction_numerical': 0.0020665426741062203, 'mean_word_length': 4.073375262054507, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1854002', 'n_tokens_mistral': 1554, 'n_tokens_neox': 1500, 'n_words': 255}