diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f58c273..8d5e5552 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## v1.3.3 (2016-01-26)
+
+* Fix: Plays by Month graph not loading.
+* Change: Disable caching for datatables.
+* Change: Improved updating library data in the database again.
+
+
+## v1.3.2 (2016-01-24)
+
+* Fix: 'datestamp' and 'timestamp' for server notifications.
+* Change: New method for updating library data in database.
+
+
## v1.3.1 (2016-01-23)
* Fix: Notifiers authorization popups for reverse proxies.
@@ -7,8 +20,8 @@
* Fix: Star rating overlapping text.
* Fix: Unable to startup when library refresh fails.
* Fix: Unable to parse 'datestamp' and 'timestamp' format.
-* Change: Rename "Last Watched" to "Last Played"
-* Change: More descriptive libraries updating message
+* Change: Rename "Last Watched" to "Last Played".
+* Change: More descriptive libraries updating message.
## v1.3.0 (2016-01-23)
diff --git a/data/interfaces/default/js/tables/history_table.js b/data/interfaces/default/js/tables/history_table.js
index 2f337189..2ecde57a 100644
--- a/data/interfaces/default/js/tables/history_table.js
+++ b/data/interfaces/default/js/tables/history_table.js
@@ -22,7 +22,7 @@ history_table_options = {
"emptyTable": "No data in table"
},
"pagingType": "bootstrap",
- "stateSave": true,
+ "stateSave": false,
"processing": false,
"serverSide": true,
"pageLength": 25,
diff --git a/data/interfaces/default/js/tables/libraries.js b/data/interfaces/default/js/tables/libraries.js
index 2fcb3346..377295ae 100644
--- a/data/interfaces/default/js/tables/libraries.js
+++ b/data/interfaces/default/js/tables/libraries.js
@@ -16,7 +16,7 @@ libraries_list_table_options = {
"pageLength": 10,
"order": [ 2, 'asc'],
"autoWidth": true,
- "stateSave": true,
+ "stateSave": false,
"pagingType": "bootstrap",
"columnDefs": [
{
diff --git a/data/interfaces/default/js/tables/logs.js b/data/interfaces/default/js/tables/logs.js
index b8a21d39..4d26d2cd 100644
--- a/data/interfaces/default/js/tables/logs.js
+++ b/data/interfaces/default/js/tables/logs.js
@@ -5,7 +5,7 @@ var log_table_options = {
"pagingType": "bootstrap",
"order": [ 0, 'desc'],
"pageLength": 50,
- "stateSave": true,
+ "stateSave": false,
"language": {
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
diff --git a/data/interfaces/default/js/tables/plex_logs.js b/data/interfaces/default/js/tables/plex_logs.js
index 8a1109ba..520eae42 100644
--- a/data/interfaces/default/js/tables/plex_logs.js
+++ b/data/interfaces/default/js/tables/plex_logs.js
@@ -5,7 +5,7 @@ var plex_log_table_options = {
"pagingType": "bootstrap",
"order": [ 0, 'desc'],
"pageLength": 50,
- "stateSave": true,
+ "stateSave": false,
"language": {
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
diff --git a/data/interfaces/default/js/tables/sync_table.js b/data/interfaces/default/js/tables/sync_table.js
index 94f4e289..a46c67d2 100644
--- a/data/interfaces/default/js/tables/sync_table.js
+++ b/data/interfaces/default/js/tables/sync_table.js
@@ -4,7 +4,7 @@ sync_table_options = {
"pagingType": "bootstrap",
"order": [ [ 0, 'desc'], [ 1, 'asc'], [2, 'asc'] ],
"pageLength": 25,
- "stateSave": true,
+ "stateSave": false,
"language": {
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
diff --git a/data/interfaces/default/js/tables/user_ips.js b/data/interfaces/default/js/tables/user_ips.js
index d025d7d6..16c3b9df 100644
--- a/data/interfaces/default/js/tables/user_ips.js
+++ b/data/interfaces/default/js/tables/user_ips.js
@@ -8,7 +8,7 @@ user_ip_table_options = {
"infoFiltered":"(filtered from _MAX_ total entries)",
"emptyTable": "No data in table",
},
- "stateSave": true,
+ "stateSave": false,
"pagingType": "bootstrap",
"processing": false,
"serverSide": true,
diff --git a/data/interfaces/default/js/tables/users.js b/data/interfaces/default/js/tables/users.js
index aeda3df1..f7147a17 100644
--- a/data/interfaces/default/js/tables/users.js
+++ b/data/interfaces/default/js/tables/users.js
@@ -16,7 +16,7 @@ users_list_table_options = {
"pageLength": 10,
"order": [ 2, 'asc'],
"autoWidth": true,
- "stateSave": true,
+ "stateSave": false,
"pagingType": "bootstrap",
"columnDefs": [
{
diff --git a/data/interfaces/default/libraries.html b/data/interfaces/default/libraries.html
index a2d1a7bb..1e99697c 100644
--- a/data/interfaces/default/libraries.html
+++ b/data/interfaces/default/libraries.html
@@ -15,7 +15,7 @@
PlexPy is updating library IDs in the database. This could take a few minutes to hours depending on the size of your database.
- You may leave this page and come back later. Note: All monitoring has been disabled while this update is in progress.
+ You may leave this page and come back later.
% endif
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/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()
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/graphs.py b/plexpy/graphs.py
index bcede4d5..e5d93720 100644
--- a/plexpy/graphs.py
+++ b/plexpy/graphs.py
@@ -14,9 +14,9 @@
# along with PlexPy. If not, see .
from plexpy import logger, database, helpers, common
+import plexpy
import datetime
-import locale
class Graphs(object):
@@ -321,7 +321,7 @@ class Graphs(object):
dt = datetime.datetime(*month_item[:6])
date_string = dt.strftime('%Y-%m')
- categories.append(dt.strftime('%b %Y').decode(locale.getlocale()[1]))
+ categories.append(dt.strftime('%b %Y').decode(plexpy.SYS_ENCODING, 'replace'))
series_1_value = 0
series_2_value = 0
series_3_value = 0
diff --git a/plexpy/libraries.py b/plexpy/libraries.py
index d61be644..61a2f621 100644
--- a/plexpy/libraries.py
+++ b/plexpy/libraries.py
@@ -18,25 +18,28 @@ import plexpy
def update_section_ids():
from plexpy import pmsconnect, activity_pinger
- import threading
+ #import threading
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)
- plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items',
- hours=0, minutes=0, seconds=0)
- plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response',
- hours=0, minutes=0, seconds=0)
+ #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)
+ #plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items',
+ # hours=0, minutes=0, seconds=0)
+ #plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response',
+ # hours=0, minutes=0, seconds=0)
monitor_db = database.MonitorDatabase()
try:
- query = 'SELECT id, rating_key FROM session_history_metadata WHERE section_id IS NULL'
- result = monitor_db.select(query=query)
+ query = 'SELECT id, rating_key, grandparent_rating_key, media_type ' \
+ 'FROM session_history_metadata WHERE section_id IS NULL'
+ history_results = monitor_db.select(query=query)
+ query = 'SELECT section_id, section_type FROM library_sections'
+ library_results = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_section_ids: %s." % e)
@@ -44,36 +47,52 @@ def update_section_ids():
plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 1)
plexpy.CONFIG.write()
- logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.")
- plexpy.initialize_scheduler()
+ #logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.")
+ #plexpy.initialize_scheduler()
return None
# 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)
- for handler in logger.logger.handlers:
- handler.addFilter(thread_filter)
+ #logger.debug(u"PlexPy Libraries :: Disabling logging in the current thread while update in progress.")
+ #thread_filter = logger.NoThreadFilter(threading.current_thread().name)
+ #for handler in logger.logger.handlers:
+ # handler.addFilter(thread_filter)
+
+ # Get rating_key: section_id mapping pairs
+ key_mappings = {}
pms_connect = pmsconnect.PmsConnect()
+ for library in library_results:
+ section_id = library['section_id']
+ section_type = library['section_type']
+
+ if section_type != 'photo':
+ library_children = pms_connect.get_library_children_details(section_id=section_id,
+ section_type=section_type)
+ if library_children:
+ children_list = library_children['childern_list']
+ key_mappings.update({child['rating_key']:child['section_id'] for child in children_list})
+ else:
+ logger.warn(u"PlexPy Libraries :: Unable to get a list of library items for section_id %s." % section_id)
error_keys = set()
- for item in result:
- id = item['id']
- rating_key = item['rating_key']
- metadata = pms_connect.get_metadata_details(rating_key=rating_key)
-
- if metadata:
- metadata = metadata['metadata']
- section_keys = {'id': id}
- section_values = {'section_id': metadata['section_id']}
- monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values)
+ for item in history_results:
+ rating_key = item['grandparent_rating_key'] if item['media_type'] != 'movie' else item['rating_key']
+ section_id = key_mappings.get(str(rating_key), None)
+
+ if section_id:
+ try:
+ section_keys = {'id': item['id']}
+ section_values = {'section_id': section_id}
+ monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values)
+ except:
+ error_keys.add(item['rating_key'])
else:
- error_keys.add(rating_key)
+ error_keys.add(item['rating_key'])
# Remove thread filter from the logger
- for handler in logger.logger.handlers:
- handler.removeFilter(thread_filter)
- logger.debug(u"PlexPy Libraries :: Re-enabling logging in the current thread.")
+ #for handler in logger.logger.handlers:
+ # handler.removeFilter(thread_filter)
+ #logger.debug(u"PlexPy Libraries :: Re-enabling logging in the current thread.")
if error_keys:
logger.info(u"PlexPy Libraries :: Updated all section_id's in database except for rating_keys: %s." %
@@ -84,8 +103,8 @@ def update_section_ids():
plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0)
plexpy.CONFIG.write()
- logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.")
- plexpy.initialize_scheduler()
+ #logger.debug(u"PlexPy Libraries :: Re-enabling monitoring.")
+ #plexpy.initialize_scheduler()
return True
diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py
index 8120f4e2..ece8ea5c 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():
@@ -462,6 +456,7 @@ def build_notify_text(session=None, timeline=None, state=None):
transcode_video_height = ''
transcode_audio_codec = ''
transcode_audio_channels = ''
+ user_id = ''
progress_time = ''
# Session values
@@ -485,7 +480,6 @@ def build_notify_text(session=None, timeline=None, state=None):
stream_duration = int((time.time() - helpers.cast_to_float(session['started'])) / 60)
view_offset = helpers.convert_milliseconds_to_minutes(session['view_offset'])
- progress_time = arrow.get(helpers.cast_to_int(session['view_offset'])/1000).format(plexpy.CONFIG.TIME_FORMAT.replace('zz','').replace('a','').replace('A','').replace('h',''))
user = session['friendly_name']
platform = session['platform']
player = session['player']
@@ -506,6 +500,8 @@ 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_time = arrow.get(helpers.cast_to_int(session['view_offset'])/1000).format(plexpy.CONFIG.TIME_FORMAT.replace('zz','').replace('a','').replace('A','').replace('h',''))
progress_percent = helpers.get_percent(view_offset, duration)
@@ -558,6 +554,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,
@@ -579,7 +576,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
@@ -798,8 +799,8 @@ def build_server_notify_text(state=None):
available_params = {'server_name': server_name,
'server_uptime': server_uptime,
'action': state,
- 'datestamp': time.strftime(helpers.parse_js_date(plexpy.CONFIG.DATE_FORMAT)),
- 'timestamp': time.strftime(helpers.parse_js_date(plexpy.CONFIG.TIME_FORMAT))}
+ 'datestamp': arrow.now().format(plexpy.CONFIG.DATE_FORMAT.replace('Do','').replace('zz','')),
+ 'timestamp': arrow.now().format(plexpy.CONFIG.TIME_FORMAT.replace('Do','').replace('zz',''))}
# Default text
subject_text = 'PlexPy (%s)' % server_name
diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py
index a23f8b58..1623cd8d 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'
}
]
@@ -1668,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'
}
]
@@ -2088,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',
diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py
index bcbd61db..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']}
@@ -72,10 +76,11 @@ def refresh_libraries():
plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', library_keys)
plexpy.CONFIG.write()
- if plexpy.CONFIG.UPDATE_SECTION_IDS == 1:
+ if plexpy.CONFIG.UPDATE_SECTION_IDS == 1 or plexpy.CONFIG.UPDATE_SECTION_IDS == -1:
from plexpy import libraries
import threading
+ # Start library section_id update on it's own thread
threading.Thread(target=libraries.update_section_ids).start()
logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.")
@@ -1588,9 +1593,9 @@ class PmsConnect(object):
sort_type = ''
if str(section_id).isdigit():
- library_data = self.get_library_list(section_id, list_type, count, sort_type, output_format='xml')
+ library_data = self.get_library_list(str(section_id), list_type, count, sort_type, output_format='xml')
elif str(rating_key).isdigit():
- library_data = self.get_children_list(rating_key, output_format='xml')
+ library_data = self.get_children_list(str(rating_key), output_format='xml')
else:
logger.warn(u"PlexPy Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.")
return []
diff --git a/plexpy/version.py b/plexpy/version.py
index 423b493f..9dd70962 100644
--- a/plexpy/version.py
+++ b/plexpy/version.py
@@ -1,2 +1,2 @@
PLEXPY_VERSION = "master"
-PLEXPY_RELEASE_VERSION = "1.3.1"
+PLEXPY_RELEASE_VERSION = "1.3.3"