コード例 #1
0
ファイル: vartools.py プロジェクト: uguer30/Project
def Convert_Special(
        filepath=xbmc.translatePath('special://home'), string=False,
        quoted=True):
    """
Convert physcial paths stored in text files to their special:// equivalent or
replace instances of physical paths to special in a string sent through.

CODE: Convert_Special([filepath, string])

AVAILABLE PARAMS:

    filepath  -  This is the path you want to scan, by default it's set to the Kodi HOME directory.
    
    string    -  By default this is set to False, if you set to True you will get the
                 string of your 'filepath' returned with any reference to physical
                 path replaced with special://

    quoted    -  By default this is set to true, this means the return you get will be converted
                 with urllib.quote_plus(). This is ideal if you need to get a string you can send
                 through as a path for routing.

EXAMPLE CODE:
path = xbmc.translatePath('special://profile')
dialog.ok('[COLOR gold]ORIGINAL PATH[/COLOR]','Let\'s convert this path to it\'s special equivalent:\n[COLOR dodgerblue]%s[/COLOR]'%path)
path = Convert_Special(filepath=path,string=True)
dialog.ok('[COLOR gold]CONVERTED PATH[/COLOR]','This is the converted path:\n[COLOR dodgerblue]%s[/COLOR]'%path)
if dialog.yesno('[COLOR gold]CONVERT PHYSICAL PATHS[/COLOR]','We will now run through your Kodi folder converting all physical paths to their special:// equivalent in xml/hash/properties/ini files.\nDo you want to continue?'):
    koding.Convert_Special()
    dialog.ok('[COLOR gold]SUCCESS[/COLOR]','Congratulations, all references to your physical paths have been converted to special:// paths.')
~"""
    import urllib
    from filetools import Text_File
    if not string:
        for root, dirs, files in os.walk(filepath):
            for file in files:
                if file.endswith(".xml") or file.endswith(
                        ".hash") or file.endswith(
                            "properies") or file.endswith(".ini"):
                    contents = Text_File(os.path.join(root, file), 'r')
                    encodedpath = urllib.quote(HOME)
                    encodedpath2 = encodedpath.replace('%3A', '%3a').replace(
                        '%5C', '%5c')
                    newfile = contents.replace(HOME,
                                               'special://home/').replace(
                                                   encodedpath,
                                                   'special://home/').replace(
                                                       encodedpath2,
                                                       'special://home/')
                    Text_File(os.path.join(root, file), 'w', newfile)
    else:
        encodedpath = urllib.quote(HOME)
        encodedpath2 = encodedpath.replace('%3A', '%3a').replace('%5C', '%5c')
        newstring = filepath.replace(HOME, 'special://home/').replace(
            encodedpath, 'special://home/').replace(encodedpath2,
                                                    'special://home/')
        if quoted:
            newstring = urllib.quote_plus(newstring)
        return newstring
コード例 #2
0
def Grab_Tutorials():
    """ internal command ~"""
    import re
    full_array = []
# Check all the modules for functions with tutorial info
    for file in os.listdir(py_path):
        file_path = os.path.join(py_path,file)
        if not os.path.isdir(file_path) and file.endswith('.py'):
            content = Text_File(file_path,'r')
            # content_array = re.compile('# TUTORIAL #\ndef (.+?)\(').findall(content)
            content_array = Find_In_Text(content=content, start='# TUTORIAL #\ndef ', end='\(', show_errors=False)
            if content_array:
                for item in content_array:
                    item = item.strip()
                    full_array.append('%s~%s'%(item,file_path))
            content_array = Find_In_Text(content=content, start='# TUTORIAL #\nclass ', end='\(', show_errors=False)
            if content_array:
                for item in content_array:
                    item = item.strip()
                    full_array.append('%s~%s'%(item,file_path))

# Return a list of tutorials
    Add_Dir('[COLOR=gold]CREATE YOUR FIRST ADD-ON[/COLOR]',video_base+'Create_Addon.mov','play_video', folder=False, icon='', fanart='', description='How to create your own add-on using the Python Koding framework.')

    for item in sorted(full_array,key=str.lower):
        name, filepath = item.split('~')
        filepath = urllib.quote(filepath)
        Add_Dir(name=name.upper().replace('_',' '), url='%s~%s'%(name,filepath), mode='show_tutorial', folder=False, icon='', fanart='', description='Instructions for how to use the %s function.'%name)
コード例 #3
0
def Get_Addon_ID(folder):
    """
If you know the folder name of an add-on but want to find out the
addon id (it may not necessarily be the same as folder name) then
you can use this function. Even if the add-on isn't enabled on the
system this will regex out the add-on id.

CODE:  Get_Addon_ID(folder)

AVAILABLE PARAMS:
    
    folder  -  This is folder name of the add-on. Just the name not the path.

EXAMPLE CODE:
dialog.ok('ABOUT','This function allows us to pass through a folder name found in the addons folder and it will return the real id. The vast majority of add-ons use the same folder name as id but there are exceptions. Let\'s check Python Koding...')
my_id = koding.Get_Addon_ID(folder='script.module.python.koding.aio')
dialog.ok('PYTHON KODING ID','The add-on id found for this folder folder is:','[COLOR=dodgerblue]%s[/COLOR]'%my_id)
~"""
    from filetools import Text_File
    import re
    xmlpath = os.path.join(ADDONS, folder, 'addon.xml')
    if xbmcvfs.exists(xmlpath):
        contents = Text_File(xmlpath, 'r')
        addon_id = re.compile('id="(.+?)"').findall(contents)
        addon_id = addon_id[0] if (len(addon_id) > 0) else ''
        return addon_id
    else:
        return folder
コード例 #4
0
ファイル: systemtools.py プロジェクト: smoke61/modules4all
def Requirements(dependency):
    """
Return the min and max versions of built-in kodi dependencies required by
the running version of Kodi (xbmc.gui, xbmc.python etc.), The return will
be a dictionary with the keys 'min' and 'max'.

CODE: Requirements(dependency)

AVAILABLE PARAMS:

    (*) dependency  -  This is the dependency you want to check.
    You can check any built-in dependency which has backwards-compatibility
    but the most commonly used are xbmc.gui and xbmc.python.

EXAMPLE CODE:
xbmc_gui = Requirements('xbmc.gui')
xbmc_python = Requirements('xbmc.python')
dialog.ok('DEPENDENCIES','[COLOR=dodgerblue]xbmc.gui[/COLOR]  Min: %s  Max: %s'%(xbmc_gui['min'],xbmc_gui['max']),'[COLOR=dodgerblue]xbmc.python[/COLOR]  Min: %s  Max: %s'%(xbmc_python['min'],xbmc_python['max']))
~"""
    from filetools import Text_File
    from vartools import Find_In_Text
    root = xbmc.translatePath('special://xbmc/addons')
    dep_path = os.path.join(root, dependency, 'addon.xml')
    content = Text_File(dep_path, 'r')
    max_ver = Find_In_Text(content=content, start='version="', end='"')[1]
    min_ver = Find_In_Text(content=content, start='abi="', end='"')[0]
    return {'min': min_ver, "max": max_ver}
