Source code for arxiv.canonical.record.metadata
import datetime
from io import BytesIO
from json import dumps, load
from typing import Type, IO, Iterable, Tuple
from .core import RecordEntry, RecordStream, D, _Self
[docs]class RecordMetadata(RecordEntry[D.Version]):
"""An entry for version metadata."""
[docs] @classmethod
def make_key(cls, identifier: D.VersionedIdentifier) -> D.Key:
if identifier.is_old_style:
filename = f'{identifier.numeric_part}v{identifier.version}.json'
else:
filename = f'{identifier}.json'
return D.Key(f'{cls.make_prefix(identifier)}/{filename}')
[docs] @classmethod
def make_prefix(cls, ident: D.VersionedIdentifier) -> str:
"""
Make a key prefix for an e-print record.
Parameters
----------
date : datetime.date
The day on which the first version of the e-print was announced.
ident : str
arXiv identifier
Returns
-------
str
"""
date_part = f'e-prints/{ident.year}/{str(ident.month).zfill(2)}'
if ident.is_old_style:
return f'{date_part}/{ident.category_part}/{ident.numeric_part}/v{ident.version}'
return f'{date_part}/{ident.arxiv_id}/v{ident.version}'
[docs] @classmethod
def from_domain(cls: Type[_Self], version: D.Version) -> _Self:
content, size_bytes = RecordMetadata._encode(version,
)
content_type = D.ContentType.json
key = RecordMetadata.make_key(version.identifier)
return cls(
key=key,
stream=RecordStream(
domain=D.CanonicalFile(
modified=version.updated_date,
size_bytes=size_bytes,
content_type=content_type,
ref=key,
filename=key.filename
),
content=content,
content_type=D.ContentType.json,
size_bytes=size_bytes
),
domain=version
)
@classmethod
def _encode(cls, version: D.Version) -> Tuple[IO[bytes], int]:
content = dumps(version.to_dict(), indent=2).encode('utf-8')
return BytesIO(content), len(content)
[docs] @classmethod
def to_domain(cls, stream: RecordStream) -> D.Version:
assert stream.content is not None
version = D.Version.from_dict(load(stream.content),
)
if stream.content.seekable:
stream.content.seek(0)
return version # RecordVersion.post_to_domain(version, load_content)
[docs] @classmethod
def from_stream(cls, key: D.Key, stream: RecordStream) -> 'RecordMetadata':
return cls(key=key, stream=stream, domain=cls.to_domain(stream))