def sendRating(self, items): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'FILMWEB') return item_count = len(items) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for item in items: # bar item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update( p, str(item_added) + ' / ' + str(item_count) + ' - ' + item['title']) # search id if item['mType'] == 'movie': id = self.searchMovieID(item) self.prepareRequest(id, item['new_rating']) if bar.iscanceled(): bar.close() return bar.close() debug.debug('Rate sended to Filmweb') debug.notify(self.login + ' - ' + __lang__(32101), False, 'Filmweb')
def start(self): # clear property for auto close menu xbmcgui.Window(10000).clearProperty(__addon_id__ + '_autoclose') # open sync dialog if no parameter if (len(sys.argv) == 0 or len(sys.argv[0]) == 0): import menu menu.MENU().start() return # get id and type from service try: id = sys.argv[1] type = sys.argv[2] except: return # get movie link import searchLink link = searchLink.LINK().start(id, type) debug.debug(str(link)) if link is None: debug.notify(__lang__(32110)) return # prepare users import dialog accounts = function.readAccounts() xbmcgui.Window(10000).setProperty(__addon_id__ + '_autoclose', '1' if 'true' in __addon__.getSetting('autoclose') else '0') for user in accounts.values(): ret = dialog.DIALOG().start('script-facebook-watching-now-menu.xml', labels={10030: user['name']}, buttons=[__lang__(32100)], list=10040) if ret is not None: self.prepare(user, link)
def sendRating(self, items): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'FILMWEB') return item_count = len(items) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for item in items: # bar item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update(p, str(item_added) + ' / ' + str(item_count) + ' - ' + item['title']) # search id if item['mType'] == 'movie': id = self.searchMovieID(item) self.prepareRequest(id, item['new_rating']) if bar.iscanceled(): bar.close() return bar.close() debug.debug('Rate sended to Filmweb') debug.notify(self.login + ' - ' + __lang__(32101), False, 'Filmweb')
def getRated(self, type): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TMDB') return rated = {} ret = self.sendRequest('getUserFilmVotes [null, null]\n'.encode('string_escape'), 'GET') matches = re.findall('\[([0-9]+),[^,]+,([0-9]+),', ret) if len(matches) > 0: for m in matches: rated[m[0]] = int(m[1]) # transform tmdb ids to KODI DB ids kodiID = {} if 'movie' in type: jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "imdbnumber", "art", "trailer"]}, "id": 1}') jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'movies' in jsonGet['result']: for m in jsonGet['result']['movies']: patterns = [ 'fwcdn.pl/po/[^/]+/[^/]+/([0-9]+)/', 'fwcdn.pl/ph/[^/]+/[^/]+/([0-9]+)/', 'http://mm.filmweb.pl/([0-9]+)/' ] for pattern in patterns: filmweb_search = re.search(pattern, urllib.unquote(str(m))) if filmweb_search is not None: filmweb_id = filmweb_search.group(1) if filmweb_id in rated.keys(): kodiID[m['movieid']] = {'title': m['title'], 'rating': rated[filmweb_id]} break return kodiID
def add(self, videosXBMC, videoToAdd, table, opt): # init progres bar addedCount = 0 countToAdd = len(videoToAdd) self.progBar.create(__lang__(32200), __addonname__ + ', ' + __lang__(32204 if opt == 'add' else 32209) + ' ' + __lang__(self.lang[table])) for video in videoToAdd: start_time = time.time() # progress bar update p = int((float(100) / float(countToAdd)) * float(addedCount)) progYear = ' (' + str(videosXBMC[table][video]['year']) + ')' if 'year' in videosXBMC[table][video] else '' self.progBar.update(p, str(addedCount + 1) + '/' + str(countToAdd) + ' - ' + videosXBMC[table][video]['title'] + progYear) # get values values = prepareValues.prep(self, videosXBMC[table][video], table) # send requst to post new Video if sendRequest.postAddVideo(self, values) is False: return False else: addedCount += 1 debug.debug('[TIME]: ' + str(time.time() - start_time)[0:5]) if addedCount > 0: debug.notify(__lang__(32104 if opt == 'add' else 32103).encode('utf-8') + ' ' + __lang__(self.lang[table]).encode('utf-8') + ': ' + str(addedCount))
def saveRatings(self, toUpdate, type): item_count = len(toUpdate.keys()) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for id, data in toUpdate.items(): item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update( p, str(item_added) + ' / ' + str(item_count) + ' - ' + data['title']) jsonGet = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "VideoLibrary.Set' + type.title() + 'Details", "params": {"' + type + 'id": ' + str(id) + ', "userrating": ' + str(data['rating']) + '}, "id": 1}') if bar.iscanceled(): break debug.notify( __lang__(32144) + ' ' + str(item_added) + ' ' + __lang__(32128)) bar.close()
def start(self, mode): xbmcgui.Window(10000).clearProperty(ADDON_ID + '_autoclose') # check is profiles is set if 'true' not in sProfile.values(): debug.notify(ADDON_LANG(32105)) xbmcaddon.Addon(id=ADDON_ID).openSettings() if mode is False: self.save() return if mode == 'service': enabledProfiles = self.getEnabledProfiles() xbmcgui.Window(10000).setProperty(ADDON_ID + '_autoclose', '1' if 'true' in ADDON.getSetting('player_autoclose') else '0') ret = dialog.DIALOG().start('script-audio-profiles-menu.xml', labels={10071: ADDON_LANG(32106)}, buttons=enabledProfiles[1], list=10070) if ret is not None: self.profile(str(enabledProfiles[0][ret])) return if mode == '0' or mode == '1' or mode == '2' or mode == '3' or mode == '4': if self.check(mode) is False: return if mode == '0': self.toggle(mode) else: self.profile(mode) return debug.debug('Wrong arg, use like RunScript("' + ADDON_ID + ',x") x - number of profile')
def removeImg(self, ImagesToRemove): # removing images toRemove = {} removedCount = 0 for type, vals in ImagesToRemove.items(): for img_type, v in vals.items(): if len(v) > 0: debug.debug('=== REMOVING ' + type.upper() + ' ' + img_type.upper() + ' IMAGES ===') for file in v: if 'poster' == img_type: toRemove[removedCount] = type + '_' + str( file) + '.jpg' if 'fanart' == img_type: toRemove[removedCount] = type + '_' + str( file) + '_f.jpg' if 'thumb' == img_type: toRemove[removedCount] = 'actors/' + str(file) + '.jpg' if 'exthumb' == img_type: toRemove[removedCount] = type + '_' + str( file) + '.jpg' removedCount += 1 toRemove[removedCount] = type + '_' + str( file) + 'm.jpg' removedCount += 1 if len(toRemove) > 0: if sendRequest.send(self, 'removeimages', toRemove) is False: return False debug.notify( __lang__(32105).encode('utf-8') + ' ' + __lang__(32121).encode('utf-8') + ': ' + str(removedCount))
def start(self): self.bar = xbmcgui.DialogProgress() self.bar.create(__lang__(32130), __lang__(32131) + '...') # generate random key key = self.generateKEY() # init auth with random key ret = function.sendRequest(AUTH_URL, '', get={ 'option': 'init', 'key': key }) if ret is False or 'init' not in ret or 'ok' not in ret['init']: self.bar.close() debug.notify(__lang__(32132), True) return None # wait for authenticate self.bar.update( 25, __lang__(32133), __lang__(32134) + ' ' + AUTH_URL + ' ' + __lang__(32135) + ' ' + key, __lang__(32136) + '...') token = self.checkForResponse(key) if token is None: debug.notify(__lang__(32137), True) self.bar.close() return token
def sendRating(self, items): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TMDB') return item_count = len(items) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for item in items: # bar item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update( p, str(item_added) + ' / ' + str(item_count) + ' - ' + item['title']) # search id and send rate if item['mType'] == 'movie': id = self.searchMovieID(item) ret = self.prepareRequest(id, 'movie/' + str(id) + '/rating', item['new_rating']) if ret is False: bar.close() return False if item['mType'] == 'tvshow': id = self.searchTVshowID(item) ret = self.prepareRequest(id, 'tv/' + str(id) + '/rating', item['new_rating']) if ret is False: bar.close() return False if item['mType'] == 'episode': episodeData = self.searchEpisodeID(item) tvshowid = self.searchTVshowID( {'dbID': str(episodeData['tvshowid'])}) ret = self.prepareRequest( tvshowid, 'tv/' + str(tvshowid) + '/season/' + str(episodeData['season']) + '/episode/' + str(episodeData['episode']) + '/rating', item['new_rating']) if ret is False: bar.close() return False if bar.iscanceled(): bar.close() return bar.close() debug.debug('Rate sended to TMDB') debug.notify(self.login + ' - ' + __lang__(32101), False, 'TMDB')
def postAddVideo(self, values=''): # prevent go Kodi to suspend if xbmc.getGlobalIdleTime() > 120: xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Input.ExecuteAction", "params": { "action": "noop" }, "id": 1 }') url = self.setXBMC['RootURL'] + 'sync/movies' debug.debug('[REQUEST]: ' + url) debug.debug('[REQUEST]: ' + str(values)) # try send data data = urllib.urlencode(values, True) data_len = len(data) debug.debug('[REQUEST DATA SIZE]: ' + str(data_len) + ' bytes') for l in range(1, 4): try: request = urllib2.Request(url, data, headers = { 'token' : self.setXBMC['Token']}) result = urllib2.urlopen(request) output = result.read() except Exception as Error: conn = False debug.debug('Can\'t connect to: ' + url) debug.debug('[REQUEST ERROR]: ' + str(Error)) if l < 3: debug.debug('[REQUEST]: Wait 5 secs and retring ' + str(l)) time.sleep(15) else: conn = True break; if conn != True: debug.notify(__lang__(32100).encode('utf-8')) return False debug.debug('[RESPONSE]: ' + str(output)) # if no values return json if values == '': try: output = unicode(output, 'utf-8', errors='ignore') output = json.loads(output) except Exception as Error: debug.debug('[GET JSON ERROR]: ' + str(Error)) return False else: #get errors if len(output) > 0 and 'ERROR:' in output: debug.notify(__lang__(32102).encode('utf-8')) return False return output
def login(self): self.login = True self.cookie = '' api_method = 'login [' + self.userData['login'] + ',' + self.userData['pass'] + ',1]\n'.encode('string_escape') page = self.sendRequest(api_method, 'post') self.login = False if len(re.findall('^err', page)) > 0: debug.debug(self.userData['name'] + ' - Błędny login lub hasło') debug.notify(self.userData['name'] + ' - Błędny login lub hasło') return False
def prepareRequest(self, id, method, rating): if id == 0: debug.debug('No tmdb/imdb id found') debug.notify(__lang__(32102), True, 'TMDB') return # send rating if rating > 0: ret = self.sendRequest(method, 'POST', {'session_id': self.session_id}, {'value': rating}) else: ret = self.sendRequest(method, 'DELETE', {'session_id': self.session_id}) return ret
def prepareRequest(self, id, method, rating): if id == 0: debug.debug('No TVDB id found') debug.notify(__lang__(32102), True, 'TVDB') return # send rating if rating > 0: ret = self.sendRequest(method + str(id) + '/' + str(rating), 'PUT') else: ret = self.sendRequest(method + str(id), 'DELETE') if ret is not False: debug.debug('Rate sended to TVDB') debug.notify(self.login + ' - ' + __lang__(32101), False, 'TVDB')
def sendRating(self, items): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TMDB') return item_count = len(items) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for item in items: # bar item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update(p, str(item_added) + ' / ' + str(item_count) + ' - ' + item['title']) # search id and send rate if item['mType'] == 'movie': id = self.searchMovieID(item) ret = self.prepareRequest(id, 'movie/' + str(id) + '/rating', item['new_rating']) if ret is False: bar.close() return False if item['mType'] == 'tvshow': id = self.searchTVshowID(item) ret = self.prepareRequest(id, 'tv/' + str(id) + '/rating', item['new_rating']) if ret is False: bar.close() return False if item['mType'] == 'episode': episodeData = self.searchEpisodeID(item) tvshowid = self.searchTVshowID({'dbID': str(episodeData['tvshowid'])}) ret = self.prepareRequest(tvshowid, 'tv/' + str(tvshowid) + '/season/' + str(episodeData['season']) + '/episode/' + str(episodeData['episode']) + '/rating', item['new_rating']) if ret is False: bar.close() return False if bar.iscanceled(): bar.close() return bar.close() debug.debug('Rate sended to TMDB') debug.notify(self.login + ' - ' + __lang__(32101), False, 'TMDB')
def profile(self, profile): # read addon settings sVolume = ADDON.getSetting('volume') sPlayer = ADDON.getSetting('player') sVideo = ADDON.getSetting('video') # read settings from profile f = xbmcvfs.File(ADDON_PATH_DATA + 'profile' + profile + '.json', 'r') result = f.read() try: jsonResult = json.loads(result) f.close() except: debug.notify(ADDON_LANG(32104) + ' ' + profile + ' (' + sName[int(profile)] + ')') debug.debug('[LOAD JSON FROM FILE]: Error reading from profile - ' + str(profile)) return False # settings needed quote for value quote_needed = [ 'audiooutput.audiodevice', 'audiooutput.passthroughdevice', 'locale.audiolanguage' ] # set settings readed from profile file for setName, setValue in jsonResult.items(): # skip setting that type is disable to changing if 'false' in sPlayer and setName.startswith('videoplayer'): continue if 'false' in sVideo and setName.startswith('videoscreen'): continue debug.debug('[RESTORING SETTING]: ' + setName + ': ' + setValue) # add quotes if setName in quote_needed: setValue = '"' + setValue + '"' # set setting if 'true' in sVolume and setName == 'volume': xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": {"volume": ' + jsonResult['volume'] + '}, "id": 1}') else: xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Settings.SetSettingValue", "params": {"setting": "' + setName + '", "value": ' + setValue.encode('utf-8') + '}, "id": 1}') debug.notify(sName[int(profile)].decode('utf-8')) # write curent profile f = xbmcvfs.File(ADDON_PATH_DATA + 'profile', 'w') f.write(profile) f.close()
def start(self): # check if exists addon data folder if xbmcvfs.exists(__datapath__ + '/') == 0: xbmcvfs.mkdir(__datapath__ ) # open settings if frist run if xbmcvfs.exists(__datapath__ + '/settings.xml') == 0: __addon__.openSettings() # if start from porgram section by user force sync all data try: mode = str(sys.argv[1]) except: self.forcedStart = True debug.debug('=== FORCED START ===') else: self.forcedStart = False self.setXBMC = {} self.setXBMC['URL'] = __addon__.getSetting('url') self.setXBMC['Token'] = __addon__.getSetting('token') self.setXBMC['Notify'] = __addon__.getSetting('notify') self.setXBMC['Debug'] = __addon__.getSetting('debug') self.setXBMC['Auth'] = __addon__.getSetting('auth') self.setXBMC['AuthLogin'] = __addon__.getSetting('authLogin') self.setXBMC['AuthPass'] = __addon__.getSetting('authPass') self.versionWebScript = '2.8.0' self.progBar = bar.Bar() # debug settings for n, s in self.setXBMC.items(): debug.debug('XBMC: ' + n + ': ' + s) # notify if debugging is on if 'true' in self.setXBMC['Debug']: debug.notify(__lang__(32115).encode('utf-8')) # prepare URL if self.setXBMC['URL'][-1:] != '/': self.setXBMC['URL'] = self.setXBMC['URL'] + '/' if self.setXBMC['URL'][:7] != 'http://': self.setXBMC['URL'] = 'http://' + self.setXBMC['URL'] self.setXBMC['RootURL'] = self.setXBMC['URL'] + 'api/' check(self)
def remove(self, videoToRemove, table): removedCount = 0 # get values values = {} for video in videoToRemove: removedCount += 1 values[removedCount] = video # send requst if sendRequest.removeMovie(self, values) is False: return False if removedCount > 0: debug.notify(__lang__(32105).encode('utf-8') + ' ' + __lang__(self.lang[table]).encode('utf-8') + ': ' + str(removedCount))
def removeImg(self, ImagesToRemove): # removing images toRemove = {} removedCount = 0 for type, vals in ImagesToRemove.items(): for img_type, v in vals.items(): if len(v) > 0: debug.debug('=== REMOVING ' + type.upper() + ' ' + img_type.upper() + ' IMAGES ===') for file in v: if 'poster' == img_type: toRemove[removedCount] = type + '_' + str( file) + '.jpg' if 'fanart' == img_type: toRemove[removedCount] = type + '_' + str( file) + '_f.jpg' if 'thumb' == img_type: toRemove[removedCount] = 'actors/' + str(file) + '.jpg' if 'exthumb' == img_type: toRemove[removedCount] = type + '_' + str( file) + '.jpg' removedCount += 1 toRemove[removedCount] = type + '_' + str( file) + 'm.jpg' removedCount += 1 if len(toRemove) > 0: if sendRequest.send(self, 'removeimages', toRemove) is False: return False debug.notify( __lang__(32105).encode('utf-8') + ' ' + __lang__(32121).encode('utf-8') + ': ' + str(removedCount)) ImagesToRemove = {} for v_type in ImagesXBMC.keys(): ImagesToRemove[v_type] = {} for img_type in ImagesXBMC[v_type].keys(): ImagesToRemove[v_type][img_type] = set( ImagesSite[v_type][img_type]) - set( ImagesXBMC[v_type][img_type].keys()) debug.debug('[ImagesToRemove]: ' + str(ImagesToRemove)) removeImg(self, ImagesToRemove) # update hash value = {'images': str(hashImagesXBMC)} if sendRequest.send(self, 'updatehash', value) is False: return False
def check(self, mode): # check profile config self.aProfile = [] # stop if selected (mode) profile are disabled if mode != '0' and 'false' in sProfile[int(mode)]: debug.notify(ADDON_LANG(32103) + ' (' + sName[int(mode)] + ')') debug.debug('[CHECK]: This profile is dosabled in addon settings - ' + str(mode)) return False # check if profile have settings file for key in sProfile: if 'true' in sProfile[key]: if not xbmcvfs.exists(ADDON_PATH_DATA + 'profile' + str(key) + '.json'): debug.notify(ADDON_LANG(32101) + ' ' + str(key) + ' (' + sName[key] + ')') debug.debug('[PROFILE FILE]: not exist for profile - ' + str(key)) return False self.aProfile.append(str(key))
def saveRatings(self, toUpdate, type): item_count = len(toUpdate.keys()) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for id, data in toUpdate.items(): item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update(p, str(item_added) + ' / ' + str(item_count) + ' - ' + data['title']) jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.Set' + type.title() + 'Details", "params": {"' + type + 'id": ' + str(id) + ', "userrating": ' + str(data['rating']) + '}, "id": 1}') if bar.iscanceled(): break debug.notify(__lang__(32144) + ' ' + str(item_added) + ' ' + __lang__(32128)) bar.close()
def remove(self, videoToRemove, table): removedCount = 0 # get values values = {} for video in videoToRemove: removedCount += 1 values[removedCount] = video # send requst if sendRequest.send(self, 'removevideo&t=' + table, values) is False: return False if removedCount > 0: debug.notify( __lang__(32105).encode('utf-8') + ' ' + __lang__(self.lang[table]).encode('utf-8') + ': ' + str(removedCount))
def prepareRequest(self, id, rating): if id == 0: debug.debug('No filmweb id found') debug.notify(__lang__(32102), True, 'FILMWEB') return # send rating date = datetime.datetime.now().strftime('%Y-%m-%d') if rating > 0: method = 'addUserFilmVote [[' + str(id) + ',' + str(rating) + ',"",0]]\nupdateUserFilmVoteDate [' + str(id) + ', ' + date + ']\n'.encode('string_escape') else: method = 'removeUserFilmVote [' + str(id) + ']\n'.encode('string_escape') ret = self.sendRequest(method, 'POST') if ret is not False and re.search('^err', ret) is None: debug.debug('Rate sended to FILMWEB') debug.notify(self.login + ' - ' + __lang__(32101), False, 'FILMWEB')
def sendRating(self, items): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TVDB') return item_count = len(items) item_added = 0 bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') for item in items: # bar item_added += 1 p = int((float(100) / float(item_count)) * float(item_added)) bar.update(p, str(item_added) + ' / ' + str(item_count) + ' - ' + item['title']) # search id if item['mType'] == 'tvshow': id = self.searchTVshowID(item) self.prepareRequest(id, 'user/ratings/series/', item['new_rating']) if item['mType'] == 'episode': episodeData = self.searchEpisodeID(item) tvshowid = self.searchTVshowID({'dbID': str(episodeData['tvshowid'])}) ret = self.sendRequest('series/' + tvshowid + '/episodes/query', 'GET', get={'airedSeason': str(episodeData['season']), 'airedEpisode': str(episodeData['episode'])}) if 'data' in ret and len(ret['data']) == 1 and 'id' in ret['data'][0]: id = ret['data'][0]['id'] else: id = 0 self.prepareRequest(id, 'user/ratings/episode/', item['new_rating']) if bar.iscanceled(): bar.close() return bar.close() debug.debug('Rate sended to TVDB') debug.notify(self.login + ' - ' + __lang__(32101), False, 'TVDB')
def getRated(self, type): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TMDB') return rated = {} ret = self.sendRequest( 'getUserFilmVotes [null, null]\n'.encode('string_escape'), 'GET') matches = re.findall('\[([0-9]+),[^,]+,([0-9]+),', ret) if len(matches) > 0: for m in matches: rated[m[0]] = int(m[1]) # transform tmdb ids to KODI DB ids kodiID = {} if 'movie' in type: jsonGet = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "imdbnumber", "art", "trailer"]}, "id": 1}' ) jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'movies' in jsonGet['result']: for m in jsonGet['result']['movies']: patterns = [ 'fwcdn.pl/po/[^/]+/[^/]+/([0-9]+)/', 'fwcdn.pl/ph/[^/]+/[^/]+/([0-9]+)/', 'http://mm.filmweb.pl/([0-9]+)/' ] for pattern in patterns: filmweb_search = re.search(pattern, urllib.unquote(str(m))) if filmweb_search is not None: filmweb_id = filmweb_search.group(1) if filmweb_id in rated.keys(): kodiID[m['movieid']] = { 'title': m['title'], 'rating': rated[filmweb_id] } break return kodiID
def add(self, videosXBMC, videoToAdd, table, opt): # init progres bar addedCount = 0 countToAdd = len(videoToAdd) self.progBar.create( __lang__(32200), __addonname__ + ', ' + __lang__(32204 if opt == 'add' else 32209) + ' ' + __lang__(self.lang[table])) for video in videoToAdd: start_time = time.time() # progress bar update p = int((float(100) / float(countToAdd)) * float(addedCount)) progYear = ' (' + str( videosXBMC[table][video] ['year']) + ')' if 'year' in videosXBMC[table][video] else '' self.progBar.update( p, str(addedCount + 1) + '/' + str(countToAdd) + ' - ' + videosXBMC[table][video]['title'] + progYear) # get values values = prepareValues.prep(self, videosXBMC[table][video], table) # send requst if sendRequest.send(self, opt + 'video&t=' + table, values) is False: return False else: addedCount += 1 debug.debug('[TIME]: ' + str(time.time() - start_time)[0:5]) if addedCount > 0: debug.notify( __lang__(32104 if opt == 'add' else 32103).encode('utf-8') + ' ' + __lang__(self.lang[table]).encode('utf-8') + ': ' + str(addedCount))
def sendRequest(self, api_method, http_method): values = { 'methods': api_method, 'signature': self.create_sig(api_method), 'appId': API_ID, 'version': API_VER } data = urllib.urlencode(values) if 'get' in http_method: req = urllib2.Request(API_URL + '?' + data) else: req = urllib2.Request(API_URL, data) req.add_header('cookie', self.cookie) try: response = urllib2.urlopen(req) except: debug.notify('Błąd połaczenia') if self.login == True: self.cookie = response.headers.get('Set-Cookie') page = response.read() debug.debug('Odpowiedź z serwera - ' + page) return page
def prepareRequest(self, id, rating): if id == 0: debug.debug('No filmweb id found') debug.notify(__lang__(32102), True, 'FILMWEB') return # send rating date = datetime.datetime.now().strftime('%Y-%m-%d') if rating > 0: method = 'addUserFilmVote [[' + str(id) + ',' + str( rating) + ',"",0]]\nupdateUserFilmVoteDate [' + str( id) + ', ' + date + ']\n'.encode('string_escape') else: method = 'removeUserFilmVote [' + str(id) + ']\n'.encode( 'string_escape') ret = self.sendRequest(method, 'POST') if ret is not False and re.search('^err', ret) is None: debug.debug('Rate sended to FILMWEB') debug.notify(self.login + ' - ' + __lang__(32101), False, 'FILMWEB')
def start(self, mode): xbmcgui.Window(10000).clearProperty(ADDON_ID + '_autoclose') # check is profiles is set if 'true' not in sProfile.values(): debug.notify(ADDON_LANG(32105)) xbmcaddon.Addon(id=ADDON_ID).openSettings() if mode is False: self.save() return if mode == 'popup': enabledProfiles = self.getEnabledProfiles() xbmcgui.Window(10000).setProperty( ADDON_ID + '_autoclose', '1' if 'true' in ADDON.getSetting('player_autoclose') else '0') ret = dialog.DIALOG().start('script-audio-profiles-menu.xml', labels={10071: ADDON_LANG(32106)}, buttons=enabledProfiles[1], list=10070) if ret is not None: self.profile(str(enabledProfiles[0][ret])) return if mode == '0' or mode == '1' or mode == '2' or mode == '3' or mode == '4': if self.check(mode) is False: return if mode == '0': self.toggle(mode) else: self.profile(mode) return debug.error('Wrong arg, use like RunScript("' + ADDON_ID + ',x") x - number of profile')
def prepare(self, user, link): token = user['token'] # check token ret = function.sendRequest(API_URL, '/me', get={'access_token': token}) if ret is False: debug.notify(__lang__(32111), True) import auth token = auth.AUTH().start() if token is None: debug.notify(__lang__(32112), True) return ret = self.sendAction(token, link) if ret is False: debug.notify(__lang__(32113), True) else: debug.notify(__lang__(32114))
def check(self, mode): # check profile config self.aProfile = [] # stop if selected (mode) profile are disabled if mode != '0' and 'false' in sProfile[int(mode)]: debug.notify(ADDON_LANG(32103) + ' (' + sName[int(mode)] + ')') debug.notice( '[CHECK]: This profile is disabled in addon settings - ' + str(mode)) return False # check if profile have settings file for key in sProfile: if 'true' in sProfile[key]: if not xbmcvfs.exists(ADDON_PATH_DATA + 'profile' + str(key) + '.json'): debug.notify( ADDON_LANG(32101) + ' ' + str(key) + ' (' + sName[key] + ')') debug.error('[PROFILE FILE]: not exist for profile - ' + str(key)) return False self.aProfile.append(str(key))
def syncSITEtoKODI(self, type, site): if 'tmdb' in site: import tmdb siteClass = tmdb.TMDB(True) siteLabel = 'TMDB' if 'tvdb' in site: import tvdb siteClass = tvdb.TVDB(True) siteLabel = 'TVDB' if 'filmweb' in site: import filmweb siteClass = filmweb.FILMWEB(True) siteLabel = 'FILMWEB' # set bar bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') bar.update(50, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' ' + siteLabel) # get rated from SITE SITErated = siteClass.getRated(type) debug.debug(siteLabel + 'rated' + type.title() + 's: ' + str(SITErated)) if SITErated is False: bar.close() debug.notify(__lang__(32141)) return if len(SITErated) == 0: bar.close() debug.notify(__lang__(32126) + ' ' + __LANGTYPE__[type + 's']) return if bar.iscanceled(): bar.close() return bar.update(100, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' KODI') # get rated from KODI KODIrated = self.getRatedKODI(type) debug.debug('KODIrated' + type.title() + 's: ' + str(KODIrated)) bar.close() # check for existed ratings SITEratedExistRate = {} SITEratedNotexistRate = {} for key, item in SITErated.items(): if key in KODIrated.keys(): SITEratedExistRate[key] = item else: SITEratedNotexistRate[key] = item # prepare labels for not existed ratings labels_title = __lang__(32128) + ' (' + str(len(SITEratedNotexistRate)) + ') ' + __lang__(32131) + ':\r\n' for id, data in SITEratedNotexistRate.items(): labels_title = labels_title + '[COLOR=green]>>[/COLOR] ' labels_title = labels_title + data['title'] + ' (' + __lang__(32132) + ': ' + str(data['rating']) + ')\r\n' labels_title = labels_title + '\r\n' # prepare labels for existed ratings labels_title = labels_title + __lang__(32128) + ' (' + str(len(SITEratedExistRate)) + ') ' + __lang__(32133) + ':\r\n' for id, data in SITEratedExistRate.items(): labels_title = labels_title + '[COLOR=red]>>[/COLOR] ' color = 'green' if data['rating'] == KODIrated[id]['new_rating'] else "red" labels_title = labels_title + data['title'] + ' (' + __lang__(32132) + ': ' + str(data['rating']) + ' - ' + __lang__(32134) + ': [COLOR=' + color + ']' + str(KODIrated[id]['new_rating']) + '[/COLOR])\r\n' ret = dialog.DIALOG().start('script-user-rating-text.xml', labels={10062: __lang__(32137) + ' ' + siteLabel + ' ' + __lang__(32142) + ' KODI'}, textboxes={10063: labels_title}, buttons=[__lang__(32138), __lang__(32139), __lang__(32140)], list=10050) if ret == 0: self.saveRatings(SITErated, type) if ret == 1: self.saveRatings(SITEratedNotexistRate, type) if ret == 2: return
def syncKODItoSITE(self, type, site): if 'tmdb' in site: import tmdb siteClass = tmdb.TMDB(True) siteLabel = 'TMDB' if 'tvdb' in site: import tvdb siteClass = tvdb.TVDB(True) siteLabel = 'TVDB' if 'filmweb' in site: import filmweb siteClass = filmweb.FILMWEB(True) siteLabel = 'FILMWEB' # set bar bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') bar.update(50, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' KODI') # get rated from KODI KODIrated = self.getRatedKODI(type) debug.debug('KODIrated' + type.title() + 's: ' + str(KODIrated)) if len(KODIrated) == 0: bar.close() debug.notify(__lang__(32126) + ' ' + __LANGTYPE__[type + 's']) return bar.update(100, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' ' + siteLabel) # get rated from Site SITErated = siteClass.getRated(type) debug.debug(siteLabel + 'rated' + type.title() + 's: ' + str(SITErated)) bar.close() # try find siteIDs for KODIrated KODIratedWithIDExistRate = {} KODIratedWithIDNotxistRate = {} KODIratedWithoutID = {} for key, item in KODIrated.items(): if 'movie' in type: siteID = siteClass.searchMovieID(item) if 'tvshow' in type: siteID = siteClass.searchTVshowID(item) if 'episode' in type: siteID = siteClass.searchEpisodeID(item) if len(siteID) == 0: siteID = 0 if siteID == 0: KODIratedWithoutID[key] = item else: if key in SITErated.keys(): KODIratedWithIDExistRate[key] = item else: KODIratedWithIDNotxistRate[key] = item debug.debug('KODIrated' + type.title() + 'sWithoutID: ' + str(KODIratedWithoutID)) debug.debug('KODIrated' + type.title() + 'sWithIDExistRate: ' + str(KODIratedWithIDExistRate)) debug.debug('KODIrated' + type.title() + 'sWithIDNotexistRate: ' + str(KODIratedWithIDNotxistRate)) # prepare labels with siteID and not exist rate labels_title = __lang__(32128) + ' (' + str(len(KODIratedWithIDExistRate) + len(KODIratedWithIDNotxistRate)) + ') ' + __lang__(32129) + ' ' + siteLabel + ' ' + __lang__(32130) + ':\r\n' labels_title = labels_title + ' ' + __lang__(32128) + ' (' + str(len(KODIratedWithIDNotxistRate)) + ') ' + __lang__(32131) + ':\r\n' for id, data in KODIratedWithIDNotxistRate.items(): labels_title = labels_title + '[COLOR=green] >>[/COLOR] ' labels_title = labels_title + data['title'] + ' (' + __lang__(32132) + ': ' + str(data['new_rating']) + ')\r\n' labels_title = labels_title + '\r\n' # prepare labels with siteID and exist rate labels_title = labels_title + ' ' + __lang__(32128) + ' (' + str(len(KODIratedWithIDExistRate)) + ') ' + __lang__(32133) + ':\r\n' for id, data in KODIratedWithIDExistRate.items(): labels_title = labels_title + '[COLOR=green] >>[/COLOR] ' color = 'green' if data['new_rating'] == SITErated[id]['rating'] else "red" labels_title = labels_title + data['title'] + ' (' + __lang__(32132) + ': ' + str(data['new_rating']) + ' - ' + __lang__(32134) + ': [COLOR=' + color + ']' + str(SITErated[id]['rating']) + '[/COLOR])\r\n' labels_title = labels_title + '\r\n' # prepare labels without siteID labels_title = labels_title + __lang__(32128) + ' (' + str(len(KODIratedWithoutID)) + ') ' + __lang__(32135) + ' ' + siteLabel + ' ' + __lang__(32136) + ':\r\n' for id, data in KODIratedWithoutID.items(): labels_title = labels_title + '[COLOR=red]>>[/COLOR] ' labels_title = labels_title + data['title'] + ' (' + __lang__(32132) + ': ' + str(data['new_rating']) + ')\r\n' ret = dialog.DIALOG().start('script-user-rating-text.xml', labels={10062: __lang__(32137) + ' KODI ' + __lang__(32142) + ' ' + siteLabel}, textboxes={10063: labels_title}, buttons=[__lang__(32138), __lang__(32139), __lang__(32140)], list=10050) toUpdate = [] if ret == 0: siteClass.sendRating(KODIratedWithIDExistRate.values() + KODIratedWithIDNotxistRate.values()) if ret == 1: siteClass.sendRating(KODIratedWithIDNotxistRate.values()) if ret == 2: return
def syncSITEtoKODI(self, type, site): if 'tmdb' in site: import tmdb siteClass = tmdb.TMDB(True) siteLabel = 'TMDB' if 'tvdb' in site: import tvdb siteClass = tvdb.TVDB(True) siteLabel = 'TVDB' if 'filmweb' in site: import filmweb siteClass = filmweb.FILMWEB(True) siteLabel = 'FILMWEB' # set bar bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') bar.update( 50, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' ' + siteLabel) # get rated from SITE SITErated = siteClass.getRated(type) debug.debug(siteLabel + 'rated' + type.title() + 's: ' + str(SITErated)) if SITErated is False: bar.close() debug.notify(__lang__(32141)) return if len(SITErated) == 0: bar.close() debug.notify(__lang__(32126) + ' ' + __LANGTYPE__[type + 's']) return if bar.iscanceled(): bar.close() return bar.update( 100, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' KODI') # get rated from KODI KODIrated = self.getRatedKODI(type) debug.debug('KODIrated' + type.title() + 's: ' + str(KODIrated)) bar.close() # check for existed ratings SITEratedExistRate = {} SITEratedNotexistRate = {} for key, item in SITErated.items(): if key in KODIrated.keys(): SITEratedExistRate[key] = item else: SITEratedNotexistRate[key] = item # prepare labels for not existed ratings labels_title = __lang__(32128) + ' (' + str( len(SITEratedNotexistRate)) + ') ' + __lang__(32131) + ':\r\n' for id, data in SITEratedNotexistRate.items(): labels_title = labels_title + '[COLOR=green]>>[/COLOR] ' labels_title = labels_title + data['title'] + ' (' + __lang__( 32132) + ': ' + str(data['rating']) + ')\r\n' labels_title = labels_title + '\r\n' # prepare labels for existed ratings labels_title = labels_title + __lang__(32128) + ' (' + str( len(SITEratedExistRate)) + ') ' + __lang__(32133) + ':\r\n' for id, data in SITEratedExistRate.items(): labels_title = labels_title + '[COLOR=red]>>[/COLOR] ' color = 'green' if data['rating'] == KODIrated[id][ 'new_rating'] else "red" labels_title = labels_title + data['title'] + ' (' + __lang__( 32132) + ': ' + str(data['rating']) + ' - ' + __lang__( 32134) + ': [COLOR=' + color + ']' + str( KODIrated[id]['new_rating']) + '[/COLOR])\r\n' ret = dialog.DIALOG().start( 'script-user-rating-text.xml', labels={ 10062: __lang__(32137) + ' ' + siteLabel + ' ' + __lang__(32142) + ' KODI' }, textboxes={10063: labels_title}, buttons=[__lang__(32138), __lang__(32139), __lang__(32140)], list=10050) if ret == 0: self.saveRatings(SITErated, type) if ret == 1: self.saveRatings(SITEratedNotexistRate, type) if ret == 2: return
def check(self): # get settings self.setSITE = sendRequest.getSettings(self) if self.setSITE is False: debug.notify(__lang__(32100).encode('utf-8')) return False if len(self.setSITE) > 0: for n, s in self.setSITE.items(): debug.debug('Server: ' + n + ': ' + s) # post_max_size in bytes post_l = self.setSITE['POST_MAX_SIZE'].strip()[:-1] post_r = self.setSITE['POST_MAX_SIZE'].strip().lower()[-1:] v = { 'g': 3, 'm': 2, 'k': 1 } if post_r in v.keys(): self.setSITE['POST_MAX_SIZE_B'] = int(post_l) * 1024 ** int(v[post_r]) else: self.setSITE['POST_MAX_SIZE_B'] = int(post_l + post_r) debug.debug('Server: POST_MAX_SIZE_B: ' + str(self.setSITE['POST_MAX_SIZE_B'])) # check master mode if self.setSITE['xbmc_master'] == '1': isMaster = xbmc.getCondVisibility('System.IsMaster') if isMaster == 0: return False # check token if hashlib.md5(self.setXBMC['Token']).hexdigest() != self.setSITE['token_md5']: debug.notify(__lang__(32101).encode('utf-8')) debug.debug('Wrong Token') return False else: debug.debug('Token is valid') # get hash tables from site self.hashSITE = sendRequest.getHashes(self) if self.hashSITE is False: return False # reset hash if forced start if self.forcedStart == True: for t in self.hashSITE: self.hashSITE[t] = "" debug.debug('[hashSITE]: ' + str(self.hashSITE)) self.lang = { 'movies': 32201, 'tvshows': 32202, 'episodes': 32203, 'poster': 32117, 'fanart': 32118, 'thumb': 32119, 'exthumb': 32120, 'actors': 32110 } self.panels = ['actor', 'genre', 'country', 'studio', 'director'] self.tn = { 'movies': { 'json': '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["cast", "title", "plot", "rating", "year", "art", "runtime", "genre", "director", "originaltitle", "country", "set", "imdbnumber", "studio", "trailer", "playcount", "lastplayed", "dateadded", "streamdetails", "file"]}, "id": "1"}', 'values' : ['id', 'table', 'title', 'originaltitle', 'year', 'rating', 'plot', 'set', 'imdbid', 'studio[]', 'genre[]', 'actor[]', 'runtime', 'country[]', 'director[]', 'trailer', 'file', 'last_played', 'play_count', 'date_added', 'stream[]', 'hash'] }, 'tvshows': { 'json': '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "originaltitle", "plot", "genre", "cast", "art", "rating", "premiered", "playcount", "lastplayed", "dateadded"]}, "id": 1}', 'values' : ['id', 'table', 'title', 'originaltitle', 'rating', 'plot', 'genre[]', 'actor[]', 'premiered', 'last_played', 'play_count', 'date_added', 'hash'] }, 'episodes': { 'json': '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"properties": ["title", "plot", "episode", "season", "tvshowid", "art", "file", "firstaired", "playcount", "lastplayed", "dateadded", "streamdetails"]}, "id": 1}', 'values' : ['id', 'table', 'title', 'plot', 'episode', 'season', 'tvshow', 'firstaired', 'last_played', 'play_count', 'date_added', 'file', 'stream[]', 'hash'] } } # check source jsonGetSource = '{"jsonrpc": "2.0", "method": "Files.GetSources", "params": {"media": "video"}, "id": 1}' jsonGetSource = xbmc.executeJSONRPC(jsonGetSource) jsonGetSource = unicode(jsonGetSource, 'utf-8', errors='ignore') jsonGetSourceResponse = json.loads(jsonGetSource) if 'result' in jsonGetSourceResponse and 'sources' in jsonGetSourceResponse['result']: for s in jsonGetSourceResponse['result']['sources']: if xbmcvfs.exists(s['file']) == 0: debug.notify(__lang__(32123).encode('utf-8') + ': ' + s['file'].encode('utf-8')) debug.debug('Source inaccessible: ' + s['file'].encode('utf-8')) return False # get videos from XBMC dataSORT = {} dataSORT['videos'] = ['movies'] ##Only movies for now, 'tvshows', 'episodes'] dataSORT['images'] = ['movies', 'tvshows', 'episodes', 'actors'] dataSORT['movies'] = ['poster', 'fanart', 'exthumb'] #dataSORT['tvshows'] = ['poster', 'fanart'] #dataSORT['episodes'] = ['poster'] dataSORT['actors'] = ['thumb'] dataXBMC = getDataFromXBMC(self, dataSORT) # sync videos debug.debug('=== SYNC VIDEOS ===') self.cleanNeeded = False self.imageNeeded = False if syncVideo.sync(self, dataXBMC['videos'], dataSORT['videos']) is False: return False # sync images ## DISABLE IMAGES FOR NOW ##debug.debug('=== SYNC IMAGES ===') ##syncImage.sync(self, dataXBMC['images'], dataSORT) # send webserver settings # if self.setSITE['xbmc_auto_conf_remote'] == '1': # debug.debug('=== SYNC WEBSERVER SETTINGS ===') # conf_remote = ['services.webserver', 'services.webserverport', 'services.webserverusername', 'services.webserverpassword'] # send_conf = {} # for s in conf_remote: # jsonGet = xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Settings.GetSettingValue", "params":{"setting": "' + s + '"},"id":1}') # jsonGet = unicode(jsonGet, 'utf-8', errors='ignore') # jsonGetResponse = json.loads(jsonGet) # send_conf[s.replace('services.', '')] = jsonGetResponse['result']['value'] # if send_conf['webserver'] == False: # debug.notify(__lang__(32122).encode('utf-8')) # debug.debug('Webserver is disabled') # else: # sendRequest.send(self, 'autoconfremote', send_conf) # start generate banner # debug.debug('=== GENREATE BANNER ===') # sendRequest.send(self, 'generatebanner', {'banner': ''}) # start clean database if self.cleanNeeded is True: debug.debug('=== CLEAN DATABASE ===')
def getRated(self, type): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TVDB') return if 'tvshow' in type: method = 'series' if 'episode' in type: method = 'episode' rated = {} ret = self.sendRequest('user/ratings', 'GET') if 'data' in ret: for item in ret['data']: if item['ratingType'] == method: if 'tvshow' in type: rated[str(item['ratingItemId'])] = item['rating'] if 'episode' in type: ret = self.sendRequest('episodes/' + str(item['ratingItemId']), 'GET') if ret is not None and 'data' in ret: if str(ret['data']['seriesId']) in rated.keys(): rated[str(ret['data']['seriesId'])].append({'season': ret['data']['airedSeason'], 'episode': ret['data']['airedEpisodeNumber'], 'rating': item['rating']}) else: rated[str(ret['data']['seriesId'])] = [{'season': ret['data']['airedSeason'], 'episode': ret['data']['airedEpisodeNumber'], 'rating': item['rating']}] # transform TVDB ids to KODI DB ids kodiID = {} if 'tvshow' in type: jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}') jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'tvshows' in jsonGet['result']: for m in jsonGet['result']['tvshows']: tvdb_search = re.search('tvdb', str(m)) if tvdb_search is not None and m['imdbnumber'] in rated.keys(): kodiID[m['tvshowid']] = {'title': m['title'], 'rating': rated[m['imdbnumber']]} if 'episode' in type: # KODI don't have site IDs for episodes # To get KODI IDs we must get TVshow ID and sseason and episode enum jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}') jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'tvshows' in jsonGet['result']: for m in jsonGet['result']['tvshows']: tvdb_search = re.search('tvdb', str(m)) if tvdb_search is not None and m['imdbnumber'] in rated.keys(): tvshowid = str(m['tvshowid']) # for each tvshow that have rated episode get episodes list jsonGetE = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": ' + tvshowid + ', "properties": ["title", "episode", "season"]}, "id": 1}') jsonGetE = json.loads(unicode(jsonGetE, 'utf-8', errors='ignore')) if 'result' in jsonGetE and 'episodes' in jsonGetE['result']: for epi in jsonGetE['result']['episodes']: # for each episode check it exist in rated table if m['imdbnumber'] in rated.keys(): for r in rated[m['imdbnumber']]: if epi['season'] == r['season'] and epi['episode'] == r['episode']: kodiID[epi['episodeid']] = {'title': m['title'] + ' - ' + epi['title'], 'rating': r['rating']} return kodiID
def syncKODItoSITE(self, type, site): if 'tmdb' in site: import tmdb siteClass = tmdb.TMDB(True) siteLabel = 'TMDB' if 'tvdb' in site: import tvdb siteClass = tvdb.TVDB(True) siteLabel = 'TVDB' if 'filmweb' in site: import filmweb siteClass = filmweb.FILMWEB(True) siteLabel = 'FILMWEB' # set bar bar = xbmcgui.DialogProgress() bar.create(__addonname__, '') bar.update( 50, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' KODI') # get rated from KODI KODIrated = self.getRatedKODI(type) debug.debug('KODIrated' + type.title() + 's: ' + str(KODIrated)) if len(KODIrated) == 0: bar.close() debug.notify(__lang__(32126) + ' ' + __LANGTYPE__[type + 's']) return bar.update( 100, __lang__(32125) + ' ' + __LANGTYPE__[type + 's'] + ' ' + __lang__(32127) + ' ' + siteLabel) # get rated from Site SITErated = siteClass.getRated(type) debug.debug(siteLabel + 'rated' + type.title() + 's: ' + str(SITErated)) bar.close() # try find siteIDs for KODIrated KODIratedWithIDExistRate = {} KODIratedWithIDNotxistRate = {} KODIratedWithoutID = {} for key, item in KODIrated.items(): if 'movie' in type: siteID = siteClass.searchMovieID(item) if 'tvshow' in type: siteID = siteClass.searchTVshowID(item) if 'episode' in type: siteID = siteClass.searchEpisodeID(item) if len(siteID) == 0: siteID = 0 if siteID == 0: KODIratedWithoutID[key] = item else: if key in SITErated.keys(): KODIratedWithIDExistRate[key] = item else: KODIratedWithIDNotxistRate[key] = item debug.debug('KODIrated' + type.title() + 'sWithoutID: ' + str(KODIratedWithoutID)) debug.debug('KODIrated' + type.title() + 'sWithIDExistRate: ' + str(KODIratedWithIDExistRate)) debug.debug('KODIrated' + type.title() + 'sWithIDNotexistRate: ' + str(KODIratedWithIDNotxistRate)) # prepare labels with siteID and not exist rate labels_title = __lang__(32128) + ' (' + str( len(KODIratedWithIDExistRate) + len(KODIratedWithIDNotxistRate)) + ') ' + __lang__( 32129) + ' ' + siteLabel + ' ' + __lang__(32130) + ':\r\n' labels_title = labels_title + ' ' + __lang__(32128) + ' (' + str( len(KODIratedWithIDNotxistRate)) + ') ' + __lang__(32131) + ':\r\n' for id, data in KODIratedWithIDNotxistRate.items(): labels_title = labels_title + '[COLOR=green] >>[/COLOR] ' labels_title = labels_title + data['title'] + ' (' + __lang__( 32132) + ': ' + str(data['new_rating']) + ')\r\n' labels_title = labels_title + '\r\n' # prepare labels with siteID and exist rate labels_title = labels_title + ' ' + __lang__(32128) + ' (' + str( len(KODIratedWithIDExistRate)) + ') ' + __lang__(32133) + ':\r\n' for id, data in KODIratedWithIDExistRate.items(): labels_title = labels_title + '[COLOR=green] >>[/COLOR] ' color = 'green' if data['new_rating'] == SITErated[id][ 'rating'] else "red" labels_title = labels_title + data['title'] + ' (' + __lang__( 32132) + ': ' + str(data['new_rating']) + ' - ' + __lang__( 32134) + ': [COLOR=' + color + ']' + str( SITErated[id]['rating']) + '[/COLOR])\r\n' labels_title = labels_title + '\r\n' # prepare labels without siteID labels_title = labels_title + __lang__(32128) + ' (' + str( len(KODIratedWithoutID)) + ') ' + __lang__( 32135) + ' ' + siteLabel + ' ' + __lang__(32136) + ':\r\n' for id, data in KODIratedWithoutID.items(): labels_title = labels_title + '[COLOR=red]>>[/COLOR] ' labels_title = labels_title + data['title'] + ' (' + __lang__( 32132) + ': ' + str(data['new_rating']) + ')\r\n' ret = dialog.DIALOG().start( 'script-user-rating-text.xml', labels={ 10062: __lang__(32137) + ' KODI ' + __lang__(32142) + ' ' + siteLabel }, textboxes={10063: labels_title}, buttons=[__lang__(32138), __lang__(32139), __lang__(32140)], list=10050) toUpdate = [] if ret == 0: siteClass.sendRating(KODIratedWithIDExistRate.values() + KODIratedWithIDNotxistRate.values()) if ret == 1: siteClass.sendRating(KODIratedWithIDNotxistRate.values()) if ret == 2: return
def save(self): xbmc_version = int(xbmc.getInfoLabel('System.BuildVersion')[0:2]) debug.debug('[XBMC VERSION]: ' + str(xbmc_version)) enabledProfiles = self.getEnabledProfiles() ret = dialog.DIALOG().start('script-audio-profiles-menu.xml', labels={10071: ADDON_LANG(32100)}, buttons=enabledProfiles[1], list=10070) if ret is None: return False else: button = enabledProfiles[0][ret] settingsToSave = {} if xbmc_version < 17: json_s = [ # get all settings from System / Audio section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"audiooutput"}},"id":1}', # get volume level '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume"]}, "id": 1}', # get all settings from Video / Playback section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"videos","category":"videoplayer"}}, "id":1}', # get all settings from System / Video section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"videoscreen"}}, "id":1}' ] else: json_s = [ # get all settings from System / Audio section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"audio"}},"id":1}', # get volume level '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume"]}, "id": 1}', # get all settings from Video / Playback section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"player","category":"videoplayer"}}, "id":1}', # get all settings from System / Video section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"display"}}, "id":1}' ] # send json requests for j in json_s: jsonGet = xbmc.executeJSONRPC(j) jsonGet = json.loads(unicode(jsonGet, 'utf-8')) debug.debug('[JSON]: ' + str(jsonGet)) if 'result' in jsonGet: if 'settings' in jsonGet['result']: for set in jsonGet['result']['settings']: if 'value' in set.keys(): if set['value'] == True or set['value'] == False: # lowercase bolean values settingsToSave[set['id']] = str(set['value']).lower() else: if type(set['value']) is int: settingsToSave[set['id']] = str(set['value']) else: settingsToSave[set['id']] = str(set['value']).encode('utf-8') if 'volume' in jsonGet['result']: settingsToSave['volume'] = str(jsonGet['result']['volume']) # prepare JSON string to save to file jsonToWrite = json.dumps(settingsToSave) # create dir in addon data if not exist if not xbmcvfs.exists(ADDON_PATH_DATA): xbmcvfs.mkdir(ADDON_PATH_DATA) # save profile file f = xbmcvfs.File(ADDON_PATH_DATA + 'profile' + str(button) + '.json', 'w') result = f.write(jsonToWrite) f.close() debug.notify(ADDON_LANG(32102) + ' ' + str(button) + ' (' + sName[button] + ')')
def sync(self, ImagesXBMC, ImagesSORT): # get panels list from XBMC ImagesSite = sendRequest.send(self, 'showimages') debug.debug('[ImagesSITE]: ' + str(ImagesSite)) # prepare hash hashImagesXBMC = hashlib.md5(str(ImagesXBMC)).hexdigest() debug.debug('[hashImagesXBMC]: ' + str(hashImagesXBMC)) if hashImagesXBMC != self.hashSITE['images'] or self.imageNeeded == True: debug.debug('[IMAGES UPDATE NEEDED]') else: debug.debug('[IMAGES UPDATE NOT NEEDED]') return False #prepare images to add ImagesToAdd = {} for v_type in ImagesXBMC.keys(): ImagesToAdd[v_type] = {} for img_type in ImagesXBMC[v_type].keys(): # check if user want sync images if self.setSITE['xbmc_'+img_type+'s'] == '1': ImagesToAdd[v_type][img_type] = set(ImagesXBMC[v_type][img_type].keys()) - set(ImagesSite[v_type][img_type]) debug.debug('[ImagesToAdd]: ' + str(ImagesToAdd)) #prepare images to remove ImagesToRemove = {} for v_type in ImagesXBMC.keys(): ImagesToRemove[v_type] = {} for img_type in ImagesXBMC[v_type].keys(): ImagesToRemove[v_type][img_type] = set(ImagesSite[v_type][img_type]) - set(ImagesXBMC[v_type][img_type].keys()) debug.debug('[ImagesToRemove]: ' + str(ImagesToRemove)) # adding new images for type in ImagesSORT['images']: for img_type in ImagesSORT[type]: if len(ImagesToAdd[type][img_type]) > 0: debug.debug('=== ADDING ' + type.upper() + ' ' + img_type.upper() + ' IMAGES ===') countToAdd = len(ImagesToAdd[type][img_type]) addedCount = 0 self.progBar.create(__lang__(32200), __addonname__ + ', ' + __lang__(32204) + ' ' + __lang__(32121) + ' (' + __lang__(self.lang[type]) + ' - ' + __lang__(self.lang[img_type]) + ')') for id in ImagesToAdd[type][img_type]: # progress bar update p = int((float(100) / float(countToAdd)) * float(addedCount)) self.progBar.update(p, str(addedCount + 1) + '/' + str(countToAdd) + ' - ' + self.namesXBMC[type][id]) if 'poster' == img_type and 'episodes' in type: t = art.create(ImagesXBMC[type][img_type][id], 'p', 200, 113, 70) if 'poster' == img_type and 'episodes' not in type: t = art.create(ImagesXBMC[type][img_type][id], 'p', 200, 294, 70) if 'fanart' == img_type: t = art.create(ImagesXBMC[type][img_type][id], 'f', 1280, 720, 70) if 'thumb' == img_type: t = art.create(ImagesXBMC[type][img_type][id], 'a', 75, 100, 70) if 'exthumb' == img_type: ex_size = self.setSITE['xbmc_exthumbs_q'].split('x') t = art.create('image://' + urllib.quote_plus(ImagesXBMC[type][img_type][id].encode('utf-8')) + '/', 'e', int(ex_size[0]), int(ex_size[1]), 70) if len(t) > 0: if 'actors' in type: name = 'actors/' + str(id) + '.jpg' else: f = '_f' if 'fanart' in img_type else '' name = type + '_' + str(id) + f + '.jpg' value = { 'name': name, 'img': base64.b64encode(t) } if sendRequest.send(self, 'addimages', value) is False: self.progBar.close() return False addedCount += 1 self.progBar.close() if addedCount > 0: debug.notify(__lang__(32104).encode('utf-8') + ' ' + __lang__(32121).encode('utf-8') + ' (' + __lang__(self.lang[type]).encode('utf-8') + ' - ' + __lang__(self.lang[img_type]).encode('utf-8') + '): ' + str(addedCount)) # removing images toRemove = {} removedCount = 0 for type, vals in ImagesToRemove.items(): for img_type, v in vals.items(): if len(v) > 0: debug.debug('=== REMOVING ' + type.upper() + ' ' + img_type.upper() + ' IMAGES ===') for file in v: if 'poster' == img_type: toRemove[removedCount] = type + '_' + str(file) + '.jpg' if 'fanart' == img_type: toRemove[removedCount] = type + '_' + str(file) + '_f.jpg' if 'thumb' == img_type: toRemove[removedCount] = 'actors/' + str(file) + '.jpg' if 'exthumb' == img_type: toRemove[removedCount] = type + '_' + str(file) + '.jpg' removedCount += 1 toRemove[removedCount] = type + '_' + str(file) + 'm.jpg' removedCount += 1 if len(toRemove) > 0: if sendRequest.send(self, 'removeimages', toRemove) is False: return False debug.notify(__lang__(32105).encode('utf-8') + ' ' + __lang__(32121).encode('utf-8') + ': ' + str(removedCount)) # update hash value = { 'images': str(hashImagesXBMC) } if sendRequest.send(self, 'updatehash', value) is False: return False
def getRated(self, type): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TMDB') return if 'movie' in type: method = 'movies' if 'tvshow' in type: method = 'tv' if 'episode' in type: method = 'tv/episodes' # read all pages from API page = 1 rated = {} while True: ret = self.sendRequest('account/' + self.account + '/rated/' + method, 'GET', {'session_id': self.session_id, 'page': page}) if ret is False or 'total_pages' not in ret or 'page' not in ret or 'results' not in ret: return False for item in ret['results']: rating = int(round(float(item['rating']))) if rating > 0: if 'movie' in type: # get external source ext = self.sendRequest('movie/' + str(item['id']), 'GET', {'session_id': self.session_id}) if 'imdb_id' in ext: rated[str(ext['imdb_id'])] = rating if 'tvshow' in type: rated[str(item['id'])] = rating if 'episode' in type: if str(item['show_id']) in rated.keys(): rated[str(item['show_id'])].append({'season': item['season_number'], 'episode': item['episode_number'], 'rating': rating}) else: rated[str(item['show_id'])] = [{'season': item['season_number'], 'episode': item['episode_number'], 'rating': rating}] if page >= ret['total_pages']: break page = ret['page'] + 1 # transform tmdb ids to KODI DB ids kodiID = {} if 'movie' in type: jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}') jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'movies' in jsonGet['result']: for m in jsonGet['result']['movies']: tmdb_search = re.search('tmdb', str(m)) if tmdb_search is not None and m['imdbnumber'] in rated.keys(): kodiID[m['movieid']] = {'title': m['title'], 'rating': rated[m['imdbnumber']]} if 'tvshow' in type: jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}') jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'tvshows' in jsonGet['result']: for m in jsonGet['result']['tvshows']: tmdb_search = re.search('tmdb', str(m)) if tmdb_search is not None and m['imdbnumber'] in rated.keys(): kodiID[m['tvshowid']] = {'title': m['title'], 'rating': rated[m['imdbnumber']]} if 'episode' in type: # KODI don't have site IDs for episodes # To get KODI IDs we must get TVshow ID and sseason and episode enum jsonGet = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}') jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'tvshows' in jsonGet['result']: for m in jsonGet['result']['tvshows']: tmdb_search = re.search('tmdb', str(m)) if tmdb_search is not None and m['imdbnumber'] in rated.keys(): tvshowid = str(m['tvshowid']) # for each tvshow that have rated episode get episodes list jsonGetE = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": ' + tvshowid + ', "properties": ["title", "episode", "season"]}, "id": 1}') jsonGetE = json.loads(unicode(jsonGetE, 'utf-8', errors='ignore')) if 'result' in jsonGetE and 'episodes' in jsonGetE['result']: for epi in jsonGetE['result']['episodes']: # for each episode check it exist in rated table if m['imdbnumber'] in rated.keys(): for r in rated[m['imdbnumber']]: if epi['season'] == r['season'] and epi['episode'] == r['episode']: kodiID[epi['episodeid']] = {'title': m['title'] + ' - ' + epi['title'], 'rating': r['rating']} return kodiID
def send(self, option, values=''): # prevent go Kodi to suspend if xbmc.getGlobalIdleTime() > 120: xbmc.executeJSONRPC( '{ "jsonrpc": "2.0", "method": "Input.ExecuteAction", "params": { "action": "noop" }, "id": 1 }' ) debug.debug('[REQUEST]: ' + self.setXBMC['URL'] + option) debug.debug('[REQUEST]: ' + str(values)) # try send data data = urllib.parse.urlencode(values, True) data_len = len(data) debug.debug('[REQUEST DATA SIZE]: ' + str(data_len) + ' bytes') if option != 'checksettings' and data_len > self.setSITE[ 'POST_MAX_SIZE_B'] and self.setSITE['POST_MAX_SIZE_B'] != 0: debug.notify(__lang__(32116).encode('utf-8')) debug.debug( '[REQUEST ERROR]: Data too large to send, server can takes only ' + str(self.setSITE['POST_MAX_SIZE_B']) + ' bytes') return False for l in range(1, 4): try: request = urllib.request.Request(self.setXBMC['URL'] + option, data) if 'true' in self.setXBMC['Auth']: base64string = base64.encodestring( self.setXBMC['AuthLogin'] + ':' + self.setXBMC['AuthPass']).replace('\n', '') request.add_header('Authorization', 'Basic ' + base64string) result = urllib.request(request) output = result.read() except Exception as Error: conn = False debug.debug('Can\'t connect to: ' + self.setXBMC['URL'] + option) debug.debug('[REQUEST ERROR]: ' + str(Error)) if l < 3: debug.debug('[REQUEST]: Wait 5 secs and retring ' + str(l)) time.sleep(15) else: conn = True break if conn != True: debug.notify(__lang__(32100).encode('utf-8')) return False debug.debug('[RESPONSE]: ' + str(output)) # if no values return json if values == '': try: output = unicode(output, 'utf-8', errors='ignore') output = json.loads(output) except Exception as Error: debug.debug('[GET JSON ERROR]: ' + str(Error)) return False else: #get errors if len(output) > 0 and 'ERROR:' in output: debug.notify(__lang__(32102).encode('utf-8')) return False return output
def addImg(self, ImagesXBMC, ImagesToAdd, ImagesSORT): # adding new images for type in ImagesSORT['images']: for img_type in ImagesSORT[type]: if len(ImagesToAdd[type][img_type]) > 0: debug.debug('=== ADDING ' + type.upper() + ' ' + img_type.upper() + ' IMAGES ===') countToAdd = len(ImagesToAdd[type][img_type]) addedCount = 0 self.progBar.create( __lang__(32200), __addonname__ + ', ' + __lang__(32204) + ' ' + __lang__(32121) + ' (' + __lang__(self.lang[type]) + ' - ' + __lang__(self.lang[img_type]) + ')') for id in ImagesToAdd[type][img_type]: # progress bar update p = int( (float(100) / float(countToAdd)) * float(addedCount)) self.progBar.update( p, str(addedCount + 1) + '/' + str(countToAdd) + ' - ' + self.namesXBMC[type][id]) if 'poster' == img_type and 'episodes' in type: t = art.create(ImagesXBMC[type][img_type][id], 'p', 200, 113, 70) if 'poster' == img_type and 'episodes' not in type: t = art.create(ImagesXBMC[type][img_type][id], 'p', 200, 294, 70) if 'fanart' == img_type: t = art.create(ImagesXBMC[type][img_type][id], 'f', 1280, 720, 70) if 'thumb' == img_type: t = art.create(ImagesXBMC[type][img_type][id], 'a', 75, 100, 70) if 'exthumb' == img_type: ex_size = self.setSITE['xbmc_exthumbs_q'].split('x') t = art.create( 'image://' + urllib.quote_plus( ImagesXBMC[type][img_type][id].encode('utf-8')) + '/', 'e', int(ex_size[0]), int(ex_size[1]), 70) if len(t) > 0: if 'actors' in type: name = 'actors/' + str(id) + '.jpg' else: f = '_f' if 'fanart' in img_type else '' name = type + '_' + str(id) + f + '.jpg' value = {'name': name, 'img': base64.b64encode(t)} if sendRequest.send(self, 'addimages', value) is False: self.progBar.close() return False addedCount += 1 self.progBar.close() if addedCount > 0: debug.notify( __lang__(32104).encode('utf-8') + ' ' + __lang__(32121).encode('utf-8') + ' (' + __lang__(self.lang[type]).encode('utf-8') + ' - ' + __lang__(self.lang[img_type]).encode('utf-8') + '): ' + str(addedCount))
def check(self): # get settings self.setSITE = sendRequest.send(self, 'checksettings') if self.setSITE is False: debug.notify(__lang__(32100).encode('utf-8')) return False if len(self.setSITE) > 0: for n, s in self.setSITE.items(): debug.debug('Server: ' + n + ': ' + s) # post_max_size in bytes post_l = self.setSITE['POST_MAX_SIZE'].strip()[:-1] post_r = self.setSITE['POST_MAX_SIZE'].strip().lower()[-1:] v = { 'g': 3, 'm': 2, 'k': 1 } if post_r in v.keys(): self.setSITE['POST_MAX_SIZE_B'] = int(post_l) * 1024 ** int(v[post_r]) else: self.setSITE['POST_MAX_SIZE_B'] = int(post_l + post_r) debug.debug('Server: POST_MAX_SIZE_B: ' + str(self.setSITE['POST_MAX_SIZE_B'])) # check master mode if self.setSITE['xbmc_master'] == '1': isMaster = xbmc.getCondVisibility('System.IsMaster') if isMaster == 0: return False # check version if 'version' not in self.setSITE or self.setSITE['version'] < self.versionWebScript: debug.notify(__lang__(32109).encode('utf-8')) debug.debug('Wrong Version of web script. Update is needed to version ' + self.versionWebScript + ' or higher') return False else: debug.debug('Version is valid') # check token if hashlib.md5(self.setXBMC['Token']).hexdigest() != self.setSITE['token_md5']: debug.notify(__lang__(32101).encode('utf-8')) debug.debug('Wrong Token') return False else: debug.debug('Token is valid') # only banner (mode = 2) if self.mode == 2: debug.debug('=== GENREATE BANNER (ONLY MODE) ===') if self.itemID != '' and self.itemTYPE != '': sendRequest.send(self, 'generatebanner', { 'id': self.itemID, 'type': self.itemTYPE }) return False # get hash tables from site self.hashSITE = sendRequest.send(self, 'showhash') if self.hashSITE is False: return False # reset hash if forced start (mode = 0) if self.mode == 0: for t in self.hashSITE: self.hashSITE[t] = "" debug.debug('[hashSITE]: ' + str(self.hashSITE)) self.lang = { 'movies': 32201, 'tvshows': 32202, 'episodes': 32203, 'poster': 32117, 'fanart': 32118, 'thumb': 32119, 'exthumb': 32120, 'actors': 32110 } self.panels = ['actor', 'genre', 'country', 'studio', 'director'] self.tn = { 'movies': { 'json': '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["cast", "title", "plot", "rating", "year", "art", "runtime", "genre", "director", "originaltitle", "country", "set", "imdbnumber", "studio", "trailer", "playcount", "lastplayed", "dateadded", "streamdetails", "file"]}, "id": "1"}', 'values' : ['id', 'table', 'title', 'originaltitle', 'year', 'rating', 'plot', 'set', 'imdbid', 'studio[]', 'genre[]', 'actor[]', 'runtime', 'country[]', 'director[]', 'trailer', 'file', 'last_played', 'play_count', 'date_added', 'stream[]', 'hash'] }, 'tvshows': { 'json': '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "originaltitle", "plot", "genre", "cast", "art", "rating", "premiered", "playcount", "lastplayed", "dateadded"]}, "id": 1}', 'values' : ['id', 'table', 'title', 'originaltitle', 'rating', 'plot', 'genre[]', 'actor[]', 'premiered', 'last_played', 'play_count', 'date_added', 'hash'] }, 'episodes': { 'json': '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"properties": ["title", "plot", "episode", "season", "tvshowid", "art", "file", "firstaired", "playcount", "lastplayed", "dateadded", "streamdetails"]}, "id": 1}', 'values' : ['id', 'table', 'title', 'plot', 'episode', 'season', 'tvshow', 'firstaired', 'last_played', 'play_count', 'date_added', 'file', 'stream[]', 'hash'] } } # check source if 'true' in self.setXBMC['CheckSource']: jsonGetSource = '{"jsonrpc": "2.0", "method": "Files.GetSources", "params": {"media": "video"}, "id": 1}' jsonGetSource = xbmc.executeJSONRPC(jsonGetSource) jsonGetSource = unicode(jsonGetSource, 'utf-8', errors='ignore') jsonGetSourceResponse = json.loads(jsonGetSource) if 'result' in jsonGetSourceResponse and 'sources' in jsonGetSourceResponse['result']: for s in jsonGetSourceResponse['result']['sources']: if xbmcvfs.exists(s['file']) == 0: debug.notify(__lang__(32123).encode('utf-8') + ': ' + s['file'].encode('utf-8')) debug.debug('Source inaccessible: ' + s['file'].encode('utf-8')) return False # get videos from XBMC dataSORT = {} dataSORT['videos'] = ['movies', 'tvshows', 'episodes'] dataSORT['images'] = ['movies', 'tvshows', 'episodes', 'actors'] dataSORT['movies'] = ['poster', 'fanart', 'exthumb'] dataSORT['tvshows'] = ['poster', 'fanart'] dataSORT['episodes'] = ['poster'] dataSORT['actors'] = ['thumb'] if self.mode == 3 and self.itemID != '' and self.itemTYPE != '': debug.debug('=== UPDATE ONE VIDEO MODE ===') dataSORT['videos'] = [self.itemTYPE+'s'] tnMovies = json.loads(self.tn[self.itemTYPE+'s']['json']) tnMovies['method'] = 'VideoLibrary.GetMovieDetails' if self.itemTYPE == 'movie' else 'VideoLibrary.GetEpisodeDetails' tnMovies['params'][self.itemTYPE+'id'] = int(self.itemID) self.tn[self.itemTYPE+'s']['json'] = json.dumps(tnMovies) dataXBMC = getDataFromXBMC(self, dataSORT) if syncVideo.add(self, dataXBMC['videos'], [self.itemID], self.itemTYPE+'s', 'update') is False: self.progBar.close() return False self.progBar.close() syncImage.sync(self, dataXBMC['images'], dataSORT, True) return dataXBMC = getDataFromXBMC(self, dataSORT) # sync videos debug.debug('=== SYNC VIDEOS ===') self.cleanNeeded = False self.imageNeeded = False if syncVideo.sync(self, dataXBMC['videos'], dataSORT['videos']) is False: return False # sync images debug.debug('=== SYNC IMAGES ===') syncImage.sync(self, dataXBMC['images'], dataSORT) # send webserver settings if self.setSITE['xbmc_auto_conf_remote'] == '1': debug.debug('=== SYNC WEBSERVER SETTINGS ===') conf_remote = ['services.webserver', 'services.webserverport', 'services.webserverusername', 'services.webserverpassword'] send_conf = {} for s in conf_remote: jsonGet = xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Settings.GetSettingValue", "params":{"setting": "' + s + '"},"id":1}') jsonGet = unicode(jsonGet, 'utf-8', errors='ignore') jsonGetResponse = json.loads(jsonGet) send_conf[s.replace('services.', '')] = jsonGetResponse['result']['value'] if send_conf['webserver'] == False: debug.notify(__lang__(32122).encode('utf-8')) debug.debug('Webserver is disabled') else: sendRequest.send(self, 'autoconfremote', send_conf) # start generate banner debug.debug('=== GENREATE BANNER ===') sendRequest.send(self, 'generatebanner', {'banner': ''}) # start clean database if self.cleanNeeded is True: debug.debug('=== CLEAN DATABASE ===') sendRequest.send(self, 'cleandb', {'clean': ''})
def save(self): xbmc_version = int(xbmc.getInfoLabel('System.BuildVersion')[0:2]) debug.debug('[XBMC VERSION]: ' + str(xbmc_version)) enabledProfiles = self.getEnabledProfiles() ret = dialog.DIALOG().start('script-audio-profiles-menu.xml', labels={10071: ADDON_LANG(32100)}, buttons=enabledProfiles[1], list=10070) if ret is None: return False else: button = enabledProfiles[0][ret] settingsToSave = {} if xbmc_version < 17: json_s = [ # get all settings from System / Audio section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"audiooutput"}},"id":1}', # get volume level '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume"]}, "id": 1}', # get all settings from Video / Playback section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"videos","category":"videoplayer"}}, "id":1}', # get all settings from System / Video section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"videoscreen"}}, "id":1}' ] else: json_s = [ # get all settings from System / Audio section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"audio"}},"id":1}', # get volume level '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume"]}, "id": 1}', # get all settings from Video / Playback section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"player","category":"videoplayer"}}, "id":1}', # get all settings from System / Video section '{"jsonrpc":"2.0","method":"Settings.GetSettings", "params":{"level": "expert", "filter":{"section":"system","category":"display"}}, "id":1}' ] # send json requests for j in json_s: jsonGet = xbmc.executeJSONRPC(j) jsonGet = json.loads(unicode(jsonGet, 'utf-8')) debug.debug('[JSON]: ' + str(jsonGet)) if 'result' in jsonGet: if 'settings' in jsonGet['result']: for set in jsonGet['result']['settings']: if 'value' in set.keys(): if set['value'] == True or set[ 'value'] == False: # lowercase bolean values settingsToSave[set['id']] = str( set['value']).lower() else: if type(set['value']) is int: settingsToSave[set['id']] = str( set['value']) else: settingsToSave[set['id']] = str( set['value']).encode('utf-8') if 'volume' in jsonGet['result']: settingsToSave['volume'] = str(jsonGet['result']['volume']) # prepare JSON string to save to file jsonToWrite = json.dumps(settingsToSave) # create dir in addon data if not exist if not xbmcvfs.exists(ADDON_PATH_DATA): xbmcvfs.mkdir(ADDON_PATH_DATA) # save profile file debug.notice('[SAVING SETTING]: ' + sName[button]) f = xbmcvfs.File(ADDON_PATH_DATA + 'profile' + str(button) + '.json', 'w') result = f.write(jsonToWrite) f.close() debug.notify( ADDON_LANG(32102) + ' ' + str(button) + ' (' + sName[button] + ')')
def profile(self, profile): # read addon settings sVolume = ADDON.getSetting('volume') sPlayer = ADDON.getSetting('player') sVideo = ADDON.getSetting('video') sCec = ADDON.getSetting('profile' + profile + '_cec') # read settings from profile f = xbmcvfs.File(ADDON_PATH_DATA + 'profile' + profile + '.json', 'r') result = f.read() try: jsonResult = json.loads(result) f.close() except: debug.notify( ADDON_LANG(32104) + ' ' + profile + ' (' + sName[int(profile)] + ')') debug.error( '[LOAD JSON FROM FILE]: Error reading from profile - ' + str(profile)) return False # settings needed quote for value quote_needed = [ 'audiooutput.audiodevice', 'audiooutput.passthroughdevice', 'locale.audiolanguage', 'lookandfeel.soundskin' ] # set settings readed from profile file debug.notice('[RESTORING SETTING]: ' + sName[int(profile)]) for setName, setValue in jsonResult.items(): # skip setting that type is disable to changing if 'false' in sPlayer and setName.startswith('videoplayer'): continue if 'false' in sVideo and setName.startswith('videoscreen'): continue debug.debug('[RESTORING SETTING]: ' + setName + ': ' + setValue) # add quotes if setName in quote_needed: setValue = '"' + setValue + '"' # set setting if 'true' in sVolume and setName == 'volume': xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": {"volume": ' + jsonResult['volume'] + '}, "id": 1}') else: xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "Settings.SetSettingValue", "params": {"setting": "' + setName + '", "value": ' + setValue.encode('utf-8') + '}, "id": 1}') debug.notify(sName[int(profile)].decode('utf-8')) # write curent profile f = xbmcvfs.File(ADDON_PATH_DATA + 'profile', 'w') f.write(profile) f.close() # CEC if sCec != '' and int(sCec) > 0: debug.notice('[SENDING CEC COMMAND]: ' + cecCommands[int(sCec)]) xbmc.executebuiltin(cecCommands[int(sCec)])
def getRated(self, type): # check login if self.tryLogin() is False: debug.notify(self.login + ' - ' + __lang__(32110), True, 'TMDB') return if 'movie' in type: method = 'movies' if 'tvshow' in type: method = 'tv' if 'episode' in type: method = 'tv/episodes' # read all pages from API page = 1 rated = {} while True: ret = self.sendRequest( 'account/' + self.account + '/rated/' + method, 'GET', { 'session_id': self.session_id, 'page': page }) if ret is False or 'total_pages' not in ret or 'page' not in ret or 'results' not in ret: return False for item in ret['results']: rating = int(round(float(item['rating']))) if rating > 0: if 'movie' in type: # get external source ext = self.sendRequest('movie/' + str(item['id']), 'GET', {'session_id': self.session_id}) if 'imdb_id' in ext: rated[str(ext['imdb_id'])] = rating if 'tvshow' in type: rated[str(item['id'])] = rating if 'episode' in type: if str(item['show_id']) in rated.keys(): rated[str(item['show_id'])].append({ 'season': item['season_number'], 'episode': item['episode_number'], 'rating': rating }) else: rated[str(item['show_id'])] = [{ 'season': item['season_number'], 'episode': item['episode_number'], 'rating': rating }] if page >= ret['total_pages']: break page = ret['page'] + 1 # transform tmdb ids to KODI DB ids kodiID = {} if 'movie' in type: jsonGet = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}' ) jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'movies' in jsonGet['result']: for m in jsonGet['result']['movies']: tmdb_search = re.search('tmdb', str(m)) if tmdb_search is not None and m[ 'imdbnumber'] in rated.keys(): kodiID[m['movieid']] = { 'title': m['title'], 'rating': rated[m['imdbnumber']] } if 'tvshow' in type: jsonGet = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}' ) jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'tvshows' in jsonGet['result']: for m in jsonGet['result']['tvshows']: tmdb_search = re.search('tmdb', str(m)) if tmdb_search is not None and m[ 'imdbnumber'] in rated.keys(): kodiID[m['tvshowid']] = { 'title': m['title'], 'rating': rated[m['imdbnumber']] } if 'episode' in type: # KODI don't have site IDs for episodes # To get KODI IDs we must get TVshow ID and sseason and episode enum jsonGet = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "imdbnumber", "art"]}, "id": 1}' ) jsonGet = json.loads(unicode(jsonGet, 'utf-8', errors='ignore')) if 'result' in jsonGet and 'tvshows' in jsonGet['result']: for m in jsonGet['result']['tvshows']: tmdb_search = re.search('tmdb', str(m)) if tmdb_search is not None and m[ 'imdbnumber'] in rated.keys(): tvshowid = str(m['tvshowid']) # for each tvshow that have rated episode get episodes list jsonGetE = xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": ' + tvshowid + ', "properties": ["title", "episode", "season"]}, "id": 1}' ) jsonGetE = json.loads( unicode(jsonGetE, 'utf-8', errors='ignore')) if 'result' in jsonGetE and 'episodes' in jsonGetE[ 'result']: for epi in jsonGetE['result']['episodes']: # for each episode check it exist in rated table if m['imdbnumber'] in rated.keys(): for r in rated[m['imdbnumber']]: if epi['season'] == r['season'] and epi[ 'episode'] == r['episode']: kodiID[epi['episodeid']] = { 'title': m['title'] + ' - ' + epi['title'], 'rating': r['rating'] } return kodiID