Beispiel #1
0
 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)
     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
Beispiel #2
0
def writeConfig(cfile, value=''):
    cfgfile = os.path.join(configpath, cfile)
    cfglockfile = os.path.join(configpath, cfile + '.lock')

    if not xbmcvfs.exists(configpath):
        xbmcvfs.mkdirs(configpath)

    while True:
        if not xbmcvfs.exists(cfglockfile):
            l = xbmcvfs.File(cfglockfile, 'w')
            l.write(str(time.time()))
            l.close()
            if value == '':
                xbmcvfs.delete(cfgfile)
            else:
                f = xbmcvfs.File(cfgfile, 'w')
                f.write(value.__str__())
                f.close()
            xbmcvfs.delete(cfglockfile)
            xbmcvfs.delete(cfglockfile)
            return True
        else:
            l = xbmcvfs.File(cfglockfile)
            modified = l.read()
            modified = float(modified) if modified else 0
            l.close()
            if time.time() - modified > 0.1:
                xbmcvfs.delete(cfglockfile)
Beispiel #3
0
def verify_kodi_defaults():
    ''' Make sure we have the kodi default folder in place.
    '''
    node_path = xbmc.translatePath("special://profile/library/video")

    if not os.path.exists(node_path):
        try:
            shutil.copytree(
                src=xbmc.translatePath("special://xbmc/system/library/video"),
                dst=xbmc.translatePath("special://profile/library/video"))
        except Exception as error:
            LOG.warning(error)
            xbmcvfs.mkdir(node_path)

    for index, node in enumerate(['movies', 'tvshows', 'musicvideos']):
        file = os.path.join(node_path, node, "index.xml")

        if xbmcvfs.exists(file):

            xml = etree.parse(file).getroot()
            xml.set('order', str(17 + index))
            tree = etree.ElementTree(xml)
            tree.write(file)

    playlist_path = xbmc.translatePath("special://profile/playlists/video")

    if not xbmcvfs.exists(playlist_path):
        xbmcvfs.mkdirs(playlist_path)
Beispiel #4
0
def get_device():
    device = None
    if xbmc.getCondVisibility('system.platform.windows'):
        device = 'Windows'
    if xbmc.getCondVisibility('system.platform.linux') \
            and not xbmc.getCondVisibility('system.platform.android'):
        device = 'Linux'
    if xbmc.getCondVisibility('system.platform.osx'):
        device = 'Darwin'
    if xbmc.getCondVisibility('system.platform.android'):
        device = 'Android'

    if xbmcvfs.exists('/proc/device-tree/model'):
        with closing(xbmcvfs.File('/proc/device-tree/model')) as open_file:
            if 'Raspberry Pi' in open_file.read():
                device = 'Raspberry Pi'

    if xbmcvfs.exists('/etc/os-release'):
        with closing(xbmcvfs.File('/etc/os-release')) as open_file:
            contents = open_file.read()
            if 'libreelec' in contents:
                device = 'LibreELEC'
            if 'osmc' in contents:
                device = 'OSMC'

    if device is None:
        try:
            device = platform.system()
        except:  # pylint: disable=bare-except
            try:
                device = platform.platform(terse=True)
            except:  # pylint: disable=bare-except
                device = sys.platform

    return device
 def create_color_swatch_image(self, colorstring):
     '''helper method to generate a colorized image using PIL'''
     color_image_file = None
     if colorstring:
         paths = []
         paths.append(u"%s%s.png" % (COLORFILES_PATH, colorstring))
         if xbmcvfs.exists(SKINCOLORFILE):
             paths.append(u"%s%s.png" % (SKINCOLORFILES_PATH, colorstring))
         for color_image_file in paths:
             if not xbmcvfs.exists(color_image_file):
                 if SUPPORTS_PIL:
                     # create image with PIL
                     try:
                         colorstring = colorstring.strip()
                         if colorstring[0] == '#':
                             colorstring = colorstring[1:]
                         a, r, g, b = colorstring[:2], colorstring[
                             2:4], colorstring[4:6], colorstring[6:]
                         a, r, g, b = [int(n, 16) for n in (a, r, g, b)]
                         color = (r, g, b, a)
                         img = Image.new("RGBA", (16, 16), color)
                         img.save(color_image_file)
                         del img
                     except Exception as exc:
                         log_exception(__name__, exc)
                 else:
                     # create image with online service if no pil support
                     xbmcvfs.copy(
                         "https://dummyimage.com/16/%s/%s.png" %
                         (colorstring[2:], colorstring[2:]),
                         color_image_file)
                     log_msg(
                         "Local PIL module not available, generating color swatch image with online service",
                         xbmc.LOGWARNING)
     return color_image_file