コード例 #5
0
def Get_Addon_ID(folder):
    """
If you know the folder name of an add-on but want to find out the
addon id (it may not necessarily be the same as folder name) then
you can use this function. Even if the add-on isn't enabled on the
system this will regex out the add-on id.

CODE:  Get_Addon_ID(folder)

AVAILABLE PARAMS:
    
    folder  -  This is folder name of the add-on. Just the name not the path.

EXAMPLE CODE:
my_id = koding.Get_Addon_ID(folder='script.module.python.koding.aio')
dialog.ok('ADDON ID','The add-on id found is:','[COLOR=dodgerblue]%s[/COLOR]'%my_id)
~"""
    from filetools import Text_File
    import re
    xmlpath = os.path.join(ADDONS, folder, 'addon.xml')
    if os.path.exists(xmlpath):
        contents = Text_File(xmlpath,'r')
        addon_id = re.compile('id="(.+?)"').findall(contents)
        addon_id = addon_id[0] if (len(addon_id) > 0) else ''
        return addon_id
    else:
        return folder
コード例 #6
0
ファイル: vartools.py プロジェクト: varunrai/scrapers
def Convert_Special(filepath=HOME, string=False, quoted=True):
    """
Convert physcial paths stored in text files to their special:// equivalent or
replace instances of physical paths to special in a string sent through.

CODE: Convert_Special([filepath, string])

AVAILABLE PARAMS:

    filepath  -  This is the path you want to scan, by default it's set to the Kodi HOME directory.
    
    string  -  By default this is set to False which means it will convert all instances found of
    the physical paths to their special equivalent. The scan will convert all instances in all filenames
    ending in ini, xml, hash, properties. If you set this value to True you will get a return of your
    'filepath' string and no files will be altered.

    quoted  -  By default this is set to true, this means the return you get will be converted
    with urllib.quote_plus(). This is ideal if you need to get a string you can send
    through as a path for routing.

EXAMPLE CODE:
path = koding.Physical_Path('special://profile')
dialog.ok('ORIGINAL PATH','Let\'s convert this path to it\'s special equivalent:\n[COLOR dodgerblue]%s[/COLOR]'%path)
path = Convert_Special(filepath=path,string=True,quoted=False)
dialog.ok('CONVERTED PATH','This is the converted path:\n[COLOR dodgerblue]%s[/COLOR]'%path)
if dialog.yesno('CONVERT PHYSICAL PATHS','We will now run through your Kodi folder converting all physical paths to their special:// equivalent in xml/hash/properties/ini files.\nDo you want to continue?'):
    koding.Convert_Special()
    dialog.ok('SUCCESS','Congratulations, all references to your physical paths have been converted to special:// paths.')
~"""
    import urllib
    from filetools import Text_File
    if not string:
        for root, dirs, files in os.walk(filepath):
            for file in files:
                if file.endswith(".xml") or file.endswith(".hash") or file.endswith("properies") or file.endswith(".ini"):
                    contents     = Text_File(os.path.join(root,file), 'r')
                    encodedpath  = urllib.quote(HOME)
                    encodedpath2 = encodedpath.replace('%3A','%3a').replace('%5C','%5c')
                    newfile = contents.replace(HOME, 'special://home/').replace(encodedpath, 'special://home/').replace(encodedpath2, 'special://home/')
                    Text_File(os.path.join(root, file), 'w', newfile)
    else:
        encodedpath  = urllib.quote(HOME)
        encodedpath2 = encodedpath.replace('%3A','%3a').replace('%5C','%5c')
        newstring = filepath.replace(HOME, 'special://home/').replace(encodedpath, 'special://home/').replace(encodedpath2, 'special://home/')
        if quoted:
            newstring = urllib.quote_plus(newstring)
        return newstring
コード例 #7
0
ファイル: addons.py プロジェクト: nusch/modules4all
def Addon_Genre(genre='adult'):
    """
[COLOR=gold]PREMIUM FEATURE FOR ADDONS EXCLUSIVELY SUPPORTED AT NOOBSANDNERDS[/COLOR]
If you'd like to hook into this please take a look at the README.

Return a dictionary of add-ons which match a specific genre.

CODE: Addon_Genre([genre])

AVAILABLE PARAMS:
    
    genre  -  By default this is set to 'adult' which will return
    a dictionary of all known adult add-ons. For a full list of all
    the available genres you can filter by take a look at the Add-on Portal
    link below. If you click on each of the genre links then look at the
    url you'll be able to see the name to use. For example if you click on
    "Dev Tools" you'll see the url shows as 'devtools' and that's what you'd
    send through to this function if you only wanted those to show.
    http://noobsandnerds.com/addons/category/genres/

EXAMPLE CODE:
space_addons = koding.Addon_Genre(genre='space')
if space_addons:
    my_return = 'LIST OF AVAILABLE SPACE BASED ADD-ONS:\n\n'

# Convert the dictionary into a list:
    space_addons = space_addons.items()
    for item in space_addons:
        my_return += '[COLOR=gold]Name:[/COLOR] %s   |   [COLOR=dodgerblue]ID:[/COLOR] %s\n' % (item[0],item[1])
    koding.Text_Box('SPACE ADD-ONS',my_return)
~"""
    import binascii
    from __init__ import Main
    from filetools import Text_File
    from systemtools import Timestamp

    xbmc.log('ADDON GENRE: %s' % genre)
    dialog = xbmcgui.Dialog()
    local_path = binascii.hexlify(genre)
    final_path = xbmc.translatePath(
        'special://profile/addon_data/script.module.python.koding.aio/cookies/%s'
        % local_path)
    if os.path.exists(final_path):
        modified = os.path.getmtime(final_path)
        old = int(modified)
        now = int(Timestamp('epoch'))
        # Add a 24hr wait so we don't kill server
        if now > (modified + 86400):
            Main('addon_list|g:%s' % genre)

# Create new file if it doesn't exist
    else:
        Main('addon_list|g:%s' % genre)

    try:
        addon_list = eval(binascii.unhexlify(Text_File(final_path, 'r')))
        return addon_list
    except:
        return False
