Browse Source

Implement POST/PUT/DELETE method on seq2seq annotation

pull/10/head
Hironsan 6 years ago
parent
commit
49b8514640
5 changed files with 45 additions and 37 deletions
  1. BIN
      app/db.sqlite3
  2. 2
      app/server/static/bundle/seq2seq.js
  3. 37
      app/server/static/js/seq2seq.js
  4. 19
      app/server/templates/annotation/seq2seq.html
  5. 24
      app/server/views.py

BIN
app/db.sqlite3

2
app/server/static/bundle/seq2seq.js

@ -185,7 +185,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _htt
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var _mixin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mixin.js */ \"./static/js/mixin.js\");\n/* harmony import */ var _http_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./http.js */ \"./static/js/http.js\");\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].use(__webpack_require__(/*! vue-shortkey */ \"./node_modules/vue-shortkey/dist/index.js\"));\n\n\n\n// localStorage persistence\nvar STORAGE_KEY = 'todos-vuejs-2.0'\nvar todoStorage = {\n fetch: function () {\n var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')\n todos.forEach(function (todo, index) {\n todo.id = index\n })\n todoStorage.uid = todos.length\n return todos\n },\n save: function (todos) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))\n }\n}\n\nvar vm = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#mail-app',\n delimiters: ['[[', ']]'],\n data: {\n todos: todoStorage.fetch(),\n newTodo: '',\n editedTodo: null\n },\n mixins: [_mixin_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"]],\n directives: {\n 'todo-focus': function (el, binding) {\n if (binding.value) {\n el.focus()\n }\n }\n },\n methods: {\n addLabel: async function (label_id) {\n var payload = {\n 'label_id': label_id\n };\n\n var doc_id = this.items[this.cur].id;\n await _http_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].post(`docs/${doc_id}/annotations/`, payload).then(response => {\n this.items[this.cur]['labels'].push(response.data);\n });\n this.updateProgress();\n },\n addTodo: function () {\n var value = this.newTodo && this.newTodo.trim()\n if (!value) {\n return\n }\n this.todos.push({\n id: todoStorage.uid++,\n title: value,\n })\n this.newTodo = ''\n },\n\n removeTodo: function (todo) {\n this.todos.splice(this.todos.indexOf(todo), 1)\n },\n\n editTodo: function (todo) {\n this.beforeEditCache = todo.title\n this.editedTodo = todo\n },\n\n doneEdit: function (todo) {\n if (!this.editedTodo) {\n return\n }\n this.editedTodo = null\n todo.title = todo.title.trim()\n if (!todo.title) {\n this.removeTodo(todo)\n }\n },\n\n cancelEdit: function (todo) {\n this.editedTodo = null\n todo.title = this.beforeEditCache\n }\n },\n created: function () {\n this.updateProgress();\n this.submit();\n },\n watch: {\n todos: {\n handler: function (todos) {\n todoStorage.save(todos)\n },\n deep: true\n }\n }\n});\n\n//# sourceURL=webpack:///./static/js/seq2seq.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var _mixin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mixin.js */ \"./static/js/mixin.js\");\n/* harmony import */ var _http_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./http.js */ \"./static/js/http.js\");\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].use(__webpack_require__(/*! vue-shortkey */ \"./node_modules/vue-shortkey/dist/index.js\"));\n\n\n\n// localStorage persistence\nvar STORAGE_KEY = 'todos-vuejs-2.0'\nvar todoStorage = {\n fetch: function () {\n var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')\n todos.forEach(function (todo, index) {\n todo.id = index\n })\n todoStorage.uid = todos.length\n return todos\n },\n save: function (todos) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))\n }\n}\n\nvar vm = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#mail-app',\n delimiters: ['[[', ']]'],\n data: {\n todos: todoStorage.fetch(),\n newTodo: '',\n editedTodo: null\n },\n mixins: [_mixin_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"]],\n directives: {\n 'todo-focus': function (el, binding) {\n if (binding.value) {\n el.focus()\n }\n }\n },\n methods: {\n addTodo: function () {\n var value = this.newTodo && this.newTodo.trim()\n if (!value) {\n return\n }\n\n var doc_id = this.items[this.cur].id;\n var payload = {text: value}\n _http_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].post(`docs/${doc_id}/annotations/`, payload).then(response => {\n this.items[this.cur]['labels'].push(response.data)\n })\n\n this.newTodo = ''\n },\n\n removeTodo: function (todo) {\n var doc_id = this.items[this.cur].id;\n _http_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].delete(`docs/${doc_id}/annotations/${todo.id}`).then(response => {\n this.items[this.cur]['labels'].splice(this.items[this.cur]['labels'].indexOf(todo), 1)\n });\n },\n\n editTodo: function (todo) {\n this.beforeEditCache = todo.text\n this.editedTodo = todo\n },\n\n doneEdit: function (todo) {\n if (!this.editedTodo) {\n return\n }\n this.editedTodo = null\n todo.text = todo.text.trim()\n if (!todo.text) {\n this.removeTodo(todo)\n }\n var doc_id = this.items[this.cur].id;\n _http_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].put(`docs/${doc_id}/annotations/${todo.id}`, todo).then(response => {\n console.log(response)\n });\n },\n\n cancelEdit: function (todo) {\n this.editedTodo = null\n todo.text = this.beforeEditCache\n }\n },\n created: function () {\n this.updateProgress();\n this.submit();\n },\n watch: {\n todos: {\n handler: function (todos) {\n todoStorage.save(todos)\n },\n deep: true\n }\n }\n});\n\n//# sourceURL=webpack:///./static/js/seq2seq.js?");
/***/ })

