diff --git a/config.yaml.dist b/config.yaml.dist index 42267452..6193505d 100644 --- a/config.yaml.dist +++ b/config.yaml.dist @@ -20,6 +20,12 @@ database: test_database: 'sqlite:///:memory:' # required for running the test suite +# Delete thumbnails and source files on post delete +# Original functionality is false, to mitigate the impacts of admins going +# on unchecked post purges. +delete_source_files: no + + thumbnails: avatar_width: 300 avatar_height: 300 diff --git a/server/szurubooru/func/posts.py b/server/szurubooru/func/posts.py index 25cd73a9..e35e2e12 100644 --- a/server/szurubooru/func/posts.py +++ b/server/szurubooru/func/posts.py @@ -400,8 +400,9 @@ def _before_post_delete( _mapper: Any, _connection: Any, post: model.Post) -> None: if post.post_id: image_hash.delete_image(str(post.post_id)) - files.delete(get_post_content_path(post)) - files.delete(get_post_thumbnail_path(post)) + if config.config['delete_source_files']: + files.delete(get_post_content_path(post)) + files.delete(get_post_thumbnail_path(post)) def _sync_post_content(post: model.Post) -> None: diff --git a/server/szurubooru/tests/api/test_post_deleting.py b/server/szurubooru/tests/api/test_post_deleting.py index 85744ad1..7e588472 100644 --- a/server/szurubooru/tests/api/test_post_deleting.py +++ b/server/szurubooru/tests/api/test_post_deleting.py @@ -8,7 +8,10 @@ from szurubooru.func import posts, snapshots @pytest.fixture(autouse=True) def inject_config(config_injector): - config_injector({'secret': 'secret', 'data_dir': '', 'privileges': {'posts:delete': model.User.RANK_REGULAR}}) + config_injector({'secret': 'secret', + 'data_dir': '', + 'delete_source_files': False, + 'privileges': {'posts:delete': model.User.RANK_REGULAR}}) def test_deleting(user_factory, post_factory, context_factory): diff --git a/server/szurubooru/tests/func/test_posts.py b/server/szurubooru/tests/func/test_posts.py index c5570f0e..b4c41ade 100644 --- a/server/szurubooru/tests/func/test_posts.py +++ b/server/szurubooru/tests/func/test_posts.py @@ -677,7 +677,8 @@ def test_feature_post(post_factory, user_factory): assert new_featured_post == post -def test_delete(post_factory): +def test_delete(post_factory, config_injector): + config_injector({'delete_source_files': False}) post = post_factory() db.session.add(post) db.session.flush() @@ -687,7 +688,8 @@ def test_delete(post_factory): assert posts.get_post_count() == 0 -def test_merge_posts_deletes_source_post(post_factory): +def test_merge_posts_deletes_source_post(post_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() db.session.add_all([source_post, target_post]) @@ -699,7 +701,8 @@ def test_merge_posts_deletes_source_post(post_factory): assert post is not None -def test_merge_posts_with_itself(post_factory): +def test_merge_posts_with_itself(post_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() db.session.add(source_post) db.session.flush() @@ -707,7 +710,8 @@ def test_merge_posts_with_itself(post_factory): posts.merge_posts(source_post, source_post, False) -def test_merge_posts_moves_tags(post_factory, tag_factory): +def test_merge_posts_moves_tags(post_factory, tag_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() tag = tag_factory() @@ -722,7 +726,9 @@ def test_merge_posts_moves_tags(post_factory, tag_factory): assert posts.get_post_by_id(target_post.post_id).tag_count == 1 -def test_merge_posts_doesnt_duplicate_tags(post_factory, tag_factory): +def test_merge_posts_doesnt_duplicate_tags( + post_factory, tag_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() tag = tag_factory() @@ -737,7 +743,9 @@ def test_merge_posts_doesnt_duplicate_tags(post_factory, tag_factory): assert posts.get_post_by_id(target_post.post_id).tag_count == 1 -def test_merge_posts_moves_comments(post_factory, comment_factory): +def test_merge_posts_moves_comments( + post_factory, comment_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() comment = comment_factory(post=source_post) @@ -751,7 +759,9 @@ def test_merge_posts_moves_comments(post_factory, comment_factory): assert posts.get_post_by_id(target_post.post_id).comment_count == 1 -def test_merge_posts_moves_scores(post_factory, post_score_factory): +def test_merge_posts_moves_scores( + post_factory, post_score_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() score = post_score_factory(post=source_post, score=1) @@ -766,7 +776,8 @@ def test_merge_posts_moves_scores(post_factory, post_score_factory): def test_merge_posts_doesnt_duplicate_scores( - post_factory, user_factory, post_score_factory): + post_factory, user_factory, post_score_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() user = user_factory() @@ -782,7 +793,9 @@ def test_merge_posts_doesnt_duplicate_scores( assert posts.get_post_by_id(target_post.post_id).score == 1 -def test_merge_posts_moves_favorites(post_factory, post_favorite_factory): +def test_merge_posts_moves_favorites( + post_factory, post_favorite_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() favorite = post_favorite_factory(post=source_post) @@ -797,7 +810,8 @@ def test_merge_posts_moves_favorites(post_factory, post_favorite_factory): def test_merge_posts_doesnt_duplicate_favorites( - post_factory, user_factory, post_favorite_factory): + post_factory, user_factory, post_favorite_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() user = user_factory() @@ -813,7 +827,8 @@ def test_merge_posts_doesnt_duplicate_favorites( assert posts.get_post_by_id(target_post.post_id).favorite_count == 1 -def test_merge_posts_moves_child_relations(post_factory): +def test_merge_posts_moves_child_relations(post_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() related_post = post_factory() @@ -828,7 +843,9 @@ def test_merge_posts_moves_child_relations(post_factory): assert posts.get_post_by_id(target_post.post_id).relation_count == 1 -def test_merge_posts_doesnt_duplicate_child_relations(post_factory): +def test_merge_posts_doesnt_duplicate_child_relations(post_factory, + config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() related_post = post_factory() @@ -844,7 +861,8 @@ def test_merge_posts_doesnt_duplicate_child_relations(post_factory): assert posts.get_post_by_id(target_post.post_id).relation_count == 1 -def test_merge_posts_moves_parent_relations(post_factory): +def test_merge_posts_moves_parent_relations(post_factory, config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() related_post = post_factory() @@ -861,7 +879,9 @@ def test_merge_posts_moves_parent_relations(post_factory): assert posts.get_post_by_id(related_post.post_id).relation_count == 1 -def test_merge_posts_doesnt_duplicate_parent_relations(post_factory): +def test_merge_posts_doesnt_duplicate_parent_relations(post_factory, + config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() related_post = post_factory() @@ -878,7 +898,9 @@ def test_merge_posts_doesnt_duplicate_parent_relations(post_factory): assert posts.get_post_by_id(related_post.post_id).relation_count == 1 -def test_merge_posts_doesnt_create_relation_loop_for_children(post_factory): +def test_merge_posts_doesnt_create_relation_loop_for_children(post_factory, + config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() source_post.relations = [target_post] @@ -892,7 +914,9 @@ def test_merge_posts_doesnt_create_relation_loop_for_children(post_factory): assert posts.get_post_by_id(target_post.post_id).relation_count == 0 -def test_merge_posts_doesnt_create_relation_loop_for_parents(post_factory): +def test_merge_posts_doesnt_create_relation_loop_for_parents(post_factory, + config_injector): + config_injector({'delete_source_files': False}) source_post = post_factory() target_post = post_factory() target_post.relations = [source_post] @@ -911,6 +935,7 @@ def test_merge_posts_replaces_content( config_injector({ 'data_dir': str(tmpdir.mkdir('data')), 'data_url': 'example.com', + 'delete_source_files': False, 'thumbnails': { 'post_width': 300, 'post_height': 300, @@ -938,6 +963,6 @@ def test_merge_posts_replaces_content( assert posts.try_get_post_by_id(source_post.post_id) is None post = posts.get_post_by_id(target_post.post_id) assert post is not None - assert not os.path.exists(source_path) + assert os.path.exists(source_path) assert os.path.exists(target_path1) assert not os.path.exists(target_path2) diff --git a/server/szurubooru/tests/model/test_post.py b/server/szurubooru/tests/model/test_post.py index 2fffd87b..704c5f1c 100644 --- a/server/szurubooru/tests/model/test_post.py +++ b/server/szurubooru/tests/model/test_post.py @@ -7,7 +7,9 @@ from szurubooru import db, model @pytest.fixture(autouse=True) def inject_config(config_injector): - config_injector({'secret': 'secret', 'data_dir': ''}) + config_injector({'secret': 'secret', + 'data_dir': '', + 'delete_source_files': False}) def test_saving_post(post_factory, user_factory, tag_factory): diff --git a/server/szurubooru/tests/model/test_tag.py b/server/szurubooru/tests/model/test_tag.py index 9121f91c..c22a6ac2 100644 --- a/server/szurubooru/tests/model/test_tag.py +++ b/server/szurubooru/tests/model/test_tag.py @@ -7,7 +7,8 @@ from szurubooru import db, model @pytest.fixture(autouse=True) def inject_config(config_injector): - config_injector({'secret': 'secret', 'data_dir': ''}) + config_injector({'delete_source_files': False, + 'secret': 'secret', 'data_dir': ''}) def test_saving_tag(tag_factory):