コード例 #8
0
def Default_Setting(setting='', addon_id='', reset=False):
    """
This will return the DEFAULT value for a setting (as set in resources/settings.xml)
and optionally reset the current value back to this default. If you pass through
the setting as blank it will return a dictionary of all default settings.

CODE:  Default_Setting(setting, [addon_id, reset])

AVAILABLE PARAMS:

    setting  -  The setting you want to retreive the value for.
    Leave blank to return a dictionary of all settings

    addon_id  -  This is optional, if not set it will use the current id.

    reset  -  By default this is set to False but if set to true and it will
    reset the current value to the default.

EXAMPLE CODE:
youtube_path = xbmc.translatePath('special://home/addons/plugin.video.youtube')
if os.path.exists(youtube_path):
    my_value = koding.Default_Setting(setting='youtube.region', addon_id='plugin.video.youtube', reset=False)
    dialog.ok('YOUTUBE SETTING','Below is a default setting for plugin.video.youtube:','Setting: [COLOR=dodgerblue]youtube.region[/COLOR]','Value: [COLOR=dodgerblue]%s[/COLOR]' % my_value)
else:
    dialog.ok('YOUTUBE NOT INSTALLED','We cannot run this example as it uses the YouTube add-on which has not been found on your system.')
~"""
    import re
    from filetools import Text_File
    from systemtools import Data_Type

    if addon_id == '':
        addon_id = Caller()
    values = {}
    addon_path = Addon_Info(id='path', addon_id=addon_id)
    settings_path = os.path.join(addon_path, 'resources', 'settings.xml')
    content = Text_File(settings_path, 'r').splitlines()
    for line in content:
        if 'id="' in line and 'default="' in line:
            idx = re.compile('id="(.*?)"').findall(line)
            idx = idx[0] if (len(idx) > 0) else ''
            value = re.compile('default="(.*?)"').findall(line)
            value = value[0] if (len(value) > 0) else ''
            if setting != '' and idx == setting:
                values = value
                break
            elif idx != '' and value != '' and setting == '':
                values[idx] = value
    if reset:
        if Data_Type(values) == 'dict':
            for item in values.items():
                Addon_Setting(addon_id=addon_id,
                              setting=item[0],
                              value=item[1])
        elif setting != '':
            Addon_Setting(addon_id=addon_id, setting=setting, value=value)
    return values
コード例 #9
0
def Requirements(dependency):
    """
Return the min and max versions of built-in kodi dependencies required by
the running version of Kodi (xbmc.gui, xbmc.python etc.), The return will
be a dictionary with the keys 'min' and 'max'.

CODE: Requirements(dependency)

AVAILABLE PARAMS:

    (*) dependency  -  This is the dependency you want to check.
    You can check any built-in dependency which has backwards-compatibility
    but the most commonly used are xbmc.gui and xbmc.python.

EXAMPLE CODE:
xbmc_gui = Requirements('xbmc.gui')
xbmc_python = Requirements('xbmc.python')
dialog.ok('DEPENDENCIES','[COLOR=dodgerblue]xbmc.gui[/COLOR]  Min: %s  Max: %s'%(xbmc_gui['min'],xbmc_gui['max']),'[COLOR=dodgerblue]xbmc.python[/COLOR]  Min: %s  Max: %s'%(xbmc_python['min'],xbmc_python['max']))
~"""
    from filetools import Physical_Path, Text_File
    from vartools import Find_In_Text
    kodi_ver = xbmc.getInfoLabel("System.BuildVersion")[:2]
    # Dictionary used for fallback if local file not accessible (AFTV for example)
    defaults = {
        '15': {
            'xbmc.gui': ['5.3.0', '5.9.0'],
            'xbmc.python': ['2.1.0', '2.20.0']
        },
        '16': {
            'xbmc.gui': ['5.10.0', '5.10.0'],
            'xbmc.python': ['2.1.0', '2.24.0']
        },
        '17': {
            'xbmc.gui': ['5.12.0', '5.12.0'],
            'xbmc.python': ['2.1.0', '2.25.0']
        }
    }
    root = 'special://xbmc/addons'
    dep_path = os.path.join(root, dependency, 'addon.xml')
    content = Text_File(dep_path, 'r')
    try:
        max_ver = Find_In_Text(content=content, start='version="', end='"')[1]
        min_ver = Find_In_Text(content=content, start='abi="', end='"')[0]
    except:
        xbmc.log(repr(defaults[kodi_ver]), 2)
        try:
            max_ver = defaults[kodi_ver][dependency][1]
            min_ver = defaults[kodi_ver][dependency][0]
        except:
            max_ver = 'unknown'
            min_ver = 'unknown'
    xbmc.log('%s min: %s' % (dependency, min_ver), 2)
    xbmc.log('%s max: %s' % (dependency, max_ver), 2)
    return {'min': min_ver, "max": max_ver}
コード例 #10
0
ファイル: addons.py プロジェクト: nusch/modules4all
def Check_Deps(addon_path, depfiles=[]):
    import re
    from filetools import Text_File
    try:
        readxml = Text_File(os.path.join(addon_path, 'addon.xml'), 'r')
        dmatch = re.compile('import addon="(.+?)"').findall(readxml)
        for requires in dmatch:
            if not 'xbmc.python' in requires and not requires in depfiles:
                depfiles.append(requires)
    except:
        pass
    return depfiles
コード例 #11
0
def Check_Deps(addon_path, depfiles = []):
    import re
    from filetools import Text_File
    from __init__  import dolog
    exclude_list  = ['xbmc.gui', 'script.module.metahandler', 'metadata.common.allmusic.com',\
                    'kodi.resource','xbmc.core','xbmc.metadata','xbmc.addon','xbmc.json','xbmc.python']
    file_location = os.path.join(addon_path,'addon.xml')
    if os.path.exists(file_location):
        readxml = Text_File(file_location,'r')
        dmatch   = re.compile('import addon="(.+?)"').findall(readxml)
        for requires in dmatch:
            if not requires in exclude_list and not requires in depfiles:
                depfiles.append(requires)
    return depfiles
コード例 #12
0
def Check_Deps(addon_path, depfiles=[]):
    import re
    from filetools import Text_File
    exclude_list = [
        'xbmc.gui', 'script.module.metahandler', 'kodi.resource', 'xbmc.core',
        'xbmc.metadata', 'xbmc.addon', 'xbmc.json', 'xbmc.python'
    ]
    try:
        readxml = Text_File(os.path.join(addon_path, 'addon.xml'), 'r')
        dmatch = re.compile('import addon="(.+?)"').findall(readxml)
        for requires in dmatch:
            if not requires in exclude_list and not requires in depfiles:
                depfiles.append(requires)
    except:
        pass
    return depfiles