37
app/server/static/js/seq2seq.js

@ -36,35 +36,30 @@ var vm = new Vue({
}
},
methods: {
addLabel: async function (label_id) {
var payload = {
'label_id': label_id
};
var doc_id = this.items[this.cur].id;
await HTTP.post(`docs/${doc_id}/annotations/`, payload).then(response => {
this.items[this.cur]['labels'].push(response.data);
});
this.updateProgress();
},
addTodo: function () {
var value = this.newTodo && this.newTodo.trim()
if (!value) {
return
}
this.todos.push({
id: todoStorage.uid++,
title: value,
var doc_id = this.items[this.cur].id;
var payload = {text: value}
HTTP.post(`docs/${doc_id}/annotations/`, payload).then(response => {
this.items[this.cur]['labels'].push(response.data)
})
this.newTodo = ''
},
removeTodo: function (todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
var doc_id = this.items[this.cur].id;
HTTP.delete(`docs/${doc_id}/annotations/${todo.id}`).then(response => {
this.items[this.cur]['labels'].splice(this.items[this.cur]['labels'].indexOf(todo), 1)
});
},
editTodo: function (todo) {
this.beforeEditCache = todo.title
this.beforeEditCache = todo.text
this.editedTodo = todo
},
@ -73,15 +68,19 @@ var vm = new Vue({
return
}
this.editedTodo = null
todo.title = todo.title.trim()
if (!todo.title) {
todo.text = todo.text.trim()
if (!todo.text) {
this.removeTodo(todo)
}
var doc_id = this.items[this.cur].id;
HTTP.put(`docs/${doc_id}/annotations/${todo.id}`, todo).then(response => {
console.log(response)
});
},
cancelEdit: function (todo) {
this.editedTodo = null
todo.title = this.beforeEditCache
todo.text = this.beforeEditCache
}
},
created: function () {

19
app/server/templates/annotation/seq2seq.html

@ -7,17 +7,6 @@
</div>
</div>
<!--
<div class="card" style="margin-top:30px;">
<div class="card-content" contenteditable="true" v-if="items[cur].labels.length">
[[ items[cur].labels[0].text ]]
</div>
<div v-else class="card-content" contenteditable="true">
Input response...
</div>
</div>
-->
<section class="todoapp">
<header class="header">
<input class="textarea new-todo"
@ -26,16 +15,16 @@
v-model="newTodo"
@keyup.enter="addTodo">
</header>
<section class="main" v-show="todos.length" v-cloak>
<section class="main" v-show="items[cur].labels.length" v-cloak>
<ul class="todo-list">
<li v-for="todo in todos" class="todo" :key="todo.id" :class="{ editing: todo == editedTodo }">
<li v-for="todo in items[cur].labels" class="todo" :key="todo.id" :class="{ editing: todo == editedTodo }">
<div class="view">
<label @dblclick="editTodo(todo)">[[ todo.title ]]</label>
<label @dblclick="editTodo(todo)">[[ todo.text ]]</label>
<button class="delete destroy is-large" @click="removeTodo(todo)"></button>
</div>
<input class="textarea edit"
type="text"
v-model="todo.title"
v-model="todo.text"
v-todo-focus="todo == editedTodo"
@blur="doneEdit(todo)"
@keyup.enter="doneEdit(todo)"

24
app/server/views.py

@ -165,19 +165,24 @@ class AnnotationsAPI(generics.ListCreateAPIView):
def post(self, request, *args, **kwargs):
doc = get_object_or_404(Document, pk=self.kwargs['doc_id'])
label = get_object_or_404(Label, pk=request.data['label_id'])
project = get_object_or_404(Project, pk=self.kwargs['project_id'])
self.serializer_class = Factory.get_annotation_serializer(project)
if project.is_type_of(Project.DOCUMENT_CLASSIFICATION):
label = get_object_or_404(Label, pk=request.data['label_id'])
annotation = DocumentAnnotation(document=doc, label=label, manual=True,
user=self.request.user)
elif project.is_type_of(Project.SEQUENCE_LABELING):
label = get_object_or_404(Label, pk=request.data['label_id'])
annotation = SequenceAnnotation(document=doc, label=label, manual=True,
user=self.request.user,
start_offset=request.data['start_offset'],
end_offset=request.data['end_offset'])
elif project.is_type_of(Project.Seq2seq):
annotation = Seq2seqAnnotation(document=doc, manual=True, user=self.request.user)
text = request.data['text']
annotation = Seq2seqAnnotation(document=doc,
text=text,
manual=True,
user=self.request.user)
annotation.save()
serializer = self.serializer_class(annotation)
@ -200,3 +205,18 @@ class AnnotationAPI(generics.RetrieveUpdateDestroyAPIView):
self.check_object_permissions(self.request, obj)
return obj
def put(self, request, *args, **kwargs):
doc = get_object_or_404(Document, pk=self.kwargs['doc_id'])
project = get_object_or_404(Project, pk=self.kwargs['project_id'])
self.serializer_class = Factory.get_annotation_serializer(project)
if project.is_type_of(Project.Seq2seq):
text = request.data['text']
annotation = get_object_or_404(Seq2seqAnnotation, pk=request.data['id'])
annotation.text = text
print(text)
annotation.save()
serializer = self.serializer_class(annotation)
return Response(serializer.data)
Loading…
Cancel
Save