def post(self, ctx): auth.verify_privilege(ctx.user, 'posts:create') content = ctx.get_file('content', required=True) tag_names = ctx.get_param_as_list('tags', required=True) safety = ctx.get_param_as_string('safety', required=True) source = ctx.get_param_as_string('source', required=False, default=None) if ctx.has_param('contentUrl') and not source: source = ctx.get_param_as_string('contentUrl') relations = ctx.get_param_as_list('relations', required=False) or [] notes = ctx.get_param_as_list('notes', required=False) or [] flags = ctx.get_param_as_list('flags', required=False) or [] post = posts.create_post(content, tag_names, ctx.user) posts.update_post_safety(post, safety) posts.update_post_source(post, source) posts.update_post_relations(post, relations) posts.update_post_notes(post, notes) posts.update_post_flags(post, flags) if ctx.has_file('thumbnail'): posts.update_post_thumbnail(post, ctx.get_file('thumbnail')) ctx.session.add(post) snapshots.save_entity_creation(post, ctx.user) ctx.session.commit() tags.export_to_json() return posts.serialize_post_with_details(post, ctx.user)
def put(self, ctx, post_id): post = posts.get_post_by_id(post_id) if ctx.has_file('content'): auth.verify_privilege(ctx.user, 'posts:edit:content') posts.update_post_content(post, ctx.get_file('content')) if ctx.has_param('tags'): auth.verify_privilege(ctx.user, 'posts:edit:tags') posts.update_post_tags(post, ctx.get_param_as_list('tags')) if ctx.has_param('safety'): auth.verify_privilege(ctx.user, 'posts:edit:safety') posts.update_post_safety(post, ctx.get_param_as_string('safety')) if ctx.has_param('source'): auth.verify_privilege(ctx.user, 'posts:edit:source') posts.update_post_source(post, ctx.get_param_as_string('source')) elif ctx.has_param('contentUrl'): posts.update_post_source(post, ctx.get_param_as_string('contentUrl')) if ctx.has_param('relations'): auth.verify_privilege(ctx.user, 'posts:edit:relations') posts.update_post_relations(post, ctx.get_param_as_list('relations')) if ctx.has_param('notes'): auth.verify_privilege(ctx.user, 'posts:edit:notes') posts.update_post_notes(post, ctx.get_param_as_list('notes')) if ctx.has_param('flags'): auth.verify_privilege(ctx.user, 'posts:edit:flags') posts.update_post_flags(post, ctx.get_param_as_list('flags')) if ctx.has_file('thumbnail'): auth.verify_privilege(ctx.user, 'posts:edit:thumbnail') posts.update_post_thumbnail(post, ctx.get_file('thumbnail')) post.last_edit_time = datetime.datetime.now() ctx.session.flush() snapshots.save_entity_modification(post, ctx.user) ctx.session.commit() tags.export_to_json() return posts.serialize_post_with_details(post, ctx.user)
def update_tag(ctx: rest.Context, params: Dict[str, str]) -> rest.Response: tag = _get_tag(params) versions.verify_version(tag, ctx) versions.bump_version(tag) if ctx.has_param('names'): auth.verify_privilege(ctx.user, 'tags:edit:names') tags.update_tag_names(tag, ctx.get_param_as_string_list('names')) if ctx.has_param('category'): auth.verify_privilege(ctx.user, 'tags:edit:category') tags.update_tag_category_name(tag, ctx.get_param_as_string('category')) if ctx.has_param('description'): auth.verify_privilege(ctx.user, 'tags:edit:description') tags.update_tag_description(tag, ctx.get_param_as_string('description')) if ctx.has_param('suggestions'): auth.verify_privilege(ctx.user, 'tags:edit:suggestions') suggestions = ctx.get_param_as_string_list('suggestions') _create_if_needed(suggestions, ctx.user) tags.update_tag_suggestions(tag, suggestions) if ctx.has_param('implications'): auth.verify_privilege(ctx.user, 'tags:edit:implications') implications = ctx.get_param_as_string_list('implications') _create_if_needed(implications, ctx.user) tags.update_tag_implications(tag, implications) tag.last_edit_time = datetime.utcnow() ctx.session.flush() snapshots.modify(tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, tag)
def create_post(ctx, _params=None): anonymous = ctx.get_param_as_bool('anonymous', default=False) if anonymous: auth.verify_privilege(ctx.user, 'posts:create:anonymous') else: auth.verify_privilege(ctx.user, 'posts:create:identified') content = ctx.get_file('content', required=True) tag_names = ctx.get_param_as_list('tags', required=False, default=[]) safety = ctx.get_param_as_string('safety', required=True) source = ctx.get_param_as_string('source', required=False, default=None) if ctx.has_param('contentUrl') and not source: source = ctx.get_param_as_string('contentUrl') relations = ctx.get_param_as_list('relations', required=False) or [] notes = ctx.get_param_as_list('notes', required=False) or [] flags = ctx.get_param_as_list('flags', required=False) or [] post, new_tags = posts.create_post( content, tag_names, None if anonymous else ctx.user) if len(new_tags): auth.verify_privilege(ctx.user, 'tags:create') posts.update_post_safety(post, safety) posts.update_post_source(post, source) posts.update_post_relations(post, relations) posts.update_post_notes(post, notes) posts.update_post_flags(post, flags) if ctx.has_file('thumbnail'): posts.update_post_thumbnail(post, ctx.get_file('thumbnail')) ctx.session.add(post) ctx.session.flush() snapshots.create(post, None if anonymous else ctx.user) for tag in new_tags: snapshots.create(tag, None if anonymous else ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_post(ctx, post)
def put(self, ctx, tag_name): tag = tags.get_tag_by_name(tag_name) if not tag: raise tags.TagNotFoundError('Tag %r not found.' % tag_name) if ctx.has_param('names'): auth.verify_privilege(ctx.user, 'tags:edit:names') tags.update_names(tag, ctx.get_param_as_list('names')) if ctx.has_param('category'): auth.verify_privilege(ctx.user, 'tags:edit:category') tags.update_category_name(tag, ctx.get_param_as_string('category')) if ctx.has_param('suggestions'): auth.verify_privilege(ctx.user, 'tags:edit:suggestions') tags.update_suggestions(tag, ctx.get_param_as_list('suggestions')) if ctx.has_param('implications'): auth.verify_privilege(ctx.user, 'tags:edit:implications') tags.update_implications(tag, ctx.get_param_as_list('implications')) tag.last_edit_time = datetime.datetime.now() snapshots.modify(tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_tag_with_details(tag)
def update_tag(ctx, params): tag = tags.get_tag_by_name(params['tag_name']) versions.verify_version(tag, ctx) versions.bump_version(tag) if ctx.has_param('names'): auth.verify_privilege(ctx.user, 'tags:edit:names') tags.update_tag_names(tag, ctx.get_param_as_list('names')) if ctx.has_param('category'): auth.verify_privilege(ctx.user, 'tags:edit:category') tags.update_tag_category_name( tag, ctx.get_param_as_string('category')) if ctx.has_param('description'): auth.verify_privilege(ctx.user, 'tags:edit:description') tags.update_tag_description( tag, ctx.get_param_as_string('description', default=None)) if ctx.has_param('suggestions'): auth.verify_privilege(ctx.user, 'tags:edit:suggestions') suggestions = ctx.get_param_as_list('suggestions') _create_if_needed(suggestions, ctx.user) tags.update_tag_suggestions(tag, suggestions) if ctx.has_param('implications'): auth.verify_privilege(ctx.user, 'tags:edit:implications') implications = ctx.get_param_as_list('implications') _create_if_needed(implications, ctx.user) tags.update_tag_implications(tag, implications) tag.last_edit_time = datetime.datetime.utcnow() ctx.session.flush() snapshots.modify(tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, tag)
def delete(self, ctx, post_id): auth.verify_privilege(ctx.user, 'posts:delete') post = posts.get_post_by_id(post_id) snapshots.save_entity_deletion(post, ctx.user) ctx.session.delete(post) ctx.session.commit() tags.export_to_json() return {}
def delete_tag(ctx: rest.Context, params: Dict[str, str]) -> rest.Response: tag = _get_tag(params) versions.verify_version(tag, ctx) auth.verify_privilege(ctx.user, 'tags:delete') snapshots.delete(tag, ctx.user) tags.delete(tag) ctx.session.commit() tags.export_to_json() return {}
def delete_post(ctx, params): auth.verify_privilege(ctx.user, 'posts:delete') post = posts.get_post_by_id(params['post_id']) versions.verify_version(post, ctx) snapshots.delete(post, ctx.user) posts.delete(post) ctx.session.commit() tags.export_to_json() return {}
def delete_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response: auth.verify_privilege(ctx.user, 'posts:delete') post = _get_post(params) versions.verify_version(post, ctx) snapshots.delete(post, ctx.user) posts.delete(post) ctx.session.commit() tags.export_to_json() return {}
def delete_tag(ctx, params): tag = tags.get_tag_by_name(params['tag_name']) versions.verify_version(tag, ctx) auth.verify_privilege(ctx.user, 'tags:delete') snapshots.delete(tag, ctx.user) tags.delete(tag) ctx.session.commit() tags.export_to_json() return {}
def set_tag_category_as_default(ctx, params): auth.verify_privilege(ctx.user, 'tag_categories:set_default') category = tag_categories.get_category_by_name( params['category_name'], lock=True) tag_categories.set_default_category(category) ctx.session.flush() snapshots.modify(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, category)
def delete_tag_category(ctx, params): category = tag_categories.get_category_by_name( params['category_name'], lock=True) versions.verify_version(category, ctx) auth.verify_privilege(ctx.user, 'tag_categories:delete') tag_categories.delete_category(category) snapshots.delete(category, ctx.user) ctx.session.commit() tags.export_to_json() return {}
def test_export_to_json( tmpdir, query_counter, config_injector, post_factory, tag_factory, tag_category_factory): config_injector({'data_dir': str(tmpdir)}) cat1 = tag_category_factory(name='cat1', color='black') cat2 = tag_category_factory(name='cat2', color='white') tag = tag_factory(names=['alias1', 'alias2'], category=cat2) tag.suggestions = [ tag_factory(names=['sug1'], category=cat1), tag_factory(names=['sug2'], category=cat1), ] tag.implications = [ tag_factory(names=['imp1'], category=cat1), tag_factory(names=['imp2'], category=cat1), ] post = post_factory() post.tags = [tag] db.session.add_all([post, tag]) db.session.flush() with query_counter: tags.export_to_json() assert len(query_counter.statements) == 5 export_path = os.path.join(str(tmpdir), 'tags.json') assert os.path.exists(export_path) with open(export_path, 'r') as handle: actual_json = json.loads(handle.read()) assert actual_json['tags'] assert actual_json['categories'] actual_json['tags'].sort(key=lambda tag: tag['names'][0]) actual_json['categories'].sort(key=lambda category: category['name']) assert actual_json == { 'tags': [ { 'names': ['alias1', 'alias2'], 'usages': 1, 'category': 'cat2', 'suggestions': ['sug1', 'sug2'], 'implications': ['imp1', 'imp2'], }, {'names': ['imp1'], 'usages': 0, 'category': 'cat1'}, {'names': ['imp2'], 'usages': 0, 'category': 'cat1'}, {'names': ['sug1'], 'usages': 0, 'category': 'cat1'}, {'names': ['sug2'], 'usages': 0, 'category': 'cat1'}, ], 'categories': [ {'name': 'cat1', 'color': 'black'}, {'name': 'cat2', 'color': 'white'}, ] }
def test_export( tmpdir, query_counter, config_injector, tag_factory, tag_category_factory): config_injector({ 'data_dir': str(tmpdir) }) cat1 = tag_category_factory(name='cat1', color='black') cat2 = tag_category_factory(name='cat2', color='white') db.session.add_all([cat1, cat2]) db.session.flush() sug1 = tag_factory(names=['sug1'], category=cat1) sug2 = tag_factory(names=['sug2'], category=cat1) imp1 = tag_factory(names=['imp1'], category=cat1) imp2 = tag_factory(names=['imp2'], category=cat1) tag = tag_factory(names=['alias1', 'alias2'], category=cat2) tag.post_count = 1 db.session.add_all([tag, sug1, sug2, imp1, imp2, cat1, cat2]) db.session.flush() db.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), ]) db.session.flush() with query_counter: tags.export_to_json() assert len(query_counter.statements) == 2 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()) == { 'tags': [ { 'names': ['alias1', 'alias2'], 'usages': 1, 'category': 'cat2', 'suggestions': ['sug1', 'sug2'], 'implications': ['imp1', 'imp2'], }, {'names': ['sug1'], 'usages': 0, 'category': 'cat1'}, {'names': ['sug2'], 'usages': 0, 'category': 'cat1'}, {'names': ['imp1'], 'usages': 0, 'category': 'cat1'}, {'names': ['imp2'], 'usages': 0, 'category': 'cat1'}, ], 'categories': [ {'name': 'cat1', 'color': 'black'}, {'name': 'cat2', 'color': 'white'}, ] }
def post(self, ctx): auth.verify_privilege(ctx.user, 'tag_categories:create') name = ctx.get_param_as_string('name', required=True) color = ctx.get_param_as_string('color', required=True) category = tag_categories.create_category(name, color) ctx.session.add(category) ctx.session.flush() snapshots.save_entity_creation(category, ctx.user) ctx.session.commit() tags.export_to_json() return tag_categories.serialize_category_with_details(category)
def set_tag_category_as_default( ctx: rest.Context, params: Dict[str, str]) -> rest.Response: auth.verify_privilege(ctx.user, 'tag_categories:set_default') category = tag_categories.get_category_by_name( params['category_name'], lock=True) tag_categories.set_default_category(category) ctx.session.flush() snapshots.modify(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, category)
def delete_tag_category( ctx: rest.Context, params: Dict[str, str]) -> rest.Response: category = tag_categories.get_category_by_name( params['category_name'], lock=True) versions.verify_version(category, ctx) auth.verify_privilege(ctx.user, 'tag_categories:delete') tag_categories.delete_category(category) snapshots.delete(category, ctx.user) ctx.session.commit() tags.export_to_json() return {}
def post(self, ctx): auth.verify_privilege(ctx.user, 'tag_categories:create') name = ctx.get_param_as_string('name', required=True) color = ctx.get_param_as_string('color', required=True) category = tag_categories.create_category(name, color) ctx.session.add(category) ctx.session.flush() snapshots.create(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_category_with_details(category)
def delete(self, ctx, tag_name): tag = tags.get_tag_by_name(tag_name) if tag.post_count > 0: raise tags.TagIsInUseError( 'Tag has some usages and cannot be deleted. ' + 'Please untag relevant posts first.') auth.verify_privilege(ctx.user, 'tags:delete') snapshots.save_entity_deletion(tag, ctx.user) tags.delete(tag) ctx.session.commit() tags.export_to_json() return {}
def create_tag_category( ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response: auth.verify_privilege(ctx.user, 'tag_categories:create') name = ctx.get_param_as_string('name') color = ctx.get_param_as_string('color') category = tag_categories.create_category(name, color) ctx.session.add(category) ctx.session.flush() snapshots.create(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, category)
def post(self, ctx): source_tag_name = ctx.get_param_as_string('remove', required=True) or '' target_tag_name = ctx.get_param_as_string('mergeTo', required=True) or '' source_tag = tags.get_tag_by_name(source_tag_name) target_tag = tags.get_tag_by_name(target_tag_name) if source_tag.tag_id == target_tag.tag_id: raise tags.InvalidTagRelationError('Cannot merge tag with itself.') auth.verify_privilege(ctx.user, 'tags:merge') snapshots.save_entity_deletion(source_tag, ctx.user) tags.merge_tags(source_tag, target_tag) ctx.session.commit() tags.export_to_json() return tags.serialize_tag_with_details(target_tag)
def merge_tags(ctx, _params=None): source_tag_name = ctx.get_param_as_string('remove', required=True) or '' target_tag_name = ctx.get_param_as_string('mergeTo', required=True) or '' source_tag = tags.get_tag_by_name(source_tag_name) target_tag = tags.get_tag_by_name(target_tag_name) versions.verify_version(source_tag, ctx, 'removeVersion') versions.verify_version(target_tag, ctx, 'mergeToVersion') versions.bump_version(target_tag) auth.verify_privilege(ctx.user, 'tags:merge') tags.merge_tags(source_tag, target_tag) snapshots.merge(source_tag, target_tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, target_tag)
def delete(self, ctx, category_name): category = tag_categories.get_category_by_name(category_name) auth.verify_privilege(ctx.user, 'tag_categories:delete') if len(tag_categories.get_all_category_names()) == 1: raise tag_categories.TagCategoryIsInUseError( 'Cannot delete the default category.') if category.tag_count > 0: raise tag_categories.TagCategoryIsInUseError( 'Tag category has some usages and cannot be deleted. ' + 'Please remove this category from relevant tags first..') snapshots.save_entity_deletion(category, ctx.user) ctx.session.delete(category) ctx.session.commit() tags.export_to_json() return {}
def put(self, ctx, category_name): category = tag_categories.get_category_by_name(category_name) if ctx.has_param('name'): auth.verify_privilege(ctx.user, 'tag_categories:edit:name') tag_categories.update_category_name( category, ctx.get_param_as_string('name')) if ctx.has_param('color'): auth.verify_privilege(ctx.user, 'tag_categories:edit:color') tag_categories.update_category_color( category, ctx.get_param_as_string('color')) ctx.session.flush() snapshots.save_entity_modification(category, ctx.user) ctx.session.commit() tags.export_to_json() return tag_categories.serialize_category_with_details(category)
def merge_tags(ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response: source_tag_name = ctx.get_param_as_string('remove') target_tag_name = ctx.get_param_as_string('mergeTo') source_tag = tags.get_tag_by_name(source_tag_name) target_tag = tags.get_tag_by_name(target_tag_name) versions.verify_version(source_tag, ctx, 'removeVersion') versions.verify_version(target_tag, ctx, 'mergeToVersion') versions.bump_version(target_tag) auth.verify_privilege(ctx.user, 'tags:merge') tags.merge_tags(source_tag, target_tag) snapshots.merge(source_tag, target_tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, target_tag)
def post(self, ctx): auth.verify_privilege(ctx.user, 'tags:create') names = ctx.get_param_as_list('names', required=True) category = ctx.get_param_as_string('category', required=True) suggestions = ctx.get_param_as_list( 'suggestions', required=False, default=[]) implications = ctx.get_param_as_list( 'implications', required=False, default=[]) tag = tags.create_tag(names, category, suggestions, implications) ctx.session.add(tag) ctx.session.flush() snapshots.create(tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_tag_with_details(tag)
def put(self, ctx, category_name): category = tag_categories.get_category_by_name(category_name) if not category: raise tag_categories.TagCategoryNotFoundError( 'Tag category %r not found.' % category_name) if ctx.has_param('name'): auth.verify_privilege(ctx.user, 'tag_categories:edit:name') tag_categories.update_name( category, ctx.get_param_as_string('name')) if ctx.has_param('color'): auth.verify_privilege(ctx.user, 'tag_categories:edit:color') tag_categories.update_color( category, ctx.get_param_as_string('color')) snapshots.modify(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_category_with_details(category)
def update_tag_category(ctx, params): category = tag_categories.get_category_by_name( params['category_name'], lock=True) versions.verify_version(category, ctx) versions.bump_version(category) if ctx.has_param('name'): auth.verify_privilege(ctx.user, 'tag_categories:edit:name') tag_categories.update_category_name( category, ctx.get_param_as_string('name')) if ctx.has_param('color'): auth.verify_privilege(ctx.user, 'tag_categories:edit:color') tag_categories.update_category_color( category, ctx.get_param_as_string('color')) ctx.session.flush() snapshots.modify(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, category)
def update_tag_category( ctx: rest.Context, params: Dict[str, str]) -> rest.Response: category = tag_categories.get_category_by_name( params['category_name'], lock=True) versions.verify_version(category, ctx) versions.bump_version(category) if ctx.has_param('name'): auth.verify_privilege(ctx.user, 'tag_categories:edit:name') tag_categories.update_category_name( category, ctx.get_param_as_string('name')) if ctx.has_param('color'): auth.verify_privilege(ctx.user, 'tag_categories:edit:color') tag_categories.update_category_color( category, ctx.get_param_as_string('color')) ctx.session.flush() snapshots.modify(category, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, category)
def update_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response: post = _get_post(params) versions.verify_version(post, ctx) versions.bump_version(post) if ctx.has_file('content'): auth.verify_privilege(ctx.user, 'posts:edit:content') posts.update_post_content(post, ctx.get_file('content')) if ctx.has_param('tags'): auth.verify_privilege(ctx.user, 'posts:edit:tags') new_tags = posts.update_post_tags( post, ctx.get_param_as_string_list('tags')) if len(new_tags): auth.verify_privilege(ctx.user, 'tags:create') db.session.flush() for tag in new_tags: snapshots.create(tag, ctx.user) if ctx.has_param('safety'): auth.verify_privilege(ctx.user, 'posts:edit:safety') posts.update_post_safety(post, ctx.get_param_as_string('safety')) if ctx.has_param('source'): auth.verify_privilege(ctx.user, 'posts:edit:source') posts.update_post_source(post, ctx.get_param_as_string('source')) elif ctx.has_param('contentUrl'): posts.update_post_source(post, ctx.get_param_as_string('contentUrl')) if ctx.has_param('relations'): auth.verify_privilege(ctx.user, 'posts:edit:relations') posts.update_post_relations( post, ctx.get_param_as_int_list('relations')) if ctx.has_param('notes'): auth.verify_privilege(ctx.user, 'posts:edit:notes') posts.update_post_notes(post, ctx.get_param_as_list('notes')) if ctx.has_param('flags'): auth.verify_privilege(ctx.user, 'posts:edit:flags') posts.update_post_flags(post, ctx.get_param_as_string_list('flags')) if ctx.has_file('thumbnail'): auth.verify_privilege(ctx.user, 'posts:edit:thumbnail') posts.update_post_thumbnail(post, ctx.get_file('thumbnail')) post.last_edit_time = datetime.utcnow() ctx.session.flush() snapshots.modify(post, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_post(ctx, post)
def post(self, ctx): auth.verify_privilege(ctx.user, 'tags:create') names = ctx.get_param_as_list('names', required=True) category = ctx.get_param_as_string('category', required=True) suggestions = ctx.get_param_as_list('suggestions', required=False, default=[]) implications = ctx.get_param_as_list('implications', required=False, default=[]) tag = tags.create_tag(names, category, suggestions, implications) ctx.session.add(tag) ctx.session.flush() snapshots.save_entity_creation(tag, ctx.user) ctx.session.commit() tags.export_to_json() return tags.serialize_tag_with_details(tag)
def post(self, ctx): source_tag_name = ctx.get_param_as_string('remove', required=True) or '' target_tag_name = ctx.get_param_as_string('merge-to', required=True) or '' source_tag = tags.get_tag_by_name(source_tag_name) target_tag = tags.get_tag_by_name(target_tag_name) if not source_tag: raise tags.TagNotFoundError( 'Source tag %r not found.' % source_tag_name) if not target_tag: raise tags.TagNotFoundError( 'Source tag %r not found.' % target_tag_name) if source_tag.tag_id == target_tag.tag_id: raise tags.InvalidTagRelationError( 'Cannot merge tag with itself.') auth.verify_privilege(ctx.user, 'tags:merge') tags.merge_tags(source_tag, target_tag) snapshots.delete(source_tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_tag_with_details(target_tag)
def update_post(ctx, params): post = posts.get_post_by_id(params['post_id']) versions.verify_version(post, ctx) versions.bump_version(post) if ctx.has_file('content'): auth.verify_privilege(ctx.user, 'posts:edit:content') posts.update_post_content(post, ctx.get_file('content')) if ctx.has_param('tags'): auth.verify_privilege(ctx.user, 'posts:edit:tags') new_tags = posts.update_post_tags(post, ctx.get_param_as_list('tags')) if len(new_tags): auth.verify_privilege(ctx.user, 'tags:create') db.session.flush() for tag in new_tags: snapshots.create(tag, ctx.user) if ctx.has_param('safety'): auth.verify_privilege(ctx.user, 'posts:edit:safety') posts.update_post_safety(post, ctx.get_param_as_string('safety')) if ctx.has_param('source'): auth.verify_privilege(ctx.user, 'posts:edit:source') posts.update_post_source(post, ctx.get_param_as_string('source')) elif ctx.has_param('contentUrl'): posts.update_post_source(post, ctx.get_param_as_string('contentUrl')) if ctx.has_param('relations'): auth.verify_privilege(ctx.user, 'posts:edit:relations') posts.update_post_relations(post, ctx.get_param_as_list('relations')) if ctx.has_param('notes'): auth.verify_privilege(ctx.user, 'posts:edit:notes') posts.update_post_notes(post, ctx.get_param_as_list('notes')) if ctx.has_param('flags'): auth.verify_privilege(ctx.user, 'posts:edit:flags') posts.update_post_flags(post, ctx.get_param_as_list('flags')) if ctx.has_file('thumbnail'): auth.verify_privilege(ctx.user, 'posts:edit:thumbnail') posts.update_post_thumbnail(post, ctx.get_file('thumbnail')) post.last_edit_time = datetime.datetime.utcnow() ctx.session.flush() snapshots.modify(post, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_post(ctx, post)
def create_tag(ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response: auth.verify_privilege(ctx.user, 'tags:create') names = ctx.get_param_as_string_list('names') category = ctx.get_param_as_string('category') description = ctx.get_param_as_string('description', default='') suggestions = ctx.get_param_as_string_list('suggestions', default=[]) implications = ctx.get_param_as_string_list('implications', default=[]) _create_if_needed(suggestions, ctx.user) _create_if_needed(implications, ctx.user) tag = tags.create_tag(names, category, suggestions, implications) tags.update_tag_description(tag, description) ctx.session.add(tag) ctx.session.flush() snapshots.create(tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, tag)
def create_tag(ctx, _params=None): auth.verify_privilege(ctx.user, 'tags:create') names = ctx.get_param_as_list('names', required=True) category = ctx.get_param_as_string('category', required=True) description = ctx.get_param_as_string( 'description', required=False, default=None) suggestions = ctx.get_param_as_list( 'suggestions', required=False, default=[]) implications = ctx.get_param_as_list( 'implications', required=False, default=[]) _create_if_needed(suggestions, ctx.user) _create_if_needed(implications, ctx.user) tag = tags.create_tag(names, category, suggestions, implications) tags.update_tag_description(tag, description) ctx.session.add(tag) ctx.session.flush() snapshots.create(tag, ctx.user) ctx.session.commit() tags.export_to_json() return _serialize(ctx, tag)
def put(self, ctx, tag_name): tag = tags.get_tag_by_name(tag_name) if ctx.has_param('names'): auth.verify_privilege(ctx.user, 'tags:edit:names') tags.update_tag_names(tag, ctx.get_param_as_list('names')) if ctx.has_param('category'): auth.verify_privilege(ctx.user, 'tags:edit:category') tags.update_tag_category_name(tag, ctx.get_param_as_string('category')) if ctx.has_param('suggestions'): auth.verify_privilege(ctx.user, 'tags:edit:suggestions') tags.update_tag_suggestions(tag, ctx.get_param_as_list('suggestions')) if ctx.has_param('implications'): auth.verify_privilege(ctx.user, 'tags:edit:implications') tags.update_tag_implications(tag, ctx.get_param_as_list('implications')) tag.last_edit_time = datetime.datetime.now() ctx.session.flush() snapshots.save_entity_modification(tag, ctx.user) ctx.session.commit() tags.export_to_json() return tags.serialize_tag_with_details(tag)
def put(self, ctx, tag_name): tag = tags.get_tag_by_name(tag_name) if ctx.has_param('names'): auth.verify_privilege(ctx.user, 'tags:edit:names') tags.update_tag_names(tag, ctx.get_param_as_list('names')) if ctx.has_param('category'): auth.verify_privilege(ctx.user, 'tags:edit:category') tags.update_tag_category_name( tag, ctx.get_param_as_string('category')) if ctx.has_param('suggestions'): auth.verify_privilege(ctx.user, 'tags:edit:suggestions') tags.update_tag_suggestions( tag, ctx.get_param_as_list('suggestions')) if ctx.has_param('implications'): auth.verify_privilege(ctx.user, 'tags:edit:implications') tags.update_tag_implications( tag, ctx.get_param_as_list('implications')) tag.last_edit_time = datetime.datetime.now() ctx.session.flush() snapshots.save_entity_modification(tag, ctx.user) ctx.session.commit() tags.export_to_json() return tags.serialize_tag_with_details(tag)
def create_post( ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response: anonymous = ctx.get_param_as_bool('anonymous', default=False) if anonymous: auth.verify_privilege(ctx.user, 'posts:create:anonymous') else: auth.verify_privilege(ctx.user, 'posts:create:identified') content = ctx.get_file('content') tag_names = ctx.get_param_as_string_list('tags', default=[]) safety = ctx.get_param_as_string('safety') source = ctx.get_param_as_string('source', default='') if ctx.has_param('contentUrl') and not source: source = ctx.get_param_as_string('contentUrl', default='') relations = ctx.get_param_as_int_list('relations', default=[]) notes = ctx.get_param_as_list('notes', default=[]) flags = ctx.get_param_as_string_list('flags', default=[]) post, new_tags = posts.create_post( content, tag_names, None if anonymous else ctx.user) if len(new_tags): auth.verify_privilege(ctx.user, 'tags:create') posts.update_post_safety(post, safety) posts.update_post_source(post, source) posts.update_post_relations(post, relations) posts.update_post_notes(post, notes) posts.update_post_flags(post, flags) if ctx.has_file('thumbnail'): posts.update_post_thumbnail(post, ctx.get_file('thumbnail')) ctx.session.add(post) ctx.session.flush() snapshots.create(post, None if anonymous else ctx.user) for tag in new_tags: snapshots.create(tag, None if anonymous else ctx.user) ctx.session.commit() tags.export_to_json() return _serialize_post(ctx, post)
def test_export_to_json(tmpdir, query_counter, config_injector, post_factory, tag_factory, tag_category_factory): config_injector({'data_dir': str(tmpdir)}) cat1 = tag_category_factory(name='cat1', color='black') cat2 = tag_category_factory(name='cat2', color='white') tag = tag_factory(names=['alias1', 'alias2'], category=cat2) tag.suggestions = [ tag_factory(names=['sug1'], category=cat1), tag_factory(names=['sug2'], category=cat1), ] tag.implications = [ tag_factory(names=['imp1'], category=cat1), tag_factory(names=['imp2'], category=cat1), ] post = post_factory() post.tags = [tag] db.session.add_all([post, tag]) db.session.flush() with query_counter: tags.export_to_json() assert len(query_counter.statements) == 5 export_path = os.path.join(str(tmpdir), 'tags.json') assert os.path.exists(export_path) with open(export_path, 'r') as handle: actual_json = json.loads(handle.read()) assert actual_json['tags'] assert actual_json['categories'] actual_json['tags'].sort(key=lambda tag: tag['names'][0]) actual_json['categories'].sort(key=lambda category: category['name']) assert actual_json == { 'tags': [ { 'names': ['alias1', 'alias2'], 'usages': 1, 'category': 'cat2', 'suggestions': ['sug1', 'sug2'], 'implications': ['imp1', 'imp2'], }, { 'names': ['imp1'], 'usages': 0, 'category': 'cat1' }, { 'names': ['imp2'], 'usages': 0, 'category': 'cat1' }, { 'names': ['sug1'], 'usages': 0, 'category': 'cat1' }, { 'names': ['sug2'], 'usages': 0, 'category': 'cat1' }, ], 'categories': [ { 'name': 'cat1', 'color': 'black' }, { 'name': 'cat2', 'color': 'white' }, ] }
def test_export(tmpdir, query_counter, config_injector, tag_factory, tag_category_factory): config_injector({'data_dir': str(tmpdir)}) cat1 = tag_category_factory(name='cat1', color='black') cat2 = tag_category_factory(name='cat2', color='white') db.session.add_all([cat1, cat2]) db.session.flush() sug1 = tag_factory(names=['sug1'], category=cat1) sug2 = tag_factory(names=['sug2'], category=cat1) imp1 = tag_factory(names=['imp1'], category=cat1) imp2 = tag_factory(names=['imp2'], category=cat1) tag = tag_factory(names=['alias1', 'alias2'], category=cat2) tag.post_count = 1 db.session.add_all([tag, sug1, sug2, imp1, imp2, cat1, cat2]) db.session.flush() db.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), ]) db.session.flush() with query_counter: tags.export_to_json() assert len(query_counter.statements) == 2 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()) == { 'tags': [ { 'names': ['alias1', 'alias2'], 'usages': 1, 'category': 'cat2', 'suggestions': ['sug1', 'sug2'], 'implications': ['imp1', 'imp2'], }, { 'names': ['sug1'], 'usages': 0, 'category': 'cat1' }, { 'names': ['sug2'], 'usages': 0, 'category': 'cat1' }, { 'names': ['imp1'], 'usages': 0, 'category': 'cat1' }, { 'names': ['imp2'], 'usages': 0, 'category': 'cat1' }, ], 'categories': [ { 'name': 'cat1', 'color': 'black' }, { 'name': 'cat2', 'color': 'white' }, ] }