mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-10 15:32:38 -07:00
Add option in settings to enable BIF indexes.
This commit is contained in:
parent
d2c65e6a65
commit
7bf45f8bef
6 changed files with 249 additions and 13 deletions
|
@ -183,6 +183,13 @@
|
||||||
<input type="checkbox" id="grouping_global_history" name="grouping_global_history" value="1" ${config['grouping_global_history']}> Enable Grouping
|
<input type="checkbox" id="grouping_global_history" name="grouping_global_history" value="1" ${config['grouping_global_history']}> Enable Grouping
|
||||||
<p class="help-block">Show grouped history data. <a target="_blank" href="https://github.com/ljunkie/plexWatch#list-watched-shows-option---nogrouping-vs-default">More info.</a></p>
|
<p class="help-block">Show grouped history data. <a target="_blank" href="https://github.com/ljunkie/plexWatch#list-watched-shows-option---nogrouping-vs-default">More info.</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="wellheader">
|
||||||
|
<h3>Extra Settings</h3>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="pms_use_bif" name="pms_use_bif" value="1" ${config['pms_use_bif']}> Use BIF thumbs
|
||||||
|
<p class="help-block">If you have media indexing enabled on your server, use these on the activity pane.</p>
|
||||||
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<input type="checkbox" id="grouping_user_history" name="grouping_user_history" value="1" ${config['grouping_user_history']}> User History
|
<input type="checkbox" id="grouping_user_history" name="grouping_user_history" value="1" ${config['grouping_user_history']}> User History
|
||||||
|
|
|
@ -41,6 +41,7 @@ videoDecision Returns the video transcode decision. Either 'transcode'
|
||||||
videoCodec Returns the name of the video codec.
|
videoCodec Returns the name of the video codec.
|
||||||
height Returns the value of the video height.
|
height Returns the value of the video height.
|
||||||
width Returns the value of the video width.
|
width Returns the value of the video width.
|
||||||
|
indexes Returns true if the media has media indexes and are enabled
|
||||||
|
|
||||||
DOCUMENTATION :: END
|
DOCUMENTATION :: END
|
||||||
</%doc>
|
</%doc>
|
||||||
|
@ -50,16 +51,17 @@ DOCUMENTATION :: END
|
||||||
% for a in data['sessions']:
|
% for a in data['sessions']:
|
||||||
<div class="instance" id="instance-${a['sessionKey']}">
|
<div class="instance" id="instance-${a['sessionKey']}">
|
||||||
<div class="poster">
|
<div class="poster">
|
||||||
% if a['type'] == 'track-to-do':
|
% if a['type'] == 'movie' and not a['indexes']:
|
||||||
<div class="art-music-face"
|
|
||||||
style="background-image:url(pms_image_proxy?img=${a['thumb']}&width=300&height=300)"></div>
|
|
||||||
% elif a['type'] == 'movie':
|
|
||||||
<div class="dashboard-activity-poster-face">
|
<div class="dashboard-activity-poster-face">
|
||||||
<img src="pms_image_proxy?img=${a['art']}&width=300&height=169"/> <!-- media artwork -->
|
<img src="pms_image_proxy?img=${a['art']}&width=300&height=169"/>
|
||||||
|
</div>
|
||||||
|
% elif a['indexes']:
|
||||||
|
<div class="dashboard-activity-poster-face">
|
||||||
|
<img onload="fadeIn(this)" src="pms_image_proxy?img=${a['thumb']}&width=300&height=169" style="display: none;"/>
|
||||||
</div>
|
</div>
|
||||||
% else:
|
% else:
|
||||||
<div class="dashboard-activity-poster-face">
|
<div class="dashboard-activity-poster-face">
|
||||||
<img src="pms_image_proxy?img=${a['thumb']}&width=300&height=169"/> <!-- media artwork -->
|
<img src="pms_image_proxy?img=${a['thumb']}&width=300&height=169"/>
|
||||||
</div>
|
</div>
|
||||||
% endif
|
% endif
|
||||||
<div class='dashboard-activity-metadata-wrapper'>
|
<div class='dashboard-activity-metadata-wrapper'>
|
||||||
|
@ -140,6 +142,11 @@ DOCUMENTATION :: END
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
% endfor
|
% endfor
|
||||||
|
<script>
|
||||||
|
function fadeIn(obj) {
|
||||||
|
$(obj).fadeIn(450);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
% else:
|
% else:
|
||||||
<div class="muted">Nothing is currently being watched.</div><br>
|
<div class="muted">Nothing is currently being watched.</div><br>
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -27,6 +27,7 @@ _CONFIG_DEFINITIONS = {
|
||||||
'PMS_PASSWORD': (str, 'PMS', ''),
|
'PMS_PASSWORD': (str, 'PMS', ''),
|
||||||
'PMS_TOKEN': (str, 'PMS', ''),
|
'PMS_TOKEN': (str, 'PMS', ''),
|
||||||
'PMS_USERNAME': (str, 'PMS', ''),
|
'PMS_USERNAME': (str, 'PMS', ''),
|
||||||
|
'PMS_USE_BIF': (int, 'PMS', 0),
|
||||||
'TIME_FORMAT': (str, 'General', 'HH:mm'),
|
'TIME_FORMAT': (str, 'General', 'HH:mm'),
|
||||||
'API_ENABLED': (int, 'General', 0),
|
'API_ENABLED': (int, 'General', 0),
|
||||||
'API_KEY': (str, 'General', ''),
|
'API_KEY': (str, 'General', ''),
|
||||||
|
|
107
plexpy/plextv.py
107
plexpy/plextv.py
|
@ -39,10 +39,11 @@ class PlexTV(object):
|
||||||
def __init__(self, username='', password=''):
|
def __init__(self, username='', password=''):
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
|
self.url = 'plex.tv'
|
||||||
|
|
||||||
def get_plex_auth(self):
|
def get_plex_auth(self):
|
||||||
|
|
||||||
http_handler = HTTPSConnection("plex.tv")
|
http_handler = HTTPSConnection(self.url)
|
||||||
base64string = base64.encodestring('%s:%s' % (self.username, self.password)).replace('\n', '')
|
base64string = base64.encodestring('%s:%s' % (self.username, self.password)).replace('\n', '')
|
||||||
|
|
||||||
http_handler.request("POST",
|
http_handler.request("POST",
|
||||||
|
@ -110,3 +111,107 @@ class PlexTV(object):
|
||||||
return user_data
|
return user_data
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_plextv_friends(self, output_format=''):
|
||||||
|
url_command = '/api/users'
|
||||||
|
http_handler = HTTPSConnection(self.url, timeout=10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
http_handler.request("GET", url_command + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN)
|
||||||
|
response = http_handler.getresponse()
|
||||||
|
request_status = response.status
|
||||||
|
request_content = response.read()
|
||||||
|
except IOError, e:
|
||||||
|
logger.warn(u"Failed to access friends list. %s" % e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if request_status == 200:
|
||||||
|
if output_format == 'dict':
|
||||||
|
output = helpers.convert_xml_to_dict(request_content)
|
||||||
|
elif output_format == 'json':
|
||||||
|
output = helpers.convert_xml_to_json(request_content)
|
||||||
|
else:
|
||||||
|
output = request_content
|
||||||
|
else:
|
||||||
|
logger.warn(u"Failed to access friends list. Status code %r" % request_status)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_plextv_user_details(self, output_format=''):
|
||||||
|
url_command = '/users/account'
|
||||||
|
http_handler = HTTPSConnection(self.url, timeout=10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
http_handler.request("GET", url_command + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN)
|
||||||
|
response = http_handler.getresponse()
|
||||||
|
request_status = response.status
|
||||||
|
request_content = response.read()
|
||||||
|
except IOError, e:
|
||||||
|
logger.warn(u"Failed to access user details. %s" % e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if request_status == 200:
|
||||||
|
if output_format == 'dict':
|
||||||
|
output = helpers.convert_xml_to_dict(request_content)
|
||||||
|
elif output_format == 'json':
|
||||||
|
output = helpers.convert_xml_to_json(request_content)
|
||||||
|
else:
|
||||||
|
output = request_content
|
||||||
|
else:
|
||||||
|
logger.warn(u"Failed to access user details. Status code %r" % request_status)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_plextv_server_list(self, output_format=''):
|
||||||
|
url_command = '/pms/servers.xml'
|
||||||
|
http_handler = HTTPSConnection(self.url, timeout=10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
http_handler.request("GET", url_command + '?includeLite=1&X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN)
|
||||||
|
response = http_handler.getresponse()
|
||||||
|
request_status = response.status
|
||||||
|
request_content = response.read()
|
||||||
|
except IOError, e:
|
||||||
|
logger.warn(u"Failed to access server list. %s" % e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if request_status == 200:
|
||||||
|
if output_format == 'dict':
|
||||||
|
output = helpers.convert_xml_to_dict(request_content)
|
||||||
|
elif output_format == 'json':
|
||||||
|
output = helpers.convert_xml_to_json(request_content)
|
||||||
|
else:
|
||||||
|
output = request_content
|
||||||
|
else:
|
||||||
|
logger.warn(u"Failed to access server list. Status code %r" % request_status)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_plextv_sync_lists(self, machine_id='', output_format=''):
|
||||||
|
url_command = '/servers/' + machine_id + '/sync_lists'
|
||||||
|
http_handler = HTTPSConnection(self.url, timeout=10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
http_handler.request("GET", url_command + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN)
|
||||||
|
response = http_handler.getresponse()
|
||||||
|
request_status = response.status
|
||||||
|
request_content = response.read()
|
||||||
|
except IOError, e:
|
||||||
|
logger.warn(u"Failed to access server list. %s" % e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if request_status == 200:
|
||||||
|
if output_format == 'dict':
|
||||||
|
output = helpers.convert_xml_to_dict(request_content)
|
||||||
|
elif output_format == 'json':
|
||||||
|
output = helpers.convert_xml_to_json(request_content)
|
||||||
|
else:
|
||||||
|
output = request_content
|
||||||
|
else:
|
||||||
|
logger.warn(u"Failed to access server list. Status code %r" % request_status)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return output
|
|
@ -179,6 +179,39 @@ class PmsConnect(object):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
"""
|
||||||
|
Return list of local servers.
|
||||||
|
|
||||||
|
Optional parameters: output_format { dict, json }
|
||||||
|
|
||||||
|
Output: array
|
||||||
|
"""
|
||||||
|
def get_server_list(self, output_format=''):
|
||||||
|
url_command = '/servers'
|
||||||
|
http_handler = HTTPConnection(self.host, self.port, timeout=10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
http_handler.request("GET", url_command + '?X-Plex-Token=' + self.token)
|
||||||
|
response = http_handler.getresponse()
|
||||||
|
request_status = response.status
|
||||||
|
request_content = response.read()
|
||||||
|
except IOError, e:
|
||||||
|
logger.warn(u"Failed to access metadata. %s" % e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if request_status == 200:
|
||||||
|
if output_format == 'dict':
|
||||||
|
output = helpers.convert_xml_to_dict(request_content)
|
||||||
|
elif output_format == 'json':
|
||||||
|
output = helpers.convert_xml_to_json(request_content)
|
||||||
|
else:
|
||||||
|
output = request_content
|
||||||
|
else:
|
||||||
|
logger.warn(u"Failed to access metadata. Status code %r" % request_status)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Return processed and validated list of recently added items.
|
Return processed and validated list of recently added items.
|
||||||
|
|
||||||
|
@ -522,10 +555,29 @@ class PmsConnect(object):
|
||||||
duration = self.get_xml_attr(media_info, 'duration')
|
duration = self.get_xml_attr(media_info, 'duration')
|
||||||
progress = self.get_xml_attr(session, 'viewOffset')
|
progress = self.get_xml_attr(session, 'viewOffset')
|
||||||
|
|
||||||
|
media_info = session.getElementsByTagName('Media')[0]
|
||||||
|
if media_info.getElementsByTagName('Part'):
|
||||||
|
indexes = self.get_xml_attr(media_info.getElementsByTagName('Part')[0], 'indexes')
|
||||||
|
part_id = self.get_xml_attr(media_info.getElementsByTagName('Part')[0], 'id')
|
||||||
|
if indexes == 'sd':
|
||||||
|
bif_thumb = '/library/parts/' + part_id + '/indexes/sd/' + progress
|
||||||
|
else:
|
||||||
|
bif_thumb = ''
|
||||||
|
else:
|
||||||
|
indexes = ''
|
||||||
|
bif_thumb = ''
|
||||||
|
|
||||||
|
if plexpy.CONFIG.PMS_USE_BIF and indexes == 'sd':
|
||||||
|
thumb = bif_thumb
|
||||||
|
use_indexes = 1
|
||||||
|
else:
|
||||||
|
thumb = self.get_xml_attr(session, 'thumb')
|
||||||
|
use_indexes = 0
|
||||||
|
|
||||||
if self.get_xml_attr(session, 'type') == 'episode':
|
if self.get_xml_attr(session, 'type') == 'episode':
|
||||||
session_output = {'sessionKey': self.get_xml_attr(session, 'sessionKey'),
|
session_output = {'sessionKey': self.get_xml_attr(session, 'sessionKey'),
|
||||||
'art': self.get_xml_attr(session, 'art'),
|
'art': self.get_xml_attr(session, 'art'),
|
||||||
'thumb': self.get_xml_attr(session, 'thumb'),
|
'thumb': thumb,
|
||||||
'user': self.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
|
'user': self.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
|
||||||
'player': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
|
'player': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
|
||||||
'state': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
|
'state': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
|
||||||
|
@ -542,12 +594,13 @@ class PmsConnect(object):
|
||||||
'duration': duration,
|
'duration': duration,
|
||||||
'progress': progress,
|
'progress': progress,
|
||||||
'progressPercent': str(helpers.get_percent(progress, duration)),
|
'progressPercent': str(helpers.get_percent(progress, duration)),
|
||||||
'type': self.get_xml_attr(session, 'type')
|
'type': self.get_xml_attr(session, 'type'),
|
||||||
|
'indexes': use_indexes
|
||||||
}
|
}
|
||||||
elif self.get_xml_attr(session, 'type') == 'movie':
|
elif self.get_xml_attr(session, 'type') == 'movie':
|
||||||
session_output = {'sessionKey': self.get_xml_attr(session, 'sessionKey'),
|
session_output = {'sessionKey': self.get_xml_attr(session, 'sessionKey'),
|
||||||
'art': self.get_xml_attr(session, 'art'),
|
'art': self.get_xml_attr(session, 'art'),
|
||||||
'thumb': self.get_xml_attr(session, 'thumb'),
|
'thumb': thumb,
|
||||||
'user': self.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
|
'user': self.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
|
||||||
'player': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
|
'player': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
|
||||||
'state': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
|
'state': self.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
|
||||||
|
@ -563,7 +616,8 @@ class PmsConnect(object):
|
||||||
'duration': duration,
|
'duration': duration,
|
||||||
'progress': progress,
|
'progress': progress,
|
||||||
'progressPercent': str(helpers.get_percent(progress, duration)),
|
'progressPercent': str(helpers.get_percent(progress, duration)),
|
||||||
'type': self.get_xml_attr(session, 'type')
|
'type': self.get_xml_attr(session, 'type'),
|
||||||
|
'indexes': use_indexes
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
logger.warn(u"No known stream types found in session list.")
|
logger.warn(u"No known stream types found in session list.")
|
||||||
|
@ -636,6 +690,7 @@ class PmsConnect(object):
|
||||||
image_path = '/photo/:/transcode?url=http://127.0.0.1:32400' + img + '&width=' + width + '&height=' + height
|
image_path = '/photo/:/transcode?url=http://127.0.0.1:32400' + img + '&width=' + width + '&height=' + height
|
||||||
else:
|
else:
|
||||||
image_path = '/photo/:/transcode?url=http://127.0.0.1:32400' + img
|
image_path = '/photo/:/transcode?url=http://127.0.0.1:32400' + img
|
||||||
|
|
||||||
http_handler.request("GET", image_path + '&X-Plex-Token=' + self.token)
|
http_handler.request("GET", image_path + '&X-Plex-Token=' + self.token)
|
||||||
response = http_handler.getresponse()
|
response = http_handler.getresponse()
|
||||||
request_status = response.status
|
request_status = response.status
|
||||||
|
|
|
@ -273,6 +273,7 @@ class WebInterface(object):
|
||||||
"pms_ip": plexpy.CONFIG.PMS_IP,
|
"pms_ip": plexpy.CONFIG.PMS_IP,
|
||||||
"pms_port": plexpy.CONFIG.PMS_PORT,
|
"pms_port": plexpy.CONFIG.PMS_PORT,
|
||||||
"pms_token": plexpy.CONFIG.PMS_TOKEN,
|
"pms_token": plexpy.CONFIG.PMS_TOKEN,
|
||||||
|
"pms_use_bif": checked(plexpy.CONFIG.PMS_USE_BIF),
|
||||||
"plexwatch_database": plexpy.CONFIG.PLEXWATCH_DATABASE,
|
"plexwatch_database": plexpy.CONFIG.PLEXWATCH_DATABASE,
|
||||||
"date_format": plexpy.CONFIG.DATE_FORMAT,
|
"date_format": plexpy.CONFIG.DATE_FORMAT,
|
||||||
"time_format": plexpy.CONFIG.TIME_FORMAT,
|
"time_format": plexpy.CONFIG.TIME_FORMAT,
|
||||||
|
@ -294,7 +295,7 @@ class WebInterface(object):
|
||||||
"synoindex_enabled", "pushover_enabled", "pushbullet_enabled",
|
"synoindex_enabled", "pushover_enabled", "pushbullet_enabled",
|
||||||
"subsonic_enabled", "twitter_enabled", "osx_notify_enabled",
|
"subsonic_enabled", "twitter_enabled", "osx_notify_enabled",
|
||||||
"boxcar_enabled", "mpc_enabled", "email_enabled", "email_tls",
|
"boxcar_enabled", "mpc_enabled", "email_enabled", "email_tls",
|
||||||
"grouping_global_history", "grouping_user_history", "grouping_charts"
|
"grouping_global_history", "grouping_user_history", "grouping_charts", "pms_use_bif"
|
||||||
]
|
]
|
||||||
for checked_config in checked_configs:
|
for checked_config in checked_configs:
|
||||||
if checked_config not in kwargs:
|
if checked_config not in kwargs:
|
||||||
|
@ -733,3 +734,63 @@ class WebInterface(object):
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
else:
|
else:
|
||||||
logger.warn('Unable to retrieve data.')
|
logger.warn('Unable to retrieve data.')
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
def get_friends_list(self, **kwargs):
|
||||||
|
|
||||||
|
plex_tv = plextv.PlexTV()
|
||||||
|
result = plex_tv.get_plextv_friends('json')
|
||||||
|
|
||||||
|
if result:
|
||||||
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
logger.warn('Unable to retrieve data.')
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
def get_user_details(self, **kwargs):
|
||||||
|
|
||||||
|
plex_tv = plextv.PlexTV()
|
||||||
|
result = plex_tv.get_plextv_user_details('json')
|
||||||
|
|
||||||
|
if result:
|
||||||
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
logger.warn('Unable to retrieve data.')
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
def get_server_list(self, **kwargs):
|
||||||
|
|
||||||
|
plex_tv = plextv.PlexTV()
|
||||||
|
result = plex_tv.get_plextv_server_list('json')
|
||||||
|
|
||||||
|
if result:
|
||||||
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
logger.warn('Unable to retrieve data.')
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
def get_sync_lists(self, machine_id='', **kwargs):
|
||||||
|
|
||||||
|
plex_tv = plextv.PlexTV()
|
||||||
|
result = plex_tv.get_plextv_sync_lists(machine_id=machine_id, output_format='json')
|
||||||
|
|
||||||
|
if result:
|
||||||
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
logger.warn('Unable to retrieve data.')
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
def get_servers(self, **kwargs):
|
||||||
|
|
||||||
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
|
result = pms_connect.get_server_list(output_format='json')
|
||||||
|
|
||||||
|
if result:
|
||||||
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
logger.warn('Unable to retrieve data.')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue