From f9f478e10014cc22433b9fc5f232f56e2a586bf5 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sat, 20 Feb 2016 20:47:33 -0800 Subject: [PATCH 01/17] Update CONTRIBUTING.md with info about issue reporting and feature requests --- CONTRIBUTING.md | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 146b1cfe..96536260 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,10 +3,41 @@ ## Issues In case you read this because you are posting an issue, please take a minute and conside the things below. The issue tracker is not a support forum. It is primarily intended to submit bugs, improvements or feature requests. However, we are glad to help you, and make sure the problem is not caused by PlexPy, but don't expect step-by-step answers. -* Use the search function. Chances are that your problem is already discussed. Do not append to (closed) issues if your problem does not fit the discussion. -* Visit the [Troubleshooting](../../wiki/TroubleShooting) wiki first. -* Use [proper formatting](https://help.github.com/articles/github-flavored-markdown/). Paste your logs in code blocks. -* Close your issue if you resolved it. +##### Many issues can simply be solved by: + +- Making sure you update to the latest version. +- Turning your device off and on again. +- Analyzing your logs, you just might find the solution yourself! +- Using the **search** function to see if this issue has already been reported/solved. +- Checking the [Wiki](https://github.com/drzoidberg33/plexpy/wiki) for +[ [Installation] ](https://github.com/drzoidberg33/plexpy/wiki/Installation) and +[ [FAQs] ](https://github.com/drzoidberg33/plexpy/wiki/Frequently-Asked-Questions-(FAQ)). +- For basic questions try asking on [Gitter](https://gitter.im/drzoidberg33/plexpy) or the [Plex Forums](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program) first before opening an issue. + +##### If nothing has worked: + +1. Open a new issue on the GitHub [issue tracker](http://github.com/drzoidberg33/plexpy/issues). +2. Provide a clear title to easily help identify your problem. +3. Use proper [markdown syntax](https://help.github.com/articles/github-flavored-markdown) to structure your post (i.e. code/log in code blocks). +4. Make sure you provide the following information: + - [ ] Branch + - [ ] Version/Commit hash + - [ ] Your operating system and python version + - [ ] What you did? + - [ ] What happened? + - [ ] What you expected? + - [ ] How can we reproduce your issue? + - [ ] What are your (relevant) settings? + - [ ] Include a link to your **FULL** (not just a few lines!) log file that has the error. Please use [Gist](http://gist.github.com) or [Pastebin](http://pastebin.com/). +5. Close your issue when it's solved! If you found the solution yourself please comment so that others benefit from it. + +## Feature Requests + +1. Search for similar existing 'issues', feature requests can be recognized by the blue `enhancement` label. +2. If a similar request exists, post a comment (+1, or add a new idea to the existing request). +3. If no similar requests exist, you can create a new one. +4. Provide a clear title to easily identify the feature request. +5. Tag your feature request with `[Feature Request]` so it can be identified easily. ## Pull Requests If you think you can contribute code to the PlexPy repository, do not hesitate to submit a pull request. From ca29333cd06acd5ed1ebdc859801ff685e7f79d4 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sat, 20 Feb 2016 20:50:20 -0800 Subject: [PATCH 02/17] Log if opening secure websocket --- plexpy/web_socket.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plexpy/web_socket.py b/plexpy/web_socket.py index 0d4fc88a..2de97dcf 100644 --- a/plexpy/web_socket.py +++ b/plexpy/web_socket.py @@ -39,11 +39,13 @@ def run(): if plexpy.CONFIG.PMS_SSL and plexpy.CONFIG.PMS_URL[:5] == 'https': uri = plexpy.CONFIG.PMS_URL.replace('https://', 'wss://') + '/:/websockets/notifications' + secure = ' secure' else: uri = 'ws://%s:%s/:/websockets/notifications' % ( plexpy.CONFIG.PMS_IP, plexpy.CONFIG.PMS_PORT ) + secure = '' # Set authentication token (if one is available) if plexpy.CONFIG.PMS_TOKEN: @@ -55,7 +57,7 @@ def run(): # Try an open the websocket connection - if it fails after 15 retries fallback to polling while not ws_connected and reconnects <= 15: try: - logger.info(u'PlexPy WebSocket :: Opening websocket, connection attempt %s.' % str(reconnects + 1)) + logger.info(u'PlexPy WebSocket :: Opening%s websocket, connection attempt %s.' % (secure, str(reconnects + 1))) ws = create_connection(uri) reconnects = 0 ws_connected = True From bc42e79bb5432edef69cf32c9baf9b1e3a75defc Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sun, 21 Feb 2016 09:33:31 -0800 Subject: [PATCH 03/17] Catch HTTP errors for Imgur upload --- plexpy/helpers.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/plexpy/helpers.py b/plexpy/helpers.py index 710449b8..10d34f7c 100644 --- a/plexpy/helpers.py +++ b/plexpy/helpers.py @@ -546,16 +546,19 @@ def uploadToImgur(imgPath, imgTitle=''): data['title'] = imgTitle data['name'] = imgTitle + '.jpg' - request = urllib2.Request('https://api.imgur.com/3/image', headers=headers, data=urllib.urlencode(data)) - response = urllib2.urlopen(request) - response = json.loads(response.read()) + try: + request = urllib2.Request('https://api.imgur.com/3/image', headers=headers, data=urllib.urlencode(data)) + response = urllib2.urlopen(request) + response = json.loads(response.read()) - if response.get('status') == 200: - logger.debug(u"PlexPy Helpers :: Image uploaded to Imgur.") - img_url = response.get('data').get('link', '') - elif response.get('status') >= 400 and response.get('status') < 500: - logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % response.reason) - else: - logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur.") + if response.get('status') == 200: + logger.debug(u"PlexPy Helpers :: Image uploaded to Imgur.") + img_url = response.get('data').get('link', '') + elif response.get('status') >= 400 and response.get('status') < 500: + logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % response.reason) + else: + logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur.") + except urllib2.HTTPError as e: + logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % e) return img_url \ No newline at end of file From f663fac2202f822e831304141db65003c5fc13dd Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sun, 21 Feb 2016 09:34:51 -0800 Subject: [PATCH 04/17] Save Imgur URL to database --- plexpy/__init__.py | 11 ++- plexpy/datafactory.py | 17 ++++ plexpy/notification_handler.py | 149 ++++++++++++++++++--------------- 3 files changed, 107 insertions(+), 70 deletions(-) diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 6e9753f5..e179d914 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -446,7 +446,7 @@ def dbcheck(): 'CREATE TABLE IF NOT EXISTS notify_log (id INTEGER PRIMARY KEY AUTOINCREMENT, ' 'session_key INTEGER, rating_key INTEGER, user_id INTEGER, user TEXT, ' 'agent_id INTEGER, agent_name TEXT, on_play INTEGER, on_stop INTEGER, on_watched INTEGER, ' - 'on_pause INTEGER, on_resume INTEGER, on_buffer INTEGER, on_created INTEGER)' + 'on_pause INTEGER, on_resume INTEGER, on_buffer INTEGER, on_created INTEGER, poster_url TEXT)' ) # library_sections table :: This table keeps record of the servers library sections @@ -724,6 +724,15 @@ def dbcheck(): 'ALTER TABLE notify_log ADD COLUMN on_created INTEGER' ) + # Upgrade session_history_metadata table from earlier versions + try: + c_db.execute('SELECT poster_url FROM notify_log') + except sqlite3.OperationalError: + logger.debug(u"Altering database. Updating database table notify_log.") + c_db.execute( + 'ALTER TABLE notify_log ADD COLUMN poster_url TEXT' + ) + # Upgrade library_sections table from earlier versions (remove UNIQUE constraint on section_id) try: result = c_db.execute('SELECT SQL FROM sqlite_master WHERE type="table" AND name="library_sections"').fetchone() diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index edbeed16..ae78646c 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -856,6 +856,23 @@ class DataFactory(object): return ip_address + def get_poster_url(self, rating_key=''): + monitor_db = database.MonitorDatabase() + + if rating_key: + query = 'SELECT id, poster_url FROM notify_log WHERE rating_key = %d ' \ + 'ORDER BY id DESC LIMIT 1' % int(rating_key) + result = monitor_db.select(query) + else: + return None + + poster_url = '' + + for item in result: + poster_url = item['poster_url'] + + return poster_url + def get_search_query(self, rating_key=''): monitor_db = database.MonitorDatabase() diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index fe782f68..925c30c5 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -20,7 +20,7 @@ import re import time import urllib -from plexpy import logger, config, notifiers, database, helpers, plextv, pmsconnect +from plexpy import logger, config, notifiers, database, helpers, plextv, pmsconnect, datafactory import plexpy @@ -50,66 +50,66 @@ def notify(stream_data=None, notify_action=None): for agent in notifiers.available_notification_agents(): if agent['on_play'] and notify_action == 'play': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_stop'] and notify_action == 'stop' \ and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < plexpy.CONFIG.NOTIFY_WATCHED_PERCENT): # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_pause'] and notify_action == 'pause' \ and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99): # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_resume'] and notify_action == 'resume' \ and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99): # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_buffer'] and notify_action == 'buffer': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, - script_args=notify_strings[2]) + script_args=metadata) - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_watched'] and notify_action == 'watched': # Get the current states for notifications from our db @@ -118,100 +118,100 @@ def notify(stream_data=None, notify_action=None): # If there is nothing in the notify_log for our agent id but it is enabled we should notify if not any(d['agent_id'] == agent['id'] for d in notify_states): # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) else: # Check in our notify log if the notification has already been sent for notify_state in notify_states: if not notify_state['on_watched'] and (notify_state['agent_id'] == agent['id']): # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif (stream_data['media_type'] == 'track' and plexpy.CONFIG.MUSIC_NOTIFY_ENABLE): for agent in notifiers.available_notification_agents(): if agent['on_play'] and notify_action == 'play': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_stop'] and notify_action == 'stop': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_pause'] and notify_action == 'pause': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_resume'] and notify_action == 'resume': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif agent['on_buffer'] and notify_action == 'buffer': # Build and send notification - notify_strings = build_notify_text(session=stream_data, state=notify_action) + notify_strings, metadata = build_notify_text(session=stream_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=stream_data, state=notify_action, agent_info=agent) + set_notify_state(session=stream_data, state=notify_action, agent_info=agent, metadata=metadata) elif stream_data['media_type'] == 'clip': pass @@ -227,15 +227,15 @@ def notify_timeline(timeline_data=None, notify_action=None): 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) + notify_strings, metadata = build_notify_text(timeline=timeline_data, state=notify_action) notifiers.send_notification(agent_id=agent['id'], subject=notify_strings[0], body=notify_strings[1], notify_action=notify_action, script_args=notify_strings[2], - metadata=notify_strings[3]) + metadata=metadata) # Set the notification state in the db - set_notify_state(session=timeline_data, state=notify_action, agent_info=agent) + set_notify_state(session=timeline_data, state=notify_action, agent_info=agent, metadata=metadata) elif not timeline_data and notify_action: for agent in notifiers.available_notification_agents(): @@ -314,39 +314,42 @@ def get_notify_state_timeline(timeline): return notify_states -def set_notify_state(session, state, agent_info): +def set_notify_state(session, state, agent_info, metadata): if session and state and agent_info: monitor_db = database.MonitorDatabase() + notify_time = int(time.time()) if state == 'play': - values = {'on_play': int(time.time())} + values = {'on_play': notify_time} elif state == 'stop': - values = {'on_stop': int(time.time())} + values = {'on_stop': notify_time} elif state == 'pause': - values = {'on_pause': int(time.time())} + values = {'on_pause': notify_time} elif state == 'resume': - values = {'on_resume': int(time.time())} + values = {'on_resume': notify_time} elif state == 'buffer': - values = {'on_buffer': int(time.time())} + values = {'on_buffer': notify_time} elif state == 'watched': - values = {'on_watched': int(time.time())} + values = {'on_watched': notify_time} elif state == 'created': - values = {'on_created': int(time.time())} + values = {'on_created': notify_time} else: return if state == 'created': keys = {'rating_key': session['rating_key'], 'agent_id': agent_info['id'], - 'agent_name': agent_info['name']} + 'agent_name': agent_info['name'], + 'poster_url': metadata.get('poster_url', None)} else: keys = {'session_key': session['session_key'], 'rating_key': session['rating_key'], 'user_id': session['user_id'], 'user': session['user'], 'agent_id': agent_info['id'], - 'agent_name': agent_info['name']} + 'agent_name': agent_info['name'], + 'poster_url': metadata.get('poster_url', None)} monitor_db.upsert(table_name='notify_log', key_dict=keys, value_dict=values) else: @@ -512,11 +515,19 @@ def build_notify_text(session=None, timeline=None, state=None): thumb = None if thumb: - # Retrieve the poster from Plex and cache to file - urllib.urlretrieve(plexpy.CONFIG.PMS_URL + thumb + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN, - os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg')) - # Upload thumb to Imgur and get link - metadata['poster_url'] = helpers.uploadToImgur(os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg'), full_title) + # Try to retrieve a poster_url from the database + data_factory = datafactory.DataFactory() + poster_url = data_factory.get_poster_url(rating_key=rating_key) + + # If no previous poster_url + if not poster_url: + # Retrieve the poster from Plex and cache to file + urllib.urlretrieve(plexpy.CONFIG.PMS_URL + thumb + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN, + os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg')) + # Upload thumb to Imgur and get link + poster_url = helpers.uploadToImgur(os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg'), full_title) + + metadata['poster_url'] = poster_url # Fix metadata params for notify recently added grandparent if state == 'created' and plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT: @@ -649,9 +660,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata elif state == 'stop': # Default body text body_text = '%s (%s) has stopped %s' % (session['friendly_name'], @@ -673,9 +684,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata elif state == 'pause': # Default body text body_text = '%s (%s) has paused %s' % (session['friendly_name'], @@ -697,9 +708,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata elif state == 'resume': # Default body text body_text = '%s (%s) has resumed %s' % (session['friendly_name'], @@ -721,9 +732,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata elif state == 'buffer': # Default body text body_text = '%s (%s) is buffering %s' % (session['friendly_name'], @@ -745,9 +756,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata elif state == 'watched': # Default body text body_text = '%s (%s) has watched %s' % (session['friendly_name'], @@ -769,9 +780,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata elif state == 'created': # Default body text body_text = '%s was recently added to Plex.' % full_title @@ -791,9 +802,9 @@ def build_notify_text(session=None, timeline=None, state=None): except: logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body. Using fallback.") - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: - return [subject_text, body_text, script_args, metadata] + return [subject_text, body_text, script_args], metadata else: return None From b669f3d71566ca3391680c5995a72b6f1ed27e67 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sun, 21 Feb 2016 09:58:27 -0800 Subject: [PATCH 05/17] Fix regression unable to clear the http password --- plexpy/webserve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plexpy/webserve.py b/plexpy/webserve.py index bb4a78e7..885d9688 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -1245,7 +1245,7 @@ class WebInterface(object): # If http password exists in config, do not overwrite when blank value received if kwargs.get('http_password'): - if kwargs['http_password'].strip() == '' and plexpy.CONFIG.HTTP_PASSWORD != '': + if kwargs['http_password'] == ' ' and plexpy.CONFIG.HTTP_PASSWORD != '': kwargs['http_password'] = plexpy.CONFIG.HTTP_PASSWORD for plain_config, use_config in [(x[4:], x) for x in kwargs if x.startswith('use_')]: From 3c6a6cdc5b94f461d59a463c7912734606295999 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sun, 21 Feb 2016 14:56:19 -0800 Subject: [PATCH 06/17] Fix wording on settings page --- data/interfaces/default/settings.html | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 36b82fb4..55035a3f 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -571,10 +571,9 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
-

Enable if you want PlexPy to calculate the total file size for TV Shows/Seasons and Artists/Albums on the media info tables.
- This is currently experimental.

+

Enable if you want PlexPy to calculate the total file size for TV Shows/Seasons and Artists/Albums on the media info tables.

@@ -610,10 +609,9 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
-

Instead of polling the server at regular intervals let the server tell us when something happens.
- This is currently experimental.

+

Instead of polling the server at regular intervals let the server tell PlexPy when something happens.