Fix crash on user page if user no longer exists as friend.

Provide fallback images if we can't load the real one.
Some sync table improvements.
This commit is contained in:
Tim 2015-07-02 15:55:31 +02:00
parent aa700e2b63
commit 2aa833d127
6 changed files with 59 additions and 46 deletions

View file

@ -46,9 +46,9 @@ DOCUMENTATION :: END
<li>
<span>
<a href="info?rating_key=${a['rows'][0]['rating_key']}">
% if a['rows'][0]['grandparent_thumb'] != '':
% if a['rows'][0]['grandparent_thumb']:
<img class="home-platforms-instance-poster"
src="pms_image_proxy?img=${a['rows'][0]['grandparent_thumb']}&width=162&height=240">
src="pms_image_proxy?img=${a['rows'][0]['grandparent_thumb']}&width=162&height=240&fallback=poster">
% else:
<img class="home-platforms-instance-poster" src="interfaces/default/images/poster.png">
% endif
@ -75,7 +75,7 @@ DOCUMENTATION :: END
<a href="info?rating_key=${a['rows'][0]['rating_key']}">
% if a['rows'][0]['grandparent_thumb'] != '':
<img class="home-platforms-instance-poster"
src="pms_image_proxy?img=${a['rows'][0]['grandparent_thumb']}&width=162&height=240">
src="pms_image_proxy?img=${a['rows'][0]['grandparent_thumb']}&width=162&height=240&fallback=poster">
% else:
<img class="home-platforms-instance-poster" src="interfaces/default/images/poster.png">
% endif

View file

