def init(self, magnet_uri): self.magnet_uri = magnet_uri self.magnet_args = urlparse.parse_qs(self.magnet_uri.replace("magnet:?", "")) # I know about urlparse.urlsplit but this is faster self.magnet_display_name = "" if self.magnet_args["dn"]: self.magnet_display_name = self.magnet_args["dn"][0] self.torrent2http_options = { "magnet": magnet_uri, "dlpath": xbmc.validatePath(xbmc.translatePath(plugin.get_setting("dlpath"))) or ".", "dlrate": plugin.get_setting("max_download_rate") or "0", "ulrate": plugin.get_setting("max_upload_rate") or "0", "encryption": plugin.get_setting("encryption"), } # Check for Android and FAT32 SD card issues if PLATFORM["os"] == "android" and "sdcard" in self.torrent2http_options["dlpath"].lower(): plugin.notify("Downloading to SD card is not supported (FAT32). Resetting.", delay=15000) plugin.set_setting("dlpath", "") self.torrent2http_options["dlpath"] = xbmc.validatePath(xbmc.translatePath(plugin.get_setting("dlpath"))) or "." # Translate smb:// url to UNC path on windows, very hacky if PLATFORM["os"] == "windows" and "smb://" in self.torrent2http_options["dlpath"].lower(): self.torrent2http_options["dlpath"] = self.torrent2http_options["dlpath"].replace("smb:", "").replace("/", "\\") if plugin.get_setting("keep_files", bool): plugin.log.info("Will keep file after playback.") self.torrent2http_options["keep"] = None self.on_playback_started = [] self.on_playback_resumed = [] self.on_playback_paused = [] self.on_playback_stopped = [] return self
def setup(self): #create authorization helper and load default settings gauth = GoogleAuth(xbmc.validatePath(xbmc.translatePath(utils.addon_dir() + '/resources/lib/pydrive/settings.yaml'))) gauth.LoadClientConfigSettings() #check if this user is already authorized if(not xbmcvfs.exists(xbmc.translatePath(utils.data_dir() + "google_drive.dat"))): settings = {"client_id":self.CLIENT_ID,'client_secret':self.CLIENT_SECRET} drive_url = gauth.GetAuthUrl(settings) utils.log("Google Drive Authorize URL: " + drive_url) code = xbmcgui.Dialog().input('Google Drive Validation Code','Input the Validation code after authorizing this app') gauth.Auth(code) gauth.SaveCredentialsFile(xbmc.validatePath(xbmc.translatePath(utils.data_dir() + 'google_drive.dat'))) else: gauth.LoadCredentialsFile(xbmc.validatePath(xbmc.translatePath(utils.data_dir() + 'google_drive.dat'))) #create the drive object self.drive = GoogleDrive(gauth) #make sure we have the folder we need xbmc_folder = self._getGoogleFile(self.root_path) print xbmc_folder if(xbmc_folder == None): self.mkdir(self.root_path)
def getClient(self): #create authorization helper and load default settings gauth = GoogleAuth(xbmc.validatePath(xbmc.translatePath(utils.addon_dir() + '/resources/lib/pydrive/settings.yaml'))) gauth.LoadClientConfigSettings() gauth.LoadCredentialsFile(xbmc.validatePath(xbmc.translatePath(utils.data_dir() + 'google_drive.dat'))) result = GoogleDrive(gauth) return result
def _get_folder_images(self, path): self.log("_get_folder_images started with path: %s" % repr(path)) dirs, files = xbmcvfs.listdir(path) images = [xbmc.validatePath(path + f) for f in files if f.lower()[-3:] in ("jpg", "png")] if addon.getSetting("recursive") == "true": for directory in dirs: if directory.startswith("."): continue images.extend(self._get_folder_images(xbmc.validatePath("/".join((path, directory, ""))))) self.log("_get_folder_images ends") return images
def MenuAccounts(): if (tfalse(addst("anon-enable","false"))==True): anonPath=xbmc.validatePath(xbmc.translatePath(addst("anon-path","special://logpath"))) #.replace(pFindWhat,"|tag|").replace("|tag|",pReplaceWith) if (len(anonPath) > 0): addon.add_directory({'mode':'System.ExecWait','url':'ftp://'+LiP+':'+addst('port','2121')+'/'},{'title':cFL('00.)','darkorange')+' User: '******'[ [I]Anonymous[/I] ]','darkorange')+'[CR]'+anonPath},is_folder=True,fanart=_artFanart,img=artp("Anonymous")) for tn in ['01','02','03','04','05','06','07','08','09','10']: if (tfalse(addst(tn+"-enable","false"))==True): tt={}; tt['path']=xbmc.validatePath(xbmc.translatePath(addst(tn+"-path","special://logpath"))) tt['user']=addst(tn+"-user",""); tt['pass']=addst(tn+"-pass","xbmchub"); tt['perm']=addst(tn+"-perm","elradfmwM") if (len(tt['user']) > 0) and (len(tt['path']) > 0): addon.add_directory({'mode':'GoToFTP','url':tn},{'title':cFL(tn+'.)','darkorange')+' User: '******'user'],'darkorange')+'[CR]'+tt['path']},is_folder=True,fanart=_artFanart,img=artp("User"+tn))
def _fetch_movies(self, request): if request == 'RecommendedMovie': # Unfinished movies json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "year", "genre", "studio", "tagline", "plot", "runtime", "fanart", "thumbnail", "file", "plotoutline", "lastplayed", "trailer", "rating", "resume"], "sort": {"order": "descending", "method": "lastplayed"}, "limits": {"end": %d}, "filter": {"field": "inprogress", "operator": "true", "value": ""}}, "id": 1}' %self.LIMIT) elif request == 'RecentMovie' and self.RECENTITEMS_UNPLAYED: # Recent added and unplayed json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "year", "genre", "studio", "tagline", "plot", "runtime", "fanart", "thumbnail", "file", "plotoutline", "lastplayed", "trailer", "rating", "resume"], "sort": {"order": "descending", "method": "dateadded"}, "limits": {"end": %d}, "filter": {"field": "playcount", "operator": "is", "value": "0"} }, "id": 1}' %self.LIMIT) elif request == 'RecentMovie': # Recent added json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "year", "genre", "studio", "tagline", "plot", "runtime", "fanart", "thumbnail", "file", "plotoutline", "lastplayed", "trailer", "rating", "resume"], "sort": {"order": "descending", "method": "dateadded"}, "limits": {"end": %d} }, "id": 1}' %self.LIMIT) elif request == "RandomMovie" and self.RANDOMITEMS_UNPLAYED: # Reandom and unplayed json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "year", "genre", "studio", "tagline", "plot", "runtime", "fanart", "thumbnail", "file", "plotoutline", "lastplayed", "trailer", "rating", "resume"], "sort": {"method": "random" }, "limits": {"end": %d} , "filter": {"field": "playcount", "operator": "lessthan", "value": "1"} }, "id": 1}' %self.LIMIT) else: # Random episode json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "playcount", "year", "genre", "studio", "tagline", "plot", "runtime", "fanart", "thumbnail", "file", "plotoutline", "lastplayed", "trailer", "rating", "resume"], "sort": {"method": "random" }, "limits": {"end": %d} }, "id": 1}' %self.LIMIT) json_query = unicode(json_query, 'utf-8', errors='ignore') json_response = simplejson.loads(json_query) if json_response['result'].has_key('movies'): self._clear_properties(request) count = 0 for item in json_response['result']['movies']: count += 1 if item['resume']['position'] > 0: resume = "true" played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) else: resume = "false" played = '0%' path = media_path(item['file']) self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) self.WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) self.WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) self.WINDOW.setProperty("%s.%d.Studio" % (request, count), item['studio'][0]) self.WINDOW.setProperty("%s.%d.Plot" % (request, count), item['plot']) self.WINDOW.setProperty("%s.%d.PlotOutline" % (request, count), item['plotoutline']) self.WINDOW.setProperty("%s.%d.Tagline" % (request, count), item['tagline']) self.WINDOW.setProperty("%s.%d.Runtime" % (request, count), item['runtime']) self.WINDOW.setProperty("%s.%d.Rating" % (request, count), str(round(float(item['rating']),1))) self.WINDOW.setProperty("%s.%d.Trailer" % (request, count), item['trailer']) self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) self.WINDOW.setProperty("%s.%d.Logo" % (request, count), xbmc.validatePath(os.path.join(path, 'logo.png'))) self.WINDOW.setProperty("%s.%d.Landscape" % (request, count), xbmc.validatePath(os.path.join(path, 'landscape.png'))) self.WINDOW.setProperty("%s.%d.Banner" % (request, count), xbmc.validatePath(os.path.join(path, 'banner.png'))) self.WINDOW.setProperty("%s.%d.Disc" % (request, count), xbmc.validatePath(os.path.join(path, 'disc.png'))) self.WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) self.WINDOW.setProperty("%s.%d.Played" % (request, count), played) self.WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) self.WINDOW.setProperty("%s.%d.Path" % (request, count), path)
def _get_legal_filepath(self, title, url, id_=0): # set our default filename and extension file_, ext = os.path.splitext(os.path.basename(url)) # does user want to use title as filename file_ = [file_, title][self.m_addon.getSetting("trailer.use.title")] # set identifier trailer_id = "" if (id_ > 0): trailer_id = " ({id})".format(id="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[id_]) # set our default trailer text trailer = ["", "-trailer"][self.m_addon.getSetting("trailer.add.trailer")] # set our default file path (if play_mode is temp, download to cache folder) if (self.m_addon.getSetting("trailer.play.mode") == 1): filepath = "special://temp/" else: filepath = self.m_addon.getSetting("trailer.save.folder") or "special://temp/" # do we want to save with movie if (self.m_addon.getSetting("trailer.save.movie")): filepath, file_, trailer = self._get_movie_path( title, filepath, file_, trailer ) # set final filename file_ = "{name}{id}{trailer}{ext}".format( name=os.path.splitext(file_)[0], id=trailer_id, trailer=trailer, ext=ext ) # FIXME: may need changing for temorary download # if file already exists add an ID and try again if (filepath != "special://temp/" and xbmcvfs.exists(xbmc.makeLegalFilename(xbmc.validatePath( os.path.join( xbmc.translatePath(filepath), file_ ) )).decode("UTF-8"))): return self._get_legal_filepath(title, url, id_ + 1) # return final path return xbmc.makeLegalFilename(xbmc.validatePath( os.path.join( xbmc.translatePath(filepath), file_ ) )).decode("UTF-8")
def viewTallImage(image_url, width, height): log( 'viewTallImage %s: %sx%s' %(image_url, width, height)) #image_url=unescape(image_url) #special case for handling reddituploads urls #log( 'viewTallImage %s: %sx%s' %(image_url, width, height)) #useWindow=xbmcgui.WindowDialog() useWindow=xbmcgui.WindowXMLDialog('slideshow05.xml', addon_path) #useWindow.setCoordinateResolution(1) #screen_w=useWindow.getHeight() #1280 #screen_h=useWindow.getWidth() #720 screen_w=1920 screen_h=1080 log('screen %dx%d'%(screen_w,screen_h)) try: w=int(float(width)) h=int(float(height)) ar=float(w/h) resize_percent=float(screen_w)/w if w > screen_w: new_h=int(h*resize_percent) else: if abs( h - screen_h) < ( screen_h / 10 ): #if the image height is about 10 percent of the screen height, zoom it a bit new_h=screen_h*2 elif h < screen_h: new_h=screen_h else: new_h=h log( ' image=%dx%d resize_percent %f new_h=%d ' %(w,h, resize_percent, new_h)) loading_img = xbmc.validatePath('/'.join((addon_path, 'resources', 'skins', 'Default', 'media', 'srr_busy.gif' ))) slide_h=new_h-screen_h log( ' slide_h=' + repr(slide_h)) #sy=0 #note: y-axis not accurate. 0 does not always indicate top of screen img_control = xbmcgui.ControlImage(0, 0, screen_w, new_h, '', aspectRatio=2) #(values 0 = stretch (default), 1 = scale up (crops), 2 = scale down (black bars) #img_control = useWindow.getControl( 101 ) img_loading = xbmcgui.ControlImage(screen_w-100, 0, 100, 100, loading_img, aspectRatio=2) #the cached image is of lower resolution. we force nocache by using setImage() instead of defining the image in ControlImage() img_control.setImage(image_url, False) useWindow.addControls( [ img_loading, img_control]) #useWindow.addControl( img_control ) img_control.setPosition(0,0) scroll_time=(int(h)/int(w))*20000 img_control.setAnimations( [ ('conditional', "condition=true delay=6000 time=%d effect=slide start=0,-%d end=0,0 tween=sine easing=inout pulse=true" %( scroll_time, slide_h) ), ('conditional', "condition=true delay=0 time=4000 effect=fade start=0 end=100 " ) , ] ) useWindow.doModal() useWindow.removeControls( [img_control,img_loading] ) del useWindow except Exception as e: log(" EXCEPTION viewTallImage:="+ str( sys.exc_info()[0]) + " " + str(e) )
def walkTree(self,directory): if(directory[-1:] == '/'): directory = directory[:-1] if(self.vfs.exists(directory + "/")): dirs,files = self.vfs.listdir(directory) #create all the subdirs first for aDir in dirs: dirPath = xbmc.validatePath(xbmc.translatePath(directory + "/" + aDir)) file_ext = aDir.split('.')[-1] if(not dirPath in self.exclude_dir): self.addFile("-" + dirPath) #catch for "non directory" type files shouldWalk = True for s in file_ext: if(s in self.not_dir): shouldWalk = False if(shouldWalk): self.walkTree(dirPath) #copy all the files for aFile in files: filePath = xbmc.translatePath(directory + "/" + aFile) self.addFile(filePath)
def create_name(self,zip_entry,sub_filename,subtitle_lang): if self.temp: name = "temp_sub" else: name = os.path.splitext( sub_filename )[0] if (__addon__.getSetting( "lang_to_end" ) == "true"): file_name = u"%s.%s%s" % ( name, subtitle_lang, os.path.splitext( zip_entry )[1] ) else: file_name = u"%s%s" % ( name, os.path.splitext( zip_entry )[1] ) log( __name__ ,"Sub in Zip [%s], File Name [%s]" % (zip_entry, file_name,)) ret_zip_entry = xbmc.validatePath(os.path.join(self.tmp_sub_dir,zip_entry)).decode("utf-8") ret_file_name = xbmc.validatePath(os.path.join(self.sub_folder,file_name)).decode("utf-8") return ret_zip_entry,ret_file_name
def hide_loading_indicator(self): bg_img = xbmc.validatePath("/".join((ADDON_PATH, "resources", "media", self.BACKGROUND_IMAGE))) self.loading_control.setAnimations([("conditional", "effect=fade start=100 end=0 time=500 condition=true")]) self.background_control.setAnimations( [("conditional", "effect=fade start=0 end=100 time=500 delay=500 condition=true")] ) self.background_control.setImage(bg_img)
def get_sources(): results = [] result = eval(xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Files.GetSources", "params": {"media": "video"}, "id": 1}')) if 'sources' not in result['result']: return results sources = result['result']['sources'] sources = [ xbmc.validatePath(s['file']) for s in sources ] for s in sources: log("FOUND SOURCE: %s" % s, xbmc.LOGINFO) if s.startswith('addons://'): s = clean_path(s) log("%s is an addon source, ignoring..." % s, xbmc.LOGINFO) elif s.startswith('multipath://'): log("%s is a multipath source, splitting and adding individuals..." % s, xbmc.LOGINFO) s = s.replace('multipath://', '') parts = s.split('/') parts = [ f for f in parts ] for b in parts: if b: b = clean_path(b) log("%s is a straight forward source, adding.." % b, xbmc.LOGINFO) results.append(b) else: s = clean_path(s) log("%s is a straight forward source, adding..." % s, xbmc.LOGINFO) results.append(s) return results
def _fetch_tvshows_recommended(self, request): # First unplayed episode of recent played tvshows json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "studio", "thumbnail", "file"], "sort": {"order": "descending", "method": "lastplayed"}, "filter": {"field": "inprogress", "operator": "true", "value": ""}, "limits": {"end": %d}}, "id": 1}' %self.LIMIT) json_query = unicode(json_query, 'utf-8', errors='ignore') json_response = simplejson.loads(json_query) if json_response['result'].has_key('tvshows'): self._clear_properties(request) count = 0 for item in json_response['result']['tvshows']: count += 1 json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": %d, "properties": ["title", "playcount", "plot", "season", "episode", "showtitle", "thumbnail", "fanart", "file", "lastplayed", "rating", "resume"], "sort": {"method": "episode"}, "filter": {"field": "playcount", "operator": "is", "value": "0"}, "limits": {"end": 1}}, "id": 1}' %item['tvshowid']) json_query2 = unicode(json_query2, 'utf-8', errors='ignore') json_response2 = simplejson.loads(json_query2) if json_response2.has_key('result') and json_response2['result'] != None and json_response2['result'].has_key('episodes'): for item2 in json_response2['result']['episodes']: episode = ("%.2d" % float(item2['episode'])) season = "%.2d" % float(item2['season']) rating = str(round(float(item2['rating']),1)) episodeno = "s%se%s" %(season,episode) seasonthumb = '' if item2['resume']['position'] > 0: resume = "true" played = '%s%%'%int((float(item2['resume']['position']) / float(item2['resume']['total'])) * 100) else: resume = "false" played = '0%' path = media_path(item['file']) self.WINDOW.setProperty("%s.%d.Title" % (request, count), item2['title']) self.WINDOW.setProperty("%s.%d.Episode" % (request, count), episode) self.WINDOW.setProperty("%s.%d.EpisodeNo" % (request, count), episodeno) self.WINDOW.setProperty("%s.%d.Season" % (request, count), season) self.WINDOW.setProperty("%s.%d.Plot" % (request, count), item2['plot']) self.WINDOW.setProperty("%s.%d.TVshowTitle" % (request, count), item2['showtitle']) self.WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item2['thumbnail']) self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item2['fanart']) self.WINDOW.setProperty("%s.%d.Poster" % (request, count), xbmc.validatePath(os.path.join(path, 'poster.jpg'))) self.WINDOW.setProperty("%s.%d.Banner" % (request, count), xbmc.validatePath(os.path.join(path, 'banner.jpg'))) self.WINDOW.setProperty("%s.%d.Logo" % (request, count), xbmc.validatePath(os.path.join(path, 'logo.png'))) self.WINDOW.setProperty("%s.%d.Clearart" % (request, count), xbmc.validatePath(os.path.join(path, 'clearart.png'))) self.WINDOW.setProperty("%s.%d.Studio" % (request, count), item['studio'][0]) self.WINDOW.setProperty("%s.%d.TvshowThumb" % (request, count), item['thumbnail']) self.WINDOW.setProperty("%s.%d.SeasonThumb" % (request, count), seasonthumb) self.WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) self.WINDOW.setProperty("%s.%d.Played" % (request, count), played) self.WINDOW.setProperty("%s.%d.File" % (request, count), item2['file']) self.WINDOW.setProperty("%s.%d.Path" % (request, count), path)
def translatePath( filepath ): # translate any special:// paths filepath = xbmc.translatePath( xbmc.validatePath( filepath ) ) # if windows and samba convert to a proper format for shutil and os modules if ( os.environ.get( "OS", "win32" ) == "win32" and filepath.startswith( "smb://" ) ): filepath = filepath.replace( "/", "\\" ).replace( "smb:", "" ) # return result return filepath
def findTrack(self, artistname, trackname): # Find the song chars0 = trackname[0].lower() + trackname[1].lower() chars1 = trackname[0].upper() + trackname[1].lower() chars2 = trackname[0].lower() + trackname[1].upper() chars3 = trackname[0].upper() + trackname[1].upper() req = { "jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "id": "libSongs", "params": { "properties": ["artist", "duration", "album", "title", "file", "thumbnail", "fanart", "track"], "limits": {"start": 0, "end": 1000}, "sort": {"order": "ascending", "method": "track", "ignorearticle": True}, "filter": {"and": [ {"field": "artist", "operator": "is", "value": artistname.encode('utf-8')}, {"or": [ #{"field": "title", "operator": "is", "value": trackname.lower().encode('utf-8')} {"field": "title", "operator": "startswith", "value": chars0.encode('utf-8')}, {"field": "title", "operator": "startswith", "value": chars1.encode('utf-8')}, {"field": "title", "operator": "startswith", "value": chars2.encode('utf-8')}, {"field": "title", "operator": "startswith", "value": chars3.encode('utf-8')}, ]} ]} } } rpcresp = xbmc.executeJSONRPC(json.dumps(req)) # xbmc.log(str(rpcresp)) rpcresp = json.loads(rpcresp) found = 0 < int(rpcresp['result']['limits']['end']) ret = None #strInd = ' ' if found: # xbmc.log(str(rpcresp)) trackname_stripped = strip_accents(trackname.strip().lower()) for s in rpcresp['result']['songs']: if trackname_stripped == strip_accents(s['title'].strip().lower()): path = xbmc.translatePath(s['file']) path = xbmc.validatePath(path) if os.path.exists(path): ret = s break log("Found in library, but file doesn't exist: %s" % path) xbmc.executebuiltin('Notification(%s,%s, 1000)' % ("File doesn't exist", os.path.basename(path))) #if artistname.lower() <> ret['artist'][0].lower() or trackname.lower() <> ret['title'].lower(): #if ret is not None: # strInd = '+++ ' # xbmc.log(strInd + str(artistname.encode('utf-8')) + " -- " + str(trackname.encode('utf-8'))) # xbmc.log(' ' + str(ret['artist'][0].encode('utf-8')) + " -- " + str(ret['title'].encode('utf-8'))) #else: #xbmc.log('NOT found track ' + str(artistname.encode('utf-8')) + " -- " + str(trackname.encode('utf-8'))) #xbmc.log(strInd + str(artistname.encode('utf-8')) + " -- " + str(trackname.encode('utf-8'))) return ret
def _get_root_dir( self, path ): # get current working directory, we need to reset sys.argv[ 0 ] to a plugin for weather plugins as they aren't run as plugins, but they are categorized as plugins cwd = os.path.dirname( xbmc.validatePath( path.replace( "Q:\\plugins\\weather\\", "plugin://weather/" ) ) ) # check if we're at root folder of addon if ( not os.path.isfile( os.path.join( xbmc.translatePath( cwd ), "addon.xml" ) ) ): # we're not at root, assume resources/lib/ cwd = os.path.dirname( os.path.dirname( cwd ) ) # return result return cwd
def init_global_controls(self): self.log("init_global_controls start") loading_img = xbmc.validatePath("/".join((ADDON_PATH, "resources", "media", "loading.gif"))) self.loading_control = ControlImage(576, 296, 128, 128, loading_img) self.preload_control = ControlImage(-1, -1, 1, 1, "") self.background_control = ControlImage(0, 0, 1280, 720, "") self.global_controls = [self.preload_control, self.background_control, self.loading_control] self.xbmc_window.addControls(self.global_controls) self.log("init_global_controls end")
def _get_folder_images(self, path): self.log('_get_folder_images started with path: %s' % repr(path)) dirs, files = xbmcvfs.listdir(path) images = [ xbmc.validatePath(path + f) for f in files if f.lower()[-3:] in ('jpg', 'png') ] if addon.getSetting('recursive') == 'true': for directory in dirs: if directory.startswith('.'): continue images.extend( self._get_folder_images( xbmc.validatePath('/'.join((path, directory, ''))) ) ) self.log('_get_folder_images ends') return images
def scanFolder(self, path): #Scan set folder for images with png and jpg extension self.log('scanFolder started with path: %s' % repr(path)) dirs, files = xbmcvfs.listdir(path) images = [ xbmc.validatePath(path + f) for f in files if f.lower()[-3:] in ('jpg', 'png') ] if addon.getSetting('recursive') == 'true': for directory in dirs: if directory.startswith('.'): continue images.extend( self.scanFolder( xbmc.validatePath('/'.join((path, directory, ''))) ) ) self.log('scanFolder ends') return images
def _get_folder_images(self, path): self.log('_get_folder_images started with path: %s' % repr(path)) _, files = xbmcvfs.listdir(path) images = [ xbmc.validatePath(path + f) for f in files if f.lower()[-3:] in ('jpg', 'png') ] self.log('_get_folder_images ends') return images
def download(url, dest, name, headers={}): util.debug("[SC] zacinam stahovat %s" % str(url)) filename = xbmc.validatePath(os.path.join(xbmc.translatePath(dest), name)) try: if 'http' not in url: xbmcvfs.copy(url, filename) return req = urllib2.Request(url) for idx, val in headers.items(): req.add_header(idx, val) r = urllib2.urlopen(req) total_length = r.info().get('content-length') chunk = min( getSettingAsInt('download-buffer') * 1024 * 1024, (1024 * 1024 * 4) if total_length is None else int(int(total_length) / 100)) dl = 0 util.debug("[SC] info: [%s] [%s]" % (str(filename), str(chunk))) fd = xbmcvfs.File(filename, 'wb') notifyEnabled = getSettingAsBool('download-notify') notifyEvery = getSettingAsInt('download-notify-every') notifyPercent = 10 if notifyEvery == 0 else 5 if notifyEvery == 1 else 1 lastNotify = None lastTime = microtime() for data in iter(lambda: r.read(chunk), ''): if total_length is not None: dl += len(data) t = microtime() if t > lastTime: kbps = int( float(len(data)) / float((t - lastTime) / 1000) / 1024) done = int(100 * int(dl) / int(total_length)) util.debug( "[SC] ... %s%% [%s]KB/s" % (str(done), str(kbps))) lastTime = t if notifyEnabled and lastNotify != done and ( done % notifyPercent) == 0: notification("%s%% - %dKB/s" % (done, kbps), name, 1000) lastNotify = done else: dl += 0 util.debug("[SC] ... %s?" % str(dl)) fd.write(data) fd.close() util.debug("[SC] msg: [%s]" % getString(30315)) if isPlaying(): notification(getString(30315), filename) else: dialog.ok(getString(30315), filename) except: dialog.ok(getString(30316), name) util.debug('[SC] ERR download: %s' % str(traceback.format_exc())) pass
def Download_Subtitles( self, pos, auto = False, gui = True ): if gui: if auto: self.getControl( STATUS_LABEL ).setLabel( _( 763 )) else: self.getControl( STATUS_LABEL ).setLabel( _( 649 )) compressed_subs = os.path.join( self.tmp_sub_dir, "compressed_subs.ext") compressed, language, file = self.Service.download_subtitles(self.subtitles_list, pos, compressed_subs, self.tmp_sub_dir, self.sub_folder, self.session_id ) sub_lang = str(languageTranslate(language,0,2)) if compressed: # backward compatibility if (file == ""): file = "zip" suffixed_compressed_subs = re.sub("\.ext$",".%s" % file,compressed_subs) os.rename(compressed_subs,suffixed_compressed_subs) log(__name__,"Extracting %s" % suffixed_compressed_subs) self.Extract_Subtitles(suffixed_compressed_subs,sub_lang, gui) else: sub_ext = os.path.splitext( file )[1] if self.temp: sub_name = "temp_sub" else: sub_name = os.path.splitext( os.path.basename( self.file_original_path ))[0] if (__addon__.getSetting( "lang_to_end" ) == "true"): file_name = u"%s.%s%s" % ( sub_name, sub_lang, sub_ext ) else: file_name = u"%s%s" % ( sub_name, sub_ext ) file_from = file file_to = xbmc.validatePath(os.path.join(self.sub_folder, file_name)).decode("utf-8") # Create a files list of from-to tuples so that multiple files may be # copied (sub+idx etc') files_list = [(file_from,file_to)] # If the subtitle's extension sub, check if an idx file exists and if so # add it to the list if ((sub_ext == ".sub") and (os.path.exists(file[:-3]+"idx"))): log( __name__ ,"found .sub+.idx pair %s + %s" % (file_from,file_from[:-3]+"idx")) files_list.append((file_from[:-3]+"idx",file_to[:-3]+"idx")) for cur_file_from, cur_file_to in files_list: subtitle_set,file_path = copy_files( cur_file_from, cur_file_to ) # Choose the last pair in the list, second item (destination file) if subtitle_set: subtitle = files_list[-1][1] xbmc.Player().setSubtitles(subtitle.encode("utf-8")) self.close() else: if gui: self.getControl( STATUS_LABEL ).setLabel( _( 654 )) self.show_service_list(gui)
def init_global_controls(self): #self.log(' init_global_controls start') loading_img = xbmc.validatePath('/'.join((ADDON_PATH, 'resources', 'skins', 'Default', 'media', 'srr_busy.gif' ))) self.loading_control = ControlImage(576, 296, 128, 128, loading_img) self.preload_control = ControlImage(-1, -1, 1, 1, '') self.background_control = ControlImage(0, 0, 1280, 720, '') self.global_controls = [ self.preload_control, self.background_control, self.loading_control ] self.xbmc_window.addControls(self.global_controls)
def backup_source(self, source_date): # nothing to backup if no source date if (source_date is None): return # set paths old_path = xbmc.validatePath( os.path.join( xbmc.translatePath(self.m_addon.getSetting("source.cache.path")), self.m_addon.getSetting("trailer.scraper"), u"source" ) ).decode("UTF-8") new_path = xbmc.validatePath( os.path.join( xbmc.translatePath(self.m_addon.getSetting("source.cache.path")), self.m_addon.getSetting("trailer.scraper"), u"source-{date}".format(date=source_date.split(" ")[0]) ) ).decode("UTF-8") # if folder exists, copy it if (xbmcvfs.exists(old_path) and not xbmcvfs.exists(new_path)): xbmcvfs.rename(old_path, new_path)
def init(self, uri): self.display_name = "" self.torrent2http_options = { "uri": uri, "dlpath": xbmc.validatePath(xbmc.translatePath(plugin.get_setting("dlpath"))) or ".", "dlrate": plugin.get_setting("max_download_rate") or "0", "ulrate": plugin.get_setting("max_upload_rate") or "0", "encryption": plugin.get_setting("encryption"), "buffer": "0.005", } if "://" in self.torrent2http_options["dlpath"]: # Translate smb:// url to UNC path on windows, very hackish if PLATFORM["os"] == "windows" and self.torrent2http_options[ "dlpath"].lower().startswith("smb://"): self.torrent2http_options[ "dlpath"] = self.torrent2http_options["dlpath"].replace( "smb:", "").replace("/", "\\") else: plugin.notify( "Downloading to an unmounted network share is not supported. Resetting.", delay=15000) plugin.set_setting("dlpath", "") self.torrent2http_options["dlpath"] = "." # Check for Android and FAT32 SD card issues if PLATFORM["os"] == "android" and self.torrent2http_options[ "dlpath"] != ".": from xbmctorrent.utils import get_path_fs fs = get_path_fs(self.torrent2http_options["dlpath"]) plugin.log.info("Download path filesytem is %s" % fs) if fs == "vfat": # FAT32 is not supported plugin.notify( "Downloading to FAT32 is not supported. Resetting.", delay=15000) plugin.set_setting("dlpath", "") self.torrent2http_options["dlpath"] = "." if plugin.get_setting("keep_files", bool): plugin.log.info("Will keep file after playback.") self.torrent2http_options["keep"] = None self.on_playback_started = [] self.on_playback_resumed = [] self.on_playback_paused = [] self.on_playback_stopped = [] return self
def hide_loading_indicator(self): bg_img = xbmc.validatePath('/'.join(( ADDON_PATH, 'resources', 'skins', 'Default', 'media', self.BACKGROUND_IMAGE ))) #bg_img = self.BACKGROUND_IMAGE self.loading_control.setAnimations([( 'conditional', 'effect=fade start=100 end=0 time=500 condition=true' )]) self.background_control.setAnimations([( 'conditional', 'effect=fade start=0 end=100 time=500 delay=500 condition=true' )]) self.background_control.setImage(bg_img)
def validate_path(path): """Returns the translated path. :param path:Path to format :type path:str :return:Translated path :rtype:str """ if hasattr(xbmcvfs, "validatePath"): path = xbmcvfs.validatePath(path) # pylint: disable=no-member else: path = xbmc.validatePath(path) # pylint: disable=no-member return path
def translatePath(path): """Converts special:// paths and smb:// paths so os and shutil work """ # translate any special:// paths path = xbmc.validatePath(xbmc.translatePath(path)).decode("UTF-8") # if windows and smb:// convert to a proper format for sqlite3, shutil and os modules if (path.startswith("smb://")): if (sys.platform == "win32" or sys.platform == "win64"): path = path.replace(u"/", u"\\").replace(u"smb:", u"") return path
def _get_root_dir(self, path): # get current working directory, we need to reset sys.argv[ 0 ] to a plugin for weather plugins as they aren't run as plugins, but they are categorized as plugins cwd = os.path.dirname( xbmc.validatePath( path.replace("Q:\\plugins\\weather\\", "plugin://weather/"))) # check if we're at root folder of addon if (not os.path.isfile( os.path.join(xbmc.translatePath(cwd), "addon.xml"))): # we're not at root, assume resources/lib/ cwd = os.path.dirname(os.path.dirname(cwd)) # return result return cwd
def get_song_info(self, songlist=False): # clear song info self._clear_song_attributes() # TODO: when/if XBMC supports Player.offset(), we can then support video # just need to change MusicPlayer -> Player # get song info from infolabels self.m_song.artist = unicode(xbmc.getInfoLabel( self.INFOLABEL_ARTIST.format(prefetch=self.prefetch)), "UTF-8") self.m_song.album = unicode(xbmc.getInfoLabel( self.INFOLABEL_ALBUM.format(prefetch=self.prefetch)), "UTF-8") self.m_song.title = unicode(xbmc.getInfoLabel( self.INFOLABEL_TITLE.format(prefetch=self.prefetch)), "UTF-8") file_ = unicode(xbmc.getInfoLabel( self.INFOLABEL_FILEPATH.format(prefetch=self.prefetch)), "UTF-8") # if no proper tags, parse from filename if (not self.m_song.artist or not self.m_song.title): self._get_song_info_from_filename(file_) # no song info found so skip if (self.m_song.artist is None): # set no song info error message and status self.m_song.message = self.m_addon.getLocalizedString(30850) self.m_song.status = False else: # we use localized "Unknown" for non existent albums. # it's used for tagging and saving lyrics self.m_song.album = self.m_song.album or self.m_addon.getLocalizedString(30799) # split basepath from file basepath, file_ = os.path.split(file_) # set shared path if user preference if (self.m_addon.getSetting("lyrics_save_mode") == 0): # set basepath basepath = self.m_addon.getSetting("lyrics_save_path") # set user subfolder preference if (self.m_addon.getSetting("lyrics_subfolder_template") == r"%A/"): subfolder = self.m_song.artist else: subfolder = os.path.join(self.m_song.artist, self.m_song.album) # set song path if user preference elif (self.m_addon.getSetting("lyrics_save_mode") in [1, 2]): # if save to artist's folder, assume artist/album/song.ext folder structure if (self.m_addon.getSetting("lyrics_save_mode") == 2): basepath = os.path.dirname(basepath) # set user preferred subfolder subfolder = self.m_addon.getSetting("lyrics_subfolder") # change extension file_ = u"{file}{ext}".format(file=os.path.splitext(file_)[0], ext=self.m_addon.getSetting("lyrics_save_extension")) # create path to lyric file self.m_song.lyrics_path = xbmc.validatePath( xbmc.makeLegalFilename(os.path.join(basepath, subfolder, file_))).decode("UTF-8") # get lyrics self.get_lyrics(songlist)
def init_global_controls(self): self.log('init_global_controls start') loading_img = xbmc.validatePath('/'.join( (ADDON_PATH, 'resources', 'media', 'loading.gif'))) logo_img = xbmc.validatePath('/'.join( (ADDON_PATH, 'resources', 'media', 'logo.png'))) self.loading_control = ControlImage(480, 250, 400, 219, loading_img) self.preload_control = ControlImage(-1, -1, 1, 1, '') self.background_control = ControlImage(0, 0, 1280, 720, '') self.logo_control = ControlImage(25, 625, 250, 65, logo_img) self.logo_label = ControlLabel(98, 680, 250, 25, '', textColor='FFFFFFFF') self.global_controls = [ self.preload_control, self.background_control, self.loading_control, self.logo_control, self.logo_label ] self.xbmc_window.addControls(self.global_controls) self.log('init_global_controls end')
def viewTallImage(image_url, width, height): log( 'viewTallImage %s: %sx%s' %(image_url, width, height)) useWindow=xbmcgui.WindowXMLDialog('slideshow05.xml', addon_path) screen_w=1920 screen_h=1080 log('screen %dx%d'%(screen_w,screen_h)) try: w=int(float(width)) h=int(float(height)) ar=float(w/h) resize_percent=float(screen_w)/w if w > screen_w: new_h=int(h*resize_percent) else: if abs( h - screen_h) < ( screen_h / 10 ): #if the image height is about 10 percent of the screen height, zoom it a bit new_h=screen_h*2 elif h < screen_h: new_h=screen_h else: new_h=h log( ' image=%dx%d resize_percent %f new_h=%d ' %(w,h, resize_percent, new_h)) loading_img = xbmc.validatePath('/'.join((addon_path, 'resources', 'skins', 'Default', 'media', 'srr_busy.gif' ))) slide_h=new_h-screen_h log( ' slide_h=' + repr(slide_h)) img_control = xbmcgui.ControlImage(0, 0, screen_w, new_h, '', aspectRatio=2) #(values 0 = stretch (default), 1 = scale up (crops), 2 = scale down (black bars) img_loading = xbmcgui.ControlImage(screen_w-100, 0, 100, 100, loading_img, aspectRatio=2) img_control.setImage(image_url, False) useWindow.addControls( [ img_loading, img_control]) img_control.setPosition(0,0) scroll_time=(int(h)/int(w))*20000 img_control.setAnimations( [ ('conditional', "condition=true delay=6000 time=%d effect=slide start=0,-%d end=0,0 tween=sine easing=inout pulse=true" %( scroll_time, slide_h) ), ('conditional', "condition=true delay=0 time=4000 effect=fade start=0 end=100 " ) , ] ) useWindow.doModal() useWindow.removeControls( [img_control,img_loading] ) del useWindow except Exception as e: log(" EXCEPTION viewTallImage:="+ str( sys.exc_info()[0]) + " " + str(e) )
def authorize(self): result = True if(not self.setup()): return False #create authorization helper and load default settings gauth = GoogleAuth(xbmc.validatePath(xbmc.translatePath(utils.addon_dir() + '/resources/lib/pydrive/settings.yaml'))) gauth.LoadClientConfigSettings() settings = {"client_id":self.CLIENT_ID,'client_secret':self.CLIENT_SECRET} drive_url = gauth.GetAuthUrl(settings) utils.log("Google Drive Authorize URL: " + drive_url) xbmcgui.Dialog().ok(utils.getString(30010),utils.getString(30056),utils.getString(30102),tinyurl.shorten(drive_url)) code = xbmcgui.Dialog().input(utils.getString(30098) + ' ' + utils.getString(30103)) gauth.Auth(code) gauth.SaveCredentialsFile(xbmc.validatePath(xbmc.translatePath(utils.data_dir() + 'google_drive.dat'))) return result
def downloadFile(LocalRoot,RemoteRoot,FileName): local_path = xbmc.validatePath(os.path.join(LocalRoot,FileName)) local_dir = os.path.dirname(local_path) if not os.path.exists(local_dir): os.makedirs(local_dir) URLPath = RemoteRoot+FileName.replace("\\","/") f = open(local_path,'wb') try: f.write(urllib2.urlopen(URLPath).read()) temp = 1 except: temp = 0 f.close() return temp
def check_cached_logo(logopath, url): if (not xbmcvfs.exists(logopath)) and url: xbmcvfs.mkdir(logopath) log("Created directory [%s] to download logo from [%s]" %( logopath, url), xbmc.LOGDEBUG) logopath = download_logo(logopath, url, "tadb") return logopath else: logopath = logopath + 'logo.png' logopath = xbmc.validatePath(logopath) if xbmcvfs.exists(logopath): log("Logo has already been downloaded and is in cache. Path is %s" % logopath, xbmc.LOGDEBUG) return logopath else: log("No local logo and no cached logo", xbmc.LOGDEBUG) return None
def init(self, uri, subtitles): if plugin.get_setting("dlpath") == "": addon = xbmcaddon.Addon() addonname = addon.getAddonInfo('name') line1 = "You have not set a download path in the settings." if plugin.get_setting("keep_files", bool): line2 = "This path will be used to store all your downloads." else: line2 = "This path will be used to store temp files that will be deleted after playback stops." line3 = "File will not play until a download path is set." xbmcgui.Dialog().ok(addonname,line1, line2, line3) raise Exception("Download path not set: You must set a download path in the settings.") self.display_name = "" self.torrent2http_options = { "uri": uri, "dlpath": xbmc.validatePath(xbmc.translatePath(plugin.get_setting("dlpath"))) or ".", "dlrate": plugin.get_setting("max_download_rate") or "0", "encryption": plugin.get_setting("encryption"), } if "://" in self.torrent2http_options["dlpath"]: # Translate smb:// url to UNC path on windows, very hackish if PLATFORM["os"] == "windows" and self.torrent2http_options["dlpath"].lower().startswith("smb://"): self.torrent2http_options["dlpath"] = self.torrent2http_options["dlpath"].replace("smb:", "").replace("/", "\\") else: plugin.notify("Downloading to an unmounted network share is not supported. Resetting.", delay=15000) plugin.set_setting("dlpath", "") self.torrent2http_options["dlpath"] = "." # Check for Android and FAT32 SD card issues if PLATFORM["os"] == "android" and self.torrent2http_options["dlpath"] != ".": from koditorrent.utils import get_path_fs fs = get_path_fs(self.torrent2http_options["dlpath"]) if fs == "vfat": # FAT32 is not supported plugin.notify("Downloading to FAT32 is not supported. Resetting.", delay=15000) plugin.set_setting("dlpath", "") self.torrent2http_options["dlpath"] = "." if plugin.get_setting("keep_files", bool): plugin.log.info("Will keep file after playback.") self.torrent2http_options["keep"] = None self.on_playback_started = [] self.on_playback_resumed = [] self.on_playback_paused = [] self.on_playback_stopped = [] self.subtitles = subtitles return self
def _get_folder_images(self, path): self.log('_get_folder_images started with path: %s' % repr(path)) _, files = xbmcvfs.listdir(path) images = [ xbmc.validatePath(path + f) for f in files if f.lower()[-3:] in ('jpg', 'png') ] #if addon.getSetting('recursive') == 'true': # for directory in dirs: # if directory.startswith('.'): # continue # images.extend( # self._get_folder_images( # xbmc.validatePath('/'.join((path, directory, ''))) # ) # ) self.log('_get_folder_images ends') return images
def downloadUrl(title, url, image, subtitlesURL): #=========================================================================================== # analogical playPlayable() see line 299 #=========================================================================================== xbmc.log('"downloadUrl reached"') if subtitlesURL and _subtitles_: subtitleFilePath = xbmc.translatePath( os.path.join( _addon_.getSetting('download_folder').decode('utf8'), title + '.srt')) subtitleFilePath = xbmc.validatePath(subtitleFilePath) subtitleFilePathUnicode = subtitleFilePath.decode('utf8') urllib.urlretrieve(subtitlesURL, subtitleFilePathUnicode) with open(subtitleFilePathUnicode, 'r') as subtitleFile: titulky = subtitleFile.readlines() noveTitulky = adjustFormat(titulky) with open(subtitleFilePathUnicode, 'w') as vystupSoubor: vystupSoubor.writelines(noveTitulky) downloadAndMerge(url, title)
def hide_loading_indicator(self): bg_img = xbmc.validatePath('/'.join( (ADDON_PATH, 'resources', 'media', self.background_image))) self.loading_control.setAnimations([ ('conditional', 'effect=fade start=100 end=0 time=500 condition=true') ]) self.background_control.setAnimations([ ('conditional', 'effect=fade start=0 end=100 time=500 delay=500 condition=true') ]) self.logo_control.setAnimations([ ('conditional', 'effect=fade start=0 end=100 time=500 delay=500 condition=true') ]) self.logo_label.setAnimations([ ('conditional', 'effect=fade start=0 end=100 time=500 delay=500 condition=true') ]) self.background_control.setImage(bg_img)
def walkTree(self, directory, recurse=True): if (utils.getSettingBool('verbose_logging')): utils.log('walking ' + directory + ', recurse: ' + str(recurse)) if (directory[-1:] == '/' or directory[-1:] == '\\'): directory = directory[:-1] if (self.vfs.exists(directory + self.pathSep)): dirs, files = self.vfs.listdir(directory) if (recurse): # create all the subdirs first for aDir in dirs: dirPath = xbmc.validatePath( xbmc.translatePath(directory + self.pathSep + aDir)) file_ext = aDir.split('.')[-1] # check if directory is excluded if (not any( dirPath.startswith(exDir) for exDir in self.exclude_dir)): self.addFile("-" + dirPath) # catch for "non directory" type files shouldWalk = True for s in file_ext: if (s in self.not_dir): shouldWalk = False if (shouldWalk): self.walkTree(dirPath) # copy all the files for aFile in files: filePath = xbmc.translatePath(directory + self.pathSep + aFile) self.addFile(filePath)
def loadIncludesFiles(self): if self._includesFilesLoaded: return basePath = getXBMCSkinPath('') for i in xpath.find('//include', xpath.findnode('//includes', self.xml)): fileAttr = i.attributes.get('file') if fileAttr: xmlName = xbmc.validatePath(fileAttr.value) p = os.path.join(basePath, xmlName) if not os.path.exists(p): continue xml = minidom.parse(p) includes = xpath.findnode('includes', xml) xpath.findnode('..', i).replaceChild(includes, i) for sub_i in xpath.find('.//include', includes): nameAttr = sub_i.attributes.get('name') if nameAttr: self.includesMap[nameAttr.value] = sub_i else: nameAttr = i.attributes.get('name') if nameAttr: self.includesMap[nameAttr.value] = i.cloneNode(True) self._includesFilesLoaded = True
def validatePath(path, trans_none=''): """ Kodi 19: xbmc.validatePath is deprecated and might be removed in future kodi versions. Please use xbmcvfs.validatePath instead. @param path: cadena a convertir platform specific @type path: str @rtype: str @return: devuelve la cadena con el path ajustado """ if not path or not isinstance(path, (unicode, basestring, bytes)): if path is None: path = trans_none return path if PY3 and xbmc_vfs: if PY3 and isinstance(path, bytes): path = path.decode(fs_encoding) path = xbmcvfs.validatePath(path) if isinstance(path, bytes): path = path.decode(fs_encoding) elif KODI: path = xbmc.validatePath(path) return path
def add_item_to_library(self, item_path, item_url): error = False new = False item_path = xbmc.validatePath(item_path) if item_path: item_path = xbmc.translatePath(item_path) dir = os.path.dirname(item_path) if not xbmcvfs.exists(dir): try: xbmcvfs.mkdirs(dir) except Exception: error = True util.error('Failed to create directory 1: ' + dir) if not xbmcvfs.exists(item_path): try: file_desc = xbmcvfs.File(item_path, 'w') file_desc.write(str(item_url)) file_desc.close() new = True except Exception, e: util.error('Failed to create .strm file: ' + item_path + " | " + str(e)) error = True
def get_local_cover(BaseString, artist, track, albumtitle): pathToCDArt = "" try: if albumtitle: pathToCDArt = xbmc.validatePath(BaseString + artist + "/" + albumtitle + "/cdart.png" ) if not xbmcvfs.exists( pathToCDArt ): pathToCDArt = "" pathToAlbumCover = xbmc.validatePath(BaseString + artist + "/" + albumtitle + "/cover.png") log("Looking for an album cover in %s" % pathToAlbumCover, xbmc.LOGDEBUG) if xbmcvfs.exists(pathToAlbumCover): log("Found a local 'cover.png' and set AlbumCover to [%s]" % pathToAlbumCover, xbmc.LOGDEBUG) return 1, pathToAlbumCover, pathToCDArt pathToAlbumCover = xbmc.validatePath(BaseString + artist + "/" + albumtitle + "/folder.jpg") log("Looking for an album cover in %s" % pathToAlbumCover, xbmc.LOGDEBUG) if xbmcvfs.exists(pathToAlbumCover): log("Found a local 'folder.jpg' and set AlbumCover to [%s]" % pathToAlbumCover, xbmc.LOGDEBUG) return 1, pathToAlbumCover, pathToCDArt pathToAlbumCover = xbmc.validatePath(BaseString + artist + "/" + track + "/folder.jpg") pathToCDArt = xbmc.validatePath(BaseString + artist + "/" + track + "/cdart.png" ) if not xbmcvfs.exists( pathToCDArt ): pathToCDArt = "" if xbmcvfs.exists(pathToAlbumCover): log("Found a local 'folder.jpg' and set AlbumCover to [%s]" % pathToAlbumCover, xbmc.LOGDEBUG) return 1, pathToAlbumCover, pathToCDArt pathToAlbumCover = xbmc.validatePath(BaseString + artist + "/" + track + "/cover.png") log("Looking for an album cover in %s (last attempt before using thumbnail)" % pathToAlbumCover, xbmc.LOGDEBUG) if xbmcvfs.exists(pathToAlbumCover): log("Found a local 'cover.png' and set AlbumCover to [%s]" % pathToAlbumCover, xbmc.LOGDEBUG) return 1, pathToAlbumCover, pathToCDArt if artist in dict4: return 2, dict4[artist], None return 0, None, None except Exception as e: log("Got an error trying to look for a cover!! [%s]" % str(e), xbmc.LOGERROR) pass return None
def findTrack(self, artistname, trackname): # Find the song chars0 = trackname[0].lower() + trackname[1].lower() chars1 = trackname[0].upper() + trackname[1].lower() chars2 = trackname[0].lower() + trackname[1].upper() chars3 = trackname[0].upper() + trackname[1].upper() req = { "jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "id": "libSongs", "params": { "properties": [ "artist", "duration", "album", "title", "file", "thumbnail", "fanart", "track" ], "limits": { "start": 0, "end": 1000 }, "sort": { "order": "ascending", "method": "track", "ignorearticle": True }, "filter": { "and": [ { "field": "artist", "operator": "is", "value": artistname.encode('utf-8') }, { "or": [ #{"field": "title", "operator": "is", "value": trackname.lower().encode('utf-8')} { "field": "title", "operator": "startswith", "value": chars0.encode('utf-8') }, { "field": "title", "operator": "startswith", "value": chars1.encode('utf-8') }, { "field": "title", "operator": "startswith", "value": chars2.encode('utf-8') }, { "field": "title", "operator": "startswith", "value": chars3.encode('utf-8') }, ] } ] } } } rpcresp = xbmc.executeJSONRPC(json.dumps(req)) # xbmc.log(str(rpcresp)) rpcresp = json.loads(rpcresp) found = 0 < int(rpcresp['result']['limits']['end']) ret = None #strInd = ' ' if found: # xbmc.log(str(rpcresp)) trackname_stripped = strip_accents(trackname.strip().lower()) for s in rpcresp['result']['songs']: if trackname_stripped == strip_accents( s['title'].strip().lower()): path = xbmc.translatePath(s['file']) path = xbmc.validatePath(path) if os.path.exists(path): ret = s break log("Found in library, but file doesn't exist: %s" % path) xbmc.executebuiltin( 'Notification(%s,%s, 1000)' % ("File doesn't exist", os.path.basename(path))) #if artistname.lower() <> ret['artist'][0].lower() or trackname.lower() <> ret['title'].lower(): #if ret is not None: # strInd = '+++ ' # xbmc.log(strInd + str(artistname.encode('utf-8')) + " -- " + str(trackname.encode('utf-8'))) # xbmc.log(' ' + str(ret['artist'][0].encode('utf-8')) + " -- " + str(ret['title'].encode('utf-8'))) #else: #xbmc.log('NOT found track ' + str(artistname.encode('utf-8')) + " -- " + str(trackname.encode('utf-8'))) #xbmc.log(strInd + str(artistname.encode('utf-8')) + " -- " + str(trackname.encode('utf-8'))) return ret
def findSubtitles(self, stream): try: if not self.getSetting('subtitles') == 'true': raise Exception() imdb = stream['imdb'] season = None episode = None if 'season' in stream: season = stream['season'] if 'episode' in stream: episode = stream['episode'] util.debug("[SC] Hladam titulky") langDict = { 'Afrikaans': 'afr', 'Albanian': 'alb', 'Arabic': 'ara', 'Armenian': 'arm', 'Basque': 'baq', 'Bengali': 'ben', 'Bosnian': 'bos', 'Breton': 'bre', 'Bulgarian': 'bul', 'Burmese': 'bur', 'Catalan': 'cat', 'Chinese': 'chi', 'Croatian': 'hrv', 'Czech': 'cze', 'Danish': 'dan', 'Dutch': 'dut', 'English': 'eng', 'Esperanto': 'epo', 'Estonian': 'est', 'Finnish': 'fin', 'French': 'fre', 'Galician': 'glg', 'Georgian': 'geo', 'German': 'ger', 'Greek': 'ell', 'Hebrew': 'heb', 'Hindi': 'hin', 'Hungarian': 'hun', 'Icelandic': 'ice', 'Indonesian': 'ind', 'Italian': 'ita', 'Japanese': 'jpn', 'Kazakh': 'kaz', 'Khmer': 'khm', 'Korean': 'kor', 'Latvian': 'lav', 'Lithuanian': 'lit', 'Luxembourgish': 'ltz', 'Macedonian': 'mac', 'Malay': 'may', 'Malayalam': 'mal', 'Manipuri': 'mni', 'Mongolian': 'mon', 'Montenegrin': 'mne', 'Norwegian': 'nor', 'Occitan': 'oci', 'Persian': 'per', 'Polish': 'pol', 'Portuguese': 'por,pob', 'Portuguese(Brazil)': 'pob,por', 'Romanian': 'rum', 'Russian': 'rus', 'Serbian': 'scc', 'Sinhalese': 'sin', 'Slovak': 'slo', 'Slovenian': 'slv', 'Spanish': 'spa', 'Swahili': 'swa', 'Swedish': 'swe', 'Syriac': 'syr', 'Tagalog': 'tgl', 'Tamil': 'tam', 'Telugu': 'tel', 'Thai': 'tha', 'Turkish': 'tur', 'Ukrainian': 'ukr', 'Urdu': 'urd' } codePageDict = { 'ara': 'cp1256', 'ar': 'cp1256', 'cs': 'cp1250', 'ell': 'cp1253', 'el': 'cp1253', 'heb': 'cp1255', 'he': 'cp1255', 'sk': 'cp1250', 'tur': 'cp1254', 'tr': 'cp1254', 'rus': 'cp1251', 'ru': 'cp1251' } quality = [ 'bluray', 'hdrip', 'brrip', 'bdrip', 'dvdrip', 'webrip', 'mhd', 'hdtv' ] langs = [] try: try: langs = langDict[self.getSetting( 'subtitles.lang.1')].split(',') except: langs.append(langDict[self.getSetting('subtitles.lang.1')]) except: pass try: try: langs = langs + langDict[self.getSetting( 'subtitles.lang.2')].split(',') except: langs.append(langDict[self.getSetting('subtitles.lang.2')]) except: pass server = xmlrpclib.Server('http://api.opensubtitles.org/xml-rpc', verbose=0) token = server.LogIn('', '', 'en', 'XBMC_Subtitles_v1')['token'] util.debug("[SC] TOKEN: %s" % token) sublanguageid = ','.join(langs) imdbid = re.sub('[^0-9]', '', imdb) if season is not None and episode is not None: result = server.SearchSubtitles(token, [{ 'sublanguageid': sublanguageid, 'imdbid': imdbid, 'season': season, 'episode': episode }])['data'] fmt = ['hdtv'] else: result = server.SearchSubtitles(token, [{ 'sublanguageid': sublanguageid, 'imdbid': imdbid }])['data'] try: vidPath = stream['url'] except: vidPath = '' fmt = re.split('\.|\(|\)|\[|\]|\s|\-', vidPath) fmt = [i.lower() for i in fmt] fmt = [i for i in fmt if i in quality] filter = [] result = [i for i in result if i['SubSumCD'] == '1'] for lang in langs: filter += [ i for i in result if i['SubLanguageID'] == lang and any( x in i['MovieReleaseName'].lower() for x in fmt) ] filter += [ i for i in result if i['SubLanguageID'] == lang and any( x in i['MovieReleaseName'].lower() for x in quality) ] filter += [i for i in result if i['SubLanguageID'] == lang] try: lang = xbmc.convertLanguage(filter[0]['SubLanguageID'], xbmc.ISO_639_1) except: lang = filter[0]['SubLanguageID'] content = [ filter[0]['IDSubtitleFile'], ] content = server.DownloadSubtitles(token, content) content = base64.b64decode(content['data'][0]['data']) content = str( zlib.decompressobj(16 + zlib.MAX_WBITS).decompress(content)) subtitle = xbmc.validatePath(xbmc.translatePath('special://temp/')) subtitle = os.path.join(subtitle, 'AutomatickeTitulky.%s.srt' % lang) codepage = codePageDict.get(lang, '') if codepage and self.getSetting('subtitles.utf') == 'true': try: content_encoded = codecs.decode(content, codepage) content = codecs.encode(content_encoded, 'utf-8') except: pass file = xbmcvfs.File(subtitle, 'w') file.write(str(content)) file.close() return subtitle except Exception: util.debug("[SC] Neriesim TITULKY") util.debug(traceback.format_exc()) pass
def pathAddon(path): special = xbmc.validatePath(xbmcaddon.Addon().getAddonInfo('path').replace('\\','/')+path.replace('\\','/')) special = special.replace('//','/').replace('special:/','special://') return special
def loop(self): from xbmctorrent.utils import SafeDialogProgress from xbmctorrent.player import OverlayText has_resolved = False plugin.log.info("Starting AceStream...") def safe_cast(val, to_type, default=None): try: return to_type(val) except ValueError: return default engine_params = { "filename": self.file_name, "host": plugin.get_setting("ace_host", str) or DEFAULT_ACESTREAM_HOST, "port": safe_cast(plugin.get_setting("ace_port"), int, DEFAULT_ACESTREAM_PORT), "keep_enc": plugin.get_setting("ace_keep_encripted", bool) } if plugin.get_setting("keep_files", bool): plugin.log.info("Will keep file after playback.") engine_params["dlpath"] = xbmc.validatePath( xbmc.translatePath( plugin.get_setting("dlpath") or "special://temp/" + plugin.id)) if engine_params["dlpath"] and "://" in engine_params["dlpath"]: # Translate smb:// url to UNC path on windows, very hackish if PLATFORM["os"] == "windows" and engine_params[ "dlpath"].lower().startswith("smb://"): engine_params["dlpath"] = engine_params["dlpath"].replace( "smb:", "").replace("/", "\\") with closing(AceEngine(**engine_params)) as engine: plugin.log.info("Opening download dialog...") # Get currently selected item current_item = get_current_list_item() with closing(SafeDialogProgress(delay_create=0)) as dialog: dialog.create("AceStream Player") connected = engine.try_to_connect() ready = False n = 1 start = time.time() while (time.time() - start) < ACESTREAM_CONNECTION_TIMEOUT: if xbmc.abortRequested or dialog.iscanceled(): return dialog.update(0, self.file_name, "Попытка соединения с AceStream (%s)" % n) if not connected: plugin.log.info("Starting AceStream engine") if engine.start(): xbmc.sleep(ACESTREAM_CONNECTION_POLL) connected = engine.try_to_connect() continue else: if engine.is_ready(): break plugin.log.info("Engine is not ready") xbmc.sleep(ACESTREAM_CONNECTION_POLL) n = n + 1 if not engine.is_ready(): return dialog.update( 0, self.file_name, "Соединение установлено. Запуск загрузки данных...") if not engine.play( self.torrent, self.index, is_raw=self.is_raw): return while not has_resolved: if xbmc.abortRequested or dialog.iscanceled(): return status = engine.get_status() if status["error"]: dialog.update( int(status["progress"]), *[ self.file_name, STATE_STRS[status["status"]], status["error"] ]) xbmc.sleep(PLAYING_EVENT_INTERVAL) return if status["state"] > 0 and status["status"]: dialog.update(int(status["progress"]), *self._get_status_lines(status)) if status["state"] >= 2 and status[ "status"] == "dl" and not has_resolved: # Downloading? if int(status["progress"]) >= 0: plugin.log.info("Resolving to %s" % status["url"]) has_resolved = True if not current_item["info"].get("title"): current_item["label"] = self.file_name current_item["path"] = status["url"] plugin.set_resolved_url(current_item) break xbmc.sleep(PLAYING_EVENT_INTERVAL) # We are now playing plugin.log.info("Now playing torrent...") with closing( OverlayText(w=OVERLAY_WIDTH, h=OVERLAY_HEIGHT, alignment=XBFONT_CENTER_X | XBFONT_CENTER_Y)) as overlay: with nested( self.attach(overlay.show, self.on_playback_paused), self.attach(overlay.hide, self.on_playback_resumed, self.on_playback_stopped), self.attach(engine.on_start, self.on_playback_started), self.attach(engine.on_pause, self.on_playback_paused), self.attach(engine.on_resume, self.on_playback_resumed), self.attach(engine.on_stop, self.on_playback_stopped), self.attach(engine.on_seek, self.on_playback_seek), self.attach(engine.on_end, self.on_playback_ended), self.attach(self.pause, engine.on_playback_paused), self.attach(self.play, engine.on_playback_resumed)): while not xbmc.abortRequested and self.isPlaying( ) and not engine.error: overlay.text = "\n".join( self._get_status_lines(engine.get_status())) xbmc.sleep(PLAYING_EVENT_INTERVAL) plugin.log.info("Closing AceStream player.")
def list_collections(args, random=False): """List collections. """ fields = "".join([ "collection.collection_id,", "collection.season,", "collection.name,", "collection.description,", "collection.complete,", "collection.media_count" ]) options = { 'series_id': args.series_id, 'fields': fields, 'sort': 'desc', 'limit': args.count } request = makeAPIRequest(args, 'list_collections', options) if request['error'] is False: if random: try: random_media_type = str(args.media_type) except: random_media_type = 'anime' try: random_name = request['data'][0]['name'] except: random_name = "[New random]" random_li = xbmcgui.ListItem(label=random_name) random_li.setInfo(type="Video", infoLabels={"Title": "[New random]"}) random_li.setArt({ 'fanart': xbmc.translatePath(args._addon.getAddonInfo('fanart')), 'thumb': xbmc.validatePath( xbmc.translatePath( args._addon.getAddonInfo('path') + "\dice.png")) }) xbmcplugin.addDirectoryItem( handle=int(sys.argv[1]), url=crm.build_url( crm.set_info_defaults( args, { 'mode': 'get_random', 'media_type': random_media_type, 'title': random_name })), listitem=random_li, isFolder=True) if len(request['data']) <= 1: for collection in request['data']: args.complete = '1' if collection['complete'] else '0' args.id = collection['collection_id'] return list_media(args) else: queued = (args.series_id in args.user_data['queue']) for collection in request['data']: complete = '1' if collection['complete'] else '0' crm.add_item(args, { 'title': collection['name'].encode("utf8"), 'filterx': args.name, 'mode': 'list_media', 'count': str(args.count), 'id': collection['collection_id'], 'plot': collection['description'].encode("utf8"), 'complete': complete, 'season': str(collection['season']), 'series_id': args.series_id, 'thumb': args.icon, 'fanart_image': args.fanart }, isFolder=True, queued=queued) crm.endofdirectory('none')
def search_tadb( local_logo, mbid, artist, dict4, dict5,checked_all_artists): """ Checks to see if there is an existing logo locally in the scripts addon_data directory. If not, attempts to find a logo on theaudiodb and download it into the cache. As radio stations often drop 'The' from band names (eg 'Who' for 'The Who', 'Kinks' for 'The Kinks') if we fail to find a match for the artist we try again with 'The ' in front of the artist name Finally we do a search with the MBID we previously obtained Args: mbid - the mbid from musicbrainz artist - name of the artist to search for dict4 - dictionary of banner URL's dict5 - dictionary of thumbnail URL's returns: artist - artist name logopath - full path to downloaded logo URL1 - URL to artist banner on TADB URL2 - URL to artist thumb on TADB """ log("----------------------------------------------------", xbmc.LOGDEBUG) log(" Entered routine 'search_tadb' ", xbmc.LOGDEBUG) log("----------------------------------------------------", xbmc.LOGDEBUG) logopath = '' url = '' response = None log("Looking up %s on tadb.com" % artist, xbmc.LOGDEBUG) searchartist = artist.replace( " ", "+" ) log ("[search_tadb] : searchartist = %s" % searchartist) tadburl = 'https://www.theaudiodb.com/api/v1/json/%s' % rusty_gate.decode( 'base64' ) searchurl = tadburl + '/search.php?s=' + (searchartist.encode('utf-8')) log("URL for TADB is : %s" % searchurl, xbmc.LOGDEBUG) response = load_url(searchurl) log(str(response)) if (response == '{"artists":null}') or (response == '') or ('!DOCTYPE' in response) or (response == None): searchartist = 'The+' + searchartist tadburl = 'https://www.theaudiodb.com/api/v1/json/%s' % rusty_gate.decode( 'base64' ) searchurl = tadburl + '/search.php?s=' + (searchartist.encode('utf-8')) log("Looking up %s on tadb.com with URL %s" % (searchartist, searchurl), xbmc.LOGDEBUG) response = load_url(searchurl) log(response, xbmc.LOGDEBUG) if (response == '{"artists":null}') or (response == '') or ('!DOCTYPE' in response) or (response == None): log("Artist not found on tadb", xbmc.LOGDEBUG) # Lookup failed on name - try with MBID log("Looking up with MBID", xbmc.LOGDEBUG) tadburl = 'https://www.theaudiodb.com/api/v1/json/%s' % rusty_gate.decode( 'base64' ) searchurl = tadburl + '/artist-mb.php?i=' + mbid log("MBID URL is : %s" % searchurl, xbmc.LOGDEBUG) response = load_url(searchurl) if not response: log("Failed to find any artist info on theaudiodb", xbmc.LOGDEBUG) return artist, None, None, None if response is not None: searching = _json.loads(response) artist, url, dict4, dict5, mbid = parse_data(artist, searching, searchartist, dict4, dict5, mbid) if url and (not local_logo): log("No local logo", xbmc.LOGDEBUG) logopath = logostring + mbid + '/' logopath = xbmc.validatePath(logopath) logopath = check_cached_logo (logopath, url) else: logopath = logostring + mbid + '/' logopath = xbmc.validatePath(logopath) logopath = check_cached_logo (logopath, url) if searchartist in dict4: return artist, logopath, dict4[searchartist], dict5[searchartist] else: return artist, logopath, None, None
def join(path1, path2): path = os.path.join(path1, path2) return xbmc.validatePath(path)
def exists(path): # path is a file or folder result = xbmcvfs.exists(xbmc.validatePath(path)) return result == 1
def viewTallImage(image_url, width, height): log('viewTallImage %s: %sx%s' % (image_url, width, height)) #image_url=unescape(image_url) #special case for handling reddituploads urls #log( 'viewTallImage %s: %sx%s' %(image_url, width, height)) #useWindow=xbmcgui.WindowDialog() useWindow = xbmcgui.WindowXMLDialog('slideshow05.xml', addon_path) #useWindow.setCoordinateResolution(1) #screen_w=useWindow.getHeight() #1280 #screen_h=useWindow.getWidth() #720 screen_w = 1920 screen_h = 1080 log('screen %dx%d' % (screen_w, screen_h)) try: w = int(float(width)) h = int(float(height)) ar = float(w / h) resize_percent = float(screen_w) / w if w > screen_w: new_h = int(h * resize_percent) else: if abs(h - screen_h) < ( screen_h / 10 ): #if the image height is about 10 percent of the screen height, zoom it a bit new_h = screen_h * 2 elif h < screen_h: new_h = screen_h else: new_h = h log(' image=%dx%d resize_percent %f new_h=%d ' % (w, h, resize_percent, new_h)) loading_img = xbmc.validatePath('/'.join( (addon_path, 'resources', 'skins', 'Default', 'media', 'srr_busy.gif'))) slide_h = new_h - screen_h log(' slide_h=' + repr(slide_h)) #sy=0 #note: y-axis not accurate. 0 does not always indicate top of screen img_control = xbmcgui.ControlImage( 0, 0, screen_w, new_h, '', aspectRatio=2 ) #(values 0 = stretch (default), 1 = scale up (crops), 2 = scale down (black bars) #img_control = useWindow.getControl( 101 ) img_loading = xbmcgui.ControlImage(screen_w - 100, 0, 100, 100, loading_img, aspectRatio=2) #the cached image is of lower resolution. we force nocache by using setImage() instead of defining the image in ControlImage() img_control.setImage(image_url, False) useWindow.addControls([img_loading, img_control]) #useWindow.addControl( img_control ) img_control.setPosition(0, 0) scroll_time = (int(h) / int(w)) * 20000 img_control.setAnimations([ ('conditional', "condition=true delay=6000 time=%d effect=slide start=0,-%d end=0,0 tween=sine easing=inout pulse=true" % (scroll_time, slide_h)), ('conditional', "condition=true delay=0 time=4000 effect=fade start=0 end=100 " ), ]) useWindow.doModal() useWindow.removeControls([img_control, img_loading]) del useWindow except Exception as e: log(" EXCEPTION viewTallImage:=" + str(sys.exc_info()[0]) + " " + str(e))
def play(self, uri, item, subtitle=None, subtitle_provider=None): # torrent2http_options = { "uri": str(uri), # Files "download_path": xbmc.validatePath(xbmc.translatePath(__addon__.getSetting("download_path"))) or CACHE_DIR, "keep_files": __addon__.getSetting("keep_files") == 'true' and True or False, "keep_complete": __addon__.getSetting("keep_complete") == 'true' and True or False, "keep_incomplete": __addon__.getSetting("keep_incomplete") == 'true' and True or False, # Network "download_kbps": int(__addon__.getSetting("download_kbps")) or 0, "upload_kbps": int(__addon__.getSetting("upload_kbps")) or 0, "connections_limit": int(__addon__.getSetting("connections_limit")) or 200, "encryption": int(__addon__.getSetting("encryption")) or 1, # Port "listen_port": int(__addon__.getSetting("listen_port")) or 6881, "use_random_port": __addon__.getSetting("use_random_port") == 'true' and True or False, # Peers "torrent_connect_boost": int(__addon__.getSetting("torrent_connect_boost")) or 50, "connection_speed": int(__addon__.getSetting("connection_speed")) or 50, "peer_connect_timeout": int(__addon__.getSetting("peer_connect_timeout")) or 15, "min_reconnect_time": int(__addon__.getSetting("min_reconnect_time")) or 60, "max_failcount": int(__addon__.getSetting("max_failcount")) or 3, # Features "enable_tcp": __addon__.getSetting("enable_tcp") == 'true' and False or True, "enable_dht": __addon__.getSetting("enable_dht") == 'true' and False or True, "enable_lsd": __addon__.getSetting("enable_lsd") == 'true' and False or True, "enable_utp": __addon__.getSetting("enable_utp") == 'true' and False or True, "enable_scrape": __addon__.getSetting("enable_scrape") == 'true' and True or False, "enable_upnp": __addon__.getSetting("enable_upnp") == 'true' and False or True, "enable_natpmp": __addon__.getSetting("enable_natpmp") == 'true' and False or True, # Additional "trackers": not __addon__.getSetting("trackers") == "" and __addon__.getSetting['trackers'].split(',') or None, "dht_routers": not __addon__.getSetting("dht_routers") == "" and __addon__.getSetting['dht_routers'].split(',') or None, # Log / Debug "log_stats": __addon__.getSetting("debug") == 'true' and True or False, "debug_alerts": __addon__.getSetting("debug_alerts") == 'true' and True or False, # Bin "binaries_path": os.path.join(RESOURCES_PATH, 'bin') } # List item self.item = item ### if torrent2http_options['download_kbps'] <= 0: torrent2http_options['download_kbps'] = None if torrent2http_options['upload_kbps'] <= 0: torrent2http_options['upload_kbps'] = None elif torrent2http_options['upload_kbps'] < 15: notify(__addon__.getLocalizedString(30313)) torrent2http_options['upload_kbps'] = 15 __addon__.setSetting('upload_kbps', '15') log('(Player) Start the torrent2http file', xbmc.LOGDEBUG) with closing(Engine(**torrent2http_options)) as engine: # Start engine and instruct torrent2http to begin download first file engine.start(0) log('(Player) Pre-Loading the movie', xbmc.LOGDEBUG) ready = False with closing(SafeDialogProgress(delay_create=0)) as dialog: dialog.create(self.item['info']['title']) dialog.update(self.progressed, *self._get_status_lines()) file_id = None while not xbmc.abortRequested and not dialog.iscanceled(): xbmc.sleep(self.progressSleepTime) # Get status status = engine.status() # Check if there is loading error and raise exception engine.check_torrent_error(status) # We need a file id if file_id is None: # Get torrent files list, filtered by video file type only files = engine.list(media_types=[MediaType.VIDEO]) if files is None: continue # Torrent has no video files if not files: raise AnErrorOccurred(30316) # Select first matching file file_id = files[0].index file_status = files[0] # Get file status file_status = engine.file_status(file_id) if not file_status: continue if status.state == State.DOWNLOADING: self._calculate_progress(int(self.item['info'].get('duration', 0)), status, file_status) if self.progressed >= 100: ready = True break dialog.update(int(self.progressed), *self._get_status_lines(status)) continue if status.state in [State.FINISHED, State.SEEDING]: ready = True break if ready: log('(Player) Finished with pre-loading the movie', xbmc.LOGDEBUG) # Download subtitle if subtitle: log('(Player) Download subtitle', xbmc.LOGDEBUG) dialog.update(99, *[__addon__.getLocalizedString(30019), ' ', ' ']) path = file_status.save_path subtitle = subtitle_provider.download(subtitle, os.path.dirname(path), ".".join([os.path.splitext(os.path.basename(path))[0], self.item['stream_info']['subtitle']['language']])) dialog.update(100, *[__addon__.getLocalizedString(30020), ' ', ' ']) elif xbmc.abortRequested or dialog.iscanceled(): log('(Player) Pre-Loading was canceled or interrupted', xbmc.LOGDEBUG) if ready: # Resolve URL to XBMC self.item.update({"path": file_status.url}) # Starts the playback log('(Player) Start the playback', xbmc.LOGDEBUG) #xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, self.item) plugin.set_resolved_url(self.item) for _ in xrange(60): if not self.isPlaying(): xbmc.sleep(1000) continue if subtitle: log('(Player) Adds the subtitle to the player', xbmc.LOGDEBUG) self.setSubtitles(subtitle) # Wait for the playback to finish log('(Player) Wait for the playback to finish', xbmc.LOGDEBUG) with closing(OverlayText()) as self.overlay: while not xbmc.abortRequested and self.isPlaying(): if self.overlay.isShowing(): self.overlay.setText("\n".join(self._get_status_lines(engine.status()))) xbmc.sleep(100) log('(Player) Playback is finished', xbmc.LOGDEBUG) if subtitle and torrent2http_options["keep_files"] == False and torrent2http_options["keep_complete"] == False and torrent2http_options["keep_incomplete"] == False: # Delete subtitle log('(Player) Delete subtitle', xbmc.LOGDEBUG) subtitle_provider.remove(subtitle) break else: log('(Player) Playback is terminated due to timeout', xbmc.LOGERROR)
def downloadAndMerge(my_url, title): #=========================================================================================== # download all ts part of video and merge them to one ts file #=========================================================================================== xbmc.log('"downloadAndMerge reached"') r = requests.get(my_url) # r.text.split() - převede str na list playlist = [ line.rstrip() for line in r.text.split() if line.rstrip().endswith('.m3u8') ] xbmc.log('"Adresa playlistu je: "' + str(playlist)) r = requests.get(playlist[0]) xbmc.log('"Výsledek stažení playlistu: "' + str(r.status_code)) ts_filenames = [ line.rstrip() for line in r.text.split() if line.rstrip().endswith('.ts') ] pocetTSFiles = len(ts_filenames) downloadPath = _addon_.getSetting('download_folder') xbmc.log('"Download folder is: "' + str(downloadPath)) ts_local_names = [] pDialog = xbmcgui.DialogProgress() ret = pDialog.create('Saving file: ' + title.encode('utf8') + '.ts') for i, ts_file in enumerate(ts_filenames): local_name = ts_file.split('/')[-2] + ts_file.split('/')[-1] downloadFilePath = xbmc.translatePath( os.path.join( _addon_.getSetting('download_folder').decode('utf8'), local_name)) xbmc.log('"After translatePath: "' + downloadFilePath) downloadFilePath = xbmc.validatePath(downloadFilePath) xbmc.log('"After validatePath: "' + downloadFilePath) with open(downloadFilePath.decode('utf8'), mode='wb') as localfile: r = requests.get(ts_file) localfile.write(r.content) # end="\r" návrat vozíku, ale nefunkční v emulátoru konzole :-) pDialog.update(int(float(i + 1) / pocetTSFiles * 100), 'downloading part:' + local_name.encode('utf8')) xbmc.log('"Staženo: "' + str(i + 1) + 'z' + str(pocetTSFiles) + '" souborů"') ts_local_names.append(downloadFilePath) pDialog.close() del pDialog # open one ts_file from the list after another and append them to merged.ts mergedFilePath = xbmc.translatePath( os.path.join( _addon_.getSetting('download_folder').decode('utf8'), title + '.ts')) mergedFilePath = xbmc.validatePath(mergedFilePath) xbmc.log('"Spojuju soubory do:" ' + mergedFilePath) pDialog = xbmcgui.DialogProgress() ret = pDialog.create('Merging file', title.encode('utf8') + '.ts and cleaning') with open(mergedFilePath.decode('utf8'), 'wb') as merged: for i, ts_file in enumerate(ts_local_names): ts_file = ts_file.decode('utf8') with open(ts_file, 'rb') as mergefile: shutil.copyfileobj(mergefile, merged) os.remove(ts_file) pDialog.update(int(float(i + 1) / pocetTSFiles * 100), 'merging part:' + local_name.encode('utf8')) pDialog.close() del (pDialog) xbmc.log('"Download finished :-)"')
def get_hdlogo(mbid, artist): """ Get the first found HD clearlogo from fanart.tv if it exists. Args: The MBID of the artist and the artist name Returns : The fully qualified path to an existing logo or newly downloaded logo or None if the logo is not found """ log("----------------------------------------------------", xbmc.LOGDEBUG) log(" Entered routine 'get_hdlogo' ", xbmc.LOGDEBUG) log("----------------------------------------------------", xbmc.LOGDEBUG) try: if checked_all_artists == False: url = "https://fanart.tv/artist/" + mbid logopath = logostring + mbid + "/logo.png" logopath = xbmc.validatePath(logopath) if not xbmcvfs.exists(logopath): log("Searching for HD logo on fanart.tv", xbmc.LOGDEBUG) response = urllib.urlopen(url).read() if response == '': log("No response from fanart.tv", xbmc.LOGDEBUG) return None index1 = response.find("<h2>HD ClearLOGO<div") if index1 != -1: index2 = response.find('<div class="image_options">',index1) anylogos = response[index1:index2] if "currently no images" in anylogos: log("No HD logos found for %s" % artist, xbmc.LOGDEBUG) return None index3= response.find('<a href="/api/download.php?type=download') index4 = response.find('class="btn btn-inverse download"') chop = response[index3+9:index4-2] url = "https://fanart.tv" + chop logopath = logostring + mbid + '/' logopath = xbmc.ValidatePath(logopath) xbmcvfs.mkdir(logopath) logopath = download_logo(logopath,url) return logopath else: logopath = logostring + mbid + '/logo.png' logopath = xbmc.validatePath(logopath) if xbmcvfs.exists(logopath): log("Logo downloaded previously", xbmc.LOGDEBUG) return logopath else: log("No logo found on fanart.tv", xbmc.LOGDEBUG) return None else: logopath = logostring + mbid + '/logo.png' logopath = xbmc.validatePath(logopath) if xbmcvfs.exists(logopath): log("Logo downloaded previously", xbmc.LOGDEBUG) return logopath else: log("No logo in cache for %s " % artist, xbmc.LOGDEBUG) return None except: log("Error searching fanart.tv for a logo", xbmc.LOGERROR) exc_type, exc_value, exc_traceback = sys.exc_info() log(repr(traceback.format_exception(exc_type, exc_value,exc_traceback)), xbmc.LOGERROR) return None