2015-03-14 08:24:59 +11:00
#################################################################################################
# utils
#################################################################################################
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import json
import os
2015-03-20 10:48:59 +11:00
import cProfile
import pstats
import time
2015-03-14 08:24:59 +11:00
import inspect
2015-03-27 22:20:40 +11:00
import sqlite3
2015-03-30 09:43:53 +11:00
import string
import unicodedata
2015-03-14 08:24:59 +11:00
from xml . etree . ElementTree import Element , SubElement , Comment , tostring
from xml . etree import ElementTree
from xml . dom import minidom
import xml . etree . cElementTree as ET
from API import API
from PlayUtils import PlayUtils
from DownloadUtils import DownloadUtils
downloadUtils = DownloadUtils ( )
2015-03-26 04:37:21 +11:00
addonSettings = xbmcaddon . Addon ( id = ' plugin.video.emby ' )
2015-03-23 22:30:03 +11:00
language = addonSettings . getLocalizedString
2015-03-27 08:35:11 +11:00
2015-03-14 08:24:59 +11:00
def logMsg ( title , msg , level = 1 ) :
2015-03-19 07:34:52 +11:00
logLevel = int ( addonSettings . getSetting ( " logLevel " ) )
2015-03-14 08:24:59 +11:00
if ( logLevel > = level ) :
2015-03-20 10:48:59 +11:00
if ( logLevel == 2 ) : # inspect.stack() is expensive
2015-03-14 08:24:59 +11:00
try :
xbmc . log ( title + " -> " + inspect . stack ( ) [ 1 ] [ 3 ] + " : " + str ( msg ) )
except UnicodeEncodeError :
xbmc . log ( title + " -> " + inspect . stack ( ) [ 1 ] [ 3 ] + " : " + str ( msg . encode ( ' utf-8 ' ) ) )
else :
try :
xbmc . log ( title + " -> " + str ( msg ) )
except UnicodeEncodeError :
xbmc . log ( title + " -> " + str ( msg . encode ( ' utf-8 ' ) ) )
2015-03-17 08:31:32 +11:00
def convertEncoding ( data ) :
#nasty hack to make sure we have a unicode string
try :
return data . decode ( ' utf-8 ' )
except :
return data
2015-03-27 08:35:11 +11:00
def KodiSQL ( ) :
2015-04-03 20:58:21 +11:00
connection = sqlite3 . connect ( getKodiDBPath ( ) )
return connection
def getKodiDBPath ( ) :
2015-03-27 11:24:49 +11:00
if xbmc . getInfoLabel ( " System.BuildVersion " ) . startswith ( " 13 " ) :
2015-03-27 08:35:11 +11:00
#gotham
dbVersion = " 78 "
2015-03-27 11:24:49 +11:00
if xbmc . getInfoLabel ( " System.BuildVersion " ) . startswith ( " 15 " ) :
2015-03-27 08:35:11 +11:00
#isengard
dbVersion = " 91 "
else :
#helix
dbVersion = " 90 "
2015-03-27 22:20:40 +11:00
dbPath = xbmc . translatePath ( " special://userdata/Database/MyVideos " + dbVersion + " .db " )
2015-04-03 20:58:21 +11:00
return dbPath
2015-03-27 11:24:49 +11:00
2015-03-14 08:24:59 +11:00
def checkAuthentication ( ) :
#check authentication
if addonSettings . getSetting ( ' username ' ) != " " and addonSettings . getSetting ( ' ipaddress ' ) != " " :
try :
downloadUtils . authenticate ( )
except Exception , e :
2015-04-03 06:47:06 +11:00
logMsg ( " Emby authentication failed " , e )
2015-03-14 08:24:59 +11:00
pass
def prettifyXml ( elem ) :
rough_string = etree . tostring ( elem , " utf-8 " )
reparsed = minidom . parseString ( rough_string )
return reparsed . toprettyxml ( indent = " \t " )
def get_params ( paramstring ) :
xbmc . log ( " Parameter string: " + paramstring )
param = { }
if len ( paramstring ) > = 2 :
params = paramstring
if params [ 0 ] == " ? " :
cleanedparams = params [ 1 : ]
else :
cleanedparams = params
if ( params [ len ( params ) - 1 ] == ' / ' ) :
params = params [ 0 : len ( params ) - 2 ]
pairsofparams = cleanedparams . split ( ' & ' )
for i in range ( len ( pairsofparams ) ) :
splitparams = { }
splitparams = pairsofparams [ i ] . split ( ' = ' )
if ( len ( splitparams ) ) == 2 :
param [ splitparams [ 0 ] ] = splitparams [ 1 ]
elif ( len ( splitparams ) ) == 3 :
param [ splitparams [ 0 ] ] = splitparams [ 1 ] + " = " + splitparams [ 2 ]
return param
2015-03-20 10:48:59 +11:00
def startProfiling ( ) :
pr = cProfile . Profile ( )
pr . enable ( )
return pr
def stopProfiling ( pr , profileName ) :
pr . disable ( )
ps = pstats . Stats ( pr )
2015-03-26 04:37:21 +11:00
addondir = xbmc . translatePath ( xbmcaddon . Addon ( id = ' plugin.video.emby ' ) . getAddonInfo ( ' profile ' ) )
2015-03-20 10:48:59 +11:00
fileTimeStamp = time . strftime ( " % Y- % m- %d % H- % M- % S " )
tabFileNamepath = os . path . join ( addondir , " profiles " )
tabFileName = os . path . join ( addondir , " profiles " , profileName + " _profile_( " + fileTimeStamp + " ).tab " )
if not xbmcvfs . exists ( tabFileNamepath ) :
xbmcvfs . mkdir ( tabFileNamepath )
f = open ( tabFileName , ' wb ' )
f . write ( " NumbCalls \t TotalTime \t CumulativeTime \t FunctionName \t FileName \r \n " )
for ( key , value ) in ps . stats . items ( ) :
( filename , count , func_name ) = key
( ccalls , ncalls , total_time , cumulative_time , callers ) = value
try :
f . write ( str ( ncalls ) + " \t " + " {:10.4f} " . format ( total_time ) + " \t " + " {:10.4f} " . format ( cumulative_time ) + " \t " + func_name + " \t " + filename + " \r \n " )
except ValueError :
f . write ( str ( ncalls ) + " \t " + " {0} " . format ( total_time ) + " \t " + " {0} " . format ( cumulative_time ) + " \t " + func_name + " \t " + filename + " \r \n " )
f . close ( )
2015-03-30 09:43:53 +11:00
def CleanName ( filename ) :
validFilenameChars = " -_.() %s %s " % ( string . ascii_letters , string . digits )
cleanedFilename = unicodedata . normalize ( ' NFKD ' , filename ) . encode ( ' ASCII ' , ' ignore ' )
return ' ' . join ( c for c in cleanedFilename if c in validFilenameChars )
2015-03-18 05:41:26 +11:00
2015-04-01 08:21:51 +11:00
def removeDirectory ( path ) :
if xbmcvfs . exists ( path ) :
allDirs , allFiles = xbmcvfs . listdir ( path )
for dir in allDirs :
xbmcvfs . rmdir ( os . path . join ( path , dir ) )
for file in allFiles :
xbmcvfs . delete ( os . path . join ( path , file ) )
xbmcvfs . rmdir ( path )
2015-04-03 06:47:06 +11:00
def reset ( ) :
2015-04-03 19:39:16 +11:00
return_value = xbmcgui . Dialog ( ) . yesno ( " Warning " , " Are you sure you want to reset your local database? " )
if return_value == 0 :
return
# first stop any db sync
WINDOW = xbmcgui . Window ( 10000 )
WINDOW . setProperty ( " SyncDatabaseShouldStop " , " true " )
count = 0
while ( WINDOW . getProperty ( " SyncDatabaseRunning " ) == " true " ) :
count + = 1
if ( count > 10 ) :
2015-04-03 21:49:39 +11:00
dialog = xbmcgui . Dialog ( )
2015-04-03 19:39:16 +11:00
dialog . ok ( ' Warning ' , ' Could not stop DB sync, you should try again. ' )
return
xbmc . sleep ( 1000 )
2015-04-03 06:47:06 +11:00
2015-04-03 20:58:21 +11:00
# delete db
2015-04-03 21:33:44 +11:00
deletecount = 0
deleted = False
while ( deleted == False ) :
try :
2015-04-03 21:53:41 +11:00
xbmcvfs . delete ( getKodiDBPath ( ) )
2015-04-03 21:33:44 +11:00
deleted = True
except :
deletecount + = 1
if ( deletecount > 10 ) :
2015-04-03 21:49:39 +11:00
dialog = xbmcgui . Dialog ( )
2015-04-03 21:33:44 +11:00
dialog . ok ( ' Warning ' , ' Could not delete Database, please try again later ' )
return
xbmc . sleep ( 1000 )
2015-04-03 23:51:15 +11:00
# extra check on the database to see it has been removed
if xbmcvfs . exists ( getKodiDBPath ( ) ) :
dialog = xbmcgui . Dialog ( )
dialog . ok ( ' Error ' , ' The video database could not be deleted, this will need to be done manually. First remove: ' + getKodiDBPath ( ) + ' Then delete the plugin from your addon_data directory and restart Kodi ' )
return
2015-04-03 20:58:21 +11:00
# remove from addon data directory
2015-04-03 06:47:06 +11:00
addon = xbmcaddon . Addon ( id = ' plugin.video.emby ' )
addondir = xbmc . translatePath ( addon . getAddonInfo ( ' profile ' ) )
2015-04-03 20:58:21 +11:00
dataPath = os . path . join ( addondir + os . sep )
2015-04-03 06:47:06 +11:00
removeDirectory ( dataPath )
# remove old entries from sources.xml
dialog = xbmcgui . Dialog ( )
2015-04-03 21:02:21 +11:00
dialog . ok ( ' Emby Reset ' , ' Reset of Emby has completed, kodi will now restart to apply the changes. ' )
2015-04-03 19:39:16 +11:00
xbmc . executebuiltin ( " RestartApp " )
2015-04-03 06:47:06 +11:00