PlayOn facilities, primarily access to the download API. Includes a nice command line tool.
Latest release 20260531:
- DOwnloads: use cs.rfc2616.content_length to get the download content-length, open the download file with 'xb'.
- PlayOnAPI is now the source of the sqltags, do not expect to access it outside.
- New _PlayOnEntity(HasSQLTags) base class for Recording and LoginState.
- PlayOnAPI: new .login_userid property for external use.
- PlayOnAPI.getitem: an int index is promoted to ('recording,str(index)) for lookup.
- PlayOnAPI: new .recordings() finding playon.recording.*; use it for iter.
- PlayOnAPI: new .recording_ids_from_str() method for use by the CLI.
- PlayOnAPI: use the new UsesTagSets stuff.
- The PlayOn API has started reciting times with a microsecond field.
- PlayOnAPI.from_playon_date: accomodate time formats with and without microseconds.
- Recording.STALE_AGE -> Recording.refresh_lifespan for Refreshable.
- PlayOnCommand.cmd_dl: use pmap() to run the downloads in parallel.
- Assorted other internal changes.
Short summary:
main: Playon command line mode; see thePlayOnCommandclass below.PlayOnAPI: Access to the PlayOn API.PlayOnCommand: Playon command line implementation.PlayonSeriesEpisodeInfo: ASeriesEpisodeInfowith afrom_Recording()factory method to build one from a PlayOnRecordinginstead or other mapping withplayon.*keys.PlayOnSQLTags: PlayOn flavouredSQLTags; it just has custom values for the default db location.Recording: A PlayOn recording.
Module contents:
main(argv=None): Playon command line mode; see thePlayOnCommandclass below.class PlayOnAPI(cs.service_api.HTTPServiceAPI): Access to the PlayOn API.
PlayOnAPI.HasTagsClass
PlayOnAPI.TagSetsClass
PlayOnAPI.__getitem__(self, index: tuple | int) -> cs.tagset.HasTags:
If index is an int return the associated Recording.
Otherwise index should be a tuple, returns the associated HasTags.
PlayOnAPI.__iter__(self):
Iteration iterates over the recordins.
PlayOnAPI.account(self):
Return account information.
PlayOnAPI.as_contextmanager(self):
Run the generator from the cls class specific __enter_exit__
method via self as a context manager.
Example from RunState which subclasses HasThreadState,
both of which are ContextManagerMixin subclasses:
class RunState(HasThreadState):
.....
def __enter_exit__(self):
with HasThreadState.as_contextmanager(self):
... RunState context manager stuff ...
This runs the HasThreadState context manager
around the main RunState context manager.
PlayOnAPI.auth_token:
An auth token obtained from the login state.
PlayOnAPI.available(self):
Yield the Recordings.
Note that this includes both recorded and queued items.
PlayOnAPI.by_entity_id(entity_id: str) -> cs.tagset.HasTags:
Return the HasTags instance corresponding to entity_id
from the full tb
Raise ValueError is entity_id cannot be parsed by
TagSetTyping.type_parts_of.
Raise KeyError if there is no UsesTagSets instance for the zone.
PlayOnAPI.cdsurl_data(self, suburl, method='GET', headers=None, **kw):
Wrapper for suburl_data using CDS_BASE as the base URL.
PlayOnAPI.download(self, download_id: int, filename=None, *, quiet: bool, runstate: Optional[cs.resources.RunState] = <function uses_runstate.<locals>.<lambda> at 0x10e6c3ce0>, verbose: bool):
Download the file with download_id to filename_basis.
Return the TagSet for the recording.
The default filename is the basename of the filename
from the download.
If the filename is supplied with a trailing dot ('.')
then the file extension will be taken from the filename
of the download URL.
PlayOnAPI.feature(self, feature_id):
Return the feature SQLTags instance for feature_id.
PlayOnAPI.featured_image_url(self, feature_name: str):
URL of the image for a featured show.
PlayOnAPI.features(self):
Fetch the list of featured shows.
PlayOnAPI.fetch_recordings(self, *, verbose=False) -> set[cs.app.playon.Recording]:
Return a set of the Recording instances for the available recordings.
This makes an API request.
PlayOnAPI.from_playon_date(date_s) -> datetime.datetime:
Return a timezone aware datetime from a PlayOn date/time value;
The PlayOn API seems to use UTC date strings.
PlayOnAPI.jwt:
The JWT token.
PlayOnAPI.login(self):
Perform a login, return the resulting dict.
Does not update the state of self.
PlayOnAPI.login_expiry:
Expiry UNIX time for the login state.
PlayOnAPI.ls(self, recording_specs, *, format: str, long_mode=False):
List the specified recordings.
PlayOnAPI.notifications(self):
Return the notifications.
PlayOnAPI.queue(self):
Return the TagSet instances for the queued recordings.
PlayOnAPI.recording_ids_from_str(self, arg):
Convert a string to a list of recording ids.
PlayOnAPI.recordings(self):
Yield the Recordings.
Note that this includes both recorded and queued items.
PlayOnAPI.renew_jwt(self):
UNUSED
PlayOnAPI.service(self, service_id: str):
Return the service SQLTags instance for service_id.
PlayOnAPI.services(self):
Fetch the list of services.
PlayOnAPI.suburl(self, suburl, *, api_version=None, headers=None, base_url=None, **kw):
Override HTTPServiceAPI.suburl with default
headers={'Authorization':self.jwt}.
-
class PlayOnCommand(cs.cmdutils.BaseCommand): Playon command line implementation.Usage summary:
Usage: playon [common-options...] subcommand [args...] Environment: PLAYON_USER PlayOn login name, default from $EMAIL. PLAYON_PASSWORD PlayOn password. This is obtained from .netrc if omitted. PLAYON_FILENAME_FORMAT Format string for downloaded filenames. Default: {series_prefix}{series_episode_name}--{resolution}--{playon.ProviderID}--playon--{playon.ID} PLAYON_TAGS_DBURL Location of state tags database. Default: ~/var/playon.sqlite Recording specification: an int The specific recording id. all All known recordings. downloaded Recordings already downloaded. expired Recording which are no longer available. pending Recordings not already downloaded. /regexp Recordings whose Series or Name match the regexp, case insensitive. Subcommands: account [common-options...] Report account state. api [common-options...] suburl GET suburl via the API, print result. cds [common-options...] suburl GET suburl via the content delivery API, print result. Example subpaths: content content/provider-name dl [common-options...] [recordings...] Download the specified recordings, default "pending". Options: -j dl-jobs Concurrent download jobs. downloaded [common-options...] recordings... Mark the specified recordings as downloaded and no longer pending. feature [common-options...] [feature_id] List features. Options: -l Long mode. help [common-options...] [-l] [-s] [subcommand-names...] Print help for subcommands. This outputs the full help for the named subcommands, or the short help for all subcommands if no names are specified. Options: -l Long listing. -r Recurse into subcommands. -s Short listing. info [common-options...] [field-names...] Recite general information. Explicit field names may be provided to override the default listing. ls [common-options...] [recordings...] List available downloads. Options: -l Long listing: list tags below each entry. -o ls-format Format string for each entry. Default format: {playon.ID} {playon.HumanSize} {resolution} {nice_name} {playon.ProviderID} {status:upper} poll [common-options...] [options...] q [common-options...] [recordings...] List queued recordings. Options: -l Long listing: list tags below each entry. -o queue-format Format string for each entry. Default format: {playon.ID} {playon.Series} {playon.Name} {playon.ProviderID} queue [common-options...] [recordings...] List queued recordings. Options: -l Long listing: list tags below each entry. -o queue-format Format string for each entry. Default format: {playon.ID} {playon.Series} {playon.Name} {playon.ProviderID} refresh [common-options...] [queue] [recordings] Update the db state from the PlayOn service. rename [common-options...] [-o filename_format] filenames... Rename the filenames according to their fstags. -n No action, dry run. -o filename_format Format for the new filename, default '{series_prefix}{series_episode_name}--{resolution}--{playon.ProviderID}--playon--{playon.ID}'. Options: -o filename-format Filename format. repl [common-options...] Run a REPL (Read Evaluate Print Loop), an interactive Python prompt. Options: --banner banner Banner. service [common-options...] [service_id] List services. shell [common-options...] Run a command prompt via cmd.Cmd using this command's subcommands.
PlayOnCommand.Options
PlayOnCommand.cmd_account(self, argv):
Usage: {cmd}
Report account state.
PlayOnCommand.cmd_api(self, argv):
Usage: {cmd} suburl
GET suburl via the API, print result.
PlayOnCommand.cmd_cds(self, argv):
Usage: {cmd} suburl
GET suburl via the content delivery API, print result.
Example subpaths:
content
content/provider-name
PlayOnCommand.cmd_dl(self, argv):
Usage: {cmd} [recordings...]
Download the specified recordings, default "pending".
Options:
-j dl-jobs Concurrent download jobs.
PlayOnCommand.cmd_downloaded(self, argv, locale='en_US'):
Usage: {cmd} recordings...
Mark the specified recordings as downloaded and no longer pending.
PlayOnCommand.cmd_feature(self, argv, locale='en_US'):
Usage: {cmd} [feature_id]
List features.
Options:
-l Long mode.
PlayOnCommand.cmd_ls(self, argv):
Usage: {cmd} [recordings...]
List available downloads.
Options:
-l Long listing: list tags below each entry.
-o ls-format Format string for each entry. Default format:
{LS_FORMAT}
PlayOnCommand.cmd_q(self, argv):
Usage: {cmd} [recordings...]
List queued recordings.
Options:
-l Long listing: list tags below each entry.
-o queue-format Format string for each entry. Default format:
{QUEUE_FORMAT}
PlayOnCommand.cmd_queue(self, argv):
Usage: {cmd} [recordings...]
List queued recordings.
Options:
-l Long listing: list tags below each entry.
-o queue-format Format string for each entry. Default format:
{QUEUE_FORMAT}
PlayOnCommand.cmd_refresh(self, argv):
Usage: {cmd} [queue] [recordings]
Update the db state from the PlayOn service.
PlayOnCommand.cmd_rename(self, argv, *, fstags: Optional[cs.fstags.FSTags] = <function <lambda> at 0x10cfa7a60>):
Usage: {cmd} [-o filename_format] filenames...
Rename the filenames according to their fstags.
-n No action, dry run.
-o filename_format
Format for the new filename, default {DEFAULT_FILENAME_FORMAT!r}.
Options:
-o filename-format Filename format.
PlayOnCommand.cmd_service(self, argv, locale='en_US'):
Usage: {cmd} [service_id]
List services.
PlayOnCommand.run_context(self):
Prepare the PlayOnAPI around each command invocation.
class PlayonSeriesEpisodeInfo(cs.mediainfo.SeriesEpisodeInfo): ASeriesEpisodeInfowith afrom_Recording()factory method to build one from a PlayOnRecordinginstead or other mapping withplayon.*keys.
PlayonSeriesEpisodeInfo.from_Recording(R: Mapping[str, Any]):
Infer series episode information from a Recording
or any mapping with ".playon.*" keys.
class PlayOnSQLTags(cs.sqltags.SQLTags): PlayOn flavouredSQLTags; it just has custom values for the default db location.class Recording(_PlayOnEntity): A PlayOn recording.
Recording.filename(self, filename_format=None) -> str:
Return the computed filename per filename_format,
default from DEFAULT_FILENAME_FORMAT: '{series_prefix}{series_episode_name}--{resolution}--{playon.ProviderID}--playon--{playon.ID}'.
Recording.is_available(self):
Is a recording available for download?
Recording.is_downloaded(self):
Test whether this recording has been downloaded
based on the presence of a download_path Tag
or a true downloaded Tag.
Recording.is_expired(self):
Test whether this recording is expired,
which implies that it is no longer available for download.
Recording.is_pending(self):
A pending download: available and not already downloaded.
Recording.is_queued(self):
Is a recording still in the queue?
Recording.ls(self, *, format=None, long_mode=False, print_func=None):
List a recording.
Recording.nice_name(self):
A nice name for the recording: the PlayOn series and name,
omitting the series if that is None.
Recording.recording_id(self):
The recording id or None.
Recording.refresh_needed(self, **kw):
Override for Refreshable.refresh_needed which always
returns False for expired recordings.
Recording.resolution(self):
The recording resolution derived from the quality
via the Recording.RECORDING_QUALITY mapping.
Recording.series_prefix(self):
Return a series prefix for recording containing the series name
and season and episode, or ''.
Recording.status(self):
Return a short status string.
Release Log
Release 20260531:
- DOwnloads: use cs.rfc2616.content_length to get the download content-length, open the download file with 'xb'.
- PlayOnAPI is now the source of the sqltags, do not expect to access it outside.
- New _PlayOnEntity(HasSQLTags) base class for Recording and LoginState.
- PlayOnAPI: new .login_userid property for external use.
- PlayOnAPI.getitem: an int index is promoted to ('recording,str(index)) for lookup.
- PlayOnAPI: new .recordings() finding playon.recording.*; use it for iter.
- PlayOnAPI: new .recording_ids_from_str() method for use by the CLI.
- PlayOnAPI: use the new UsesTagSets stuff.
- The PlayOn API has started reciting times with a microsecond field.
- PlayOnAPI.from_playon_date: accomodate time formats with and without microseconds.
- Recording.STALE_AGE -> Recording.refresh_lifespan for Refreshable.
- PlayOnCommand.cmd_dl: use pmap() to run the downloads in parallel.
- Assorted other internal changes.
Release 20241007: Make things more cancellable.
Release 20240723:
- Replace many raises of RuntimeError with NotImplementedError, suggestion by @dimaqq on discuss.python.org.
- This update tracks some bugfixes in some required modules.
Release 20240522: New superior tv-series/season/episode inference.
Release 20240316: Fixed release upload artifacts.
Release 20240201.1: Release with "playon" script.
Release 20240201:
- PlayOnCommand.cmd_dl: collapse dashes more reliably, restore the space squashing, make the downloads interruptable.
- PlayOnCommand._list: sort each listing argument by recording id.
Release 20230705: DEFAULT_FILENAME_FORMAT: replace naive playon.Name with series_episode_name which is the name with leading series/episode info removed, honour in "playon dl".
Release 20230703:
- PlayOnAPI: features, feature, featured_image_url, service_image_url.
- PlayOnCommand: new cmd_feature like cmd_service but for featured shows.
- PlayOnAPI.suburl: infer _base_url from api_version if _base_url is None and api_version is provided.
- Recording.is_downloaded: also check for a 'downloaded' tag, fallback for when the downloaded_path is empty.
- PlayOnCommand.cmd_downloaded: add 'downloaded" tag to specified recordings.
Release 20230217:
- Move some core stuff off into cs.service_api.HTTPServiceAPI.
- Move core Recording.is_stale() method to TagSet.is_stale(), leave override method behind.
- Persist login tokens in a db for reuse while still fresh.
- "playon dl": allow interrupting downloads.
- Cleaner handling of playon.Name having a leading SNNeNN prefix.
Release 20221228:
- PlayOnAPI.suburl_data: progress reporting, raise on bad response, upgrade JSON error warning.
- PlayOnAPI: use a common cookie jar across API calls.
- PlayOnCommand: new "api" and "cds" API access subcommands.
- PlayOnCommand._refresh_sqltags_data: bugfix "expired cache" logic.
- PlayOnCommand: new "poll" subcommand reporting the API notifications response.
Release 20220311: Bugfix criteria for refreshing the PlayOn state.
Release 20211212: Initial release.
Release files for cs-app-playon 20260531
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cs_app_playon-20260531.tar.gz | 19.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cs_app_playon-20260531-py2.py3-none-any.whl | Python 3, Python 2 | none | any | Details |
Total release size: 37.0 kB
Release files / cs_app_playon-20260531.tar.gz
| Download URL | cs_app_playon-20260531.tar.gz |
|---|---|
| Size | 19.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
71f29bdfe15583fbbcb2677074a885ec58c4bac9a5a594055b8a5c069a769629
|
|
BLAKE2b-256 checksum How to use checksums |
83a069c309e9c0091943eaee2c97b9948a2efc8bfc662ccddab54836ebb47fba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.1
|
Release files / cs_app_playon-20260531-py2.py3-none-any.whl
| Download URL | cs_app_playon-20260531-py2.py3-none-any.whl |
|---|---|
| Size | 17.4 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
a20249d95514f97e6b28b18ff433194b2c6c397ed16216fb698fb39c315cf233
|
|
BLAKE2b-256 checksum How to use checksums |
a07a4b722af0c83010bab1a3f9328ef648abd8fda3483ba702b64b0aaf3d5233
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.1
|