Repository: internetarchive/openlibrary

Issue:
Adds "Safe Mode" to blur NSWF covers
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->

## Describe the problem that you'd like solved
<!-- A clear and concise description of what you want to happen. -->

### SFW: “Safe For Work” mode MVP

**Objective:** Allow librarians to add `content_warnings:` subject tags (e.g. `content_warning:pornographic`) to works. Let librarians decide the name of these tags or use the conventions that archive.org uses via the standard `edit` subject UI.

**Checklist:**

1. [ ] SWF: On the /account settings page, update "Manage Privacy Settings" --> "Manage Privacy & Content Moderation Settings"
  * This feature is very similar to https://github.com/internetarchive/openlibrary/pull/826/files
  * <img width="388" alt="Screenshot 2023-03-27 at 3 16 56 PM" src="https://user-images.githubusercontent.com/978325/228079331-e88c9ec3-0705-4f65-ad6e-a19bf886e9a1.png">
  * Edit the /account/privacy page to have a new section:
      * Add a label description: **Enable Safe Mode?** Safe Mode helps you tailor your experience where possible to moderate the content you are shown. 
      * Radio buttons for "Enable Safe Mode", "Disable Safe Mode"
  * When this update, is performed 
    * Update the POST/submit of this form so the patron's setting is saved in their settings (`https://openlibrary.org/people/{username}/preferences.yml`) under `notifications` as `safe_mode` with a value of `yes`, `no` or omitted (also `no`)
    * Set/unset the `sfw` cookie, similar to how the `pd` (printdisabled setting) cookie is set for certain patrons: https://github.com/internetarchive/openlibrary/blob/master/openlibrary/plugins/upstream/account.py#L393-L397
    * Use `statsd.incr` or find a query to keep track of how many times the feature has been enabled. 
2. [ ] If `swf` cookie set, update the search results page to...
   * Blur covers if work has `content_warnings:*` subject and account cookie has “sfw”
3. [ ] Edit UI: Introduce a check to prevent non-librarians from adding a subject with `content_warning:` prefix
   * This a bonus as the feature will work without this final step.

Next steps:
* [ ] Updating (homepage) carousels so we know which works have content warnings?
* [ ] Adding "Safe Mode" as an option for/during account registration






Discussion:
If we blur covers, we need to show titles some other way.
By "content_warning" you mean for the covers only? I don't think we need to block all books with any adult content. It's only covers I've ever gotten complaints about. We need to be very clear about what is eligible for a content warning as this is highly subjective. 
SFW mode may create unrealistic expectations for patrons, especially at first, so we need to be clear to patrons that it will not necessarily block everything...and again...subjectivity.
In terms of a first-step, let's assume content_warning cover blurs will be the result of an opt-in decision per account.

The cover might receive a blur css class and the title may be overlayed on the blurred cover with a content warning note; something like:

<img width="246" alt="Screenshot 2023-03-01 at 9 31 38 AM" src="https://user-images.githubusercontent.com/978325/222217218-0b7ff146-3b42-4a2f-8bbd-670d2570e6ef.png">


  
How does this work for users in Iran or Texas vs San Francisco? Are there a set of different tags with differing criteria on what gets censored and what doesn't? Is this done at the level of a nation or some other geo-political entity? Will users have a profile setting for religious beliefs so that those can be taken into account as well? 
This is opt-in, librarians can place different tags, and we can grow into patrons choosing their filters accordingly. For now, the priority is giving patrons the option to filter e.g. covers so it's safer for students/kids, etc
One interesting idea which came up is, as a mechanism, using "filters" which can leverage any tag / subject / solr query w/e

I am hoping that Ri & Sivan work on this one with @jimchamp -- Ri + Sivan, if you two can comment on this issue, we can get you assigned!
Hi, sorry we forgot to comment on this in order to be officially assigned, but we're working on this issue!  
Yup, hope to open a draft PR today!
Adding an update to the issue proper; to reiterate from the top comment, my and @rs1dev 's PR #7775 has been opened with two goals: first, to add a safe mode value to a user's preference that can be updated through settings and is stored as a cookie when the user is logged in. This part has mostly been implemented already. Second, if a user has enabled safe mode, when they see a book cover which belongs to a book that has a subject marking it as inappropriate, they should see a blurred version of the book cover.

@mek has given us some guidance as to how this second part should be implemented on both the search page (our primary focus) and home page (might not get done in the next week and a half or so that we are working), which he has requested that we write down here for everyone to see.

For the search page, the first step is to check whether a user has safe mode enabled (in cookie form), which can be done at the time of search in `plugins/worksearch/code.py`. If they do, we can grab a list of subjects during the search in addition to the usual information, and check if any of these subjects indicate that a book cover should be blurred. After that, in `macros/FulltextResults.html`, we can load either `macros/SearchResultWork.html` or an appropriately blurred counterpart based on the status of the work.

For the homepage, it's more complicated due to the way that the page is generated, but follows mostly the same formula. Mek's suggestion is that in `plugins/openlibrary/home.py`, which controls the homepage, we should check whether the user has the safe mode cookie set, and render a special safe mode version of the page by passing an argument to the carousels to blur the covers there.

Any discussion or questions around implementation details or the best method by which subjects can be used to indicate that a book/book cover should be blurred is welcome. 
Some questions we have that might serve as basis for discussion:
- Should we blur a book's cover(s) based on the content of the book being inappropriate, or the book cover itself being inappropriate?
- If we only blur when the cover is inappropriate, how do we know which cover to blur for multiple covers?
For now, let's blur any work with a subject that starts with `content_warning:`
For the design of the cover, we could have a blurred cover w/ a square w/ text that shows content warnings + a red link to optionally show cover.

Resolving patch:
diff --git a/openlibrary/plugins/worksearch/code.py b/openlibrary/plugins/worksearch/code.py
--- a/openlibrary/plugins/worksearch/code.py
+++ b/openlibrary/plugins/worksearch/code.py
@@ -292,14 +292,15 @@ def do_search(
     :param sort: csv sort ordering
     :param spellcheck_count: Not really used; should probably drop
     """
+
+    if web.cookies(sfw="").sfw == 'yes':
+        fields = list(
+            WorkSearchScheme.default_fetched_fields | {'editions'} | {'subject'}
+        )
+    else:
+        fields = list(WorkSearchScheme.default_fetched_fields | {'editions'})
     return run_solr_query(
-        WorkSearchScheme(),
-        param,
-        rows,
-        page,
-        sort,
-        spellcheck_count,
-        fields=list(WorkSearchScheme.default_fetched_fields | {'editions'}),
+        WorkSearchScheme(), param, rows, page, sort, spellcheck_count, fields=fields
     )
 
 


Test patch: