async def check_playing(self): activity = px.t_request('get_activity') if activity: guild = await self.bot.fetch_guild(settings.DISCORD_SERVER_ID) if guild: watching_role = discord.utils.get( guild.roles, name=settings.CURRENTLY_PLAYING_ROLE_NAME) guild = self.bot.get_guild( guild.id) # Yes, this is unfortunately necessary users_with_role = [ member for member in guild.members if (watching_role in member.roles) ] active_users = [ session['username'] for session in activity['response']['data']['sessions'] ] # print('Users currently using Plex: {}'.format(active_users)) # Remove old users first for user in users_with_role: plexUsername = db.find_user_in_db(ServerOrDiscord='Plex', data=str(user.id))[0] if not plexUsername or plexUsername not in active_users: await user.remove_roles(watching_role, reason="Not watching Plex.") # Now add new users for username in active_users: discordID = db.find_user_in_db(ServerOrDiscord='Discord', data=username) if discordID: await guild.add_roles(watching_role, reason="Is watching Plex.")
async def plex_search(self, ctx: commands.Context, *, searchTerm: str): """ Search for Plex content """ json_data = px.t_request("search", "query=" + searchTerm)['response']['data'] embed = discord.Embed(title="'" + searchTerm + "' Search Results") if json_data['results_count'] > 0: for k, l in json_data['results_list'].items(): results = "" results_list = [] if k.lower() not in ['episode']: # ignore episode titles for r in l: if searchTerm.lower() in str(r['title']).lower(): if r['title'] in results_list or k == 'collection': results_list.append(r['title'] + " - " + r['library_name']) results += "[{title} - {lib}]((https://app.plex.tv/desktop#!/server/{id}//details?key=%2Flibrary%2Fmetadata%2F{key})\n".format( title=r['title'], lib=r['library_name'], id=settings.PLEX_SERVER_ID, key=r['rating_key']) else: results_list.append(r['title']) results += "[{title}](https://app.plex.tv/desktop#!/server/{id}/details?key=%2Flibrary%2Fmetadata%2F{key})\n".format( title=r['title'], id=settings.PLEX_SERVER_ID, key=r['rating_key']) if results: embed.add_field(name=k.capitalize() + ("s" if len(results_list) > 1 else ""), value=str(results), inline=False) await ctx.send(embed=embed)
async def plex_size(self, ctx: commands.Context): """ Size of Plex libraries """ embed = discord.Embed(title=settings.PLEX_SERVER_NAME[0] + " Library Statistics") size = 0 for l in px.t_request("get_libraries", None)['response']['data']: if l['section_name'] not in [ '' ]: # Exempt sections from list if needed if l['section_type'] == 'movie': size = size + \ px.t_request("get_library_media_info", "section_id=" + str(l['section_id']))['response'][ 'data']['total_file_size'] embed.add_field(name=str(l['count']) + " movies", value=str(l['section_name']), inline=False) elif l['section_type'] == 'show': size = size + \ px.t_request("get_library_media_info", "section_id=" + str(l['section_id']))['response'][ 'data']['total_file_size'] embed.add_field(name=str(l['count']) + " shows, " + str(l['parent_count']) + " seasons, " + str(l['child_count']) + " episodes", value=str(l['section_name']), inline=False) elif l['section_type'] == 'artist': size = size + \ px.t_request("get_library_media_info", "section_id=" + str(l['section_id']))['response'][ 'data']['total_file_size'] embed.add_field(name=str(l['count']) + " artists, " + str(l['parent_count']) + " albums, " + str(l['child_count']) + " songs", value=str(l['section_name']), inline=False) embed.add_field(name='\u200b', value="Total: " + filesize(size)) await ctx.send(embed=embed)
async def plex_stats(self, ctx: commands.Context, PlexUsername: str): """ Watch time statistics for a user """ user_id = None for u in px.t_request("get_user_names", None)['response']['data']: if u['friendly_name'] == PlexUsername: user_id = u['user_id'] break if not user_id: await ctx.send("User not found.") else: embed = discord.Embed(title=PlexUsername + "'s Total Plex Watch Time") for i in px.t_request("get_user_watch_time_stats", "user_id=" + str(user_id))['response']['data']: embed.add_field( name=str(datetime.timedelta(seconds=int(i['total_time']))) + ", " + str(i['total_plays']) + " plays", value=("Last " + str(i['query_days']) + (" Day " if int(i['query_days']) == 1 else " Days ") if int(i['query_days']) != 0 else "All Time "), inline=False) await ctx.send(embed=embed)
async def purge_winners(self, ctx): try: results = db.getWinners() monitorlist = [] for u in results: monitorlist.append(u[0]) print("Winners: ") print(monitorlist) data = px.t_request("get_users_table", "length=1000") removed_list = "" error_message = "" for i in data['response']['data']['data']: try: if str(i['friendly_name']) in monitorlist: PlexUsername = (px.t_request( "get_user", "user_id=" + str(i['user_id'])))['response']['data']['username'] if i['duration'] is None: print(PlexUsername + " has not watched anything. Purging...") mention_id = await self.remove_winner( str(PlexUsername)) removed_list = removed_list + ( mention_id if mention_id is not None else "") elif i['last_seen'] is None: print(PlexUsername + " has never been seen. Purging...") mention_id = await self.remove_winner( str(PlexUsername)) removed_list = removed_list + ( mention_id if mention_id is not None else "") elif i['duration'] / 3600 < settings.WINNER_THRESHOLD: print( PlexUsername + " has NOT met the duration requirements. Purging..." ) mention_id = await self.remove_winner( str(PlexUsername)) removed_list = removed_list + ( mention_id if mention_id is not None else "") elif time.time() - i['last_seen'] > 1209600: print(PlexUsername + " last seen too long ago. Purging...") mention_id = await self.remove_winner( str(PlexUsername)) removed_list = removed_list + ( mention_id if mention_id is not None else "") else: print( PlexUsername + " has met the requirements, and will not be purged." ) except Exception as e: print(e) error_message = error_message + "Error checking " + str( i['friendly_name']) + ". " pass if removed_list != "": await ctx.send( removed_list + "You have been removed as a Winner due to inactivity.") else: await ctx.send("No winners purged.") if error_message != "": await ctx.send(error_message) except Exception as e: print(e) await ctx.send("Something went wrong. Please try again later.")
async def plex_new(self, ctx: commands.Context): """ See recently added content """ e = discord.Embed(title="Recently Added to " + str(settings.PLEX_SERVER_NAME[0])) count = 5 cur = 0 recently_added = px.t_request("get_recently_added", "count=" + str(count)) listing = recently_added['response']['data']['recently_added'][cur] url = '{base}/api/v2?apikey={key}&cmd=pms_image_proxy&img={thumb}'.format( base=settings.TAUTULLI_URL[0], key=settings.TAUTULLI_API_KEY[0], thumb=listing['thumb']) e.set_image(url=url) e.description = "({loc}/{count}) {title} - [Watch Now](https://app.plex.tv/desktop#!/server/{id}//details?key=%2Flibrary%2Fmetadata%2F{key})".format( loc=str(cur + 1), count=str(count), title=(listing['grandparent_title'] if listing['grandparent_title'] else (listing['parent_title'] if listing['parent_title'] else listing['full_title'])), id=settings.PLEX_SERVER_ID, key=listing['rating_key']) ra_embed = await ctx.send(embed=e) nav = True while nav: def check(reaction, user): return user != ra_embed.author try: if cur == 0: await ra_embed.add_reaction(u"\u27A1") # arrow_right elif cur == count - 1: await ra_embed.add_reaction(u"\u2B05") # arrow_left else: await ra_embed.add_reaction(u"\u2B05") # arrow_left await ra_embed.add_reaction(u"\u27A1") # arrow_right reaction, user = await self.bot.wait_for('reaction_add', timeout=60.0, check=check) except asyncio.TimeoutError: await ra_embed.delete() nav = False px.t_request("delete_image_cache", None) else: if reaction.emoji == u"\u27A1": if cur + 1 < count: cur += 1 listing = recently_added['response']['data'][ 'recently_added'][cur] url = '{base}/api/v2?apikey={key}&cmd=pms_image_proxy&img={thumb}'.format( base=settings.TAUTULLI_URL[0], key=settings.TAUTULLI_API_KEY[0], thumb=listing['thumb']) e.set_image(url=url) e.description = "({loc}/{count}) {title} - [Watch Now](https://app.plex.tv/desktop#!/server/{id}//details?key=%2Flibrary%2Fmetadata%2F{key})".format( loc=str(cur + 1), count=str(count), title=(listing['grandparent_title'] if listing['grandparent_title'] else (listing['parent_title'] if listing['parent_title'] else listing['full_title'])), id=settings.PLEX_SERVER_ID, key=listing['rating_key']) await ra_embed.edit(embed=e) await ra_embed.clear_reactions() else: if cur - 1 >= 0: cur -= 1 listing = recently_added['response']['data'][ 'recently_added'][cur] url = '{base}/api/v2?apikey={key}&cmd=pms_image_proxy&img={thumb}'.format( base=settings.TAUTULLI_URL[0], key=settings.TAUTULLI_API_KEY[0], thumb=listing['thumb']) e.set_image(url=url) e.description = "({loc}/{count}) {title} - [Watch Now](https://app.plex.tv/desktop#!/server/{id}//details?key=%2Flibrary%2Fmetadata%2F{key})".format( loc=str(cur + 1), count=str(count), title=(listing['grandparent_title'] if listing['grandparent_title'] else (listing['parent_title'] if listing['parent_title'] else listing['full_title'])), id=settings.PLEX_SERVER_ID, key=listing['rating_key']) await ra_embed.edit(embed=e) await ra_embed.clear_reactions()
async def plex_now(self, ctx: commands.Context): """ Current Plex activity """ embed = discord.Embed(title="Current Plex activity") json_data = px.t_request("get_activity", None) try: stream_count = json_data['response']['data']['stream_count'] transcode_count = json_data['response']['data'][ 'stream_count_transcode'] total_bandwidth = json_data['response']['data']['total_bandwidth'] lan_bandwidth = json_data['response']['data']['lan_bandwidth'] overview_message = "Sessions: " + str(stream_count) + ( " stream" if int(stream_count) == 1 else " streams") + ( (" (" + str(transcode_count) + (" transcode" if int(transcode_count) == 1 else " transcodes") + ")") if int(transcode_count) > 0 else "" ) + ((" | Bandwidth: " + str(round(Decimal(float(total_bandwidth) / 1024), 1)) + " Mbps" + ((" (LAN: " + str(round(Decimal(float(lan_bandwidth) / 1024), 1)) + " Mbps)") if int(lan_bandwidth) > 0 else "")) if int(total_bandwidth) > 0 else "") sessions = json_data['response']['data']['sessions'] count = 0 final_message = overview_message + "\n" for session in sessions: try: count = count + 1 stream_message = "**(" + str(count) + ")** " + selectIcon( str(session['state'])) + " " + str( session['username']) + ": *" + str( session["full_title"]) + "*\n" stream_message = stream_message + "__Player__: " + str( session['product']) + " (" + str( session['player']) + ")\n" stream_message = stream_message + "__Quality__: " + str( session['quality_profile'] ) + " (" + (str( round(Decimal(float(session['bandwidth']) / 1024), 1)) if session['bandwidth'] is not "" else "O") + " Mbps)" + (" (Transcode)" if str( session['stream_container_decision']) == 'transcode' else "") final_message = final_message + "\n" + stream_message + "\n" session_ids.append(str(session['session_id'])) except ValueError: session_ids.append("000") pass print(final_message) if int(stream_count) > 0: sent_message = await ctx.send( final_message + "\nTo terminate a stream, react with the stream number.") for i in range(count): await sent_message.add_reaction(emoji_numbers[i]) manage_streams = True while manage_streams: def check(reaction, user): return user != sent_message.author try: reaction, user = await self.bot.wait_for( 'reaction_add', timeout=60.0, check=check) if reaction and str(reaction.emoji) in emoji_numbers: try: loc = emoji_numbers.index(str(reaction.emoji)) px.t_request( 'terminate_session', 'session_id=' + str(session_ids[loc]) + '&message=' + str(settings.TERMINATE_MESSAGE)) end_notification = await ctx.send( content="Stream " + str(loc + 1) + " was ended.") await end_notification.delete(delay=1.0) except: end_notification = await ctx.send( content="Something went wrong.") await end_notification.delete(delay=1.0) except asyncio.TimeoutError: await sent_message.delete() manage_streams = False else: await ctx.send("No current activity.") except KeyError: await ctx.send("**Connection error.**")
async def plex_top(self, ctx: commands.Context, searchTerm: str, timeRange: int): """ Most popular media or most active users during time range (in days) Use 'movies','shows','artists' or 'users' """ embed = discord.Embed( title=('Most popular ' + searchTerm.lower() if searchTerm.lower() != 'users' else 'Most active users') + ' in past ' + str(timeRange) + (' days' if int(timeRange) > 1 else ' day')) count = 1 if searchTerm.lower() == "movies": for m in \ px.t_request("get_home_stats", "time_range=" + str(timeRange) + "&stats_type=duration&stats_count=5")[ 'response']['data'][0]['rows']: embed.add_field( name=str(count) + ". " + str(m['title']), value=str(m['total_plays']) + (" plays" if int(m['total_plays']) > 1 else " play"), inline=False) count = count + 1 await ctx.send(embed=embed) elif searchTerm.lower() == "shows": for m in \ px.t_request("get_home_stats", "time_range=" + str(timeRange) + "&stats_type=duration&stats_count=5")[ 'response']['data'][1]['rows']: embed.add_field( name=str(count) + ". " + str(m['title']), value=str(m['total_plays']) + (" plays" if int(m['total_plays']) > 1 else " play"), inline=False) count = count + 1 await ctx.send(embed=embed) elif searchTerm.lower() == "artists": for m in \ px.t_request("get_home_stats", "time_range=" + str(timeRange) + "&stats_type=duration&stats_count=5")[ 'response']['data'][2]['rows']: embed.add_field( name=str(count) + ". " + str(m['title']), value=str(m['total_plays']) + (" plays" if int(m['total_plays']) > 1 else " play"), inline=False) count = count + 1 await ctx.send(embed=embed) elif searchTerm.lower() == "users": for m in \ px.t_request("get_home_stats", "time_range=" + str(timeRange) + "&stats_type=duration&stats_count=5")[ 'response']['data'][7]['rows']: embed.add_field( name=str(count) + ". " + str(m['friendly_name']), value=str(m['total_plays']) + (" plays" if int(m['total_plays']) > 1 else " play"), inline=False) count = count + 1 await ctx.send(embed=embed) else: await ctx.send( "Please try again. Use 'movies','shows','artists' or 'users'")