Example #1
0
    def message(self):
        ips = ', '.join(self.ips)
        warning = click.style('Warning:', bg='red', fg='white', bold=True)
        msg = """
          {warning} not connected to a VPN

          The ip addresses in config.ini ({config_ips}) don't match
          your current ip address which is {current_ip}.

          If you know you are connected to a VPN, add your current ip to the
          config.ini file otherwise don't add it.

          Would you like me to open config.ini in your default editor
          so you can add {current_ip}? [y/n]""".format(config_ips=ips,
                                                       current_ip=self.ip,
                                                       warning=warning)

        msg = format_paragraphs(msg)
        click.echo(msg)
        c = click.getchar()
        click.echo()
        if c == 'y':
            click.edit(filename=Config.user_config)
        else:
            click.echo('Config is here: %s' % Config.user_config)
Example #2
0
    def message(self):
        ips = ', '.join(self.ips)
        warning = click.style('Warning:', bg='red', fg='white', bold=True)
        msg = """
          {warning} not connected to a VPN

          Your current public ip ({ip}) is not in the good ip list.
          Would you like this ip added to the whitelist? [y/n]""".format(
              warning=warning, ip=self.ip)

        msg = format_paragraphs(msg)
        click.echo()
        click.echo(msg, nl=False)
        c = click.getchar()
        click.echo()
        if c == 'y':
            self.add_ip()
            return True
        return False
Example #3
0
    def ask(self):
        if not DB.get_config('telemetry_asked'):
            question = format_paragraphs("""
                May TV Overlord report anonymous usage statistics?

                This is the single most useful thing a user can do.  This
                data will help decide the features that get the most
                attention and the future direction of TV Overlord.

                More information at:

                https://github.com/8cylinder/tv-overlord/wiki/telemetry-data

            """)
            question = click.style(question, fg='green')
            click.echo()
            telemetry_ok = click.confirm(question, default=True)
            click.echo()

            DB.set_config('telemetry_ok', telemetry_ok)
            DB.set_config('telemetry_asked', True)
            if not DB.get_config('uuid4'):
                DB.set_config('uuid4', str(uuid.uuid4()))
                DB.set_config('uuid1', str(uuid.uuid1()))
Example #4
0
    def download(self, chosen_show, destination, search_type='torrent'):
        """
        Pass the chosen show's data and destination to the providers
        download method and return the name of the file downloaded
        back to get-nzb.v2.py
        """

        downloaded_filename = ''
        if chosen_show.startswith("magnet:"):

            # write magnet links to a file
            if Config.magnet_dir:
                Config.magnet_dir = os.path.expanduser(Config.magnet_dir)
                fn = self.magnet_filename()
                if os.path.isdir(Config.magnet_dir):
                    full = os.path.join(Config.magnet_dir, fn)
                    with open(full, 'w') as f:
                        f.write(chosen_show)
                else:
                    sys.exit('\n"%s" does not exist' % Config.magnet_dir)

            # use a command specified in config.ini
            elif Config.client:
                args = self.config_command(chosen_show)
                try:
                    subprocess.Popen(args)
                except FileNotFoundError:
                    sys.exit('\n"%s" not found.' % args[0])

            elif platform.system() == 'Linux':
                err_msg = format_paragraphs('''
                    You do not have a default handler for magnet
                    links.  Either install a bittorent client or
                    configure the "magnet folder" or "client"
                    settings in config.ini.''')

                isX = True if os.environ.get('DISPLAY') else False
                if isX:
                    app = 'xdg-open'
                else:
                    click.echo()
                    sys.exit(err_msg)

                try:
                    subprocess.Popen([app, chosen_show],
                                     stderr=subprocess.DEVNULL,
                                     stdout=subprocess.DEVNULL)
                except OSError:
                    click.echo()
                    sys.exit(err_msg)

            elif platform.system() == 'Darwin':
                subprocess.Popen(["open", "--background", chosen_show])

            elif platform.system() == 'Windows':
                os.startfile(chosen_show)

            else:
                unknown_system = platform.platform()
                sys.exit('\nUnknown system:', unknown_system)

        else:  # is a nzb file
            final_name = ''
            # only cleans name for tv show downloads
            if self.season and self.episode:
                final_name = '%s.%s.nzb' % (
                    self.show_name.replace(' ', '.'), "S%sE%s" %
                    (self.season.rjust(2, '0'), self.episode.rjust(2, '0')))
            else:
                final_name = '%s.nzb' % (self.show_name)

            downloader = self.newsgroup_engines[0].Provider()
            downloaded_filename = downloader.download(chosen_show, destination,
                                                      final_name)

        return downloaded_filename
