Merge branch 'dev'

This commit is contained in:
JonnyWong16 2016-01-29 21:32:37 -08:00
commit cff6b44109
13 changed files with 219 additions and 134 deletions

View file

@ -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.

View file

@ -359,6 +359,10 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
</label>
<p class="help-block">Force PlexPy to connect to your Plex Server via SSL. Your server needs to have remote access enabled.</p>
</div>
<input type="hidden" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
<input type="checkbox" name="server_changed" id="server_changed" value="1" style="display:none">
<div class="padded-header">
<h3>Plex Logs</h3>
</div>
@ -374,8 +378,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<a href="https://support.plex.tv/hc/en-us/articles/200250417-Plex-Media-Server-Log-Files" target="_blank">Click here</a> for help. This is required if you enable IP logging (for PMS 0.9.12 and below). </p>
</div>
<input type="hidden" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
</div>
@ -1072,7 +1074,7 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<thead>
<tr>
<th>
Server Details
Global
</th>
</tr>
</thead>
@ -1085,6 +1087,18 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{server_uptime}</strong></td>
<td>The uptime (in days, hours, mins, secs) of your Plex Server.</td>
</tr>
<tr>
<td><strong>{action}</strong></td>
<td>The action that triggered the notification.</td>
</tr>
<tr>
<td><strong>{datestamp}</strong></td>
<td>The date the notification was triggered.</td>
</tr>
<tr>
<td><strong>{timestamp}</strong></td>
<td>The time the notification was triggered.</td>
</tr>
</tbody>
</table>
<table class="notification-params">
@ -1100,18 +1114,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{streams}</strong></td>
<td>The number of concurrent streams.</td>
</tr>
<tr>
<td><strong>{action}</strong></td>
<td>The action that triggered the notification.</td>
</tr>
<tr>
<td><strong>{datestamp}</strong></td>
<td>The date the notification was triggered.</td>
</tr>
<tr>
<td><strong>{timestamp}</strong></td>
<td>The time the notification was triggered.</td>
</tr>
<tr>
<td><strong>{user}</strong></td>
<td>The username of the person streaming.</td>
@ -1128,10 +1130,6 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{ip_address}</strong></td>
<td>The IP address of the device being used for playback. (PMS 0.9.14 and above)</td>
</tr>
<tr>
<td><strong>{media_type}</strong></td>
<td>The type of media being played (movie, episode, track).</td>
</tr>
<tr>
<td><strong>{stream_duration}</strong></td>
<td>The stream duration (in minutes) for the item.</td>
@ -1224,6 +1222,10 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{transcode_audio_channels}</strong></td>
<td>The audio channels of the transcoded media.</td>
</tr>
<tr>
<td><strong>{user_id}</strong></td>
<td>The unique identifier for the user.</td>
</tr>
</tbody>
</table>
<table class="notification-params">
@ -1235,37 +1237,41 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
</tr>
</thead>
<tbody>
<tr>
<td><strong>{media_type}</strong></td>
<td>The type of media (movie, episode, track).</td>
</tr>
<tr>
<td><strong>{title}</strong></td>
<td>The full title of the item being played.</td>
<td>The full title of the item.</td>
</tr>
<tr>
<td><strong>{library_name}</strong></td>
<td>The library title of the item being played.</td>
<td>The library title of the media item.</td>
</tr>
<tr>
<td><strong>{show_name}</strong></td>
<td>The title of the TV series being played.</td>
<td>The title of the TV series.</td>
</tr>
<tr>
<td><strong>{episode_name}</strong></td>
<td>The title of the episode being played.</td>
<td>The title of the episode.</td>
</tr>
<tr>
<td><strong>{artist_name}</strong></td>
<td>The name of the artist being played.</td>
<td>The name of the artistd.</td>
</tr>
<tr>
<td><strong>{album_name}</strong></td>
<td>The title of the album being played.</td>
<td>The title of the album.</td>
</tr>
<tr>
<td><strong>{track_name}</strong></td>
<td>The title of the track being played.</td>
<td>The title of the track.</td>
</tr>
<tr>
<td><strong>{season_num}</strong></td>
<td>The season number for the media item if item is episode.</td>
<td>The season number for the item if item is episode.</td>
</tr>
<tr>
<td><strong>{season_num00}</strong></td>
@ -1273,43 +1279,51 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
</tr>
<tr>
<td><strong>{episode_num}</strong></td>
<td>The episode number for the media item if item is episode.</td>
<td>The episode number for the item if item is episode.</td>
</tr>
<tr>
<td><strong>{episode_num00}</strong></td>
<td>The two digit episode number.</td>
</tr>
<tr>
<td><strong>{track_num}</strong></td>
<td>The track number for the item if item is track.</td>
</tr>
<tr>
<td><strong>{track_num00}</strong></td>
<td>The two digit track number.</td>
</tr>
<tr>
<td><strong>{year}</strong></td>
<td>The release year for the media item.</td>
<td>The release year for the item.</td>
</tr>
<tr>
<td><strong>{studio}</strong></td>
<td>The studio for the media item.</td>
<td>The studio for the item.</td>
</tr>
<tr>
<td><strong>{content_rating}</strong></td>
<td>The content rating for the media item. (e.g. TV-MA, TV-PG, etc.)</td>
<td>The content rating for the item. (e.g. TV-MA, TV-PG, etc.)</td>
</tr>
<tr>
<td><strong>{directors}</strong></td>
<td>A list of directors for the media item.</td>
<td>A list of directors for the item.</td>
</tr>
<tr>
<td><strong>{writers}</strong></td>
<td>A list of writers for the media item.</td>
<td>A list of writers for the item.</td>
</tr>
<tr>
<td><strong>{actors}</strong></td>
<td>A list of actors for the media item.</td>
<td>A list of actors for the item.</td>
</tr>
<tr>
<td><strong>{genres}</strong></td>
<td>A list of genres for the media item.</td>
<td>A list of genres for the item.</td>
</tr>
<tr>
<td><strong>{summary}</strong></td>
<td>A short plot summary for the media item.</td>
<td>A short plot summary for the item.</td>
</tr>
<tr>
<td><strong>{tagline}</strong></td>
@ -1323,6 +1337,22 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{duration}</strong></td>
<td>The duration (in minutes) for the item.</td>
</tr>
<tr>
<td><strong>{section_id}</strong></td>
<td>The unique identifier for the library.</td>
</tr>
<tr>
<td><strong>{rating_key}</strong></td>
<td>The unique identifier for the item.</td>
</tr>
<tr>
<td><strong>{parent_rating_key}</strong></td>
<td>The unique identifier for the item's parent (season or album).</td>
</tr>
<tr>
<td><strong>{grandparent_rating_key}</strong></td>
<td>The unique identifier for the item's grandparent (TV show or artist).</td>
</tr>
</tbody>
</table>
</div>
@ -1534,6 +1564,7 @@ $(document).ready(function() {
serverChanged = true;
$("#pms_identifier").val("");
$("#pms-verify-status").html("");
$("#server_changed").prop('checked', true);
verifyServer();
});

