ajax-cat 1.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,3 +44,19 @@ class Utils
44
44
 
45
45
  @trim: (text) =>
46
46
  return text.replace(/^\s+|\s+$/g, "")
47
+
48
+ @edit_distance: (source, target) ->
49
+ a = []
50
+ for i in [0..source.length]
51
+ a[i] = new Array(target.length + 1)
52
+ a[i][0] = i
53
+ a[0] = [0..target.length]
54
+
55
+ for i in [1..source.length]
56
+ for j in [1..target.length]
57
+ substitute_cost = a[i - 1][j - 1]
58
+ substitute_cost += 1 if (source.charAt(i - 1) != target.charAt(j - 1))
59
+ a[i][j] = Math.min(substitute_cost, a[i-1][j] + 1, a[i][j-1] + 1)
60
+ return a[source.length][target.length]
61
+
62
+
@@ -40,6 +40,7 @@ AjaxCatList = (function() {
40
40
  alert("Write your email, please.");
41
41
  return;
42
42
  }
43
+ $.cookie("email", email);
43
44
  return $.ajax("/admin/get_experiment", {
44
45
  data: {
45
46
  email: email,
@@ -48,7 +49,7 @@ AjaxCatList = (function() {
48
49
  success: function(data) {
49
50
  var id;
50
51
  data = JSON.parse(data);
51
- id = _this.add_translation(data.sentence, "EXPERIMENT #" + data.task_id + ", " + data.email, data.pair, data.task_id, data.email);
52
+ id = _this.add_translation(JSON.parse(data.sentences), "EXPERIMENT #" + data.task_id + ", " + data.email, data.pair, data.task_id, data.email, data);
52
53
  return window.location = "/translation.html#" + id;
53
54
  },
54
55
  error: function() {
@@ -60,6 +61,7 @@ AjaxCatList = (function() {
60
61
  AjaxCatList.prototype.new_experiment_translation = function() {
61
62
  var _this = this;
62
63
  $("#new-experiment-pair").html("");
64
+ $("#new-experiment-email").val($.cookie("email"));
63
65
  return $.ajax("/api/info", {
64
66
  success: function(data) {
65
67
  var p, _i, _len, _ref;
@@ -138,7 +140,7 @@ AjaxCatList = (function() {
138
140
  return this.show_translations();
139
141
  };
140
142
 
141
- AjaxCatList.prototype.add_translation = function(text, name, pair, task_id, email) {
143
+ AjaxCatList.prototype.add_translation = function(text, name, pair, task_id, email, experiment_data) {
142
144
  var doc, docs;
143
145
  if (task_id == null) task_id = false;
144
146
  if (email == null) email = false;
@@ -153,7 +155,12 @@ AjaxCatList = (function() {
153
155
  doc.pair = pair;
154
156
  doc.email = email;
155
157
  doc.task_id = task_id;
156
- doc.source = Utils.split_source(text);
158
+ if (jQuery.isArray(text)) {
159
+ doc.source = text;
160
+ doc.options = JSON.parse(experiment_data.options);
161
+ } else {
162
+ doc.source = Utils.split_source(text);
163
+ }
157
164
  doc.target = new Array(doc.source.length);
158
165
  docs.push(doc.id);
159
166
  localStorage.setItem('ac-data', JSON.stringify(docs));
@@ -169,6 +176,10 @@ AjaxCatTranslation = (function() {
169
176
 
170
177
  AjaxCatTranslation.prototype.cur_position = false;
171
178
 
179
+ AjaxCatTranslation.prototype.experiment = false;
180
+
181
+ AjaxCatTranslation.prototype.param_suggestion = true;
182
+
172
183
  function AjaxCatTranslation() {
173
184
  this.add_words = __bind(this.add_words, this);
174
185
  this.change_position = __bind(this.change_position, this);
@@ -179,6 +190,7 @@ AjaxCatTranslation = (function() {
179
190
  this.resize = __bind(this.resize, this);
180
191
  this.log = __bind(this.log, this);
181
192
  this.prepare_test = __bind(this.prepare_test, this);
193
+ this.change_experiment_sentence = __bind(this.change_experiment_sentence, this);
182
194
  this.time = __bind(this.time, this);
183
195
  var data, i, s, t, _i, _j, _len, _len2, _ref, _ref2,
184
196
  _this = this;
@@ -235,16 +247,16 @@ AjaxCatTranslation = (function() {
235
247
  return setTimeout(this.time, 10);
236
248
  };
237
249
 
238
- AjaxCatTranslation.prototype.prepare_test = function() {
250
+ AjaxCatTranslation.prototype.change_experiment_sentence = function() {
239
251
  var _this = this;
240
- AjaxCatList.delete_document(this.hash);
241
- $("#save").hide();
242
- $("#send-experiment").show();
243
- $("#send-experiment").click(function() {
252
+ if (this.cur_position + 1 < this.doc.source.length) {
253
+ return this.change_position(this.cur_position + 1);
254
+ } else {
244
255
  $("#send-experiment").hide();
245
256
  return $.ajax("/admin/save_experiment", {
246
257
  data: {
247
- log: JSON.stringify(_this.doc)
258
+ "log_id": this.doc.task_id,
259
+ log: JSON.stringify(this.doc)
248
260
  },
249
261
  type: "post",
250
262
  success: function() {
@@ -255,6 +267,20 @@ AjaxCatTranslation = (function() {
255
267
  return alert("Could not save experiment.");
256
268
  }
257
269
  });
270
+ }
271
+ };
272
+
273
+ AjaxCatTranslation.prototype.prepare_test = function() {
274
+ var _this = this;
275
+ AjaxCatList.delete_document(this.hash);
276
+ this.experiment = true;
277
+ $("#save").hide();
278
+ $("#experiment-settings").show();
279
+ $("#top-translations").hide();
280
+ $("#bottom-translations").hide();
281
+ $("#send-experiment").show();
282
+ $("#send-experiment").click(function() {
283
+ return _this.change_experiment_sentence();
258
284
  });
259
285
  this.doc.log = [];
260
286
  this.time();
@@ -273,7 +299,10 @@ AjaxCatTranslation = (function() {
273
299
  };
274
300
  if (type) new_log.type = type;
275
301
  if (param) new_log.param = param;
276
- this.doc.log.push(new_log);
302
+ if (this.doc.log[this.cur_position] === void 0) {
303
+ this.doc.log[this.cur_position] = [];
304
+ }
305
+ this.doc.log[this.cur_position].push(new_log);
277
306
  return $("#log").append(JSON.stringify(new_log) + "<br>");
278
307
  };
279
308
 
@@ -357,6 +386,7 @@ AjaxCatTranslation = (function() {
357
386
 
358
387
  AjaxCatTranslation.prototype.load_translation_table = function(sentence) {
359
388
  var _this = this;
389
+ if (this.table_request) this.table_request.abort();
360
390
  sentence = Utils.tokenize(sentence);
361
391
  if (sentence.match(/^[\ \t]*$/)) {
362
392
  $("#translation-table-container").html("");
@@ -364,7 +394,7 @@ AjaxCatTranslation = (function() {
364
394
  return;
365
395
  }
366
396
  $("#translation-table-container").text("");
367
- return $.ajax("/api/table", {
397
+ return this.table_request = $.ajax("/api/table", {
368
398
  data: {
369
399
  pair: this.pair,
370
400
  q: sentence
@@ -379,6 +409,18 @@ AjaxCatTranslation = (function() {
379
409
  };
380
410
 
381
411
  AjaxCatTranslation.prototype.change_position = function(position) {
412
+ if (this.experiment) {
413
+ if (!((position === 0 && this.cur_position === false) || (this.cur_position + 1 === position))) {
414
+ return;
415
+ }
416
+ this.param_suggestion = this.doc.options[position].suggestion;
417
+ $("#suggestion-panel-is-on").text(this.param_suggestion);
418
+ $("#translated-status").text("translating sentence " + (position + 1) + " out of " + this.doc.source.length);
419
+ if ((position + 1) === this.doc.source.length) {
420
+ $("#send-experiment").text("Finish experiment");
421
+ }
422
+ }
423
+ this.suggestions.clear();
382
424
  if (this.cur_position !== false) this.save_target();
383
425
  $("#source-top").children().slice(0, position).show();
384
426
  $("#source-top").children().slice(position, this.length).hide();
@@ -453,6 +495,7 @@ Suggestions = (function() {
453
495
  }
454
496
 
455
497
  Suggestions.prototype.clear = function() {
498
+ if (this.suggestion_request) this.suggestion_request.abort();
456
499
  $(".ac-suggestion").text("");
457
500
  $(".ac-suggestion").removeClass('suggestion-enabled');
458
501
  return $(".ac-suggestion").removeClass('suggestion-active');
@@ -462,11 +505,12 @@ Suggestions = (function() {
462
505
  var covered, sentence, translated,
463
506
  _this = this;
464
507
  this.clear();
508
+ if (!this.translation.param_suggestion) return;
465
509
  sentence = $("#source-sentence").text();
466
510
  sentence = Utils.tokenize(sentence);
467
511
  translated = Utils.tokenize($("#source-target").text());
468
512
  covered = this.translation.table.covered_vector();
469
- return $.ajax("/api/suggestion", {
513
+ return this.suggestion_request = $.ajax("/api/suggestion", {
470
514
  data: {
471
515
  pair: this.translation.pair,
472
516
  q: Utils.tokenize(sentence),
@@ -482,11 +526,13 @@ Suggestions = (function() {
482
526
  };
483
527
 
484
528
  Suggestions.prototype.take_suggestion = function() {
485
- var text;
529
+ var from, text, to;
486
530
  if (this.get_position() === false) return;
487
531
  text = $(".suggestion-active span").text();
532
+ from = $(".suggestion-active").data('from');
533
+ to = $(".suggestion-active").data('to');
488
534
  this.translation.add_words(text);
489
- return this.translation.table.mark_words(text);
535
+ return this.translation.table.mark_interval(from, to);
490
536
  };
491
537
 
492
538
  Suggestions.prototype.process_suggestions = function(data) {
@@ -498,7 +544,9 @@ Suggestions = (function() {
498
544
  suggestion = _ref[_i];
499
545
  translation = $("#target-sentence").val();
500
546
  el = $(".ac-suggestion").slice(i, i + 1);
501
- el.html("" + translation + " <span>" + suggestion + "</span>");
547
+ el.html("" + translation + " <span>" + suggestion.text + "</span>");
548
+ el.data('from', suggestion.from);
549
+ el.data('to', suggestion.to);
502
550
  el.addClass('suggestion-enabled');
503
551
  _results.push(i += 1);
504
552
  }
@@ -550,6 +598,7 @@ TranslationTable = (function() {
550
598
  this.unmark_position = __bind(this.unmark_position, this);
551
599
  this.mark_position = __bind(this.mark_position, this);
552
600
  this.mark_interval = __bind(this.mark_interval, this);
601
+ this.mark_words_OLD = __bind(this.mark_words_OLD, this);
553
602
  this.mark_words = __bind(this.mark_words, this);
554
603
  this.position_marked = __bind(this.position_marked, this);
555
604
  this.get_row = __bind(this.get_row, this);
@@ -643,8 +692,32 @@ TranslationTable = (function() {
643
692
  return false;
644
693
  };
645
694
 
646
- TranslationTable.prototype.mark_words = function(words) {
695
+ TranslationTable.prototype.mark_words = function(word) {
696
+ var best_element, best_result, el, element_text, maximal_acceptable_distance, result, _i, _len, _ref;
697
+ word = Utils.trim(word);
698
+ best_result = 10000;
699
+ best_element = null;
700
+ maximal_acceptable_distance = 1;
701
+ if (word.length < 5) maximal_acceptable_distance = 0;
702
+ if (word.length > 10) maximal_acceptable_distance = 2;
703
+ _ref = $(".ac-word div");
704
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
705
+ el = _ref[_i];
706
+ element_text = Utils.trim($(el).text());
707
+ result = Utils.edit_distance(word, element_text);
708
+ if (result < best_result) {
709
+ best_result = result;
710
+ best_element = $(el);
711
+ }
712
+ }
713
+ if (best_element !== null && best_result <= maximal_acceptable_distance) {
714
+ return this.mark_interval(best_element.data('position-from'), best_element.data('position-to'));
715
+ }
716
+ };
717
+
718
+ TranslationTable.prototype.mark_words_OLD = function(words) {
647
719
  var el, el_text, _i, _len, _ref;
720
+ console.log("MARKING WORDS: " + words);
648
721
  words = "" + words + " ";
649
722
  _ref = $(".ac-word div");
650
723
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -761,6 +834,28 @@ Utils = (function() {
761
834
  return text.replace(/^\s+|\s+$/g, "");
762
835
  };
763
836
 
837
+ Utils.edit_distance = function(source, target) {
838
+ var a, i, j, substitute_cost, _i, _ref, _ref2, _ref3, _ref4, _results;
839
+ a = [];
840
+ for (i = 0, _ref = source.length; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
841
+ a[i] = new Array(target.length + 1);
842
+ a[i][0] = i;
843
+ }
844
+ a[0] = (function() {
845
+ _results = [];
846
+ for (var _i = 0, _ref2 = target.length; 0 <= _ref2 ? _i <= _ref2 : _i >= _ref2; 0 <= _ref2 ? _i++ : _i--){ _results.push(_i); }
847
+ return _results;
848
+ }).apply(this);
849
+ for (i = 1, _ref3 = source.length; 1 <= _ref3 ? i <= _ref3 : i >= _ref3; 1 <= _ref3 ? i++ : i--) {
850
+ for (j = 1, _ref4 = target.length; 1 <= _ref4 ? j <= _ref4 : j >= _ref4; 1 <= _ref4 ? j++ : j--) {
851
+ substitute_cost = a[i - 1][j - 1];
852
+ if (source.charAt(i - 1) !== target.charAt(j - 1)) substitute_cost += 1;
853
+ a[i][j] = Math.min(substitute_cost, a[i - 1][j] + 1, a[i][j - 1] + 1);
854
+ }
855
+ }
856
+ return a[source.length][target.length];
857
+ };
858
+
764
859
  return Utils;
765
860
 
766
861
  }).call(this);
@@ -0,0 +1,72 @@
1
+ /*jshint eqnull:true */
2
+ /*!
3
+ * jQuery Cookie Plugin v1.2
4
+ * https://github.com/carhartl/jquery-cookie
5
+ *
6
+ * Copyright 2011, Klaus Hartl
7
+ * Dual licensed under the MIT or GPL Version 2 licenses.
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ * http://www.opensource.org/licenses/GPL-2.0
10
+ */
11
+ (function ($, document, undefined) {
12
+
13
+ var pluses = /\+/g;
14
+
15
+ function raw(s) {
16
+ return s;
17
+ }
18
+
19
+ function decoded(s) {
20
+ return decodeURIComponent(s.replace(pluses, ' '));
21
+ }
22
+
23
+ $.cookie = function (key, value, options) {
24
+
25
+ // key and at least value given, set cookie...
26
+ if (value !== undefined && !/Object/.test(Object.prototype.toString.call(value))) {
27
+ options = $.extend({}, $.cookie.defaults, options);
28
+
29
+ if (value === null) {
30
+ options.expires = -1;
31
+ }
32
+
33
+ if (typeof options.expires === 'number') {
34
+ var days = options.expires, t = options.expires = new Date();
35
+ t.setDate(t.getDate() + days);
36
+ }
37
+
38
+ value = String(value);
39
+
40
+ return (document.cookie = [
41
+ encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
42
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
43
+ options.path ? '; path=' + options.path : '',
44
+ options.domain ? '; domain=' + options.domain : '',
45
+ options.secure ? '; secure' : ''
46
+ ].join(''));
47
+ }
48
+
49
+ // key and possibly options given, get cookie...
50
+ options = value || $.cookie.defaults || {};
51
+ var decode = options.raw ? raw : decoded;
52
+ var cookies = document.cookie.split('; ');
53
+ for (var i = 0, parts; (parts = cookies[i] && cookies[i].split('=')); i++) {
54
+ if (decode(parts.shift()) === key) {
55
+ return decode(parts.join('='));
56
+ }
57
+ }
58
+
59
+ return null;
60
+ };
61
+
62
+ $.cookie.defaults = {};
63
+
64
+ $.removeCookie = function (key, options) {
65
+ if ($.cookie(key, options) !== null) {
66
+ $.cookie(key, null, options);
67
+ return true;
68
+ }
69
+ return false;
70
+ };
71
+
72
+ })(jQuery, document);
@@ -6,7 +6,7 @@
6
6
  <link rel="stylesheet" type="text/css" href="/bootstrap.css" />
7
7
  <link rel="stylesheet" type="text/css" href="/style.css" />
8
8
  <script src="/jquery.js"></script>
9
- <script src="/jquery.js"></script>
9
+ <script src="/cookie.js"></script>
10
10
  <script src="/bootstrap.js"></script>
11
11
  <script src="/ajax-cat.js"></script>
12
12
  <script src="/index.js"></script>
@@ -30,9 +30,6 @@
30
30
  <li><a href="#about" id="preview">Preview</a></li>
31
31
  </ul>
32
32
  <p class="pull-right">
33
- <button class="btn btn-info" id="send-experiment">
34
- Send experiment results
35
- </button>
36
33
  <button class="btn btn-info" id="save">
37
34
  Save into browser
38
35
  </button>
@@ -47,10 +44,13 @@
47
44
  <div class="container-fluid">
48
45
  <div class="row-fluid">
49
46
  <h1>Translations</h1>
50
- <span id="time"></span>
47
+ <h2><span id="translated-status"></span> <span id="time"></span></h2>
48
+ <button class="btn btn-info btn-large" id="send-experiment">
49
+ Next sentence >
50
+ </button>
51
51
 
52
52
  <table class=" table-bordered table-condensed" id="translation">
53
- <tr>
53
+ <tr id="top-translations">
54
54
  <td width="50%" id="source-top"></td>
55
55
  <td width="50%" id="target-top"></td>
56
56
  </tr>
@@ -62,7 +62,7 @@
62
62
  <div id="translation-table-container"></div>
63
63
  </td>
64
64
  </tr>
65
- <tr>
65
+ <tr id="bottom-translations">
66
66
  <td id="source-bottom"></td>
67
67
  <td id="target-bottom"></td>
68
68
  </tr>
@@ -70,7 +70,13 @@
70
70
 
71
71
  </div><!--/row-->
72
72
 
73
- <div id="log"></div>
73
+ <div id="experiment-settings" style="display: none;">
74
+ <h2>Current experiment settings</h2>
75
+ <table class="table">
76
+ <tr><th>Suggestion panel:</th><td id="suggestion-panel-is-on"></td></tr>
77
+ </table>
78
+ </div>
79
+ <div id="log" style="display: none;"></div>
74
80
 
75
81
  <hr>
76
82
 
@@ -13,6 +13,7 @@ module AjaxCat
13
13
  @translated = translated
14
14
  @translated_length = tokenize(translated).length
15
15
  @suggestions = []
16
+ @suggested_phrases = []
16
17
  end
17
18
 
18
19
  def prepare_moses_request
@@ -28,8 +29,17 @@ module AjaxCat
28
29
  def process_line(line)
29
30
  words = line.split(" ||| ")[1].strip.split(" ")
30
31
  if @suggestions.length < @@rows
31
- suggestion = words[@translated_length, @@suggestion_length].join(" ")
32
- @suggestions.push(suggestion) unless @suggestions.member?(suggestion)
32
+ alignment = line.split(" ||| ")[4].strip.split(" ").first
33
+ phrase = Phrase.new(words, alignment)
34
+ suggestion = {
35
+ "text" => phrase.words,
36
+ "from" => phrase.from,
37
+ "to" => phrase.to
38
+ }
39
+ if not @suggested_phrases.member?(suggestion['text'])
40
+ @suggested_phrases.push(suggestion['text'])
41
+ @suggestions.push(suggestion)
42
+ end
33
43
  end
34
44
  end
35
45