Feature: move annotations from one tag to another

This commit is contained in:
Ruben van de Ven 2022-06-08 18:22:04 +02:00
parent 5fa5096c44
commit 4b0b5c2c16
5 changed files with 78 additions and 5 deletions

View file

@ -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'] = {}

View file

@ -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()

View file

@ -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
View file

@ -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"},

View file

@ -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]