View file

@ -169,6 +169,7 @@ from plexpy import common
<input type="checkbox" name="launch_browser" id="launch_browser" value="1" ${config['launch_browser']}>
<input type="checkbox" name="refresh_users_on_startup" id="refresh_users_on_startup" value="1" ${config['refresh_users_on_startup']}>
<input type="checkbox" name="refresh_libraries_on_startup" id="refresh_libraries_on_startup" value="1" ${config['refresh_libraries_on_startup']}>
<input type="checkbox" name="server_changed" id="server_changed" value="1" checked>
<input type="checkbox" name="first_run_complete" id="first_run_complete" value="1" checked>
<input type="checkbox" name="check_github" id="check_github" value="1" checked>
<input type="text" name="home_stats_cards" id="home_stats_cards" value="first_run_wizard">

View file

@ -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
@ -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',
@ -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'

View file

@ -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()

View file

@ -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),

View file

@ -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)
@ -44,13 +42,20 @@ 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.")
#plexpy.initialize_scheduler()
return None
if not history_results:
plexpy.CONFIG.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)
@ -100,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.")
@ -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 ' \

View file

@ -211,12 +211,6 @@ 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
@ -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 = ''
# Session values
if session:
@ -504,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)
@ -523,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,
@ -555,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,
@ -566,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'],
@ -576,7 +575,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
@ -585,10 +588,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 = re.sub(params_to_quote, r'"\g<0>"', script_args_text)
if script_args_text:
try:
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
@ -804,10 +803,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 = re.sub(params_to_quote, r'"\g<0>"', script_args_text)
if script_args_text:
try:
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]