コード例 #13
0
def Check_Repo(repo,show_busy=True,timeout=10):
    """
This will check the status of repo and return True if the repo is online or False
if it contains paths that are no longer accessible online.

IMPORTANT: If you're running an old version of Kodi which uses the old Python 2.6
(OSX and Android lower than Kodi 17 or a linux install with old Python installed on system)
you will get a return of False on https links regardless of their real status. This is due
to the fact Python 2.6 cannot access secure links. Any still using standard http links
will return the correct results.

CODE:  Check_Repo(repo, [show_busy, timeout])

AVAILABLE PARAMS:

    (*) repo  -  This is the name of the folder the repository resides in.
    You can either use the full path or just the folder name which in 99.99%
    of cases is the add-on id. If only using the folder name DOUBLE check first as
    there are a handful which have used a different folder name to the actual add-on id!

    show_busy - By default this is set to True and a busy dialog will show during the check

    timeout - By default this is set to 10 (seconds) - this is the maximum each request
    to the repo url will take before timing out and returning False.

EXAMPLE CODE:
repo_status = Check_Repo('repository.xxxecho',show_busy=False,timeout=10)
if repo_status:
    dialog.ok('REPO STATUS','The repository modules4all is: [COLOR=lime]ONLINE[/COLOR]')
else:
    dialog.ok('REPO STATUS','The repository modules4all is: [COLOR=red]OFFLINE[/COLOR]')
~"""
    import re

    from __init__  import dolog
    from filetools import Text_File
    from guitools  import Show_Busy
    from web       import Validate_Link
    dolog('### CHECKING %s'%repo)
    status = True
    if show_busy:
        Show_Busy()
    if repo.startswith('special://'):
        repo_path = xbmc.translatePath(repo)
    elif not ADDONS in repo and not XBMC_PATH in repo:
        repo_path = os.path.join(ADDONS,repo)
    else:
        repo_path = repo
    repo_path = os.path.join(repo_path,'addon.xml')
    dolog(repo_path)
    if os.path.exists(repo_path):
        content  = Text_File(repo_path,'r')
        md5_urls = re.findall(r'<checksum>(.+?)</checksum>', content, re.DOTALL)
        for item in md5_urls:
            link_status = Validate_Link(item,timeout)
            dolog(item)
            dolog('STATUS: %s'%link_status)
            if link_status < 200 or link_status >= 400:
                status = False
                break
        if show_busy:
            Show_Busy(False)
        return status
    else:
        if show_busy:
            Show_Busy(False)
        return False
コード例 #14
0
def Addon_Genre(genre='adult',custom_url=''):
    """
Return a dictionary of add-ons which match a specific genre.

CODE: Addon_Genre([genre, custom_url])

AVAILABLE PARAMS:
    
    genre  -  By default this is set to 'adult' which will return
    a dictionary of all known adult add-ons. The genre details are pulled from the
    Add-on Portal at noobsandnerds.com so you can use any of the supported genre tags
    listed on this page: http://noobsandnerds.com/latest/?p=3762

    custom_url  -  If you have your own custom url which returns a dictionary
    of genres you can enter it here and use that rather than rely on NaN categorisation.

EXAMPLE CODE:
dialog.ok('[COLOR gold]ADD-ON GENRES[/COLOR]','We will now list all known comedy based add-ons. If you have add-ons installed which you feel should be categorised as supplying comedy but they aren\'t then you can help tag them up correctly via the Add-on Portal at NaN.')
comedy_addons = koding.Addon_Genre(genre='comedy')
if comedy_addons:
    my_return = 'LIST OF AVAILABLE COMEDY BASED ADD-ONS:\n\n'

# Convert the dictionary into a list:
    comedy_addons = comedy_addons.items()
    for item in comedy_addons:
        my_return += '[COLOR=gold]Name:[/COLOR] %s   |   [COLOR=dodgerblue]ID:[/COLOR] %s\n' % (item[0],item[1])
    koding.Text_Box('[COLOR gold]COMEDY ADD-ONS[/COLOR]',my_return)
~"""
    import binascii
    from __init__       import converthex
    from filetools      import Text_File
    from systemtools    import Timestamp
    from web            import Open_URL
    
    download_new = True
    local_path   = binascii.hexlify('addons')
    cookie_path  = xbmc.translatePath("special://profile/addon_data/script.module.python.koding.aio/cookies/")
    final_path   = os.path.join(cookie_path,local_path)
    if not os.path.exists(cookie_path):
        os.makedirs(cookie_path)

    if os.path.exists(final_path):
        modified = os.path.getmtime(final_path)
        old = int(modified)
        now = int(Timestamp('epoch'))
# Add a 24hr wait so we don't kill server
        if now < (modified+86400):
            download_new = False

# Create new file
    if download_new:
        if custom_url == '':
            custom_url = converthex('687474703a2f2f6e6f6f6273616e646e657264732e636f6d2f6164646f6e732f6164646f6e5f6c6973742e747874')
        addon_list = Open_URL(custom_url)
        Text_File(final_path, "w", addon_list)

# Grab details of the relevant genre
    if os.path.exists(final_path):
        try:
            addon_list = eval( Text_File(final_path, 'r') )
            return addon_list[genre]
        except:
            os.remove(final_path)
            return False
    else:
        return False
コード例 #15
0
def Addon_Service(addons='all', mode='list', skip_service='all'):
    """
Send through an add-on id, list of id's or leave as the default which is "all". This
will loop through the list of add-ons and return the ones which are run as services.

This enable/disable feature will comment out the service lines, and does not stop a running
service or start a service. This is designed more for if you've manually extracted a new
add-on into your system and it isn't yet enabled. Occasionally if the add-ons have dependencies
which are run as services then trying to enable them can cause Kodi to freeze.

CODE: Addon_Service([addon,disable])

AVAILABLE PARAMS:
    
    addons  -  By default this is set to "all" but if there's a sepcific set of add-ons you
    want to disable the service for just send through the id's in the form of a list.

    mode  -  By default this is set to 'list' meaning you'll get a return of add-on folders
    which contain an instance of service in the add-on.xml. You can set this to "disable" to
    comment out the instances of service and similarly when you need to re-enable you can use
    "enable" and that will uncomment out the service item. Please note that by uncommenting
    the service will not automatically start - you'll need to reload the profile for that.

    skip_service  -  This function can fail if certain dependencies are
    run as a service, if they are causing problems you can send through
    the id or a list of id's which you want to disable the service for.
    This will comment out the service part in the addon.xml before attempting
    to enable the add-on. Don't forget to re-enable this if you want the service
    running.

EXAMPLE CODE:
dialog.ok('[COLOR gold]CHECKING FOR SERVICES[/COLOR]','We will now check for all add-ons installed which contain services')
service_addons = Addon_Service(mode='list')
my_text = 'List of add-ons running as a service:\n\n'
for item in service_addons:
    my_text += item+'\n'
koding.Text_Box('[COLOR gold]SERVICE ADDONS[/COLOR]',my_text)
~"""
    from filetools   import Get_Contents, Text_File
    from systemtools import Data_Type
    from guitools    import Text_Box
    service_addons = []
    if addons=='all':
        addons = Get_Contents(path=ADDONS, exclude_list=['packages','temp'],full_path=False)
    else:
        if Data_Type(addons) == 'str':
            addons = [addons]

    if skip_service=='all':
        skip_service = addons
    else:
        if Data_Type(skip_service) == 'str':
            skip_service = [skip_service]

    service_line = '<extension point="xbmc.service"'
    
    for item in addons:
        addon_path = os.path.join(ADDONS,item,'addon.xml')
        if os.path.exists(addon_path) and item not in skip_service:
            content = Text_File(addon_path,'r')
            if service_line in content:
                xbmc.log('%s contains a service,'%item,2)
                for line in content.splitlines():
                    if service_line in line:
                        if item not in service_addons:
                            service_addons.append(item)
                            if not (line.strip().startswith('<!--')) and (mode == 'disable'):
                                replace_line = '<!--%s-->'%line
                                Text_File(addon_path,'w',content.replace(line,replace_line))
                                break
                            elif line.strip().startswith('<!--') and mode == 'enable':
                                replace_line = line.replace(r'<!--','').replace(r'-->','')
                                Text_File(addon_path,'w',content.replace(line,replace_line))
                                break
    return service_addons
