Feature: move annotations from one tag to another
This commit is contained in:
parent
5fa5096c44
commit
4b0b5c2c16
5 changed files with 78 additions and 5 deletions
|
@ -522,6 +522,8 @@ class AnnotationIndex:
|
|||
Drawing(fn, self.metadata_dir, self.drawing_dir) for fn in self.get_drawing_filenames()
|
||||
]
|
||||
}
|
||||
|
||||
self.root_tag = getRootTag()
|
||||
self.shelve['_tags'] = {tag.id: [] for tag in self.root_tag.descendants}
|
||||
self.shelve['_annotations'] = {}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import json
|
|||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from urllib.error import HTTPError
|
||||
import tornado.ioloop
|
||||
import tornado.web
|
||||
import tornado.websocket
|
||||
|
@ -12,6 +13,7 @@ import html
|
|||
import argparse
|
||||
import coloredlogs
|
||||
import glob
|
||||
import filelock
|
||||
import svganim.strokes
|
||||
import svganim.uimethods
|
||||
|
||||
|
@ -410,6 +412,41 @@ class AnnotationHandler(tornado.web.RequestHandler):
|
|||
"tag": annotation.tag,
|
||||
"audio": f"/annotation/{annotation.id}.mp3",
|
||||
}))
|
||||
|
||||
def post(self, annotation_id):
|
||||
"""change tag for given annotation"""
|
||||
if annotation_id not in self.index.annotations:
|
||||
raise tornado.web.HTTPError(404)
|
||||
|
||||
# might be set on file level, but let's try to avoid issues by keeping it simple
|
||||
lock = filelock.FileLock("metadata_write.lock", timeout=10)
|
||||
with lock:
|
||||
newTagId = self.get_argument('tag_id')
|
||||
if not self.index.has_tag(newTagId):
|
||||
raise tornado.web.HTTPError(400)
|
||||
|
||||
annotation: svganim.strokes.Annotation = self.index.annotations[annotation_id]
|
||||
|
||||
logger.info(f"change tag from {annotation.tag} to {newTagId}")
|
||||
|
||||
# change metadata and reload index
|
||||
metadata = annotation.drawing.get_metadata()
|
||||
change = False
|
||||
for idx, ann in enumerate(metadata['annotations']):
|
||||
if ann['t_in'] == annotation.t_in and ann['t_out'] == annotation.t_out and annotation.tag == ann['tag']:
|
||||
#found!?
|
||||
metadata['annotations'][idx]['tag'] = newTagId
|
||||
change = True
|
||||
break
|
||||
|
||||
if change == False:
|
||||
raise HTTPError(409)
|
||||
|
||||
with open(annotation.drawing.metadata_fn, "w") as fp:
|
||||
logger.info(f"save tag in {annotation.drawing.metadata_fn}")
|
||||
json.dump(metadata, fp)
|
||||
|
||||
self.index.refresh()
|
||||
|
||||
|
||||
class DrawingHandler(tornado.web.RequestHandler):
|
||||
|
@ -544,6 +581,9 @@ class TagsHandler(tornado.web.RequestHandler):
|
|||
|
||||
with open('www/tags.json', 'w') as fp:
|
||||
fp.write(newTagsContent)
|
||||
|
||||
# update as to load new tag into cache
|
||||
self.index.refresh()
|
||||
|
||||
self.set_status(204)
|
||||
# print()
|
||||
|
|
|
@ -301,9 +301,23 @@ class AnnotationManager {
|
|||
this.saveTags();
|
||||
}
|
||||
|
||||
moveSelectedAnnotations(tag) {
|
||||
async moveSelectedAnnotations(tag) {
|
||||
// TODO: add button for this
|
||||
alert(`This doesn't work yet! (move to tag ${tag.get_name()})`)
|
||||
// alert(`This doesn't work yet! (move to tag ${tag.get_name()})`)
|
||||
|
||||
await Promise.all(this.selectedAnnotations.map(async (annotation) => {
|
||||
const formData = new FormData();
|
||||
formData.append('tag_id', tag.id)
|
||||
return await fetch('/annotation/'+annotation.id, {
|
||||
method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json'
|
||||
// },
|
||||
body: formData //JSON.stringify({'tag_id': tag.id})
|
||||
}).catch((e) => alert('Something went wrong saving the tags'));
|
||||
}));
|
||||
|
||||
this.loadAnnotationsForTag(this.selectedTag)
|
||||
}
|
||||
|
||||
async saveTags() {
|
||||
|
|
22
poetry.lock
generated
22
poetry.lock
generated
|
@ -2,7 +2,7 @@
|
|||
name = "anytree"
|
||||
version = "2.8.0"
|
||||
description = "Powerful and Lightweight Python Tree Data Structure.."
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
|
@ -27,6 +27,18 @@ humanfriendly = ">=9.1"
|
|||
[package.extras]
|
||||
cron = ["capturer (>=2.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.7.1"
|
||||
description = "A platform independent file lock."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||
testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "humanfriendly"
|
||||
version = "10.0"
|
||||
|
@ -58,7 +70,7 @@ python-versions = "*"
|
|||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "main"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
|
@ -81,7 +93,7 @@ python-versions = ">= 3.5"
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "1ad87cd5b37157a20ee2ec8f23d84b0275ca9f3aa3218c98eb18859d43aa5080"
|
||||
content-hash = "11298c8670e03d4235a76555b1ca7e6cbf0740041f14c14fdf409f633e197bf5"
|
||||
|
||||
[metadata.files]
|
||||
anytree = [
|
||||
|
@ -92,6 +104,10 @@ coloredlogs = [
|
|||
{file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"},
|
||||
{file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"},
|
||||
]
|
||||
filelock = [
|
||||
{file = "filelock-3.7.1-py3-none-any.whl", hash = "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404"},
|
||||
{file = "filelock-3.7.1.tar.gz", hash = "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"},
|
||||
]
|
||||
humanfriendly = [
|
||||
{file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"},
|
||||
{file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"},
|
||||
|
|
|
@ -11,6 +11,7 @@ coloredlogs = "^15.0.1"
|
|||
pydub = "^0.25.1"
|
||||
svgwrite = "^1.4.1"
|
||||
anytree = "^2.8.0"
|
||||
filelock = "^3.7.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
|
|
Loading…
Reference in a new issue