Fix bug with xml and unicode conversion.

Fix some minor front-end issues.
Initial work on new users table.
This commit is contained in:
Tim 2015-07-01 19:51:42 +02:00
parent 12331e1c4c
commit 2d822c8468
8 changed files with 256 additions and 18 deletions

View file

@ -23,7 +23,7 @@ from plexpy import helpers
<div class="span9"><h2><i class="fa fa-book"></i> Logs</h2></div>
<div class="span3">
<div class="pull-right">
<h5><a id="menu_link_edit" href="clearLogs"><i class="fa fa-trash-o"></i> Clear log</a>
<h5><a id="menu_link_edit" href="clearLogs"><i class="fa fa-trash-o"></i> Clear log</a></h5>
</div>
</div>
</div>

View file

@ -14,7 +14,12 @@ from plexpy import helpers
<div class="span12">
<div class="wellheader-bg">
<div class="dashboard-wellheader-no-chevron">
<h2><i class="fa fa-group"></i> Users</h2>
<div class="span9"><h2><i class="fa fa-group"></i> Users</h2></div>
<div class="span3">
<div class="pull-right">
<h5><a href="refresh_users_list"><i class="fa fa-refresh"></i> Refresh users</a></h5>
</div>
</div>
</div>
</div>
</div>

View file

@ -307,8 +307,35 @@ def sig_handler(signum=None, frame=None):
def dbcheck():
conn = sqlite3.connect(plexpy.CONFIG.PLEXWATCH_DATABASE)
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS plexpy_users (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'username TEXT NOT NULL UNIQUE, friendly_name TEXT)')
c.execute(
'CREATE TABLE IF NOT EXISTS plexpy_users (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'user_id INTEGER DEFAULT NULL UNIQUE, username TEXT NOT NULL UNIQUE, '
'friendly_name TEXT, thumb TEXT, email TEXT, is_home_user INTEGER DEFAULT NULL, '
'is_allow_sync INTEGER DEFAULT NULL, is_restricted INTEGER DEFAULT NULL)'
)
# Upgrade plexpy_users table from earlier versions
try:
c.execute('SELECT user_id from plexpy_users')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table plexpy_users.")
c.execute(
'CREATE TABLE tmp_table (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'user_id INTEGER DEFAULT NULL UNIQUE, username TEXT NOT NULL UNIQUE, '
'friendly_name TEXT, thumb TEXT, email TEXT, is_home_user INTEGER DEFAULT NULL, '
'is_allow_sync INTEGER DEFAULT NULL, is_restricted INTEGER DEFAULT NULL)'
)
c.execute(
'INSERT INTO tmp_table SELECT id, NULL, username, friendly_name, NULL, NULL, NULL, NULL, NULL '
'FROM plexpy_users'
)
c.execute(
'DROP TABLE plexpy_users'
)
c.execute(
'ALTER TABLE tmp_table RENAME TO plexpy_users'
)
conn.commit()
c.close()

View file