コード例 #16
0
def Show_Tutorial(url):
    """ internal command ~"""
    name, filepath = url.split('~')
    filepath = urllib.unquote(filepath)
    readfile = Text_File(filepath,'r')
    raw_find = Find_In_Text(content=readfile, start='# TUTORIAL #\ndef %s' % name,end='~"""')[0]
# Check if an example code segment exists in the comments    
    if 'EXAMPLE CODE:' in raw_find:
        code = re.findall(r'(?<=EXAMPLE CODE:)(?s)(.*$)', raw_find)[0]
        code = code.replace('script.module.python.koding.aio','temp_replace_string')
        code = code.replace('koding.','').strip()
        code = code.replace('temp_replace_string','script.module.python.koding.aio')

    else:
        code = None

# Check if a video exists in the comments
    internetstate = xbmc.getInfoLabel('System.InternetState')
    if internetstate:
        video_page = Open_URL(video_base)
        extension = Find_In_Text(video_page, name, '"', False)
        if extension != '' and extension != None:
            video = video_base+name+extension[0]
        else:
            video = None
    else:
        video = None

    counter  = 0
    removal_string = ''
    final_header   = ''
    newline        = ''
    temp_raw = raw_find.splitlines()
    for line in temp_raw:
        if counter == 0:
            removal_string += line
            if '[' in line:
                replace_file = Find_In_Text(content=line,start='\[',end='\]')
                for item in replace_file:
                    line = line.replace(item,'')
            if ',' in line:
                header_extension = line.split(',')
                for item in header_extension:
                    if '=' in item:
                        item = item.split('=')[0]
                    final_header += item+','
                final_header = 'koding.'+name+final_header[:-2]+')'
            else:
                final_header = 'koding.'+name+line[:-1]
        else:
            removal_string += '\n'+line
        counter += 1
        if counter == 2:
            break
    if final_header.endswith('))'):
        final_header = final_header[:-1]
    if final_header.startswith('koding.User_Info'):
        final_header = 'koding.User_Info()'
    full_text = raw_find.replace(removal_string,'').strip()

# Initialise the dialog select
    dialog_array = ['Documentation']
    if code:
        dialog_array.append('Run Example Code')
    if video:
        dialog_array.append('Watch Video')
    
# If there's more than one item we show a dialog select otherwise we just load up the text window
    if len(dialog_array) > 1:
        choice = dialog.select(name, dialog_array)
        if choice >= 0:
            choice = dialog_array[choice]
        if choice == 'Documentation':
            Text_Box(final_header,full_text
                .replace('AVAILABLE PARAMS:','[COLOR=dodgerblue]AVAILABLE PARAMS:[/COLOR]')
                .replace('EXAMPLE CODE:','[COLOR=dodgerblue]EXAMPLE CODE:[/COLOR]')
                .replace('IMPORTANT:','[COLOR=gold]IMPORTANT:[/COLOR]')
                .replace('CODE:','[COLOR=dodgerblue]CODE:[/COLOR]')
                .replace('AVAILABLE VALUES:','[COLOR=dodgerblue]AVAILABLE VALUES:[/COLOR]')
                .replace('WARNING:','[COLOR=red]WARNING:[/COLOR]'))
        elif choice == 'Run Example Code':
            codefile = filepath.split(os.sep)
            codefile = codefile[len(codefile)-1].replace('.py','')
            exec('from %s import *' % codefile)
            # exec('from %s import %s' % (codefile, params["name"]))
            exec(code)
        elif choice == 'Watch Video':
            Play_Video(video)
        if choice < 0:
            return
    else:
        Text_Box(final_header,full_text
            .replace('AVAILABLE PARAMS:','[COLOR=dodgerblue]AVAILABLE PARAMS:[/COLOR]')
            .replace('EXAMPLE CODE:','[COLOR=dodgerblue]EXAMPLE CODE:[/COLOR]')
            .replace('IMPORTANT:','[COLOR=gold]IMPORTANT:[/COLOR]')
            .replace('CODE:','[COLOR=dodgerblue]CODE:[/COLOR]')
            .replace('AVAILABLE VALUES:','[COLOR=dodgerblue]AVAILABLE VALUES:[/COLOR]')
            .replace('WARNING:','[COLOR=red]WARNING:[/COLOR]'))
