From 422b99ac8d880dbc710ac2502c051c5d400ab676 Mon Sep 17 00:00:00 2001
From: rr- <rr-@sakuya.pl>
Date: Fri, 26 Aug 2016 16:07:00 +0200
Subject: [PATCH] server/search: add content-checksum

---
 API.md                                        | 81 ++++++++++---------
 client/html/help_search_posts.tpl             |  4 +
 .../search/configs/post_search_config.py      |  2 +
 .../search/configs/test_post_search_config.py | 18 +++++
 4 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/API.md b/API.md
index 3c6bb2f..ec5e4e8 100644
--- a/API.md
+++ b/API.md
@@ -632,46 +632,47 @@ data.
 
     **Named tokens**
 
-    | `<key>`          | Description                                                |
-    | ---------------- | ---------------------------------------------------------- |
-    | `id`             | having given post number                                   |
-    | `tag`            | having given tag                                           |
-    | `score`          | having given score                                         |
-    | `uploader`       | uploaded by given user                                     |
-    | `upload`         | alias of upload                                            |
-    | `submit`         | alias of upload                                            |
-    | `comment`        | commented by given user                                    |
-    | `fav`            | favorited by given user                                    |
-    | `tag-count`      | having given number of tags                                |
-    | `comment-count`  | having given number of comments                            |
-    | `fav-count`      | favorited by given number of users                         |
-    | `note-count`     | having given number of annotations                         |
-    | `relation-count` | having given number of relations                           |
-    | `feature-count`  | having been featured given number of times                 |
-    | `type`           | given type of posts. `<value>` can be either `image`, `animation` (or `animated` or `anim`), `flash` (or `swf`) or `video` (or `webm`). |
-    | `file-size`      | having given file size (in bytes)                          |
-    | `image-width`    | having given image width (where applicable)                |
-    | `image-height`   | having given image height (where applicable)               |
-    | `image-area`     | having given number of pixels (image width * image height) |
-    | `width`          | alias of `image-width`                                     |
-    | `height`         | alias of `image-height`                                    |
-    | `area`           | alias of `image-area`                                      |
-    | `creation-date`  | posted at given date                                       |
-    | `creation-time`  | alias of `creation-date`                                   |
-    | `date`           | alias of `creation-date`                                   |
-    | `time`           | alias of `creation-date`                                   |
-    | `last-edit-date` | edited at given date                                       |
-    | `last-edit-time` | alias of `last-edit-date`                                  |
-    | `edit-date`      | alias of `last-edit-date`                                  |
-    | `edit-time`      | alias of `last-edit-date`                                  |
-    | `comment-date`   | commented at given date                                    |
-    | `comment-time`   | alias of `comment-date`                                    |
-    | `fav-date`       | last favorited at given date                               |
-    | `fav-time`       | alias of `fav-date`                                        |
-    | `feature-date`   | featured at given date                                     |
-    | `feature-time`   | alias of `feature-time`                                    |
-    | `safety`         | having given safety. `<value>` can be either `safe`, `sketchy` (or `questionable`) or `unsafe`. |
-    | `rating`         | alias of `safety`                                          |
+    | `<key>`            | Description                                                |
+    | ------------------ | ---------------------------------------------------------- |
+    | `id`               | having given post number                                   |
+    | `tag`              | having given tag                                           |
+    | `score`            | having given score                                         |
+    | `uploader`         | uploaded by given user                                     |
+    | `upload`           | alias of upload                                            |
+    | `submit`           | alias of upload                                            |
+    | `comment`          | commented by given user                                    |
+    | `fav`              | favorited by given user                                    |
+    | `tag-count`        | having given number of tags                                |
+    | `comment-count`    | having given number of comments                            |
+    | `fav-count`        | favorited by given number of users                         |
+    | `note-count`       | having given number of annotations                         |
+    | `relation-count`   | having given number of relations                           |
+    | `feature-count`    | having been featured given number of times                 |
+    | `type`             | given type of posts. `<value>` can be either `image`, `animation` (or `animated` or `anim`), `flash` (or `swf`) or `video` (or `webm`). |
+    | `content-checksum` | having given SHA1 checksum                                 |
+    | `file-size`        | having given file size (in bytes)                          |
+    | `image-width`      | having given image width (where applicable)                |
+    | `image-height`     | having given image height (where applicable)               |
+    | `image-area`       | having given number of pixels (image width * image height) |
+    | `width`            | alias of `image-width`                                     |
+    | `height`           | alias of `image-height`                                    |
+    | `area`             | alias of `image-area`                                      |
+    | `creation-date`    | posted at given date                                       |
+    | `creation-time`    | alias of `creation-date`                                   |
+    | `date`             | alias of `creation-date`                                   |
+    | `time`             | alias of `creation-date`                                   |
+    | `last-edit-date`   | edited at given date                                       |
+    | `last-edit-time`   | alias of `last-edit-date`                                  |
+    | `edit-date`        | alias of `last-edit-date`                                  |
+    | `edit-time`        | alias of `last-edit-date`                                  |
+    | `comment-date`     | commented at given date                                    |
+    | `comment-time`     | alias of `comment-date`                                    |
+    | `fav-date`         | last favorited at given date                               |
+    | `fav-time`         | alias of `fav-date`                                        |
+    | `feature-date`     | featured at given date                                     |
+    | `feature-time`     | alias of `feature-time`                                    |
+    | `safety`           | having given safety. `<value>` can be either `safe`, `sketchy` (or `questionable`) or `unsafe`. |
+    | `rating`           | alias of `safety`                                          |
 
     **Sort style tokens**
 
