@@ -359,9 +359,29 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
+
+
+
+
+
+ Refresh Libraries List on Startup
+
+
Refresh the libraries list when PlexPy starts.
diff --git a/plexpy/__init__.py b/plexpy/__init__.py
index 681d2565..703aaaaf 100644
--- a/plexpy/__init__.py
+++ b/plexpy/__init__.py
@@ -175,6 +175,10 @@ def initialize(config_file):
if CONFIG.PMS_TOKEN and CONFIG.REFRESH_USERS_ON_STARTUP:
plextv.refresh_users()
+ # Refresh the libraries list on startup
+ if CONFIG.PMS_TOKEN and CONFIG.REFRESH_LIBRARIES_ON_STARTUP:
+ pmsconnect.refresh_libraries()
+
# Store the original umask
UMASK = os.umask(0)
os.umask(UMASK)
@@ -311,8 +315,14 @@ def initialize_scheduler():
else:
hours = 0
+
if CONFIG.PMS_TOKEN:
- schedule_job(plextv.refresh_users, 'Refresh users list', hours=hours, minutes=0, seconds=0)
+ schedule_job(plextv.refresh_users, 'Refresh users list',
+ hours=hours, minutes=0, seconds=0)
+
+ if CONFIG.PMS_IP and CONFIG.PMS_TOKEN:
+ schedule_job(pmsconnect.refresh_libraries, 'Refresh libraries list',
+ hours=hours, minutes=0, seconds=0)
# Start scheduler
if start_jobs and len(SCHED.get_jobs()):
@@ -431,7 +441,9 @@ def dbcheck():
# library_sections table :: This table keeps record of the servers library sections
c_db.execute(
'CREATE TABLE IF NOT EXISTS library_sections (id INTEGER PRIMARY KEY AUTOINCREMENT, '
- 'section_id INTEGER UNIQUE, section_name TEXT, section_type TEXT)'
+ 'server_id TEXT, section_id INTEGER UNIQUE, section_name TEXT, section_type TEXT, thumb TEXT, '
+ 'count INTEGER, parent_count INTEGER, child_count INTEGER, '
+ 'do_notify INTEGER DEFAULT 1, keep_history INTEGER DEFAULT 1)'
)
# Upgrade sessions table from earlier versions
diff --git a/plexpy/config.py b/plexpy/config.py
index ac33003c..0c5a9a3f 100644
--- a/plexpy/config.py
+++ b/plexpy/config.py
@@ -293,6 +293,8 @@ _CONFIG_DEFINITIONS = {
'PUSHOVER_ON_INTDOWN': (int, 'Pushover', 0),
'PUSHOVER_ON_EXTUP': (int, 'Pushover', 0),
'PUSHOVER_ON_INTUP': (int, 'Pushover', 0),
+ 'REFRESH_LIBRARIES_INTERVAL': (int, 'Monitoring', 12),
+ 'REFRESH_LIBRARIES_ON_STARTUP': (int, 'Monitoring', 1),
'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12),
'REFRESH_USERS_ON_STARTUP': (int, 'Monitoring', 1),
'SLACK_ENABLED': (int, 'Slack', 0),
diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py
index c83e6fbb..d334d1c1 100644
--- a/plexpy/datafactory.py
+++ b/plexpy/datafactory.py
@@ -654,6 +654,35 @@ class DataFactory(object):
return home_stats
+ def get_library_stats(self, library_cards=''):
+ monitor_db = database.MonitorDatabase()
+
+ library_stats = []
+
+ for id in library_cards:
+ if id.isdigit():
+ try:
+ query = 'SELECT section_id, section_name, section_type, thumb, count, parent_count, child_count ' \
+ 'FROM library_sections ' \
+ 'WHERE section_id = %s' % id
+ result = monitor_db.select(query)
+ except:
+ logger.warn("Unable to execute database query for get_library_stats.")
+ return None
+
+ for item in result:
+ library = {'section_id': item['section_id'],
+ 'section_name': item['section_name'],
+ 'section_type': item['section_type'],
+ 'thumb': item['thumb'],
+ 'count': item['count'],
+ 'parent_count': item['parent_count'],
+ 'child_count': item['child_count']
+ }
+ library_stats.append(library)
+
+ return library_stats
+
def get_stream_details(self, row_id=None):
monitor_db = database.MonitorDatabase()
diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py
index d88ecf53..d59d09e1 100644
--- a/plexpy/pmsconnect.py
+++ b/plexpy/pmsconnect.py
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see
.
-from plexpy import logger, helpers, users, http_handler, common
+from plexpy import logger, helpers, users, http_handler, common, database
from urlparse import urlparse
import plexpy
@@ -37,6 +37,42 @@ def get_server_friendly_name():
return server_name
+def refresh_libraries():
+ logger.info("Requesting libraries list refresh...")
+ library_sections = PmsConnect().get_library_details()
+
+ server_id = plexpy.CONFIG.PMS_IDENTIFIER
+
+ if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']:
+ populate_cards = True
+ else:
+ populate_cards = False
+
+ cards = []
+
+ if library_sections:
+ monitor_db = database.MonitorDatabase()
+
+ for section in library_sections:
+ section_keys = {'server_id': server_id,
+ 'section_id': section['key']}
+ section_values = {'server_id': server_id,
+ 'section_id': section['key'],
+ 'section_name': section['title'],
+ 'section_type': section['type'],
+ 'thumb': section['thumb'],
+ 'count': section['count'],
+ 'parent_count': section.get('parent_count', None),
+ 'child_count': section.get('child_count', None)
+ }
+
+ monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values)
+
+ logger.info("Libraries list refreshed.")
+ else:
+ logger.warn("Unable to refresh libraries list.")
+
+
class PmsConnect(object):
"""
Retrieve data from Plex Server
@@ -1446,10 +1482,22 @@ class PmsConnect(object):
sort_type = '&type=1'
elif library_type == 'show':
sort_type = '&type=2'
+ elif library_type == 'season':
+ sort_type = '&type=3'
elif library_type == 'episode':
sort_type = '&type=4'
+ elif library_type == 'artist':
+ sort_type = '&type=8'
elif library_type == 'album':
- list_type = 'albums'
+ sort_type = '&type=9'
+ elif library_type == 'track':
+ sort_type = '&type=10'
+ elif library_type == 'photo':
+ sort_type = ''
+ elif library_type == 'photoAlbum':
+ sort_type = '&type=14'
+ elif library_type == 'picture':
+ sort_type = '&type=13'
library_data = self.get_library_list(section_key, list_type, count, sort_type, output_format='xml')
@@ -1492,7 +1540,7 @@ class PmsConnect(object):
Output: array
"""
- def get_library_stats(self, library_cards=''):
+ def get_library_details(self):
server_libraries = self.get_server_children()
server_library_stats = []
@@ -1503,35 +1551,57 @@ class PmsConnect(object):
for library in libraries_list:
library_type = library['type']
section_key = library['key']
- if section_key in library_cards:
- library_list = self.get_library_children(library_type, section_key)
- else:
- continue
+ library_list = self.get_library_children(library_type, section_key)
if library_list['library_count'] != '0':
library_stats = {'key': library['key'],
'title': library['title'],
+ 'type': library_type,
'thumb': library['thumb'],
'count': library_list['library_count'],
'count_type': library_list['count_type']
}
if library_type == 'show':
- episode_list = self.get_library_children(library_type='episode', section_key=section_key)
- episode_stats = {'episode_count': episode_list['library_count'],
- 'episode_count_type': 'All Episodes'
- }
- library_stats.update(episode_stats)
+ parent_list = self.get_library_children(library_type='season', section_key=section_key)
+ parent_stats = {'parent_count': parent_list['library_count'],
+ 'parent_count_type': 'All Seasons'
+ }
+ library_stats.update(parent_stats)
+
+ child_list = self.get_library_children(library_type='episode', section_key=section_key)
+ child_stats = {'child_count': child_list['library_count'],
+ 'child_count_type': 'All Episodes'
+ }
+ library_stats.update(child_stats)
if library_type == 'artist':
- album_list = self.get_library_children(library_type='album', section_key=section_key)
- album_stats = {'album_count': album_list['library_count'],
- 'album_count_type': 'All Albums'
- }
- library_stats.update(album_stats)
+ parent_list = self.get_library_children(library_type='album', section_key=section_key)
+ parent_stats = {'parent_count': parent_list['library_count'],
+ 'parent_count_type': 'All Seasons'
+ }
+ library_stats.update(parent_stats)
- server_library_stats.append({'type': library_type,
- 'rows': library_stats})
+ child_list = self.get_library_children(library_type='track', section_key=section_key)
+ child_stats = {'child_count': child_list['library_count'],
+ 'child_count_type': 'All Albums'
+ }
+ library_stats.update(child_stats)
+
+ if library_type == 'photo':
+ parent_list = self.get_library_children(library_type='photoAlbum', section_key=section_key)
+ parent_stats = {'parent_count': parent_list['library_count'],
+ 'parent_count_type': 'All Photo Albums'
+ }
+ library_stats.update(parent_stats)
+
+ child_list = self.get_library_children(library_type='picture', section_key=section_key)
+ child_stats = {'child_count': child_list['library_count'],
+ 'child_count_type': 'All Photos'
+ }
+ library_stats.update(child_stats)
+
+ server_library_stats.append(library_stats)
return server_library_stats
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index 28fe3219..8f8ab162 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -80,6 +80,7 @@ class WebInterface(object):
config = {
"launch_browser": checked(plexpy.CONFIG.LAUNCH_BROWSER),
"refresh_users_on_startup": checked(plexpy.CONFIG.REFRESH_USERS_ON_STARTUP),
+ "refresh_librareis_on_startup": checked(plexpy.CONFIG.REFRESH_LIBRARIES_ON_STARTUP),
"pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER,
"pms_ip": plexpy.CONFIG.PMS_IP,
"pms_is_remote": checked(plexpy.CONFIG.PMS_IS_REMOTE),
@@ -146,23 +147,12 @@ class WebInterface(object):
@cherrypy.expose
def library_stats(self, **kwargs):
- pms_connect = pmsconnect.PmsConnect()
+ data_factory = datafactory.DataFactory()
library_cards = plexpy.CONFIG.HOME_LIBRARY_CARDS.split(', ')
- if library_cards == ['library_statistics_first']:
- library_cards = ['library_statistics']
- server_children = pms_connect.get_server_children()
- server_libraries = server_children['libraries_list']
-
- for library in server_libraries:
- library_cards.append(library['key'])
-
- plexpy.CONFIG.HOME_LIBRARY_CARDS = ', '.join(library_cards)
- plexpy.CONFIG.write()
-
- stats_data = pms_connect.get_library_stats(library_cards=library_cards)
-
+ stats_data = data_factory.get_library_stats(library_cards=library_cards)
+
return serve_template(templatename="library_stats.html", title="Library Stats", data=stats_data)
@cherrypy.expose
@@ -445,6 +435,8 @@ class WebInterface(object):
"monitor_remote_access": checked(plexpy.CONFIG.MONITOR_REMOTE_ACCESS),
"monitoring_interval": plexpy.CONFIG.MONITORING_INTERVAL,
"monitoring_use_websocket": checked(plexpy.CONFIG.MONITORING_USE_WEBSOCKET),
+ "refresh_libraries_interval": plexpy.CONFIG.REFRESH_LIBRARIES_INTERVAL,
+ "refresh_libraries_on_startup": checked(plexpy.CONFIG.REFRESH_LIBRARIES_ON_STARTUP),
"refresh_users_interval": plexpy.CONFIG.REFRESH_USERS_INTERVAL,
"refresh_users_on_startup": checked(plexpy.CONFIG.REFRESH_USERS_ON_STARTUP),
"ip_logging_enable": checked(plexpy.CONFIG.IP_LOGGING_ENABLE),
@@ -503,9 +495,10 @@ class WebInterface(object):
"movie_notify_enable", "tv_notify_enable", "music_notify_enable", "monitoring_use_websocket",
"tv_notify_on_start", "movie_notify_on_start", "music_notify_on_start",
"tv_notify_on_stop", "movie_notify_on_stop", "music_notify_on_stop",
- "tv_notify_on_pause", "movie_notify_on_pause", "music_notify_on_pause", "refresh_users_on_startup",
- "ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable",
- "pms_is_remote", "home_stats_type", "group_history_tables", "notify_consecutive",
+ "tv_notify_on_pause", "movie_notify_on_pause", "music_notify_on_pause",
+ "refresh_libraries_on_startup", "refresh_users_on_startup",
+ "ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable",
+ "pms_is_remote", "home_stats_type", "group_history_tables", "notify_consecutive",
"notify_recently_added", "notify_recently_added_grandparent", "monitor_remote_access"
]
for checked_config in checked_configs:
@@ -524,9 +517,15 @@ class WebInterface(object):
del kwargs[use_config]
# Check if we should refresh our data
+ refresh_libraries = False
refresh_users = False
reschedule = False
+ if 'monitoring_interval' in kwargs and 'refresh_libraries_interval' in kwargs:
+ if (kwargs['monitoring_interval'] != str(plexpy.CONFIG.MONITORING_INTERVAL)) or \
+ (kwargs['refresh_libraries_interval'] != str(plexpy.CONFIG.REFRESH_LIBRARIES_INTERVAL)):
+ reschedule = True
+
if 'monitoring_interval' in kwargs and 'refresh_users_interval' in kwargs:
if (kwargs['monitoring_interval'] != str(plexpy.CONFIG.MONITORING_INTERVAL)) or \
(kwargs['refresh_users_interval'] != str(plexpy.CONFIG.REFRESH_USERS_INTERVAL)):
@@ -542,6 +541,7 @@ class WebInterface(object):
if 'pms_ip' in kwargs:
if kwargs['pms_ip'] != plexpy.CONFIG.PMS_IP:
+ refresh_libraries = True
refresh_users = True
if 'home_stats_cards' in kwargs:
@@ -567,6 +567,10 @@ class WebInterface(object):
if reschedule:
plexpy.initialize_scheduler()
+ # Refresh users table if our server IP changes.
+ if refresh_libraries:
+ threading.Thread(target=pmsconnect.refresh_libraries).start()
+
# Refresh users table if our server IP changes.
if refresh_users:
threading.Thread(target=plextv.refresh_users).start()
@@ -1310,10 +1314,15 @@ class WebInterface(object):
else:
logger.warn('Unable to retrieve data.')
+ @cherrypy.expose
+ def refresh_libraries_list(self, **kwargs):
+ threading.Thread(target=pmsconnect.refresh_libraries).start()
+ logger.info('Manual libraries list refresh requested.')
+
@cherrypy.expose
def refresh_users_list(self, **kwargs):
threading.Thread(target=plextv.refresh_users).start()
- logger.info('Manual user list refresh requested.')
+ logger.info('Manual users list refresh requested.')
@cherrypy.expose
def get_sync(self, machine_id=None, user_id=None, **kwargs):