From 8e8486497fb702583deaca13861e8f3999fa746e Mon Sep 17 00:00:00 2001
From: tomjmul <github@celtware.com>
Date: Tue, 19 Mar 2019 12:57:29 +0000
Subject: [PATCH] Restirct a user to a set of tags

---
 .gitignore                                    |  1 +
 cps/templates/user_edit.html                  |  5 +++++
 cps/translations/de/LC_MESSAGES/messages.po   |  5 +++++
 cps/translations/es/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/fr/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/hu/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/it/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/ja/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/km/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/nl/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/pl/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/ru/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/sv/LC_MESSAGES/messages.po   |  4 ++++
 cps/translations/uk/LC_MESSAGES/messages.po   |  4 ++++
 .../zh_Hans_CN/LC_MESSAGES/messages.po        |  4 ++++
 cps/ub.py                                     |  1 +
 cps/web.py                                    | 21 +++++++++++++++++--
 17 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 09bf3faa..cd822a75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,3 +29,4 @@ gdrive_credentials
 
 vendor
 client_secrets.json
+venv/
diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html
index 79de265f..f25d7710 100644
--- a/cps/templates/user_edit.html
+++ b/cps/templates/user_edit.html
@@ -44,6 +44,11 @@
             {% endfor %}
         </select>
     </div>
+      <div class="form-group">
+          <label for="allowed_tags">{{_('Allowed Tags')}}</label>
+          <input type="text" class="form-control" name="allowed_tags" id="allowed_tags" value="{{ content.allowed_tags if content.allowed_tags != None }}" autocomplete="off">
+      </div>
+
     <div class="col-sm-6">
       <div class="form-group">
           <input type="checkbox" name="show_random" id="show_random" {% if content.show_random_books() %}checked{% endif %}>
diff --git a/cps/translations/de/LC_MESSAGES/messages.po b/cps/translations/de/LC_MESSAGES/messages.po
index d4ee9a09..72c3cb3f 100644
--- a/cps/translations/de/LC_MESSAGES/messages.po
+++ b/cps/translations/de/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "Zeige nur Bücher mit dieser Sprache"
 msgid "Show all"
 msgstr "Zeige alle"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Zulässige Tags"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Benutzer löschen"
@@ -2005,3 +2009,4 @@ msgstr "Benutzer löschen"
 msgid "Recent Downloads"
 msgstr "Letzte Downloads"
 
+
diff --git a/cps/translations/es/LC_MESSAGES/messages.po b/cps/translations/es/LC_MESSAGES/messages.po
index c3803984..fc00ba33 100644
--- a/cps/translations/es/LC_MESSAGES/messages.po
+++ b/cps/translations/es/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "Mostrar libros con idioma"
 msgid "Show all"
 msgstr "Mostrar todo"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Etiquetas permitidas"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Borrar este usuario"
diff --git a/cps/translations/fr/LC_MESSAGES/messages.po b/cps/translations/fr/LC_MESSAGES/messages.po
index 99d32f30..4ca6b4c4 100644
--- a/cps/translations/fr/LC_MESSAGES/messages.po
+++ b/cps/translations/fr/LC_MESSAGES/messages.po
@@ -2010,6 +2010,10 @@ msgstr "Montrer les livres dans la langue"
 msgid "Show all"
 msgstr "Montrer tout"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Tags autorisés"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Supprimer cet utilisateur"
diff --git a/cps/translations/hu/LC_MESSAGES/messages.po b/cps/translations/hu/LC_MESSAGES/messages.po
index 6365bc0c..04e0b066 100644
--- a/cps/translations/hu/LC_MESSAGES/messages.po
+++ b/cps/translations/hu/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "Mutasd a könyveket a következő nyelvvel"
 msgid "Show all"
 msgstr "Mindent mutass"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Engedélyezett címkék"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "A felhasználó törlése"
diff --git a/cps/translations/it/LC_MESSAGES/messages.po b/cps/translations/it/LC_MESSAGES/messages.po
index f1c07611..1c48cecc 100644
--- a/cps/translations/it/LC_MESSAGES/messages.po
+++ b/cps/translations/it/LC_MESSAGES/messages.po
@@ -1996,6 +1996,10 @@ msgstr "Mostra libri per lingua"
 msgid "Show all"
 msgstr "Mostra tutto"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Tag consentiti"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Elimina questo utente"
