def get_game(self, game_id): # The game_id is expected to be an integer # The idea is to check the database for said integer # and return data accordingly # If nothing is found, create a new entry within the database # and put them newly discovered details here # Whoever thought of 2 endpoints for this # can walk on broken glass try: game_name = twitchy_database.DatabaseFunctions().fetch_data( ('Name', 'AltName'), 'games', {'GameID': game_id}, 'EQUALS')[0] return game_name except TypeError: # Implies the game is not in the database # Its name will have to be fetched from the API # It will then be added to the database to prevent # repeated API calls # This means that all games EVER seen will be in the database now # F**k whoever thought of this try: game_details = name_id_translate('games', 'name_from_id', (game_id,)) game_name = game_details[0][1].replace("'", "") twitchy_database.DatabaseFunctions().add_games(game_name, game_id) return (game_name, None) except IndexError: # In the event the streamer gets lazy and does not set a game return ('No game set', None)
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 time_tracking(self): end_time = time.time() time_watched = end_time - self.start_time database_instance = twitchy_database.DatabaseFunctions() def fetch_time_data(): # Even for a non watched channel, the database # always has a 0 value associated # Therefore, there will be no None returns time_watched_channel = database_instance.fetch_data( ('TimeWatched',), 'channels', {'Name': self.channel_name}, 'EQUALS', True) time_watched_game = database_instance.fetch_data( ('TimeWatched',), 'games', {'Name': self.channel_params['game']}, 'EQUALS', True) return time_watched_channel, time_watched_game time_data = fetch_time_data() time_values = { 'channel_name': self.channel_name, 'new_time_channel': time_data[0] + time_watched, 'game_name': self.channel_params['game'], 'new_time_game': time_data[1] + time_watched} database_instance.modify_data( 'update_time', None, time_values) time_data_new = fetch_time_data() game_display_name = self.channel_params['game_display_name'] if not game_display_name: game_display_name = self.channel_params['game'] channel_rank = get_rank_data('channels', self.channel_name) if channel_rank: channel_rank = ' (' + channel_rank + ')' game_rank = get_rank_data('games', self.channel_params['game']) if game_rank: game_rank = ' (' + game_rank + ')' # Consider shfting this to the main module if twitchy_config.print_to_stdout: print( ' ' + Colors.WHITE + self.channel_params['display_name'] + ': ' + Colors.ENDC + time_convert(time_data_new[0]) + channel_rank + ' | ' + Colors.WHITE + game_display_name + ': ' + Colors.ENDC + time_convert(time_data_new[1]) + game_rank)
def get_rank_data(table, name): # Returns the rank of the requisite channel or game # as a string database_instance = twitchy_database.DatabaseFunctions() time_and_name = database_instance.fetch_data(('TimeWatched', 'Name'), table, None, 'EQUALS') time_and_name.sort(reverse=True) names_only = [i[1] for i in time_and_name] try: rank = str(names_only.index(name) + 1) except ValueError: # In case the provided name is not in the database return return rank
# Custom imports from twitchy import twitchy_config # This import also creates the path from twitchy.twitchy_config import Colors, YouAndTheHorseYouRodeInOn twitchy_config.ConfigInit() # Everything will error out unless # both the config and the database files exist from twitchy import twitchy_database twitchy_database.DatabaseInit() from twitchy import twitchy_api from twitchy import twitchy_display from twitchy import twitchy_play # All database functions are methods in database_instance database_instance = twitchy_database.DatabaseFunctions() Options = twitchy_config.Options() Options.parse_options() 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
def check_channels(self): # The API imposes an upper limit of 100 channels # checked at once. Pagination is required, as usual. while self.channels: api_endpoint = 'https://api.twitch.tv/helix/streams' params = (('first', 100), ('user_id', self.channels[:100])) del self.channels[:100] stream_data = api_call(api_endpoint, params) # The API currently does NOT return the game_name # It does return a game_id. In case you intend to go # forward with that at this time, the game_id will have # to be cached in the database along with its name # The stream data dictionary is # Key: name # Value: as below # Partner status will have to come from another endpoint # Time watched is a database function - See if it # needs to be integrated here for i in stream_data['data']: user_id = i['user_id'] try: channel_details = twitchy_database.DatabaseFunctions( ).fetch_data( ('Name', 'DisplayName', 'AltName', 'IsPartner'), 'channels', {'ChannelID': user_id}, 'EQUALS')[0] channel_name = channel_details[0] # Set the display name to a preset AltName if possible # Or go back to the display name set by the channel channel_display_name = channel_details[2] if not channel_display_name: channel_display_name = channel_details[1] # Partner status is returned as string True # This is clearly unacceptable for anyone who # doesn't sleep in a dumpster is_partner = ast.literal_eval(channel_details[3]) # Download images in case they aren't found # No extension is needed # Will only really be slow the first time profile_image = location_prefix + 'images/' + channel_name if not os.path.exists(profile_image): self.no_profile_images.append(channel_name) except TypeError: # Implies that the channel is not present in the database # and its details will have to be queried from the API # This should only get triggered in case of -w # This will *really* slow down if multiple non database channels # are put into -w since all of them are checked individually # A pox upon thee, Twitch API developers channel_details = name_id_translate( 'channels', 'name_from_id', [user_id]) for j in channel_details.items(): channel_name = j[0] channel_display_name = j[1]['display_name'] is_partner = False if j[1]['broadcaster_type'] == 'partner': is_partner = True uptime = self.parse_uptime(i['started_at']) # Game name and any alternate names will have to be correlated # to the game_id that's returned by the API # Whoever thought this was a good idea can sit on it and rotate game_id = i['game_id'] if not game_id or game_id == '': game_name = game_display_name = 'IDK' else: game_data = self.get_game(game_id) game_name = game_display_name = game_data[0] if game_data[1]: game_display_name = game_data[1] self.online_channels[channel_name] = { 'game': game_name, 'game_id': game_id, 'game_display_name': game_display_name, 'status': i['title'].replace('\n', ''), 'viewers': i['viewer_count'], 'display_name': channel_display_name, 'uptime': uptime, 'is_partner': is_partner } get_profile_image(self.no_profile_images) return self.online_channels