Beispiel #6
0
def writeConfig(cfile, value):
    cfgfile = OSPJoin(writeConfig.configPath, cfile)
    cfglockfile = OSPJoin(writeConfig.configPath, cfile + '.lock')

    if not xbmcvfs.exists(writeConfig.configPath):
        xbmcvfs.mkdirs(writeConfig.configPath)

    while True:
        if not xbmcvfs.exists(cfglockfile):
            l = xbmcvfs.File(cfglockfile, 'w')
            l.write(str(time.time()))
            l.close()
            if value == '':
                xbmcvfs.delete(cfgfile)
            else:
                f = xbmcvfs.File(cfgfile, 'w')
                f.write(value.__str__())
                f.close()
            xbmcvfs.delete(cfglockfile)
            return True
        else:
            try:
                l = xbmcvfs.File(cfglockfile)
                modified = float(l.read())
                l.close()
                if time.time() - modified > 0.1:
                    xbmcvfs.delete(cfglockfile)
            except:
                pass
Beispiel #7
0
def ffmpeg_location():
    ffmpeg_src = xbmc.translatePath(plugin.get_setting('ffmpeg', str))

    if xbmc.getCondVisibility('system.platform.android'):
        ffmpeg_dst = '/data/data/%s/ffmpeg' % android_get_current_appid()

        if (plugin.get_setting('ffmpeg', str) != plugin.get_setting(
                'ffmpeg.last', str)) or (not xbmcvfs.exists(ffmpeg_dst)
                                         and ffmpeg_src != ffmpeg_dst):
            xbmcvfs.copy(ffmpeg_src, ffmpeg_dst)
            plugin.set_setting('ffmpeg.last',
                               plugin.get_setting('ffmpeg', str))

        ffmpeg = ffmpeg_dst
    else:
        ffmpeg = ffmpeg_src

    if ffmpeg:
        try:
            st = os.stat(ffmpeg)
            if not (st.st_mode & stat.S_IXUSR):
                try:
                    os.chmod(ffmpeg, st.st_mode | stat.S_IXUSR)
                except:
                    pass
        except:
            pass
    if xbmcvfs.exists(ffmpeg):
        return ffmpeg
    else:
        xbmcgui.Dialog().notification("IPTV Archive Downloader",
                                      addon.getLocalizedString(30056))
Beispiel #8
0
def verify_kodi_defaults():
    ''' Make sure we have the kodi default folder in place.
    '''

    source_base_path = xbmc.translatePath("special://xbmc/system/library/video")
    dest_base_path = xbmc.translatePath("special://profile/library/video")

    # Make sure the files exist in the local profile.
    # TODO: Investigate why this is needed.
    # I would think Kodi pulls data from the default profile
    # if we don't do this.
    for source_path, dirs, files in os.walk(source_base_path):
        relative_path = os.path.relpath(source_path, source_base_path)
        dest_path = os.path.join(dest_base_path, relative_path)

        if not os.path.exists(dest_path):
            os.mkdir(os.path.normpath(dest_path))

        for file_name in files:
            dest_file = os.path.join(dest_path, file_name)
            copy = False

            if not os.path.exists(dest_file):
                copy = True
            elif os.path.splitext(file_name)[1].lower() == '.xml':
                try:
                    etree.parse(dest_file)
                except etree.ParseError:
                    LOG.warning("Unable to parse `{}`, recovering from default.".format(dest_file))
                    copy = True

            if copy:
                source_file = os.path.join(source_path, file_name)
                LOG.debug("Copying `{}` -> `{}`".format(source_file, dest_file))
                xbmcvfs.copy(source_file, dest_file)

    # This code seems to enforce a fixed ordering.
    # Is it really desirable to force this on users?
    # The default (system wide) order is [10, 20, 30] in Kodi 19.
    for index, node in enumerate(['movies', 'tvshows', 'musicvideos']):
        file_name = os.path.join(dest_base_path, node, "index.xml")

        if xbmcvfs.exists(file_name):
            try:
                tree = etree.parse(file_name)
            except etree.ParseError:
                LOG.error("Unable to parse `{}`".format(file_name))
                LOG.exception("We ensured the file was OK above, something is wrong!")

            tree.getroot().set('order', str(17 + index))
            tree.write(file_name)

    playlist_path = xbmc.translatePath("special://profile/playlists/video")

    if not xbmcvfs.exists(playlist_path):
        xbmcvfs.mkdirs(playlist_path)
Beispiel #9
0
 def fileExists(self, dest):
     if xbmcvfs.exists(dest):
         if not xbmcgui.Dialog().yesno(ADDON_NAME,
                                       LANGUAGE(30004),
                                       dest.rsplit('/', 1)[-1],
                                       nolabel=LANGUAGE(30005),
                                       yeslabel=LANGUAGE(30006)):
             return True
     elif CLEAN and xbmcvfs.exists(self.lastPath):
         self.deleleAPK(self.lastPath)
     return False
Beispiel #10
0
 def run(self):
     while not self.myMonitor.abortRequested():
         if self.myMonitor.waitForAbort(2): break
         elif not M3UXMLTV or self.running: continue
         lastCheck = float(REAL_SETTINGS.getSetting('Last_Scan') or 0)
         conditions = [xbmcvfs.exists(M3U_FILE),xbmcvfs.exists(XMLTV_FILE)]
         if (time.time() > (lastCheck + 3600)) or False in conditions:
             self.running = True
             if self.myChannels.buildService(): 
                 REAL_SETTINGS.setSetting('Last_Scan',str(time.time()))
                 notificationDialog(LANGUAGE(30007))
             self.running = False
    def __init__(self, *args, **kwargs):
        super(xbmcgui.WindowXMLDialog, self).__init__()
        self.action_exitkeys_id = [10, 13]
        self.win = xbmcgui.Window(10000)
        self.build_colors_list()
        self.result = -1

        # check paths
        if xbmcvfs.exists(
                SKINCOLORFILE) and not xbmcvfs.exists(SKINCOLORFILES_PATH):
            xbmcvfs.mkdirs(SKINCOLORFILES_PATH)
        if not xbmcvfs.exists(COLORFILES_PATH):
            xbmcvfs.mkdirs(COLORFILES_PATH)
Beispiel #12
0
def save_merkliste(merkliste, my_ordner):
    PLog('save_merkliste:')

    fname = WATCHFILE
    if SETTINGS.getSetting(
            'pref_merkextern') == 'true':  # externe Merkliste gewählt?
        fname = SETTINGS.getSetting('pref_MerkDest_path')
        if fname == '' or xbmcvfs.exists(fname) == False:
            PLog("merkextern: %s, %d" % (fname, xbmcvfs.exists(fname)))
            msg1 = u"Merkliste nicht gefunden\nBitte Settings überprüfen"
            return False, err_msg
    PLog(fname)

    # Merkliste + Ordnerinfo + Ordner:
    err_msg = ''  # gefüllt von Aufrufer
    if my_ordner == '' or my_ordner == []:  # Fallback Basis-Ordner-Liste
        my_ordner = ORDNER
    my_ordner = " ".join(my_ordner)
    ordner_info = "\n".join(ORDNER_INFO)
    merkliste = "<merkliste>\n%s</merkliste>\n\n%s\n\n<ordnerliste>%s</ordnerliste>\n" %\
     (merkliste, ordner_info, my_ordner)
    try:
        if '//' not in fname:
            err_msg = RSave(fname, merkliste,
                            withcodec=True)  # Merkliste speichern
            if err_msg:
                ret = False
            else:
                ret = True
        else:
            PLog("xbmcvfs_fname: " + fname)
            f = xbmcvfs.File(fname, 'w')
            if PYTHON2:
                ret = f.write(merkliste)
                f.close()
            else:  # Python3: Bytearray
                buf = bytearray()
                buf.extend(merkliste.encode())
                ret = f.write(buf)
                f.close()
            PLog("xbmcvfs_ret: " + str(ret))
        if ret:
            sync_list_intern(src_file=fname,
                             dest_file=WATCHFILE)  # Synchronisation
        return ret, err_msg

    except Exception as exception:
        ret = False
        PLog(str(exception))
        err_msg = str(exception)
        return ret, err_msg
    def __init__(self, output_path=None, forced=False):
        self.working_path = ADDON_PROFILE
        self.output_path = output_path or xbmc.translatePath(
            settings.get('output_dir', '').strip() or self.working_path)

        if not xbmcvfs.exists(self.working_path):
            xbmcvfs.mkdirs(self.working_path)

        if not xbmcvfs.exists(self.output_path):
            xbmcvfs.mkdirs(self.output_path)

        self.forced = forced
        self.tmp_file = os.path.join(self.working_path, 'iptv_merge_tmp')
        self._playlist_epgs = []
Beispiel #14
0
    def _makedirs(path):
        if len(path) == 0:
            return False

        if(xbmcvfs.exists(path)):
            return True

        success = xbmcvfs.mkdir(path)
        if success == False:
            if path == os.path.dirname(xbmcvfs.translatePath(path)):
                return False

            if FileAccess._makedirs(os.path.dirname(xbmcvfs.translatePath(path))):
                return xbmcvfs.mkdir(path)
        return xbmcvfs.exists(path)
Beispiel #15
0
def safe_copy(src, dst, del_src=False):
    src = xbmc.translatePath(src)
    dst = xbmc.translatePath(dst)

    if not xbmcvfs.exists(src) or same_file(src, dst):
        return

    if xbmcvfs.exists(dst):
        xbmcvfs.delete(dst)

    log.debug('Copying: {} > {}'.format(src, dst))
    xbmcvfs.copy(src, dst)

    if del_src:
        xbmcvfs.delete(src)
Beispiel #16
0
 def toggle(self, mode):
     # create profile file
     if not xbmcvfs.exists(ADDON_PATH_DATA):
         xbmcvfs.mkdir(ADDON_PATH_DATA)
     # try read last active profile
     f = xbmcvfs.File(os.path.join(ADDON_PATH_DATA, 'profile'))
     try:
         profile = f.read()
     except IOError:
         profile = ''
     f.close()
     if profile:
         if (len(self.aProfile) == 1) or (profile not in self.aProfile):
             profile = self.aProfile[0]
         else:
             ip = int(self.aProfile.index(profile))
             if len(self.aProfile) == ip:
                 try:
                     profile = self.aProfile[0]
                 except IndexError:
                     profile = self.aProfile[0]
             else:
                 try:
                     profile = self.aProfile[ip + 1]
                 except IndexError:
                     profile = self.aProfile[0]
     else:
         profile = self.aProfile[0]
     self.profile(profile)
Beispiel #17
0
def reset_artwork():
    ''' Remove all existing texture.
    '''
    thumbnails = xbmc.translatePath('special://thumbnails/')

    if xbmcvfs.exists(thumbnails):
        dirs, ignore = xbmcvfs.listdir(thumbnails)

        for directory in dirs:
            ignore, thumbs = xbmcvfs.listdir(
                os.path.join(thumbnails, directory))

            for thumb in thumbs:
                LOG.debug("DELETE thumbnail %s", thumb)
                xbmcvfs.delete(os.path.join(thumbnails, directory, thumb))

    with Database('texture') as texdb:
        texdb.cursor.execute(
            "SELECT tbl_name FROM sqlite_master WHERE type='table'")

        for table in texdb.cursor.fetchall():
            name = table[0]

            if name != 'version':
                texdb.cursor.execute("DELETE FROM " + name)

    LOG.info("[ reset artwork ]")
Beispiel #18
0
    def use_up_next(self):
        upnext_id = 'service.upnext'
        s_upnext_enabled = self._get_setting('use_up_next', fresh=True)

        try:
            _ = xbmcaddon.Addon(upnext_id)
            has_upnext = True
            upnext_disabled = False
        except RuntimeError:
            addon_xml = xbmc.translatePath('special://home/addons/%s/addon.xml' % upnext_id)
            if xbmcvfs.exists(addon_xml):  # if addon.xml exists, add-on is disabled
                has_upnext = True
                upnext_disabled = True
            else:
                has_upnext = False
                upnext_disabled = False

        if s_upnext_enabled and has_upnext and upnext_disabled:
            enable_upnext = xbmcgui.Dialog().yesno(self.addon_name,
                                                   self.settings.getLocalizedString(30688))
            if enable_upnext:
                upnext_disabled = not self.enable_addon(upnext_id)

        if (not has_upnext or upnext_disabled) and s_upnext_enabled:
            self._set_setting('use_up_next', False)
            return False

        return s_upnext_enabled and has_upnext and not upnext_disabled
    def _mnt_path(cls):
        ''' Return mount path, usually ~/.kodi/userdata/addon_data/tmp/mnt '''
        mnt_path = os.path.join(cls._temp_path(), 'mnt')
        if not xbmcvfs.exists(mnt_path):
            xbmcvfs.mkdir(mnt_path)

        return mnt_path
def grab_tv_guide(menu_id, menu):
    xmltv_url = get_xmltv_url(menu_id)
    Script.log('xmltv url of {}: {}'.format(menu_id, xmltv_url))

    xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
    Script.log('xmltv filename of {}: {}'.format(menu_id, xmltv_fn))

    xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

    # Remove old xmltv files of this country
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    for fn in files:
        if xmltv_infos[menu_id]['keyword'] in fn and fn != xmltv_fn:
            Script.log('Remove old xmltv file: {}'.format(fn))
            xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))

    # Check if we need to download a fresh xmltv file
    if not xbmcvfs.exists(xmltv_fp):
        Script.log("xmltv file of {} for today does not exist, let's download it".format(menu_id))
        r = urlquick.get(xmltv_url)
        with open(xmltv_fp, 'wb') as f:
            f.write(r.content)

    # Grab programmes in xmltv file
    programmes = read_current_programmes(xmltv_fp)

    # Use the channel as key
    tv_guide = {}
    for programme in programmes:
        programme = programme_post_treatment(programme)
        tv_guide[programme['channel']] = programme

    return tv_guide
Beispiel #21
0
    def download_external_subs(cls, src, filename):
        ''' Download external subtitles to temp folder
            to be able to have proper names to streams.
        '''
        temp = xbmc.translatePath(
            "special://profile/addon_data/plugin.video.jellyfin/temp/")

        if not xbmcvfs.exists(temp):
            xbmcvfs.mkdir(temp)

        path = os.path.join(temp, filename)

        try:
            response = requests.get(src, stream=True, verify=False)
            response.raise_for_status()
        except Exception as error:
            LOG.exception(error)
            raise
        else:
            response.encoding = 'utf-8'
            with open(path, 'wb') as f:
                f.write(response.content)
                del response

        return path
Beispiel #22
0
def get_credentials():
    if (3, 0) <= sys.version_info < (3, 6):
        LOG.error("Python versions 3.0-3.5 are NOT supported.")

    if not xbmcvfs.exists(ADDON_DATA):
        xbmcvfs.mkdirs(ADDON_DATA)

    try:
        with open(os.path.join(ADDON_DATA, 'data.json'), 'rb') as infile:
            credentials = json.load(infile)
    except IOError:
        credentials = {}

    credentials['Servers'] = credentials.get('Servers', [])

    # Migration for #145
    # TODO: CLEANUP for 1.0.0 release
    for server in credentials['Servers']:
        # Functionality removed in #60
        if 'RemoteAddress' in server:
            del server['RemoteAddress']
        if 'ManualAddress' in server:
            server['address'] = server['ManualAddress']
            del server['ManualAddress']
            # If manual is present, local should always be here, but better to be safe
            if 'LocalAddress' in server:
                del server['LocalAddress']
        elif 'LocalAddress' in server:
            server['address'] = server['LocalAddress']
            del server['LocalAddress']
        if 'LastConnectionMode' in server:
            del server['LastConnectionMode']

    return credentials
def migrate_from_pickled_fav():
    """
    This function moves existing pickled favourites in
    the new json file used for the favourites.
    The new format (json) appeared in 0.2.17~beta04
    All user with version >= 0.2.17 will use favourites in the JSON format
    Maybe we can remove the migration check on version 0.2.20?
    """

    # Move all pickled existing favs in json file
    fav_pickle_fp = os.path.join(Script.get_info('profile'), "favourites.pickle")
    if xbmcvfs.exists(fav_pickle_fp):
        Script.log('Start favourites migration from pickle file to json file')
        new_fav_dict = {}
        with storage.PersistentDict("favourites.pickle") as db:
            new_fav_dict = dict(db)
        # Fix old fav
        for item_hash, item_dict in new_fav_dict.items():
            if 'params' in item_dict and isinstance(item_dict['params'], listing.Params):
                new_fav_dict[item_hash]['params'] = dict(new_fav_dict[item_hash]['params'])
                try:
                    del new_fav_dict[item_hash]['params']['item_dict']['params']
                except Exception:
                    pass
            if 'properties' in item_dict:
                if isinstance(item_dict['properties'], listing.Property):
                    new_fav_dict[item_hash]['properties'] = dict(new_fav_dict[item_hash]['properties'])
        fav_json_fp = os.path.join(Script.get_info('profile'), "favourites.json")
        with open(fav_json_fp, 'w') as f:
            json.dump(new_fav_dict, f, indent=4)
        xbmcvfs.delete(fav_pickle_fp)
Beispiel #24
0
def favourites(param):
    mode = param[param.find("###MODE###=") + 11:]
    mode = mode[:mode.find("###")]
    channelEntry = param[param.find("###USER###="):]
    user = param[11 + param.find("###USER###="):param.find("###THUMB###")]
    user = user.encode('utf8') if six.PY2 else user
    if mode == "ADD":
        if xbmcvfs.exists(channelFavsFile):
            with open(channelFavsFile, 'r') as fh:
                content = fh.read()
            if content.find(channelEntry) == -1:
                with open(channelFavsFile, 'a') as fh:
                    fh.write(channelEntry + "\n")
        else:
            with open(channelFavsFile, 'a') as fh:
                fh.write(channelEntry + "\n")
            fh.close()
        xbmcgui.Dialog().notification(
            'Info:', '{0} {1}!'.format(user, translation(30030)), _icon, 5000,
            False)
    elif mode == "REMOVE":
        refresh = param[param.find("###REFRESH###=") + 14:]
        refresh = refresh[:refresh.find("###USER###=")]
        with open(channelFavsFile, 'r') as fh:
            content = fh.read()
        # entry = content[content.find(channelEntry):]
        with open(channelFavsFile, 'w') as fh:
            fh.write(content.replace(channelEntry + "\n", ""))
        if refresh == "TRUE":
            xbmc.executebuiltin("Container.Refresh")
    def _temp_path(cls):
        ''' Return temporary path, usually ~/.kodi/userdata/addon_data/tmp '''
        temp_path = os.path.join(ADDON_PROFILE, 'tmp')
        if not xbmcvfs.exists(temp_path):
            xbmcvfs.mkdir(temp_path)

        return temp_path
Beispiel #26
0
def copy_directory_contents_xbmcvfs(directory_from, directory_to):
    overall_success = True
    files_out = list()
    dirs_in_dir, files_in_dir = xbmcvfs.listdir(
        os.path.join(directory_from, ''))
    for ff in files_in_dir:
        if not xbmcvfs.copy(
                os.path.join(directory_from, ff), os.path.join(
                    directory_to, ff)):  #If move does not work, then copy
            overall_success = False
        else:
            xbmc.log(
                msg=
                'Retro BIOS Tool:  The file was copied from: %(file_from)s, to: %(file_to)s'
                % {
                    'file_from': os.path.join(directory_from, ff),
                    'file_to': os.path.join(directory_to, ff)
                },
                level=xbmc.LOGDEBUG)
            files_out.append(os.path.join(directory_to, ff))
    for dd in dirs_in_dir:
        if xbmcvfs.exists(os.path.join(directory_to, dd, '')) or xbmcvfs.mkdir(
                os.path.join(directory_to, dd)):
            files_out2, success = copy_directory_contents_xbmcvfs(
                os.path.join(directory_from, dd),
                os.path.join(directory_to, dd))
            files_out = files_out + files_out2
        else:
            overall_success = False
    return files_out, overall_success
Beispiel #27
0
def get_device_id(reset=False):
    ''' Return the device_id if already loaded.
        It will load from jellyfin_guid file. If it's a fresh
        setup, it will generate a new GUID to uniquely
        identify the setup for all users.

        window prop: jellyfin_deviceId
    '''
    client_id = window('jellyfin_deviceId')

    if client_id:
        return client_id

    directory = xbmc.translatePath(
        'special://profile/addon_data/plugin.video.jellyfin/')

    if not xbmcvfs.exists(directory):
        xbmcvfs.mkdir(directory)

    jellyfin_guid = os.path.join(directory, "jellyfin_guid")
    file_guid = xbmcvfs.File(jellyfin_guid)
    client_id = file_guid.read()

    if not client_id or reset:
        LOG.debug("Generating a new GUID.")

        client_id = str(create_id())
        file_guid = xbmcvfs.File(jellyfin_guid, 'w')
        file_guid.write(client_id)

    file_guid.close()
    LOG.debug("DeviceId loaded: %s", client_id)
    window('jellyfin_deviceId', value=client_id)

    return client_id
Beispiel #28
0
    def _widevine_path(cls):
        ''' Get full widevine path '''
        widevine_path = os.path.join(cls._ia_cdm_path(), config.WIDEVINE_CDM_FILENAME[system_os()])
        if xbmcvfs.exists(widevine_path):
            return widevine_path

        return False
    def build_colors_list(self):
        '''
            build the list of colorswatches we want to display, check if skinner
            overrides the default provided colorsfile and pick the right colorpalette
        '''

        # prefer skin colors file
        if xbmcvfs.exists(SKINCOLORFILE):
            colors_file = SKINCOLORFILE
            self.colors_path = SKINCOLORFILES_PATH
        else:
            colors_file = os.path.join(ADDON_PATH, 'resources', 'colors',
                                       'colors.xml')
            self.colors_path = COLORFILES_PATH

        doc = parse(colors_file)
        palette_listing = doc.documentElement.getElementsByTagName('palette')
        if palette_listing:
            # we have multiple palettes specified
            for item in palette_listing:
                palette_name = item.attributes['name'].nodeValue
                self.all_colors[palette_name] = self.get_colors_from_xml(item)
                self.all_palettes.append(palette_name)
        else:
            # we do not have multiple palettes
            self.all_colors["all"] = self.get_colors_from_xml(
                doc.documentElement)
            self.all_palettes.append("all")
Beispiel #30
0
 def selectPath(self, url, bypass=False):
     log('selectPath, url = ' + str(url))
     newURL = url
     while not self.myMonitor.abortRequested():
         items = list(self.buildItems(url))
         if len(items) == 0: break
         elif len(items) == 2 and not bypass and items[0].getLabel().lower(
         ) == 'parent directory' and not items[1].getLabel().startswith(
                 '.apk'):
             select = 1  #If one folder bypass selection.
         else:
             select = selectDialog(
                 url.replace(BASE_URL, './').replace('//', '/'), items)
         if select is None: return  #return on cancel.
         label = items[select].getLabel()
         newURL = items[select].getPath()
         preURL = url.rsplit('/', 2)[0] + '/'
         if newURL.endswith('.apk'):
             if not xbmcvfs.exists(SETTINGS_LOC):
                 xbmcvfs.mkdir(SETTINGS_LOC)
             dest = xbmc.translatePath(os.path.join(SETTINGS_LOC, label))
             self.setLastPath(url, dest)
             return self.downloadAPK(newURL, dest)
         elif label.lower(
         ) == 'parent directory' and "android" in preURL.lower():
             return self.selectPath(preURL, True)
         elif label.lower(
         ) == 'parent directory' and "android" not in preURL.lower():
             return self.selectPath(self.buildMain(), False)
         url = newURL + '/'
Beispiel #31
0
def download_subs(link, referrer, filename):
    """
    Download selected subs

    :param link: str - a download link for the subs.
    :param referrer: str - a referer URL for the episode page
        (required by addic7ed.com).
    :param filename: str - the name of the video-file being played.

    The function must add a single ListItem instance with one property:
        label - the download location for subs.
    """
    # Re-create a download location in a temporary folder
    if xbmcvfs.exists(temp_dir):
        shutil.rmtree(temp_dir)
    xbmcvfs.mkdirs(temp_dir)
    # Combine a path where to download the subs
    subspath = os.path.join(temp_dir, filename[:-3] + 'srt')
    # Download the subs from addic7ed.com
    try:
        parser.download_subs(link, referrer, subspath)
    except Add7ConnectionError:
        logger.error('Unable to connect to addic7ed.com')
        dialog.notification(get_ui_string(32002), get_ui_string(32005), 'error')
    except DailyLimitError:
        dialog.notification(get_ui_string(32002), get_ui_string(32003), 'error',
                            3000)
        logger.error('Exceeded daily limit for subs downloads.')
    else:
        # Create a ListItem for downloaded subs and pass it
        # to the Kodi subtitles engine to move the downloaded subs file
        # from the temp folder to the designated
        # location selected by 'Subtitle storage location' option
        # in 'Settings > Video > Subtitles' section.
        # A 2-letter language code will be added to subs filename.
        list_item = xbmcgui.ListItem(label=subspath)
        xbmcplugin.addDirectoryItem(handle=handle,
                                    url=subspath,
                                    listitem=list_item,
                                    isFolder=False)
        dialog.notification(get_ui_string(32000), get_ui_string(32001), icon,
                            3000, False)
        logger.notice('Subs downloaded.')
Beispiel #32
0
    def quickPlayer (self,activity):
        from . import details
        #print self.nextUrl
        Audio = False
        self.wasFullScreen = True
        windowed = self.settings.XNEWA_LIVE_SKIN
        if 'playlist' in activity:
            import os
            import re
            dd = {}
            xbmc.PlayList(0).clear()
            for playlist in activity['playlist']:
                nextUrl = re.sub('[^?&]*client[^&]+&*','',playlist['url'].encode('utf-8'))
                xbmc.log(nextUrl)
                url = nextUrl.split('=',1)[1]
                if url[0:2]=='\\\\':
                    url = 'smb:'+ url.replace('\\','/')
                if xbmcvfs.exists(url) == False:
                    s = self.base + playlist['url'].replace(' ','+').replace('&f=','&mode=http&f=')
                    xbmc.log(s)
                    xbmc.PlayList(0).add(s)
                else:
                    xbmc.PlayList(0).add(url)
            dd['movie'] = False
            dd['playlist'] = xbmc.PlayList(0)
            windowed = False
        elif self.nextUrl.startswith('/live?channel'):
            try:
                #v5
                if self.settings.XNEWA_INTERFACE == 'XML' or self.settings.XNEWA_INTERFACE == 'Version5':
                    url = self.base + '/services?method=channel.listings.current' + self.xnewa.client + '&channel_id=' + str (activity['channel_id'])
                    xbmc.log(url)
                    dd1 = self.xnewa._progs2array_xml(url)
                else:
                    url = self.base + '/public/GuideService/Listing' + self.xnewa.jsid + '&channelId=' + str (activity['channel_id'])
                    xbmc.log(url)
                    dd1 = self.xnewa._progs2array_json(url)
                dd = dd1[0]['progs'][0]
                dd['program_oid'] = dd['oid']
                #dd['season'] = 0
            except Exception as err:
                print(err)
                dd = {}
                dd['program_oid'] = 12346
                dd['title'] = activity['channel_name']
                dd['subtitle'] = str(activity['channel_number'])
                dd['end'] = ''
                dd['season'] = 0
                dd['desc'] = ''

            dd['channel_oid'] = activity['channel_id']
            channel = {}
            channel[0] = activity['channel_name']
            channel[1] = activity['channel_number']
            channel[2] = '0'
            self.prev_channel = self.channel_number
            self.channel_number = activity['channel_number']
            dd['channel'] = channel
            dd['bookmarkSecs'] = 0
            dd['movie'] = False
        elif self.nextUrl.startswith('/stream?'):
            dd = {}
            dd['title'] = 'title'
            dd['movie'] = False
            dd['filename'] = py2_decode(self.nextUrl.split('=',1)[1]).replace('http://plugin','plugin')
            dd['season'] = 0
            if 'duration' in activity:
                dd['library_duration'] = activity['duration']
            else:
                import re
                m = re.search('.*_(\d{2})(\d{2})(\d{2})(\d{2})(-\d)\.ts', dd['filename'])
                if m:
                    start = int(m.group(1)) * 60 + int(m.group(2))
                    end = int(m.group(3)) * 60 + int(m.group(4))
                    #print start
                    #print end
                    if start > end:
                        dd['library_duration'] = (start + end - 1440) * 60
                    else:
                        dd['library_duration'] = (end - start) * 60
            dd['filename'] = dd['filename'].replace('127.0.0.1',self.xnewa.ip)


            #self.getPlaybackPosition(dd['filename'])
            dd['nextUrl'] = self.nextUrl
            if 'recording_description' in activity:
                dd['desc'] = activity['recording_description']
            elif 'description' in activity:
                dd['desc'] = activity['description']
            else:
                dd['desc'] = ''

            if 'recording_title' in activity:
                dd['title'] = activity['recording_title']
            elif dd['filename'].startswith('http:'):
                if '.m3u8' not in  dd['filename']:
                    Audio = True
            elif 'title' in activity:
                dd['title'] = activity['title']

            if 'recording_subtitle' in activity:
                dd['subtitle'] = activity['recording_subtitle']
            elif 'subtitle' in activity:
                dd['subtitle'] = activity['subtitle']
            else:
                dd['subtitle'] = None

            if 'recording_resume' in activity:
                dd['bookmarkSecs'] = activity['recording_resume']
                dd['resume'] = activity['recording_resume']
            else:
                dd['bookmarkSecs'] = 0

            if 'album' in activity:
                Audio = True

            if 'recording_id' in activity:
                dd['recording_oid'] = activity['recording_id']
                dd['nextUrl'] = '/live?recording=' + dd['recording_oid']
                if self.settings.NextPVR_ICON_DL == 'Yes' and self.xnewa.getShowIcon(dd['title']) is None:
                    self.xnewa.getDetails(self.settings.NextPVR_USER,self.settings.NextPVR_PW,dd['recording_oid'],'R','Yes')
            else:
                dd['recording_oid'] = 0

            if 'Genres' in activity:
                dd['genres'] = activity['Genres']
                for  genre in dd['Genres']:
                    if genre == "Movie" or genre == "Movies" or genre == "Film":
                        dd['movie'] = True
                        break
        detailDialog = details.DetailDialog("nextpvr_recording_details.xml",  WHERE_AM_I,self.settings.XNEWA_SKIN, xnewa=self.xnewa, settings=self.settings, oid=123, epg=True, type="R")
        xbmc.log(str(windowed))
        if self.sdlmode == SDL.disabled:
            self.setOSDMode(False)
            windowed = False
        if isinstance(self.t1, Thread):
            xbmc.Player().stop()
            while self.t1.is_alive():
                xbmc.sleep(100)
            self.renderstop = False


        self.t1 = Thread(target=detailDialog._myPlayer, args=(dd,None,windowed,Audio,False))
        self.t1.start()
        self.state = videoState.started

        #xbmc.executebuiltin('XBMC.ActivateWindow(25)')
        #self.player = detailDialog.getPlayer()
        #self.player.overlay = self
        #xbmc.executebuiltin('ActivateWindow(visualisation)')
        #xbmc.executebuiltin('ActivateWindow(musicosd)')
        return