server/tags: add JSON export
This commit is contained in:
parent
61d2fb88ea
commit
9247e11596
6
API.md
6
API.md
|
@ -115,6 +115,12 @@ data.
|
|||
|
||||
Searches for tags.
|
||||
|
||||
**Note**: independently, the server exports current tag list snapshots to
|
||||
the data directory under `tags.json` name. Its purpose is to reduce the
|
||||
trips frontend needs to make when doing autocompletion, and ease caching.
|
||||
The data directory and its URL are controlled with `data_dir` and
|
||||
`data_url` variables in server's configuration.
|
||||
|
||||
**Anonymous tokens**
|
||||
|
||||
Same as `name` token.
|
||||
|
|
|
@ -48,6 +48,7 @@ class TagListApi(BaseApi):
|
|||
ctx.session, names, category, suggestions, implications)
|
||||
ctx.session.add(tag)
|
||||
ctx.session.commit()
|
||||
tags.export_to_json(ctx.session)
|
||||
return {'tag': _serialize_tag(tag)}
|
||||
|
||||
class TagDetailApi(BaseApi):
|
||||
|
@ -84,6 +85,7 @@ class TagDetailApi(BaseApi):
|
|||
|
||||
tag.last_edit_time = datetime.datetime.now()
|
||||
ctx.session.commit()
|
||||
tags.export_to_json(ctx.session)
|
||||
return {'tag': _serialize_tag(tag)}
|
||||
|
||||
def delete(self, ctx, tag_name):
|
||||
|
@ -98,4 +100,5 @@ class TagDetailApi(BaseApi):
|
|||
auth.verify_privilege(ctx.user, 'tags:delete')
|
||||
ctx.session.delete(tag)
|
||||
ctx.session.commit()
|
||||
tags.export_to_json(ctx.session)
|
||||
return {}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import datetime
|
||||
import os
|
||||
import pytest
|
||||
from szurubooru import api, db, errors
|
||||
from szurubooru import api, config, db, errors
|
||||
from szurubooru.util import misc, tags
|
||||
|
||||
def get_tag(session, name):
|
||||
|
@ -15,8 +16,14 @@ def assert_relations(relations, expected_tag_names):
|
|||
|
||||
@pytest.fixture
|
||||
def test_ctx(
|
||||
session, config_injector, context_factory, user_factory, tag_factory):
|
||||
tmpdir,
|
||||
session,
|
||||
config_injector,
|
||||
context_factory,
|
||||
user_factory,
|
||||
tag_factory):
|
||||
config_injector({
|
||||
'data_dir': str(tmpdir),
|
||||
'tag_categories': ['meta', 'character', 'copyright'],
|
||||
'tag_name_regex': '^[^!]*$',
|
||||
'ranks': ['anonymous', 'regular_user'],
|
||||
|
@ -58,6 +65,7 @@ def test_creating_simple_tags(test_ctx, fake_datetime):
|
|||
assert tag.post_count == 0
|
||||
assert_relations(tag.suggestions, [])
|
||||
assert_relations(tag.implications, [])
|
||||
assert os.path.exists(os.path.join(config.config['data_dir'], 'tags.json'))
|
||||
|
||||
def test_duplicating_names(test_ctx):
|
||||
result = test_ctx.api.post(
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
import pytest
|
||||
import os
|
||||
from datetime import datetime
|
||||
from szurubooru import api, db, errors
|
||||
from szurubooru import api, config, db, errors
|
||||
from szurubooru.util import misc, tags
|
||||
|
||||
@pytest.fixture
|
||||
def test_ctx(
|
||||
session, config_injector, context_factory, tag_factory, user_factory):
|
||||
tmpdir,
|
||||
session,
|
||||
config_injector,
|
||||
context_factory,
|
||||
tag_factory,
|
||||
user_factory):
|
||||
config_injector({
|
||||
'data_dir': str(tmpdir),
|
||||
'privileges': {
|
||||
'tags:delete': 'regular_user',
|
||||
},
|
||||
|
@ -29,6 +36,7 @@ def test_removing_tags(test_ctx):
|
|||
'tag')
|
||||
assert result == {}
|
||||
assert test_ctx.session.query(db.Tag).count() == 0
|
||||
assert os.path.exists(os.path.join(config.config['data_dir'], 'tags.json'))
|
||||
|
||||
def test_removing_tags_without_privileges(test_ctx):
|
||||
test_ctx.session.add(test_ctx.tag_factory(names=['tag']))
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import datetime
|
||||
import os
|
||||
import json
|
||||
from szurubooru import config, db
|
||||
from szurubooru.util import tags
|
||||
|
||||
def test_export(tmpdir, session, config_injector, tag_factory):
|
||||
config_injector({
|
||||
'data_dir': str(tmpdir)
|
||||
})
|
||||
sug1 = tag_factory(names=['sug1'])
|
||||
sug2 = tag_factory(names=['sug2'])
|
||||
imp1 = tag_factory(names=['imp1'])
|
||||
imp2 = tag_factory(names=['imp2'])
|
||||
tag = tag_factory(names=['alias1', 'alias2'])
|
||||
tag.post_count = 1
|
||||
session.add_all([tag, sug1, sug2, imp1, imp2])
|
||||
session.flush()
|
||||
session.add_all([
|
||||
db.TagSuggestion(tag.tag_id, sug1.tag_id),
|
||||
db.TagSuggestion(tag.tag_id, sug2.tag_id),
|
||||
db.TagImplication(tag.tag_id, imp1.tag_id),
|
||||
db.TagImplication(tag.tag_id, imp2.tag_id),
|
||||
])
|
||||
session.flush()
|
||||
|
||||
tags.export_to_json(session)
|
||||
export_path = os.path.join(config.config['data_dir'], 'tags.json')
|
||||
assert os.path.exists(export_path)
|
||||
with open(export_path, 'r') as handle:
|
||||
assert json.loads(handle.read()) == [
|
||||
{
|
||||
'names': ['alias1', 'alias2'],
|
||||
'usages': 1,
|
||||
'suggestions': ['sug1', 'sug2'],
|
||||
'implications': ['imp1', 'imp2'],
|
||||
},
|
||||
{'names': ['sug1'], 'usages': 0},
|
||||
{'names': ['sug2'], 'usages': 0},
|
||||
{'names': ['imp1'], 'usages': 0},
|
||||
{'names': ['imp2'], 'usages': 0},
|
||||
]
|
|
@ -1,6 +1,7 @@
|
|||
import datetime
|
||||
import os
|
||||
import pytest
|
||||
from szurubooru import api, db, errors
|
||||
from szurubooru import api, config, db, errors
|
||||
from szurubooru.util import misc, tags
|
||||
|
||||
def get_tag(session, name):
|
||||
|
@ -15,8 +16,14 @@ def assert_relations(relations, expected_tag_names):
|
|||
|
||||
@pytest.fixture
|
||||
def test_ctx(
|
||||
session, config_injector, context_factory, user_factory, tag_factory):
|
||||
tmpdir,
|
||||
session,
|
||||
config_injector,
|
||||
context_factory,
|
||||
user_factory,
|
||||
tag_factory):
|
||||
config_injector({
|
||||
'data_dir': str(tmpdir),
|
||||
'tag_categories': ['meta', 'character', 'copyright'],
|
||||
'tag_name_regex': '^[^!]*$',
|
||||
'ranks': ['anonymous', 'regular_user'],
|
||||
|
@ -66,6 +73,7 @@ def test_simple_updating(test_ctx, fake_datetime):
|
|||
assert tag.category == 'character'
|
||||
assert tag.suggestions == []
|
||||
assert tag.implications == []
|
||||
assert os.path.exists(os.path.join(config.config['data_dir'], 'tags.json'))
|
||||
|
||||
def test_trying_to_update_non_existing_tag(test_ctx):
|
||||
with pytest.raises(tags.TagNotFoundError):
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import datetime
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
import sqlalchemy
|
||||
from szurubooru import config, db, errors
|
||||
|
@ -25,6 +27,24 @@ def _lower_list(names):
|
|||
def _check_name_intersection(names1, names2):
|
||||
return len(set(_lower_list(names1)).intersection(_lower_list(names2))) > 0
|
||||
|
||||
def export_to_json(session):
|
||||
output = []
|
||||
for tag in session.query(db.Tag).all():
|
||||
item = {
|
||||
'names': [tag_name.name for tag_name in tag.names],
|
||||
'usages': tag.post_count
|
||||
}
|
||||
if len(tag.suggestions):
|
||||
item['suggestions'] = \
|
||||
[rel.child_tag.names[0].name for rel in tag.suggestions]
|
||||
if len(tag.implications):
|
||||
item['implications'] = \
|
||||
[rel.child_tag.names[0].name for rel in tag.implications]
|
||||
output.append(item)
|
||||
export_path = os.path.join(config.config['data_dir'], 'tags.json')
|
||||
with open(export_path, 'w') as handle:
|
||||
handle.write(json.dumps(output, separators=(',', ':')))
|
||||
|
||||
def get_by_name(session, name):
|
||||
return session.query(db.Tag) \
|
||||
.join(db.TagName) \
|
||||
|
|
Loading…
Reference in New Issue