Пример #1
0
 def __init__(self, addon):
     self.addon = addon
     self.xml_file_location = xbmc.translatePath(addon['obj'].getSetting('xml_file_location'))
     self.root = ET.parse( self.xml_file_location ).getroot()
     
     if addon['obj'].getSetting('debug_update_xml'):
         self.xml_file_modified = int(xbmcvfs.Stat(self.xml_file_location).st_mtime())
     else:
         self.xml_file_modified = 0
     self.stream_folder =  xbmc.translatePath(addon['obj'].getSetting('stream_folder_location'))
     xbmcvfs.mkdirs(self.stream_folder)
     self.url_replace = [ ('art\:\/\/', xbmc.translatePath(addon['obj'].getSetting('art_folder_location'))) ]
     
     
     self.force_refresh = False
     
     self.db = DBHandler(xbmc.translatePath('special://profile/addon_data/plugin.video.drawers/data/'))
Пример #2
0
class Drawers:
    
    
    def __init__(self, addon):
        self.addon = addon
        self.xml_file_location = xbmc.translatePath(addon['obj'].getSetting('xml_file_location'))
        self.root = ET.parse( self.xml_file_location ).getroot()
        
        if addon['obj'].getSetting('debug_update_xml'):
            self.xml_file_modified = int(xbmcvfs.Stat(self.xml_file_location).st_mtime())
        else:
            self.xml_file_modified = 0
        self.stream_folder =  xbmc.translatePath(addon['obj'].getSetting('stream_folder_location'))
        xbmcvfs.mkdirs(self.stream_folder)
        self.url_replace = [ ('art\:\/\/', xbmc.translatePath(addon['obj'].getSetting('art_folder_location'))) ]
        
        
        self.force_refresh = False
        
        self.db = DBHandler(xbmc.translatePath('special://profile/addon_data/plugin.video.drawers/data/'))
        
    

            

    def get_drawer(self, path=None, force_refresh=False, cached=True):
        if path is None:
            path = self._get_path()
        self.force_refresh = force_refresh        
        if cached:
            return self._get_cache_drawer(path)
        else:
            return self._get_drawer(path)
    

    def _get_drawer(self, path):
        (fids, sids, url) = self._parse_path(path)
        (items, settings) = self._create_items(fids, sids, url)
        return items, settings
    

    def update_drawers(self, force=False):
        wid = xbmcgui.getCurrentWindowId()
        if wid in WINDOW_UPDATE_IDS and not force:
            return 5
        data = self.db.select('drawers', values=['path'], params={}, filter="nextupdate>0 AND nextupdate<%d" % int(time.time()))
        if len(data) > 0:
            self._get_cache_drawer(data[0]['path'], update=True)
            print '>>>> %s updated' % data[0]['path']
            if len(data) > 1:
                return random.randint(2, 5)
        
        data = self.db.select('drawers', values=['nextupdate'], params={}, filter="nextupdate>0 AND nextupdate>%d" % int(time.time()))

        return int( min([int(d['nextupdate']- time.time()) for d in data] + [60])  + 2 )
     
        
    def refresh_drawer(self):
        items, settings = self.get_drawer(force_refresh=True)
        xbmc.executebuiltin("Container.Refresh()")
        return items, settings
        
    
    def _get_cache_drawer(self, path, update=False):
        self.log( path )
        handle = _get_handle(path, URL_FILTERS)
        db_data = self.db.select('drawers', values=['timeout','lastupdate'], params={'handle': handle})
        
        # no cache available or refresh forced
        if self.force_refresh or update or db_data == [] or db_data[0]['lastupdate'] == 0:
            (fids, sids, url) = self._parse_path(path)  
            (items, settings) = self._create_items(fids, sids, url)
            
            if self.force_refresh or update or db_data == [] \
                or (settings['timeout'] > time.time() and settings['updated']):
                
                if settings.get('refresh', -1) > 0:
                    nextupdate = int(time.time()) + settings['refresh']
                else:
                    nextupdate = settings['refresh']
                
            
                self.db.upsert('drawers', 
                               values={'data': repr( (items, settings) ),
                                       'lastupdate': int(time.time()),
                                       'timeout': int(settings['timeout'] - time.time()),
                                       'nextupdate': nextupdate,
                                       'path': path},
                               params={'handle': handle})
                
                #self.db.delete('drawer_source', params={'drawer': handle})
                
                for source_handle in settings['sources']:
                    self.db.insert('drawer_source', 
                                   values={'drawer': handle,
                                           'source': source_handle})  
                  
        
        # cache available, but needs update    
        elif int( db_data[0]['timeout'] + db_data[0]['lastupdate']) < time.time() \
                or int( db_data[0]['lastupdate']) < self.xml_file_modified:
            (items, settings) = eval( self.db.select('drawers', values=['data'], params={'handle': handle})[0]['data'] )
            settings['update'] = True
            if settings.get('refresh', -1) > 0:
                nextupdate = db_data[0]['lastupdate'] + settings['refresh']
            else:
                nextupdate = settings.get('refresh', -1)
            self.db.upsert('drawers', values={'nextupdate': nextupdate}, params={'handle': handle})
           
            
        # cache available and up to date
        else:
            (items, settings) = eval( self.db.select('drawers', values=['data'], params={'handle': handle})[0]['data'] )
            
        
        # collect subdrawers in DB for caching
        if update is False and False:
            for item in items:
                if item['path'].startswith(self.addon['name']):
                    settings['paths'] = settings.get('paths', []) + [item['path']]             
        
        return items, settings
    
    
    def insert_paths(self, paths):
        for p in paths:
            handle = hash(p)
            data = self.db.select('drawers', values=['handle'], params={'handle': handle})
            if data == []:
                self.db.upsert('drawers', 
                    values={'lastupdate': 0,
                            'timeout': 0,
                            'nextupdate': 1,
                            'path': p},
                    params={'handle': handle})     

            
    def _get_plugin_data(self, url, force_timeout):
        data, source_timeout, updated = self._cache_source(url, force_timeout)
        items = []
        for f in data:
            info = dict((k, v) for (k, v) in f.iteritems() if k in video_info)
            if info.has_key('runtime') and not info.has_key('duration'):
                info['duration'] = info['runtime']
                #info.pop('runtime')
            if info.has_key('duration') and info['duration'] < 3000:
                info['duration'] = info['duration'] * 60
            if info.has_key('director') and isinstance(info['director'], list) and len(info['director']) > 0:
                info['director'] = info['director'][0]
            if info.has_key('studio') and isinstance(info['studio'], list):
                info['studio'] = '/'.join( info['studio'] )
            if info.has_key('genre') and isinstance(info['genre'], list):
                info['genre'] = ' / '.join( info['genre'] )
                
            info['isFolder'] = f.get('mimetype', '') == 'x-directory/normal' or f.get('filetype', '') == "directory"
            items.append( {'label': f.get('label', ''), 
                           'path': f['file'],
                           'art': f.get('art', {}), 
                           'info': info } )                    
        return items, source_timeout, updated
    
    def _cache_source(self, source, force_timeout=-1):
        updated = False
        handle = _get_handle(source, URL_FILTERS)
        db_data = self.db.select('sources', values=['lastupdate', 'timeout', 'hash', 'hash_label'], params={'handle':handle})
        if len(db_data) == 0:
            hash_old = ''
            timeout = 3
            data_timeout = 0
            hash_label = ''
        else:
            hash_old = db_data[0]['hash']
            hash_label = db_data[0]['hash_label']
            timeout = int(db_data[0]['timeout'])
            data_timeout = int( db_data[0]['lastupdate'] ) + SOURCE_TIMEOUTS[timeout]
        
            
        if data_timeout < time.time() or self.force_refresh:
            data = self._read_dir(source)
            raw_data = repr(data)
            hash_new = hash(raw_data)
            if hash_old != hash_new:
                updated = True
                # makes sure to only update timeout if actual ListElements are changed,
                # prevents updates due to changes in sessionids of path vars
                hash_label_new = hash(repr(sorted([d['label'] for d in data])))
                if hash_label_new != hash_label:
                    timeout = timeout - 1
                else:
                    timeout = timeout + (2 if not self.force_refresh else 1)
                timeout = min(max(0, timeout), len(SOURCE_TIMEOUTS)-1)
                self.db.upsert('sources',
                                values={'source': source,
                                        'lastupdate': time.time(),
                                        'timeout': timeout,
                                        'data': raw_data,
                                        'hash': hash_new,
                                        'hash_label': hash_label_new} ,
                                params={'handle': handle})
            else:
                timeout = min(len(SOURCE_TIMEOUTS)-1, timeout + (2 if not self.force_refresh else 1) )
                self.db.upsert('sources',
                                values={'lastupdate': time.time(),
                                        'timeout': timeout},
                                params={'handle': handle})
            if force_timeout >= 0:
                data_timeout = time.time() + force_timeout
            else:
                data_timeout = time.time() + SOURCE_TIMEOUTS[timeout]
                
        else:
            raw_data = self.db.select('sources', values=['data'], params={'handle':handle})
            data = eval( raw_data[0]['data'] )
        
        return data, data_timeout, updated
                          
    
    def _read_dir(self, dir):  
        #xbmc.executebuiltin("Notification(Drawers, Reading: %s, 3000, C:/Users/Programming/AppData/Roaming/Kodi/addons/plugin.video.drawers/icon.png)" % dir  ) 
        viewmode = xbmcgui.Window(xbmcgui.getCurrentWindowId()).getFocusId()
        data = self._get_json().Files.GetDirectory(directory=dir, properties=file_info)
        if xbmcgui.Window(xbmcgui.getCurrentWindowId()).getFocusId() != viewmode:
            xbmc.executebuiltin('Container.setViewmode(%d)' % viewmode)
        if data is None or not data.has_key('files'):
            return []
        return [clean(d) for d in data['files']]
    

            
    
    def _create_items(self, fids=[], sids=[], url='', depth=5, recur=False):
        items = []
        menu = [('Refresh Drawer', 'RunPlugin("%s%s%s")' % (self._get_path(fids, sids, url),
                                                            '&' if '?' in url else '?',
                                                            'drawer_action=force_refresh'))]
        timeout = time.time() + SOURCE_TIMEOUTS[-1]
        source_handles = []
        updated = False
        
        # add folders
        if sids == []:
            for i, f in enumerate(self._xmlitems('folder', fids)):
                item = {'label': self._xmlitem('folder[%d]'% (i+1), fids).attrib['label'].encode('utf-8'), 
                        'path': self._get_path(fids+[i+1]), 
                        'info': { 'isPlayable': 'False', 'isFolder': True } }
                items.append( (item, fids+[i+1], []) )
                
        
        # prepare to add items from sources
        if sids == []:
            sources = self._xmlitems('source', fids)
        else:
            source = self._xmlitem('source[%s]' % sids[0], fids)
            if url != '':
                source.attrib['url'] = url
            sources = [source] 
            
        for s_i, s in enumerate(sources):
            if not s.attrib.has_key('url'):
                continue
            
            source_handles.append( _get_handle(s.attrib['url'], URL_FILTERS) )
            if sids == []:
                sids_n = [str(s_i+1)]
            else:
                sids_n = sids
                
            force_timeout = calc_time( s.attrib['timeout'] ) if s.attrib.has_key('timeout') else -1
            pitems, source_timeout, source_updated = self._get_plugin_data(s.attrib['url'], force_timeout)
            if timeout > source_timeout:
                timeout = source_timeout
                updated = updated or source_updated

            for p in pitems:
                p['url'] = s.attrib['url']
                p['depth'] = depth
                if p['info'].get('isFolder', False):
                    i, xml_subfolder = self._match_target(self._xmlitems('subfolder', fids, sids_n), \
                                                      p, attr='flatten', values=None)
                    if xml_subfolder is not None:
                        try:
                            d = int(xml_subfolder.attrib['flatten'])
                        except:
                            d = 1
                        new_depth = min(depth, d) - 1
                        if new_depth >= 0:
                            items_rec, source_handles_new = self._create_items(fids, sids_n, p['path'], new_depth, recur=True)
                            items += items_rec
                            source_handles += source_handles_new
                        else: 
                            items.append( (p, fids, sids_n) )
                    else: 
                        items.append( (p, fids, sids_n) )
                else:
                    items.append( (p, fids, sids_n) )
        
             
        if recur:
            return items, source_handles
        
        settings = self._mod_folder(fids, sids)
        items, settings = self._mod_items(items, settings, url)
        settings['sources'] = source_handles
        settings['timeout'] = timeout
        settings['updated'] = updated
        settings['menu'] = settings.get('menu', []) + menu
        return items, settings
    
    
    
    def _mod_folder(self, fids, sids):
        options = self._xmlitem('', fids, sids if len(sids) > 1 else []).attrib
        settings = { 'content': options.get('content', 'files'),
                      'refresh': -1 }
        if options.has_key('viewmode'):
            settings['viewmode'] = options['viewmode']
        if options.has_key('timeout'):
            settings['max_timeout'] = options['timeout']
        if options.has_key('update'):
            settings['refresh'] = calc_time( options['update'] )
            
        return settings
    
    def _mod_item(self, item, fids, sids):
        items, s = self._mod_items([(item, fids, sids)], url='', add_folders=False)
        if len(items) == 0:
            return None
        return items[0]
                      
    def _mod_items(self, items, settings={}, url='', add_folders=True):
        mod_items = []
        added_items = []
        
                
        for _item in items:
            item, fids, sids = _item
            item_mods = []
            s_i = []
            
            if len(sids) > 1:
                parent_folder = self._xmlitem('', fids, sids)
                if parent_folder is not None and parent_folder.attrib.get('type', '') == 'copy':
                    item = self._mod_item(item, fids, sids[:-1])
                if item is None:
                    continue            
            
            #===================================================================
            # item matching
            #===================================================================
            xml_subfolders = self._xmlitems('subfolder', fids, sids)
            
            xml_matches = self._match_targets( xml_subfolders, item, attr='type', values=['copy'])
            for i, xml_item in xml_matches:
                if url == '':
                    url = self._xmlitem('', fids, [sids[0]]).attrib['url']
                    
                item_new = {'label': xml_item.get('label', 'Copyfolder'), 
                            'path': self._get_path(fids, sids + [i], url), 
                            'info': { 'isFolder': True } }
                if item_new['label'] not in [it.get('label','') for it in added_items if it is not None] \
                    and add_folders:
                    item_new, s = self._mod_item_attrib(item_new, [xml_item.attrib])
                    if item_new is not None:
                        item_new = self._mod_item(item_new, fids, sids)
                        if item_new is not None:
                            added_items.append( item_new )
            
            if str(item['info']['isFolder']) == 'False':
                xml_items = self._xmlitems('item', fids, sids)    
                xml_matches = self._match_targets( xml_items, item, attr='type', values=[None])
                for i, xml_item in xml_matches:
                    s_i.append( i )
                    item_mods.append( xml_item.attrib )
                    
            
            else:
                    
                i, xml_subfolder = self._match_target( xml_subfolders, item, attr='type', values=['paging'])
                if xml_subfolder is not None:
                    item['path'] = self._get_path(fids, sids, item['path'])
                    item['type'] = 'paging'
                    if xml_subfolder.attrib.has_key('precache'):
                        settings['precache'] = settings.get('precache', []) + [item['path']]
                    item_mods.append( xml_subfolder.attrib )
                
                i, xml_subfolder = self._match_target( xml_subfolders, item, attr='type', values=[None])
                if xml_subfolder is not None:
                    item['path'] = self._get_path(fids, sids + [i], item['path'])
                    item_mods.append( xml_subfolder.attrib )
                    
                elif sids == []:
                    item_mods.append( self._xmlitem('', fids).attrib )
            
        
            
            #===================================================================
            # set item attributes
            #==================================================================
            
            item, settings_mod = self._mod_item_attrib(item, item_mods)
            print settings_mod
            if settings_mod.has_key('refresh'):
                print 'REFRESHING'
                if settings['refresh'] > 0:
                    settings['refresh'] = min(settings['refresh'], settings_mod['refresh'])
                else: 
                    settings['refresh'] = settings_mod['refresh']
            #===================================================================
            # apply folder/source/subfolder mods
            #===================================================================
            for i in s_i:
                item = self._mod_groups(item, fids, sids, i)
            if len(sids) == 1:
                item = self._mod_groups(item, fids)
                item = self._mod_groups(item, fids, sids[0])
            if len(sids) > 1:
                item = self._mod_groups(item, fids, sids)
            
            if not item:
                continue
            
            if item.has_key('movie_stream'):
                settings['movie_stream'] = True
            if item.has_key('tvshow_stream'):
                settings['tvshow_stream'] = True
            
            # Propages show title to subfolders
            if (settings.get('content', '') == 'tvshows' or self.addon['options'].has_key('drawer_show')) and str(item['info']['isFolder']) == 'True':
                path = item.get('path', '')
                if path != '':
                    if settings['content'] == 'tvshows':
                        show = item['info'].get('titel', item.get('label', ''))
                    else:
                        show = self.addon['options']['drawer_show']
                    path += ('?' if not '?' in path else '&') + 'drawer_show=' + show
                    item['path'] = path
                    
            if settings.get('content', '') == 'episodes' and self.addon['options'].has_key('drawer_show'):
                item['info']['showtitle'] = urllib.unquote( self.addon['options']['drawer_show'] )
                
            
            if item not in mod_items:
                mod_items.append(item)
        
        if add_folders:
            mod_items += added_items
        return mod_items, settings   
    
    def _mod_item_attrib(self, item, item_mods):
        settings = {}
        for item_mod in item_mods:
            if item_mod.has_key('label'):
                item['label'] = item_mod['label']
            
            item['art'] = item.get('art', {})
            if item_mod.has_key('poster'):
                item['art']['poster'] = self._mod_url( item_mod['poster'] )
            if item_mod.has_key('fanart'):
                item['art']['fanart'] = self._mod_url( item_mod['fanart'] )
            if item_mod.has_key('banner'):
                item['art']['banner'] = self._mod_url( item_mod['banner'] )
            if item_mod.has_key('thumb'):
                item['art']['thumb'] = self._mod_url( item_mod['thumb'] )
            
            if item_mod.has_key('hide'):
                item = None
                
            if item_mod.has_key('force_refresh'):
                path = item.get('path', '')
                if path != '':
                    path += ('?' if not '?' in path else '&') + 'drawer_options=force_refresh'
                item['path'] = path   
                
            if item_mod.has_key('update'):
                settings['refresh'] = calc_time( item_mod['update'] )
        return item, settings
    
    def _mod_groups(self, item, fids=[], sids=[], iid=None):
        if iid is not None:
            xml_items = self._xmlitems('item[%d]/mod' % iid, fids, sids)
        else:
            xml_items = self._xmlitems('mod', fids, sids)
            xml_items = xml_items
        
        
        for mod in xml_items:
            if item is None:
                return None
            options = mod.attrib
            type = options.get('type', '')
            
            if type == 'replace':
                value = self._get_prop(item, options.get('target', 'label'))
                if options.has_key('pattern'):
                    value = re.sub(options['pattern'], options.get('replacement',''), value)
                
                for pattern in mod.findall('./pattern'):
                    value = re.sub(pattern.text, pattern.attrib.get('replacement', ''), value)
                    
                self._set_prop(item, options.get('target', 'label'), value)
                
            elif type == 'remove':
                if self._match_pattern(mod, item):
                    item = None
                    
            elif type == 'set_prop' and options.has_key('var'):
                if options.has_key('value'):
                    self._set_prop(item, options['var'], options['value'])
                    
                elif options.has_key('source'):
                    value = self._get_prop(item, options['source'])
                    if value is not None:
                        self._set_prop(item, options['var'], value)
                        
                               
            elif type == 'get_movies':