@ -81,11 +81,11 @@ def latinToAscii(unicrap):
0xfd: 'y', 0xfe: 'th', 0xff: 'y',
0xa1: '!', 0xa2: '{cent}', 0xa3: '{pound}', 0xa4: '{currency}',
0xa5: '{yen}', 0xa6: '|', 0xa7: '{section}', 0xa8: '{umlaut}',
0xa9: '{C}', 0xaa: '{^a}', 0xab: '<<', 0xac: '{not}',
0xa9: '{C}', 0xaa: '{^a}', 0xab: '&lt;&lt;', 0xac: '{not}',
0xad: '-', 0xae: '{R}', 0xaf: '_', 0xb0: '{degrees}',
0xb1: '{+/-}', 0xb2: '{^2}', 0xb3: '{^3}', 0xb4: "'",
0xb5: '{micro}', 0xb6: '{paragraph}', 0xb7: '*', 0xb8: '{cedilla}',
0xb9: '{^1}', 0xba: '{^o}', 0xbb: '>>',
0xb9: '{^1}', 0xba: '{^o}', 0xbb: '&gt;&gt;',
0xbc: '{1/4}', 0xbd: '{1/2}', 0xbe: '{3/4}', 0xbf: '?',
0xd7: '*', 0xf7: '/'
}

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, common, request
from plexpy import logger, helpers
from xml.dom import minidom
from httplib import HTTPSConnection
@ -214,3 +214,72 @@ class PlexTV(object):
return None
return output
"""
Validate xml keys to make sure they exist and return their attribute value, return blank value is none found
"""
@staticmethod
def get_xml_attr(xml_key, attribute, return_bool=False, default_return=''):
if xml_key.getAttribute(attribute):
if return_bool:
return True
else:
return xml_key.getAttribute(attribute)
else:
if return_bool:
return False
else:
return default_return
def get_full_users_list(self):
friends_list = self.get_plextv_friends()
own_account = self.get_plextv_user_details()
users_list = []
try:
xml_parse = minidom.parseString(own_account)
except Exception, e:
logger.warn("Error parsing XML for Plex account details: %s" % e)
except:
logger.warn("Error parsing XML for Plex account details.")
xml_head = xml_parse.getElementsByTagName('user')
if not xml_head:
logger.warn("Error parsing XML for Plex account details.")
else:
for a in xml_head:
own_details = {"user_id": self.get_xml_attr(a, 'id'),
"username": self.get_xml_attr(a, 'username'),
"thumb": self.get_xml_attr(a, 'thumb'),
"email": self.get_xml_attr(a, 'email'),
"is_home_user": self.get_xml_attr(a, 'home'),
"is_allow_sync": None,
"is_restricted": self.get_xml_attr(a, 'restricted')
}
users_list.append(own_details)
try:
xml_parse = minidom.parseString(friends_list)
except Exception, e:
logger.warn("Error parsing XML for Plex friends list: %s" % e)
except:
logger.warn("Error parsing XML for Plex friends list.")
xml_head = xml_parse.getElementsByTagName('User')
if not xml_head:
logger.warn("Error parsing XML for Plex friends list.")
else:
for a in xml_head:
friend = {"user_id": self.get_xml_attr(a, 'id'),
"username": self.get_xml_attr(a, 'title'),
"thumb": self.get_xml_attr(a, 'thumb'),
"email": self.get_xml_attr(a, 'email'),
"is_home_user": self.get_xml_attr(a, 'home'),
"is_allow_sync": self.get_xml_attr(a, 'allowSync'),
"is_restricted": self.get_xml_attr(a, 'restricted')
}
users_list.append(friend)
return users_list

View file

