#!/usr/bin/env python
from setuptools import setup
setup(
  name = 'cs.app.playon',
  author = 'Cameron Simpson',
  author_email = 'cs@cskk.id.au',
  version = '20220311',
  url = 'https://bitbucket.org/cameron_simpson/css/commits/all',
  description =
    ('PlayOn facilities, primarily access to the download API. Includes a nice '    
 'command line tool.'),
  long_description =
    ('PlayOn facilities, primarily access to the download API.\n'    
 'Includes a nice command line tool.\n'    
 '\n'    
 '*Latest release 20220311*:\n'    
 'Bugfix criteria for refreshing the PlayOn state.\n'    
 '\n'    
 '## Function `main(argv=None)`\n'    
 '\n'    
 'Playon command line mode;\n'    
 'see the `PlayOnCommand` class below.\n'    
 '\n'    
 '## Class `PlayOnAPI(cs.resources.MultiOpenMixin, '    
 'cs.context.ContextManagerMixin)`\n'    
 '\n'    
 'Access to the PlayOn API.\n'    
 '\n'    
 '*Method `PlayOnAPI.__getitem__(self, download_id: int)`*:\n'    
 'Return the recording `TagSet` associated with the recording `download_id`.\n'    
 '\n'    
 '*Method `PlayOnAPI.account(self, *a, **kw)`*:\n'    
 'Return account information.\n'    
 '\n'    
 '*Property `PlayOnAPI.auth_token`*:\n'    
 'An auth token obtained from the login state.\n'    
 '\n'    
 "*Method `PlayOnAPI.cdsurl_data(self, suburl, _method='GET', headers=None, "    
 '**kw)`*:\n'    
 'Wrapper for `suburl_data` using `CDS_BASE` as the base URL.\n'    
 '\n'    
 '*Method `PlayOnAPI.download(self, *a, **kw)`*:\n'    
 'Download the file with `download_id` to `filename_basis`.\n'    
 'Return the `TagSet` for the recording.\n'    
 '\n'    
 'The default `filename` is the basename of the filename\n'    
 'from the download.\n'    
 "If the filename is supplied with a trailing dot (`'.'`)\n"    
 'then the file extension will be taken from the filename\n'    
 'of the download URL.\n'    
 '\n'    
 '*Method `PlayOnAPI.from_playon_date(date_s)`*:\n'    
 'The PlayOn API seems to use UTC date strings.\n'    
 '\n'    
 '*Property `PlayOnAPI.jwt`*:\n'    
 'The JWT token.\n'    
 '\n'    
 '*Property `PlayOnAPI.login_state`*:\n'    
 'The login state, a `dict`. Performs a login if necessary.\n'    
 '\n'    
 '*Method `PlayOnAPI.queue(self, *a, **kw)`*:\n'    
 'Return the `TagSet` instances for the queued recordings.\n'    
 '\n'    
 '*Method `PlayOnAPI.recordings(self, *a, **kw)`*:\n'    
 'Return the `TagSet` instances for the available recordings.\n'    
 '\n'    
 '*Method `PlayOnAPI.service(self, service_id)`*:\n'    
 'Return the service `SQLTags` instance for `service_id`.\n'    
 '\n'    
 '*Method `PlayOnAPI.services(self, *a, **kw)`*:\n'    
 'Fetch the list of services.\n'    
 '\n'    
 '*Method `PlayOnAPI.startup_shutdown(self)`*:\n'    
 'Start up: open and init the `SQLTags`, open the `FSTags`.\n'    
 '\n'    
 "*Method `PlayOnAPI.suburl_data(self, suburl, _base_url=None, _method='GET', "    
 'headers=None, raw=False, **kw)`*:\n'    
 "Call `suburl` and return the `'data'` component on success.\n"    
 '\n'    
 'Parameters:\n'    
 '* `suburl`: the API subURL designating the endpoint.\n'    
 "* `_method`: optional HTTP method, default `'GET'`.\n"    
 '* `headers`: hreaders to accompany the request;\n'    
 "  default `{'Authorization':self.jwt}`.\n"    
 'Other keyword arguments are passed to the `requests` method\n'    
 'used to perform the HTTP call.\n'    
 '\n'    
 '*Method `PlayOnAPI.suburl_request(base_url, method, suburl)`*:\n'    
 'Return a curried `requests` method\n'    
 'to fetch `API_BASE/suburl`.\n'    
 '\n'    
 '## Class `PlayOnCommand(cs.cmdutils.BaseCommand)`\n'    
 '\n'    
 'Playon command line implementation.\n'    
 '\n'    
 'Command line usage:\n'    
 '\n'    
 '    Usage: playon subcommand [args...]\n'    
 '\n'    
 '        Environment:\n'    
 '          PLAYON_USER               PlayOn login name, default from $EMAIL.\n'    
 '          PLAYON_PASSWORD           PlayOn password.\n'    
 '                                    This is obtained from .netrc if '    
 'omitted.\n'    
 '          PLAYON_FILENAME_FORMAT  Format string for downloaded filenames.\n'    
 '                                    Default: '    
 '{playon.Series}--{playon.Name}--{resolution}--{playon.ProviderID}--playon--{playon.ID}\n'    
 '          PLAYON_TAGS_DBURL         Location of state tags database.\n'    
 '                                    Default: ~/var/playon.sqlite\n'    
 '\n'    
 '        Recording specification:\n'    
 '          an int        The specific recording id.\n'    
 '          all           All known recordings.\n'    
 '          downloaded    Recordings already downloaded.\n'    
 '          expired       Recording which are no longer available.\n'    
 '          pending       Recordings not already downloaded.\n'    
 '          /regexp       Recordings whose Series or Name match the regexp,\n'    
 '                        case insensitive.\n'    
 '\n'    
 '      Subcommands:\n'    
 '        account\n'    
 '          Report account state.\n'    
 '        dl [-j jobs] [-n] [recordings...]\n'    
 '          Download the specified recordings, default "pending".\n'    
 '          -j jobs   Run this many downloads in parallel.\n'    
 '                    The default is 2.\n'    
 '          -n        No download. List the specified recordings.\n'    
 '        help [-l] [subcommand-names...]\n'    
 '          Print the full help for the named subcommands,\n'    
 '          or for all subcommands if no names are specified.\n'    
 '          -l  Long help even if no subcommand-names provided.\n'    
 '        ls [-l] [recordings...]\n'    
 '          List available downloads.\n'    
 '          -l        Long listing: list tags below each entry.\n'    
 '          -o format Format string for each entry.\n'    
 '          Default format: {playon.ID} {playon.HumanSize} {resolution} '    
 '{playon.Series} {playon.Name} {playon.ProviderID} {status:upper}\n'    
 '        q [-l] [recordings...]\n'    
 '          List queued recordings.\n'    
 '          -l        Long listing: list tags below each entry.\n'    
 '          -o format Format string for each entry.\n'    
 '          Default format: {playon.ID} {playon.Series} {playon.Name} '    
 '{playon.ProviderID}\n'    
 '        queue [-l] [recordings...]\n'    
 '          List queued recordings.\n'    
 '          -l        Long listing: list tags below each entry.\n'    
 '          -o format Format string for each entry.\n'    
 '          Default format: {playon.ID} {playon.Series} {playon.Name} '    
 '{playon.ProviderID}\n'    
 '        refresh [queue] [recordings]\n'    
 '          Update the db state from the PlayOn service.\n'    
 '        service [service_id]\n'    
 '          List services.\n'    
 '\n'    
 '*Method `PlayOnCommand.cmd_account(self, argv)`*:\n'    
 'Usage: {cmd}\n'    
 'Report account state.\n'    
 '\n'    
 '*Method `PlayOnCommand.cmd_dl(self, argv)`*:\n'    
 'Usage: {cmd} [-j jobs] [-n] [recordings...]\n'    
 'Download the specified recordings, default "pending".\n'    
 '-j jobs   Run this many downloads in parallel.\n'    
 '          The default is {DEFAULT_DL_PARALLELISM}.\n'    
 '-n        No download. List the specified recordings.\n'    
 '\n'    
 '*Method `PlayOnCommand.cmd_ls(self, argv)`*:\n'    
 'Usage: {cmd} [-l] [recordings...]\n'    
 'List available downloads.\n'    
 '-l        Long listing: list tags below each entry.\n'    
 '-o format Format string for each entry.\n'    
 'Default format: {LS_FORMAT}\n'    
 '\n'    
 '*Method `PlayOnCommand.cmd_q(self, argv)`*:\n'    
 'Usage: {cmd} [-l] [recordings...]\n'    
 'List queued recordings.\n'    
 '-l        Long listing: list tags below each entry.\n'    
 '-o format Format string for each entry.\n'    
 'Default format: {QUEUE_FORMAT}\n'    
 '\n'    
 '*Method `PlayOnCommand.cmd_queue(self, argv)`*:\n'    
 'Usage: {cmd} [-l] [recordings...]\n'    
 'List queued recordings.\n'    
 '-l        Long listing: list tags below each entry.\n'    
 '-o format Format string for each entry.\n'    
 'Default format: {QUEUE_FORMAT}\n'    
 '\n'    
 '*Method `PlayOnCommand.cmd_refresh(self, argv)`*:\n'    
 'Usage: {cmd} [queue] [recordings]\n'    
 'Update the db state from the PlayOn service.\n'    
 '\n'    
 "*Method `PlayOnCommand.cmd_service(self, argv, locale='en_US')`*:\n"    
 'Usage: {cmd} [service_id]\n'    
 'List services.\n'    
 '\n'    
 '*Method `PlayOnCommand.run_context(self)`*:\n'    
 'Prepare the `PlayOnAPI` around each command invocation.\n'    
 '\n'    
 '## Class `PlayOnSQLTags(cs.sqltags.SQLTags, cs.tagset.BaseTagSets, '    
 'cs.resources.MultiOpenMixin, cs.context.ContextManagerMixin, '    
 'collections.abc.MutableMapping, collections.abc.Mapping, '    
 'collections.abc.Collection, collections.abc.Sized, collections.abc.Iterable, '    
 'collections.abc.Container)`\n'    
 '\n'    
 '`SQLTags` subclass with PlayOn related methods.\n'    
 '\n'    
 '*Method `PlayOnSQLTags.__iter__(self)`*:\n'    
 'Yield recording `TagSet`s, those named `"recording.*"`.\n'    
 '\n'    
 'Note that this includes both recorded and queued items.\n'    
 '\n'    
 '*Method `PlayOnSQLTags.infer_db_url(envvar=None, default_path=None)`*:\n'    
 'Infer the database URL.\n'    
 '\n'    
 'Parameters:\n'    
 '* `envvar`: environment variable to specify a default,\n'    
 '  default from `DBURL_ENVVAR` (`PLAYON_TAGS_DBURL`).\n'    
 '\n'    
 '*Method `PlayOnSQLTags.recording_ids_from_str(self, *a, **kw)`*:\n'    
 'Convert a string to a list of recording ids.\n'    
 '\n'    
 '*Method `PlayOnSQLTags.recordings(self)`*:\n'    
 'Yield recording `TagSet`s, those named `"recording.*"`.\n'    
 '\n'    
 'Note that this includes both recorded and queued items.\n'    
 '\n'    
 '## Class `Recording(cs.sqltags.SQLTagSet, cs.obj.SingletonMixin, '    
 'cs.tagset.TagSet, builtins.dict, cs.dateutils.UNIXTimeMixin, '    
 'cs.lex.FormatableMixin, cs.lex.FormatableFormatter, string.Formatter, '    
 'cs.mappings.AttrableMappingMixin)`\n'    
 '\n'    
 'An `SQLTagSet` with knowledge about PlayOn recordings.\n'    
 '\n'    
 '*Method `Recording.is_available(self)`*:\n'    
 'Is a recording available for download?\n'    
 '\n'    
 '*Method `Recording.is_downloaded(self)`*:\n'    
 'Test whether this recording has been downloaded\n'    
 'based on the presence of a `download_path` `Tag`.\n'    
 '\n'    
 '*Method `Recording.is_expired(self)`*:\n'    
 'Test whether this recording is expired,\n'    
 'which implies that it is no longer available for download.\n'    
 '\n'    
 '*Method `Recording.is_pending(self)`*:\n'    
 'A pending download: available and not already downloaded.\n'    
 '\n'    
 '*Method `Recording.is_queued(self)`*:\n'    
 'Is a recording still in the queue?\n'    
 '\n'    
 '*Method `Recording.is_stale(self, max_age=None)`*:\n'    
 'Test whether this entry is stale\n'    
 'i.e. the time since `self.last_updated` exceeds `max_age` seconds\n'    
 '(default from `self.STALE_AGE`).\n'    
 'Note that expired recordings are never stale\n'    
 'because they can no longer be queried from the API.\n'    
 '\n'    
 '*Method `Recording.ls(self, ls_format=None, long_mode=False, '    
 'print_func=None)`*:\n'    
 'List a recording.\n'    
 '\n'    
 '*Method `Recording.nice_name(self)`*:\n'    
 'A nice name for the recording: the PlayOn series and name,\n'    
 'omitting the series if `None`.\n'    
 '\n'    
 '*Method `Recording.recording_id(self)`*:\n'    
 'The recording id or `None`.\n'    
 '\n'    
 '*Method `Recording.resolution(self)`*:\n'    
 'The recording resolution derived from the quality\n'    
 'via the `Recording.RECORDING_QUALITY` mapping.\n'    
 '\n'    
 '*Method `Recording.status(self)`*:\n'    
 'Return a short status string.\n'    
 '\n'    
 '# Release Log\n'    
 '\n'    
 '\n'    
 '\n'    
 '*Release 20220311*:\n'    
 'Bugfix criteria for refreshing the PlayOn state.\n'    
 '\n'    
 '*Release 20211212*:\n'    
 'Initial release.'),
  install_requires = ['cs.cmdutils', 'cs.context', 'cs.deco', 'cs.fileutils>=20210731', 'cs.fstags', 'cs.lex', 'cs.logutils', 'cs.pfx>=20210731', 'cs.progress', 'cs.resources', 'cs.result', 'cs.sqltags', 'cs.threads', 'cs.units', 'cs.upd', 'requests', 'typeguard'],
  classifiers = ['Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Topic :: Utilities', 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)'],
  entry_points = {'console_scripts': ['playon = cs.app.playon:main']},
  keywords = ['python3'],
  license = 'GNU General Public License v3 or later (GPLv3+)',
  long_description_content_type = 'text/markdown',
  package_dir = {'': 'lib/python'},
  py_modules = ['cs.app.playon'],
)