#                 try:
                from metahandler.metahandlers import MetaData   
                metahandler = MetaData()
                
                #if metahandler._cache_lookup_by_name('movie', item['label']) is not None:
                label = self._get_prop(item, options.get('target', 'label'))
                data = metahandler.get_meta('movie', item['label'].encode('utf-8'))
                if data is None or not abs(int(data['year']) - int(item['info'].get('year', 0)) ) <= 1:
                    data = None
                    if not item['info'].has_key('year'):
                        continue
                    movies = metahandler.search_movies(item['label'].encode('utf-8'))
                    if movies is None:
                        continue
                    movies = [m for m in movies if m.get('year', None) is not None]
                    movies = sorted(movies, key=lambda m: abs(int(m.get('year', 0)) - int(item['info']['year'])) )
                    data = metahandler.get_meta('movie', item['label'].encode('utf-8'), tmdb_id=movies[0]['tmdb_id'])
                        
                if data is None:
                    continue
                data = clean(data)
                if data.get('cover_url','') != '':
                    item['art']['poster'] = data['cover_url']
                if data.get('backdrop_url','') != '':
                    item['art']['fanart'] = data['backdrop_url']
                data = dict( (k, v) for k, v in data.items() if k not in ['cover_url', 'backdrop_url', 'thumb', 'thumbnail', 'thumb_url'] )
                item['info'].update(data)
                
                

            elif type == 'get_tvshows':
                try:
                    from metahandler.metahandlers import MetaData   
                    metahandler = MetaData()
                except:
                    pass  
                
                                    
                data = metahandler.get_meta('tvshow', item['label'].encode('utf-8'), 
                                            imdb_id=options.get('imdb_id', ''))
                if data is not None:
                    data = clean(data)
                    item['info'].update(data)
                    if data.get('cover_url','') != '':
                        item['art']['poster'] = data['cover_url']
                    if data.get('backdrop_url','') != '':
                        item['art']['fanart'] = data['backdrop_url']
                    if data.get('banner_url','') != '':
                        item['art']['banner'] = data['banner_url']                  
                
            elif type == "create_movie_streams":
                item['movie_stream'] = options.get('folder', '')
            elif type == "create_tvshow_streams":
                item['tvshow_stream'] = options.get('folder', '')
                
        return item
    
                    
    def create_movie_streams(self, items):
        for item in items:
            if not item.has_key('movie_stream'):
                continue
            folder = os.path.join(self.stream_folder, item['movie_stream'])
            if item['path'] != '' and self.addon['name'] not in item['path']:
                name = re.sub('(\:|\.|\,)', '', item['label'])
                name = name + (' (%s)' % item['info']['year'] if item['info'].get('year','') != '' else '')
                subfolder = self._make_dir(folder, name)
                self._create_file(subfolder, name + '.strm', str(item.get('path', '')) )
        
        
                
    def create_tvshow_streams(self, items):
        for item in items:
            if not item['info'].get('isFolder', True) and item.has_key('tvshow_stream') and item['info'].has_key('showtitle'):
                name = item['info']['showtitle']
                folder = self._make_dir(os.path.join(self.stream_folder, item['tvshow_stream']), name)
                if item['info'].has_key('season') and item['info'].has_key('episode') and item['info']['season'] != '-1':
                    subfolder = self._make_dir(folder, 'Season %s' % item['info']['season'])
                    filename = '%s.S%sE%s.strm' % (re.sub(' ', '.', name), item['info']['season'], item['info']['episode'])
                    self._create_file(subfolder, filename, str(item.get('path', '')) )
                elif item['info'].has_key('airdate'):
                    from datetime import datetime
                    d = datetime.strptime(item['info']['airdate'], '%d.%m.%Y')
                    airdate = d.strftime('%m.%d.%Y')
                    filename = '%s.%s.strm' % (re.sub(' ', '.', name), airdate)
                    self._create_file(folder, filename, str(item.get('path', '')) )
                    
                
                
    
    def log(self, m):
        print '%s >>> %s' % (self.addon['name'], m)
    
        
    def _get_json(self):
        #=======================================================================
        # self.host_ip = self.addon['obj'].getSetting('host_ip')
        # self.host_port = self.addon['obj'].getSetting('host_port')
        # self.host_username = self.addon['obj'].getSetting('username')
        # self.host_password = self.addon['obj'].getSetting('host_ip')        
        # 
        # return JSONConnection(host=self.host_ip, port=self.host_port, username=self.host_username, password=self.host_password)
        #=======================================================================
        
        return JSONConnection()
        
    def _parse_path(self, path):
        url = ''
        path_split = path.split('_')
        fids = path_split[0].split('/')[3:-1]
        if len(path_split) > 1:
            sids = '_'.join(path_split[1:]).split('/')
            url = '/'.join( sids[sids.index('plugin:'):] )
            sids = sids[1: sids.index('plugin:')]
        else:
            sids  = []
        return fids, sids, url
    
    def _get_path(self, fids=None, sids=None, url=None):
        if fids is None:
            return self.addon['path'] + dict2var(self.addon['vars'])
        path = '%s%s%s' % (self.addon['name'], '/'.join(str(f) for f in fids), '/' if fids != [] else '')
        if sids:
            path += '_/' + '/'.join(str(s) for s in sids) + ('/' if sids != [] else '')
        if url:
            path += url
        return path
    
    def _get_url(self, path):
        if 'plugin:' not in path[1:]:
            return path
        path_split = path.split('/')
        return '/'.join( path_split[path_split[1:].index('plugin:')+1:] )
            
    def _make_dir(self, path, dir):
        subpath = os.path.join(path, dir)
        try:
            if not xbmcvfs.exists(subpath): xbmcvfs.mkdirs(subpath)
        except:
            if not os.path.exists(subpath): os.makedirs(subpath)              
        return subpath
    
    def _create_file(self, path, filename, content):
        filepath = os.path.join(path, filename)
        if os.path.isfile(filepath):
            os.utime(filepath, None)
        else:
            f = xbmcvfs.File(filepath, 'w')
            f.write(content)
            f.close()
    
    def _set_prop(self, item, id, value):
        ids = id.split('/')
        for l in ids[:-1]:
            item = item[l]
        item[ids[-1]] = value
    def _get_prop(self, item, id):
        try:
            for l in id.split('/'):
                item = item[l]
            return item
        except:
            return None
        
    
    def _mod_url(self, url):
        for pattern, repl in self.url_replace:
            if re.match(pattern, url):
                url = repl + re.sub(pattern, '', url)
        return xbmc.translatePath(url)                 
    
    def _xmlitems(self, tag, fids=[], sids=[]):
        return self.root.findall(self._xpath(tag, fids, sids))  
    def _xmlitem(self, tag, fids=[], sids=[]):
        return self.root.find(self._xpath(tag, fids, sids))          
    def _xpath(self, tag, fids=[], sids=[]):
        xpath = '.'
        for fid in fids:
            xpath += '/folder[%s]' % str(fid)
        if sids:
            xpath += '/source[%s]' % str(sids[0])
        for sid in sids[1:]:
            xpath += '/subfolder[%s]' % str(sid)
        if tag != '':
            xpath += '/' + tag
        return xpath
 
 
    def _match_target(self, matchers, target, attr=None, values=[]):
        res = self._match_targets(matchers, target, attr, values)
        if len(res) == 0:
            return None, None
        return res[0]
    def _match_targets(self, matchers, target, attr=None, values=[]):
        res = []
        for i, matcher in enumerate(matchers):
            if self._match_pattern(matcher, target):
                if attr is None \
                        or (matcher.attrib.has_key(attr) and values is None)\
                        or (values is not None and matcher.attrib.get(attr, None) in values):
                    res.append((i+1, matcher))
        return res   
    def _match_pattern(self, matcher, target):
        s = self._get_prop(target, matcher.get('target', 'label')).encode('utf-8', 'ignore')
        if not matcher.attrib.has_key('pattern') or s is None:
            return False
        return (re.search(matcher.attrib['pattern'], s) is None) == matcher.attrib.has_key('exclude')
    


    
    def _show_notification(self, header='Drawers', text='', time=5):
        text = uni(text)
        image = self.addon['obj'].getAddonInfo('icon')
        xbmc.executebuiltin('Notification(%s, %s, %d, "%s")' % (header, text, time, image))