コード例 #17
0
ファイル: systemtools.py プロジェクト: smoke61/modules4all
def Grab_Log(log_type='std', formatting='original', sort_order='reverse'):
    """
This will grab the log file contents, works on all systems even forked kodi.

CODE:  Grab_Log([log_type, formatting, sort_order])

AVAILABLE PARAMS:
    
    log_type    -  This is optional, if not set you will get the current log.
    If you would prefer the old log set this to 'old'

    formatting  -  By default you'll just get a default log but you can set
    this to 'warnings', 'notices', 'errors' to filter by only those error types.
    Notices will return in blue, warnings in gold and errors in red.
    You can use as many of the formatting values as you want, just separate by an
    underscore such as 'warnings_errors'. If using anything other than the
    default in here your log will returned in order of newest log activity first
    (reversed order). You can also use 'clean' as an option and that will just
    return the full log but with clean text formatting and in reverse order.

    sort_order   -  This will only work if you've sent through an argument other
    than 'original' for the formatting. By default the log will be shown in
    'reverse' order but you can set this to 'original' if you prefer ascending
    timestamp ordering like a normal log.

EXAMPLE CODE:
my_log = koding.Grab_Log()
dialog.ok('KODI LOG LOOP','Press OK to see various logging options, every 5 seconds it will show a new log style.')
koding.Text_Box('CURRENT LOG FILE (ORIGINAL)',my_log)
xbmc.sleep(5000)
my_log = koding.Grab_Log(formatting='clean', sort_order='reverse')
koding.Text_Box('CURRENT LOG FILE (clean in reverse order)',my_log)
xbmc.sleep(5000)
my_log = koding.Grab_Log(formatting='errors_warnings', sort_order='reverse')
koding.Text_Box('CURRENT LOG FILE (erros & warnings only - reversed)',my_log)
xbmc.sleep(5000)
old_log = koding.Grab_Log(log_type='old')
koding.Text_Box('OLD LOG FILE',old_log)
~"""
    from filetools import Text_File
    log_path = xbmc.translatePath('special://logpath/')
    logfilepath = os.listdir(log_path)
    finalfile = 0
    for item in logfilepath:
        cont = False
        if item.endswith('.log') and not item.endswith(
                '.old.log') and log_type == 'std':
            mylog = os.path.join(log_path, item)
            cont = True
        elif item.endswith('.old.log') and log_type == 'old':
            mylog = os.path.join(log_path, item)
            cont = True
        if cont:
            lastmodified = os.path.getmtime(mylog)
            if lastmodified > finalfile:
                finalfile = lastmodified
                logfile = mylog

    logtext = Text_File(logfile, 'r')

    if formatting != 'original':
        logtext_final = ''

        with open(logfile) as f:
            log_array = f.readlines()
        log_array = [line.strip() for line in log_array]

        if sort_order == 'reverse':
            log_array = reversed(log_array)

        for line in log_array:
            if ('warnings' in formatting
                    or 'clean' in formatting) and 'WARNING:' in line:
                logtext_final += line.replace(
                    'WARNING:', '[COLOR=gold]WARNING:[/COLOR]') + '\n'
            if ('errors' in formatting
                    or 'clean' in formatting) and 'ERROR:' in line:
                logtext_final += line.replace(
                    'ERROR:', '[COLOR=red]ERROR:[/COLOR]') + '\n'
            if ('notices' in formatting
                    or 'clean' in formatting) and 'NOTICE:' in line:
                logtext_final += line.replace(
                    'NOTICE:', '[COLOR=dodgerblue]NOTICE:[/COLOR]') + '\n'

        logtext = logtext_final

    return logtext
コード例 #18
0
ファイル: addons.py プロジェクト: varunrai/scrapers
def Addon_Service(addons='all', mode='list', skip_service=[]):
    """
Send through an add-on id, list of id's or leave as the default which is "all". This
will loop through the list of add-ons and return the ones which are run as services.

This enable/disable feature will comment out the service lines, and does not stop a running
service or start a service. This is designed more for if you've manually extracted a new
add-on into your system and it isn't yet enabled. Occasionally if the add-ons have dependencies
which are run as services then trying to enable them can cause Kodi to freeze.

CODE: Addon_Service([addon,disable])

AVAILABLE PARAMS:
    
    addons  -  By default this is set to "all" but if there's a sepcific set of add-ons you
    want to disable the service for just send through the id's in the form of a list.

    mode  -  By default this is set to 'list' meaning you'll get a return of add-on folders
    which contain an instance of service in the add-on.xml. You can set this to "disable" to
    comment out the instances of service and similarly when you need to re-enable you can use
    "enable" and that will uncomment out the service item. Please note that by uncommenting
    the service will not automatically start - you'll need to reload the profile for that.

    skip_service  -  When running the enable or disable mode you can choose to add a list of
    add-ons you'd like to skip the process for. Of course you may be thinking why would I send
    through a list of addons I want the service enabled/disabled for but then I also add them
    to the skip_service list to say DON'T enable/disable - it makes no sense?! Well you'd be
    correct that doesn't make any sense as presumably you've already filtered out the add-ons
    you don't want affected, this command is designed more for those who don't send through a
    list of add-ons and instead use the default "all" value for the addons paramater. This
    then makes it very easy to just skip a handful of add-on services and enable all others.

EXAMPLE CODE:
dialog.ok('CHECKING FOR SERVICES','We will now check for all add-ons installed which contain services')
service_addons = Addon_Service(mode='list')
my_text = 'List of add-ons running as a service:\n\n'
for item in service_addons:
    my_text += item+'\n'
koding.Text_Box('[COLOR gold]SERVICE ADDONS[/COLOR]',my_text)
~"""
    from filetools  import Get_Contents, Physical_Path, Text_File
    from vartools   import Data_Type
    from guitools   import Text_Box
    service_addons = []
    if addons=='all':
        addons = Get_Contents(path=ADDONS, exclude_list=['packages','temp'],full_path=False)
    else:
        if Data_Type(addons) == 'str':
            addons = [addons]

    if Data_Type(skip_service) == 'str':
        skip_service = [skip_service]

    service_line = '<extension point="xbmc.service"'
    
    for item in addons:
        addon_path = os.path.join(ADDONS,item,'addon.xml')
        content = Text_File(addon_path,'r')
        if service_line in content:
            if item not in service_addons:
                service_addons.append(item)
                if mode != 'list':
                    if not item in skip_service:
                        for line in content.splitlines():
                            if service_line in line:
                                if not (line.strip().startswith('<!--')) and (mode == 'disable'):
                                    replace_line = '<!--%s-->'%line
                                    Text_File(addon_path,'w',content.replace(line,replace_line))
                                    break
                                elif line.strip().startswith('<!--') and mode == 'enable':
                                    replace_line = line.replace(r'<!--','').replace(r'-->','')
                                    Text_File(addon_path,'w',content.replace(line,replace_line))
                                    break
    return service_addons