@ -9,12 +9,14 @@ sync_table_options = {
"pageLength": 25,
"stateSave": true,
"language": {
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
"emptyTable": "No synced items",
"info":"Showing _START_ to _END_ of _TOTAL_ lines",
"infoEmpty":"Showing 0 to 0 of 0 lines",
"infoFiltered":"(filtered from _MAX_ total lines)"},
"search":"Search: ",
"lengthMenu":"Show _MENU_ lines per page",
"emptyTable": "No synced items",
"info":"Showing _START_ to _END_ of _TOTAL_ lines",
"infoEmpty":"Showing 0 to 0 of 0 lines",
"infoFiltered":"(filtered from _MAX_ total lines)",
"loadingRecords":'<i class="fa fa-refresh fa-spin"></i> Loading items...</div>'
},
"columnDefs": [
{
"targets": [0],
@ -91,11 +93,10 @@ sync_table_options = {
},
{
"targets": [10],
"data": null,
"data": "item_downloaded_percent_complete",
"createdCell": function (td, cellData, rowData, row, col) {
if (rowData['item_count'] > 0 ) {
percent_complete = Math.round((rowData['item_downloaded_count']/rowData['item_count']*100),0);
$(td).html('<span class="badge">' + percent_complete + '%</span>');
$(td).html('<span class="badge">' + cellData + '%</span>');
} else {
$(td).html('<span class="badge">0%</span>');
}

View file

@ -25,10 +25,10 @@ import re
from plexpy import version
#Identify Our Application
# Identify Our Application
USER_AGENT = 'PlexPy/-' + version.PLEXPY_VERSION + ' (' + platform.system() + ' ' + platform.release() + ')'
### Notification Types
# Notification Types
NOTIFY_SNATCH = 1
NOTIFY_DOWNLOAD = 2
@ -36,13 +36,5 @@ notifyStrings = {}
notifyStrings[NOTIFY_SNATCH] = "Started Download"
notifyStrings[NOTIFY_DOWNLOAD] = "Download Finished"
### Release statuses
UNKNOWN = -1 # should never happen
UNAIRED = 1 # releases that haven't dropped yet
SNATCHED = 2 # qualified with quality
WANTED = 3 # releases we don't have but want to get
DOWNLOADED = 4 # qualified with quality
SKIPPED = 5 # releases we don't want
ARCHIVED = 6 # releases that you don't have locally (counts toward download completion stats)
IGNORED = 7 # releases that you don't want included in your download stats
SNATCHED_PROPER = 9 # qualified with quality
DEFAULT_USER_THUMB = "interfaces/default/images/gravatar-default-80x80.png"
DEFAULT_POSTER_THUMB = "interfaces/default/images/poster.png"

View file

@ -17,17 +17,9 @@ from plexpy import logger, helpers, plexwatch
from xml.dom import minidom
from httplib import HTTPSConnection
from urlparse import parse_qsl
from urllib import urlencode
import base64
import cherrypy
import urllib
import urllib2
import plexpy
import os.path
import subprocess
import json
class PlexTV(object):
@ -346,6 +338,8 @@ class PlexTV(object):
status_item_ready_count = self.get_xml_attr(status, 'itemsReadyCount')
status_item_successful_count = self.get_xml_attr(status, 'itemsSuccessfulCount')
status_total_size = self.get_xml_attr(status, 'totalSize')
status_item_download_percent_complete = helpers.get_percent(
status_item_downloaded_count, status_item_count)
for settings in item.getElementsByTagName('MediaSettings'):
settings_audio_boost = self.get_xml_attr(settings, 'audioBoost')
@ -376,6 +370,7 @@ class PlexTV(object):
"item_count": status_item_count,
"item_complete_count": status_item_complete_count,
"item_downloaded_count": status_item_downloaded_count,
"item_downloaded_percent_complete": status_item_download_percent_complete,
"music_bitrate": settings_music_bitrate,
"photo_quality": settings_photo_quality,
"video_quality": settings_video_quality,

View file

@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
from plexpy import logger, helpers, datatables, db
from plexpy import logger, helpers, datatables, db, common
from xml.dom import minidom
import sys
if sys.version_info < (2, 7):
@ -100,8 +100,8 @@ class PlexWatch(object):
rows = []
for item in users:
if not item['thumb']:
user_thumb = 'interfaces/default/images/gravatar-default-80x80.png'
if not item['thumb'] or item['thumb'] == '':
user_thumb = common.DEFAULT_USER_THUMB
else:
user_thumb = item['thumb']
@ -710,8 +710,8 @@ class PlexWatch(object):
return None
for item in result:
if not item['thumb']:
user_thumb = 'interfaces/default/images/gravatar-default-80x80.png'
if not item['thumb'] or item['thumb'] == '':
user_thumb = common.DEFAULT_USER_THUMB
else:
user_thumb = item[4]
@ -948,10 +948,20 @@ class PlexWatch(object):
def get_user_details(self, user=None, user_id=None):
try:
myDB = db.DBConnection()
t = self.get_history_table_name()
if user:
query = 'select user_id, username, friendly_name, email, thumb, ' \
'is_home_user, is_allow_sync, is_restricted FROM plexpy_users WHERE username = ? LIMIT 1'
result = myDB.select(query, args=[user])
query = 'SELECT user_id, username, friendly_name, email, ' \
'thumb, is_home_user, is_allow_sync, is_restricted ' \
'FROM plexpy_users ' \
'WHERE username = ? ' \
'UNION ALL ' \
'SELECT null, user, null, null, null, null, null, null ' \
'FROM %s ' \
'WHERE user = ? ' \
'GROUP BY user ' \
'LIMIT 1' % t
result = myDB.select(query, args=[user, user])
elif user_id:
query = 'select user_id, username, friendly_name, email, thumb, ' \
'is_home_user, is_allow_sync, is_restricted FROM plexpy_users WHERE user_id = ? LIMIT 1'
@ -962,12 +972,16 @@ class PlexWatch(object):
friendly_name = item['username']
else:
friendly_name = item['friendly_name']
if not item['thumb'] or item['thumb'] == '':
user_thumb = common.DEFAULT_USER_THUMB
else:
user_thumb = item['thumb']
user_details = {"user_id": item['user_id'],
"username": item['username'],
"friendly_name": friendly_name,
"email": item['email'],
"thumb": item['thumb'],
"thumb": user_thumb,
"is_home_user": item['is_home_user'],
"is_allow_sync": item['is_allow_sync'],
"is_restricted": item['is_restricted']

View file

@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
from plexpy import logger, notifiers, plextv, pmsconnect, plexwatch, db
from plexpy import logger, notifiers, plextv, pmsconnect, plexwatch, db, common
from plexpy.helpers import checked, radio
from mako.lookup import TemplateLookup
@ -50,6 +50,10 @@ def serve_template(templatename, **kwargs):
class WebInterface(object):
def __init__(self):
self.interface_dir = os.path.join(str(plexpy.PROG_DIR), 'data/')
@cherrypy.expose
def index(self):
raise cherrypy.HTTPRedirect("home")
@ -108,7 +112,6 @@ class WebInterface(object):
user_details = plex_watch.get_user_details(user)
except:
logger.warn("Unable to retrieve friendly name for user %s " % user)
friendly_name = user
return serve_template(templatename="user.html", title="User", data=user_details)
@ -532,7 +535,7 @@ class WebInterface(object):
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def pms_image_proxy(self, img='', width='0', height='0', **kwargs):
def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs):
if img != '':
try:
pms_connect = pmsconnect.PmsConnect()
@ -541,10 +544,18 @@ class WebInterface(object):
return result[1]
except:
logger.warn('Image proxy queried but errors occured.')
return 'No image'
if fallback == 'poster':
logger.info('Trying fallback image...')
try:
fallback_image = open(self.interface_dir + common.DEFAULT_POSTER_THUMB, 'rb')
cherrypy.response.headers['Content-type'] = 'image/png'
return fallback_image
except IOError, e:
logger.error('Unable to read fallback image. %s' % e)
return None
else:
logger.warn('Image proxy queried but no parameters received.')
return 'No image'
return None
@cherrypy.expose
def info(self, rating_key='', **kwargs):