From 19904af95851b0679fab8f58726a273503ef808b Mon Sep 17 00:00:00 2001 From: Ebru Yucesar Date: Wed, 22 May 2024 11:04:09 -0400 Subject: [PATCH] add doctests, move json load to settings --- web/config/settings/settings_base.py | 8 ++++++ web/conftest.py | 5 ++++ web/main/models.py | 26 +++++++++++++++---- .../includes/casebook_copyright_notice.html | 2 +- web/main/views.py | 2 -- web/static/data/ali_materials.json | 14 +++++----- web/tasks.py | 7 ++--- 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/web/config/settings/settings_base.py b/web/config/settings/settings_base.py index dedd3519c..1b80ad803 100644 --- a/web/config/settings/settings_base.py +++ b/web/config/settings/settings_base.py @@ -12,6 +12,7 @@ import os from typing import Any, TypedDict +import json BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) ALLOWED_HOSTS: list[str] = [] @@ -299,3 +300,10 @@ class LoggerConfig(TypedDict, total=False): SENTRY_SEND_DEFAULT_PII = False COVER_IMAGES = False + +# Load ali materials +try: + with open(f"{STATIC_ROOT}/data/ali_materials.json", "r") as file: + ALI_MATERIALS = json.load(file) +except FileNotFoundError as e: + print("Error opening file.", e) diff --git a/web/conftest.py b/web/conftest.py index fd0ca233e..fd88e0b14 100644 --- a/web/conftest.py +++ b/web/conftest.py @@ -684,6 +684,11 @@ def legal_doc(legal_document_factory): return legal_document_factory() +@pytest.fixture +def content_node(content_node_factory): + return content_node_factory() + + @pytest.fixture def capapi_mock(requests_mock): """ diff --git a/web/main/models.py b/web/main/models.py index 4ceb0f99d..892a53945 100644 --- a/web/main/models.py +++ b/web/main/models.py @@ -2,7 +2,6 @@ import logging import time -import json from datetime import datetime from enum import Enum from os.path import commonprefix @@ -1658,19 +1657,36 @@ def export_content(self, request): return self.resource.content def get_ali_license_text(self): - with open(f"{settings.STATIC_ROOT}/data/ali_materials.json", "r") as file: - licensed_materials = json.load(file) + """Returns custom license text if title contains all items of the match_words list + + >>> node = getfixture('content_node') + >>> # title including both items in the form of single word strings + >>> node.title = 'Restatement (Third) of Property (Servitudes) Notes and Questions' + >>> assert node.get_ali_license_text() == 'Restatement of the Law, Property, copyright @ 1977-2023 by the American Law Institute. Reproduced with permission, not as part of a Creative Commons license.' + >>> # title including both items in the form of one single word string and one multi-word string + >>> node.title = 'Excerpts from Restatement (First) and (Second) of Conflict of Laws' + >>> assert node.get_ali_license_text() == 'Restatement of the Law, Conflict of Laws, copyright @ 1971-2023 by the American Law Institute. Reproduced with permission, not as part of a Creative Commons license.' + >>> # title including both items in the form of two multi-word strings in lower case + >>> node.title = 'section from model penal code sexual assault and related offenses publication' + >>> assert node.get_ali_license_text() == 'Model Penal Code, Sexual Assault and Related Offenses, copyright @ 2021-2022 by the American Law Institute. Reproduced with permission, not as part of a Creative Commons license.' + >>> # title that only includes one of the words + >>> node.title = 'section from the principles of law publications' + >>> assert node.get_ali_license_text() == '' + >>> # title that doesn't include any of the words + >>> node.title = 'Text that does not include any of the match words' + >>> assert node.get_ali_license_text() == '' + """ title = self.title.lower() license_txt = "" - for item in licensed_materials: + for item in settings.ALI_MATERIALS: if all(word in title for word in item["match_words"]): license_txt = ( f"{item['title']}, copyright @ {item['years']} by the American Law Institute. " f"Reproduced with permission, not as part of a Creative Commons license." ) - + break return license_txt @property diff --git a/web/main/templates/includes/casebook_copyright_notice.html b/web/main/templates/includes/casebook_copyright_notice.html index 54c554af8..d66c998f0 100644 --- a/web/main/templates/includes/casebook_copyright_notice.html +++ b/web/main/templates/includes/casebook_copyright_notice.html @@ -5,7 +5,7 @@ {% if section.ali_licensed %} - {{ ali_license }} + {{ section.get_ali_license_text }} {% else %} Any excerpts from the Restatements of the Law, Principles of the Law, and the Model Penal Code are copyright by The American Law Institute. Excerpts are reproduced with permission, not as part of a Creative Commons license. {% endif %} diff --git a/web/main/views.py b/web/main/views.py index f63b6e0be..3aad1a976 100644 --- a/web/main/views.py +++ b/web/main/views.py @@ -2132,7 +2132,6 @@ def get(self, request, casebook, section): { "casebook": casebook, "section": section, - "ali_license": section.get_ali_license_text(), "tabs": section.tabs_for_user(request.user), "casebook_color_class": casebook.casebook_color_indicator, "edit_mode": casebook.directly_editable_by(request.user), @@ -2379,7 +2378,6 @@ def get(self, request, casebook: Casebook, resource: Resource): { "casebook": casebook, "section": section, - "ali_license": section.get_ali_license_text(), "body_json": body_json, "contents": section, "include_vuejs": section.annotatable, diff --git a/web/static/data/ali_materials.json b/web/static/data/ali_materials.json index de45d57ab..f6998f171 100644 --- a/web/static/data/ali_materials.json +++ b/web/static/data/ali_materials.json @@ -139,7 +139,7 @@ "title": "Principle of the Law, Aggregate Litigation", "years": "2010-2023", "match_words": [ - "restatement", + "principle", "aggregate litigation" ] }, @@ -147,7 +147,7 @@ "title": "Principle of the Law, Corporate Governance", "years": "1994-2023", "match_words": [ - "restatement", + "principle", "corporate governance" ] }, @@ -155,7 +155,7 @@ "title": "Principle of the Law, Data Privacy", "years": "2020", "match_words": [ - "restatement", + "principle", "data privacy" ] }, @@ -163,7 +163,7 @@ "title": "Principle of the Law, Election Administration: Non-Precinct Voting and Resolution of Ballot-Counting Disputes", "years": "2019-2023", "match_words": [ - "restatement", + "principle", "election administration: non-precinct voting and resolution of ballot-counting disputes" ] }, @@ -171,7 +171,7 @@ "title": "Principle of the Law, Family Dissolution", "years": "2002-2023", "match_words": [ - "restatement", + "principle", "family dissolution" ] }, @@ -179,7 +179,7 @@ "title": "Principle of the Law, Intellectual Property: Principles Governing Jurisdiction, Choice of Law, and Judgments in Transnational Disputes", "years": "2008", "match_words": [ - "restatement", + "principle", "intellectual property: principles governing jurisdiction, choice of law, and judgments in transnational disputes" ] }, @@ -187,7 +187,7 @@ "title": "Principle of the Law, Software Contracts", "years": "2010", "match_words": [ - "restatement", + "principle", "software contracts" ] }, diff --git a/web/tasks.py b/web/tasks.py index 7246158c4..a18c38eb2 100644 --- a/web/tasks.py +++ b/web/tasks.py @@ -475,7 +475,8 @@ def populate_ali_licensed(ctx): """ from main.models import ContentNode - for node in ContentNode.objects.all(): - if node.get_ali_license_text(): - node.ali_licensed = True + for node in tqdm(ContentNode.objects.iterator()): + is_licensed = bool(node.get_ali_license_text()) + if node.ali_licensed is not is_licensed: + node.ali_licensed = is_licensed node.save(update_fields=["ali_licensed"])