Skip to content

Commit 6a747f4

Browse files
authored
Merge pull request #870 from fshowalter/draft
draft
2 parents 355f837 + b56c549 commit 6a747f4

File tree

12 files changed

+52
-177
lines changed

12 files changed

+52
-177
lines changed

booklog/exports/api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from booklog.exports import authors, reviewed_works, stats, timeline_entries
3+
from booklog.exports import authors, reading_entries, reviewed_works, stats
44
from booklog.exports.repository_data import RepositoryData
55
from booklog.repository import api as repository_api
66

@@ -26,5 +26,5 @@ def export_data() -> None:
2626

2727
authors.export(repository_data)
2828
reviewed_works.export(repository_data)
29-
timeline_entries.export(repository_data)
29+
reading_entries.export(repository_data)
3030
stats.export(repository_data)

booklog/exports/authors.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@ def _build_json_author_reviewed_work(
1212
repository_data: RepositoryData,
1313
) -> JsonReviewedWork:
1414
return JsonReviewedWork(
15-
reviewSequence=repository_data.review_sequence_map.get(work.slug, 0),
15+
reviewSequence=repository_data.review_sequence_map.get(work.slug, review.date.isoformat()),
1616
title=work.title,
1717
reviewed=True,
1818
subtitle=work.subtitle,
1919
workYear=work.year,
20-
workYearSequence=repository_data.work_year_sequence_map.get(work.slug, 0),
21-
authorSequence=repository_data.author_sequence_map.get(work.slug, 0),
22-
titleSequence=repository_data.title_sequence_map.get(work.slug, 0),
2320
kind=work.kind,
2421
slug=work.slug,
2522
sortTitle=work.sort_title,
2623
grade=review.grade,
2724
gradeValue=review.grade_value,
28-
gradeSequence=repository_data.grade_sequence_map.get(work.slug, 0),
2925
reviewDate=review.date,
3026
reviewYear=str(review.date.year),
3127
authors=[

booklog/exports/json_reviewed_work.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55

66

77
class JsonReviewedWork(JsonWork):
8-
reviewSequence: int
8+
reviewSequence: str
99
grade: str
1010
gradeValue: int
11-
gradeSequence: int
1211
reviewDate: datetime.date
1312
reviewYear: str
1413
reviewed: Literal[True]

booklog/exports/json_work.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ class JsonWork(TypedDict):
88
subtitle: str | None
99
sortTitle: str
1010
workYear: str
11-
workYearSequence: int
12-
authorSequence: int
13-
titleSequence: int
1411
authors: list[JsonWorkAuthor]
1512
kind: str
1613
slug: str
Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,50 @@
88
from booklog.utils.logging import logger
99

1010

11-
class JsonTimelineEntry(TypedDict):
12-
timelineSequence: int
11+
class JsonReadingEntry(TypedDict):
12+
readingEntrySequence: int
1313
slug: str
1414
edition: str
15-
timelineDate: datetime.date
15+
readingEntryDate: datetime.date
1616
progress: str
1717
reviewed: bool
1818
workYear: str
19-
workYearSequence: int
20-
authorSequence: int
21-
titleSequence: int
2219
title: str
2320
kind: str
2421
authors: list[JsonAuthor]
2522
includedInSlugs: list[str]
2623

2724

28-
def _build_json_timeline_entry_author(
25+
def _build_json_reading_entry_author(
2926
work_author: repository_api.WorkAuthor, authors: list[repository_api.Author]
3027
) -> JsonAuthor:
3128
author = work_author.author(authors)
3229
return JsonAuthor(name=author.name, sortName=author.sort_name, slug=author.slug)
3330

3431

35-
def _build_json_timeline_entry(
32+
def _build_json_reading_entry(
3633
reading: repository_api.Reading,
37-
timeline_entry: repository_api.TimelineEntry,
34+
reading_entry: repository_api.TimelineEntry,
3835
repository_data: RepositoryData,
39-
) -> JsonTimelineEntry:
36+
) -> JsonReadingEntry:
4037
work = reading.work(repository_data.works)
4138
reviewed = bool(work.review(repository_data.reviews))
4239

4340
# Create the key tuple for looking up the sequence number
44-
timeline_key = (str(timeline_entry.date), str(reading.timeline[-1].date), str(reading.sequence))
41+
entry_key = (str(reading_entry.date), str(reading.timeline[-1].date), str(reading.sequence))
4542

46-
return JsonTimelineEntry(
47-
timelineSequence=repository_data.timeline_sequence_map.get(timeline_key, 0),
43+
return JsonReadingEntry(
44+
readingEntrySequence=repository_data.reading_entry_sequence_map.get(entry_key, 0),
4845
slug=work.slug,
4946
edition=reading.edition,
5047
kind=work.kind,
51-
timelineDate=timeline_entry.date,
52-
progress=timeline_entry.progress,
48+
readingEntryDate=reading_entry.date,
49+
progress=reading_entry.progress,
5350
reviewed=reviewed,
5451
workYear=work.year,
55-
workYearSequence=repository_data.work_year_sequence_map.get(work.slug, 0),
56-
authorSequence=repository_data.author_sequence_map.get(work.slug, 0),
57-
titleSequence=repository_data.title_sequence_map.get(work.slug, 0),
5852
title=work.title,
5953
authors=[
60-
_build_json_timeline_entry_author(work_author, repository_data.authors)
54+
_build_json_reading_entry_author(work_author, repository_data.authors)
6155
for work_author in work.work_authors
6256
],
6357
includedInSlugs=[
@@ -70,17 +64,17 @@ def _build_json_timeline_entry(
7064
def export(repository_data: RepositoryData) -> None:
7165
logger.log("==== Begin exporting {}...", "timeline-entries")
7266

73-
json_progress = [
74-
_build_json_timeline_entry(
67+
json_entries = [
68+
_build_json_reading_entry(
7569
reading=reading,
76-
timeline_entry=timeline_entry,
70+
reading_entry=reading_entry,
7771
repository_data=repository_data,
7872
)
7973
for reading in repository_data.readings
80-
for timeline_entry in reading.timeline
74+
for reading_entry in reading.timeline
8175
]
8276

8377
exporter.serialize_dicts(
84-
sorted(json_progress, key=lambda progress: progress["timelineSequence"], reverse=True),
85-
"timeline-entries",
78+
sorted(json_entries, key=lambda entry: entry["readingEntrySequence"], reverse=True),
79+
"reading-entries",
8680
)

booklog/exports/repository_data.py

Lines changed: 11 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -10,113 +10,38 @@ class RepositoryData:
1010
works: list[repository_api.Work]
1111
readings: list[repository_api.Reading]
1212
reviews: list[repository_api.Review]
13-
work_year_sequence_map: dict[str, int] = field(default_factory=dict, init=False)
14-
author_sequence_map: dict[str, int] = field(default_factory=dict, init=False)
15-
title_sequence_map: dict[str, int] = field(default_factory=dict, init=False)
16-
review_sequence_map: dict[str, int] = field(default_factory=dict, init=False)
17-
grade_sequence_map: dict[str, int] = field(default_factory=dict, init=False)
18-
timeline_sequence_map: dict[tuple[str, str, str], int] = field(default_factory=dict, init=False)
13+
review_sequence_map: dict[str, str] = field(default_factory=dict, init=False)
14+
reading_entry_sequence_map: dict[tuple[str, str, str], int] = field(
15+
default_factory=dict, init=False
16+
)
1917
reading_sequence_map: dict[tuple[str, int], int] = field(default_factory=dict, init=False)
2018

2119
def __post_init__(self) -> None:
2220
"""Calculate sequence maps after initialization."""
23-
self.work_year_sequence_map = self._build_work_year_sequence_map()
24-
self.author_sequence_map = self._build_author_sequence_map()
25-
self.title_sequence_map = self._build_title_sequence_map()
2621
self.review_sequence_map = self._build_review_sequence_map()
27-
self.grade_sequence_map = self._build_grade_sequence_map()
28-
self.timeline_sequence_map = self._build_timeline_sequence_map()
22+
self.reading_entry_sequence_map = self._build_reading_entry_sequence_map()
2923
self.reading_sequence_map = self._build_reading_sequence_map()
3024

31-
def _build_work_year_sequence_map(self) -> dict[str, int]:
32-
"""Build a mapping of work slugs to their numeric position based on year-author-title sort.
33-
34-
Returns a dictionary where keys are work slugs and values are their 1-based
35-
position in the sorted order of "{work.year}-{first_author_sort_name}-{work.sort_title}".
36-
"""
37-
38-
def get_sort_key(work: repository_api.Work) -> str:
39-
first_author = work.work_authors[0].author(self.authors)
40-
first_author_sort_name = first_author.sort_name
41-
return f"{work.year}-{first_author_sort_name}-{work.sort_title}"
42-
43-
sorted_works = sorted(self.works, key=get_sort_key)
44-
return {work.slug: idx + 1 for idx, work in enumerate(sorted_works)}
45-
46-
def _build_author_sequence_map(self) -> dict[str, int]:
47-
"""Build a mapping of work slugs to their numeric position based on author-year-title sort.
48-
49-
Returns a dictionary where keys are work slugs and values are their 1-based
50-
position in the sorted order of "{first_author_sort_name}-{work.year}-{work.sort_title}".
51-
"""
52-
53-
def get_sort_key(work: repository_api.Work) -> str:
54-
first_author = work.work_authors[0].author(self.authors)
55-
first_author_sort_name = first_author.sort_name
56-
return f"{first_author_sort_name}-{work.year}-{work.sort_title}"
57-
58-
sorted_works = sorted(self.works, key=get_sort_key)
59-
return {work.slug: idx + 1 for idx, work in enumerate(sorted_works)}
60-
61-
def _build_title_sequence_map(self) -> dict[str, int]:
62-
"""Build a mapping of work slugs to their numeric position based on title-author-year sort.
63-
64-
Returns a dictionary where keys are work slugs and values are their 1-based
65-
position in the sorted order of "{work.sort_title}-{first_author_sort_name}-{work.year}".
66-
"""
67-
68-
def get_sort_key(work: repository_api.Work) -> str:
69-
first_author = work.work_authors[0].author(self.authors)
70-
first_author_sort_name = first_author.sort_name
71-
return f"{work.sort_title}-{first_author_sort_name}-{work.year}"
72-
73-
sorted_works = sorted(self.works, key=get_sort_key)
74-
return {work.slug: idx + 1 for idx, work in enumerate(sorted_works)}
75-
76-
def _build_review_sequence_map(self) -> dict[str, int]:
25+
def _build_review_sequence_map(self) -> dict[str, str]:
7726
"""Build a mapping of work slugs to their review sequence number.
7827
7928
Returns a dictionary where keys are work slugs and values are their 1-based
8029
position in the sorted order of "{review.date}-{most_recent_reading.sequence}".
8130
"""
82-
review_sequences: list[tuple[str, str]] = [] # (work_slug, sort_key)
83-
84-
for review in self.reviews:
85-
work = review.work(self.works)
86-
readings = list(work.readings(self.readings))
87-
88-
if readings:
89-
most_recent_reading = sorted(readings, key=lambda r: r.sequence, reverse=True)[0]
90-
sort_key = f"{review.date}-{most_recent_reading.sequence}"
91-
review_sequences.append((work.slug, sort_key))
92-
93-
# Sort by the sort_key and create mapping
94-
sorted_sequences = sorted(review_sequences, key=lambda x: x[1])
95-
return {work_slug: idx + 1 for idx, (work_slug, _) in enumerate(sorted_sequences)}
96-
97-
def _build_grade_sequence_map(self) -> dict[str, int]:
98-
"""Build a mapping of work slugs to their grade sequence number.
99-
100-
Returns a dictionary where keys are work slugs and values are their 1-based
101-
position in the sorted order of
102-
"{review.grade_value}-{review.date}-{most_recent_reading.sequence}".
103-
"""
104-
grade_sequences: list[tuple[str, str]] = [] # (work_slug, sort_key)
31+
review_sequences: dict[str, str] = {} # (work_slug, sort_key)
10532

10633
for review in self.reviews:
10734
work = review.work(self.works)
10835
readings = list(work.readings(self.readings))
10936

11037
if readings:
11138
most_recent_reading = sorted(readings, key=lambda r: r.sequence, reverse=True)[0]
112-
sort_key = f"{review.grade_value:02d}-{review.date}-{most_recent_reading.sequence}"
113-
grade_sequences.append((work.slug, sort_key))
39+
sort_key = f"{review.date}-{most_recent_reading.sequence:02}"
40+
review_sequences[work.slug] = sort_key
11441

115-
# Sort by the sort_key and create mapping
116-
sorted_sequences = sorted(grade_sequences, key=lambda x: x[1])
117-
return {work_slug: idx + 1 for idx, (work_slug, _) in enumerate(sorted_sequences)}
42+
return review_sequences
11843

119-
def _build_timeline_sequence_map(self) -> dict[tuple[str, str, str], int]:
44+
def _build_reading_entry_sequence_map(self) -> dict[tuple[str, str, str], int]:
12045
"""Build a mapping of timeline entries to their sequence number.
12146
12247
Returns a dictionary where keys are tuples of

booklog/exports/reviewed_works.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,16 @@ def _build_json_more_review(
5858
assert review, f"Expected review for {work.title}"
5959

6060
return JsonReviewedWork(
61-
reviewSequence=repository_data.review_sequence_map.get(work.slug, 0),
61+
reviewSequence=repository_data.review_sequence_map.get(work.slug, review.date.isoformat()),
6262
title=work.title,
6363
subtitle=work.subtitle,
6464
sortTitle=work.sort_title,
6565
kind=work.kind,
6666
workYear=work.year,
6767
reviewed=True,
68-
workYearSequence=repository_data.work_year_sequence_map.get(work.slug, 0),
69-
authorSequence=repository_data.author_sequence_map.get(work.slug, 0),
70-
titleSequence=repository_data.title_sequence_map.get(work.slug, 0),
7168
slug=work.slug,
7269
grade=review.grade,
7370
gradeValue=review.grade_value,
74-
gradeSequence=repository_data.grade_sequence_map.get(work.slug, 0),
7571
reviewDate=review.date,
7672
reviewYear=str(review.date.year),
7773
includedInSlugs=[
@@ -217,9 +213,6 @@ def _build_json_included_work(
217213
reviewed=bool(review),
218214
kind=included_work.kind,
219215
workYear=included_work.year,
220-
workYearSequence=repository_data.work_year_sequence_map.get(included_work.slug, 0),
221-
authorSequence=repository_data.author_sequence_map.get(included_work.slug, 0),
222-
titleSequence=repository_data.title_sequence_map.get(included_work.slug, 0),
223216
authors=[
224217
json_work_author.build_json_work_author(
225218
work_author=included_work_author, all_authors=repository_data.authors
@@ -246,19 +239,15 @@ def _build_json_reviewed_work(
246239
)
247240

248241
return JsonReviewedWorkWithDetails(
249-
reviewSequence=repository_data.review_sequence_map.get(work.slug, 0),
242+
reviewSequence=repository_data.review_sequence_map.get(work.slug, review.date.isoformat()),
250243
slug=work.slug,
251244
title=work.title,
252245
subtitle=work.subtitle,
253246
sortTitle=work.sort_title,
254247
workYear=work.year,
255248
reviewed=True,
256-
workYearSequence=repository_data.work_year_sequence_map.get(work.slug, 0),
257-
authorSequence=repository_data.author_sequence_map.get(work.slug, 0),
258-
titleSequence=repository_data.title_sequence_map.get(work.slug, 0),
259249
grade=review.grade,
260250
gradeValue=review.grade_value,
261-
gradeSequence=repository_data.grade_sequence_map.get(work.slug, 0),
262251
kind=work.kind,
263252
reviewDate=review.date,
264253
authors=[
@@ -267,9 +256,7 @@ def _build_json_reviewed_work(
267256
)
268257
for work_author in work.work_authors
269258
],
270-
readings=[
271-
_build_json_reading(reading, repository_data) for reading in readings_for_work
272-
],
259+
readings=[_build_json_reading(reading, repository_data) for reading in readings_for_work],
273260
includedInSlugs=[
274261
included_in_work.slug
275262
for included_in_work in work.included_in_works(repository_data.works)

booklog/exports/stats.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ class JsonMostReadAuthorReading(TypedDict):
1717
kind: str
1818
title: str
1919
workYear: str
20-
workYearSequence: int
21-
authorSequence: int
22-
titleSequence: int
2320
includedInSlugs: list[str]
2421
reviewed: bool
2522

@@ -142,9 +139,6 @@ def _build_json_most_read_author_reading(
142139
kind=work.kind,
143140
title=work.title,
144141
workYear=work.year,
145-
workYearSequence=repository_data.work_year_sequence_map.get(work.slug, 0),
146-
authorSequence=repository_data.author_sequence_map.get(work.slug, 0),
147-
titleSequence=repository_data.title_sequence_map.get(work.slug, 0),
148142
includedInSlugs=[
149143
included_in_work.slug
150144
for included_in_work in work.included_in_works(repository_data.works)

tests/exports/__snapshots__/test_api/test_exports_authors.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"name": "Stephen King",
33
"reviewedWorks": [
44
{
5-
"authorSequence": 2,
65
"authors": [
76
{
87
"name": "Stephen King",
@@ -12,21 +11,18 @@
1211
}
1312
],
1413
"grade": "A+",
15-
"gradeSequence": 1,
1614
"gradeValue": 13,
1715
"includedInSlugs": [],
1816
"kind": "Nonfiction",
1917
"reviewDate": "2016-03-10",
20-
"reviewSequence": 1,
18+
"reviewSequence": "2016-03-10-01",
2119
"reviewYear": "2016",
2220
"reviewed": true,
2321
"slug": "on-writing-by-stephen-king",
2422
"sortTitle": "On Writing: A Memoir of the Craft",
2523
"subtitle": "A Memoir of the Craft",
2624
"title": "On Writing",
27-
"titleSequence": 1,
28-
"workYear": "2000",
29-
"workYearSequence": 2
25+
"workYear": "2000"
3026
}
3127
],
3228
"slug": "stephen-king",

0 commit comments

Comments
 (0)