@ -72,7 +72,9 @@ class PlexWatch(object):
t + '.time',
t + '.ip_address',
'COUNT(' + t + '.title) as plays',
t + '.user']
t + '.user',
'plexpy_users.user_id as user_id',
'plexpy_users.thumb as thumb']
try:
query = data_tables.ssp_query(table_name=t,
columns=columns,
@ -98,14 +100,18 @@ class PlexWatch(object):
rows = []
for item in users:
thumb = self.get_user_gravatar_image(item['user'])
if not item['thumb']:
user_thumb = 'interfaces/default/images/gravatar-default-80x80.png'
else:
user_thumb = item['thumb']
row = {"plays": item['plays'],
"time": item['time'],
"friendly_name": item["friendly_name"],
"ip_address": item["ip_address"],
"thumb": thumb['user_thumb'],
"user": item["user"]
"thumb": user_thumb,
"user": item["user"],
"user_id": item['user_id']
}
rows.append(row)
@ -295,12 +301,12 @@ class PlexWatch(object):
try:
xml_parse = minidom.parseString(helpers.latinToAscii(item['xml']))
except IOError, e:
logger.warn("Error parsing XML in PlexWatch db: %s" % e)
except:
logger.warn("Error parsing XML in PlexWatch db")
xml_head = xml_parse.getElementsByTagName('opt')
if not xml_head:
logger.warn("Error parsing XML in PlexWatch db: %s" % e)
logger.warn("Error parsing XML in PlexWatch db.")
for s in xml_head:
if s.getAttribute('duration') and s.getAttribute('viewOffset'):
@ -925,7 +931,10 @@ class PlexWatch(object):
myDB = db.DBConnection()
query = 'select friendly_name FROM plexpy_users WHERE username = ?'
result = myDB.select_single(query, args=[user])
if result:
return result
else:
return user
except:
return user
@ -956,7 +965,9 @@ def check_db_tables():
try:
myDB = db.DBConnection()
query = 'CREATE TABLE IF NOT EXISTS plexpy_users (id INTEGER PRIMARY KEY AUTOINCREMENT, ' \
'username TEXT NOT NULL UNIQUE, friendly_name TEXT)'
'user_id INTEGER DEFAULT NULL UNIQUE, username TEXT NOT NULL UNIQUE, ' \
'friendly_name TEXT, thumb TEXT, email TEXT, is_home_user INTEGER DEFAULT NULL, ' \
'is_allow_sync INTEGER DEFAULT NULL, is_restricted INTEGER DEFAULT NULL)'
result = myDB.action(query)
except:
logger.debug(u"Unable to create users table.")

View file

@ -212,6 +212,39 @@ class PmsConnect(object):
return output
"""
Return the local servers preferences.
Optional parameters: output_format { dict, json }
Output: array
"""
def get_server_prefs(self, output_format=''):
url_command = '/:/prefs'
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.
@ -681,6 +714,41 @@ class PmsConnect(object):
return output
"""
Return the local machine identifier.
Output: string
"""
def get_servers_info(self):
recent = self.get_server_list()
try:
xml_parse = minidom.parseString(recent)
except Exception, e:
logger.warn("Error parsing XML for Plex server prefs: %s" % e)
return None
except:
logger.warn("Error parsing XML for Plex server prefs.")
return None
xml_head = xml_parse.getElementsByTagName('Server')
if not xml_head:
logger.warn("Error parsing XML for Plex server prefs.")
return None
server_info = []
for a in xml_head:
output = {"name": self.get_xml_attr(a, 'name'),
"machineIdentifier": self.get_xml_attr(a, 'machineIdentifier'),
"host": self.get_xml_attr(a, 'host'),
"port": self.get_xml_attr(a, 'port'),
"version": self.get_xml_attr(a, 'version')
}
server_info.append(output)
return server_info
"""
Return image data as array.
Array contains the image content type and image binary

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
from plexpy import logger, notifiers, plextv, pmsconnect, plexwatch, db
from plexpy.helpers import checked, radio
from mako.lookup import TemplateLookup
@ -833,3 +833,61 @@ class WebInterface(object):
return result
else:
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_servers_info(self, **kwargs):
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_servers_info()
if result:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
else:
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def get_server_prefs(self, **kwargs):
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_server_prefs(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_full_users_list(self, **kwargs):
plex_tv = plextv.PlexTV()
result = plex_tv.get_full_users_list()
if result:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
else:
logger.warn('Unable to retrieve data.')
@cherrypy.expose
def refresh_users_list(self, **kwargs):
plex_tv = plextv.PlexTV()
result = plex_tv.get_full_users_list()
myDB = db.DBConnection()
for item in result:
control_value_dict = {"username": item['username']}
new_value_dict = {"user_id": item['user_id'],
"username": item['username'],
"thumb": item['thumb'],
"email": item['email'],
"is_home_user": item['is_home_user'],
"is_allow_sync": item['is_allow_sync'],
"is_restricted": item['is_restricted']
}
myDB.upsert('plexpy_users', new_value_dict, control_value_dict)
logger.info("Users list refreshed.")
raise cherrypy.HTTPRedirect("users")