aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorrr-2016-04-18 21:41:47 +0200
committerrr-2016-04-18 22:08:30 +0200
commite3a4793d54e5a740bf841dba5654a718661ba39d (patch)
tree00306f56fda17495a7688a6015fb480ef9661d9a /server
parent9350c4ff97ee04560233467180e813d929a12dd6 (diff)
server/tags: move tag categories to database
Diffstat (limited to 'server')
-rw-r--r--server/szurubooru/api/password_reset_api.py4
-rw-r--r--server/szurubooru/api/tag_api.py18
-rw-r--r--server/szurubooru/api/user_api.py6
-rw-r--r--server/szurubooru/config.py3
-rw-r--r--server/szurubooru/db/__init__.py1
-rw-r--r--server/szurubooru/db/tag.py18
-rw-r--r--server/szurubooru/db/tag_category.py12
-rw-r--r--server/szurubooru/middleware/authenticator.py2
-rw-r--r--server/szurubooru/migrations/versions/00cb3a2734db_create_tags_tables.py15
-rw-r--r--server/szurubooru/tests/api/test_tag_creating.py15
-rw-r--r--server/szurubooru/tests/api/test_tag_deleting.py8
-rw-r--r--server/szurubooru/tests/api/test_tag_updating.py41
-rw-r--r--server/szurubooru/tests/api/test_user_deleting.py6
-rw-r--r--server/szurubooru/tests/conftest.py6
-rw-r--r--server/szurubooru/tests/db/test_tag.py64
-rw-r--r--server/szurubooru/tests/util/test_snapshots.py20
-rw-r--r--server/szurubooru/util/snapshots.py2
-rw-r--r--server/szurubooru/util/tags.py35
-rw-r--r--server/szurubooru/util/users.py6
19 files changed, 166 insertions, 116 deletions
diff --git a/server/szurubooru/api/password_reset_api.py b/server/szurubooru/api/password_reset_api.py
index 0489509..b90b1b1 100644
--- a/server/szurubooru/api/password_reset_api.py
+++ b/server/szurubooru/api/password_reset_api.py
@@ -11,7 +11,7 @@ MAIL_BODY = \
class PasswordResetApi(BaseApi):
def get(self, ctx, user_name):
''' Send a mail with secure token to the correlated user. '''
- user = users.get_by_name_or_email(ctx.session, user_name)
+ user = users.get_user_by_name_or_email(ctx.session, user_name)
if not user:
raise errors.NotFoundError('User %r not found.' % user_name)
if not user.email:
@@ -29,7 +29,7 @@ class PasswordResetApi(BaseApi):
def post(self, ctx, user_name):
''' Verify token from mail, generate a new password and return it. '''
- user = users.get_by_name_or_email(ctx.session, user_name)
+ user = users.get_user_by_name_or_email(ctx.session, user_name)
if not user:
raise errors.NotFoundError('User %r not found.' % user_name)
good_token = auth.generate_authentication_token(user)
diff --git a/server/szurubooru/api/tag_api.py b/server/szurubooru/api/tag_api.py
index 5ce750b..5be996c 100644
--- a/server/szurubooru/api/tag_api.py
+++ b/server/szurubooru/api/tag_api.py
@@ -6,7 +6,7 @@ from szurubooru.api.base_api import BaseApi
def _serialize_tag(tag):
return {
'names': [tag_name.name for tag_name in tag.names],
- 'category': tag.category,
+ 'category': tag.category.name,
'suggestions': [
relation.names[0].name for relation in tag.suggestions],
'implications': [
@@ -47,21 +47,22 @@ class TagListApi(BaseApi):
tag = tags.create_tag(
ctx.session, names, category, suggestions, implications)
ctx.session.add(tag)
+ ctx.session.flush()
+ snapshots.create(ctx.session, tag, ctx.user)
ctx.session.commit()
tags.export_to_json(ctx.session)
- snapshots.create(ctx.session, tag, ctx.user)
return {'tag': _serialize_tag(tag)}
class TagDetailApi(BaseApi):
def get(self, ctx, tag_name):
auth.verify_privilege(ctx.user, 'tags:view')
- tag = tags.get_by_name(ctx.session, tag_name)
+ tag = tags.get_tag_by_name(ctx.session, tag_name)
if not tag:
raise tags.TagNotFoundError('Tag %r not found.' % tag_name)
return {'tag': _serialize_tag(tag)}
def put(self, ctx, tag_name):
- tag = tags.get_by_name(ctx.session, tag_name)
+ tag = tags.get_tag_by_name(ctx.session, tag_name)
if not tag:
raise tags.TagNotFoundError('Tag %r not found.' % tag_name)
@@ -72,7 +73,8 @@ class TagDetailApi(BaseApi):
if ctx.has_param('category'):
auth.verify_privilege(ctx.user, 'tags:edit:category')
- tags.update_category(tag, ctx.get_param_as_string('category'))
+ tags.update_category_name(
+ ctx.session, tag, ctx.get_param_as_string('category'))
if ctx.has_param('suggestions'):
auth.verify_privilege(ctx.user, 'tags:edit:suggestions')
@@ -85,13 +87,13 @@ class TagDetailApi(BaseApi):
ctx.session, tag, ctx.get_param_as_list('implications'))
tag.last_edit_time = datetime.datetime.now()
+ snapshots.modify(ctx.session, tag, ctx.user)
ctx.session.commit()
tags.export_to_json(ctx.session)
- snapshots.modify(ctx.session, tag, ctx.user)
return {'tag': _serialize_tag(tag)}
def delete(self, ctx, tag_name):
- tag = tags.get_by_name(ctx.session, tag_name)
+ tag = tags.get_tag_by_name(ctx.session, tag_name)
if not tag:
raise tags.TagNotFoundError('Tag %r not found.' % tag_name)
if tag.post_count > 0:
@@ -100,8 +102,8 @@ class TagDetailApi(BaseApi):
'Please untag relevant posts first.')
auth.verify_privilege(ctx.user, 'tags:delete')
+ snapshots.delete(ctx.session, tag, ctx.user)
ctx.session.delete(tag)
ctx.session.commit()
- snapshots.delete(ctx.session, tag, ctx.user)
tags.export_to_json(ctx.session)
return {}
diff --git a/server/szurubooru/api/user_api.py b/server/szurubooru/api/user_api.py
index deb7bd9..3af11a9 100644
--- a/server/szurubooru/api/user_api.py
+++ b/server/szurubooru/api/user_api.py
@@ -75,13 +75,13 @@ class UserListApi(BaseApi):
class UserDetailApi(BaseApi):
def get(self, ctx, user_name):
auth.verify_privilege(ctx.user, 'users:view')
- user = users.get_by_name(ctx.session, user_name)
+ user = users.get_user_by_name(ctx.session, user_name)
if not user:
raise users.UserNotFoundError('User %r not found.' % user_name)
return {'user': _serialize_user(ctx.user, user)}
def put(self, ctx, user_name):
- user = users.get_by_name(ctx.session, user_name)
+ user = users.get_user_by_name(ctx.session, user_name)
if not user:
raise users.UserNotFoundError('User %r not found.' % user_name)
@@ -119,7 +119,7 @@ class UserDetailApi(BaseApi):
return {'user': _serialize_user(ctx.user, user)}
def delete(self, ctx, user_name):
- user = users.get_by_name(ctx.session, user_name)
+ user = users.get_user_by_name(ctx.session, user_name)
if not user:
raise users.UserNotFoundError('User %r not found.' % user_name)
diff --git a/server/szurubooru/config.py b/server/szurubooru/config.py
index ed96205..ba33d0c 100644
--- a/server/szurubooru/config.py
+++ b/server/szurubooru/config.py
@@ -53,8 +53,5 @@ def validate_config(src):
raise errors.ConfigError(
'Database is not configured: %r is missing' % key)
- if not len(src['tag_categories']):
- raise errors.ConfigError('Must have at least one tag category')
-
config = read_config() # pylint: disable=invalid-name
validate_config(config)
diff --git a/server/szurubooru/db/__init__.py b/server/szurubooru/db/__init__.py
index 7448a94..837020c 100644
--- a/server/szurubooru/db/__init__.py
+++ b/server/szurubooru/db/__init__.py
@@ -1,5 +1,6 @@
from szurubooru.db.base import Base
from szurubooru.db.user import User
from szurubooru.db.tag import Tag, TagName, TagSuggestion, TagImplication
+from szurubooru.db.tag_category import TagCategory
from szurubooru.db.post import Post, PostTag, PostRelation
from szurubooru.db.snapshot import Snapshot
diff --git a/server/szurubooru/db/tag.py b/server/szurubooru/db/tag.py
index 287eea6..bf98745 100644
--- a/server/szurubooru/db/tag.py
+++ b/server/szurubooru/db/tag.py
@@ -7,8 +7,10 @@ from szurubooru.db.post import PostTag
class TagSuggestion(Base):
__tablename__ = 'tag_suggestion'
- parent_id = Column('parent_id', Integer, ForeignKey('tag.id'), primary_key=True)
- child_id = Column('child_id', Integer, ForeignKey('tag.id'), primary_key=True)
+ parent_id = Column(
+ 'parent_id', Integer, ForeignKey('tag.id'), primary_key=True)
+ child_id = Column(
+ 'child_id', Integer, ForeignKey('tag.id'), primary_key=True)
def __init__(self, parent_id, child_id):
self.parent_id = parent_id
@@ -17,8 +19,10 @@ class TagSuggestion(Base):
class TagImplication(Base):
__tablename__ = 'tag_implication'
- parent_id = Column('parent_id', Integer, ForeignKey('tag.id'), primary_key=True)
- child_id = Column('child_id', Integer, ForeignKey('tag.id'), primary_key=True)
+ parent_id = Column(
+ 'parent_id', Integer, ForeignKey('tag.id'), primary_key=True)
+ child_id = Column(
+ 'child_id', Integer, ForeignKey('tag.id'), primary_key=True)
def __init__(self, parent_id, child_id):
self.parent_id = parent_id
@@ -28,7 +32,7 @@ class TagName(Base):
__tablename__ = 'tag_name'
tag_name_id = Column('tag_name_id', Integer, primary_key=True)
- tag_id = Column('tag_id', Integer, ForeignKey('tag.id'))
+ tag_id = Column('tag_id', Integer, ForeignKey('tag.id'), nullable=False)
name = Column('name', String(64), nullable=False, unique=True)
def __init__(self, name):
@@ -38,10 +42,12 @@ class Tag(Base):
__tablename__ = 'tag'
tag_id = Column('id', Integer, primary_key=True)
- category = Column('category', String(32), nullable=False)
+ category_id = Column(
+ 'category_id', Integer, ForeignKey('tag_category.id'), nullable=False)
creation_time = Column('creation_time', DateTime, nullable=False)
last_edit_time = Column('last_edit_time', DateTime)
+ category = relationship('TagCategory')
names = relationship('TagName', cascade='all, delete-orphan')
suggestions = relationship(
'Tag',
diff --git a/server/szurubooru/db/tag_category.py b/server/szurubooru/db/tag_category.py
new file mode 100644
index 0000000..40d9af0
--- /dev/null
+++ b/server/szurubooru/db/tag_category.py
@@ -0,0 +1,12 @@
+from sqlalchemy import Column, Integer, String
+from szurubooru.db.base import Base
+
+class TagCategory(Base):
+ __tablename__ = 'tag_category'
+
+ tag_category_id = Column('id', Integer, primary_key=True)
+ name = Column('name', String(32), nullable=False)
+ color = Column('color', String(32), nullable=False, default='#000000')
+
+ def __init__(self, name):
+ self.name = name
diff --git a/server/szurubooru/middleware/authenticator.py b/server/szurubooru/middleware/authenticator.py
index 8c506f9..ec01925 100644
--- a/server/szurubooru/middleware/authenticator.py
+++ b/server/szurubooru/middleware/authenticator.py
@@ -40,7 +40,7 @@ class Authenticator(object):
def _authenticate(self, session, username, password):
''' Try to authenticate user. Throw AuthError for invalid users. '''
- user = users.get_by_name(session, username)
+ user = users.get_user_by_name(session, username)
if not user:
raise errors.AuthError('No such user.')
if not auth.is_valid_password(user, password):
diff --git a/server/szurubooru/migrations/versions/00cb3a2734db_create_tags_tables.py b/server/szurubooru/migrations/versions/00cb3a2734db_create_tags_tables.py
index ba20230..ac50213 100644
--- a/server/szurubooru/migrations/versions/00cb3a2734db_create_tags_tables.py
+++ b/server/szurubooru/migrations/versions/00cb3a2734db_create_tags_tables.py
@@ -15,17 +15,25 @@ depends_on = None
def upgrade():
op.create_table(
+ 'tag_category',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('name', sa.String(length=32), nullable=False),
+ sa.Column('color', sa.String(length=32), nullable=False),
+ sa.PrimaryKeyConstraint('id'))
+
+ op.create_table(
'tag',
sa.Column('id', sa.Integer(), nullable=False),
- sa.Column('category', sa.String(length=32), nullable=False),
+ sa.Column('category_id', sa.Integer(), nullable=False),
sa.Column('creation_time', sa.DateTime(), nullable=False),
sa.Column('last_edit_time', sa.DateTime(), nullable=True),
+ sa.ForeignKeyConstraint(['category_id'], ['tag_category.id']),
sa.PrimaryKeyConstraint('id'))
op.create_table(
'tag_name',
sa.Column('tag_name_id', sa.Integer(), nullable=False),
- sa.Column('tag_id', sa.Integer(), nullable=True),
+ sa.Column('tag_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=64), nullable=False),
sa.ForeignKeyConstraint(['tag_id'], ['tag.id']),
sa.PrimaryKeyConstraint('tag_name_id'),
@@ -49,6 +57,7 @@ def upgrade():
def downgrade():
op.drop_table('tag_suggestion')
- op.drop_table('tag_name')
op.drop_table('tag_implication')
+ op.drop_table('tag_name')
op.drop_table('tag')
+ op.drop_table('tag_category')
diff --git a/server/szurubooru/tests/api/test_tag_creating.py b/server/szurubooru/tests/api/test_tag_creating.py
index ec77322..ffc8ccd 100644
--- a/server/szurubooru/tests/api/test_tag_creating.py
+++ b/server/szurubooru/tests/api/test_tag_creating.py
@@ -24,11 +24,14 @@ def test_ctx(
tag_factory):
config_injector({
'data_dir': str(tmpdir),
- 'tag_categories': ['meta', 'character', 'copyright'],
'tag_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': {'tags:create': 'regular_user'},
})
+ session.add_all([
+ db.TagCategory(name) for name in [
+ 'meta', 'character', 'copyright']])
+ session.flush()
ret = misc.dotdict()
ret.session = session
ret.context_factory = context_factory
@@ -60,7 +63,7 @@ def test_creating_simple_tags(test_ctx, fake_datetime):
}
tag = get_tag(test_ctx.session, 'tag1')
assert [tag_name.name for tag_name in tag.names] == ['tag1', 'tag2']
- assert tag.category == 'meta'
+ assert tag.category.name == 'meta'
assert tag.last_edit_time is None
assert tag.post_count == 0
assert_relations(tag.suggestions, [])
@@ -111,8 +114,8 @@ def test_trying_to_create_tag_with_invalid_name(test_ctx, names):
def test_trying_to_use_existing_name(test_ctx):
test_ctx.session.add_all([
- test_ctx.tag_factory(names=['used1'], category='meta'),
- test_ctx.tag_factory(names=['used2'], category='meta'),
+ test_ctx.tag_factory(names=['used1'], category_name='meta'),
+ test_ctx.tag_factory(names=['used2'], category_name='meta'),
])
test_ctx.session.commit()
with pytest.raises(tags.TagAlreadyExistsError):
@@ -195,8 +198,8 @@ def test_creating_new_suggestions_and_implications(
def test_reusing_suggestions_and_implications(test_ctx):
test_ctx.session.add_all([
- test_ctx.tag_factory(names=['tag1', 'tag2'], category='meta'),
- test_ctx.tag_factory(names=['tag3'], category='meta'),
+ test_ctx.tag_factory(names=['tag1', 'tag2'], category_name='meta'),
+ test_ctx.tag_factory(names=['tag3'], category_name='meta'),
])
test_ctx.session.commit()
result = test_ctx.api.post(
diff --git a/server/szurubooru/tests/api/test_tag_deleting.py b/server/szurubooru/tests/api/test_tag_deleting.py
index a895bec..2e5136d 100644
--- a/server/szurubooru/tests/api/test_tag_deleting.py
+++ b/server/szurubooru/tests/api/test_tag_deleting.py
@@ -27,7 +27,7 @@ def test_ctx(
ret.api = api.TagDetailApi()
return ret
-def test_removing_tags(test_ctx):
+def test_deleting_tags(test_ctx):
test_ctx.session.add(test_ctx.tag_factory(names=['tag']))
test_ctx.session.commit()
result = test_ctx.api.delete(
@@ -38,7 +38,7 @@ def test_removing_tags(test_ctx):
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):
+def test_deleting_tags_without_privileges(test_ctx):
test_ctx.session.add(test_ctx.tag_factory(names=['tag']))
test_ctx.session.commit()
with pytest.raises(errors.AuthError):
@@ -48,7 +48,7 @@ def test_removing_tags_without_privileges(test_ctx):
'tag')
assert test_ctx.session.query(db.Tag).count() == 1
-def test_removing_tags_with_usages(test_ctx, post_factory):
+def test_deleting_tags_with_usages(test_ctx, post_factory):
tag = test_ctx.tag_factory(names=['tag'])
post = post_factory()
post.tags.append(tag)
@@ -61,7 +61,7 @@ def test_removing_tags_with_usages(test_ctx, post_factory):
'tag')
assert test_ctx.session.query(db.Tag).count() == 1
-def test_removing_non_existing(test_ctx):
+def test_deleting_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
diff --git a/server/szurubooru/tests/api/test_tag_updating.py b/server/szurubooru/tests/api/test_tag_updating.py
index d7262ab..7c41290 100644
--- a/server/szurubooru/tests/api/test_tag_updating.py
+++ b/server/szurubooru/tests/api/test_tag_updating.py
@@ -24,7 +24,6 @@ def test_ctx(
tag_factory):
config_injector({
'data_dir': str(tmpdir),
- 'tag_categories': ['meta', 'character', 'copyright'],
'tag_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': {
@@ -34,6 +33,10 @@ def test_ctx(
'tags:edit:implications': 'regular_user',
},
})
+ session.add_all([
+ db.TagCategory(name) for name in [
+ 'meta', 'character', 'copyright']])
+ session.flush()
ret = misc.dotdict()
ret.session = session
ret.context_factory = context_factory
@@ -43,7 +46,7 @@ def test_ctx(
return ret
def test_simple_updating(test_ctx, fake_datetime):
- tag = test_ctx.tag_factory(names=['tag1', 'tag2'], category='meta')
+ tag = test_ctx.tag_factory(names=['tag1', 'tag2'], category_name='meta')
test_ctx.session.add(tag)
test_ctx.session.commit()
with fake_datetime('1997-12-01'):
@@ -70,7 +73,7 @@ def test_simple_updating(test_ctx, fake_datetime):
tag = get_tag(test_ctx.session, 'tag3')
assert tag is not None
assert [tag_name.name for tag_name in tag.names] == ['tag3']
- assert tag.category == 'character'
+ assert tag.category.name == 'character'
assert tag.suggestions == []
assert tag.implications == []
assert os.path.exists(os.path.join(config.config['data_dir'], 'tags.json'))
@@ -86,7 +89,7 @@ def test_trying_to_update_non_existing_tag(test_ctx):
@pytest.mark.parametrize('dup_name', ['tag1', 'TAG1'])
def test_reusing_own_name(test_ctx, dup_name):
test_ctx.session.add(
- test_ctx.tag_factory(names=['tag1', 'tag2'], category='meta'))
+ test_ctx.tag_factory(names=['tag1', 'tag2'], category_name='meta'))
test_ctx.session.commit()
result = test_ctx.api.put(
test_ctx.context_factory(
@@ -102,7 +105,7 @@ def test_reusing_own_name(test_ctx, dup_name):
def test_duplicating_names(test_ctx):
test_ctx.session.add(
- test_ctx.tag_factory(names=['tag1', 'tag2'], category='meta'))
+ test_ctx.tag_factory(names=['tag1', 'tag2'], category_name='meta'))
result = test_ctx.api.put(
test_ctx.context_factory(
input={'names': ['tag3', 'TAG3']},
@@ -121,7 +124,8 @@ def test_duplicating_names(test_ctx):
{'names': ['x' * 65]},
])
def test_trying_to_set_invalid_name(test_ctx, input):
- test_ctx.session.add(test_ctx.tag_factory(names=['tag1'], category='meta'))
+ test_ctx.session.add(
+ test_ctx.tag_factory(names=['tag1'], category_name='meta'))
test_ctx.session.commit()
with pytest.raises(tags.InvalidNameError):
test_ctx.api.put(
@@ -133,8 +137,8 @@ def test_trying_to_set_invalid_name(test_ctx, input):
@pytest.mark.parametrize('dup_name', ['tag1', 'TAG1', 'tag2', 'TAG2'])
def test_trying_to_use_existing_name(test_ctx, dup_name):
test_ctx.session.add_all([
- test_ctx.tag_factory(names=['tag1', 'tag2'], category='meta'),
- test_ctx.tag_factory(names=['tag3', 'tag4'], category='meta')])
+ test_ctx.tag_factory(names=['tag1', 'tag2'], category_name='meta'),
+ test_ctx.tag_factory(names=['tag3', 'tag4'], category_name='meta')])
test_ctx.session.commit()
with pytest.raises(tags.TagAlreadyExistsError):
test_ctx.api.put(
@@ -144,7 +148,8 @@ def test_trying_to_use_existing_name(test_ctx, dup_name):
'tag3')
def test_trying_to_update_tag_with_invalid_category(test_ctx):
- test_ctx.session.add(test_ctx.tag_factory(names=['tag1'], category='meta'))
+ test_ctx.session.add(
+ test_ctx.tag_factory(names=['tag1'], category_name='meta'))
test_ctx.session.commit()
with pytest.raises(tags.InvalidCategoryError):
test_ctx.api.put(
@@ -182,7 +187,8 @@ def test_trying_to_update_tag_with_invalid_category(test_ctx):
])
def test_updating_new_suggestions_and_implications(
test_ctx, input, expected_suggestions, expected_implications):
- test_ctx.session.add(test_ctx.tag_factory(names=['main'], category='meta'))
+ test_ctx.session.add(
+ test_ctx.tag_factory(names=['main'], category_name='meta'))
test_ctx.session.commit()
result = test_ctx.api.put(
test_ctx.context_factory(
@@ -198,9 +204,9 @@ def test_updating_new_suggestions_and_implications(
def test_reusing_suggestions_and_implications(test_ctx):
test_ctx.session.add_all([
- test_ctx.tag_factory(names=['tag1', 'tag2'], category='meta'),
- test_ctx.tag_factory(names=['tag3'], category='meta'),
- test_ctx.tag_factory(names=['tag4'], category='meta'),
+ test_ctx.tag_factory(names=['tag1', 'tag2'], category_name='meta'),
+ test_ctx.tag_factory(names=['tag3'], category_name='meta'),
+ test_ctx.tag_factory(names=['tag4'], category_name='meta'),
])
test_ctx.session.commit()
result = test_ctx.api.put(
@@ -225,7 +231,8 @@ def test_reusing_suggestions_and_implications(test_ctx):
{'names': ['ok'], 'implications': ['ok2', '!']},
])
def test_trying_to_update_tag_with_invalid_relation(test_ctx, input):
- test_ctx.session.add(test_ctx.tag_factory(names=['tag'], category='meta'))
+ test_ctx.session.add(
+ test_ctx.tag_factory(names=['tag'], category_name='meta'))
test_ctx.session.commit()
with pytest.raises(tags.InvalidNameError):
test_ctx.api.put(
@@ -253,7 +260,8 @@ def test_trying_to_update_tag_with_invalid_relation(test_ctx, input):
}
])
def test_tag_trying_to_relate_to_itself(test_ctx, input):
- test_ctx.session.add(test_ctx.tag_factory(names=['tag1'], category='meta'))
+ test_ctx.session.add(
+ test_ctx.tag_factory(names=['tag1'], category_name='meta'))
test_ctx.session.commit()
with pytest.raises(tags.RelationError):
test_ctx.api.put(
@@ -268,7 +276,8 @@ def test_tag_trying_to_relate_to_itself(test_ctx, input):
{'implications': ['whatever']},
])
def test_trying_to_update_tag_without_privileges(test_ctx, input):
- test_ctx.session.add(test_ctx.tag_factory(names=['tag'], category='meta'))
+ test_ctx.session.add(
+ test_ctx.tag_factory(names=['tag'], category_name='meta'))
test_ctx.session.commit()
with pytest.raises(errors.AuthError):
test_ctx.api.put(
diff --git a/server/szurubooru/tests/api/test_user_deleting.py b/server/szurubooru/tests/api/test_user_deleting.py
index 663c9b5..0cdfd21 100644
--- a/server/szurubooru/tests/api/test_user_deleting.py
+++ b/server/szurubooru/tests/api/test_user_deleting.py
@@ -19,7 +19,7 @@ def test_ctx(session, config_injector, context_factory, user_factory):
ret.api = api.UserDetailApi()
return ret
-def test_removing_oneself(test_ctx):
+def test_deleting_oneself(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='regular_user')
user2 = test_ctx.user_factory(name='u2', rank='regular_user')
test_ctx.session.add_all([user1, user2])
@@ -30,7 +30,7 @@ def test_removing_oneself(test_ctx):
assert result == {}
assert [u.name for u in test_ctx.session.query(db.User).all()] == ['u2']
-def test_removing_someone_else(test_ctx):
+def test_deleting_someone_else(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='regular_user')
user2 = test_ctx.user_factory(name='u2', rank='regular_user')
mod_user = test_ctx.user_factory(rank='mod')
@@ -40,7 +40,7 @@ def test_removing_someone_else(test_ctx):
test_ctx.api.delete(test_ctx.context_factory(user=mod_user), 'u2')
assert test_ctx.session.query(db.User).all() == []
-def test_removing_non_existing(test_ctx):
+def test_deleting_non_existing(test_ctx):
with pytest.raises(users.UserNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
diff --git a/server/szurubooru/tests/conftest.py b/server/szurubooru/tests/conftest.py
index 48f9a02..d964bbe 100644
--- a/server/szurubooru/tests/conftest.py
+++ b/server/szurubooru/tests/conftest.py
@@ -66,8 +66,10 @@ def user_factory():
return factory
@pytest.fixture
-def tag_factory():
- def factory(names=None, category='dummy'):
+def tag_factory(session):
+ def factory(names=None, category_name='dummy'):
+ category = db.TagCategory(category_name)
+ session.add(category)
tag = db.Tag()
tag.names = [db.TagName(name) for name in (names or [get_unique_name()])]
tag.category = category
diff --git a/server/szurubooru/tests/db/test_tag.py b/server/szurubooru/tests/db/test_tag.py
index dfbafba..dd67f65 100644
--- a/server/szurubooru/tests/db/test_tag.py
+++ b/server/szurubooru/tests/db/test_tag.py
@@ -2,30 +2,29 @@ from datetime import datetime
from szurubooru import db
def test_saving_tag(session, tag_factory):
- suggested_tag1 = tag_factory(names=['suggested1'])
- suggested_tag2 = tag_factory(names=['suggested2'])
- implied_tag1 = tag_factory(names=['implied1'])
- implied_tag2 = tag_factory(names=['implied2'])
+ sug1 = tag_factory(names=['sug1'])
+ sug2 = tag_factory(names=['sug2'])
+ imp1 = tag_factory(names=['imp1'])
+ imp2 = tag_factory(names=['imp2'])
tag = db.Tag()
tag.names = [db.TagName('alias1'), db.TagName('alias2')]
tag.suggestions = []
tag.implications = []
- tag.category = 'category'
+ tag.category = db.TagCategory('category')
tag.creation_time = datetime(1997, 1, 1)
tag.last_edit_time = datetime(1998, 1, 1)
- session.add_all([
- tag, suggested_tag1, suggested_tag2, implied_tag1, implied_tag2])
+ session.add_all([tag, sug1, sug2, imp1, imp2])
session.commit()
assert tag.tag_id is not None
- assert suggested_tag1.tag_id is not None
- assert suggested_tag2.tag_id is not None
- assert implied_tag1.tag_id is not None
- assert implied_tag2.tag_id is not None
- tag.suggestions.append(suggested_tag1)
- tag.suggestions.append(suggested_tag2)
- tag.implications.append(implied_tag1)
- tag.implications.append(implied_tag2)
+ assert sug1.tag_id is not None
+ assert sug2.tag_id is not None
+ assert imp1.tag_id is not None
+ assert imp2.tag_id is not None
+ tag.suggestions.append(sug1)
+ tag.suggestions.append(sug2)
+ tag.implications.append(imp1)
+ tag.implications.append(imp2)
session.commit()
tag = session.query(db.Tag) \
@@ -33,40 +32,39 @@ def test_saving_tag(session, tag_factory):
.filter(db.TagName.name=='alias1') \
.one()
assert [tag_name.name for tag_name in tag.names] == ['alias1', 'alias2']
- assert tag.category == 'category'
+ assert tag.category.name == 'category'
assert tag.creation_time == datetime(1997, 1, 1)
assert tag.last_edit_time == datetime(1998, 1, 1)
assert [relation.names[0].name for relation in tag.suggestions] \
- == ['suggested1', 'suggested2']
+ == ['sug1', 'sug2']
assert [relation.names[0].name for relation in tag.implications] \
- == ['implied1', 'implied2']
+ == ['imp1', 'imp2']
def test_cascade_deletions(session, tag_factory):
- suggested_tag1 = tag_factory(names=['suggested1'])
- suggested_tag2 = tag_factory(names=['suggested2'])
- implied_tag1 = tag_factory(names=['implied1'])
- implied_tag2 = tag_factory(names=['implied2'])
+ sug1 = tag_factory(names=['sug1'])
+ sug2 = tag_factory(names=['sug2'])
+ imp1 = tag_factory(names=['imp1'])
+ imp2 = tag_factory(names=['imp2'])
tag = db.Tag()
tag.names = [db.TagName('alias1'), db.TagName('alias2')]
tag.suggestions = []
tag.implications = []
- tag.category = 'category'
+ tag.category = db.TagCategory('category')
tag.creation_time = datetime(1997, 1, 1)
tag.last_edit_time = datetime(1998, 1, 1)
tag.post_count = 1
- session.add_all([
- tag, suggested_tag1, suggested_tag2, implied_tag1, implied_tag2])
+ session.add_all([tag, sug1, sug2, imp1, imp2])
session.commit()
assert tag.tag_id is not None
- assert suggested_tag1.tag_id is not None
- assert suggested_tag2.tag_id is not None
- assert implied_tag1.tag_id is not None
- assert implied_tag2.tag_id is not None
- tag.suggestions.append(suggested_tag1)
- tag.suggestions.append(suggested_tag2)
- tag.implications.append(implied_tag1)
- tag.implications.append(implied_tag2)
+ assert sug1.tag_id is not None
+ assert sug2.tag_id is not None
+ assert imp1.tag_id is not None
+ assert imp2.tag_id is not None
+ tag.suggestions.append(sug1)
+ tag.suggestions.append(sug2)
+ tag.implications.append(imp1)
+ tag.implications.append(imp2)
session.commit()
session.delete(tag)
diff --git a/server/szurubooru/tests/util/test_snapshots.py b/server/szurubooru/tests/util/test_snapshots.py
index 036d46a..431a87a 100644
--- a/server/szurubooru/tests/util/test_snapshots.py
+++ b/server/szurubooru/tests/util/test_snapshots.py
@@ -4,13 +4,13 @@ from szurubooru import db
from szurubooru.util import snapshots
def test_serializing_tag(session, tag_factory):
- tag = tag_factory(names=['main_name', 'alias'], category='dummy')
+ tag = tag_factory(names=['main_name', 'alias'], category_name='dummy')
assert snapshots.get_tag_snapshot(tag) == {
'names': ['main_name', 'alias'],
'category': 'dummy'
}
- tag = tag_factory(names=['main_name', 'alias'], category='dummy')
+ tag = tag_factory(names=['main_name', 'alias'], category_name='dummy')
imp1 = tag_factory(names=['imp1_main_name', 'imp1_alias'])
imp2 = tag_factory(names=['imp2_main_name', 'imp2_alias'])
sug1 = tag_factory(names=['sug1_main_name', 'sug1_alias'])
@@ -27,7 +27,7 @@ def test_serializing_tag(session, tag_factory):
}
def test_merging_modification_to_creation(session, tag_factory, user_factory):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user = user_factory()
session.add_all([tag, user])
session.flush()
@@ -43,7 +43,7 @@ def test_merging_modification_to_creation(session, tag_factory, user_factory):
def test_merging_modifications(
fake_datetime, session, tag_factory, user_factory):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user = user_factory()
session.add_all([tag, user])
session.flush()
@@ -67,7 +67,7 @@ def test_merging_modifications(
def test_not_adding_snapshot_if_data_doesnt_change(
fake_datetime, session, tag_factory, user_factory):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user = user_factory()
session.add_all([tag, user])
session.flush()
@@ -84,7 +84,7 @@ def test_not_adding_snapshot_if_data_doesnt_change(
def test_not_merging_due_to_time_difference(
fake_datetime, session, tag_factory, user_factory):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user = user_factory()
session.add_all([tag, user])
session.flush()
@@ -99,7 +99,7 @@ def test_not_merging_due_to_time_difference(
def test_not_merging_operations_by_different_users(
fake_datetime, session, tag_factory, user_factory):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user1, user2 = [user_factory(), user_factory()]
session.add_all([tag, user1, user2])
session.flush()
@@ -113,7 +113,7 @@ def test_not_merging_operations_by_different_users(
def test_merging_resets_merging_time_window(
fake_datetime, session, tag_factory, user_factory):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user = user_factory()
session.add_all([tag, user])
session.flush()
@@ -136,7 +136,7 @@ def test_merging_resets_merging_time_window(
'initial_operation', [snapshots.create, snapshots.modify])
def test_merging_deletion_to_modification_or_creation(
fake_datetime, session, tag_factory, user_factory, initial_operation):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'], category_name='dummy')
user = user_factory()
session.add_all([tag, user])
session.flush()
@@ -162,7 +162,7 @@ def test_merging_deletion_to_modification_or_creation(
'expected_operation', [snapshots.create, snapshots.modify])
def test_merging_deletion_all_the_way_deletes_all_snapshots(
fake_datetime, session, tag_factory, user_factory, expected_operation):
- tag = tag_factory(names=['dummy'], category='dummy')
+ tag = tag_factory(names=['dummy'])
user = user_factory()
session.add_all([tag, user])
session.flush()
diff --git a/server/szurubooru/util/snapshots.py b/server/szurubooru/util/snapshots.py
index e5eaecf..f9ae2d6 100644
--- a/server/szurubooru/util/snapshots.py
+++ b/server/szurubooru/util/snapshots.py
@@ -5,7 +5,7 @@ from szurubooru import db
def get_tag_snapshot(tag):
ret = {
'names': [tag_name.name for tag_name in tag.names],
- 'category': tag.category
+ 'category': tag.category.name
}
if tag.suggestions:
ret['suggestions'] = sorted(rel.first_name for rel in tag.suggestions)
diff --git a/server/szurubooru/util/tags.py b/server/szurubooru/util/tags.py
index 7fa5126..cf4a2fe 100644
--- a/server/szurubooru/util/tags.py
+++ b/server/szurubooru/util/tags.py
@@ -45,13 +45,19 @@ def export_to_json(session):
with open(export_path, 'w') as handle:
handle.write(json.dumps(output, separators=(',', ':')))
-def get_by_name(session, name):
+def get_tag_by_name(session, name):
return session.query(db.Tag) \
.join(db.TagName) \
.filter(db.TagName.name.ilike(name)) \
.first()
-def get_by_names(session, names):
+def get_default_category(session):
+ return session.query(db.TagCategory) \
+ .order_by(db.TagCategory.tag_category_id.asc()) \
+ .limit(1) \
+ .one()
+
+def get_tags_by_names(session, names):
names = misc.icase_unique(names)
if len(names) == 0:
return []
@@ -60,11 +66,11 @@ def get_by_names(session, names):
expr = expr | db.TagName.name.ilike(name)
return session.query(db.Tag).join(db.TagName).filter(expr).all()
-def get_or_create_by_names(session, names):
+def get_or_create_tags_by_names(session, names):
names = misc.icase_unique(names)
for name in names:
_verify_name_validity(name)
- related_tags = get_by_names(session, names)
+ related_tags = get_tags_by_names(session, names)
new_tags = []
for name in names:
found = False
@@ -76,27 +82,32 @@ def get_or_create_by_names(session, names):
new_tag = create_tag(
session,
names=[name],
- category=config.config['tag_categories'][0],
+ category_name=get_default_category(session).name,
suggestions=[],
implications=[])
session.add(new_tag)
new_tags.append(new_tag)
return related_tags, new_tags
-def create_tag(session, names, category, suggestions, implications):
+def create_tag(session, names, category_name, suggestions, implications):
tag = db.Tag()
tag.creation_time = datetime.datetime.now()
update_names(session, tag, names)
- update_category(tag, category)
+ update_category_name(session, tag, category_name)
update_suggestions(session, tag, suggestions)
update_implications(session, tag, implications)
return tag
-def update_category(tag, category):
- if not category in config.config['tag_categories']:
+def update_category_name(session, tag, category_name):
+ category = session.query(db.TagCategory) \
+ .filter(db.TagCategory.name == category_name) \
+ .first()
+ if not category:
+ category_names = [
+ name[0] for name in session.query(db.TagCategory.name).all()]
raise InvalidCategoryError(
'Category %r is invalid. Valid categories: %r.' % (
- category, config.config['tag_categories']))
+ category_name, category_names))
tag.category = category
def update_names(session, tag, names):
@@ -129,13 +140,13 @@ def update_names(session, tag, names):
def update_implications(session, tag, relations):
if _check_name_intersection(_get_plain_names(tag), relations):
raise RelationError('Tag cannot imply itself.')
- related_tags, new_tags = get_or_create_by_names(session, relations)
+ related_tags, new_tags = get_or_create_tags_by_names(session, relations)
session.flush()
tag.implications = related_tags + new_tags
def update_suggestions(session, tag, relations):
if _check_name_intersection(_get_plain_names(tag), relations):
raise RelationError('Tag cannot suggest itself.')
- related_tags, new_tags = get_or_create_by_names(session, relations)
+ related_tags, new_tags = get_or_create_tags_by_names(session, relations)
session.flush()
tag.suggestions = related_tags + new_tags
diff --git a/server/szurubooru/util/users.py b/server/szurubooru/util/users.py
index 6ae457a..a921ff6 100644
--- a/server/szurubooru/util/users.py
+++ b/server/szurubooru/util/users.py
@@ -12,12 +12,12 @@ class InvalidPasswordError(errors.ValidationError): pass
class InvalidRankError(errors.ValidationError): pass
class InvalidAvatarError(errors.ValidationError): pass
-def get_by_name(session, name):
+def get_user_by_name(session, name):
return session.query(db.User) \
.filter(func.lower(db.User.name) == func.lower(name)) \
.first()
-def get_by_name_or_email(session, name_or_email):
+def get_user_by_name_or_email(session, name_or_email):
return session.query(db.User) \
.filter(
(func.lower(db.User.name) == func.lower(name_or_email))
@@ -40,7 +40,7 @@ def create_user(session, name, password, email, auth_user):
def update_name(session, user, name, auth_user):
if misc.value_exceeds_column_size(name, db.User.name):
raise InvalidNameError('User name is too long.')
- other_user = get_by_name(session, name)
+ other_user = get_user_by_name(session, name)
if other_user and other_user.user_id != auth_user.user_id:
raise UserAlreadyExistsError('User %r already exists.' % name)
name = name.strip()

© 2015 - 2026 Jakob L. Kreuze