server: make linters happier
This commit is contained in:
		
							parent
							
								
									fd30675124
								
							
						
					
					
						commit
						abf1fc2b2d
					
				@ -1,3 +1,3 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
pylint szurubooru
 | 
			
		||||
pycodestyle szurubooru --ignore=E128,E131,W503
 | 
			
		||||
pycodestyle szurubooru
 | 
			
		||||
 | 
			
		||||
@ -33,11 +33,11 @@ def get_info(ctx, _params=None):
 | 
			
		||||
        'diskUsage': _get_disk_usage(),
 | 
			
		||||
        'featuredPost':
 | 
			
		||||
            posts.serialize_post(post_feature.post, ctx.user)
 | 
			
		||||
                if post_feature else None,
 | 
			
		||||
            if post_feature else None,
 | 
			
		||||
        'featuringTime': post_feature.time if post_feature else None,
 | 
			
		||||
        'featuringUser':
 | 
			
		||||
            users.serialize_user(post_feature.user, ctx.user)
 | 
			
		||||
                if post_feature else None,
 | 
			
		||||
            if post_feature else None,
 | 
			
		||||
        'serverTime': datetime.datetime.utcnow(),
 | 
			
		||||
        'config': {
 | 
			
		||||
            'userNameRegex': config.config['user_name_regex'],
 | 
			
		||||
 | 
			
		||||
@ -252,8 +252,8 @@ class Post(Base):
 | 
			
		||||
    relation_count = column_property(
 | 
			
		||||
        select([func.count(PostRelation.child_id)])
 | 
			
		||||
        .where(
 | 
			
		||||
            (PostRelation.parent_id == post_id)
 | 
			
		||||
            | (PostRelation.child_id == post_id))
 | 
			
		||||
            (PostRelation.parent_id == post_id) |
 | 
			
		||||
            (PostRelation.child_id == post_id))
 | 
			
		||||
        .correlate_except(PostRelation))
 | 
			
		||||
 | 
			
		||||
    __mapper_args__ = {
 | 
			
		||||
 | 
			
		||||
@ -106,23 +106,29 @@ class Tag(Base):
 | 
			
		||||
        .correlate_except(PostTag))
 | 
			
		||||
 | 
			
		||||
    first_name = column_property(
 | 
			
		||||
        select([TagName.name])
 | 
			
		||||
        (
 | 
			
		||||
            select([TagName.name])
 | 
			
		||||
            .where(TagName.tag_id == tag_id)
 | 
			
		||||
            .order_by(TagName.order)
 | 
			
		||||
            .limit(1)
 | 
			
		||||
            .as_scalar(),
 | 
			
		||||
            .as_scalar()
 | 
			
		||||
        ),
 | 
			
		||||
        deferred=True)
 | 
			
		||||
 | 
			
		||||
    suggestion_count = column_property(
 | 
			
		||||
        select([func.count(TagSuggestion.child_id)])
 | 
			
		||||
        (
 | 
			
		||||
            select([func.count(TagSuggestion.child_id)])
 | 
			
		||||
            .where(TagSuggestion.parent_id == tag_id)
 | 
			
		||||
            .as_scalar(),
 | 
			
		||||
            .as_scalar()
 | 
			
		||||
        ),
 | 
			
		||||
        deferred=True)
 | 
			
		||||
 | 
			
		||||
    implication_count = column_property(
 | 
			
		||||
        select([func.count(TagImplication.child_id)])
 | 
			
		||||
        (
 | 
			
		||||
            select([func.count(TagImplication.child_id)])
 | 
			
		||||
            .where(TagImplication.parent_id == tag_id)
 | 
			
		||||
            .as_scalar(),
 | 
			
		||||
            .as_scalar()
 | 
			
		||||
        ),
 | 
			
		||||
        deferred=True)
 | 
			
		||||
 | 
			
		||||
    __mapper_args__ = {
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,8 @@ class User(Base):
 | 
			
		||||
    @property
 | 
			
		||||
    def post_count(self):
 | 
			
		||||
        from szurubooru.db import session
 | 
			
		||||
        return (session
 | 
			
		||||
        return (
 | 
			
		||||
            session
 | 
			
		||||
            .query(func.sum(1))
 | 
			
		||||
            .filter(Post.user_id == self.user_id)
 | 
			
		||||
            .one()[0] or 0)
 | 
			
		||||
@ -45,7 +46,8 @@ class User(Base):
 | 
			
		||||
    @property
 | 
			
		||||
    def comment_count(self):
 | 
			
		||||
        from szurubooru.db import session
 | 
			
		||||
        return (session
 | 
			
		||||
        return (
 | 
			
		||||
            session
 | 
			
		||||
            .query(func.sum(1))
 | 
			
		||||
            .filter(Comment.user_id == self.user_id)
 | 
			
		||||
            .one()[0] or 0)
 | 
			
		||||
@ -53,7 +55,8 @@ class User(Base):
 | 
			
		||||
    @property
 | 
			
		||||
    def favorite_post_count(self):
 | 
			
		||||
        from szurubooru.db import session
 | 
			
		||||
        return (session
 | 
			
		||||
        return (
 | 
			
		||||
            session
 | 
			
		||||
            .query(func.sum(1))
 | 
			
		||||
            .filter(PostFavorite.user_id == self.user_id)
 | 
			
		||||
            .one()[0] or 0)
 | 
			
		||||
@ -61,7 +64,8 @@ class User(Base):
 | 
			
		||||
    @property
 | 
			
		||||
    def liked_post_count(self):
 | 
			
		||||
        from szurubooru.db import session
 | 
			
		||||
        return (session
 | 
			
		||||
        return (
 | 
			
		||||
            session
 | 
			
		||||
            .query(func.sum(1))
 | 
			
		||||
            .filter(PostScore.user_id == self.user_id)
 | 
			
		||||
            .filter(PostScore.score == 1)
 | 
			
		||||
@ -70,7 +74,8 @@ class User(Base):
 | 
			
		||||
    @property
 | 
			
		||||
    def disliked_post_count(self):
 | 
			
		||||
        from szurubooru.db import session
 | 
			
		||||
        return (session
 | 
			
		||||
        return (
 | 
			
		||||
            session
 | 
			
		||||
            .query(func.sum(1))
 | 
			
		||||
            .filter(PostScore.user_id == self.user_id)
 | 
			
		||||
            .filter(PostScore.score == -1)
 | 
			
		||||
 | 
			
		||||
@ -127,4 +127,4 @@ def create_app():
 | 
			
		||||
    return rest.application
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
app = create_app()
 | 
			
		||||
app = create_app()  # pylint: disable=invalid-name
 | 
			
		||||
 | 
			
		||||
@ -67,21 +67,21 @@ def _normalize_and_threshold(diff_array, identical_tolerance, n_levels):
 | 
			
		||||
    if np.all(mask):
 | 
			
		||||
        return None
 | 
			
		||||
    positive_cutoffs = np.percentile(
 | 
			
		||||
        diff_array[diff_array > 0.], np.linspace(0, 100, n_levels+1))
 | 
			
		||||
        diff_array[diff_array > 0.], np.linspace(0, 100, n_levels + 1))
 | 
			
		||||
    negative_cutoffs = np.percentile(
 | 
			
		||||
        diff_array[diff_array < 0.], np.linspace(100, 0, n_levels+1))
 | 
			
		||||
        diff_array[diff_array < 0.], np.linspace(100, 0, n_levels + 1))
 | 
			
		||||
    for level, interval in enumerate(
 | 
			
		||||
            positive_cutoffs[i:i+2]
 | 
			
		||||
            positive_cutoffs[i:i + 2]
 | 
			
		||||
            for i in range(positive_cutoffs.shape[0] - 1)):
 | 
			
		||||
        diff_array[
 | 
			
		||||
            (diff_array >= interval[0]) & (diff_array <= interval[1])] = \
 | 
			
		||||
                level + 1
 | 
			
		||||
            level + 1
 | 
			
		||||
    for level, interval in enumerate(
 | 
			
		||||
            negative_cutoffs[i:i+2]
 | 
			
		||||
            negative_cutoffs[i:i + 2]
 | 
			
		||||
            for i in range(negative_cutoffs.shape[0] - 1)):
 | 
			
		||||
        diff_array[
 | 
			
		||||
            (diff_array <= interval[0]) & (diff_array >= interval[1])] = \
 | 
			
		||||
                -(level + 1)
 | 
			
		||||
            -(level + 1)
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -110,14 +110,22 @@ def _compute_mean_level(image, x_coords, y_coords, p):
 | 
			
		||||
 | 
			
		||||
def _compute_differentials(grey_level_matrix):
 | 
			
		||||
    flipped = np.fliplr(grey_level_matrix)
 | 
			
		||||
    right_neighbors = -np.concatenate((
 | 
			
		||||
        np.diff(grey_level_matrix),
 | 
			
		||||
        np.zeros(grey_level_matrix.shape[0])
 | 
			
		||||
            .reshape((grey_level_matrix.shape[0], 1))), axis=1)
 | 
			
		||||
    down_neighbors = -np.concatenate((
 | 
			
		||||
        np.diff(grey_level_matrix, axis=0),
 | 
			
		||||
        np.zeros(grey_level_matrix.shape[1])
 | 
			
		||||
            .reshape((1, grey_level_matrix.shape[1]))))
 | 
			
		||||
    right_neighbors = -np.concatenate(
 | 
			
		||||
        (
 | 
			
		||||
            np.diff(grey_level_matrix),
 | 
			
		||||
            (
 | 
			
		||||
                np.zeros(grey_level_matrix.shape[0])
 | 
			
		||||
                .reshape((grey_level_matrix.shape[0], 1))
 | 
			
		||||
            )
 | 
			
		||||
        ), axis=1)
 | 
			
		||||
    down_neighbors = -np.concatenate(
 | 
			
		||||
        (
 | 
			
		||||
            np.diff(grey_level_matrix, axis=0),
 | 
			
		||||
            (
 | 
			
		||||
                np.zeros(grey_level_matrix.shape[1])
 | 
			
		||||
                .reshape((1, grey_level_matrix.shape[1]))
 | 
			
		||||
            )
 | 
			
		||||
        ))
 | 
			
		||||
    left_neighbors = -np.concatenate(
 | 
			
		||||
        (right_neighbors[:, -1:], right_neighbors[:, :-1]), axis=1)
 | 
			
		||||
    up_neighbors = -np.concatenate((down_neighbors[-1:], down_neighbors[:-1]))
 | 
			
		||||
@ -146,15 +154,18 @@ def _compute_differentials(grey_level_matrix):
 | 
			
		||||
 | 
			
		||||
def _generate_signature(path_or_image):
 | 
			
		||||
    im_array = _preprocess_image(path_or_image)
 | 
			
		||||
    image_limits = _crop_image(im_array,
 | 
			
		||||
    image_limits = _crop_image(
 | 
			
		||||
        im_array,
 | 
			
		||||
        lower_percentile=LOWER_PERCENTILE,
 | 
			
		||||
        upper_percentile=UPPER_PERCENTILE)
 | 
			
		||||
    x_coords, y_coords = _compute_grid_points(
 | 
			
		||||
        im_array, n=N, window=image_limits)
 | 
			
		||||
    avg_grey = _compute_mean_level(im_array, x_coords, y_coords, p=P)
 | 
			
		||||
    diff_matrix = _compute_differentials(avg_grey)
 | 
			
		||||
    _normalize_and_threshold(diff_matrix,
 | 
			
		||||
        identical_tolerance=IDENTICAL_TOLERANCE, n_levels=N_LEVELS)
 | 
			
		||||
    _normalize_and_threshold(
 | 
			
		||||
        diff_matrix,
 | 
			
		||||
        identical_tolerance=IDENTICAL_TOLERANCE,
 | 
			
		||||
        n_levels=N_LEVELS)
 | 
			
		||||
    return np.ravel(diff_matrix).astype('int8')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -166,7 +177,7 @@ def _get_words(array, k, n):
 | 
			
		||||
    words = np.zeros((n, k)).astype('int8')
 | 
			
		||||
    for i, pos in enumerate(word_positions):
 | 
			
		||||
        if pos + k <= array.shape[0]:
 | 
			
		||||
            words[i] = array[pos:pos+k]
 | 
			
		||||
            words[i] = array[pos:pos + k]
 | 
			
		||||
        else:
 | 
			
		||||
            temp = array[pos:].copy()
 | 
			
		||||
            temp.resize(k)
 | 
			
		||||
 | 
			
		||||
@ -111,4 +111,5 @@ class Image:
 | 
			
		||||
        assert 'streams' in self.info
 | 
			
		||||
        if len(self.info['streams']) < 1:
 | 
			
		||||
            logger.warning('The video contains no video streams.')
 | 
			
		||||
            raise errors.ProcessingError('The video contains no video streams.')
 | 
			
		||||
            raise errors.ProcessingError(
 | 
			
		||||
                'The video contains no video streams.')
 | 
			
		||||
 | 
			
		||||
@ -474,12 +474,15 @@ def merge_posts(source_post, target_post, replace_content):
 | 
			
		||||
    def merge_tables(table, anti_dup_func, source_post_id, target_post_id):
 | 
			
		||||
        alias1 = table
 | 
			
		||||
        alias2 = sqlalchemy.orm.util.aliased(table)
 | 
			
		||||
        update_stmt = (sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
            .where(alias1.post_id == source_post_id))
 | 
			
		||||
 | 
			
		||||
        if anti_dup_func is not None:
 | 
			
		||||
            update_stmt = (update_stmt
 | 
			
		||||
                .where(~sqlalchemy.exists()
 | 
			
		||||
            update_stmt = (
 | 
			
		||||
                update_stmt
 | 
			
		||||
                .where(
 | 
			
		||||
                    ~sqlalchemy.exists()
 | 
			
		||||
                    .where(anti_dup_func(alias1, alias2))
 | 
			
		||||
                    .where(alias2.post_id == target_post_id)))
 | 
			
		||||
 | 
			
		||||
@ -513,19 +516,23 @@ def merge_posts(source_post, target_post, replace_content):
 | 
			
		||||
    def merge_relations(source_post_id, target_post_id):
 | 
			
		||||
        alias1 = db.PostRelation
 | 
			
		||||
        alias2 = sqlalchemy.orm.util.aliased(db.PostRelation)
 | 
			
		||||
        update_stmt = (sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
            .where(alias1.parent_id == source_post_id)
 | 
			
		||||
            .where(alias1.child_id != target_post_id)
 | 
			
		||||
            .where(~sqlalchemy.exists()
 | 
			
		||||
            .where(
 | 
			
		||||
                ~sqlalchemy.exists()
 | 
			
		||||
                .where(alias2.child_id == alias1.child_id)
 | 
			
		||||
                .where(alias2.parent_id == target_post_id))
 | 
			
		||||
            .values(parent_id=target_post_id))
 | 
			
		||||
        db.session.execute(update_stmt)
 | 
			
		||||
 | 
			
		||||
        update_stmt = (sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
            .where(alias1.child_id == source_post_id)
 | 
			
		||||
            .where(alias1.parent_id != target_post_id)
 | 
			
		||||
            .where(~sqlalchemy.exists()
 | 
			
		||||
            .where(
 | 
			
		||||
                ~sqlalchemy.exists()
 | 
			
		||||
                .where(alias2.parent_id == alias1.parent_id)
 | 
			
		||||
                .where(alias2.child_id == target_post_id))
 | 
			
		||||
            .values(child_id=target_post_id))
 | 
			
		||||
@ -567,7 +574,8 @@ def search_by_image(image_content):
 | 
			
		||||
def populate_reverse_search():
 | 
			
		||||
    excluded_post_ids = image_hash.get_all_paths()
 | 
			
		||||
 | 
			
		||||
    post_ids_to_hash = (db.session
 | 
			
		||||
    post_ids_to_hash = (
 | 
			
		||||
        db.session
 | 
			
		||||
        .query(db.Post.post_id)
 | 
			
		||||
        .filter(
 | 
			
		||||
            (db.Post.type == db.Post.TYPE_IMAGE) |
 | 
			
		||||
@ -577,7 +585,8 @@ def populate_reverse_search():
 | 
			
		||||
        .all())
 | 
			
		||||
 | 
			
		||||
    for post_ids_chunk in util.chunks(post_ids_to_hash, 100):
 | 
			
		||||
        posts_chunk = (db.session
 | 
			
		||||
        posts_chunk = (
 | 
			
		||||
            db.session
 | 
			
		||||
            .query(db.Post)
 | 
			
		||||
            .filter(db.Post.post_id.in_(post_ids_chunk))
 | 
			
		||||
            .all())
 | 
			
		||||
 | 
			
		||||
@ -86,10 +86,13 @@ def create(entity, auth_user):
 | 
			
		||||
def modify(entity, auth_user):
 | 
			
		||||
    assert entity
 | 
			
		||||
 | 
			
		||||
    model = next((model
 | 
			
		||||
        for model in db.Base._decl_class_registry.values()
 | 
			
		||||
        if hasattr(model, '__table__')
 | 
			
		||||
            and model.__table__.fullname == entity.__table__.fullname),
 | 
			
		||||
    model = next(
 | 
			
		||||
        (
 | 
			
		||||
            model
 | 
			
		||||
            for model in db.Base._decl_class_registry.values()
 | 
			
		||||
            if hasattr(model, '__table__')
 | 
			
		||||
            and model.__table__.fullname == entity.__table__.fullname
 | 
			
		||||
        ),
 | 
			
		||||
        None)
 | 
			
		||||
    assert model
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -104,7 +104,8 @@ def export_to_json():
 | 
			
		||||
            'color': result[2],
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    for result in (db.session
 | 
			
		||||
    for result in (
 | 
			
		||||
            db.session
 | 
			
		||||
            .query(db.TagName.tag_id, db.TagName.name)
 | 
			
		||||
            .order_by(db.TagName.order)
 | 
			
		||||
            .all()):
 | 
			
		||||
@ -112,7 +113,8 @@ def export_to_json():
 | 
			
		||||
            tags[result[0]] = {'names': []}
 | 
			
		||||
        tags[result[0]]['names'].append(result[1])
 | 
			
		||||
 | 
			
		||||
    for result in (db.session
 | 
			
		||||
    for result in (
 | 
			
		||||
            db.session
 | 
			
		||||
            .query(db.TagSuggestion.parent_id, db.TagName.name)
 | 
			
		||||
            .join(db.TagName, db.TagName.tag_id == db.TagSuggestion.child_id)
 | 
			
		||||
            .all()):
 | 
			
		||||
@ -120,7 +122,8 @@ def export_to_json():
 | 
			
		||||
            tags[result[0]]['suggestions'] = []
 | 
			
		||||
        tags[result[0]]['suggestions'].append(result[1])
 | 
			
		||||
 | 
			
		||||
    for result in (db.session
 | 
			
		||||
    for result in (
 | 
			
		||||
            db.session
 | 
			
		||||
            .query(db.TagImplication.parent_id, db.TagName.name)
 | 
			
		||||
            .join(db.TagName, db.TagName.tag_id == db.TagImplication.child_id)
 | 
			
		||||
            .all()):
 | 
			
		||||
@ -146,7 +149,8 @@ def export_to_json():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def try_get_tag_by_name(name):
 | 
			
		||||
    return (db.session
 | 
			
		||||
    return (
 | 
			
		||||
        db.session
 | 
			
		||||
        .query(db.Tag)
 | 
			
		||||
        .join(db.TagName)
 | 
			
		||||
        .filter(sqlalchemy.func.lower(db.TagName.name) == name.lower())
 | 
			
		||||
@ -198,7 +202,8 @@ def get_tag_siblings(tag):
 | 
			
		||||
    tag_alias = sqlalchemy.orm.aliased(db.Tag)
 | 
			
		||||
    pt_alias1 = sqlalchemy.orm.aliased(db.PostTag)
 | 
			
		||||
    pt_alias2 = sqlalchemy.orm.aliased(db.PostTag)
 | 
			
		||||
    result = (db.session
 | 
			
		||||
    result = (
 | 
			
		||||
        db.session
 | 
			
		||||
        .query(tag_alias, sqlalchemy.func.count(pt_alias2.post_id))
 | 
			
		||||
        .join(pt_alias1, pt_alias1.tag_id == tag_alias.tag_id)
 | 
			
		||||
        .join(pt_alias2, pt_alias2.post_id == pt_alias1.post_id)
 | 
			
		||||
@ -214,10 +219,10 @@ def delete(source_tag):
 | 
			
		||||
    assert source_tag
 | 
			
		||||
    db.session.execute(
 | 
			
		||||
        sqlalchemy.sql.expression.delete(db.TagSuggestion)
 | 
			
		||||
            .where(db.TagSuggestion.child_id == source_tag.tag_id))
 | 
			
		||||
        .where(db.TagSuggestion.child_id == source_tag.tag_id))
 | 
			
		||||
    db.session.execute(
 | 
			
		||||
        sqlalchemy.sql.expression.delete(db.TagImplication)
 | 
			
		||||
            .where(db.TagImplication.child_id == source_tag.tag_id))
 | 
			
		||||
        .where(db.TagImplication.child_id == source_tag.tag_id))
 | 
			
		||||
    db.session.delete(source_tag)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -230,10 +235,13 @@ def merge_tags(source_tag, target_tag):
 | 
			
		||||
    def merge_posts(source_tag_id, target_tag_id):
 | 
			
		||||
        alias1 = db.PostTag
 | 
			
		||||
        alias2 = sqlalchemy.orm.util.aliased(db.PostTag)
 | 
			
		||||
        update_stmt = (sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
            .where(alias1.tag_id == source_tag_id))
 | 
			
		||||
        update_stmt = (update_stmt
 | 
			
		||||
            .where(~sqlalchemy.exists()
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            update_stmt
 | 
			
		||||
            .where(
 | 
			
		||||
                ~sqlalchemy.exists()
 | 
			
		||||
                .where(alias1.post_id == alias2.post_id)
 | 
			
		||||
                .where(alias2.tag_id == target_tag_id)))
 | 
			
		||||
        update_stmt = update_stmt.values(tag_id=target_tag_id)
 | 
			
		||||
@ -242,19 +250,23 @@ def merge_tags(source_tag, target_tag):
 | 
			
		||||
    def merge_relations(table, source_tag_id, target_tag_id):
 | 
			
		||||
        alias1 = table
 | 
			
		||||
        alias2 = sqlalchemy.orm.util.aliased(table)
 | 
			
		||||
        update_stmt = (sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
            .where(alias1.parent_id == source_tag_id)
 | 
			
		||||
            .where(alias1.child_id != target_tag_id)
 | 
			
		||||
            .where(~sqlalchemy.exists()
 | 
			
		||||
            .where(
 | 
			
		||||
                ~sqlalchemy.exists()
 | 
			
		||||
                .where(alias2.child_id == alias1.child_id)
 | 
			
		||||
                .where(alias2.parent_id == target_tag_id))
 | 
			
		||||
            .values(parent_id=target_tag_id))
 | 
			
		||||
        db.session.execute(update_stmt)
 | 
			
		||||
 | 
			
		||||
        update_stmt = (sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
        update_stmt = (
 | 
			
		||||
            sqlalchemy.sql.expression.update(alias1)
 | 
			
		||||
            .where(alias1.child_id == source_tag_id)
 | 
			
		||||
            .where(alias1.parent_id != target_tag_id)
 | 
			
		||||
            .where(~sqlalchemy.exists()
 | 
			
		||||
            .where(
 | 
			
		||||
                ~sqlalchemy.exists()
 | 
			
		||||
                .where(alias2.parent_id == alias1.parent_id)
 | 
			
		||||
                .where(alias2.child_id == target_tag_id))
 | 
			
		||||
            .values(child_id=target_tag_id))
 | 
			
		||||
 | 
			
		||||
@ -44,10 +44,9 @@ def get_avatar_url(user):
 | 
			
		||||
        return 'https://gravatar.com/avatar/%s?d=retro&s=%d' % (
 | 
			
		||||
            util.get_md5((user.email or user.name).lower()),
 | 
			
		||||
            config.config['thumbnails']['avatar_width'])
 | 
			
		||||
    else:
 | 
			
		||||
        assert user.name
 | 
			
		||||
        return '%s/avatars/%s.png' % (
 | 
			
		||||
            config.config['data_url'].rstrip('/'), user.name.lower())
 | 
			
		||||
    assert user.name
 | 
			
		||||
    return '%s/avatars/%s.png' % (
 | 
			
		||||
        config.config['data_url'].rstrip('/'), user.name.lower())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_email(user, auth_user, force_show_email):
 | 
			
		||||
@ -126,7 +125,8 @@ def get_user_by_name(name):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def try_get_user_by_name_or_email(name_or_email):
 | 
			
		||||
    return (db.session
 | 
			
		||||
    return (
 | 
			
		||||
        db.session
 | 
			
		||||
        .query(db.User)
 | 
			
		||||
        .filter(
 | 
			
		||||
            (func.lower(db.User.name) == func.lower(name_or_email)) |
 | 
			
		||||
 | 
			
		||||
@ -102,6 +102,7 @@ def parse_time_range(value):
 | 
			
		||||
    ''' Return tuple containing min/max time for given text representation. '''
 | 
			
		||||
    one_day = timedelta(days=1)
 | 
			
		||||
    one_second = timedelta(seconds=1)
 | 
			
		||||
    almost_one_day = one_day - one_second
 | 
			
		||||
 | 
			
		||||
    value = value.lower()
 | 
			
		||||
    if not value:
 | 
			
		||||
@ -111,8 +112,8 @@ def parse_time_range(value):
 | 
			
		||||
        now = datetime.utcnow()
 | 
			
		||||
        return (
 | 
			
		||||
            datetime(now.year, now.month, now.day, 0, 0, 0),
 | 
			
		||||
            datetime(now.year, now.month, now.day, 0, 0, 0)
 | 
			
		||||
                + one_day - one_second)
 | 
			
		||||
            datetime(now.year, now.month, now.day, 0, 0, 0) + almost_one_day
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    if value == 'yesterday':
 | 
			
		||||
        now = datetime.utcnow()
 | 
			
		||||
 | 
			
		||||
@ -19,8 +19,8 @@ def upgrade():
 | 
			
		||||
        'tag_category', sa.Column('default', sa.Boolean(), nullable=True))
 | 
			
		||||
    op.execute(
 | 
			
		||||
        sa.table('tag_category', sa.column('default'))
 | 
			
		||||
            .update()
 | 
			
		||||
            .values(default=False))
 | 
			
		||||
        .update()
 | 
			
		||||
        .values(default=False))
 | 
			
		||||
    op.alter_column('tag_category', 'default', nullable=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,8 @@ def upgrade():
 | 
			
		||||
        op.add_column(table, sa.Column('version', sa.Integer(), nullable=True))
 | 
			
		||||
        op.execute(
 | 
			
		||||
            sa.table(table, sa.column('version'))
 | 
			
		||||
                .update()
 | 
			
		||||
                .values(version=1))
 | 
			
		||||
            .update()
 | 
			
		||||
            .values(version=1))
 | 
			
		||||
        op.alter_column(table, 'version', nullable=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,7 @@ def application(env, start_response):
 | 
			
		||||
                    hook(ctx)
 | 
			
		||||
                try:
 | 
			
		||||
                    response = handler(ctx, match.groupdict())
 | 
			
		||||
                except:
 | 
			
		||||
                except Exception:
 | 
			
		||||
                    ctx.session.rollback()
 | 
			
		||||
                    raise
 | 
			
		||||
                finally:
 | 
			
		||||
 | 
			
		||||
@ -44,9 +44,10 @@ class Context:
 | 
			
		||||
        return self._headers.get(name, None)
 | 
			
		||||
 | 
			
		||||
    def has_file(self, name, allow_tokens=True):
 | 
			
		||||
        return (name in self._files
 | 
			
		||||
            or name + 'Url' in self._params
 | 
			
		||||
            or (allow_tokens and name + 'Token' in self._params))
 | 
			
		||||
        return (
 | 
			
		||||
            name in self._files or
 | 
			
		||||
            name + 'Url' in self._params or
 | 
			
		||||
            (allow_tokens and name + 'Token' in self._params))
 | 
			
		||||
 | 
			
		||||
    def get_file(self, name, required=False, allow_tokens=True):
 | 
			
		||||
        ret = None
 | 
			
		||||
@ -80,7 +81,7 @@ class Context:
 | 
			
		||||
        if isinstance(value, list):
 | 
			
		||||
            try:
 | 
			
		||||
                value = ','.join(value)
 | 
			
		||||
            except:
 | 
			
		||||
            except TypeError:
 | 
			
		||||
                raise errors.InvalidParameterError('Expected simple string.')
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ def _create_score_filter(score):
 | 
			
		||||
        if not getattr(criterion, 'internal', False):
 | 
			
		||||
            raise errors.SearchError(
 | 
			
		||||
                'Votes cannot be seen publicly. Did you mean %r?'
 | 
			
		||||
                    % 'special:liked')
 | 
			
		||||
                % 'special:liked')
 | 
			
		||||
        user_alias = aliased(db.User)
 | 
			
		||||
        score_alias = aliased(db.PostScore)
 | 
			
		||||
        expr = score_alias.score == score
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,8 @@ from szurubooru.search import criteria
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def wildcard_transformer(value):
 | 
			
		||||
    return (value
 | 
			
		||||
    return (
 | 
			
		||||
        value
 | 
			
		||||
        .replace('\\', '\\\\')
 | 
			
		||||
        .replace('%', '\\%')
 | 
			
		||||
        .replace('_', '\\_')
 | 
			
		||||
 | 
			
		||||
@ -41,18 +41,18 @@ class Executor:
 | 
			
		||||
            filter_query, search_query, False)
 | 
			
		||||
        prev_filter_query = (
 | 
			
		||||
            filter_query
 | 
			
		||||
                .filter(self.config.id_column > entity_id)
 | 
			
		||||
                .order_by(None)
 | 
			
		||||
                .order_by(sqlalchemy.func.abs(
 | 
			
		||||
                    self.config.id_column - entity_id).asc())
 | 
			
		||||
                .limit(1))
 | 
			
		||||
            .filter(self.config.id_column > entity_id)
 | 
			
		||||
            .order_by(None)
 | 
			
		||||
            .order_by(sqlalchemy.func.abs(
 | 
			
		||||
                self.config.id_column - entity_id).asc())
 | 
			
		||||
            .limit(1))
 | 
			
		||||
        next_filter_query = (
 | 
			
		||||
            filter_query
 | 
			
		||||
                .filter(self.config.id_column < entity_id)
 | 
			
		||||
                .order_by(None)
 | 
			
		||||
                .order_by(sqlalchemy.func.abs(
 | 
			
		||||
                    self.config.id_column - entity_id).asc())
 | 
			
		||||
                .limit(1))
 | 
			
		||||
            .filter(self.config.id_column < entity_id)
 | 
			
		||||
            .order_by(None)
 | 
			
		||||
            .order_by(sqlalchemy.func.abs(
 | 
			
		||||
                self.config.id_column - entity_id).asc())
 | 
			
		||||
            .limit(1))
 | 
			
		||||
        return [
 | 
			
		||||
            prev_filter_query.one_or_none(),
 | 
			
		||||
            next_filter_query.one_or_none()]
 | 
			
		||||
 | 
			
		||||
@ -44,9 +44,8 @@ def test_using_special_tokens(user_factory, post_factory, context_factory):
 | 
			
		||||
    db.session.add_all([post1, post2, auth_user])
 | 
			
		||||
    db.session.flush()
 | 
			
		||||
    with patch('szurubooru.func.posts.serialize_post'):
 | 
			
		||||
        posts.serialize_post.side_effect = \
 | 
			
		||||
            lambda post, *_args, **_kwargs: \
 | 
			
		||||
                'serialized post %d' % post.post_id
 | 
			
		||||
        posts.serialize_post.side_effect = lambda post, *_args, **_kwargs: \
 | 
			
		||||
            'serialized post %d' % post.post_id
 | 
			
		||||
        result = api.post_api.get_posts(
 | 
			
		||||
            context_factory(
 | 
			
		||||
                params={'query': 'special:fav', 'page': 1},
 | 
			
		||||
 | 
			
		||||
@ -14,9 +14,8 @@ def test_get_tag_siblings(user_factory, tag_factory, context_factory):
 | 
			
		||||
    db.session.flush()
 | 
			
		||||
    with patch('szurubooru.func.tags.serialize_tag'), \
 | 
			
		||||
            patch('szurubooru.func.tags.get_tag_siblings'):
 | 
			
		||||
        tags.serialize_tag.side_effect = \
 | 
			
		||||
            lambda tag, *args, **kwargs: \
 | 
			
		||||
                'serialized tag %s' % tag.names[0].name
 | 
			
		||||
        tags.serialize_tag.side_effect = lambda tag, *args, **kwargs: \
 | 
			
		||||
            'serialized tag %s' % tag.names[0].name
 | 
			
		||||
        tags.get_tag_siblings.return_value = [
 | 
			
		||||
            (tag_factory(names=['sib1']), 1),
 | 
			
		||||
            (tag_factory(names=['sib2']), 3),
 | 
			
		||||
 | 
			
		||||
@ -494,9 +494,8 @@ def test_update_post_content_leaving_custom_thumbnail(
 | 
			
		||||
def test_update_post_tags(tag_factory):
 | 
			
		||||
    post = db.Post()
 | 
			
		||||
    with patch('szurubooru.func.tags.get_or_create_tags_by_names'):
 | 
			
		||||
        tags.get_or_create_tags_by_names.side_effect \
 | 
			
		||||
            = lambda tag_names: \
 | 
			
		||||
                ([tag_factory(names=[name]) for name in tag_names], [])
 | 
			
		||||
        tags.get_or_create_tags_by_names.side_effect = lambda tag_names: \
 | 
			
		||||
            ([tag_factory(names=[name]) for name in tag_names], [])
 | 
			
		||||
        posts.update_post_tags(post, ['tag1', 'tag2'])
 | 
			
		||||
    assert len(post.tags) == 2
 | 
			
		||||
    assert post.tags[0].names[0].name == 'tag1'
 | 
			
		||||
 | 
			
		||||
@ -21,22 +21,22 @@ def test_get_avatar_path(user_name):
 | 
			
		||||
        'user',
 | 
			
		||||
        None,
 | 
			
		||||
        db.User.AVATAR_GRAVATAR,
 | 
			
		||||
        'https://gravatar.com/avatar/' +
 | 
			
		||||
            'ee11cbb19052e40b07aac0ca060c23ee?d=retro&s=100',
 | 
			
		||||
        ('https://gravatar.com/avatar/' +
 | 
			
		||||
            'ee11cbb19052e40b07aac0ca060c23ee?d=retro&s=100'),
 | 
			
		||||
    ),
 | 
			
		||||
    (
 | 
			
		||||
        None,
 | 
			
		||||
        'user@example.com',
 | 
			
		||||
        db.User.AVATAR_GRAVATAR,
 | 
			
		||||
        'https://gravatar.com/avatar/' +
 | 
			
		||||
            'b58996c504c5638798eb6b511e6f49af?d=retro&s=100',
 | 
			
		||||
        ('https://gravatar.com/avatar/' +
 | 
			
		||||
            'b58996c504c5638798eb6b511e6f49af?d=retro&s=100'),
 | 
			
		||||
    ),
 | 
			
		||||
    (
 | 
			
		||||
        'user',
 | 
			
		||||
        'user@example.com',
 | 
			
		||||
        db.User.AVATAR_GRAVATAR,
 | 
			
		||||
        'https://gravatar.com/avatar/' +
 | 
			
		||||
            'b58996c504c5638798eb6b511e6f49af?d=retro&s=100',
 | 
			
		||||
        ('https://gravatar.com/avatar/' +
 | 
			
		||||
            'b58996c504c5638798eb6b511e6f49af?d=retro&s=100'),
 | 
			
		||||
    ),
 | 
			
		||||
    (
 | 
			
		||||
        'user',
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user