Example #5
0
def edit_db(search_str):
    try:
        import readline
    except ImportError:
        pass

    sql = 'SELECT * FROM shows WHERE name like :search'
    conn = sqlite3.connect(Config.db_file)
    conn.row_factory = tvu.dict_factory
    curs = conn.cursor()
    values = {'search': '%{}%'.format(search_str)}
    results = curs.execute(sql, values)

    data = []
    for i in results:
        data.append(i)

    if len(data) == 0:
        sys.exit('"%s" not found' % search_str)
    elif len(data) > 1:
        click.echo('Multiple shows found, type a number to edit.')
        click.echo('Type "<ctrl> c" to cancel.')
        click.echo()
        for index, show in enumerate(data):
            click.echo('  %s. %s' % (index + 1, show['name']))
        click.echo()
        choice = click.prompt(
            'Choose number', default=1,
            type=click.IntRange(min=1, max=len(data)))
        idchoice = choice - 1
        if idchoice not in range(len(data)):
            sys.exit('Invalid choice: %s' % choice)
        row = data[idchoice]
    else:
        row = data[0]

    editcolor = 'green' if Config.is_win else 31
    dirty = False
    is_error = False

    click.echo()
    click.echo(tvu.format_paragraphs('''
      While editing a field, hit <enter> in an empty field to leave it
      unchanged and skip to the next one.  Type "<ctrl> c" to cancel all
      edits.  The current value is shown in ()\'s beside the field
      name.'''))
    click.echo()

    title = '%s' % row['name']
    click.echo(tvu.style(title, bold=True, ul=True))
    click.echo()
    try:
        msg = tvu.style('Search engine name (%s): ', fg=editcolor)
        new_search_engine_name = input(msg % (row['search_engine_name']))
        if not new_search_engine_name:
            new_search_engine_name = row['search_engine_name']
        else:
            dirty = True

        msg = tvu.style('Current season (%s): ', fg=editcolor)
        new_season = input(msg % (row['season']))
        if not new_season:
            new_season = str(row['season'])
        else:
            dirty = True

        msg = tvu.style('Last episode (%s): ', fg=editcolor)
        new_episode = input(msg % (row['episode']))
        if not new_episode:
            new_episode = str(row['episode'])
        else:
            dirty = True

        msg = tvu.style('Status (%s): ', fg=editcolor)
        new_status = input(msg % (row['status']))
        if not new_status:
            new_status = row['status']
        else:
            dirty = True

        date_pretty = 'y' if row['search_by_date'] == 1 else 'n'
        msg = tvu.style('Search by date (%s) [y/n]: ', fg=editcolor)
        new_date = input(msg % (date_pretty))
        if not new_date:
            new_date = date_pretty
        else:
            dirty = True

        new_format = row['date_format']
        if new_date == 'y':
            click.echo('  The optional date format string can be any valid Python format string.')
            click.echo('  https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior')
            msg = tvu.style('  Date format string (%s): ', fg=editcolor)
            new_format = input(msg % (row['date_format']))
            if not new_format:
                new_format = row['date_format']
            else:
                dirty = True

    except KeyboardInterrupt:
        click.echo('\n\nDatabase edit cancelled.')
        sys.exit(0)

    click.echo()

    if dirty is False:
        click.echo('No changes made.')
        sys.exit(0)

    if not new_season.isdigit():
        click.echo('Error: Season must be a number')
        is_error = True

    if not new_episode.isdigit():
        click.echo('Error: Episode must be a number')
        is_error = True

    if new_status not in ['active', 'inactive']:
        click.echo('Error: Status must be either "active" or "inactive"')
        is_error = True

    if new_date not in ['y', 'n']:
        click.echo('Error: Search by date must be either "y" or "n"')
        is_error = True

    if is_error:
        sys.exit(1)

    if not click.confirm('Are these changes correct? (you can always change it back)', default='Y'):
        click.echo('\nDatabase edit cancelled.')
        sys.exit()

    sql = '''UPDATE shows SET
                season=:season,
                episode=:episode,
                status=:status,
                search_engine_name=:search_engine_name,
                search_by_date=:search_by_date,
                date_format=:date_format
             WHERE thetvdb_series_id=:tvdb_id'''

    row_values = {
        'season': new_season,
        'episode': new_episode,
        'status': new_status,
        'search_engine_name': new_search_engine_name,
        'tvdb_id': row['thetvdb_series_id'],
        'search_by_date': 1 if new_date == 'y' else 0,
        'date_format': new_format,
    }

    curs.execute(sql, row_values)

    conn.commit()
    conn.close()
