Last active
August 29, 2015 14:11
-
-
Save larrybolt/84c7531352a1772b5220 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import xbmc, xbmcgui, xbmcaddon, xbmcvfs | |
import re | |
import sys, os | |
import unicodedata | |
import time | |
import sqlite3 | |
import mysql.connector | |
import buggalo | |
buggalo.GMAIL_RECIPIENT = "[email protected]" | |
# buggalo.SUBMIT_URL = 'http://msahadl.ms.funpic.de/buggalo-web/submit.php' | |
import resources.lib.utils as utils | |
if utils.getSetting('dbbackup') == 'true': | |
import zipfile | |
import datetime | |
# Main class of the add-on | |
class WatchedList: | |
def __init__(self): | |
self.watchedmovielist_wl = list([]) # 0imdbnumber, 1empty, 2empty, 3lastPlayed, 4playCount, 5title, 6lastChange | |
self.watchedepisodelist_wl = list([]) # 0imdbnumber, 1season, 2episode, 3lastplayed, 4playcount, 5empty, 6lastChange | |
self.watchedmovielist_xbmc = list([]) # 0imdbnumber, 1empty, 2empty, 3lastPlayed, 4playCount, 5title, 6empty, 7movieid | |
self.watchedepisodelist_xbmc = list([]) # 0imdbnumber, 1season, 2episode, 3lastplayed, 4playcount, 5name, 6empty, 7episodeid | |
self.tvshows = {} # dict: key=xbmcid, value=[imdbnumber, showname] | |
self.tvshownames = {} #dict: key=imdbnumber, value=showname | |
self.sqlcon = 0 | |
self.sqlcursor = 0 | |
self.db_method = 'file' # either 'file' or 'mysql' | |
# flag to remember copying the databasefile if requested | |
self.dbcopydone = False | |
self.watch_user_changes_count = 0 | |
# normal access of files or access over the xbmc virtual file system (on unix) | |
self.dbfileaccess = 'normal' | |
self.dbpath = '' | |
self.dbdirectory = '' | |
# infinite loop for periodic database update | |
def runProgram(self): | |
# return codes: | |
# 0 success | |
# 3 error/exit | |
try: | |
# workaround to disable autostart, if requested | |
if utils.getSetting("autostart") == 'false': | |
return 0 | |
utils.buggalo_extradata_settings() | |
utils.footprint() | |
if self.sqlcursor == 0 or self.sqlcon == 0: | |
if self.load_db(): | |
utils.showNotification(utils.getString(32102), utils.getString(32601)) | |
return 3 | |
if len(self.tvshownames) == 0: self.sync_tvshows() | |
if len(self.watchedmovielist_wl) == 0: self.get_watched_wl(1) | |
if len(self.watchedmovielist_xbmc) == 0: self.get_watched_xbmc(1) | |
executioncount = 0 | |
idletime = 0 | |
# wait the delay time after startup | |
delaytime = float(utils.getSetting("delay")) * 60 # in seconds | |
utils.log(u'Delay time before execution: %d seconds' % delaytime, xbmc.LOGDEBUG) | |
utils.showNotification(utils.getString(32101), utils.getString(32004)%float(utils.getSetting("delay"))) | |
if utils.sleepsafe(delaytime): | |
return 0 | |
if utils.getSetting("watch_user") == 'true': utils.showNotification(utils.getString(32101), utils.getString(32005)) | |
# handle the periodic execution | |
while float(utils.getSetting("starttype")) > 0 or utils.getSetting("watch_user") == 'true': | |
starttime = time.time() | |
# determine sleeptime before full watched-database update | |
if float(utils.getSetting("starttype")) > 0: | |
if utils.getSetting("starttype") == '2': | |
sleeptime = float(utils.getSetting("interval")) * 3600 # wait interval until next startup in [seconds] | |
# wait and then update again | |
utils.log(u'wait %d seconds until next update' % sleeptime) | |
utils.showNotification(utils.getString(32101), utils.getString(32003)%(sleeptime/3600)) | |
else: | |
sleeptime = 3600 # arbitrary time for infinite loop | |
else: | |
sleeptime = 3600 # arbitrary time for infinite loop | |
# workaround to sleep the requested time. When using the sleep-function, xbmc can not exit | |
while 1: | |
if xbmc.abortRequested: return 1 | |
# check if user changes arrived | |
if utils.getSetting("watch_user") == 'true': | |
idletime_old = idletime | |
idletime = xbmc.getGlobalIdleTime() # xbmc idletime in seconds | |
# check if user could have made changes and process these changes to the wl database | |
self.watch_user_changes(idletime_old, idletime) | |
# check if time for update arrived | |
if time.time() > starttime + sleeptime: | |
break | |
xbmc.sleep(1000) # wait 1 second until next check if xbmc terminates | |
if utils.getSetting("starttype") == '1' and executioncount == 0 or utils.getSetting("starttype") == '2': | |
self.runUpdate(False) | |
executioncount += 1 | |
if float(utils.getSetting("starttype")) < 2 and utils.getSetting("watch_user") == 'false': | |
return 0 # the program may exit. No purpose for background process | |
# do not use the periodic update | |
return 0 | |
except: | |
buggalo.onExceptionRaised() | |
# entry point for manual start. | |
# perform the update step by step | |
def runUpdate(self, manualstart): | |
# return codes: | |
# 0 success | |
# 3 Error opening database | |
# 4 Error getting watched state from addon database | |
# 5 Error getting watched state from xbmc database | |
# 6 Error writing WL Database | |
# 7 Error writing XBMC database | |
try: | |
utils.buggalo_extradata_settings() | |
# check if player is running before doing the update. Only do this check for automatic start | |
while xbmc.Player().isPlaying() == True and not manualstart: | |
if utils.sleepsafe(60*1000): return 1 # wait one minute until next check for active playback | |
if xbmc.Player().isPlaying() == False: | |
if utils.sleepsafe(180*1000): return 1 # wait 3 minutes so the dialogue does not pop up directly after the playback ends | |
# load the addon-database | |
if self.load_db(True): # True: Manual start | |
utils.showNotification(utils.getString(32102), utils.getString(32601)) | |
return 3 | |
if self.sync_tvshows(): | |
utils.showNotification(utils.getString(32102), utils.getString(32604)) | |
return 5 | |
# get the watched state from the addon | |
if self.get_watched_wl(0): | |
utils.showNotification(utils.getString(32102), utils.getString(32602)) | |
return 4 | |
# get watched state from xbmc | |
if self.get_watched_xbmc(0): | |
utils.showNotification(utils.getString(32102), utils.getString(32603)) | |
return 5 | |
if self.sync_tvshows(): | |
utils.showNotification(utils.getString(32102), utils.getString(32604)) | |
return 5 | |
# import from xbmc into addon database | |
res = self.write_wl_wdata() | |
if res == 2: # user exit | |
return 0 | |
elif res == 1: # error | |
utils.showNotification(utils.getString(32102), utils.getString(32604)) | |
return 6 | |
# close the sqlite database (addon) | |
self.close_db() # should be closed by the functions directly accessing the database | |
# export from addon database into xbmc database | |
res = self.write_xbmc_wdata((utils.getSetting("progressdialog") == 'true'), 2) | |
if res == 2: # user exit | |
return 0 | |
elif res == 1: # error | |
utils.showNotification(utils.getString(32102), utils.getString(32605)) | |
return 7 | |
utils.showNotification(utils.getString(32101), utils.getString(32107)) | |
utils.log(u'runUpdate exited with success', xbmc.LOGDEBUG) | |
return 0 | |
except: | |
buggalo.onExceptionRaised() | |
def load_db(self, manualstart=False): | |
# return codes: | |
# 0 successfully opened database | |
# 1 error | |
# 2 shutdown (serious error in subfunction) | |
# if manualstart, only retry opening db once | |
try: | |
#if utils.getSetting("db_format") == 0: | |
if True: | |
# SQlite3 database in a file | |
# load the db path | |
if utils.getSetting("extdb") == 'false': | |
# use the default file | |
self.dbdirectory = xbmc.translatePath( utils.data_dir() ).decode('utf-8') | |
buggalo.addExtraData('dbdirectory', self.dbdirectory); | |
self.dbpath = os.path.join( self.dbdirectory , "watchedlist.db" ) | |
else: | |
wait_minutes = 1 # retry waittime if db path does not exist/ is offline | |
while xbmc.abortRequested == False: | |
# use a user specified file, for example to synchronize multiple clients | |
self.dbdirectory = xbmc.translatePath( utils.getSetting("dbpath") ).decode('utf-8') | |
self.dbfileaccess = utils.fileaccessmode(self.dbdirectory) | |
self.dbdirectory = utils.translateSMB(self.dbdirectory) | |
self.dbpath = os.path.join( self.dbdirectory , utils.getSetting("dbfilename").decode('utf-8') ) | |
# xbmc.validatePath(self.dbdirectory) # does not work for smb | |
if not xbmcvfs.exists(self.dbdirectory): # do not use os.path.exists to access smb:// paths | |
if manualstart: | |
utils.log(u'db path does not exist: %s' % self.dbdirectory, xbmc.LOGWARNING) | |
return 1 # error | |
else: | |
utils.log(u'db path does not exist, wait %d minutes: %s' % (wait_minutes, self.dbdirectory), xbmc.LOGWARNING) | |
utils.showNotification(utils.getString(32102), utils.getString(32002) % self.dbdirectory ) | |
# Wait "wait_minutes" minutes until next check for file path (necessary on network shares, that are offline) | |
wait_minutes += wait_minutes # increase waittime until next check | |
if utils.sleepsafe(wait_minutes*60): return 2 | |
else: | |
break # directory exists, continue below | |
# on unix, smb-shares can not be accessed with sqlite3 --> copy the db with xbmc file system operations and work in mirror directory | |
buggalo.addExtraData('dbfileaccess', self.dbfileaccess); | |
buggalo.addExtraData('dbdirectory', self.dbdirectory); | |
buggalo.addExtraData('dbpath', self.dbpath); | |
if self.dbfileaccess == 'copy': | |
self.dbdirectory_copy = self.dbdirectory | |
self.dbpath_copy = self.dbpath # path to db file as in the settings (but not accessable) | |
buggalo.addExtraData('dbdirectory_copy', self.dbdirectory_copy); | |
buggalo.addExtraData('dbpath_copy', self.dbpath_copy); | |
# work in copy directory in the xbmc profile folder | |
self.dbdirectory = os.path.join( xbmc.translatePath( utils.data_dir() ).decode('utf-8'), 'dbcopy') | |
if not xbmcvfs.exists(self.dbdirectory): | |
xbmcvfs.mkdir(self.dbdirectory) | |
utils.log(u'created directory %s' % str(self.dbdirectory)) | |
self.dbpath = os.path.join( self.dbdirectory , "watchedlist.db" ) | |
if xbmcvfs.exists(self.dbpath_copy): | |
success = xbmcvfs.copy(self.dbpath_copy, self.dbpath) # copy the external db file to local mirror directory | |
utils.log(u'copied db file %s -> %s. Success: %d' % (self.dbpath_copy, self.dbpath, success), xbmc.LOGDEBUG) | |
buggalo.addExtraData('dbdirectory', self.dbdirectory); | |
buggalo.addExtraData('dbpath', self.dbpath); | |
#connect to the database. create database if it does not exist | |
self.sqlcon = sqlite3.connect(self.dbpath); | |
self.sqlcursor = self.sqlcon.cursor() | |
else: | |
# MySQL Database on a server | |
self.sqlcon = mysql.connector.connect(user=utils.getSetting("mysql_user"), password=utils.getSetting("mysql_pass"), database=utils.getSetting("mysql_db"), host=utils.getSetting("mysql_server"), port=utils.getSetting("mysql_port")) | |
self.sqlcursor = self.sqlcon.cursor() | |
# create tables if they don't exist | |
if True: # sqlite file | |
sql = "CREATE TABLE IF NOT EXISTS movie_watched (idMovieImdb INTEGER PRIMARY KEY,playCount INTEGER,lastChange INTEGER,lastPlayed INTEGER,title TEXT)" | |
self.sqlcursor.execute(sql) | |
sql = "CREATE TABLE IF NOT EXISTS episode_watched (idShow INTEGER, season INTEGER, episode INTEGER, playCount INTEGER,lastChange INTEGER,lastPlayed INTEGER, PRIMARY KEY (idShow, season, episode))" | |
self.sqlcursor.execute(sql) | |
sql = "CREATE TABLE IF NOT EXISTS tvshows (idShow INTEGER, title TEXT, PRIMARY KEY (idShow))" | |
self.sqlcursor.execute(sql) | |
else: # mysql network database | |
sql = ("CREATE TABLE IF NOT EXISTS `movie_watched` (" | |
"`idMovieImdb` int unsigned NOT NULL," | |
"`playCount` tinyint unsigned DEFAULT NULL," | |
"`lastChange` timestamp NULL DEFAULT NULL," | |
"`lastPlayed` timestamp NULL DEFAULT NULL," | |
"`title` text," | |
"PRIMARY KEY (`idMovieImdb`)" | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8;") | |
self.sqlcursor.execute(sql) | |
sql = ("CREATE TABLE IF NOT EXISTS `episode_watched` (" | |
"`idShow` int unsigned NOT NULL DEFAULT '0'," | |
"`season` smallint unsigned NOT NULL DEFAULT '0'," | |
"`episode` smallint unsigned NOT NULL DEFAULT '0'," | |
"`playCount` tinyint unsigned DEFAULT NULL," | |
"`lastChange` timestamp NULL DEFAULT NULL," | |
"`lastPlayed` timestamp NULL DEFAULT NULL," | |
"PRIMARY KEY (`idShow`,`season`,`episode`)" | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8;") | |
self.sqlcursor.execute(sql) | |
sql = ("CREATE TABLE IF NOT EXISTS `tvshows` (" | |
"`idShow` int unsigned NOT NULL," | |
"`title` text," | |
"PRIMARY KEY (`idShow`)" | |
") ENGINE=InnoDB DEFAULT CHARSET=utf8;") | |
self.sqlcursor.execute(sql) | |
buggalo.addExtraData('db_connstatus', 'connected') | |
except sqlite3.Error as e: | |
try: | |
errstring = e.args[0] # TODO: Find out, why this does not work some times | |
except: | |
errstring = '' | |
utils.log(u"Database error while opening %s. '%s'" % (self.dbpath, errstring), xbmc.LOGERROR) | |
self.close_db() | |
buggalo.addExtraData('db_connstatus', 'sqlite3 error, closed') | |
return 1 | |
except mysql.connector.Error as err: | |
# Catch common mysql errors and show them to guide the user | |
utils.log(u"Database error while opening mySQL DB %s [%s:%s@%s]. %s" % (utils.getSetting("mysql_db"), utils.getSetting("mysql_user"), utils.getSetting("mysql_pass"), utils.getSetting("mysql_db"), err), xbmc.LOGERROR) | |
if err.errno == mysql.connector.errorcode.ER_DBACCESS_DENIED_ERROR: | |
utils.showNotification(utils.getString(32103), utils.getString(32210) % (utils.getSetting("mysql_user"), utils.getSetting("mysql_db"))) | |
elif err.errno == mysql.connector.errorcode.ER_ACCESS_DENIED_ERROR: | |
utils.showNotification(utils.getString(32103), utils.getString(32208)) | |
elif err.errno == mysql.connector.errorcode.ER_BAD_DB_ERROR: | |
utils.showNotification(utils.getString(32103), utils.getString(32209) % utils.getSetting("mysql_db") ) | |
buggalo.addExtraData('db_connstatus', 'mysql error, closed') | |
self.close_db() | |
return 1 | |
except: | |
utils.log(u"Error while opening %s: %s" % (self.dbpath, sys.exc_info()[2]), xbmc.LOGERROR) | |
self.close_db() | |
buggalo.addExtraData('dbpath', self.dbpath) | |
buggalo.addExtraData('db_connstatus', 'error, closed') | |
buggalo.onExceptionRaised() | |
return 1 | |
# only commit the changes if no error occured to ensure database persistence | |
self.sqlcon.commit() | |
return 0 | |
def close_db(self): | |
if self.sqlcon: | |
self.sqlcon.close() | |
self.sqlcon = 0 | |
# copy the db file back to the shared directory, if needed | |
if utils.getSetting("db_format") == 0 and self.dbfileaccess == 'copy': | |
if xbmcvfs.exists(self.dbpath): | |
success = xbmcvfs.copy(self.dbpath, self.dbpath_copy) | |
utils.log(u'copied db file %s -> %s. Success: %d' % (self.dbpath, self.dbpath_copy, success), xbmc.LOGDEBUG) | |
if not success: | |
utils.showNotification(utils.getString(32102), utils.getString(32606) % self.dbpath ) | |
return 1 | |
buggalo.addExtraData('db_connstatus', 'closed') | |
return 0 | |
# cursor is not changed -> error | |
def get_watched_xbmc(self, silent): | |
try: | |
############################################ | |
# first tv shows with TheTVDB-ID, then tv episodes | |
if utils.getSetting("w_episodes") == 'true': | |
############################################ | |
# get imdb tv-show id from xbmc database | |
utils.log(u'get_watched_xbmc: Get all episodes from xbmc database', xbmc.LOGDEBUG) | |
json_response = utils.executeJSON({ | |
"jsonrpc": "2.0", | |
"method": "VideoLibrary.GetTVShows", | |
"params": { | |
"properties": ["title", "imdbnumber"], | |
"sort": { "order": "ascending", "method": "title" } | |
}, | |
"id": 1}) | |
if json_response.has_key('result') and json_response['result'] != None and json_response['result'].has_key('tvshows'): | |
for item in json_response['result']['tvshows']: | |
tvshowId_xbmc = int(item['tvshowid']) | |
try: | |
# check if series number is in imdb-format (scraper=imdb?) | |
res = re.compile('tt(\d+)').findall(item['imdbnumber']) | |
if len(res) == 0: | |
# number in thetvdb-format | |
tvshowId_imdb = int(item['imdbnumber']) | |
else: | |
# number in imdb-format | |
tvshowId_imdb = int(res[0]) | |
except: | |
utils.log(u'get_watched_xbmc: tv show "%s" has no imdb-number in database. tvshowid=%d Try rescraping.' % (item['title'], tvshowId_xbmc), xbmc.LOGDEBUG) | |
continue | |
self.tvshows[tvshowId_xbmc] = list([tvshowId_imdb, item['title']]) | |
self.tvshownames[tvshowId_imdb] = item['title'] | |
# Get all watched movies and episodes by unique id from xbmc-database via JSONRPC | |
self.watchedmovielist_xbmc = list([]) | |
self.watchedepisodelist_xbmc = list([]) | |
for modus in ['movie', 'episode']: | |
buggalo.addExtraData('modus', modus); | |
if modus == 'movie' and utils.getSetting("w_movies") != 'true': | |
continue | |
if modus == 'episode' and utils.getSetting("w_episodes") != 'true': | |
continue | |
utils.log(u'get_watched_xbmc: Get all %ss from xbmc database' % modus, xbmc.LOGDEBUG) | |
if modus == 'movie': | |
# use the JSON-RPC to access the xbmc-database. | |
json_response = utils.executeJSON({ | |
"jsonrpc": "2.0", | |
"method": "VideoLibrary.GetMovies", | |
"params": { | |
"properties": ["title", "year", "imdbnumber", "lastplayed", "playcount"], | |
"sort": { "order": "ascending", "method": "title" } | |
}, | |
"id": 1 | |
}) | |
else: | |
json_response = utils.executeJSON({ | |
"jsonrpc": "2.0", | |
"method": "VideoLibrary.GetEpisodes", | |
"params": { | |
"properties": ["tvshowid", "season", "episode", "playcount", "showtitle", "lastplayed"] | |
}, | |
"id": 1 | |
}) | |
if modus == 'movie': searchkey = 'movies' | |
else: searchkey = 'episodes' | |
if json_response.has_key('result') and json_response['result'] != None and json_response['result'].has_key(searchkey): | |
# go through all watched movies and save them in the class-variable self.watchedmovielist_xbmc | |
for item in json_response['result'][searchkey]: | |
if modus == 'movie': | |
name = item['title'] + ' (' + str(item['year']) + ')' | |
res = re.compile('tt(\d+)').findall(item['imdbnumber']) | |
if len(res) == 0: | |
# no imdb-number for this movie in database. Skip | |
utils.log(u'get_watched_xbmc: Movie %s has no imdb-number in database. movieid=%d Try rescraping' % (name, int(item['movieid'])), xbmc.LOGDEBUG) | |
continue | |
imdbId = int(res[0]) | |
else: # episodes | |
tvshowId_xbmc = item['tvshowid'] | |
name = '%s S%02dE%02d' % (item['showtitle'], item['season'], item['episode']) | |
try: | |
tvshowId_imdb = self.tvshows[tvshowId_xbmc][0] | |
except: | |
utils.log(u'get_watched_xbmc: xbmc tv showid %d is not in table xbmc-tvshows. Skipping %s' % (item['tvshowid'], name), xbmc.LOGWARNING) | |
continue | |
lastplayed = utils.sqlDateTimeToTimeStamp(item['lastplayed']) # convert to integer-timestamp | |
playcount = int(item['playcount']) | |
# add data to the class-variables | |
if modus == 'movie': | |
self.watchedmovielist_xbmc.append(list([imdbId, 0, 0, lastplayed, playcount, name, 0, int(item['movieid'])]))# 0imdbnumber, 1empty, 2empty, 3lastPlayed, 4playCount, 5title, 6empty, 7movieid | |
else: | |
self.watchedepisodelist_xbmc.append(list([tvshowId_imdb, int(item['season']), int(item['episode']), lastplayed, playcount, name, 0, int(item['episodeid'])])) | |
if not silent: utils.showNotification( utils.getString(32101), utils.getString(32299)%(len(self.watchedmovielist_xbmc), len(self.watchedepisodelist_xbmc)) ) | |
return 0 | |
except: | |
utils.log(u'get_watched_xbmc: error getting the xbmc database : %s' % sys.exc_info()[2], xbmc.LOGERROR) | |
self.close_db() | |
buggalo.onExceptionRaised() | |
return 1 | |
def get_watched_wl(self, silent): | |
# return codes: | |
# 0 successfully got watched states from WL-database | |
# 1 unknown error (programming related) | |
# 2 shutdown (error in subfunction) | |
# 3 error related to opening the database | |
try: | |
buggalo.addExtraData('self_sqlcursor', self.sqlcursor); buggalo.addExtraData('self_sqlcon', self.sqlcon); | |
if self.sqlcursor == 0 or self.sqlcon == 0: | |
if self.load_db(): | |
return 2 | |
# get watched movies from addon database | |
self.watchedmovielist_wl = list([]) | |
if utils.getSetting("w_movies") == 'true': | |
utils.log(u'get_watched_wl: Get watched movies from WL database', xbmc.LOGDEBUG) | |
#if utils.getSetting("db_format") == 0: # SQLite3 File. Timestamp stored as integer | |
if True: # SQLite3 File. Timestamp stored as integer | |
self.sqlcursor.execute("SELECT idMovieImdb, lastPlayed, playCount, title, lastChange FROM movie_watched ORDER BY title") | |
else: # mySQL: Create integer timestamp with the request | |
self.sqlcursor.execute("SELECT `idMovieImdb`, strftime('%s', `lastPlayed`), `playCount`, `title`, strftime('%s', `lastChange`) FROM `movie_watched` ORDER BY `title`") | |
rows = self.sqlcursor.fetchall() | |
for row in rows: | |
self.watchedmovielist_wl.append(list([int(row[0]), 0, 0, int(row[1]), int(row[2]), row[3], int(row[4])])) # 0imdbnumber, 1empty, 2empty, 3lastPlayed, 4playCount, 5title, 6lastChange | |
# get watched episodes from addon database | |
self.watchedepisodelist_wl = list([]) | |
if utils.getSetting("w_episodes") == 'true': | |
utils.log(u'get_watched_wl: Get watched episodes from WL database', xbmc.LOGDEBUG) | |
#if utils.getSetting("db_format") == 0: # SQLite3 File. Timestamp stored as integer | |
if True: # SQLite3 File. Timestamp stored as integer | |
self.sqlcursor.execute("SELECT idShow, season, episode, lastPlayed, playCount, lastChange FROM episode_watched ORDER BY idShow, season, episode") | |
else: # mySQL: Create integer timestamp with the request | |
self.sqlcursor.execute("SELECT `idShow`, `season`, `episode`, strftime('%s', `lastPlayed`), `playCount`, strftime('%s', `lastChange`) FROM `episode_watched` ORDER BY `idShow`, `season`, `episode`") | |
rows = self.sqlcursor.fetchall() | |
for row in rows: | |
try: | |
name = '%s S%02dE%02d' % (self.tvshownames[int(row[0])], int(row[1]), int(row[2])) | |
except: | |
name = 'tvdb-id %d S%02dE%02d' % (int(row[0]), int(row[1]), int(row[2])) | |
self.watchedepisodelist_wl.append(list([int(row[0]), int(row[1]), int(row[2]), int(row[3]), int(row[4]), name, int(row[5])]))# 0imdbnumber, 1season, 2episode, 3lastplayed, 4playcount, 5name, 6lastChange | |
if not silent: utils.showNotification(utils.getString(32101), utils.getString(32298)%(len(self.watchedmovielist_wl), len(self.watchedepisodelist_wl))) | |
self.close_db() | |
return 0 | |
except sqlite3.Error as e: | |
try: | |
errstring = e.args[0] # TODO: Find out, why this does not work some times | |
except: | |
errstring = '' | |
utils.log(u'get_watched_wl: SQLite Database error getting the wl database. %s' % errstring, xbmc.LOGERROR) | |
self.close_db() | |
# error could be that the database is locked (for tv show strings). This is not an error to disturb the other functions | |
return 3 | |
except mysql.connector.Error as err: | |
utils.log(u'get_watched_wl: MySQL Database error getting the wl database. %s' % err, xbmc.LOGERROR) | |
return 3 | |
except: | |
utils.log(u'get_watched_wl: Error getting the wl database : %s' % sys.exc_info()[2], xbmc.LOGERROR) | |
self.close_db() | |
buggalo.onExceptionRaised() | |
return 1 | |
def sync_tvshows(self): | |
# return codes: | |
# 0 successfully synched tv shows | |
# 1 database access error | |
# 2 database loading error | |
try: | |
utils.log(u'sync_tvshows: sync tvshows with wl database : %s' % sys.exc_info()[2], xbmc.LOGDEBUG) | |
if self.sqlcursor == 0 or self.sqlcon == 0: | |
if self.load_db(): | |
return 2 | |
# write eventually new tv shows to wl database | |
for xbmcid in self.tvshows: | |
#if utils.getSetting("db_format") == 0: # sqlite3 | |
if True: | |
sql = "INSERT OR IGNORE INTO tvshows (idShow,title) VALUES (?, ?)" | |
else: # mysql | |
sql = "INSERT IGNORE INTO tvshows (idShow,title) VALUES (%s, %s)" | |
values = self.tvshows[xbmcid] | |
self.sqlcursor.execute(sql, values) | |
self.database_copy() | |
self.sqlcon.commit() | |
# get all known tv shows from wl database | |
self.sqlcursor.execute("SELECT idShow, title FROM tvshows") | |
rows = self.sqlcursor.fetchall() | |
for i in range(len(rows)): | |
self.tvshownames[int(rows[i][0])] = rows[i][1] | |
self.close_db() | |
except sqlite3.Error as e: | |
try: | |
errstring = e.args[0] # TODO: Find out, why this does not work some times | |
except: | |
errstring = '' | |
utils.log(u'sync_tvshows: SQLite Database error accessing the wl database: ''%s''' % errstring, xbmc.LOGERROR) | |
self.close_db() | |
# error could be that the database is locked (for tv show strings). | |
return 1 | |
except mysql.connector.Error as err: | |
utils.log(u"sync_tvshows: MySQL Database error accessing the wl database: ''%s''" % (err), xbmc.LOGERROR) | |
self.close_db() | |
return 1 | |
except: | |
utils.log(u'sync_tvshows: Error getting the wl database: ''%s''' % sys.exc_info()[2], xbmc.LOGERROR) | |
self.close_db() | |
buggalo.onExceptionRaised() | |
return 1 | |
return 0 | |
def write_wl_wdata(self): | |
# Go through all watched movies from xbmc and check whether they are up to date in the addon database | |
# return codes: | |
# 0 successfully written WL | |
# 1 program exception | |
# 2 database loading error | |
buggalo.addExtraData('self_sqlcursor', self.sqlcursor); buggalo.addExtraData('self_sqlcon', self.sqlcon); | |
if self.sqlcursor == 0 or self.sqlcon == 0: | |
if self.load_db(): | |
return 2 | |
for modus in ['movie', 'episode']: | |
buggalo.addExtraData('modus', modus); | |
if modus == 'movie' and utils.getSetting("w_movies") != 'true': | |
continue | |
if modus == 'episode' and utils.getSetting("w_episodes") != 'true': | |
continue | |
utils.log(u'write_wl_wdata: Write watched %ss to WL database' % modus, xbmc.LOGDEBUG) | |
count_insert = 0 | |
count_update = 0 | |
if utils.getSetting("progressdialog") == 'true': | |
DIALOG_PROGRESS = xbmcgui.DialogProgress() | |
DIALOG_PROGRESS.create( utils.getString(32101) , utils.getString(32105)) | |
if modus == 'movie': | |
list_length = len(self.watchedmovielist_xbmc) | |
else: | |
list_length = len(self.watchedepisodelist_xbmc) | |
for i in range(list_length): | |
if xbmc.abortRequested: break # this loop can take some time in debug mode and prevents xbmc exit | |
if utils.getSetting("progressdialog") == 'true' and DIALOG_PROGRESS.iscanceled(): | |
if modus == 'movie': strno = 32202 | |
else: strno = 32203; | |
utils.showNotification(utils.getString(strno), utils.getString(32301)%(count_insert, count_update)) | |
return 2 | |
if modus == 'movie': | |
row_xbmc = self.watchedmovielist_xbmc[i] | |
else: | |
row_xbmc = self.watchedepisodelist_xbmc[i] | |
if utils.getSetting("progressdialog") == 'true': | |
DIALOG_PROGRESS.update(100*(i+1)/list_length, utils.getString(32105), utils.getString(32610) % (i+1, list_length, row_xbmc[5]) ) | |
try: | |
count = self.wl_update_media(modus, row_xbmc, 0, 0) | |
count_insert += count[0]; count_update += count[1]; | |
except sqlite3.Error as e: | |
try: | |
errstring = e.args[0] # TODO: Find out, why this does not work some times | |
except: | |
errstring = '' | |
utils.log(u'write_wl_wdata: SQLite Database error ''%s'' while updating %s %s' % (errstring, modus, row_xbmc[5]), xbmc.LOGERROR) | |
# error at this place is the result of duplicate movies, which produces a DUPLICATE PRIMARY KEY ERROR | |
return 1 | |
except mysql.connector.Error as err: | |
utils.log(u'write_wl_wdata: MySQL Database error ''%s'' while updating %s %s' % (err, modus, row_xbmc[5]), xbmc.LOGERROR) | |
self.close_db() | |
return 1 # error while writing. Do not continue with episodes, if movies raised an exception | |
except: | |
utils.log(u'write_wl_wdata: Error while updating %s %s: %s' % (modus, row_xbmc[5], sys.exc_info()[2]), xbmc.LOGERROR) | |
self.close_db() | |
if utils.getSetting("progressdialog") == 'true': DIALOG_PROGRESS.close() | |
buggalo.addExtraData('count_update', count_update); buggalo.addExtraData('count_insert', count_insert); | |
buggalo.onExceptionRaised() | |
return 1 | |
if utils.getSetting("progressdialog") == 'true': DIALOG_PROGRESS.close() | |
# only commit the changes if no error occured to ensure database persistence | |
if count_insert > 0 or count_update > 0: | |
self.database_copy() | |
self.sqlcon.commit() | |
if modus == 'movie': strno = [32202, 32301] | |
else: strno = [32203, 32301]; | |
utils.showNotification(utils.getString(strno[0]), utils.getString(strno[1])%(count_insert, count_update)) | |
self.close_db() | |
return 0 | |
# update the xbmc database. | |
# progressdialogue | |
# notifications: 0= no, 1=only changed info, 2=all | |
def write_xbmc_wdata(self, progressdialogue, notifications): | |
# Go through all watched movies/episodes from the wl-database and check, if the xbmc-database is up to date | |
# return codes: | |
# 0 successfully written XBMC database | |
# 1 program exception | |
# 2 cancel by user interaction | |
for modus in ['movie', 'episode']: | |
buggalo.addExtraData('modus', modus); | |
if modus == 'movie' and utils.getSetting("w_movies") != 'true': | |
continue | |
if modus == 'episode' and utils.getSetting("w_episodes") != 'true': | |
continue | |
utils.log(u'write_xbmc_wdata: Write watched %ss to xbmc database (pd=%d, noti=%d)' % (modus, progressdialogue, notifications), xbmc.LOGDEBUG) | |
count_update = 0 | |
if progressdialogue: | |
DIALOG_PROGRESS = xbmcgui.DialogProgress() | |
DIALOG_PROGRESS.create( utils.getString(32101), utils.getString(32106)) | |
# list to iterate over | |
if modus == 'movie': | |
list_length = len(self.watchedmovielist_wl) | |
else: | |
list_length = len(self.watchedepisodelist_wl) | |
# iterate over wl-list | |
for j in range(list_length): | |
if xbmc.abortRequested: break # this loop can take some time in debug mode and prevents xbmc exit | |
if progressdialogue and DIALOG_PROGRESS.iscanceled(): | |
if notifications > 0: utils.showNotification(utils.getString(32204), utils.getString(32302)%(count_update)) | |
return 2 | |
# get media-specific list items | |
if modus == 'movie': | |
row_wl = self.watchedmovielist_wl[j] | |
else: | |
row_wl = self.watchedepisodelist_wl[j] | |
season = row_wl[1] | |
episode = row_wl[2] | |
imdbId = row_wl[0] | |
name = row_wl[5] | |
if progressdialogue: | |
DIALOG_PROGRESS.update(100*(j+1)/list_length, utils.getString(32106), utils.getString(32610) % (j+1, list_length, name) ) | |
try: | |
# search the unique movie/episode id in the xbmc-list | |
if modus == 'movie': | |
indices = [i for i, x in enumerate(self.watchedmovielist_xbmc) if x[0] == imdbId] # the movie can have multiple entries in xbmc | |
else: | |
indices = [i for i, x in enumerate(self.watchedepisodelist_xbmc) if x[0] == imdbId and x[1] == season and x[2] == episode] | |
lastplayed_wl = row_wl[3] | |
playcount_wl = row_wl[4] | |
lastchange_wl = row_wl[6] | |
if len(indices) > 0: | |
# the movie/episode is already in the xbmc-list | |
for i in indices: | |
if modus == 'movie': | |
row_xbmc = self.watchedmovielist_xbmc[i] | |
else: | |
row_xbmc = self.watchedepisodelist_xbmc[i] | |
lastplayed_xbmc = row_xbmc[3] | |
playcount_xbmc = row_xbmc[4] | |
change_xbmc_db = False | |
# check if movie/episode is set as unwatched in the wl database | |
if playcount_wl != playcount_xbmc and lastchange_wl > lastplayed_xbmc: | |
change_xbmc_db = True | |
# compare playcount and lastplayed (update if xbmc data is older) | |
if playcount_xbmc < playcount_wl or (lastplayed_xbmc < lastplayed_wl and playcount_wl > 0): | |
change_xbmc_db = True | |
if not change_xbmc_db: | |
if utils.getSetting("debug") == 'true': | |
# utils.log(u'write_xbmc_wdata: xbmc database up-to-date for tt%d, %s' % (imdbId, row_xbmc[2]), xbmc.LOGDEBUG) | |
pass | |
continue | |
# check if the lastplayed-timestamp in wl is useful | |
if playcount_wl == 0: | |
lastplayed_new = 0 | |
else: | |
if lastplayed_wl == 0: | |
lastplayed_new = lastplayed_xbmc | |
else: | |
lastplayed_new = lastplayed_wl | |
# update database | |
mediaid = row_xbmc[7] | |
if modus == 'movie': jsonmethod = "VideoLibrary.SetMovieDetails"; idfieldname = "movieid" | |
else: jsonmethod = "VideoLibrary.SetEpisodeDetails"; idfieldname = "episodeid" | |
jsondict = { | |
"jsonrpc": "2.0", | |
"method": jsonmethod, | |
"params": {idfieldname: mediaid, "playcount": playcount_wl, "lastplayed": utils.TimeStamptosqlDateTime(lastplayed_new)}, | |
"id": 1 | |
} | |
json_response = utils.executeJSON(jsondict) | |
if (json_response.has_key('result') and json_response['result'] == 'OK'): | |
utils.log(u'write_xbmc_wdata: xbmc database updated for %s. playcount: {%d -> %d}, lastplayed: {"%s" -> "%s"} (%sid=%d)' % (name, playcount_xbmc, playcount_wl, utils.TimeStamptosqlDateTime(lastplayed_xbmc), utils.TimeStamptosqlDateTime(lastplayed_new), modus, mediaid), xbmc.LOGINFO) | |
if utils.getSetting("debug") == 'true': | |
if playcount_wl == 0: | |
if notifications > 0: utils.showNotification(utils.getString(32404), name) | |
else: | |
if notifications > 0: utils.showNotification(utils.getString(32401), name) | |
count_update += 1 | |
# update the xbmc-db-mirror-variable | |
if modus == 'movie': | |
self.watchedmovielist_xbmc[i][3] = lastplayed_new | |
self.watchedmovielist_xbmc[i][4] = playcount_wl | |
else: | |
self.watchedepisodelist_xbmc[i][3] = lastplayed_new | |
self.watchedepisodelist_xbmc[i][4] = playcount_wl | |
else: | |
utils.log(u'write_xbmc_wdata: error updating xbmc database. %s. json_response=%s' % (name, str(json_response)), xbmc.LOGERROR) | |
else: | |
# the movie is in the watched-list but not in the xbmc-list -> no action | |
# utils.log(u'write_xbmc_wdata: movie not in xbmc database: tt%d, %s' % (imdbId, row_xbmc[2]), xbmc.LOGDEBUG) | |
continue | |
except: | |
utils.log(u"write_xbmc_wdata: Error while updating %s %s: %s" % (modus, name, sys.exc_info()[2]), xbmc.LOGERROR) | |
if progressdialogue: DIALOG_PROGRESS.close() | |
buggalo.addExtraData('count_update', count_update); | |
buggalo.onExceptionRaised() | |
return 1 | |
if progressdialogue: DIALOG_PROGRESS.close() | |
if notifications > 1: | |
if modus == 'movie': strno = [32204, 32302] | |
else: strno = [32205, 32303]; | |
utils.showNotification(utils.getString(strno[0]), utils.getString(strno[1])%(count_update)) | |
return 0 | |
# create a copy of the database, in case something goes wrong (only if database file is used) | |
def database_copy(self): | |
# return codes: | |
# 0 successfully copied database | |
# 1 file writing error | |
# 2 program exception | |
if utils.getSetting("db_format") != 0: | |
return 0 # no backup needed since we are using mysql database | |
if utils.getSetting('dbbackup') == 'false': | |
return 0 # no backup requested in the addon settings | |
if not self.dbcopydone: | |
if not xbmcvfs.exists(self.dbpath): | |
utils.log(u'database_copy: directory %s does not exist. No backup possible.' % self.dbpath, xbmc.LOGERROR) | |
return 1 | |
now = datetime.datetime.now() | |
timestr = u'%04d%02d%02d_%02d%02d%02d' % (now.year, now.month, now.day, now.hour, now.minute, now.second) | |
zipfilename = os.path.join(self.dbdirectory, utils.decode(timestr + u'-watchedlist.db.zip')) | |
zf = False | |
try: | |
zf = zipfile.ZipFile(zipfilename, 'w') | |
zf.write(self.dbpath, compress_type=zipfile.ZIP_DEFLATED) | |
zf.close() | |
self.dbcopydone = True | |
utils.log(u'database_copy: database backup copy created to %s' % zipfilename, xbmc.LOGINFO) | |
# copy the zip file with xbmc file system, if needed | |
if self.dbfileaccess == 'copy': | |
xbmcvfs.copy(zipfilename, os.path.join(self.dbdirectory_copy, utils.decode(timestr + u'-watchedlist.db.zip'))) | |
xbmcvfs.delete(zipfilename) | |
return 0 | |
except: | |
if zf: | |
zf.close() | |
buggalo.addExtraData('zipfilename', zipfilename); | |
buggalo.onExceptionRaised() | |
return 2 | |
# check if the user made changes in the watched states. Especially setting movies as "not watched". This can not be | |
# recognized by the functions above | |
def watch_user_changes(self, idletime_old, idletime): | |
# return codes: Not defined | |
if xbmc.Player().isPlaying() == True: | |
return | |
if idletime > idletime_old: | |
# the idle time increased. No user interaction probably happened | |
return | |
utils.log(u'watch_user_changes: Check for user changes (no. %d)' % self.watch_user_changes_count, xbmc.LOGDEBUG) | |
self.watch_user_changes_count = self.watch_user_changes_count + 1 | |
# save previous state | |
old_watchedmovielist_xbmc = self.watchedmovielist_xbmc | |
old_watchedepisodelist_xbmc = self.watchedepisodelist_xbmc | |
# get new state | |
self.get_watched_xbmc(1) | |
#save exception information | |
buggalo.addExtraData('len_old_watchedmovielist_xbmc', len(old_watchedmovielist_xbmc)) | |
buggalo.addExtraData('len_old_watchedepisodelist_xbmc', len(old_watchedepisodelist_xbmc)) | |
buggalo.addExtraData('len_self_watchedmovielist_xbmc', len(self.watchedmovielist_xbmc)) | |
buggalo.addExtraData('len_self_watchedepisodelist_xbmc', len(self.watchedepisodelist_xbmc)) | |
# separate the change detection and the change in the database to prevent circle reference | |
indices_changed = list([]) | |
# compare states of movies/episodes | |
for modus in ['movie', 'episode']: | |
buggalo.addExtraData('modus', modus); | |
if modus == 'movie' and utils.getSetting("w_movies") != 'true': | |
continue | |
if modus == 'episode' and utils.getSetting("w_episodes") != 'true': | |
continue | |
if modus == 'movie': | |
list_new = self.watchedmovielist_xbmc | |
list_old = old_watchedmovielist_xbmc | |
else: | |
list_new = self.watchedepisodelist_xbmc | |
list_old = old_watchedepisodelist_xbmc | |
if len(list_old) == 0 or len(list_new) == 0: | |
# one of the lists is empty: nothing to compare. No user changes noticable | |
continue | |
for i_n, row_xbmc in enumerate(list_new): | |
if xbmc.abortRequested: return | |
mediaid = row_xbmc[7] | |
lastplayed_new = row_xbmc[3] | |
playcount_new = row_xbmc[4] | |
# index of this movie/episode in the old database (before the change by the user) | |
if (len(list_old) > i_n) and (list_old[i_n][7] == mediaid): i_o = i_n # db did not change | |
else: # search the movieid | |
i_o = [i for i, x in enumerate(list_old) if x[7] == mediaid] | |
if len(i_o) == 0: continue #movie is not in old array | |
i_o = i_o[0] # convert list to int | |
lastplayed_old = list_old[i_o][3] | |
playcount_old = list_old[i_o][4] | |
if playcount_new != playcount_old or lastplayed_new != lastplayed_old: | |
if playcount_new == playcount_old and playcount_new == 0: | |
continue # do not add lastplayed to database, when placount = 0 | |
# The user changed the playcount or lastplayed. | |
# update wl with new watched state | |
indices_changed.append([i_n, i_o, row_xbmc]) | |
# go through all movies changed by the user | |
for icx in indices_changed: | |
if xbmc.abortRequested: return 1 | |
i_o = icx[1]; row_xbmc = icx[2] | |
i_n = icx[0]; | |
lastplayed_old = list_old[i_o][3]; playcount_old = list_old[i_o][4]; | |
lastplayed_new = row_xbmc[3]; playcount_new = row_xbmc[4]; mediaid = row_xbmc[7] | |
utils.log(u'watch_user_changes: %s "%s" changed playcount {%d -> %d} lastplayed {"%s" -> "%s"}. %sid=%d' % (modus, row_xbmc[5], playcount_old, playcount_new, utils.TimeStamptosqlDateTime(lastplayed_old), utils.TimeStamptosqlDateTime(lastplayed_new), modus, mediaid)) | |
try: | |
self.wl_update_media(modus, row_xbmc, 1, 1) | |
except sqlite3.Error as e: | |
try: | |
errstring = e.args[0] # TODO: Find out, why this does not work some times | |
except: | |
errstring = '' | |
utils.log(u'write_wl_wdata: SQLite Database error (%s) while updating %s %s' % (errstring, modus, row_xbmc[5])) | |
if utils.getSetting("debug") == 'true': | |
utils.showNotification(utils.getString(32102), utils.getString(32606) % ('(%s)' % errstring)) | |
# error because of db locked or similar error | |
self.close_db() | |
break | |
except mysql.connector.Error as err: | |
# Catch common mysql errors and show them to guide the user | |
utils.log(u'write_wl_wdata: MySQL Database error (%s) while updating %s %s' % (err, modus, row_xbmc[5])) | |
if utils.getSetting("debug") == 'true': | |
utils.showNotification(utils.getString(32102), utils.getString(32606) % ('(%s)' % err)) | |
self.close_db() | |
break | |
# update xbmc watched status, e.g. to set duplicate movies also as watched | |
if len(indices_changed) > 0: | |
self.write_xbmc_wdata(0, 1) # this changes self.watchedmovielist_xbmc | |
self.close_db() # keep the db closed most of the time (no access problems) | |
# update the wl database for one movie/episode with the information in row_xbmc. | |
# Use saveanyway to skip checks whether not to save the changes. With commit, the db change is committed directly (slow with many movies, but safe) | |
def wl_update_media(self, mediatype, row_xbmc, saveanyway, commit): | |
# return codes: | |
# 2 error loading database | |
buggalo.addExtraData('self_sqlcursor', self.sqlcursor); buggalo.addExtraData('self_sqlcon', self.sqlcon); | |
buggalo.addExtraData('len_self_watchedmovielist_wl', len(self.watchedmovielist_wl)) | |
buggalo.addExtraData('len_self_watchedepisodelist_wl', len(self.watchedepisodelist_wl)) | |
buggalo.addExtraData('len_self_tvshownames', len(self.tvshownames)) | |
buggalo.addExtraData('row_xbmc', row_xbmc) | |
buggalo.addExtraData('saveanyway', saveanyway) | |
if self.sqlcursor == 0 or self.sqlcon == 0: | |
if self.load_db(): | |
return 2 | |
for modus in [mediatype]: | |
buggalo.addExtraData('modus', modus) | |
# row_xbmc: 0imdbnumber, 1empty, 2empty, 3lastPlayed, 4playCount, 5title, 6empty, 7movieid | |
imdbId = row_xbmc[0] | |
lastplayed_xbmc = row_xbmc[3] | |
playcount_xbmc = row_xbmc[4] | |
name = row_xbmc[5] | |
if modus == 'episode': | |
season = row_xbmc[1] | |
episode = row_xbmc[2] | |
count_return = list([0, 0]) | |
self.database_copy() | |
if self.sqlcursor == 0 or self.sqlcon == 0: | |
if self.load_db(): | |
return count_return | |
if not saveanyway and playcount_xbmc == 0: | |
# playcount in xbmc-list is empty. Nothing to save | |
if utils.getSetting("debug") == 'true': | |
# utils.log(u'wl_update_%s: not watched in xbmc: tt%d, %s' % (modus, imdbId, name), xbmc.LOGDEBUG) | |
pass | |
return count_return | |
if modus == 'movie': | |
j = [ii for ii, x in enumerate(self.watchedmovielist_wl) if x[0] == imdbId] | |
if modus == 'episode': | |
j = [ii for ii, x in enumerate(self.watchedepisodelist_wl) if x[0] == imdbId and x[1] == season and x[2] == episode] | |
if len(j) > 0: | |
j = j[0] # there can only be one valid index j, since only one entry in wl per imdbId | |
# the movie is already in the watched-list | |
if modus == 'movie': | |
row_wl = self.watchedmovielist_wl[j] | |
else: | |
row_wl = self.watchedepisodelist_wl[j] | |
lastplayed_wl = row_wl[3] | |
playcount_wl = row_wl[4] | |
lastchange_wl = row_wl[6] | |
if not saveanyway: | |
# compare playcount and lastplayed | |
# check if an update of the wl database is necessary (xbmc watched status newer) | |
if lastchange_wl > lastplayed_xbmc: | |
return count_return | |
if playcount_wl >= playcount_xbmc and lastplayed_wl >= lastplayed_xbmc: | |
if utils.getSetting("debug") == 'true': | |
# utils.log(u'wl_update_movie: wl database up-to-date for movie tt%d, %s' % (imdbId, moviename), xbmc.LOGDEBUG) | |
pass | |
return count_return | |
# check if the lastplayed-timestamp in xbmc is useful | |
if lastplayed_xbmc == 0: | |
lastplayed_new = lastplayed_wl | |
else: | |
lastplayed_new = lastplayed_xbmc | |
else: | |
lastplayed_new = lastplayed_xbmc | |
lastchange_new = int(time.time()) | |
if modus == 'movie': | |
#if utils.getSetting("db_format") == 0: # sqlite3 | |
if True: # sqlite3 | |
sql = 'UPDATE movie_watched SET playCount = ?, lastplayed = ?, lastChange = ? WHERE idMovieImdb LIKE ?' | |
else: # mysql | |
sql = 'UPDATE movie_watched SET playCount = %s, lastplayed = %s, lastChange = FROM_UNIXTIME(%s) WHERE idMovieImdb LIKE %s' | |
values = list([playcount_xbmc, lastplayed_new, lastchange_new, imdbId]) | |
else: | |
#if utils.getSetting("db_format") == 0: # sqlite3 | |
if True: # sqlite3 | |
sql = 'UPDATE episode_watched SET playCount = ?, lastPlayed = ?, lastChange = ? WHERE idShow LIKE ? AND season LIKE ? AND episode LIKE ?' | |
else: # mysql | |
sql = 'UPDATE episode_watched SET playCount = %s, lastPlayed = FROM_UNIXTIME(%s), lastChange = FROM_UNIXTIME(%s) WHERE idShow LIKE %s AND season LIKE %s AND episode LIKE %s' | |
values = list([playcount_xbmc, lastplayed_new, lastchange_new, imdbId, season, episode]) | |
self.sqlcursor.execute(sql, values) | |
count_return[1] = 1 | |
# update the local mirror variable of the wl database: # 0imdbnumber, season, episode, 3lastPlayed, 4playCount, 5title, 6lastChange | |
if modus == 'movie': | |
self.watchedmovielist_wl[j] = list([imdbId, 0, 0, lastplayed_new, playcount_xbmc, name, lastchange_new]) | |
else: | |
self.watchedepisodelist_wl[j] = list([imdbId, season, episode, lastplayed_new, playcount_xbmc, name, lastchange_new]) | |
if utils.getSetting("debug") == 'true': | |
utils.log(u'wl_update_%s: updated wl db for "%s" (tt%d). playcount: {%d -> %d}. lastplayed: {"%s" -> "%s"}. lastchange: "%s"' % (modus, name, imdbId, playcount_wl, playcount_xbmc, utils.TimeStamptosqlDateTime(lastplayed_wl), utils.TimeStamptosqlDateTime(lastplayed_new), utils.TimeStamptosqlDateTime(lastchange_new))) | |
if playcount_xbmc > 0: | |
utils.showNotification(utils.getString(32403), name) | |
else: | |
utils.showNotification(utils.getString(32405), name) | |
else: | |
# the movie is not in the watched-list -> insert the movie | |
# order: idMovieImdb,playCount,lastChange,lastPlayed,title | |
lastchange_new = int(time.time()) | |
if modus == 'movie': | |
#if utils.getSetting("db_format") == 0: # sqlite3 | |
if True: # sqlite3 | |
sql = 'INSERT INTO movie_watched (idMovieImdb,playCount,lastChange,lastPlayed,title) VALUES (?, ?, ?, ?, ?)' | |
else: # mysql | |
sql = 'INSERT INTO movie_watched (idMovieImdb,playCount,lastChange,lastPlayed,title) VALUES (%s, %s, FROM_UNIXTIME(%s), FROM_UNIXTIME(%s), %s)' | |
values = list([imdbId, playcount_xbmc, lastchange_new, lastplayed_xbmc, name]) | |
else: | |
#if utils.getSetting("db_format") == 0: # sqlite3 | |
if True: # sqlite3 | |
sql = 'INSERT INTO episode_watched (idShow,season,episode,playCount,lastChange,lastPlayed) VALUES (?, ?, ?, ?, ?, ?)' | |
else: # mysql | |
sql = 'INSERT INTO episode_watched (idShow,season,episode,playCount,lastChange,lastPlayed) VALUES (%s, %s, %s, %s, FROM_UNIXTIME(%s), FROM_UNIXTIME(%s))' | |
values = list([imdbId, season, episode, playcount_xbmc, lastchange_new, lastplayed_xbmc]) | |
self.sqlcursor.execute(sql, values) | |
utils.log(u'wl_update_%s: new entry for wl database: "%s", lastChange="%s", lastPlayed="%s", playCount=%d' % (modus, name, utils.TimeStamptosqlDateTime(lastchange_new), utils.TimeStamptosqlDateTime(lastplayed_xbmc), playcount_xbmc)) | |
count_return[0] = 1 | |
# update the local mirror variable of the wl database | |
if modus == 'movie': | |
self.watchedmovielist_wl.append(list([imdbId, 0, 0, lastplayed_xbmc, playcount_xbmc, name, lastchange_new])) | |
else: | |
self.watchedepisodelist_wl.append(list([imdbId, season, episode, lastplayed_xbmc, playcount_xbmc, name, lastchange_new])) | |
if utils.getSetting("debug") == 'true': | |
if playcount_xbmc > 0: | |
utils.showNotification(utils.getString(32402), name) | |
else: | |
utils.showNotification(utils.getString(32405), name) | |
if commit: | |
self.sqlcon.commit() | |
return count_return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment