def _get_database(self): """get reference to our sqllite _database - performs basic integrity check""" dbpath = ADDON.getAddonInfo('profile') dbfile = xbmcvfs.translatePath("%s/simplecache.db" % dbpath) if not xbmcvfs.exists(dbpath): xbmcvfs.mkdirs(dbpath) 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 zip_tofile(src, dst): '''method to create a zip file from all files/dirs in a path''' import zipfile zip_file = zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) abs_src = os.path.abspath(xbmcvfs.translatePath(src)) zip_file = add_tozip(src, zip_file, abs_src) zip_file.close()
def selectview(self, content_type="other", current_view=None, display_none=False): '''reads skinfile with all views to present a dialog to choose from''' cur_view_select_id = None label = "" all_views = [] if display_none: listitem = xbmcgui.ListItem(label="None") listitem.setProperty("id", "None") all_views.append(listitem) # read the special skin views file if sys.version_info.major == 3: views_file = try_decode( xbmcvfs.translatePath('special://skin/extras/views.xml')) else: views_file = try_decode( xbmc.translatePath('special://skin/extras/views.xml')) if xbmcvfs.exists(views_file): doc = parse(views_file) listing = doc.documentElement.getElementsByTagName('view') itemcount = 0 for view in listing: label = xbmc.getLocalizedString( int(view.attributes['languageid'].nodeValue)) viewid = view.attributes['value'].nodeValue mediatypes = view.attributes['type'].nodeValue.lower().split( ",") if label.lower() == current_view.lower( ) or viewid == current_view: cur_view_select_id = itemcount if display_none: cur_view_select_id += 1 if (("all" in mediatypes or content_type.lower() in mediatypes) and (not "!" + content_type.lower() in mediatypes) and not getCondVisibility( "Skin.HasSetting(SkinHelper.view.Disabled.%s)" % viewid)): image = "special://skin/extras/viewthumbs/%s.jpg" % viewid listitem = xbmcgui.ListItem(label=label, iconImage=image) listitem.setProperty("viewid", viewid) listitem.setProperty("icon", image) all_views.append(listitem) itemcount += 1 dialog = DialogSelect("DialogSelect.xml", "", listing=all_views, windowtitle=self.addon.getLocalizedString(32012), richlayout=True) dialog.autofocus_id = cur_view_select_id dialog.doModal() result = dialog.result del dialog if result: viewid = result.getProperty("viewid") label = try_decode(result.getLabel()) return (viewid, label) else: return (None, None)
def translatePath(path): try: from xbmcvfs import translatePath except ImportError: from xbmc import translatePath return translatePath(path)
def get_local_db_path(db_filename): # First ensure database folder exists from resources.lib.common import folder_exists db_folder = xbmcvfs.translatePath(os.path.join(G.DATA_PATH, 'database')) if not folder_exists(db_folder): xbmcvfs.mkdirs(db_folder) return os.path.join(db_folder, db_filename)
def main(): dialog = xbmcgui.Dialog() __addon__ = xbmcaddon.Addon(sys.argv[1]) __addonProfile__ = xbmcvfs.translatePath(__addon__.getAddonInfo('profile')) customiser_json = os.path.join(__addonProfile__, 'customiser.json') toEdit = sys.argv[2] with open(customiser_json, 'r+') as f: data = json.load(f) if toEdit == 'category': kw = 'hidden_category' msg = 'UnSelect Cateogry\'s to show in Category List again' elif toEdit == 'channel': kw = 'hidden_channel' msg = 'UnSelect Channel\'s to show in Channel List again' cdata = data.get(kw) ckeys = list(cdata.keys()) items = [] for c in ckeys: li = xbmcgui.ListItem(cdata.get(c), c) items.append(li) pre = list(range(0, len(items))) ret = dialog.multiselect(msg, items, preselect=pre) if ret: to_del = list(set(pre) ^ set(ret)) for i in to_del: cdata.pop(ckeys[i]) f.seek(0) json.dump(data, f, indent=4) f.truncate()
def zapiSession(self): zapiSession = ZapiSession(xbmcvfs.translatePath(__addon__.getAddonInfo('profile'))) PROVIDER = __addon__.getSetting('provider') debug('Provider '+str(PROVIDER)) if PROVIDER == "0": ZAPIUrl = "https://zattoo.com" elif PROVIDER == "1": ZAPIUrl = "https://www.1und1.tv" elif PROVIDER == "2": ZAPIURL = "https://tvonline.swb-gruppe.de" elif PROVIDER == "3": ZAPIUrl = "https://tvplus.m-net.de" elif PROVIDER == "4": ZAPIUrl = "https://player.waly.tv" elif PROVIDER == "5": ZAPIUrl = "https://www.meinewelt.cc" elif PROVIDER == "6": ZAPIUrl = "https://www.bbv-tv.net" elif PROVIDER == "7": ZAPIUrl = "https://www.vtxtv.ch" elif PROVIDER == "8": ZAPIUrl = "https://tv.salt.ch" elif PROVIDER == "9": ZAPIUrl = "https://iptv.glattvision.ch" elif PROVIDER == "10": ZAPIUrl = "https://www.saktv.ch" elif PROVIDER == "11": ZAPIUrl = "https://nettv.netcologne.de" elif PROVIDER == "12": ZAPIUrl = "https://tvonline.ewe.de" elif PROVIDER == "13": ZAPIUrl = "https://www.quantum-tv.com" if zapiSession.init_session(__addon__.getSetting('username'), __addon__.getSetting('password'), ZAPIUrl): return zapiSession else: # show home window, zattooHiQ settings and quit xbmc.executebuiltin('ActivateWindow(10000)') xbmcgui.Dialog().ok(__addon__.getAddonInfo('name'), __addon__.getLocalizedString(31902)) __addon__.openSettings() zapiSession.renew_session() xbmcgui.Dialog().ok(__addon__.getAddonInfo('name'), local(24074)) import sys sys.exit()
def loadFavourites(self): entries = list() if sys.version_info[0] > 2: path = xbmcvfs.translatePath('special://userdata/favourites.xml') else: path = xbmc.translatePath('special://userdata/favourites.xml') if os.path.exists(path): f = open(path) xml = f.read() f.close() try: doc = ElementTree.fromstring(xml) for node in doc.findall('favourite'): value = node.text if value[0:11] == 'PlayMedia("': value = value[11:-2] elif value[0:10] == 'PlayMedia(': value = value[10:-1] elif value[0:22] == 'ActivateWindow(10025,"': value = value[22:-9] elif value[0:22] == 'ActivateWindow(10025,': value = value[22:-9] else: continue entries.append((node.get('name'), value)) except ExpatError: pass return entries
def __get_archive_file_name(self, filename): log.info("ArchiveHandler.__get_archive_file_name") archive_file_name = 'archive://%(archive_file)s' % { 'archive_file': quote_plus(xbmcvfs.translatePath(filename)) } log.debug("archive_file_name: {0}".format(archive_file_name)) return archive_file_name
def showNotification(message): xbmcgui.Dialog().notification(getString(30010), message, time=4000, icon=xbmcvfs.translatePath( __Addon.getAddonInfo('path') + "/resources/images/icon.png"))
def preview(addon: xbmcaddon.Addon, timerid: int, player: 'xbmc.Player') -> None: addon_dir = xbmcvfs.translatePath(addon.getAddonInfo('path')) timer = Timer.init_from_settings(timerid) if timer._is_playing_media_timer(): icon_file = os.path.join( addon_dir, "resources", "assets", "icon.png") xbmcgui.Dialog().notification(addon.getLocalizedString( 32027), addon.getLocalizedString(32110) % addon.getLocalizedString(32004 + timerid), icon=icon_file) if is_script(timer.s_path): run_addon(timer.s_path) elif timer.s_mediatype == PICTURE: play_slideshow(timer.s_path, shuffle=timer.b_shuffle) else: playlist = build_playlist(path=timer.s_path, label=timer.s_label) player.play(playlist) else: xbmcgui.Dialog().notification(addon.getLocalizedString( 32027), addon.getLocalizedString(32109))
def download(self, link): dest_dir = os.path.join( xbmcvfs.translatePath(self.addon.getAddonInfo('profile')), 'temp') dest = os.path.join(dest_dir, "download.tmp") log(__name__, 'Downloading subtitles from %s' % link) res = urllib.request.urlopen(link) subtitles_filename = re.search( "Content\-Disposition: attachment; filename=\"(.+?)\"", str(res.info())).group(1) log(__name__, 'Filename: %s' % subtitles_filename) subtitles_format = re.search("\.(\w+?)$", subtitles_filename, re.IGNORECASE).group(1) log(__name__, "Subs in %s" % subtitles_format) subtitles_data = res.read() log(__name__, 'Saving to file %s' % dest) zip_file = open(dest, 'wb') zip_file.write(subtitles_data) zip_file.close() final_dest = os.path.join(dest_dir, "download." + subtitles_format) log(__name__, 'Changing filename to %s' % final_dest) os.rename(dest, final_dest) return final_dest
def playPlayable(playable, skipAutoQuality=False, forceQuality=None): image = xbmcvfs.translatePath( os.path.join(_addon_.getAddonInfo('path'), 'resources', 'media', 'logo_' + playable.ID.lower() + '_400x225.png')) if isinstance(playable, ivysilani.Programme): image = playable.imageURL if _auto_quality_ and not skipAutoQuality and not forceQuality: url = autoSelectQuality(playable) if url: playUrl(playable.title, url, image, subtitles=getattr(playable, 'subs_available', False)) return if forceQuality: quality = ivysilani.Quality(forceQuality) url = playable.url(quality) if url: playUrl(playable.title, url, image, subtitles=getattr(playable, 'subs_available', False)) return qualities = playable.available_qualities() for quality in qualities: addDirectoryItem(quality.label(), url=_baseurl_ + "?force_quality=" + str(quality) + "&play=" + playable.ID, title=_toString(playable.title), image=image, isFolder=False) xbmcplugin.endOfDirectory(_handle_, updateListing=False, cacheToDisc=False)
def __init__(self, url, idFilme, pastaData, temporada, episodio, nome, logo, imdb): xbmc.Player.__init__(self) self.url = url self.temporada = temporada self.episodio = episodio self.playing = True self.tempo = 0 self.tempoTotal = 0 self.idFilme = idFilme self.pastaData = xbmcvfs.translatePath(pastaData) self.nome = nome self.logo = logo self.imdb = imdb self.API_SITE = controlo.API_SITE if not xbmcvfs.exists(os.path.join(pastaData, 'tracker')): xbmcvfs.mkdirs(os.path.join(pastaData, 'tracker')) if self.temporada != 0 and self.episodio != 0: self.pastaVideo = os.path.join( self.pastaData, 'tracker', str(self.idFilme) + '_S' + str(self.temporada) + 'x' + str(self.episodio) + '.mrpiracy') self.content = 'episode' else: self.pastaVideo = os.path.join(self.pastaData, 'tracker', str(self.idFilme) + '.mrpiracy') self.content = 'movie'
def __init__(self): if py3: self._dirname = xbmcvfs.translatePath('special://temp') else: self._dirname = xbmc.translatePath('special://temp') for subdir in ('xbmcup', 'script.module.libtorrent'): self._dirname = os.path.join(self._dirname, subdir) if not xbmcvfs.exists(self._dirname): xbmcvfs.mkdir(self._dirname)
def get_skinsettings(filters=None): '''get all active skin settings''' all_skinsettings = [] guisettings_path = 'special://profile/addon_data/%s/settings.xml' % xbmc.getSkinDir( ) if xbmcvfs.exists(guisettings_path): doc = parse(xbmcvfs.translatePath(guisettings_path)) skinsettings = doc.documentElement.getElementsByTagName('setting') for skinsetting in skinsettings: settingname = skinsetting.attributes['id'].nodeValue settingtype = skinsetting.attributes['type'].nodeValue # we must grab the actual values because the xml file only updates at restarts if settingtype == "bool": if "$INFO" not in settingname and xbmc.getCondVisibility( "Skin.HasSetting(%s)" % settingname): settingvalue = "true" else: settingvalue = "false" else: settingvalue = xbmc.getInfoLabel("Skin.String(%s)" % settingname) if not filters: # no filter - just add all settings we can find all_skinsettings.append( (settingtype, settingname, settingvalue)) else: # only select settings defined in our filters for filteritem in filters: if filteritem.lower() in settingname.lower(): all_skinsettings.append( (settingtype, settingname, settingvalue)) return all_skinsettings
def play(item_to_play): channel_data = fetch_channel_data(fetch_local_channel_data, fetch_remote_channel_data) xml_data = ET.fromstring(channel_data) try: channel_data = xml_data.find(".//channel[@id='" + item_to_play + "']") channel = Channel(handle, tempdir, channel_data, quality_priority(), format_priority()) except: for element in xml_data.findall(".//channel"): channel = Channel(handle, tempdir, element, quality_priority(), format_priority()) if channel.getid() == item_to_play: break list_item = ListItem(channel.get_simple_element('title'), channel.get_simple_element('description'), channel.get_content_url()) list_item.setArt({ "icon": channel.geticon(), "thumb": channel.getthumbnail(), "fanart": xbmcvfs.translatePath("special://home/addons/%s/fanart.jpg" % __addonid__) }) xbmcplugin.setResolvedUrl(handle, True, list_item)
def download(self, path, url, name): xbmc.log("Downloading {}".format(url), level=xbmc.LOGDEBUG) if xbmcvfs.exists(path): xbmcvfs.delete(path) self.dp.update(0, name) self.path = xbmcvfs.translatePath(path) xbmc.sleep(500) start_time = time.time() u = urlopen(url) meta = u.info() meta_func = meta.getheaders if hasattr(meta, "getheaders") else meta.get_all meta_length = meta_func("Content-Length") file_size = None block_sz = 8192 if meta_length: file_size = int(meta_length[0]) file_size_dl = 0 with xbmcvfs.File(self.path, 'wb') as f: numblocks = 0 while not self.stop: buffer = u.read(block_sz) if not buffer: break f.write(buffer) file_size_dl += len(buffer) numblocks += 1 self.dialogdown(name, numblocks, block_sz, file_size, self.dp, start_time)
def __init__(self): self.conn = None profilePath = xbmcvfs.translatePath(__addon__.getAddonInfo('profile')) if not os.path.exists(profilePath): os.makedirs(profilePath) self.databasePath = os.path.join(profilePath, "zattoo.db") self.connectSQL() self.zapi=self.zapiSession()
def run(): """Run data generators""" log('Updating data...', LogLevel.INFO) provider = get_provider() filepath = os.path.join(xbmcvfs.translatePath(get_addon_profile()), 'playlist.m3u8') log(filepath, LogLevel.DEBUG) PlaylistGenerator(provider=provider).write(filepath=filepath) filepath = os.path.join(xbmcvfs.translatePath(get_addon_profile()), 'epg.xml') log(filepath, LogLevel.DEBUG) EPGGenerator(provider=provider).write(filepath=filepath) log('Channels and programs data updated', LogLevel.INFO)
def refresh_image(imagepath): """tell kodi texture cache to refresh a particular image""" import sqlite3 if sys.version_info.major == 3: dbpath = xbmcvfs.translatePath("special://database/Textures13.db") else: dbpath = xbmc.translatePath("special://database/Textures13.db").decode( 'utf-8') connection = sqlite3.connect(dbpath, timeout=30, isolation_level=None) try: cache_image = connection.execute( 'SELECT cachedurl FROM texture WHERE url = ?', (imagepath, )).fetchone() if sys.version_info.major == 3: if cache_image and isinstance(cache_image, str): if xbmcvfs.exists(cache_image): xbmcvfs.delete("special://profile/Thumbnails/%s" % cache_image) connection.execute('DELETE FROM texture WHERE url = ?', (imagepath, )) else: if cache_image and isinstance(cache_image, (unicode, str)): if xbmcvfs.exists(cache_image): xbmcvfs.delete("special://profile/Thumbnails/%s" % cache_image) connection.execute('DELETE FROM texture WHERE url = ?', (imagepath, )) connection.close() except Exception as exc: log_exception(__name__, exc) finally: del connection
def file_exists(file_path): """ Checks if a given file exists :param file_path: File path to check :return: True if exists """ return xbmcvfs.exists(xbmcvfs.translatePath(file_path))
def load_channels_groups(self): addon = xbmcaddon.Addon() addon_userdata_dir = translatePath(addon.getAddonInfo('profile')) filename = os.path.join(addon_userdata_dir, 'channels_groups.txt') try: with codecs.open(filename, 'r', encoding='utf-8') as file: for line in file: if line[:-1].find(';') != -1: channel_group = line[:-1].split(';') if channel_group[0] in self.channels: groups = self.channels[channel_group[0]] groups.append(channel_group[1]) self.channels.update({channel_group[0]: groups}) else: self.channels.update( {channel_group[0]: [channel_group[1]]}) else: group = line[:-1] if group[0] == '*': self.selected = group[1:] self.groups.append(group[1:]) else: self.groups.append(group) except IOError: self.groups = [] self.channels = {} self.selected = None
def get_system_arch(): if xbmc.getCondVisibility( 'System.Platform.UWP') or '4n2hpmxwrvr6p' in xbmcvfs.translatePath( 'special://xbmc/'): system = 'UWP' elif xbmc.getCondVisibility('System.Platform.Android'): system = 'Android' elif xbmc.getCondVisibility('System.Platform.IOS'): system = 'IOS' else: system = platform.system() if system == 'Windows': arch = platform.architecture()[0] else: try: arch = platform.machine() except: arch = '' #64bit kernel with 32bit userland if ('aarch64' in arch or 'arm64' in arch) and (struct.calcsize("P") * 8) == 32: arch = 'armv7' elif 'arm' in arch: if 'v6' in arch: arch = 'armv6' else: arch = 'armv7' elif arch == 'i686': arch = 'i386' return system, arch
def _writeCronFile(self): # write the cron file in full try: doc = xml.dom.minidom.Document() rootNode = doc.createElement("cron") doc.appendChild(rootNode) for aJob in self.jobs.values(): # create the child newChild = doc.createElement("job") newChild.setAttribute('id', str(aJob.id)) newChild.setAttribute("name", aJob.name) newChild.setAttribute("expression", aJob.expression) newChild.setAttribute("command", aJob.command) newChild.setAttribute("show_notification", aJob.show_notification) newChild.setAttribute("addon", aJob.addon) rootNode.appendChild(newChild) # write the file f = xbmcvfs.File(xbmcvfs.translatePath(self.CRONFILE), "w") doc.writexml(f, " ") f.close() except IOError: utils.log("error writing cron file", xbmc.LOGERROR)
def migrate_library(): # Migrate the Kodi library to the new format of STRM path # - Old STRM: '/play/show/xxxxxxxx/season/xxxxxxxx/episode/xxxxxxxx/' (used before ver 1.7.0) # - New STRM: '/play_strm/show/xxxxxxxx/season/xxxxxxxx/episode/xxxxxxxx/' (used from ver 1.7.0) folders = get_library_subfolders( FOLDER_NAME_MOVIES) + get_library_subfolders(FOLDER_NAME_SHOWS) if not folders: return LOG.debug('Start migrating STRM files') try: with ui.ProgressDialog(True, title='Migrating library to new format', max_value=len(folders)) as progress_bar: for folder_path in folders: folder_name = os.path.basename( xbmcvfs.translatePath(folder_path)) progress_bar.set_message('PLEASE WAIT - Migrating: ' + folder_name) _migrate_strm_files(folder_path) except Exception as exc: # pylint: disable=broad-except LOG.error('Migrating failed: {}', exc) import traceback LOG.error(traceback.format_exc()) ui.show_ok_dialog('Migrating library to new format', ( 'Library migration has failed.[CR]' 'Before try play a Netflix video from library, you must run manually the library migration, ' 'otherwise you will have add-on malfunctions.[CR][CR]' 'Open add-on settings on "Library" section, and select "Import existing library".' ))
def _get_upnext_info(self, info_data, metadata, is_played_from_strm): """Get the data to send to Up Next add-on""" upnext_info = { 'current_episode': _upnext_info(self.videoid, *info_data[self.videoid.value]), 'next_episode': _upnext_info(self.videoid_next_episode, *info_data[self.videoid_next_episode.value]) } if is_played_from_strm: # The current video played is a STRM, then generate the path of next STRM file file_path = G.SHARED_DB.get_episode_filepath( self.videoid_next_episode.tvshowid, self.videoid_next_episode.seasonid, self.videoid_next_episode.episodeid) url = xbmcvfs.translatePath(file_path) else: url = common.build_url( videoid=self.videoid_next_episode, mode=G.MODE_PLAY, params={'profile_guid': G.LOCAL_DB.get_active_profile_guid()}) upnext_info['play_url'] = url if 'creditsOffset' in metadata[0]: upnext_info['notification_offset'] = metadata[0]['creditsOffset'] return upnext_info
def verifyFileSize(filename): if not filename: return True ADDONID = 'plugin.audio.mp3streams' ADDON = xbmcaddon.Addon(ADDONID) precache = int(ADDON.getSetting('pre-cache').replace('K', '')) filename = xbmcvfs.translatePath(filename) log('VERIFYING %s' % filename) count = 100 while count > 0: if xbmcgui.Window(10000).getProperty(filename) == 'EXCEPTION': xbmcgui.Window(10000).clearProperty(filename) log('Exception downloading %s' % filename) return False log('verifyFileSize %d' % count) if xbmcvfs.exists(filename): size = xbmcvfs.File(filename).size() log('CURRENT SIZE = %d' % size) if size == 212 and unavailable(filename): return False if size > precache * 1024: log(size) log('FILE SIZE VERIFIED!!') return True count -= 1 xbmc.sleep(500) return False
class Settings(object): advancedsettings_file = xbmcvfs.translatePath("special://profile/advancedsettings.xml") defaults = { ("video", "playcountminimumpercent"): 90, ("video", "ignoresecondsatstart"): 180, ("video", "ignorepercentatend"): 8, } _locs = { "Россия": "ru", "Нидерланды": "nl", } def __getattr__(self, name): if name == "advanced": return self._get_adv_setting if name.startswith("show_"): return eval(xbmcaddon.Addon().getSetting(name).title()) if name == "loc": self._locs[xbmcaddon.Addon().getSetting(name)] return xbmcaddon.Addon().getSetting(name) def __setattr__(self, name, value): if value is not None: value = str(value) xbmcaddon.Addon().setSetting(name, value) def _get_adv_setting(self, *args): try: root = ET.parse(self.advancedsettings_file).getroot() except (ET.ParseError, IOError): return self.defaults.get(args) elem = root.find("./{}".format("/".join(args))) return elem.text if elem else self.defaults.get(args)
def __init__(self, base_url=None, handle=None): addon = self.get_addon() self.base_url = base_url self.handle = handle self.addon_path = xbmcvfs.translatePath(addon.getAddonInfo('path')) self.addon_profile = xbmcvfs.translatePath(addon.getAddonInfo('profile')) self.addon_name = addon.getAddonInfo('id') self.addon_version = addon.getAddonInfo('version') self.language = addon.getLocalizedString self.logging_prefix = '[%s-%s]' % (self.addon_name, self.addon_version) if not xbmcvfs.exists(self.addon_profile): xbmcvfs.mkdir(self.addon_profile) if self.get_setting('first_run'): self.get_addon().openSettings() self.set_setting('first_run', 'false') self.vp = Viaplay(self.addon_profile, self.get_country_code(), True)