diff --git a/cps/translations/ja/LC_MESSAGES/messages.po b/cps/translations/ja/LC_MESSAGES/messages.po
index 02d209d5..44352129 100644
--- a/cps/translations/ja/LC_MESSAGES/messages.po
+++ b/cps/translations/ja/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "言語で本を表示する"
 msgid "Show all"
 msgstr "全て表示"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "許可されたタグ"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "このユーザを削除する"
diff --git a/cps/translations/km/LC_MESSAGES/messages.po b/cps/translations/km/LC_MESSAGES/messages.po
index 72317e95..f69209bf 100644
--- a/cps/translations/km/LC_MESSAGES/messages.po
+++ b/cps/translations/km/LC_MESSAGES/messages.po
@@ -1998,6 +1998,10 @@ msgstr "បង្ហាញសៀវភៅដែលមានភាសា"
 msgid "Show all"
 msgstr "បង្ហាញទាំងអស់"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "ស្លាកដែលបានអនុញ្ញាត"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "លុបអ្នកប្រើប្រាស់នេះ"
diff --git a/cps/translations/nl/LC_MESSAGES/messages.po b/cps/translations/nl/LC_MESSAGES/messages.po
index b62e0cd8..80d877c1 100644
--- a/cps/translations/nl/LC_MESSAGES/messages.po
+++ b/cps/translations/nl/LC_MESSAGES/messages.po
@@ -1998,6 +1998,10 @@ msgstr "Toon boeken met taal"
 msgid "Show all"
 msgstr "Toon alles"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Toegestane tags"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Wis deze gebruiker"
diff --git a/cps/translations/pl/LC_MESSAGES/messages.po b/cps/translations/pl/LC_MESSAGES/messages.po
index b905f11a..6a3c8e20 100644
--- a/cps/translations/pl/LC_MESSAGES/messages.po
+++ b/cps/translations/pl/LC_MESSAGES/messages.po
@@ -2000,6 +2000,10 @@ msgstr "Pokaż książki w języku"
 msgid "Show all"
 msgstr "Pokaż wszystko"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Dozwolone tagi"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Usuń tego użytkownika"
diff --git a/cps/translations/ru/LC_MESSAGES/messages.po b/cps/translations/ru/LC_MESSAGES/messages.po
index 50fe62ff..33ffb087 100644
--- a/cps/translations/ru/LC_MESSAGES/messages.po
+++ b/cps/translations/ru/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "Показать книги на языках"
 msgid "Show all"
 msgstr "Показать все"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Разрешенные теги"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Удалить этого пользователя"
diff --git a/cps/translations/sv/LC_MESSAGES/messages.po b/cps/translations/sv/LC_MESSAGES/messages.po
index 39fb8c45..6631d115 100644
--- a/cps/translations/sv/LC_MESSAGES/messages.po
+++ b/cps/translations/sv/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "Visa böcker med språk"
 msgid "Show all"
 msgstr "Visa alla"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Tillåten etiketter"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Ta bort den här användaren"
diff --git a/cps/translations/uk/LC_MESSAGES/messages.po b/cps/translations/uk/LC_MESSAGES/messages.po
index 76a6234b..de5d8d00 100644
--- a/cps/translations/uk/LC_MESSAGES/messages.po
+++ b/cps/translations/uk/LC_MESSAGES/messages.po
@@ -1995,6 +1995,10 @@ msgstr "Показувати книги на мовах"
 msgid "Show all"
 msgstr "Показати всі"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "Дозволені теги"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "Видалити цього користувача"
diff --git a/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po b/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po
index 1af2fc34..2a5b881a 100644
--- a/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po
+++ b/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po
@@ -1997,6 +1997,10 @@ msgstr "按语言显示书籍"
 msgid "Show all"
 msgstr "显示全部"
 
