From 8bbc6a6611a015a935e6da9ff4633bdb88a3d40e Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 19:51:10 -0800 Subject: [PATCH 01/14] Fix libraries without section_id in database --- plexpy/__init__.py | 15 +++++++++++++-- plexpy/pmsconnect.py | 8 ++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 03b393f1..c59ee7a2 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -739,7 +739,7 @@ def dbcheck(): 'ALTER TABLE library_sections_temp RENAME TO library_sections' ) except sqlite3.OperationalError: - logger.debug(u"Unable to remove section_id unique constraint from library_sections.") + logger.warn(u"Unable to remove section_id unique constraint from library_sections.") try: c_db.execute( 'DROP TABLE library_sections_temp' @@ -747,6 +747,17 @@ def dbcheck(): except: pass + # Upgrade library_sections table from earlier versions (remove duplicated libraries) + try: + result = c_db.execute('SELECT * FROM library_sections WHERE server_id = ""') + if result.rowcount > 0: + logger.debug(u"Altering database. Removing duplicate libraries from library_sections table.") + c_db.execute( + 'DELETE FROM library_sections WHERE server_id = ""' + ) + except sqlite3.OperationalError: + logger.warn(u"Unable to remove duplicate libraries from library_sections table.") + # Upgrade users table from earlier versions (remove UNIQUE constraint on username) try: result = c_db.execute('PRAGMA index_xinfo("sqlite_autoindex_users_2")') @@ -773,7 +784,7 @@ def dbcheck(): 'ALTER TABLE users_temp RENAME TO users' ) except sqlite3.OperationalError: - logger.debug(u"Unable to remove username unique constraint from users.") + logger.warn(u"Unable to remove username unique constraint from users.") try: c_db.execute( 'DROP TABLE users_temp' diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index 8f2e0bfd..2a1a76b0 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -40,15 +40,19 @@ def get_server_friendly_name(): def refresh_libraries(): logger.info(u"PlexPy Pmsconnect :: Requesting libraries list refresh...") - library_sections = PmsConnect().get_library_details() server_id = plexpy.CONFIG.PMS_IDENTIFIER + if not server_id: + logger.error(u"PlexPy Pmsconnect :: No PMS identifier, cannot refresh libraries. Verify server in settings.") + return - library_keys = [] + library_sections = PmsConnect().get_library_details() if library_sections: monitor_db = database.MonitorDatabase() + library_keys = [] + for section in library_sections: section_keys = {'server_id': server_id, 'section_id': section['section_id']} From bc52ac3559e82a239cca2254ca91861cc4d06497 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 19:51:36 -0800 Subject: [PATCH 02/14] Remove media type toggles from recently added notifications --- plexpy/notification_handler.py | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index 27ce5a28..d1ea6856 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -211,23 +211,17 @@ def notify(stream_data=None, notify_action=None): def notify_timeline(timeline_data=None, notify_action=None): if timeline_data and notify_action: - if (timeline_data['media_type'] == 'movie' and plexpy.CONFIG.MOVIE_NOTIFY_ENABLE) \ - or ((timeline_data['media_type'] == 'show' or timeline_data['media_type'] == 'episode') \ - and plexpy.CONFIG.TV_NOTIFY_ENABLE) \ - or ((timeline_data['media_type'] == 'artist' or timeline_data['media_type'] == 'track') \ - and plexpy.CONFIG.MUSIC_NOTIFY_ENABLE): - - for agent in notifiers.available_notification_agents(): - if agent['on_created'] and notify_action == 'created': - # Build and send notification - notify_strings = build_notify_text(timeline=timeline_data, state=notify_action) - notifiers.send_notification(config_id=agent['id'], - subject=notify_strings[0], - body=notify_strings[1], - notify_action=notify_action, - script_args=notify_strings[2]) - # Set the notification state in the db - set_notify_state(session=timeline_data, state=notify_action, agent_info=agent) + for agent in notifiers.available_notification_agents(): + if agent['on_created'] and notify_action == 'created': + # Build and send notification + notify_strings = build_notify_text(timeline=timeline_data, state=notify_action) + notifiers.send_notification(config_id=agent['id'], + subject=notify_strings[0], + body=notify_strings[1], + notify_action=notify_action, + script_args=notify_strings[2]) + # Set the notification state in the db + set_notify_state(session=timeline_data, state=notify_action, agent_info=agent) elif not timeline_data and notify_action: for agent in notifiers.available_notification_agents(): From 95f92bd292667aa314afa5073f9747c6c784a554 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 19:51:58 -0800 Subject: [PATCH 03/14] Add unique identifiers to notification options --- data/interfaces/default/settings.html | 20 ++++++++++++++++++++ plexpy/notification_handler.py | 9 ++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 672c9fbf..92134041 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -1224,6 +1224,10 @@ available_notification_agents = sorted(notifiers.available_notification_agents() {transcode_audio_channels} The audio channels of the transcoded media. + + {user_id} + The unique identifier for the user. + @@ -1323,6 +1327,22 @@ available_notification_agents = sorted(notifiers.available_notification_agents() + + + + + + + + + + + + + + + +
{duration} The duration (in minutes) for the item.
{section_id}The unique identifier for the library.
{rating_key}The unique identifier for the item.
{parent_rating_key}The unique identifier for the item parent (season or album).
{grandparent_rating_key}The unique identifier for the item grandparent (TV show or artist).
diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index d1ea6856..fab5803d 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -456,6 +456,7 @@ def build_notify_text(session=None, timeline=None, state=None): transcode_video_height = '' transcode_audio_codec = '' transcode_audio_channels = '' + user_id = '' # Session values if session: @@ -498,6 +499,7 @@ def build_notify_text(session=None, timeline=None, state=None): transcode_video_height = session['transcode_height'] transcode_audio_codec = session['transcode_audio_codec'] transcode_audio_channels = session['transcode_audio_channels'] + user_id = session['user_id'] progress_percent = helpers.get_percent(view_offset, duration) @@ -549,6 +551,7 @@ def build_notify_text(session=None, timeline=None, state=None): 'transcode_video_height': transcode_video_height, 'transcode_audio_codec': transcode_audio_codec, 'transcode_audio_channels': transcode_audio_channels, + 'user_id': user_id, 'title': full_title, 'library_name': metadata['library_name'], 'show_name': show_name, @@ -570,7 +573,11 @@ def build_notify_text(session=None, timeline=None, state=None): 'summary': metadata['summary'], 'tagline': metadata['tagline'], 'rating': metadata['rating'], - 'duration': duration + 'duration': duration, + 'section_id': metadata['section_id'], + 'rating_key': metadata['rating_key'], + 'parent_rating_key': metadata['parent_rating_key'], + 'grandparent_rating_key': metadata['grandparent_rating_key'] } # Default subject text From d94b34878030b30e37c4a7ece6fce57014bb900b Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 19:52:30 -0800 Subject: [PATCH 04/14] Fix buffer notifications even when disabled with websockets --- plexpy/activity_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py index 956cee73..fe6de42f 100644 --- a/plexpy/activity_handler.py +++ b/plexpy/activity_handler.py @@ -156,8 +156,8 @@ class ActivityHandler(object): (self.get_session_key(), buffer_last_triggered)) time_since_last_trigger = int(time.time()) - int(buffer_last_triggered) - if current_buffer_count >= plexpy.CONFIG.BUFFER_THRESHOLD and time_since_last_trigger == 0 or \ - time_since_last_trigger >= plexpy.CONFIG.BUFFER_WAIT: + if plexpy.CONFIG.BUFFER_THRESHOLD > 0 and (current_buffer_count >= plexpy.CONFIG.BUFFER_THRESHOLD and \ + time_since_last_trigger == 0 or time_since_last_trigger >= plexpy.CONFIG.BUFFER_WAIT): ap.set_session_buffer_trigger_time(session_key=self.get_session_key()) threading.Thread(target=notification_handler.notify, kwargs=dict(stream_data=db_stream, notify_action='buffer')).start() From 58796c45ed13dbb4e5834109d6276f663d6f9cf1 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 21:19:18 -0800 Subject: [PATCH 05/14] Remove built in Twitter consumer key and secret --- plexpy/config.py | 7 +++-- plexpy/notifiers.py | 73 +++++++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/plexpy/config.py b/plexpy/config.py index afe81bf8..9cc23068 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -360,9 +360,10 @@ _CONFIG_DEFINITIONS = { 'TV_NOTIFY_ON_STOP': (int, 'Monitoring', 0), 'TV_NOTIFY_ON_PAUSE': (int, 'Monitoring', 0), 'TWITTER_ENABLED': (int, 'Twitter', 0), - 'TWITTER_PASSWORD': (str, 'Twitter', ''), - 'TWITTER_PREFIX': (str, 'Twitter', 'PlexPy'), - 'TWITTER_USERNAME': (str, 'Twitter', ''), + 'TWITTER_ACCESS_TOKEN': (str, 'Twitter', ''), + 'TWITTER_ACCESS_TOKEN_SECRET': (str, 'Twitter', ''), + 'TWITTER_CONSUMER_KEY': (str, 'Twitter', ''), + 'TWITTER_CONSUMER_SECRET': (str, 'Twitter', ''), 'TWITTER_ON_PLAY': (int, 'Twitter', 0), 'TWITTER_ON_STOP': (int, 'Twitter', 0), 'TWITTER_ON_PAUSE': (int, 'Twitter', 0), diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index a23f8b58..360fa47e 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1165,8 +1165,10 @@ class TwitterNotifier(object): SIGNIN_URL = 'https://api.twitter.com/oauth/authenticate' def __init__(self): - self.consumer_key = "2LdJKXHDUwJtjYBsdwJisIOsh" - self.consumer_secret = "QWbUcZzAIiL4zbDCIhy2EdUkV8yEEav3qMdo5y3FugxCFelWrA" + self.access_token = plexpy.CONFIG.TWITTER_ACCESS_TOKEN + self.access_token_secret = plexpy.CONFIG.TWITTER_ACCESS_TOKEN_SECRET + self.consumer_key = plexpy.CONFIG.TWITTER_CONSUMER_KEY + self.consumer_secret = plexpy.CONFIG.TWITTER_CONSUMER_SECRET def notify(self, subject, message): if not subject or not message: @@ -1191,16 +1193,16 @@ class TwitterNotifier(object): else: request_token = dict(parse_qsl(content)) - plexpy.CONFIG.TWITTER_USERNAME = request_token['oauth_token'] - plexpy.CONFIG.TWITTER_PASSWORD = request_token['oauth_token_secret'] + plexpy.CONFIG.TWITTER_ACCESS_TOKEN = request_token['oauth_token'] + plexpy.CONFIG.TWITTER_ACCESS_TOKEN_SECRET = request_token['oauth_token_secret'] return self.AUTHORIZATION_URL + "?oauth_token=" + request_token['oauth_token'] def _get_credentials(self, key): request_token = {} - request_token['oauth_token'] = plexpy.CONFIG.TWITTER_USERNAME - request_token['oauth_token_secret'] = plexpy.CONFIG.TWITTER_PASSWORD + request_token['oauth_token'] = plexpy.CONFIG.TWITTER_ACCESS_TOKEN + request_token['oauth_token_secret'] = plexpy.CONFIG.TWITTER_ACCESS_TOKEN_SECRET request_token['oauth_callback_confirmed'] = 'true' token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret']) @@ -1225,20 +1227,20 @@ class TwitterNotifier(object): else: # logger.info(u"PlexPy Notifiers :: Your Twitter Access Token key: %s" % access_token['oauth_token']) # logger.info(u"PlexPy Notifiers :: Access Token secret: %s" % access_token['oauth_token_secret']) - plexpy.CONFIG.TWITTER_USERNAME = access_token['oauth_token'] - plexpy.CONFIG.TWITTER_PASSWORD = access_token['oauth_token_secret'] + plexpy.CONFIG.TWITTER_ACCESS_TOKEN = access_token['oauth_token'] + plexpy.CONFIG.TWITTER_ACCESS_TOKEN_SECRET = access_token['oauth_token_secret'] plexpy.CONFIG.write() return True def _send_tweet(self, message=None): - username = self.consumer_key - password = self.consumer_secret - access_token_key = plexpy.CONFIG.TWITTER_USERNAME - access_token_secret = plexpy.CONFIG.TWITTER_PASSWORD + consumer_key = self.consumer_key + consumer_secret = self.consumer_secret + access_token = self.access_token + access_token_secret = self.access_token_secret # logger.info(u"PlexPy Notifiers :: Sending tweet: " + message) - api = twitter.Api(username, password, access_token_key, access_token_secret) + api = twitter.Api(consumer_key, consumer_secret, access_token, access_token_secret) try: api.PostUpdate(message) @@ -1251,30 +1253,37 @@ class TwitterNotifier(object): def return_config_options(self): config_option = [{'label': 'Instructions', - 'description': 'Step 1: Click the Request Authorization button below.
\ - Step 2: Input the Authorization Key you received from Step 1 below.
\ - Step 3: Click the Verify Key button below.', + 'description': 'Step 1: Visit \ + Twitter Apps to Create New App. A vaild "Website" is not required.
\ + Step 2: Go to Keys and Access Tokens and click \ + Create my access token.
\ + Step 3: Fill in the Consumer Key, Consumer Secret, \ + Access Token, and Access Token Secret below.', 'input_type': 'help' }, - {'label': 'Request Authorization', - 'value': 'Request Authorization', - 'name': 'twitterStep1', - 'description': 'Request Twitter authorization. (Ensure you allow the browser pop-up).', - 'input_type': 'button' - }, - {'label': 'Authorization Key', - 'value': '', - 'name': 'twitter_key', - 'description': 'Your Twitter authorization key.', + {'label': 'Twitter Consumer Key', + 'value': self.consumer_key, + 'name': 'twitter_consumer_key', + 'description': 'Your Twitter consumer key.', 'input_type': 'text' }, - {'label': 'Verify Key', - 'value': 'Verify Key', - 'name': 'twitterStep2', - 'description': 'Verify your Twitter authorization key.', - 'input_type': 'button' + {'label': 'Twitter Consumer Secret', + 'value': self.consumer_secret, + 'name': 'twitter_consumer_secret', + 'description': 'Your Twitter consumer secret.', + 'input_type': 'text' }, - {'input_type': 'nosave' + {'label': 'Twitter Access Token', + 'value': self.access_token, + 'name': 'twitter_access_token', + 'description': 'Your Twitter access token.', + 'input_type': 'text' + }, + {'label': 'Twitter Access Token Secret', + 'value': self.access_token_secret, + 'name': 'twitter_access_token_secret', + 'description': 'Your Twitter access token secret.', + 'input_type': 'text' } ] From c19162295a862ada11365ee73d81c95de5191c0c Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 21:20:04 -0800 Subject: [PATCH 06/14] Update Facebook instructions --- plexpy/notifiers.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 360fa47e..bb5d8947 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -2097,12 +2097,16 @@ class FacebookNotifier(object): config_option = [{'label': 'Instructions', 'description': 'Facebook notifications are currently experimental!

\ Step 1: Visit \ - Facebook Developers to create a new app using advanced setup.
\ - Step 2: Go to Settings > Advanced and fill in \ + Facebook Developers to add a new app using basic setup.
\ + Step 2: Go to Settings > Basic and fill in a \ + Contact Email.
\ + Step 3: Go to Settings > Advanced and fill in \ Valid OAuth redirect URIs with your PlexPy URL (i.e. http://localhost:8181).
\ - Step 3: Fill in the PlexPy URL below with the exact same URL from Step 2.
\ - Step 4: Fill in the App ID and App Secret below.
\ - Step 5: Click the Request Authorization button below.', + Step 4: Go to App Review and toggle public to Yes.
\ + Step 5: Fill in the PlexPy URL below with the exact same URL from Step 3.
\ + Step 6: Fill in the App ID and App Secret below.
\ + Step 7: Click the Request Authorization button below.
\ + Step 8: Fill in the Group ID below.', 'input_type': 'help' }, {'label': 'PlexPy URL', From a9ce92decb9f7d65fd0221baf3454ba3c61649d3 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 21:30:35 -0800 Subject: [PATCH 07/14] Change Telegram wording --- plexpy/notifiers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index bb5d8947..1623cd8d 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1677,10 +1677,10 @@ class TELEGRAM(object): 'description': 'Your Telegram bot token. Contact @BotFather on Telegram to get one.', 'input_type': 'text' }, - {'label': 'Telegram Chat ID', + {'label': 'Telegram Chat ID, Group ID, or Channel Username', 'value': self.chat_id, 'name': 'telegram_chat_id', - 'description': 'Your Telegram Chat ID, Group ID, or channel username. Contact @myidbot on Telegram to get an ID.', + 'description': 'Your Telegram Chat ID, Group ID, or @channelusername. Contact @myidbot on Telegram to get an ID.', 'input_type': 'text' } ] From a8aae9f1f5e036c5bd0b3fb784c85fb9876725a8 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 23:32:01 -0800 Subject: [PATCH 08/14] Fix libraries and users refresh --- data/interfaces/default/settings.html | 7 +++++-- data/interfaces/default/welcome.html | 1 + plexpy/__init__.py | 2 +- plexpy/libraries.py | 14 +++++++++----- plexpy/users.py | 3 +-- plexpy/webserve.py | 18 +++++++++++------- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 92134041..96c2f14f 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -359,6 +359,10 @@ available_notification_agents = sorted(notifiers.available_notification_agents()

Force PlexPy to connect to your Plex Server via SSL. Your server needs to have remote access enabled.

+ + + +

Plex Logs

@@ -374,8 +378,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents() Click here for help. This is required if you enable IP logging (for PMS 0.9.12 and below).

- - @@ -1554,6 +1556,7 @@ $(document).ready(function() { serverChanged = true; $("#pms_identifier").val(""); $("#pms-verify-status").html(""); + $("#server_changed").prop('checked', true); verifyServer(); }); diff --git a/data/interfaces/default/welcome.html b/data/interfaces/default/welcome.html index 0b19eca1..a717ad0e 100644 --- a/data/interfaces/default/welcome.html +++ b/data/interfaces/default/welcome.html @@ -169,6 +169,7 @@ from plexpy import common + diff --git a/plexpy/__init__.py b/plexpy/__init__.py index c59ee7a2..1bc46e8c 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -176,7 +176,7 @@ def initialize(config_file): plextv.refresh_users() # Refresh the libraries list on startup - if CONFIG.PMS_TOKEN and CONFIG.REFRESH_LIBRARIES_ON_STARTUP: + if CONFIG.PMS_IP and CONFIG.PMS_TOKEN and CONFIG.REFRESH_LIBRARIES_ON_STARTUP: pmsconnect.refresh_libraries() # Store the original umask diff --git a/plexpy/libraries.py b/plexpy/libraries.py index 61a2f621..ca60e11c 100644 --- a/plexpy/libraries.py +++ b/plexpy/libraries.py @@ -22,8 +22,6 @@ def update_section_ids(): plexpy.CONFIG.UPDATE_SECTION_IDS = -1 - logger.info(u"PlexPy Libraries :: Updating section_id's in database.") - #logger.debug(u"PlexPy Libraries :: Disabling monitoring while update in progress.") #plexpy.schedule_job(activity_pinger.check_active_sessions, 'Check for active sessions', # hours=0, minutes=0, seconds=0) @@ -51,6 +49,13 @@ def update_section_ids(): #plexpy.initialize_scheduler() return None + if not history_results: + plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0) + plexpy.CONFIG.write() + return None + + logger.info(u"PlexPy Libraries :: Updating section_id's in database.") + # Add thread filter to the logger #logger.debug(u"PlexPy Libraries :: Disabling logging in the current thread while update in progress.") #thread_filter = logger.NoThreadFilter(threading.current_thread().name) @@ -572,11 +577,10 @@ class Libraries(object): return library_details else: logger.warn(u"PlexPy Libraries :: Unable to retrieve library from local database. Requesting library list refresh.") - # Let's first refresh the user list to make sure the user isn't newly added and not in the db yet + # Let's first refresh the libraries list to make sure the library isn't newly added and not in the db yet + pmsconnect.refresh_libraries() try: if section_id: - # Refresh libraries - pmsconnect.refresh_libraries() query = 'SELECT section_id, section_name, section_type, count, parent_count, child_count, ' \ 'thumb AS library_thumb, custom_thumb_url AS custom_thumb, art, ' \ 'do_notify, do_notify_created, keep_history ' \ diff --git a/plexpy/users.py b/plexpy/users.py index d4221efa..19294285 100644 --- a/plexpy/users.py +++ b/plexpy/users.py @@ -292,10 +292,9 @@ class Users(object): else: logger.warn(u"PlexPy Users :: Unable to retrieve user from local database. Requesting user list refresh.") # Let's first refresh the user list to make sure the user isn't newly added and not in the db yet + plextv.refresh_users() try: if str(user_id).isdigit(): - # Refresh users - plextv.refresh_users() query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \ 'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history ' \ 'FROM users ' \ diff --git a/plexpy/webserve.py b/plexpy/webserve.py index c1cb3df1..f3f18dfc 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -1151,6 +1151,7 @@ class WebInterface(object): del kwargs[use_config] # Check if we should refresh our data + server_changed = False refresh_libraries = False refresh_users = False reschedule = False @@ -1173,11 +1174,6 @@ class WebInterface(object): (kwargs['monitor_remote_access'] != plexpy.CONFIG.MONITOR_REMOTE_ACCESS): reschedule = True - if 'pms_ip' in kwargs: - if kwargs['pms_ip'] != plexpy.CONFIG.PMS_IP: - refresh_libraries = True - refresh_users = True - # Remove config with 'hscard-' prefix and change home_stats_cards to list if 'home_stats_cards' in kwargs: for k in kwargs.keys(): @@ -1198,16 +1194,24 @@ class WebInterface(object): if kwargs['home_library_cards'] == ['first_run_wizard']: refresh_libraries = True + if 'server_changed' in kwargs: + del kwargs['server_changed'] + server_changed = True + refresh_users = True + refresh_libraries = True + plexpy.CONFIG.process_kwargs(kwargs) # Write the config plexpy.CONFIG.write() # Get new server URLs for SSL communications. - plextv.get_real_pms_url() + if server_changed: + plextv.get_real_pms_url() # Get new server friendly name. - pmsconnect.get_server_friendly_name() + if server_changed: + pmsconnect.get_server_friendly_name() # Reconfigure scheduler if intervals changed if reschedule: From 67377a256157a9a42c09577b75eeadfd4d015bc9 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 27 Jan 2016 23:32:21 -0800 Subject: [PATCH 09/14] Fix server verification in settings --- plexpy/webserve.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plexpy/webserve.py b/plexpy/webserve.py index f3f18dfc..a70b8252 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -1382,9 +1382,16 @@ class WebInterface(object): @cherrypy.expose def get_server_id(self, hostname=None, port=None, identifier=None, ssl=0, remote=0, **kwargs): - from plexpy import http_handler + if not identifier: + plex_tv = plextv.PlexTV() + servers = plex_tv.discover() - if hostname and port: + for server in servers: + if server['ip'] == hostname and server['port'] == port: + identifier = server['clientIdentifier'] + break + + if identifier and hostname and port: # Set PMS attributes to get the real PMS url plexpy.CONFIG.__setattr__('PMS_IP', hostname) plexpy.CONFIG.__setattr__('PMS_PORT', port) From 0eaea4d011c1378a7a3f1d058a321161920ee63c Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Fri, 29 Jan 2016 18:38:19 -0800 Subject: [PATCH 10/14] Fix empty libraries not added --- plexpy/pmsconnect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index 2a1a76b0..b31e56e9 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -1694,8 +1694,8 @@ class PmsConnect(object): section_id = library['section_id'] children_list = self.get_library_children_details(section_id=section_id, section_type=section_type, count='1') - if children_list and children_list['library_count'] != '0': - library_stats = {'section_id': library['section_id'], + if children_list: + library_stats = {'section_id': section_id, 'section_name': library['section_name'], 'section_type': section_type, 'thumb': library['thumb'], From 1cb75bd05318beda184bdce046df249dca6de566 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Fri, 29 Jan 2016 18:47:12 -0800 Subject: [PATCH 11/14] Remove unnecessary quoting of script arguments --- plexpy/notification_handler.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index fab5803d..cea0b601 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -586,10 +586,6 @@ def build_notify_text(session=None, timeline=None, state=None): # Default scripts args script_args = [] - # Regex to match {param} but not "{param}" - params_to_quote = re.compile(r'(?"', script_args_text) - if script_args_text: try: script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()] @@ -805,10 +801,6 @@ def build_server_notify_text(state=None): # Default scripts args script_args = [] - # Regex to match {param} but not "{param}" - params_to_quote = re.compile(r'(?"', script_args_text) - if script_args_text: try: script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()] From 01fe7bf6121f4d96590814cb6f57737c1689f8bd Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Fri, 29 Jan 2016 19:06:08 -0800 Subject: [PATCH 12/14] Reorganize notification options --- data/interfaces/default/settings.html | 80 +++++++++++++++------------ plexpy/notification_handler.py | 4 +- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 96c2f14f..f05d4ba7 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -1074,7 +1074,7 @@ available_notification_agents = sorted(notifiers.available_notification_agents() - Server Details + Global @@ -1087,6 +1087,18 @@ available_notification_agents = sorted(notifiers.available_notification_agents() {server_uptime} The uptime (in days, hours, mins, secs) of your Plex Server. + + {action} + The action that triggered the notification. + + + {datestamp} + The date the notification was triggered. + + + {timestamp} + The time the notification was triggered. + @@ -1102,18 +1114,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents() - - - - - - - - - - - - @@ -1130,10 +1130,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents() - - - - @@ -1241,37 +1237,41 @@ available_notification_agents = sorted(notifiers.available_notification_agents() + + + + - + - + - + - + - + - + - + - + @@ -1279,43 +1279,51 @@ available_notification_agents = sorted(notifiers.available_notification_agents() - + + + + + + + + + - + - + - + - + - + - + - + - + @@ -1339,11 +1347,11 @@ available_notification_agents = sorted(notifiers.available_notification_agents() - + - +
{streams} The number of concurrent streams.
{action}The action that triggered the notification.
{datestamp}The date the notification was triggered.
{timestamp}The time the notification was triggered.
{user} The username of the person streaming.{ip_address} The IP address of the device being used for playback. (PMS 0.9.14 and above)
{media_type}The type of media being played (movie, episode, track).
{stream_duration} The stream duration (in minutes) for the item.
{media_type}The type of media (movie, episode, track).
{title}The full title of the item being played.The full title of the item.
{library_name}The library title of the item being played.The library title of the media item.
{show_name}The title of the TV series being played.The title of the TV series.
{episode_name}The title of the episode being played.The title of the episode.
{artist_name}The name of the artist being played.The name of the artistd.
{album_name}The title of the album being played.The title of the album.
{track_name}The title of the track being played.The title of the track.
{season_num}The season number for the media item if item is episode.The season number for the item if item is episode.
{season_num00}
{episode_num}The episode number for the media item if item is episode.The episode number for the item if item is episode.
{episode_num00} The two digit episode number.
{track_num}The track number for the item if item is track.
{track_num00}The two digit track number.
{year}The release year for the media item.The release year for the item.
{studio}The studio for the media item.The studio for the item.
{content_rating}The content rating for the media item. (e.g. TV-MA, TV-PG, etc.)The content rating for the item. (e.g. TV-MA, TV-PG, etc.)
{directors}A list of directors for the media item.A list of directors for the item.
{writers}A list of writers for the media item.A list of writers for the item.
{actors}A list of actors for the media item.A list of actors for the item.
{genres}A list of genres for the media item.A list of genres for the item.
{summary}A short plot summary for the media item.A short plot summary for the item.
{tagline}
{parent_rating_key}The unique identifier for the item parent (season or album).The unique identifier for the item's parent (season or album).
{grandparent_rating_key}The unique identifier for the item grandparent (TV show or artist).The unique identifier for the item's grandparent (TV show or artist).
diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index cea0b601..2e400ca8 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -519,10 +519,10 @@ def build_notify_text(session=None, timeline=None, state=None): available_params = {'server_name': server_name, 'server_uptime': server_uptime, - 'streams': stream_count, 'action': state, 'datestamp': arrow.now().format(plexpy.CONFIG.DATE_FORMAT.replace('Do','').replace('zz','')), 'timestamp': arrow.now().format(plexpy.CONFIG.TIME_FORMAT.replace('Do','').replace('zz','')), + 'streams': stream_count, 'user': user, 'platform': platform, 'player': player, @@ -563,6 +563,8 @@ def build_notify_text(session=None, timeline=None, state=None): 'season_num00': metadata['parent_media_index'].zfill(2), 'episode_num': metadata['media_index'].zfill(1), 'episode_num00': metadata['media_index'].zfill(2), + 'track_num': metadata['media_index'].zfill(1), + 'track_num00': metadata['media_index'].zfill(2), 'year': metadata['year'], 'studio': metadata['studio'], 'content_rating': metadata['content_rating'], From afc265a1882aea4b193a0c1519b0a09ad022f08f Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Fri, 29 Jan 2016 21:26:27 -0800 Subject: [PATCH 13/14] Fix schedulers not starting with library update --- plexpy/__init__.py | 2 +- plexpy/libraries.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 1bc46e8c..6827df72 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -282,7 +282,7 @@ def initialize_scheduler(): else: seconds = 0 - if CONFIG.PMS_IP and CONFIG.PMS_TOKEN and CONFIG.UPDATE_SECTION_IDS != -1: + if CONFIG.PMS_IP and CONFIG.PMS_TOKEN: schedule_job(plextv.get_real_pms_url, 'Refresh Plex Server URLs', hours=12, minutes=0, seconds=0) schedule_job(pmsconnect.get_server_friendly_name, 'Refresh Plex Server Name', diff --git a/plexpy/libraries.py b/plexpy/libraries.py index ca60e11c..b764077b 100644 --- a/plexpy/libraries.py +++ b/plexpy/libraries.py @@ -42,7 +42,7 @@ def update_section_ids(): logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_section_ids: %s." % e) logger.warn(u"PlexPy Libraries :: Unable to update section_id's in database.") - plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 1) + plexpy.CONFIG.UPDATE_SECTION_IDS = 1 plexpy.CONFIG.write() #logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.") @@ -50,7 +50,7 @@ def update_section_ids(): return None if not history_results: - plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0) + plexpy.CONFIG.UPDATE_SECTION_IDS = 0 plexpy.CONFIG.write() return None @@ -105,7 +105,7 @@ def update_section_ids(): else: logger.info(u"PlexPy Libraries :: Updated all section_id's in database.") - plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0) + plexpy.CONFIG.UPDATE_SECTION_IDS = 0 plexpy.CONFIG.write() #logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.") From fb7ad9438e8883eb34044e873b26833c3b7cdd4d Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Fri, 29 Jan 2016 21:31:25 -0800 Subject: [PATCH 14/14] v1.3.4 --- CHANGELOG.md | 15 +++++++++++++++ plexpy/version.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d5e5552..7d928908 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## v1.3.4 (2016-01-29) + +* Fix: Activity checker not starting with library update (history not logging). +* Fix: Libraries duplicated in database. +* Fix: Buffer notifications even when disabled when using websockets. +* Fix: Libraries and Users lists not refreshing. +* Fix: Server verification in settings. +* Fix: Empty libraries not added to database. +* Add: Unique identifier to notification options. +* Remove: Media type toggles for recently added notifications. +* Remove: Built in Twitter key and secret. +* Remove: Unnecessary quoting of script arguments. +* Change: Facebook notification instructions. + + ## v1.3.3 (2016-01-26) * Fix: Plays by Month graph not loading. diff --git a/plexpy/version.py b/plexpy/version.py index 9dd70962..74c338e8 100644 --- a/plexpy/version.py +++ b/plexpy/version.py @@ -1,2 +1,2 @@ PLEXPY_VERSION = "master" -PLEXPY_RELEASE_VERSION = "1.3.3" +PLEXPY_RELEASE_VERSION = "1.3.4"