Source code for arxiv.canonical.integrity.listing
from datetime import date
from typing import Optional, Type
from ..manifest import ManifestEntry, Manifest
from .core import (IntegrityBase, IntegrityEntryBase, D, R, _Self,
Year, Month, YearMonth, calculate_checksum)
[docs]class IntegrityListing(IntegrityEntryBase[R.RecordListing]):
record_type = R.RecordListing
[docs] @classmethod
def from_record(cls: Type[_Self], record: R.RecordListing,
checksum: Optional[str] = None,
calculate_new_checksum: bool = True) -> _Self:
"""Make an :class:`.IntegrityListing` from a :class:`.RecordListing."""
if calculate_new_checksum:
checksum = calculate_checksum(record.stream)
return cls(name=record.key, record=record, checksum=checksum)
# This is redefined since the entry has no manifest; the record entry is
# used instead.
[docs] def calculate_checksum(self) -> str:
return calculate_checksum(self.record.stream)
[docs]class IntegrityListingDay(IntegrityBase[date,
R.RecordListingDay,
D.ListingIdentifier,
IntegrityListing]):
"""Integrity collection of listings for a single day."""
[docs] @classmethod
def make_manifest_entry(cls, member: IntegrityListing) -> ManifestEntry:
assert isinstance(member.record.domain, D.Listing)
return ManifestEntry(key=member.manifest_name,
checksum=member.checksum,
size_bytes=member.record.stream.size_bytes,
mime_type=member.record.stream.content_type.mime_type,
number_of_versions=0,
number_of_events=len(member.record.domain.events),
number_of_events_by_type=member.record.domain.number_of_events_by_type)
@property
def manifest_name(self) -> str:
"""The name to use for this record in a parent manifest."""
return self.name.isoformat()
[docs] @classmethod
def from_record(cls: Type[_Self], record: R.RecordListingDay,
checksum: Optional[str] = None,
calculate_new_checksum: bool = True) -> _Self:
"""
Generate an :class:`.IntegrityListing` from a :class:`.RecordListing`.
"""
members = {name: IntegrityListing.from_record(record.members[name])
for name in record.members}
# members = {
# record.listing.name: IntegrityEntry.from_record(record.listing)
# }
manifest = cls.make_manifest(members)
if calculate_new_checksum:
checksum = calculate_checksum(manifest)
assert not isinstance(checksum, bool)
return cls(record.name, members=members, manifest=manifest,
checksum=checksum)
[docs]class IntegrityListingMonth(IntegrityBase[YearMonth,
R.RecordListingMonth,
date,
IntegrityListingDay]):
"""Integrity collection of listings for a single month."""
@property
def manifest_name(self) -> str:
"""The name to use for this record in a parent manifest."""
return f'{self.year}-{str(self.month).zfill(2)}'
@property
def month(self) -> Month:
"""The numeric month represented by this collection."""
return self.name[1]
@property
def year(self) -> Year:
"""The numeric year represented by this collection."""
return self.name[0]
[docs]class IntegrityListingYear(IntegrityBase[Year,
R.RecordListingYear,
YearMonth,
IntegrityListingMonth]):
"""Integrity collection of listings for a single year."""
@property
def year(self) -> Year:
"""The numeric year represented by this collection."""
return self.name
[docs]class IntegrityListings(IntegrityBase[str,
R.RecordListings,
Year,
IntegrityListingYear]):
"""Integrity collection of all listings."""