+#: cps/templates/user_edit.html:48
+msgid "Allowed Tags"
+msgstr "允许的标签"
+
 #: cps/templates/user_edit.html:141
 msgid "Delete this user"
 msgstr "删除此用户"
diff --git a/cps/ub.py b/cps/ub.py
index 4b69a457..58042220 100644
--- a/cps/ub.py
+++ b/cps/ub.py
@@ -192,6 +192,7 @@ class User(UserBase, Base):
     sidebar_view = Column(Integer, default=1)
     default_language = Column(String(3), default="all")
     mature_content = Column(Boolean, default=True)
+    allowed_tags = Column(String)
 
 
 # Class for anonymous user is derived from User base and completly overrides methods and properties for the
diff --git a/cps/web.py b/cps/web.py
index d59b6ba8..6a7a4321 100644
--- a/cps/web.py
+++ b/cps/web.py
@@ -497,6 +497,12 @@ def edit_required(f):
 
     return inner
 
+def allowed_tags(tags):
+    if sys.version_info > (3, 0): # Python3 str, Python2 unicode
+        lstrip = str.lstrip
+    else:
+        lstrip = unicode.lstrip
+    return list(map(lstrip, tags.split(",")))
 
 # Language and content filters for displaying in the UI
 def common_filters():
@@ -504,9 +510,14 @@ def common_filters():
         lang_filter = db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())
     else:
         lang_filter = true()
+    if current_user.allowed_tags is not None and current_user.allowed_tags != '':
+        tags_filter = db.Books.tags.any(db.Tags.name.in_(allowed_tags(current_user.allowed_tags)))
+    else:
+        tags_filter = true()
     content_rating_filter = false() if current_user.mature_content else \
         db.Books.tags.any(db.Tags.name.in_(config.mature_content_tags()))
-    return and_(lang_filter, ~content_rating_filter)
+
+    return and_(tags_filter, lang_filter, ~content_rating_filter)
 
 
 # Creates for all stored languages a translated speaking name in the array for the UI
@@ -1085,7 +1096,8 @@ def get_comic_book(book_id, book_format, page):
 def get_authors_json():
     if request.method == "GET":
         query = request.args.get('q')
-        entries = db.session.query(db.Authors).filter(db.Authors.name.ilike("%" + query + "%")).all()
+        entries = db.session.query(db.Authors).join(db.books_authors_link).join(db.Books).filter(common_filters())\
+            .filter(db.Authors.name.ilike("%" + query + "%")).all()
         json_dumps = json.dumps([dict(name=r.name.replace('|',',')) for r in entries])
         return json_dumps
 
@@ -2710,6 +2722,8 @@ def profile():
                 content.password = generate_password_hash(to_save["password"])
         if "kindle_mail" in to_save and to_save["kindle_mail"] != content.kindle_mail:
             content.kindle_mail = to_save["kindle_mail"]
+        if "allowed_tags" in to_save and to_save["allowed_tags"] != content.allowed_tags:
+            content.allowed_tags = to_save["allowed_tags"].strip()
         if to_save["email"] and to_save["email"] != content.email:
             if config.config_public_reg and not check_valid_domain(to_save["email"]):
                 flash(_(u"E-mail is not from valid domain"), category="error")
@@ -2872,6 +2886,7 @@ def view_configuration():
             content.config_default_show = content.config_default_show + ub.SIDEBAR_SORTED
         if "show_mature_content" in to_save:
             content.config_default_show = content.config_default_show + ub.MATURE_CONTENT
+
         ub.session.commit()
         flash(_(u"Calibre-Web configuration updated"), category="success")
         config.loadSettings()
@@ -3336,6 +3351,8 @@ def edit_user(user_id):
                 content.email = to_save["email"]
             if "kindle_mail" in to_save and to_save["kindle_mail"] != content.kindle_mail:
                 content.kindle_mail = to_save["kindle_mail"]
+            if "allowed_tags" in to_save and to_save["allowed_tags"] != content.allowed_tags:
+                content.allowed_tags = to_save["allowed_tags"]
         try:
             ub.session.commit()
             flash(_(u"User '%(nick)s' updated", nick=content.nickname), category="success")