コード例 #19
0
def Addon_Genre(genre='adult', custom_url=''):
    """
[COLOR=gold]PREMIUM FEATURE FOR ADDONS EXCLUSIVELY SUPPORTED AT NOOBSANDNERDS[/COLOR]
If you'd like to hook into this please take a look at the README.

Please Note: Although this hooks into the NaN framework to pull genres you can use this without
having to hook into their framework if you have a custom url which returns results in the same format.
Your url must return a dictionary of items in this format: {"addon_name":"addon_id","addon_name_2":"addon_id_2"}

Return a dictionary of add-ons which match a specific genre.

CODE: Addon_Genre([genre, custom_url])

AVAILABLE PARAMS:
    
    genre  -  By default this is set to 'adult' which will return
    a dictionary of all known adult add-ons. For a full list of all
    the available genres you can filter by take a look at the Add-on Portal
    link below. If you click on each of the genre links then look at the
    url you'll be able to see the name to use. For example if you click on
    "Dev Tools" you'll see the url shows as 'devtools' and that's what you'd
    send through to this function if you only wanted those to show.
    http://noobsandnerds.com/addons/category/genres/

    custom_url  -  If you have your own custom url which returns genres
    you can enter it here and use that rather than rely on NaN categorisation.

EXAMPLE CODE:
space_addons = koding.Addon_Genre(genre='space')
if space_addons:
    my_return = 'LIST OF AVAILABLE SPACE BASED ADD-ONS:\n\n'

# Convert the dictionary into a list:
    space_addons = space_addons.items()
    for item in space_addons:
        my_return += '[COLOR=gold]Name:[/COLOR] %s   |   [COLOR=dodgerblue]ID:[/COLOR] %s\n' % (item[0],item[1])
    koding.Text_Box('SPACE ADD-ONS',my_return)
~"""
    import binascii
    from __init__ import Main
    from filetools import Text_File
    from systemtools import Timestamp
    from web import Open_URL

    local_path = binascii.hexlify(genre)
    cookie_path = xbmc.translatePath(
        "special://profile/addon_data/script.module.python.koding.aio/cookies/"
    )
    final_path = os.path.join(cookie_path, local_path)
    if not os.path.exists(cookie_path):
        os.makedirs(cookie_path)

    if os.path.exists(final_path):
        modified = os.path.getmtime(final_path)
        old = int(modified)
        now = int(Timestamp('epoch'))
        # Add a 24hr wait so we don't kill server
        if now > (modified + 86400):
            if custom_url == '':
                Main('addon_list|g:%s' % genre)
            else:
                addon_list = Open_URL(custom_url)
                try:
                    addon_list = eval(addon_list)
                    Text_File(final_path, "w",
                              binascii.hexlify(str(addon_list)))
                except:
                    pass

# Create new file if it doesn't exist
    else:
        if custom_url == '':
            Main('addon_list|g:%s' % genre)
        else:
            addon_list = Open_URL(custom_url)
            try:
                addon_list = eval(addon_list)
                Text_File(final_path, "w", binascii.hexlify(str(addon_list)))
            except:
                pass

    if os.path.exists(final_path):
        try:
            addon_list = eval(binascii.unhexlify(Text_File(final_path, 'r')))
            return addon_list
        except:
            return False
    else:
        return False
コード例 #20
0
def Addon_Genre(genre='adult', custom_url=''):
    """
Return a dictionary of add-ons which match a specific genre.

CODE: Addon_Genre([genre, custom_url])

AVAILABLE PARAMS:
    
    genre  -  By default this is set to 'adult' which will return a dictionary of all known
    adult add-ons. We recommend using the genre labels listed below as they are already in use
    by some add-on developers, however you can of course create your very own genre keys in
    your custom genre file if you wish.

    custom_url  -  If you have your own custom url which returns a dictionary
    of genres and add-ons you can enter it here. The page must adhere to the format shown below.

    Recommended Genre Keys:
    adult, anime, audiobooks, comedy, comics, documentary, food, gaming, health, howto, kids,
    livetv, movies, music, news, podcasts, radio, religion, space, sports, subscription,
    tech, trailers, tvshows, world

    Correct Genre Dictionary Structure:
    The dictionary must be a dictionary of genres with each genre dictionary containing keys for
    each add-on ID and the value being the name you want displayed. See below for an example:
    { "movies":{"plugin.video.mymovie":"My movie add-on","plugin.video.trailers":"My Trailer add-on"}, "sports":{"plugin.video.sports":"Sport Clips"} }

EXAMPLE CODE:
dialog.ok('ADD-ON GENRES','We will now list all known comedy based add-ons. If you have add-ons installed which you feel should be categorised as supplying comedy but they aren\'t then you can help tag them up correctly via the Add-on Portal at NaN.')
comedy_addons = koding.Addon_Genre(genre='comedy')
if comedy_addons:
    my_return = 'LIST OF AVAILABLE COMEDY BASED ADD-ONS:\n\n'

# Convert the dictionary into a list:
    comedy_addons = comedy_addons.items()
    for item in comedy_addons:
        my_return += '[COLOR=gold]Name:[/COLOR] %s   |   [COLOR=dodgerblue]ID:[/COLOR] %s\n' % (item[0],item[1])
    koding.Text_Box('[COLOR gold]COMEDY ADD-ONS[/COLOR]',my_return)
~"""
    import binascii
    from __init__ import converthex
    from filetools import Text_File
    from systemtools import Timestamp
    from vartools import Merge_Dicts
    from web import Open_URL

    download_new = True
    local_path = binascii.hexlify('genre_list')
    cookie_path = "special://profile/addon_data/script.module.python.koding.aio/cookies/"
    custom_genres = "special://profile/addon_data/script.module.python.koding.aio/genres.txt"
    final_path = os.path.join(cookie_path, local_path)
    if not xbmcvfs.exists(cookie_path):
        xbmcvfs.mkdirs(cookie_path)

    if xbmcvfs.exists(final_path):
        modified = xbmcvfs.Stat(final_path).st_mtime()
        old = int(modified)
        now = int(Timestamp('epoch'))
        # Add a 24hr wait so we don't kill server
        if now < (modified + 86400):
            download_new = False

# Create new file
    if download_new and custom_url != '':
        addon_list = Open_URL(custom_url)
        Text_File(final_path, "w", addon_list)

# Grab details of the relevant genre
    if xbmcvfs.exists(final_path):
        try:
            addon_list = eval(Text_File(final_path, 'r'))
            addon_list = addon_list[genre]
        except:
            xbmcvfs.delete(final_path)
            addon_list = {}

    if xbmcvfs.exists(custom_genres):
        try:
            custom_list = eval(Text_File(custom_genres, 'r'))
            custom_list = custom_list[genre]
            addon_list = Merge_Dicts(addon_list, custom_list)
        except:
            pass
    return addon_list
