def channel_addition(option, channels): # option is either 'add' for -a # -a expects a list # OR 'sync' for -s # -s accepts only a string # Everything is converted to lowercase in the relevant function print(' ' + Colors.YELLOW + 'Additions to database:' + Colors.ENDC) # Get the numeric id of each channel that is to be added to the database if option == 'add': valid_channels = twitchy_api.name_id_translate('channels', 'id_from_name', [channels]) elif option == 'sync': valid_channels = twitchy_api.sync_from_id(channels) if not valid_channels: raise YouAndTheHorseYouRodeInOn(' No valid channels.') # Actual addition to the database takes place here added_channels = twitchy_database.DatabaseFunctions().add_channels( valid_channels) if not added_channels: raise YouAndTheHorseYouRodeInOn(' No valid channels.') else: for i in added_channels: print(' ' + i)
def watch_vods(channel_name): channel_data = twitchy_api.name_id_translate('channels', 'id_from_name', [channel_name]) try: channel_id = channel_data[channel_name[0]]['id'] display_name = channel_data[channel_name[0]]['display_name'] except KeyError: raise YouAndTheHorseYouRodeInOn(' Invalid name.') vod_list = twitchy_api.get_vods(channel_id) print(' ' + Options.colors.numbers + f'VODs for {display_name}:' + Colors.ENDC) if not vod_list: raise YouAndTheHorseYouRodeInOn(' No VODs found.') final_selection = { display_name: twitchy_display.GenerateVODTable(vod_list).begin() } twitchy_config.time_tracking = False twitchy_config.vod_mode = True print(' q / Ctrl + C to quit \n Now watching:') twitchy_play.play_instance_generator(final_selection)
def api_call(url, params=None): try: headers = { 'Client-ID': 'guulhcvqo9djhuyhb2vi56wqnglc351'} def make_request(): r = requests.get( url, headers=headers, params=params) my_json = r.json() try: status = my_json['status'] if status == 429: # Wait for 2 seconds in case of an API overload # Hopefully the recursion doesn't end the universe time.sleep(2) make_request() except KeyError: return my_json return make_request() except requests.exceptions.ConnectionError: raise YouAndTheHorseYouRodeInOn(' Unable to connect to Twitch.')
def fetch_data(self, columns, table, selection_criteria, equivalence, fetch_one=False): # columns is a tuple that will be passed as a comma separated list # table is a string that will be used as is # selection_criteria is a dictionary which contains the name of a column linked # to a corresponding value for selection # Example: # Name and AltName are expected to be the same # sel_dict = { # 'Name': 'sav', # 'AltName': 'sav' # } # data = DatabaseFunctions().fetch_data(('Name',), 'channels', sel_dict) try: column_list = ','.join(columns) sql_command_fetch = f"SELECT {column_list} FROM {table}" if selection_criteria: sql_command_fetch += " WHERE" if equivalence == 'EQUALS': for i in selection_criteria.keys(): search_parameter = selection_criteria[i] sql_command_fetch += f" {i} = '{search_parameter}' OR" elif equivalence == 'LIKE': for i in selection_criteria.keys(): search_parameter = "'%" + selection_criteria[i] + "%'" sql_command_fetch += f" {i} LIKE {search_parameter} OR" sql_command_fetch = sql_command_fetch[: -3] # Truncate the last OR # channel data is returned as a list of tuples channel_data = self.database.execute(sql_command_fetch).fetchall() if channel_data: # Because this is the result of a fetchall(), we need an # ugly hack (tm) to get correct results for anything that # isn't a database id search # This will cause issues in case someone wants to refer to # streamers and games as digits. We don't need that shit here. # Another consideration is returns for time watched # In that case, just go 0 of 0 if fetch_one: return channel_data[0][0] return channel_data else: return None except sqlite3.OperationalError: raise YouAndTheHorseYouRodeInOn(' Database error.')
def database_modification(option, database_search=None): # option is either 'delete' for -d # OR 'alternate_name' for -an try: table_wanted = input(' Modify (s)treamer or (g)ame name? ') except (KeyboardInterrupt, EOFError): exit(1) if table_wanted.lower() == 's': table_wanted = 'channels' elif table_wanted.lower() == 'g': table_wanted = 'games' if database_search: database_search = {'Name': database_search, 'AltName': database_search} channel_data = database_instance.fetch_data( ('Name', 'TimeWatched', 'AltName'), table_wanted, database_search, 'LIKE') if not channel_data: raise YouAndTheHorseYouRodeInOn(' No matching records.') final_selection = twitchy_display.GenerateDatabaseTable( channel_data, table_wanted).begin() if option == 'delete': yes_default = ['y', 'Y', 'yes', 'YES'] confirmed_deletions = [] for i in final_selection: confirm_delete = input( f' Delete {Colors.YELLOW + i + Colors.ENDC} (y/N) ') if confirm_delete in yes_default: confirmed_deletions.append(i) database_instance.modify_data('delete', table_wanted, i) if confirmed_deletions: print(' Deleted: ' + Colors.RED + ', '.join(confirmed_deletions) + Colors.ENDC) elif option == 'alternate_name': for i in final_selection: new_name = input( f' Alternate name for {Colors.YELLOW + i + Colors.ENDC} ') criteria_dict = {'old_name': i, 'new_name': new_name} database_instance.modify_data('alternate_name', table_wanted, criteria_dict)
def watch_channel(mode, database_search=None): if mode == 'watch': # database_search is expected to be a list # exact names of the channels the user wants to watch # Watch times are NOT tracked with -w # This greatly decreases the number of special conditions # that need to be accounted for twitchy_config.time_tracking = False id_string_list = [] not_in_database = [] database_search = [i.lower() for i in database_search] for i in database_search: search_criteria = {'Name': i} channel_data = database_instance.fetch_data( ('ChannelID', ), 'channels', search_criteria, 'EQUALS', True) if channel_data: # Channel data is expected as a string id_string_list.append(str(channel_data)) else: not_in_database.append(i) if not_in_database: get_ids_from_api = twitchy_api.name_id_translate( 'channels', 'id_from_name', [not_in_database]) ids_only = [i[1]['id'] for i in get_ids_from_api.items()] id_string_list.extend(ids_only) if not id_string_list: raise YouAndTheHorseYouRodeInOn(' No valid channels.') else: # This is the standard watch() function # It expects only one argument if database_search: database_search = { 'Name': database_search, 'AltName': database_search } channel_data = database_instance.fetch_data( ('ChannelID', ), 'channels', database_search, 'LIKE') if channel_data: id_string_list = [str(i[0]) for i in channel_data] else: raise YouAndTheHorseYouRodeInOn( ' Database query returned nothing.') print(' ' + Options.colors.numbers + f'Checking {len(id_string_list)} channel(s)...' + Colors.ENDC) channels_online = twitchy_api.GetOnlineStatus( id_string_list).check_channels() if not channels_online: raise YouAndTheHorseYouRodeInOn(' All channels offline.') final_selection = twitchy_display.GenerateWatchTable( channels_online).begin() #print(' q / Ctrl + C to quit \n Now watching:') twitchy_play.play_instance_generator(final_selection)
import os import ast import time import datetime from twitchy import twitchy_database from twitchy.twitchy_config import YouAndTheHorseYouRodeInOn, location_prefix, Options Options = Options() Options.parse_options() try: import requests except ImportError: raise YouAndTheHorseYouRodeInOn(' requests not installed.') def api_call(url, params=None): try: headers = {'Client-ID': 'guulhcvqo9djhuyhb2vi56wqnglc351'} def make_request(): r = requests.get(url, headers=headers, params=params) my_json = r.json() try: status = my_json['status'] if status == 429: # Wait for 2 seconds in case of an API overload