Example #6
0
    def _get_thetvdb_series_data(self):
        """Dynamicaly add all the data from Thetvdb.com

        networkid      - None
        rating         - 8.6
        airs_dayofweek - Thursday
        contentrating  - TV-14
        seriesName     - 30 Rock
        id             - 79488
        airs_time      - 8:30 PM
        network        - NBC
        fanart         - http://www.thetvdb.com/banners/fanart/original/79488-11.jpg
        lastupdated    - 1358045748
        actors         - |Tina Fey|Alec Baldwin|Tracy Morgan|Jane Krakowski|Kevin Brown|Maulik Pancholy|Keith Powell|Katrina Bowden|Lonny Ross|Scott Adsit|Judah Friedlander|Jack McBrayer|John Lutz|Grizz Chapman|
        ratingcount    - 196
        status         - Continuing
        added          - None
        poster         - http://www.thetvdb.com/banners/posters/79488-7.jpg
        imdb_id        - tt0496424
        genre          - |Comedy|
        banner         - http://www.thetvdb.com/banners/graphical/79488-g11.jpg
        seriesid       - 58326
        language       - en
        zap2it_id      - SH00848357
        addedby        - None
        firstaired     - 2006-10-11
        runtime        - 30
        overview       - Emmy Award Winner Tina Fey writ...

        """

        # tv = tvdb_api.Tvdb(apikey=Config.thetvdb_apikey,
        #                    cache=Config.use_cache)
        # self.tvapi = tv
        # tv = self.tvapi

        tvdb_msg = format_paragraphs('''

            An error occurred while retrieving data from thetvdb.com.

            This may mean that thetvdb is having issues.  This error
            is usually caused by corrupted or incomplete data being
            returned from thetvdb.

            Keep retrying using the --no-cache flag or wait a while.

            Checking thetvdb's twitter feed sometimes gives current
            status: https://twitter.com/thetvdb

            Or isitdownrightnow.com:
            http://www.isitdownrightnow.com/thetvdb.com.html

            If the error continues, open an issue at GitHub and paste
            this error. https://github.com/8cylinder/tv-overlord/issues

            Error #: {error_no}

            Error message from stack trace:

            {stack_msg}
        ''')

        try:
            series = self.tvapi[self.db_name]
            self.show_exists = True
        except xml.etree.ElementTree.ParseError as e:
            print('-' * 20)
            print(e)
            print('-' * 20)
        except KeyError as e:
            # print('>>>', e)
            msg = tvdb_msg.format(error_no=101, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except tvdb_api.tvdb_shownotfound:
            self.show_exists = False
            click.echo('\nShow not found: %s' % self.db_name, err=True)
            return
        except tvdb_api.tvdb_error as e:
            # msg = tvdb_msg.format(error_no=102, stack_msg=e)
            # click.echo(msg, err=True)
            # sys.exit(1)
            print('>>> ERROR', self.db_name)
            return
        except UnboundLocalError as e:
            msg = tvdb_msg.format(error_no=103, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except requests.exceptions.ChunkedEncodingError as e:
            msg = tvdb_msg.format(error_no=104, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except requests.exceptions.ConnectionError as e:
            msg = tvdb_msg.format(error_no=105, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)

        for i in series.data:
            setattr(self, i, series.data[i])
        self.series = series
Example #7
0
    def add_new(self, name):
        try:
            result = self.tvapi.search(name)
        except KeyError as e:
            click.echo(
                'Show data returned from TheTVDB.com has an error in it.',
                err=True)
            sys.exit(1)

        if not result:
            click.echo('No show found.')
            return
        else:
            click.echo('Multiple shows found, type a number to select.')
            click.echo('Type "<ctrl> c" to cancel.')
            click.echo()
            indent = '     '
            for index, show in enumerate(result):
                title = show['seriesName']
                click.echo(' %2s. ' % (index + 1), nl=False)
                click.secho(title, bold=True)
                if 'overview' in show:
                    click.echo(
                        format_paragraphs(show['overview'], indent=indent))
                if 'firstaired' in show:
                    click.secho('%sFirst aired: %s' %
                                (indent, show['firstaired']),
                                fg='green')
                click.echo()

            choice = click.prompt('Choose number (or [enter] for #1)',
                                  default=1,
                                  type=click.IntRange(min=1, max=len(result)))
            idchoice = choice - 1
            show = result[idchoice]

        self.db_name = show['seriesName']  # name
        self._get_thetvdb_series_data()

        last_season = 1
        last_episode = 0
        for season in self.series:
            last_season = season
            for episode in self.series[season]:
                b_date = self.series[season][episode]['firstaired']
                if not b_date:
                    continue  # some episodes have no broadcast date
                split_date = b_date.split('-')
                broadcast_date = datetime.datetime(int(split_date[0]),
                                                   int(split_date[1]),
                                                   int(split_date[2]))
                today = datetime.datetime.today()
                if broadcast_date > today:
                    break
                last_episode = episode

        last_sxxexx = style(sxxexx(last_season, last_episode), bold=True)

        if int(last_season) == 1 and int(last_episode) == 0:
            se = 0
            ep = 0
        else:
            click.echo()
            click.echo('The last episode broadcast was %s.' % last_sxxexx)
            msg = 'Start downloading the [f]irst (or [enter]), [l]atest or season and episode?'
            start = click.prompt(msg, default='f')

            if start == 'f':
                se = ep = 0
            elif start == 'l':
                se = last_season
                ep = last_episode
            else:
                try:
                    se, ep = [int(i) for i in start.split()]
                except ValueError:
                    sys.exit(
                        'Season and episode must be two numbers seperated by a space.'
                    )

            if ep > 0:
                ep -= 1  # episode in db is the NEXT episode

        msg = self._add_new_db(season=se, episode=ep)
        click.echo()
        click.echo(msg)
Example #8
0
    def _get_thetvdb_series_data(self):
        """Dynamicaly add all the data from Thetvdb.com

        networkid      - None
        rating         - 8.6
        airs_dayofweek - Thursday
        contentrating  - TV-14
        seriesname     - 30 Rock
        id             - 79488
        airs_time      - 8:30 PM
        network        - NBC
        fanart         - http://www.thetvdb.com/banners/fanart/original/79488-11.jpg
        lastupdated    - 1358045748
        actors         - |Tina Fey|Alec Baldwin|Tracy Morgan|Jane Krakowski|Kevin Brown|Maulik Pancholy|Keith Powell|Katrina Bowden|Lonny Ross|Scott Adsit|Judah Friedlander|Jack McBrayer|John Lutz|Grizz Chapman|
        ratingcount    - 196
        status         - Continuing
        added          - None
        poster         - http://www.thetvdb.com/banners/posters/79488-7.jpg
        imdb_id        - tt0496424
        genre          - |Comedy|
        banner         - http://www.thetvdb.com/banners/graphical/79488-g11.jpg
        seriesid       - 58326
        language       - en
        zap2it_id      - SH00848357
        addedby        - None
        firstaired     - 2006-10-11
        runtime        - 30
        overview       - Emmy Award Winner Tina Fey writ...

        """

        # tv = tvdb_api.Tvdb(apikey=Config.thetvdb_apikey,
        #                    cache=Config.use_cache)
        # self.tvapi = tv
        # tv = self.tvapi

        tvdb_msg = format_paragraphs('''

            An error occurred while retrieving data from thetvdb.com.

            This may mean that thetvdb is having issues.  This error
            is usually caused by corrupted or incomplete data being
            returned from thetvdb.

            Keep retrying using the --no-cache flag or wait a while.

            Checking thetvdb's twitter feed sometimes gives current
            status: https://twitter.com/thetvdb

            Or isitdownrightnow.com:
            http://www.isitdownrightnow.com/thetvdb.com.html

            If the error continues, open an issue at GitHub and paste
            this error. https://github.com/8cylinder/tv-overlord/issues

            Error #: {error_no}

            Error message from stack trace:

            {stack_msg}
        ''')

        try:
            series = self.tvapi[self.db_name]
            self.show_exists = True
        except xml.etree.ElementTree.ParseError as e:
            print('-' * 20)
            print(e)
            print('-' * 20)
        except KeyError as e:
            # print('>>>', e)
            msg = tvdb_msg.format(error_no=101, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except tvdb_api.tvdb_shownotfound:
            self.show_exists = False
            click.echo('\nShow not found: %s' % self.db_name, err=True)
            return
        except tvdb_api.tvdb_error as e:
            msg = tvdb_msg.format(error_no=102, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except UnboundLocalError as e:
            msg = tvdb_msg.format(error_no=103, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except requests.exceptions.ChunkedEncodingError as e:
            msg = tvdb_msg.format(error_no=104, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)
        except requests.exceptions.ConnectionError as e:
            msg = tvdb_msg.format(error_no=105, stack_msg=e)
            click.echo(msg, err=True)
            sys.exit(1)

        for i in series.data:
            setattr(self, i, series.data[i])
        self.series = series
Example #9
0
    def add_new(self, name):
        try:
            result = self.tvapi.search(name)
        except KeyError as e:
            click.echo(
                'Show data returned from TheTVDB.com has an error in it.',
                err=True)
            sys.exit(1)

        if not result:
            click.echo('No show found.')
            return
        else:
            click.echo('Multiple shows found, type a number to select.')
            click.echo('Type "<ctrl> c" to cancel.')
            click.echo()
            indent = '     '
            for index, show in enumerate(result):
                title = show['seriesname']
                click.echo(' %2s. ' % (index + 1), nl=False)
                click.secho(title, bold=True)
                if 'overview' in show:
                    click.echo(format_paragraphs(
                        show['overview'], indent=indent))
                if 'firstaired' in show:
                    click.secho(
                        '%sFirst aired: %s' % (indent, show['firstaired']),
                        fg='green')
                click.echo()

            choice = click.prompt(
                'Choose number (or [enter] for #1)', default=1,
                type=click.IntRange(min=1, max=len(result)))
            idchoice = choice - 1
            show = result[idchoice]

        self.db_name = show['seriesname']  # name
        self._get_thetvdb_series_data()

        last_season = 1
        last_episode = 0
        for season in self.series:
            last_season = season
            for episode in self.series[season]:
                b_date = self.series[season][episode]['firstaired']
                if not b_date:
                    continue  # some episodes have no broadcast date
                split_date = b_date.split('-')
                broadcast_date = datetime.datetime(
                    int(split_date[0]), int(split_date[1]), int(split_date[2]))
                today = datetime.datetime.today()
                if broadcast_date > today:
                    break
                last_episode = episode

        last_sxxexx = style(sxxexx(last_season, last_episode), bold=True)

        if int(last_season) == 1 and int(last_episode) == 0:
            se = 0
            ep = 0
        else:
            click.echo()
            click.echo('The last episode broadcast was %s.' % last_sxxexx)
            msg = 'Start downloading the [f]irst (or [enter]), [l]atest or season and episode?'
            start = click.prompt(msg, default='f')

            if start == 'f':
                se = ep = 0
            elif start == 'l':
                se = last_season
                ep = last_episode
            else:
                try:
                    se, ep = [int(i) for i in start.split()]
                except ValueError:
                    sys.exit('Season and episode must be two numbers seperated by a space.')

            if ep > 0:
                ep -= 1  # episode in db is the NEXT episode

        msg = self._add_new_db(season=se, episode=ep)
        click.echo()
        click.echo(msg)
Example #10
0
def info(show_name, show_all, sort_by_next, db_status,
         ask_inactive, show_links, synopsis):
    """Show information about your tv shows.

    SHOW_NAME can be a full or partial name of a show.  If used, it
    will show information about any shows that match that string, else
    it will show informaton about all your shows.
    """
    show_info = {}
    counter = 0
    status = 'active'

    # When the user specifies a single show, turn on --show-all
    # because the show they are asking for might an inactive show
    # and turn on --synopsis and --show-links since its only one
    # show we may as well show everything
    filter_name = ''
    if show_name:
        show_all = True
        synopsis = True
        show_links = True
        filter_name = show_name
        db_status = 'all'

    if Config.is_win:
        colors = {'links': 'blue', 'ended': 'red',
                  'last': 'cyan', 'future': 'green'}
    else:
        colors = {'links': 20, 'ended': 'red',
                  'last': 48, 'future': 22}

    shows = Shows(name_filter=filter_name, status=db_status)
    for show in shows:
        title = show.db_name

        if show.status == 'Ended':
            status = style(show.status, fg=colors['ended'])
        else:
            status = ''

        # build first row of info for each show
        se = 'Last downloaded: S%sE%s' % (
            str(show.db_current_season).rjust(2, '0'),
            str(show.db_last_episode).rjust(2, '0'),
        )
        se = style(se, fg=colors['last'])

        imdb_url = thetvdb_url = ''
        if show_links:
            imdb_url = style('\n    IMDB.com:    http://imdb.com/title/%s' % show.imdb_id,
                             fg=colors['links'])
            thetvdb_url = style('\n    TheTVDB.com: http://thetvdb.com/?tab=series&id=%s' % show.id,
                                fg=colors['links'])

        synopsis_text = None
        if synopsis and show.overview:
            paragraph = show.overview
            indent = '    '
            paragraph = format_paragraphs(paragraph, indent=indent)
            synopsis_text = '\n%s' % paragraph

        first_row_a = []
        fancy_title = style(title, bold=True)
        for i in [fancy_title + ',', se, status, imdb_url, thetvdb_url, synopsis_text]:
            if i: first_row_a.append(i)
        first_row = ' '.join(first_row_a)

        # build 'upcoming episodes' list
        today = datetime.datetime.today()
        first_time = True
        episodes_list = []
        counter += 1
        for i in show.series:  # season
            for j in show.series[i]:  # episode
                b_date = show.series[i][j]['firstaired']
                if not b_date: continue  # some episode have no broadcast date?

                split_date = b_date.split('-')
                broadcast_date = datetime.datetime(
                    int(split_date[0]), int(split_date[1]), int(split_date[2]))

                if not show_all:
                    if broadcast_date < today:
                        continue

                future_date = date_parser.parse(b_date)
                diff = future_date - today
                fancy_date = future_date.strftime('%b %d')
                if broadcast_date >= today:
                    episodes_list.append('S%sE%s, %s (%s)' % (
                        show.series[i][j]['seasonnumber'].rjust(2, '0'),
                        show.series[i][j]['episodenumber'].rjust(2, '0'),
                        fancy_date,
                        diff.days + 1,
                    ))

                if first_time:
                    first_time = False
                    if sort_by_next:
                        sort_key = str(diff.days).rjust(5, '0') + str(counter)
                    else:
                        sort_key = show.db_name.replace('The ', '')

        if not first_time:
            if episodes_list:
                indent = '    '
                episode_list = 'Future episodes: ' + ' - '.join(episodes_list)
                episodes = format_paragraphs(episode_list, indent=indent)
                show_info[sort_key] = first_row + '\n' + episodes
            else:
                show_info[sort_key] = first_row

        if ask_inactive:
            if show.status == 'Ended' and first_time:
                click.echo(
                    '%s has ended, and all have been downloaded. Set as inactive? [y/n]: ' %
                    title)
                set_status = click.getchar()
                click.echo(set_status)
                if set_status == 'y':
                    show.set_inactive()

    keys = list(show_info.keys())
    keys.sort()
    full_output = ''
    for i in keys:
        full_output = full_output + show_info[i] + '\n\n'

    # remove the last '\n\n'
    full_output = full_output.strip()

    if len(keys) < 4:
        click.echo(full_output)
    elif Config.is_win:
        click.echo(full_output)
    else:
        click.echo_via_pager(full_output)
Example #11
0
    def download(self, chosen_show, destination, search_type='torrent'):
        """
        Pass the chosen show's data and destination to the providers
        download method and return the name of the file downloaded
        back to get-nzb.v2.py
        """
        downloaded_filename = ''
        if chosen_show.startswith("magnet:"):

            # write magnet links to a file
            if Config.magnet_dir:
                Config.magnet_dir = os.path.expanduser(Config.magnet_dir)
                fn = self.magnet_filename(chosen_show)
                if os.path.isdir(Config.magnet_dir):
                    full = os.path.join(Config.magnet_dir, fn)
                    with open(full, 'w') as f:
                        f.write(chosen_show)
                else:
                    sys.exit('\n"%s" does not exist' % Config.magnet_dir)

            # use a command specified in config.ini
            elif Config.client:
                args = self.config_command(chosen_show)
                try:
                    subprocess.Popen(args)
                except FileNotFoundError:
                    sys.exit('\n"%s" not found.' % args[0])

            elif platform.system() == 'Linux':
                err_msg = tu.format_paragraphs('''
                    You do not have a default handler for magnet
                    links.  Either install a bittorent client or
                    configure the "magnet folder" or "client"
                    settings in config.ini.''')

                isX = True if os.environ.get('DISPLAY') else False
                if isX:
                    app = 'xdg-open'
                else:
                    click.echo()
                    sys.exit(err_msg)

                try:
                    subprocess.Popen([app, chosen_show],
                                     stderr=subprocess.DEVNULL,
                                     stdout=subprocess.DEVNULL)
                except OSError:
                    click.echo()
                    sys.exit(err_msg)

            elif platform.system() == 'Darwin':
                subprocess.Popen(["open", "--background", chosen_show])

            elif platform.system() == 'Windows':
                os.startfile(chosen_show)

            else:
                unknown_system = platform.platform()
                sys.exit('\nUnknown system:', unknown_system)

        else:  # is a nzb file
            final_name = ''

            show_fname = 'unknown'
            for f in self.episodes:
                if chosen_show == f[4]:
                    show_fname = tu.clean_filename(f[0], strict=True)
            final_name = '%s.nzb' % (show_fname)

            idx, guid = chosen_show.split('|')
            downloader = self.newsgroup_engines[int(idx)]
            downloaded_filename = downloader.download(
                guid, destination, final_name)

        return downloaded_filename
Example #12
0
def edit_db(search_str):
    try:
        import readline
    except ImportError:
        pass

    sql = 'SELECT * FROM shows WHERE name like :search'
    conn = sqlite3.connect(Config.db_file)
    conn.row_factory = tvu.dict_factory
    curs = conn.cursor()
    values = {'search': '%{}%'.format(search_str)}
    results = curs.execute(sql, values)

    data = []
    for i in results:
        data.append(i)

    if len(data) == 0:
        sys.exit('"%s" not found' % search_str)
    elif len(data) > 1:
        click.echo('Multiple shows found, type a number to edit.')
        click.echo('Type "<ctrl> c" to cancel.')
        click.echo()
        for index, show in enumerate(data):
            click.echo('  %s. %s' % (index + 1, show['name']))
        click.echo()
        choice = click.prompt(
            'Choose number', default=1,
            type=click.IntRange(min=1, max=len(data)))
        idchoice = choice - 1
        if idchoice not in range(len(data)):
            sys.exit('Invalid choice: %s' % choice)
        row = data[idchoice]
    else:
        row = data[0]

    editcolor = 'green' if Config.is_win else 31
    dirty = False
    is_error = False

    click.echo()
    click.echo(tvu.format_paragraphs('''
      While editing a field, hit <enter> in an empty field to leave it
      unchanged and skip to the next one.  Type "<ctrl> c" to cancel all
      edits.  The current value is shown in ()\'s beside the field
      name.'''))
    click.echo()

    title = '%s' % row['name']
    click.echo(tvu.style(title, bold=True, ul=True))
    click.echo()
    try:
        msg = tvu.style('Search engine name (%s): ', fg=editcolor)
        new_search_engine_name = input(msg % (row['search_engine_name']))
        if not new_search_engine_name:
            new_search_engine_name = row['search_engine_name']
        else:
            dirty = True

        msg = tvu.style('Current season (%s): ', fg=editcolor)
        new_season = input(msg % (row['season']))
        if not new_season:
            new_season = str(row['season'])
        else:
            dirty = True

        msg = tvu.style('Last episode (%s): ', fg=editcolor)
        new_episode = input(msg % (row['episode']))
        if not new_episode:
            new_episode = str(row['episode'])
        else:
            dirty = True

        msg = tvu.style('Status (%s): ', fg=editcolor)
        new_status = input(msg % (row['status']))
        if not new_status:
            new_status = row['status']
        else:
            dirty = True

        date_pretty = 'y' if row['search_by_date'] == 1 else 'n'
        msg = tvu.style('Search by date (%s) [y/n]: ', fg=editcolor)
        new_date = input(msg % (date_pretty))
        if not new_date:
            new_date = date_pretty
        else:
            dirty = True

        new_format = row['date_format']
        if new_date == 'y':
            click.echo('  The optional date format string can be any valid Python format string.')
            click.echo('  https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior')
            msg = tvu.style('  Date format string (%s): ', fg=editcolor)
            new_format = input(msg % (row['date_format']))
            if not new_format:
                new_format = row['date_format']
            else:
                dirty = True

    except KeyboardInterrupt:
        click.echo('\n\nDatabase edit cancelled.')
        sys.exit(0)

    click.echo()

    if dirty is False:
        click.echo('No changes made.')
        sys.exit(0)

    if not new_season.isdigit():
        click.echo('Error: Season must be a number')
        is_error = True

    if not new_episode.isdigit():
        click.echo('Error: Episode must be a number')
        is_error = True

    if new_status not in ['active', 'inactive']:
        click.echo('Error: Status must be either "active" or "inactive"')
        is_error = True

    if new_date not in ['y', 'n']:
        click.echo('Error: Search by date must be either "y" or "n"')
        is_error = True

    if is_error:
        sys.exit(1)

    if not click.confirm('Are these changes correct? (you can always change it back)', default='Y'):
        click.echo('\nDatabase edit cancelled.')
        sys.exit()

    sql = '''UPDATE shows SET
                season=:season,
                episode=:episode,
                status=:status,
                search_engine_name=:search_engine_name,
                search_by_date=:search_by_date,
                date_format=:date_format
             WHERE thetvdb_series_id=:tvdb_id'''

    row_values = {
        'season': new_season,
        'episode': new_episode,
        'status': new_status,
        'search_engine_name': new_search_engine_name,
        'tvdb_id': row['thetvdb_series_id'],
        'search_by_date': 1 if new_date == 'y' else 0,
        'date_format': new_format,
    }

    curs.execute(sql, row_values)

    conn.commit()
    conn.close()