Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 7.4.0 -> main #1206

Merged
merged 37 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
77b1df3
Added transcript content and button
krishan-torchbox Jul 5, 2023
c441cb8
Merge branch 'develop' into feature/UN-554-Image-transcript-FE
krishan-torchbox Jul 5, 2023
b0f3447
Added accordion feature
krishan-torchbox Jul 6, 2023
328eef9
Merge branch 'develop' into feature/UN-554-Image-transcript-FE
krishan-torchbox Jul 6, 2023
7af0c95
Refactored image block reduce and remove duplication of code
krishan-torchbox Jul 6, 2023
00af0d5
Merge branch 'develop' into feature/UN-554-Image-transcript-FE
krishan-torchbox Jul 6, 2023
31bb9c3
Merge branch 'develop' into feature/UN-554-Image-transcript-FE
krishan-torchbox Jul 6, 2023
31b348d
Merge main to develop: Post Release 7.3.0 into main (#1173) (#1174)
jamesbiggs Jul 11, 2023
049efe6
Reinstate frontend styles, fix issues, update footer classes (#1168)
ahosgood Jul 11, 2023
0f5e2f3
Fix SASS compilation on platform.sh (#1175)
ahosgood Jul 11, 2023
a5102c9
CHORE: JS Package Updates (#1177)
jamesbiggs Jul 12, 2023
d26514b
DF-714: Accessibility for date fields (#1074)
TNA-Allan Jul 12, 2023
8aa04cd
DF-696 helpertext in date filters (#1169)
JohnHeeryTNA Jul 12, 2023
863bcd5
DF-714-fix for date labels on search (#1180)
JohnHeeryTNA Jul 12, 2023
485273b
DF-546 (+ DF-724 & DF-770): BE record creators details page (#1086)
TNA-Allan Jul 12, 2023
a014bb8
DF-740: Fix archive links details page and search results (#1179)
TNA-Allan Jul 12, 2023
af6b1e7
UN-780: Record, Focused, and Article page types in "More Stories" (#1…
jamesbiggs Jul 13, 2023
7400c18
DF-772 apply styling to website results (#1181)
JohnHeeryTNA Jul 13, 2023
9df15fd
DF-725: Other archives hierarchy (#1058)
jamesbiggs Jul 14, 2023
7a90738
DF-505: Hide available to download for closed records, show closure s…
TNA-Allan Jul 14, 2023
c022325
Merge branch 'develop' of github.com:nationalarchives/ds-wagtail into…
ahosgood Jul 14, 2023
2f55c23
Fix overflow issue in longtranscriptswithnospaces
ahosgood Jul 14, 2023
dde74ab
UN 554 image transcript fe (#1154)
ahosgood Jul 14, 2023
60fad7f
Df 772 apply styling to website results (#1190)
JohnHeeryTNA Jul 17, 2023
a16600b
CHORE: Python Package Updates (#1178)
jamesbiggs Jul 17, 2023
95c4530
DF-585:Fix uniqueness for sort_by id (#1192)
TNA-Allan Jul 18, 2023
d33f205
DF-774:Fix hierarchy and search results links for various record leve…
TNA-Allan Jul 18, 2023
1f129c0
DF-755: Search results analytics (#1193)
jamesbiggs Jul 19, 2023
b7ffcfa
CHORE: Password page template (#1109)
jamesbiggs Jul 19, 2023
ba2f7ff
Df-772 apply styling to website results (#1195)
JohnHeeryTNA Jul 19, 2023
22734be
CHORE: Fix record revealed promo (#1196)
jamesbiggs Jul 20, 2023
e022b4c
Fix/DF-778 fixes to website results formatting (#1198)
JohnHeeryTNA Jul 20, 2023
ab5a331
CHORE: JavaScript package updates (#1197)
jamesbiggs Jul 20, 2023
f51487d
Disable Codecov comment in PRs (#1194)
ahosgood Jul 20, 2023
14cbddf
UN-612 - Multiple images with transcripts bug (#1191)
ahosgood Jul 20, 2023
5ecb218
feedback mech option layouts (#1199)
JohnHeeryTNA Jul 20, 2023
2412b64
Fix/DF-778 fixes to website results formatting (#1200)
JohnHeeryTNA Jul 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .platform.app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ hooks:

npm install
npm install -g sass
sass sass/etna.scss:templates/static/css/dist/etna.css
sass --quiet-deps --style=compressed --load-path=node_modules sass/etna.scss:templates/static/css/dist/etna.css

npx webpack --config webpack.config.js

Expand Down
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: false
4 changes: 4 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@

WAGTAILIMAGES_IMAGE_MODEL = "images.CustomImage"

# Custom password template for private pages

PASSWORD_REQUIRED_TEMPLATE = "password_pages/password_required.html"

# Kong client

KONG_CLIENT_BASE_URL = os.getenv("KONG_CLIENT_BASE_URL")
Expand Down
60 changes: 28 additions & 32 deletions etna/articles/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, Tuple
from typing import Any, Dict, List, Tuple, Union

from django.conf import settings
from django.db import models
Expand Down Expand Up @@ -252,7 +252,9 @@ def save(self, *args, **kwargs):
super().save(*args, **kwargs)

@cached_property
def similar_items(self) -> Tuple["ArticlePage"]:
def similar_items(
self,
) -> Tuple[Union["ArticlePage", "FocusedArticlePage", "RecordArticlePage"], ...]:
"""
Returns a maximum of three ArticlePages that are tagged with at least
one of the same ArticleTags. Items should be ordered by the number
Expand All @@ -267,49 +269,43 @@ def similar_items(self) -> Tuple["ArticlePage"]:
# Avoid unncecssary lookups
return ()

# Identify 'other' live pages with tags in common
tag_match_ids = (
ArticlePage.objects.public()
.live()
# Identify other live pages with tags in common
related_tags = (
Page.objects.live()
.public()
.not_page(self)
.exact_type(ArticlePage, FocusedArticlePage, RecordArticlePage)
.filter(tagged_items__tag_id__in=tag_ids)
.values_list("id", flat=True)
.distinct()
)
if not tag_match_ids:
# Avoid unncecssary lookups
return ()

# Use search() to prioritise items with the highest number of matches
return tuple(
ArticlePage.objects.filter(id__in=tag_match_ids).search(
self.article_tag_names,
fields=["article_tag_names"],
operator="or",
)[:3]
Page.objects.filter(id__in=related_tags).order_by("-first_published_at")[:3]
)

@cached_property
def latest_items(self) -> Tuple["ArticlePage"]:
def latest_items(
self,
) -> List[Union["ArticlePage", "FocusedArticlePage", "RecordArticlePage"]]:
"""
Return the three most recently published ArticlePages,
excluding this object.
"""
similarqueryset = list(self.similar_items)

latestqueryset = list(
ArticlePage.objects.public()
.live()
.not_page(self)
.select_related("hero_image")
.prefetch_related("hero_image__renditions")
.order_by("-first_published_at")
)
filterlatestpages = [
page for page in latestqueryset if page not in similarqueryset
]

return tuple(filterlatestpages[:3])
latest_query_set = []

for page_type in [ArticlePage, FocusedArticlePage, RecordArticlePage]:
latest_query_set.extend(
page_type.objects.live()
.public()
.exclude(id__in=[page.id for page in self.similar_items])
.not_page(self)
.select_related("teaser_image")
.prefetch_related("teaser_image__renditions")
)

return sorted(
latest_query_set, key=lambda x: x.first_published_at, reverse=True
)[:3]


class FocusedArticlePage(
Expand Down
14 changes: 7 additions & 7 deletions etna/articles/tests/test_similar_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@ def setUp(self):
self.different_tags_page.save()

def test_similar_items_ranking(self):
# Items should be in 'best match' order
# Items should be in 'most recent' order
# No draft items should be included
test_page = ArticlePage.objects.get(id=self.original_page.id)
with self.assertNumQueries(4):
with self.assertNumQueries(3):
self.assertEqual(
list(test_page.similar_items),
list(page.id for page in test_page.similar_items),
[
self.three_matches_page,
self.two_matches_page,
self.single_match_page,
self.three_matches_page.id,
self.two_matches_page.id,
self.single_match_page.id,
],
)

Expand All @@ -98,5 +98,5 @@ def test_further_queries_prevented_when_no_tags_available(self):

def test_search_prevented_if_no_tag_matches_identified(self):
test_page = ArticlePage.objects.get(id=self.different_tags_page.id)
with self.assertNumQueries(3):
with self.assertNumQueries(4):
self.assertFalse(test_page.similar_items)
20 changes: 20 additions & 0 deletions etna/ciim/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,21 @@ class LevelKeys(StrEnum):
LEVEL_7 = "Item"


@forTemplate
class NonTNALevelKeys(StrEnum):
LEVEL_1 = "Fonds"
LEVEL_2 = "Sub-fonds"
LEVEL_3 = "Sub-sub-fonds"
LEVEL_4 = "Sub-sub-sub-fonds"
LEVEL_5 = "Series"
LEVEL_6 = "Sub-series"
LEVEL_7 = "Sub-sub-series"
LEVEL_8 = "Sub-sub-sub-series"
LEVEL_9 = "File"
LEVEL_10 = "Item"
LEVEL_11 = "Sub-item"


LEVELS = (
"Division",
"Lettercode",
Expand Down Expand Up @@ -749,3 +764,8 @@ class Display(StrEnum):
"long_display_name": "Paper catalogues available to view at The National Archives",
},
]

CLOSURE_CLOSED_STATUS = [
"Closed Or Retained Document, Closed Description",
"Closed Or Retained Document, Open Description",
]
1 change: 1 addition & 0 deletions etna/records/field_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
"related_records": "Related records",
"related_articles": "Related content",
"related_materials": "Related material",
"closure": "Closure Status",
}
192 changes: 192 additions & 0 deletions etna/records/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ def iaid(self) -> str:
except KeyError:
candidate = self.get("@admin.id", default="")

try:
# fallback for Record Creators
if not candidate:
candidate = self.template["primaryIdentifier"]
except KeyError:
candidate = ""

if candidate and re.match(IAIDConverter.regex, candidate):
# value is not guaranteed to be a valid 'iaid', so we must
# check it before returning it as one
Expand Down Expand Up @@ -713,6 +720,191 @@ def archive_accessions(self) -> Optional[AccessionsInfo]:
def archive_repository_url(self) -> str:
return self.get("repository.url", "")

@cached_property
def alternative_names(self) -> tuple(dict):
alternative_names = ()
if names := self.get("name", ()):
for item in names:
if type := item.get("type", ""):
if type in (
"maiden name",
"also known as",
"formerly known as",
"later known as",
"pseudonym",
"relation of",
"real name",
"standardised form of name according to other rules",
):
alternative_names += (
{
"label": type.capitalize(),
"value": item.get("value", ""),
},
)
elif type == "unknown / other":
alternative_names += (
{"label": type.title(), "value": item.get("value", "")},
)

return alternative_names

@cached_property
def first_name(self) -> str:
first_name = ""
if name_data := self.get("name", ()):
for item in name_data:
if first_name_list := item.get("first_name"):
first_name = " ".join(first_name_list)
return first_name

@cached_property
def last_name(self) -> str:
if name_data := self.get("name", ()):
for item in name_data:
if last_name := item.get("last_name", ""):
return last_name
return ""

@cached_property
def title_prefix(self) -> str:
if name_data := self.get("name", ()):
for item in name_data:
if title_prefix := item.get("title_prefix"):
return title_prefix
return ""

@cached_property
def title_for_name(self) -> str:
if name_data := self.get("name", ()):
for item in name_data:
if title := item.get("title"):
return title
return ""

@cached_property
def gender(self) -> str:
if gender := self.get("gender", ""):
if gender == "M":
return "Male"
elif gender == "F":
return "Female"
logger.debug(
f"Gender value={gender} could not be translated for iaid={self.iaid}"
)
return gender

@cached_property
def history(self) -> str:
if description := self.get("description", ()):
for item in description:
if item.get("type") == "history":
if value := item.get("value", ""):
return mark_safe(value)
return ""

@cached_property
def biography(self) -> dict:
if description := self.get("description", ()):
for item in description:
if item.get("type") == "biography":
return {"value": item.get("value", ""), "url": item.get("url", "")}
return {}

@cached_property
def func_occup_activ(self) -> str:
if description := self.get("description", ()):
for item in description:
if item.get("type") == "functions, occupations and activities":
if value := item.get("value", ""):
document = pq(value)
for tag in ("foa", "function"):
if doc_value := document(tag).text():
return doc_value
return value
return ""

@cached_property
def places(self) -> tuple(str):
places = ()
if place := self.get("place", ()):
for item in place:
if name := item.get("name", ()):
for item in name:
if value := item.get("value", ""):
places += (value,)
return places

@cached_property
def birth_date(self) -> str:
return extract(self.get("birth", {}), "date.value", default="")

@cached_property
def death_date(self) -> str:
return extract(self.get("death", {}), "date.value", default="")

@cached_property
def start_date(self) -> str:
if date := extract(self.get("start", {}), "date", default=()):
for item in date:
if value := item.get("value", ""):
return value
return ""

@cached_property
def end_date(self) -> str:
if date := extract(self.get("end", {}), "date", default=()):
for item in date:
if value := item.get("value", ""):
return value
return ""

@cached_property
def record_creators_date(self) -> str:
"""
Returns dates for person, person's activity/service, both, or any if available
"""
separator = "-"
joiner = "; "
person_date = service_activity_date = ""
if self.birth_date and self.death_date:
person_date = f"{self.birth_date}{separator}{self.death_date}"
else:
person_date = self.birth_date or self.death_date

if self.start_date and self.end_date:
service_activity_date = f"{self.start_date}{separator}{self.end_date}"
else:
service_activity_date = self.start_date or self.end_date

# return self.birth_date or self.death_date or self.start_date or self.end_date
if person_date and service_activity_date:
return joiner.join([person_date, service_activity_date])

return person_date or service_activity_date

@cached_property
def name_authority_reference(self) -> str:
if identifier := self.get("identifier", ()):
for item in identifier:
if name_authority_reference := item.get("name_authority_reference", ""):
return name_authority_reference
return ""

@cached_property
def former_name_authority_reference(self) -> str:
if identifier := self.get("identifier", ()):
for item in identifier:
if former_name_authority_reference := item.get(
"former_name_authority_reference", ""
):
return former_name_authority_reference
return ""

@cached_property
def closure_status(self) -> str:
return extract(self.get("@template", {}), "details.closureStatus", default="")


@dataclass
class Image:
Expand Down
Loading
Loading