Source code for upsies.uis.tui.commands.submit

"""
Generate all required metadata and upload to tracker
"""

import functools

from .... import __project_name__, constants, imagehosts, jobs, trackers, utils
from . import base


[docs] class submit(base.CommandBase): """Generate all required metadata and upload to TRACKER""" names = ('submit',) cli_arguments = {} subcommand_name = 'TRACKER' subcommands = { tracker.name: { 'description': ( f'Generate all required metadata and upload it to {tracker.label}.\n' '\n' f'For step-by-step instructions run this command:\n' '\n' f' $ {__project_name__} submit {tracker.name} --howto-setup\n' ), 'cli': { # Default arguments for all tackers ('--howto-setup',): { 'action': base.PrintText(text_getter=tracker.generate_setup_howto), 'nargs': 0, 'help': 'Show detailed instructions on how to do your first upload', }, 'CONTENT': { 'type': utils.argtypes.content, 'help': 'Path to release content', }, ('--is-scene',): { 'type': utils.argtypes.bool_or_none, 'default': None, 'help': ('Whether this is a scene release (usually autodetected)\n' 'Valid values: ' + ', '.join( f'{true}/{false}' for true, false in zip(utils.types.Bool.truthy, utils.types.Bool.falsy) )), }, ('--exclude-files', '--ef'): { 'nargs': '+', 'action': 'extend', 'metavar': 'PATTERN', 'help': ('Glob pattern to exclude from torrent ' '(matched case-insensitively against path in torrent)'), 'default': [], }, ('--exclude-files-regex', '--efr'): { 'nargs': '+', 'action': 'extend', 'metavar': 'PATTERN', 'help': ('Regular expression to exclude from torrent ' '(matched case-sensitively against path in torrent)'), 'type': utils.argtypes.regex, 'default': [], }, ('--reuse-torrent', '-t'): { 'nargs': '+', 'metavar': 'TORRENT', 'help': ('Use hashed pieces from TORRENT instead of generating ' 'them again or getting them from ' f'{utils.fs.tildify_path(constants.GENERIC_TORRENTS_DIRPATH)}\n' 'TORRENT may also be a directory, which is searched recursively ' 'for a matching *.torrent file.\n' "NOTE: This option is ignored if TORRENT doesn't match properly."), 'type': utils.argtypes.existing_path, 'default': (), }, ('--add-to', '-a'): { 'metavar': 'CLIENT', 'help': ('BitTorrent client name.\n' 'Valid names are section names in ' f'{utils.fs.tildify_path(constants.CLIENTS_FILEPATH)}.'), }, ('--copy-to', '-c'): { 'metavar': 'PATH', 'help': 'Copy the created torrent to PATH (file or directory)', }, ('--ignore-rules', '--ir'): { 'action': 'store_true', 'help': 'Allow submission if it is against tracker rules', }, ('--confirm', '--co'): { 'type': utils.argtypes.bool_or_none, 'default': None, 'help': ( 'Whether to ask if you really want to submit after all metadata is generated\n' 'Valid values: ' + ', '.join( f'{true}/{false}' for true, false in zip(utils.types.Bool.truthy, utils.types.Bool.falsy) ) ), }, # Custom arguments defined by tracker for this command **tracker.cli_arguments.get('submit', {}), }, } for tracker in trackers.tracker_classes() } @functools.cached_property def jobs(self): return ( *self.tracker_jobs.jobs_before_upload, self.main_job, *self.tracker_jobs.jobs_after_upload, ) @functools.cached_property def main_job(self): return jobs.submit.SubmitJob( home_directory=self.home_directory, cache_directory=self.cache_directory, ignore_cache=self.args.ignore_cache, tracker_jobs=self.tracker_jobs, ) @functools.cached_property def tracker_name(self): """Lower-case abbreviation of tracker name""" return self.args.subcommand.lower() @functools.cached_property def tracker_options(self): """ :attr:`tracker_name` section in trackers configuration file combined with CLI arguments where CLI arguments take precedence unless their value is `None` """ return self.get_options('trackers', self.tracker_name) @functools.cached_property def tracker(self): """ :class:`~.trackers.base.TrackerBase` instance from one of the submodules of :mod:`.trackers` """ return trackers.tracker( name=self.tracker_name, options=self.tracker_options, ) @functools.cached_property def tracker_jobs(self): """ :class:`~.trackers.base.TrackerJobsBase` instance from one of the submodules of :mod:`.trackers` """ return self.tracker.TrackerJobs( tracker=self.tracker, options=self.tracker_options, content_path=self.args.CONTENT, reuse_torrent_path=( tuple(self.args.reuse_torrent) + tuple(self.config['config']['torrent-create']['reuse_torrent_paths']) ), screenshots_optimization=self.config['config']['screenshots']['optimize'], screenshots_tonemapped=self.config['config']['screenshots']['tonemap'], show_poster=self.config['config']['id']['show_poster'], image_hosts=self._get_image_hosts(), btclient_config=self._get_btclient_config(), torrent_destination=self._get_torrent_destination(), exclude_files=( tuple(self.config['trackers'][self.tracker.name]['exclude']) + tuple(self.args.exclude_files) + tuple(self.args.exclude_files_regex) ), common_job_args={ 'home_directory': self.home_directory, 'cache_directory': self.cache_directory, 'ignore_cache': self.args.ignore_cache, }, ) def _get_image_hosts(self): return tuple( self._get_image_host(name) for name in self.tracker_options.get('image_host', ()) ) def _get_image_host(self, name): # Get global image host options from imghosts.ini. name = str(name).lower() config = self.config['imghosts'][name].copy() # Apply tracker-specific options that are common for all image hosts # (e.g. thumbnail size). config.update(self.tracker.TrackerJobs.image_host_config.get('common', {})) # Apply tracker-specific options for the used image host. config.update(self.tracker.TrackerJobs.image_host_config.get(name, {})) return imagehosts.imagehost( name=name, config=config, cache_directory=self.home_directory, ) def _get_btclient_config(self): btclient_name = ( getattr(self.args, 'add_to', None) or self.tracker_options.get('add_to', None) or None ) if btclient_name: return self.config['clients'][btclient_name] def _get_torrent_destination(self): return ( getattr(self.args, 'copy_to', None) or self.tracker_options.get('copy_to', None) or None )