def stream_stop(self, twitch_user_id): try: sql = "SELECT `id` FROM `stream_metrics_time` WHERE `twitch_user_id` = %s AND `stream_stop` IS NULL ORDER BY `id` DESC LIMIT 1" data = data_handler().select(sql, [twitch_user_id]) id = data[0]['id'] sql = "UPDATE `stream_metrics_time` SET `stream_stop`=NOW() WHERE `id`=%s" result = data_handler().update(sql, [id]) except Exception as e: print('stream_metrics: 2') print(e) pass
def __init__(self, twitch_username, discord_channel_id): self.db = data_handler() self.twitch = twitch_handler() self.twitch_username = twitch_username self.discord_channel_id = discord_channel_id self.twitch_user_id = self.twitch.get_twitch_user_id(twitch_username)
def stream_start(self, twitch_user_id): try: sql = "INSERT INTO `stream_metrics_time` VALUES (null, %s, NOW(), null)" x = data_handler().insert(sql, [twitch_user_id]) except: print('stream_metrics: 1') pass
def get_discord_channel_ids(self, yt_channel_id): # This function will search the databse for discord_channel_ids that have subscribed to yt_channel_id sql = "SELECT `disc_channel_id` FROM `youtube` WHERE `yt_channel_id` = %s" values = [yt_channel_id] data = data_handler().select(sql, values) # Flatten the dict to only the keys (disc_channel_id) return(list(map(lambda x : x['disc_channel_id'], data)))
def event(self, data): # This function is called when Twitch sends a webhook callback event = data["event"] try: # store/check event["id"]; Twitch creates a unique ID for each event # Sometimes the same event can be delivered multiple times. This prevents # the event from being processed multiple times. sql = "SELECT `event_id` FROM `twitch_event_ids` WHERE `event_id` = %s" res = data_handler().select(sql, [event["id"]]) if (len(res) != 0): # Event has already been published return # New event, add to the database sql = "INSERT INTO `twitch_event_ids` (`event_id`) VALUES (%s)" data_handler().insert(sql, [event["id"]]) if (event["type"] == "live"): # Channel is now live # Update live status in database sql = "UPDATE `twitch_channels` SET `streaming` = 1 WHERE `twitch_user_id` = %s" data_handler().update(sql, [event['broadcaster_user_id']]) # Format thumbnail URL twitch_thumbnail_url = "https://static-cdn.jtvnw.net/previews-ttv/live_user_" + event[ "broadcaster_user_name"] + "-640x360.jpg" # Prepare and Send discord message discord_post_obj = discord_post() message = discord_post_obj.prepare_twitch_message( event["broadcaster_user_name"], twitch_thumbnail_url) discord_channel_ids = data_handler().select( 'SELECT DISTINCT `discord_channel_id` FROM `twitch_notifications` WHERE `twitch_user_id`=%s', [event["broadcaster_user_id"]]) discord_channel_ids = list( map(lambda x: x['discord_channel_id'], discord_channel_ids)) # FLatten results into a list discord_post_obj.post_message(message, discord_channel_ids) elif (event["type"] == "offline"): # Set streaming status to false sql = "UPDATE `twitch_channels` SET `streaming` = 0 WHERE `twitch_user_id` = %s" data_handler().update(sql, [event['broadcaster_user_id']]) except Exception as e: get_logger().error(e, exc_info=True)
def on_post(self, req, resp, twitch_user_id=None): try: data = json.loads(req.bounded_stream.read().decode()) if 'user_id' in data['data'][0]: # Twitch user is online twitch_username = data['data'][0]['user_name'] # twitch_user_id = data['data'][0]['user_id'] twitch_thumbnail_url = data['data'][0]['thumbnail_url'] # is_streaming resloves an issue with twitch sending multiple stream objects # this prevents duplicate stream notifications is_streaming = data_handler().defined_select("is_streaming", twitch_user_id, False) if(is_streaming[0]['streaming'] == True): # Streaming notification already sent pass else: # Notifcation has not been sent discord_post_obj = discord_post() message = discord_post_obj.prepare_twitch_message(twitch_username, twitch_thumbnail_url) discord_channel_ids = data_handler().defined_select('discord_channels_by_twitch_user_id', [twitch_user_id], True) discord_post_obj.post_message(message, discord_channel_ids) stream_metrics().stream_start(twitch_user_id) data_handler().defined_update('update_is_streaming', [1, twitch_user_id]) except Exception as e: resp.body = str(e) # twitch user is offline stream_metrics().stream_stop(twitch_user_id) data_handler().defined_update('update_is_streaming', [0, twitch_user_id])
def __init__(self): # General headers required for Discord API interactions self.headers = { "Authorization": "Bot {}".format(os.getenv('DISCORD_BOT_TOKEN').strip("\r")), "User-Agent": "KeshBotics (v3.3)", "Content-Type": "application/json" } self.db = data_handler()
def validate_auth_code(self, code): # Checks if the provided code exist in the database, returns true or false db_obj = data_handler() input = [code] sql = "SELECT `authorization_code` FROM `discord_auth` WHERE `authorization_code` = %s" db_select = db_obj.select(sql, input) if (len(db_select) == 0): return (False) else: return (True)
def get_twitch_notifications(self, discord_channel_id): # Return format: # [{'twitch_user_id':x,'twitch_username':y}, ... ] # Get Twitch User IDs sql = "SELECT `twitch_user_id` FROM `twitch_notifications` WHERE `discord_channel_id` = %s" twitch_user_ids = data_handler().select(sql, [discord_channel_id]) if (len(twitch_user_ids) == 0): # No twitch notifications found for the discord_channel_id return (list()) # Flatten the twitch_user_ids dict into a list twitch_user_ids = list( map(lambda x: x['twitch_user_id'], twitch_user_ids)) # Get Twitch Usernames, associated with the list of twitch_user_ids sql = "SELECT `twitch_user_id`, `twitch_username` FROM `twitch_channels` WHERE `twitch_user_id` IN (%s)" # Inserts a '%s' for each element in the twitch_user_ids list sql = sql % ','.join(['%s'] * len(twitch_user_ids)) twitch_data = data_handler().select(sql, tuple(twitch_user_ids)) return (twitch_data)
def on_get(self, req, resp): # Return a list of recent event entries. try: # Get level and limit variables from the headers # If the 'level' header is not provided, set it to 0 if req.get_header('min-log-level') is None: level = 0 else: # Will raise exception if cannot convert to int level = int(req.get_header('min-log-level')) # Create a soft limit of 100 events, this will prevent an excessive amount # of entries being returned. Also if limit is not provided, set it to 100 if req.get_header('limit') is None: limit = 100 else: # Get int value of limit, if limit is greater than 100: set to 100 # Will raise exception if cannot convert to int limit = int(req.get_header('limit')) if limit > 100: limit = 100 # Retrieve the requested entries from the database events = data_handler().select("SELECT * FROM `logging` WHERE `level` >= %s ORDER BY `id` DESC LIMIT %s", [level, limit]) resp.status = falcon.HTTP_200 resp.content_type = ['application/json'] # default=str resloves an issue with datetime.datetime not being # JSON serializable resp.body = json.dumps(events, default=str) except (TypeError, ValueError) as e: # Intended to capture value/type errors with header value int casting get_logger().warning(e, exc_info=True) resp.status = falcon.HTTP_400 resp.content_type = ['application/json'] resp.body = json.dumps({"status":"error", "code":400, "message":"Ensure that header values 'min-log-level' and 'limit' are integers."}) except Exception as e: get_logger().error(e, exc_info=True) resp.status = falcon.HTTP_400 resp.content_type = ['application/json'] resp.body = json.dumps({"status":"error", "code":400, "message":"Failed to retrieve entries."})
def get_stream_metrics(self, twitch_user_id, limit=10): # Prepare dict for return values return_data = {'twitch_user_id':twitch_user_id, 'streams':[ ], 'total':0 } # Retreive stream_start, stream_stop data sql = "SELECT `stream_start`, `stream_stop` FROM `stream_metrics_time` WHERE `twitch_user_id` = %s ORDER BY `id` DESC LIMIT %s" input = [twitch_user_id, limit] data = data_handler().select(sql, input) # Object for storing the total length of broadcast total_time = datetime.timedelta() for stream in data: try: # Compute the lenght of the stream and add to total_time time = stream['stream_stop']-stream['stream_start'] total_time += time # Convert time objects to string stream['time'] = str(time) stream['stream_start'] = str(stream['stream_start']) stream['stream_stop'] = str(stream['stream_stop']) # Append formated stream information to return_data return_data['streams'].append(stream) except Exception as e: print('stream_metrics: 3') pass # Sort the list of streams to be chronological return_data['streams'].reverse() # Add str value of total_time to return data return_data['total'] = str(total_time) return(return_data)
def insert_auth_token(self, data, code): try: db_obj = data_handler() input = [ None, None, code, data['access_token'], data['refresh_token'], data['scope'], data['token_type'] ] sql = "INSERT INTO `discord_auth` VALUES (%s,%s,%s,%s,%s,%s,%s)" db_insert = db_obj.insert(sql, input) return (db_insert) except Exception as e: get_logger().error(e, exc_info=True) return (False)
def __init__(self): self.db = data_handler()
def __init__(self): # Fetch twitch_oauth_token from `settings` DB, and then prepend 'Bearer' twitch_oauth_token = data_handler().select( 'SELECT `setting_value` FROM `settings` WHERE `setting_key` = "twitch_oauth_token"', None)[0]['setting_value'] self.twitch_oauth_token = 'Bearer ' + twitch_oauth_token
def __init__(self): self.oauth_token = 'Bearer ' + data_handler().defined_select( 'twitch_oauth_token', input=None)[0]['setting_value']
def __init__(self): # Object for interacting with the database self.data_handler = data_handler()