diff --git a/client/html/help_search_posts.tpl b/client/html/help_search_posts.tpl
index ed2d523..074819f 100644
--- a/client/html/help_search_posts.tpl
+++ b/client/html/help_search_posts.tpl
@@ -66,6 +66,10 @@
             <td><code>type</code></td>
             <td>given type of posts. <code>&lt;value&gt;</code> can be either <code>image</code>, <code>animation</code> (or <code>animated</code> or <code>anim</code>), <code>flash</code> (or <code>swf</code>) or <code>video</code> (or <code>webm</code>).</td>
         </tr>
+        <tr>
+            <td><code>content-checksum</code></td>
+            <td>having given SHA1 checksum</td>
+        </tr>
         <tr>
             <td><code>file-size</code></td>
             <td>having given file size (in bytes)</td>
diff --git a/server/szurubooru/search/configs/post_search_config.py b/server/szurubooru/search/configs/post_search_config.py
index 743f5b6..1c8db0e 100644
--- a/server/szurubooru/search/configs/post_search_config.py
+++ b/server/szurubooru/search/configs/post_search_config.py
@@ -182,6 +182,8 @@ class PostSearchConfig(BaseSearchConfig):
             'type':
                 search_util.create_str_filter(
                     db.Post.type, _type_transformer),
+            'content-checksum': search_util.create_str_filter(
+                db.Post.checksum),
             'file-size': search_util.create_num_filter(db.Post.file_size),
             ('image-width', 'width'):
                 search_util.create_num_filter(db.Post.canvas_width),
diff --git a/server/szurubooru/tests/search/configs/test_post_search_config.py b/server/szurubooru/tests/search/configs/test_post_search_config.py
index 0987083..d579677 100644
--- a/server/szurubooru/tests/search/configs/test_post_search_config.py
+++ b/server/szurubooru/tests/search/configs/test_post_search_config.py
@@ -365,6 +365,24 @@ def test_filter_by_invalid_type(executor):
         executor.execute('type:invalid', page=1, page_size=100)
 
 
+@pytest.mark.parametrize('input,expected_post_ids', [
+    ('content-checksum:checksum1', [1]),
+    ('content-checksum:checksum3', [3]),
+    ('content-checksum:checksum1,checksum3', [1, 3]),
+])
+def test_filter_by_content_checksum(
+        verify_unpaged, post_factory, input, expected_post_ids):
+    post1 = post_factory(id=1)
+    post2 = post_factory(id=2)
+    post3 = post_factory(id=3)
+    post1.checksum = 'checksum1'
+    post2.checksum = 'checksum2'
+    post3.checksum = 'checksum3'
+    db.session.add_all([post1, post2, post3])
+    db.session.flush()
+    verify_unpaged(input, expected_post_ids)
+
+
 @pytest.mark.parametrize('input,expected_post_ids', [
     ('file-size:100', [1]),
     ('file-size:102', [3]),