コード例 #21
0
def Addon_Service(addons='all', mode='list', skip_service=[]):
    """
Send through an add-on id, list of id's or leave as the default which is "all". This
will loop through the list of add-ons and return the ones which are run as services.

This enable/disable feature will comment out the service lines, and does not stop a running
service or start a service. This is designed more for if you've manually extracted a new
add-on into your system and it isn't yet enabled. Occasionally if the add-ons have dependencies
which are run as services then trying to enable them can cause Kodi to freeze.

CODE: Addon_Service([addon,disable])

AVAILABLE PARAMS:
    
    addons  -  By default this is set to "all" but if there's a sepcific set of add-ons you
    want to disable the service for just send through the id's in the form of a list.

    mode  -  By default this is set to 'list' meaning you'll get a return of add-on folders
    which contain an instance of service in the add-on.xml. You can set this to "disable" to
    comment out the instances of service and similarly when you need to re-enable you can use
    "enable" and that will uncomment out the service item. Please note that by uncommenting
    the service will not automatically start - you'll need to reload the profile for that.

    skip_service  -  When running the enable or disable mode you can choose to add a list of
    add-ons you'd like to skip the process for. Of course you may be thinking why would I send
    through a list of addons I want the service enabled/disabled for but then I also add them
    to the skip_service list to say DON'T enable/disable - it makes no sense?! Well you'd be
    correct that doesn't make any sense as presumably you've already filtered out the add-ons
    you don't want affected, this command is designed more for those who don't send through a
    list of add-ons and instead use the default "all" value for the addons paramater. This
    then makes it very easy to just skip a handful of add-on services and enable all others.

EXAMPLE CODE:
dialog.ok('CHECKING FOR SERVICES','We will now check for all add-ons installed which contain services')
service_addons = Addon_Service(mode='list')
my_text = 'List of add-ons running as a service:\n\n'
for item in service_addons:
    my_text += item+'\n'
koding.Text_Box('[COLOR gold]SERVICE ADDONS[/COLOR]',my_text)
~"""
    from filetools import Get_Contents, Physical_Path, Text_File
    from vartools import Data_Type
    from guitools import Text_Box
    service_addons = []
    if addons == 'all':
        addons = Get_Contents(path=ADDONS,
                              exclude_list=['packages', 'temp'],
                              full_path=False)
    else:
        if Data_Type(addons) == 'str':
            addons = [addons]

    if Data_Type(skip_service) == 'str':
        skip_service = [skip_service]

    service_line = '<extension point="xbmc.service"'

    for item in addons:
        addon_path = os.path.join(ADDONS, item, 'addon.xml')
        content = Text_File(addon_path, 'r')
        if service_line in content:
            if item not in service_addons:
                service_addons.append(item)
                if mode != 'list':
                    if not item in skip_service:
                        for line in content.splitlines():
                            if service_line in line:
                                if not (line.strip().startswith('<!--')) and (
                                        mode == 'disable'):
                                    replace_line = '<!--%s-->' % line
                                    Text_File(
                                        addon_path, 'w',
                                        content.replace(line, replace_line))
                                    break
                                elif line.strip().startswith(
                                        '<!--') and mode == 'enable':
                                    replace_line = line.replace(r'<!--',
                                                                '').replace(
                                                                    r'-->', '')
                                    Text_File(
                                        addon_path, 'w',
                                        content.replace(line, replace_line))
                                    break
    return service_addons
コード例 #22
0
ファイル: video.py プロジェクト: smoke61/modules4all
def M3U_Selector(url, post_type='get', header='Stream Selection'):
    """
Send through an m3u/m3u8 playlist and have the contents displayed via a dialog select.
The return will be a dictionary of 'name' and 'url'. You can send through either
a locally stored filepath or an online URL.

This function will try it's best to pull out the relevant playlist details even if the
web page isn't a correctly formatted m3u playlist (e.g. an m3u playlist embedded into
a blog page).

CODE: M3U_Selector(url, [post_type, header])

AVAILABLE PARAMS:
    (*) url  -  The location of your m3u file, this can be local or online

    post_type  -  If you need to use POST rather than a standard query string
    in your url set this to 'post', by default it's set to 'get'.

    header  -  This is the header you want to appear at the top of your dialog
    selection window, by default it's set to "Stream Selection"

EXAMPLE CODE:
# This example uses YouTube plugin paths but any playable paths will work
vid = koding.M3U_Selector(url='http://totalrevolution.tv/videos/playlists/youtube.m3u')

# Make sure there is a valid link returned
if vid:
    playback = koding.Play_Video(video=vid['url'], showbusy=False)
    if playback:
        dialog.ok('SUCCESS!','Congratulations the playback was successful!')
        xbmc.Player().stop()
    else:
        dialog.ok('OOPS!','Looks like something went wrong there, the playback failed. Check the links are still valid.')
~"""
    from web import Open_URL
    from vartools import Cleanup_String, Find_In_Text
    from filetools import Text_File
    success = False
    if url.startswith('http'):
        content = Open_URL(url=url, post_type=post_type, timeout=10)
    else:
        try:
            url = xbmc.translatePath(url)
        except:
            pass
        content = Text_File(url, 'r')
    if content:
        newcontent = content.splitlines()
        name_array = []
        url_array = []
        name = ''
        for line in newcontent:
            line = line.strip()
            # Grab the name of the stream
            if line.startswith('#EXT'):
                name = line.split(',')
                name.pop(0)
                name = ''.join(name)
        # Grab the url(s) of the stream
            if name != '' and line != '' and not line.startswith('#EXT'):
                name_array.append(Cleanup_String(name))
                line = line.replace('<br>',
                                    '').replace('<br />',
                                                '').replace('<br/>', '')
                line = line.replace('</p>',
                                    '').replace('</div>',
                                                '').replace('</class>', '')
                dolog('line: %s' % line)
                if 'm3u' in line or 'm3u8' in line:
                    line = 'LIST~' + line
                if 'src="' in line:
                    line = Find_In_Text(content=line, start='src="',
                                        end='"')[0]
                url_array.append(line)
                name = ''
                line = ''
        # If there is only one entry with no names/comments just return as unknown with the link
            if not '#EXT' in content:
                return {'name': 'Unknown', 'url': line}

    # If there's a list we show a dialog select of the available links
        if len(name_array) > 0:
            choice = xbmcgui.Dialog().select(header, name_array)
            if choice >= 0:

                # If the selection is a final url and not a list of multiple links
                if not url_array[choice].startswith('LIST~'):
                    success = True
                    return {
                        'name': name_array[choice],
                        'url': url_array[choice]
                    }

            # List of multiple links detected, give option of which link to play
                else:
                    clean_link = url_array[choice].replace('LIST~', '')
                    content = Open_URL(url=clean_link, timeout=10)
                    if content:
                        newcontent = content.splitlines()
                        name_array = []
                        url_array = []
                        name = ''
                        counter = 1
                        for line in newcontent:
                            # Show name as link 1,2,3,4 etc.
                            if line.startswith('#EXT'):
                                name = 'LINK ' + str(counter)
                        # Grab the link(s) to the video
                            if name != '' and line != '' and not line.startswith(
                                    '#EXT'):
                                name_array.append(name)
                                line = line.replace('<br>', '').replace(
                                    '<br />', '').replace('<br/>', '')
                                line = line.replace('</p>', '').replace(
                                    '</div>', '').replace('</class>', '')
                                url_array.append(line)
                                name = ''
                                line = ''
                                counter += 1
                        # If there is only one entry with no names/comments just return as unknown with the link
                            if not '#EXT' in content:
                                return {'name': 'Unknown', 'url': line}

                    # Give option of which link to play in case of multiple links available
                        if len(name_array) > 0:
                            choice = xbmcgui.Dialog().select(
                                header, name_array)
                            if choice >= 0:
                                success = True
                                return {
                                    'name': name_array[choice],
                                    'url': url_array[choice]
                                }
    if not success:
        xbmcgui.Dialog().ok(
            'NO LINKS FOUND',
            'Sorry no valid links could be found for this stream.')
        return False