View file

@ -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 <strong>Request Authorization</strong> button below.<br>\
Step 2: Input the <strong>Authorization Key</strong> you received from Step 1 below.<br>\
Step 3: Click the <strong>Verify Key</strong> button below.',
'description': 'Step 1: Visit <a href="https://apps.twitter.com/" target="_blank"> \
Twitter Apps</a> to <strong>Create New App</strong>. A vaild "Website" is not required.<br>\
Step 2: Go to <strong>Keys and Access Tokens</strong> and click \
<strong>Create my access token</strong>.<br>\
Step 3: Fill in the <strong>Consumer Key</strong>, <strong>Consumer Secret</strong>, \
<strong>Access Token</strong>, and <strong>Access Token Secret</strong> 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 <a href="http://telegram.me/BotFather" target="_blank">@BotFather</a> 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 <a href="http://telegram.me/myidbot" target="_blank">@myidbot</a> on Telegram to get an ID.',
'description': 'Your Telegram Chat ID, Group ID, or @channelusername. Contact <a href="http://telegram.me/myidbot" target="_blank">@myidbot</a> on Telegram to get an ID.',
'input_type': 'text'
}
]
@ -2088,12 +2097,16 @@ class FacebookNotifier(object):
config_option = [{'label': 'Instructions',
'description': '<strong>Facebook notifications are currently experimental!</strong><br><br> \
Step 1: Visit <a href="https://developers.facebook.com/apps/" target="_blank"> \
Facebook Developers</a> to create a new app using <strong>advanced setup</strong>.<br>\
Step 2: Go to <strong>Settings > Advanced</strong> and fill in \
Facebook Developers</a> to add a new app using <strong>basic setup</strong>.<br>\
Step 2: Go to <strong>Settings > Basic</strong> and fill in a \
<strong>Contact Email</strong>.<br>\
Step 3: Go to <strong>Settings > Advanced</strong> and fill in \
<strong>Valid OAuth redirect URIs</strong> with your PlexPy URL (i.e. http://localhost:8181).<br>\
Step 3: Fill in the <strong>PlexPy URL</strong> below with the exact same URL from Step 2.<br>\
Step 4: Fill in the <strong>App ID</strong> and <strong>App Secret</strong> below.<br>\
Step 5: Click the <strong>Request Authorization</strong> button below.',
Step 4: Go to <strong>App Review</strong> and toggle public to <strong>Yes</strong>.<br>\
Step 5: Fill in the <strong>PlexPy URL</strong> below with the exact same URL from Step 3.<br>\
Step 6: Fill in the <strong>App ID</strong> and <strong>App Secret</strong> below.<br>\
Step 7: Click the <strong>Request Authorization</strong> button below.<br> \
Step 8: Fill in the <strong>Group ID</strong> below.',
'input_type': 'help'
},
{'label': 'PlexPy URL',

View file

@ -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']}
@ -1690,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'],

View file

@ -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 ' \

View file

@ -1,2 +1,2 @@
PLEXPY_VERSION = "master"
PLEXPY_RELEASE_VERSION = "1.3.3"
PLEXPY_RELEASE_VERSION = "1.3.4"

View file

@ -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,15 +1194,23 @@ 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.
if server_changed:
plextv.get_real_pms_url()
# Get new server friendly name.
if server_changed:
pmsconnect.get_server_friendly_name()
# Reconfigure scheduler if intervals changed
@ -1378,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)