Skip to content

Commit

Permalink
Float durations for audiobooks are serialized into the feeds
Browse files Browse the repository at this point in the history
  • Loading branch information
RishiDiwanTT committed Oct 24, 2023
1 parent 2e7e1ce commit 141db89
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/feed/annotator/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ def annotate_work_entry(
if edition.series:
computed.series = self.series(edition.series, edition.series_position)

if edition.duration is not None:
computed.duration = float(edition.duration)

content = self.content(work)
if content:
computed.summary = FeedEntryType(text=content)
Expand Down
4 changes: 4 additions & 0 deletions core/feed/serializer/opds.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ def serialize_work_entry(self, feed_entry: WorkEntryData) -> etree._Element:
feed_entry.subtitle.text,
)
)
if feed_entry.duration is not None:
entry.append(
OPDSFeed.E(f"{{{OPDSFeed.ATOM_NS}}}duration", str(feed_entry.duration))
)
if feed_entry.summary:
entry.append(OPDSFeed.E("summary", feed_entry.summary.text))
if feed_entry.pwid:
Expand Down
2 changes: 2 additions & 0 deletions core/feed/serializer/opds2.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def serialize_work_entry(self, data: WorkEntryData) -> Dict[str, Any]:
metadata["title"] = data.title.text
if data.sort_title:
metadata["sortAs"] = data.sort_title.text
if data.duration is not None:
metadata["duration"] = data.duration

if data.subtitle:
metadata["subtitle"] = data.subtitle.text
Expand Down
1 change: 1 addition & 0 deletions core/feed/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class WorkEntryData(BaseModel):
identifier: Optional[str] = None
pwid: Optional[str] = None
issued: Optional[datetime | date] = None
duration: Optional[float] = None

summary: Optional[FeedEntryType] = None
language: Optional[FeedEntryType] = None
Expand Down
2 changes: 2 additions & 0 deletions tests/api/feed/test_opds2_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def test_serialize_work_entry(self):
Acquisition(href="http://acquisition", rel="acquisition-rel")
],
other_links=[Link(href="http://link", rel="rel")],
duration=10,
)

serializer = OPDS2Serializer()
Expand All @@ -92,6 +93,7 @@ def test_serialize_work_entry(self):
assert metadata["@type"] == data.additionalType
assert metadata["title"] == data.title.text
assert metadata["sortAs"] == data.sort_title.text
assert metadata["duration"] == data.duration
assert metadata["subtitle"] == data.subtitle.text
assert metadata["identifier"] == data.identifier
assert metadata["language"] == data.language.text
Expand Down
5 changes: 5 additions & 0 deletions tests/api/feed/test_opds_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def test_serialize_work_entry(self):
FeedEntryType.create(scheme="scheme", term="term", label="label")
],
ratings=[FeedEntryType(text="rating")],
duration=10,
)

element = OPDS1Serializer().serialize_work_entry(data)
Expand Down Expand Up @@ -238,6 +239,10 @@ def test_serialize_work_entry(self):
assert len(child) == 1
assert child[0].text == data.ratings[0].text

child = element.findall(f"{{{OPDSFeed.ATOM_NS}}}duration")
assert len(child) == 1
assert child[0].text == "10"

def test_serialize_work_entry_empty(self):
# A no-data work entry
element = OPDS1Serializer().serialize_work_entry(WorkEntryData())
Expand Down
6 changes: 6 additions & 0 deletions tests/core/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ def test_from_edition(self, db: DatabaseTransactionFixture):
edition.primary_identifier.add_link(
Hyperlink.IMAGE, "image", edition.data_source
)
edition.duration = 100.1
metadata = Metadata.from_edition(edition)

# make sure the metadata and the originating edition match
Expand Down Expand Up @@ -704,6 +705,7 @@ def test_update(self, db: DatabaseTransactionFixture):
edition_old.subtitle = "old_subtitile"
edition_old.series = "old_series"
edition_old.series_position = 5
edition_old.duration = 10
metadata_old = Metadata.from_edition(edition_old)

edition_new, pool = db.edition(with_license_pool=True)
Expand All @@ -712,6 +714,7 @@ def test_update(self, db: DatabaseTransactionFixture):
edition_new.subtitle = "new_updated_subtitile"
edition_new.series = "new_series"
edition_new.series_position = 0
edition_new.duration = 11
metadata_new = Metadata.from_edition(edition_new)

metadata_old.update(metadata_new)
Expand All @@ -720,6 +723,7 @@ def test_update(self, db: DatabaseTransactionFixture):
assert metadata_old.subtitle == metadata_new.subtitle
assert metadata_old.series == edition_new.series
assert metadata_old.series_position == edition_new.series_position
assert metadata_old.duration == metadata_new.duration

def test_apply(self, db: DatabaseTransactionFixture):
edition_old, pool = db.edition(with_license_pool=True)
Expand All @@ -737,6 +741,7 @@ def test_apply(self, db: DatabaseTransactionFixture):
imprint="Follywood",
published=datetime.date(1987, 5, 4),
issued=datetime.date(1989, 4, 5),
duration=10,
)

edition_new, changed = metadata.apply(edition_old, pool.collection)
Expand All @@ -753,6 +758,7 @@ def test_apply(self, db: DatabaseTransactionFixture):
assert edition_new.imprint == "Follywood"
assert edition_new.published == datetime.date(1987, 5, 4)
assert edition_new.issued == datetime.date(1989, 4, 5)
assert edition_new.duration == 10

edition_new, changed = metadata.apply(edition_new, pool.collection)
assert changed == False
Expand Down

0 comments on commit 141db89

Please sign in to comment.