def Delete_Files(filepath=HOME, filetype='*.txt', subdirectories=False):
    """
Delete all specific filetypes in a path (including sub-directories)

CODE: Delete_Files([filepath, filetype, subdirectories])

AVAILABLE PARAMS:
    
    (*) filepath  -  By default this points to the Kodi HOME folder (special://home).
    The path you send through must be a physical path and not special://

    (*) filetype  -  The type of files you want to delete, by default it's set to *.txt

    subdirectories  -  By default it will only search the folder given, if set to True
    all filetypes listed above will be deleted in the sub-directories too.

WARNING: This is an extremely powerful and dangerous tool! If you wipe your whole system
by putting in the wrong path then it's your own stupid fault!

EXAMPLE CODE:
delete_path = 'special://profile/addon_data/test'
xbmcvfs.mkdirs(delete_path)
test1 = os.path.join(delete_path,'test1.txt')
test2 = os.path.join(delete_path,'test2.txt')
koding.Text_File(test1,'w','testing1')
koding.Text_File(test2,'w','testing2')
dialog.ok('DELETE FILES','All *.txt files will be deleted from:', '', '/userdata/addon_data/test/')
koding.Delete_Files(filepath=delete_path, filetype='.txt', subdirectories=True)
~"""
    filepath = Physical_Path(filepath)
    if filepath == '/' or filepath == '.' or filepath == '' or (
            filepath[1] == ':' and len(filepath) < 4):
        dialog.ok(
            'IDTenT ERROR!!!', 'You are trying to wipe your whole system!!!',
            'Be more careful in future, not everyone puts checks like this in their code!'
        )
        return

    if os.path.exists(filepath):
        filetype = filetype.replace('*', '')

        if subdirectories:
            for parent, dirnames, filenames in os.walk(filepath):
                for fn in filenames:
                    if fn.lower().endswith(filetype):
                        xbmcvfs.delete(os.path.join(parent, fn))

        else:
            for delete_file in xbmcvfs.listdir(filepath):
                delete_path = os.path.join(filepath, delete_file)
                if delete_path.endswith(filetype):
                    try:
                        xbmcvfs.delete(delete_path)
                    except:
                        xbmc.log(Last_Error(), 2)
    else:
        xbmc.log(
            '### Cannot delete files as directory does not exist: %s' %
            filepath, 2)
def Text_File(path, mode, text=''):
    """
Open/create a text file and read/write to it.

CODE: koding.Text_File(path, mode, [text])

AVAILABLE PARAMS:
    
    (*) path  -  This is the path to the text file

    (*) mode  -  This can be 'r' (for reading) or 'w' (for writing)

    text  -  This is only required if you're writing to a file, this
    is the text you want to enter. This will completely overwrite any
    text already in the file.

EXAMPLE CODE:
HOME = koding.Physical_Path('special://home')
koding_test = os.path.join(HOME, 'koding_test.txt')
koding.Text_File(path=koding_test, mode='w', text='Well done, you\'ve created a text file containing this text!')
dialog.ok('CREATE TEXT FILE','If you check your home Kodi folder and you should now have a new koding_test.txt file in there.','[COLOR=gold]DO NOT DELETE IT YET![/COLOR]')
mytext = koding.Text_File(path=koding_test, mode='r')
dialog.ok('TEXT FILE CONTENTS','The text in the file created is:','[COLOR=dodgerblue]%s[/COLOR]'%mytext,'[COLOR=gold]CLICK OK TO DELETE THE FILE[/COLOR]')
try:
    os.remove(koding_test)
except:
    dialog.ok('FAILED TO REMOVE','Could not remove the file, looks like you might have it open in a text editor. Please manually remove yourself')
~"""
    try:
        textfile = xbmcvfs.File(path, mode)

        if mode == 'r':
            content = textfile.read()
            textfile.close()
            return content

        if mode == 'w':
            textfile.write(text)
            textfile.close()
            return True

    except:
        xbmc.log(Last_Error(), 2)
        return False


#----------------------------------------------------------------
Example #3
0
def Toggle_Addons(addon='all', enable=True, safe_mode=True, exclude_list=[], new_only=True, refresh=True, update_status=0):
    """
Send through either a list of add-on ids or one single add-on id.
The add-ons sent through will then be added to the addons*.db
and enabled or disabled (depending on state sent through).

WARNING: If safe_mode is set to False this directly edits the
addons*.db rather than using JSON-RPC. Although directly amending
the db is a lot quicker there is no guarantee it won't cause
severe problems in later versions of Kodi (this was created for v17).
DO NOT set safe_mode to False unless you 100% understand the consequences!

CODE:  Toggle_Addons([addon, enable, safe_mode, exclude_list, new_only, refresh])

AVAILABLE PARAMS:
    (*) addon  -  This can be a list of addon ids, one single id or
    'all' to enable/disable all. If enabling all you can still use
    the exclude_list for any you want excluded from this function.
    enable  -  By default this is set to True, if you want to disable
    the add-on(s) then set this to False.
    
    safe_mode  -  By default this is set to True which means the add-ons
    are enabled/disabled via JSON-RPC which is the method recommended by
    the XBMC foundation. Setting this to False will result in a much
    quicker function BUT there is no guarantee this will work on future
    versions of Kodi and it may even cause corruption in future versions.
    Setting to False is NOT recommended and you should ONLY use this if
    you 100% understand the risks that you could break multiple setups.
    
    exclude_list  -  Send through a list of any add-on id's you do not
    want to be included in this command.
    
    new_only  -  By default this is set to True so only newly extracted
    add-on folders will be enabled/disabled. This means that any existing
    add-ons which have deliberately been disabled by the end user are
    not affected.
    
    refresh  - By default this is set to True, it will refresh the
    current container and also force a local update on your add-ons db.

    update_status  - When running this function it needs to disable the
    auto-update of add-ons by Kodi otherwise it risks crashing. This
    update_status paramater is the state you want Kodi to revert back to
    once the toggle of add-ons has completed. By default this is set to 0
    which is auto-update. You can also choose 1 (notify of updates) or 2
    (disable auto updates).

EXAMPLE CODE:
from systemtools import Refresh
xbmc.executebuiltin('ActivateWindow(Videos, addons://sources/video/)')
xbmc.sleep(2000)
dialog.ok('DISABLE YOUTUBE','We will now disable YouTube (if installed)')
koding.Toggle_Addons(addon='plugin.video.youtube', enable=False, safe_mode=True, exclude_list=[], new_only=False)
koding.Refresh('container')
xbmc.sleep(2000)
dialog.ok('ENABLE YOUTUBE','When you click OK we will enable YouTube (if installed)')
koding.Toggle_Addons(addon='plugin.video.youtube', enable=True, safe_mode=True, exclude_list=[], new_only=False)
koding.Refresh('container')
~"""
    from __init__       import dolog
    from filetools      import DB_Path_Check, Get_Contents
    from database       import DB_Query
    from systemtools    import Data_Type, Last_Error, Refresh, Set_Setting, Sleep_If_Function_Active, Timestamp

    Set_Setting('general.addonupdates', 'kodi_setting', '2')
    dolog('disabled auto updates for add-ons')
    kodi_ver        = int(float(xbmc.getInfoLabel("System.BuildVersion")[:2]))
    addons_db       = DB_Path_Check('addons')
    data_type       = Data_Type(addon)
    state           = int(bool(enable))
    enabled_list    = []
    disabled_list   = []
    if kodi_ver >= 17:
        on_system   = DB_Query(addons_db,'SELECT addonID, enabled from installed')
# Create a list of enabled and disabled add-ons already on system
        enabled_list  = Addon_List(enabled=True)
        disabled_list = Addon_List(enabled=False)

# If addon has been sent through as a string we add into a list
    if data_type == 'unicode':
        addon = addon.encode('utf8')
        data_type = Data_Type(addon)

    if data_type == 'str' and addon!= 'all':
        addon = [addon]

# Grab all the add-on ids from addons folder
    if addon == 'all':
        addon     = []
        ADDONS    = xbmc.translatePath('special://home/addons')
        my_addons = Get_Contents(path=ADDONS, exclude_list=['packages','temp'])
        for item in my_addons:
            addon_id = Get_Addon_ID(item)
            addon.append(addon_id)

# Find out what is and isn't enabled in the addons*.db
    temp_list = []
    for addon_id in addon:
        if not addon_id in exclude_list and addon_id != '':
            dolog('CHECKING: %s'%addon_id)
            if addon_id in disabled_list and not new_only and enable:
                temp_list.append(addon_id)
            elif addon_id not in disabled_list and addon_id not in enabled_list:
                temp_list.append(addon_id)
            elif addon_id in enabled_list and not enable:
                temp_list.append(addon_id)
            elif addon_id in disabled_list and enable:
                temp_list.append(addon_id)
    addon = temp_list

# If you want to bypass the JSON-RPC mode and directly modify the db (READ WARNING ABOVE!!!)
    if not safe_mode and kodi_ver >= 17:
        installedtime   = Timestamp('date_time')
        insert_query    = 'INSERT or IGNORE into installed (addonID , enabled, installDate) VALUES (?,?,?)'
        update_query    = 'UPDATE installed SET enabled = ? WHERE addonID = ? '
        insert_values   = [addon, state, installedtime]
        try:
            for item in addon:
                DB_Query(addons_db, insert_query, [item, state, installedtime])
                DB_Query(addons_db, update_query, [state, item])
        except:
            dolog(Last_Error())
        if refresh:
            Refresh()

# Using the safe_mode (JSON-RPC)
    else:
        mydeps        = []
        final_enabled = []
        if state:
            my_value      = 'true'
            log_value     = 'ENABLED'
            final_addons  = []
        else:
            my_value      = 'false'
            log_value     = 'DISABLED'
            final_addons  = addon

        for my_addon in addon:

        # If enabling the add-on then we also check for dependencies and enable them first
            if state:
                dolog('Checking dependencies for : %s'%my_addon)
                dependencies = Dependency_Check(addon_id=my_addon, recursive=True)
                mydeps.append(dependencies)

    # if enable selected we traverse through the dependencies enabling addons with lowest amount of deps to highest
        if state:
            mydeps = sorted(mydeps, key=len)
            for dep in mydeps:
                counter = 0
                for item in dep:
                    enable_dep = True
                    if counter == 0:
                        final_addons.append(item)
                        enable_dep = False
                    elif item in final_enabled:
                        enable_dep = False
                    else:
                        enable_dep = True
                    if enable_dep:
                        if not item in exclude_list and not item in final_enabled and not item in enabled_list:
                            dolog('Attempting to enable: %s'%item)
                            if Set_Setting(setting_type='addon_enable', setting=item, value = 'true'):
                                dolog('%s now %s' % (item, log_value))
                                final_enabled.append(item)
                    counter += 1

    # Now the dependencies are enabled we need to enable the actual main add-ons
        for my_addon in final_addons:
            if not my_addon in final_enabled:
                dolog('Attempting to enable: %s'%my_addon)
                if Set_Setting(setting_type='addon_enable', setting=my_addon, value = my_value):
                    dolog('%s now %s' % (my_addon, log_value))
                    final_enabled.append(addon)
            else:
                dolog('Already enabled, skipping: %s'%my_addon)
    if refresh:
        Refresh(['addons','container'])
    Set_Setting('general.addonupdates', 'kodi_setting', '%s'%update_status)
#----------------------------------------------------------------
Example #4
0
def Extract(_in, _out, dp=None, show_error=False):
    """
This function will extract a zip or tar file and return true or false so unlike the
builtin xbmc function "Extract" this one will pause code until it's completed the action.

CODE: koding.Extract(src,dst,[dp])
dp is optional, by default it is set to false

AVAILABLE PARAMS:

    (*) src    - This is the source file, the actual zip/tar. Make sure this is a full path to
    your zip file and also make sure you're not using "special://". This extract function
    is only compatible with .zip/.tar/.tar.gz files

    (*) dst    - This is the destination folder, make sure it's a physical path and not
    "special://...". This needs to be a FULL path, if you want it to extract to the same
    location as where the zip is located you still have to enter the full path.

    dp - This is optional, if you pass through the dp function as a DialogProgress()
    then you'll get to see the status of the extraction process. If you choose not to add
    this paramater then you'll just get a busy spinning circle icon until it's completed.
    See the example below for a dp example.

    show_error - By default this is set to False, if set to True an error dialog 
    will appear showing details of the file which failed to extract.

EXAMPLE CODE:
koding_path = koding.Physical_Path('special://home/addons/script.module.python.koding.aio')
zip_dest = koding.Physical_Path('special://home/test_addon.zip')
extract_dest = koding.Physical_Path('special://home/TEST')
koding.Compress(src=koding_path,dst=zip_dest,compression='zip',parent=True)
dp = xbmcgui.DialogProgress()
dp.create('Extracting Zip','Please Wait')
if koding.Extract(_in=zip_dest,_out=extract_dest,dp=dp,show_error=True):
    dialog.ok('YAY IT WORKED!','We just zipped up your python koding add-on then extracted it to a new folder in your Kodi root directory called TEST. Press OK to delete these files.')
    xbmcvfs.delete(zip_dest)
    shutil.rmtree(extract_dest)
else:
    dialog.ok('BAD NEWS!','UH OH SOMETHING WENT HORRIBLY WRONG')
~"""
    import tarfile
    import xbmcaddon
    import zipfile

    module_id   = 'script.module.python.koding.aio'
    this_module = xbmcaddon.Addon(id=module_id)
    nFiles      = 0
    count       = 0

    if xbmcvfs.exists(_in):
        if zipfile.is_zipfile(_in):
            zin      = zipfile.ZipFile(_in,  'r')
            nFiles   = float(len(zin.infolist()))
            contents = zin.infolist()

        elif tarfile.is_tarfile(_in):
            zin      = tarfile.open(_in)
            contents = [tarinfo for tarinfo in zin.getmembers()]
            nFiles   = float(len(contents))
       
        if nFiles > 0:
            if dp:
                try:
                    for item in contents:
                        count += 1
                        update = count / nFiles * 100
                        dp.update(int(update))
                        zin.extract(item, _out)
                    zin.close()
                    return True

                except:
                    xbmc.log(Last_Error(),2)
                    return False
            else:
                try:
                    zin.extractall(_out)
                    return True
                except:
                    xbmc.log(Last_Error(),2)
                    return False
        
        else:
            xbmc.log('NOT A VALID ZIP OR TAR FILE: %s' % _in,2)
    else:
        if show_error:
            dialog.ok(this_module.getLocalizedString(30965),this_module.getLocalizedString(30815) % _in)
Example #5
0
def Run(default="main"):
    """
This needs to be called at the bottom of your code in the main default.py

This checks the modes called in Add_Dir and does all the clever stuff
in the background which assigns those modes to functions and sends
through the various params.

Just after this command you need to make
sure you set the endOfDirectory (as shown below).


CODE: run([default])
xbmcplugin.endOfDirectory(int(sys.argv[1]))

AVAILABLE PARAMS:
    
    default  -  This is the default mode you want the add-on to open
    into, it's set as "main" by default. If you have a different mode
    name you want to open into just edit accordingly.
~"""
    import urllib
    import urlparse
    import sys
    from __init__    import DEBUG
    from guitools    import Text_Box
    from systemtools import Last_Error

    params = dict(urlparse.parse_qsl(sys.argv[2].replace('?', '')))
    mode = params.get("mode", default)
    if mode in master_modes:
        evaled_args = []

    # Grab the url and split up into a dictionary of args
        try:
            main_url = params["url"]
        # Convert back from special to physical path - useful for community shares
            if urllib.unquote_plus("special://home/") in main_url:
                main_url = main_url.replace('special://home/',HOME)
        except:
            main_url = ''
        try:
            my_args = eval(main_url)
        except:
            my_args = {"url":main_url}

        for arg in master_modes[mode]["args"]:
            try:
                evaled_args.append(my_args[arg])
            except:
                if DEBUG == 'true':
                    dialog.ok('ERROR IN CODE','Your Add_Dir function is expecting the [COLOR=gold][B]%s[/B][/COLOR] paramater to be sent through. This does not exist, please check your Add_Dir function.'%arg)
                    xbmc.log(Last_Error(),2)
                return
        try:
            master_modes[mode]["function"](*evaled_args)
        except:
            if DEBUG == 'true':
                Text_Box('ERROR IN CODE', Last_Error())
                xbmc.log(Last_Error(),2)
            else:
                pass
    else:
        dialog.ok('MODE DOES NOT EXIST',
                            'The following mode does not exist in your\
                            master_modes dictionary:',
                            '[COLOR=dodgerblue]%s[/COLOR]' % mode)
Example #6
0
def Toggle_Addons(addon='all',
                  enable=True,
                  safe_mode=True,
                  exclude_list=[],
                  new_only=True,
                  refresh=True):
    """
Send through either a list of add-on ids or one single add-on id.
The add-ons sent through will then be added to the addons*.db
and enabled or disabled (depending on state sent through).
WARNING: If safe_mode is set to False this directly edits the
addons*.db rather than using JSON-RPC. Although directly amending
the db is a lot quicker there is no guarantee it won't cause
severe problems in later versions of Kodi (this was created for v17).
DO NOT set safe_mode to False unless you 100% understand the consequences!
CODE:  Toggle_Addons([addon, enable, safe_mode, exclude_list, new_only, refresh])
AVAILABLE PARAMS:
    (*) addon  -  This can be a list of addon ids, one single id or
    'all' to enable/disable all. If enabling all you can still use
    the exclude_list for any you want excluded from this function.
    enable  -  By default this is set to True, if you want to disable
    the add-on(s) then set this to False.
    safe_mode  -  By default this is set to True which means the add-ons
    are enabled/disabled via JSON-RPC which is the method recommended by
    the XBMC foundation. Setting this to False will result in a much
    quicker function BUT there is no guarantee this will work on future
    versions of Kodi and it may even cause corruption in future versions.
    Setting to False is NOT recommended and you should ONLY use this if
    you 100% understand the risks that you could break multiple setups.
    exclude_list  -  Send through a list of any add-on id's you do not
    want to be included in this command.
    new_only  -  By default this is set to True so only newly extracted
    add-on folders will be enabled/disabled. This means that any existing
    add-ons which have deliberately been disabled by the end user are
    not affected.
    refresh  - By default this is set to True, it will refresh the
    current container and also force a local update on your add-ons db.
EXAMPLE CODE:
from systemtools import Refresh
xbmc.executebuiltin('ActivateWindow(Videos, addons://sources/video/)')
xbmc.sleep(2000)
dialog.ok('DISABLE YOUTUBE','We will now disable YouTube (if installed)')
koding.Toggle_Addons(addon='plugin.video.youtube', enable=False, safe_mode=True, exclude_list=[], new_only=False)
koding.Refresh('container')
xbmc.sleep(2000)
dialog.ok('ENABLE YOUTUBE','When you click OK we will enable YouTube (if installed)')
koding.Toggle_Addons(addon='plugin.video.youtube', enable=True, safe_mode=True, exclude_list=[], new_only=False)
koding.Refresh('container')
~"""
    from __init__ import dolog
    from filetools import DB_Path_Check, Get_Contents
    from database import DB_Query
    from systemtools import Data_Type, Last_Error, Refresh, Set_Setting, Timestamp

    kodi_ver = int(float(xbmc.getInfoLabel("System.BuildVersion")[:2]))
    addons_db = DB_Path_Check('addons')
    data_type = Data_Type(addon)
    state = int(bool(enable))
    enabled_list = []
    disabled_list = []
    if kodi_ver >= 17:
        on_system = DB_Query(addons_db,
                             'SELECT addonID, enabled from installed')
        # Create a list of enabled and disabled add-ons already on system
        enabled_list = Addon_List(enabled=True)
        disabled_list = Addon_List(enabled=False)

# If addon has been sent through as a string we add into a list
    if data_type == 'unicode':
        addon = addon.encode('utf8')
        data_type = Data_Type(addon)

    if data_type == 'str' and addon != 'all':
        addon = [addon, '']

# Grab all the add-on ids from addons folder
    if addon == 'all':
        addon = []
        ADDONS = xbmc.translatePath('special://home/addons')
        my_addons = Get_Contents(path=ADDONS,
                                 exclude_list=['packages', 'temp'])
        for item in my_addons:
            addon_id = Get_Addon_ID(item)
            addon.append(addon_id)

# Find out what is and isn't enabled in the addons*.db
    temp_list = []
    for addon_id in addon:
        if not addon_id in exclude_list and addon_id != '':
            dolog('CHECKING: %s' % addon_id)
            if addon_id in disabled_list and not new_only and enable:
                temp_list.append(addon_id)
            elif addon_id not in disabled_list and addon_id not in enabled_list:
                temp_list.append(addon_id)
            elif addon_id in enabled_list and not enable:
                temp_list.append(addon_id)
            elif addon_id in disabled_list and enable:
                temp_list.append(addon_id)
    addon = temp_list

    # If you want to bypass the JSON-RPC mode and directly modify the db (READ WARNING ABOVE!!!)
    if not safe_mode and kodi_ver >= 17:
        installedtime = Timestamp('date_time')
        insert_query = 'INSERT or IGNORE into installed (addonID , enabled, installDate) VALUES (?,?,?)'
        update_query = 'UPDATE installed SET enabled = ? WHERE addonID = ? '
        insert_values = [addon, state, installedtime]
        try:
            for item in addon:
                DB_Query(addons_db, insert_query, [item, state, installedtime])
                DB_Query(addons_db, update_query, [state, item])
        except:
            dolog(Last_Error())
        if refresh:
            Refresh()

# Using the safe_mode (JSON-RPC)
    else:
        final_enabled = []
        if state:
            my_value = 'true'
            log_value = 'ENABLED'
        else:
            my_value = 'false'
            log_value = 'DISABLED'

        for my_addon in addon:

            # If enabling the add-on then we also check for dependencies and enable them first
            if state:
                dolog('Checking dependencies for : %s' % my_addon)
                dependencies = Dependency_Check(addon_id=my_addon,
                                                recursive=True)

                # traverse through the dependencies in reverse order attempting to enable
                for item in reversed(dependencies):
                    if not item in exclude_list and not item in final_enabled and not item in enabled_list:
                        dolog('Attempting to enable: %s' % item)
                        addon_set = Set_Setting(setting_type='addon_enable',
                                                setting=item,
                                                value='true')

                        # If we've successfully enabled then we add to list so we can skip any other instances
                        if addon_set:
                            dolog('%s now %s' % (my_addon, log_value))
                            final_enabled.append(item)

# Now the dependencies are enabled we need to enable the actual main add-on
            if not my_addon in final_enabled:
                addon_set = Set_Setting(setting_type='addon_enable',
                                        setting=my_addon,
                                        value=my_value)
            try:
                if addon_set:
                    dolog('%s now %s' % (my_addon, log_value))
                    final_enabled.append(addon)
            except:
                pass
    if refresh:
        Refresh(['addons', 'container'])


# NEW CODE NOT WORKING
#     from __init__       import dolog
#     from filetools      import DB_Path_Check, Get_Contents
#     from database       import DB_Query
#     from systemtools    import Data_Type, Last_Error, Refresh, Set_Setting, Timestamp
#     from web            import Validate_Link

#     addons_db       = DB_Path_Check('addons')
#     data_type       = Data_Type(addon)
#     state           = int(bool(enable))
#     enabled_list    = []
#     disabled_list   = []
#     if kodi_ver >= 17:
#         on_system   = DB_Query(addons_db,'SELECT addonID, enabled from installed')
# # Create a list of enabled and disabled add-ons already on system
#         enabled_list  = Addon_List(enabled=True)
#         disabled_list = Addon_List(enabled=False)

# # If addon has been sent through as a string we add into a list
#     if data_type == 'unicode':
#         addon = addon.encode('utf8')
#         data_type = Data_Type(addon)

#     if data_type == 'str' and addon!= 'all':
#         addon = [addon,'']

# # Grab all the add-on ids from addons folder
#     if addon == 'all':
#         addon     = []
#         my_addons = Get_Contents(path=ADDONS, exclude_list=['packages','temp'])
#         for item in my_addons:
#             addon_id = Get_Addon_ID(item)
#             addon.append(addon_id)

# # Find out what is and isn't enabled in the addons*.db
#     temp_list = []
#     for addon_id in addon:
#         if not addon_id in exclude_list and addon_id != '':
#             dolog('CHECKING: %s'%addon_id)

# # Check ALL addons and not just newly extracted not yet in db
#             if addon_id in disabled_list and not new_only and enable:
#                 dolog('[1] Adding to temp list: %s'%addon_id)
#                 temp_list.append(addon_id)

# # Check addons not in our disabled list and also aren't in the enabled list
#             elif addon_id not in disabled_list and addon_id not in enabled_list:
#                 dolog('[2] Adding to temp list: %s'%addon_id)
#                 temp_list.append(addon_id)

# # Check addons that are already enabled, get ready to disable
#             elif addon_id in enabled_list and not enable:
#                 dolog('[3] Adding to temp list: %s'%addon_id)
#                 temp_list.append(addon_id)

# # Check addons which are disabled get ready to enable (same as first if function??)
#             elif addon_id in disabled_list and enable:
#                 dolog('[4] Adding to temp list: %s'%addon_id)
#                 temp_list.append(addon_id)
#     addon = temp_list

# # If you want to bypass the JSON-RPC mode and directly modify the db (READ WARNING ABOVE!!!)
#     if not safe_mode and kodi_ver >= 17:
#         installedtime   = Timestamp('date_time')
#         insert_query    = 'INSERT or IGNORE into installed (addonID , enabled, installDate) VALUES (?,?,?)'
#         update_query    = 'UPDATE installed SET enabled = ? WHERE addonID = ? '
#         insert_values   = [addon, state, installedtime]
#         try:
#             for item in addon:
#                 DB_Query(addons_db, insert_query, [item, state, installedtime])
#                 DB_Query(addons_db, update_query, [state, item])
#         except:
#             dolog(Last_Error())
#         if refresh:
#             Refresh()

# # Using the safe_mode (JSON-RPC)
#     else:
#         Refresh('addons')
#         xbmc.sleep(1000)
#         final_enabled = []
#         if state:
#             my_value = 'true'
#             log_value = 'ENABLED'
#         else:
#             my_value = 'false'
#             log_value = 'DISABLED'

#         for my_addon in addon:

# # If enabling the add-on then we also check for dependencies and enable them first
#             if state:
#                 dolog('Checking dependencies for : %s'%my_addon)
#                 dependencies = Dependency_Check(addon_id=my_addon, recursive=True)
#                 dolog('Dependencies: %s'%dependencies)

# # traverse through the dependencies in reverse order attempting to enable
#                 for item in reversed(dependencies):
#                     if not item in exclude_list and not item in final_enabled and not item in enabled_list:
#                         dolog('Attempting to enable: %s'%item)
#                         addon_set = Set_Setting(setting_type='addon_enable', setting=item, value = 'true')

# # If we've successfully enabled then we add to list so we can skip any other instances
#                         if addon_set:
#                             dolog('%s now %s' % (my_addon, log_value))
#                             final_enabled.append(item)

# # Now the dependencies are enabled we need to enable the actual main add-on
#         bad_repo = []
#         for my_addon in addon:
#             if not my_addon in final_enabled:
#                 ok = True
#                 addon_set = True
#                 if 'repo' in my_addon:
#                     ok = Check_Repo(my_addon)
#                     if not ok:
#                         dolog('BAD REPO: %s IS NOT RESOLVING SO WE ARE NOT INSTALLING'%my_addon)
#                         addon_set = False
#                 if addon_set:
#                     addon_set = Set_Setting(setting_type='addon_enable', setting=my_addon, value = my_value)
#                 if addon_set:
#                     dolog('%s now %s' % (my_addon, log_value))
#                     final_enabled.append(addon)
#                 else:
#                     bad_repo.append(my_addon)
#         if len(bad_repo) > 0:
#             final_list = 'The following repostitories are not resolving so have not been installed: '
#             for item in bad_repo:
#                 final_list += item+','
#             final_list = final_list[:-1]
#             dialog.ok('[COLOR=gold]BAD REPOSITORIES FOUND[/COLOR]',final_list)
#     if refresh:
#         Refresh('container')
# ----------------------------------------------------------------
Example #7
0
def Play_Video(video,
               showbusy=True,
               content='video',
               ignore_dp=False,
               timeout=10,
               item=None,
               player=xbmc.Player()):
    """
This will attempt to play a video and return True or False on
whether or not playback was successful. This function is similar
to Check_Playback but this actually tries a number of methods to
play the video whereas Check_Playback does not actually try to
play a video - it will just return True/False on whether or not
a video is currently playing.

If you have m3u or m3u8 playlist links please use the M3U_Selector
function to get the final resolved url.

CODE: Play_Video(video, [showbusy, content, ignore_dp, timeout, item])

AVAILABLE PARAMS:

    (*) video  -  This is the path to the video, this can be a local
    path, online path or a channel number from the PVR.

    showbusy  -  By default this is set to True which means while the
    function is attempting to playback the video the user will see the
    busy dialog. Set to False if you prefer this not to appear but do
    bare in mind a user may navigate to another section and try playing
    something else if they think this isn't doing anything.

    content  -  By default this is set to 'video', however if you're
    passing through audio you may want to set this to 'music' so the
    system can correctly set the tags for artist, song etc.

    ignore_dp  -  By default this is set to True but if set to False
    this will ignore the DialogProgress window. If you use a DP while
    waiting for the stream to start then you'll want to set this True.
    Please bare in mind the reason this check is in place and enabled
    by default is because some streams do bring up a DialogProgress
    when initiated (such as f4m proxy links) and disabling this check
    in those circumstances can cause false positives.

    timeout  -  This is the amount of time you want to allow for playback
    to start before sending back a response of False. Please note if
    ignore_dp is set to True then it will also add a potential 10s extra
    to this amount if a DialogProgress window is open. The default setting
    for this is 10s.

    item  -  By default this is set to None and in this case the metadata
    will be auto-populated from the previous Add_Dir so you'll just get the
    basics like title, thumb and description. If you want to send through your
    own metadata in the form of a dictionary you can do so and it will override
    the auto-generation. If anything else sent through no metadata will be set,
    you would use this option if you've already set metadata in a previous function.


EXAMPLE CODE:
isplaying = koding.Play_Video('http://totalrevolution.tv/videos/python_koding/Browse_To_Folder.mov')
if isplaying:
    dialog.ok('PLAYBACK SUCCESSFUL','Congratulations, playback was successful')
    xbmc.Player().stop()
else:
    dialog.ok('PLAYBACK FAILED','Sorry, playback failed :(')
~"""

    dolog('### ORIGINAL VIDEO: %s' % video)
    import urlresolver
    try:
        import simplejson as json
    except:
        import json

    if not item:
        meta = {}
        for i in [
                'title', 'originaltitle', 'tvshowtitle', 'year', 'season',
                'episode', 'genre', 'rating', 'votes', 'director', 'writer',
                'plot', 'tagline'
        ]:
            try:
                meta[i] = xbmc.getInfoLabel('listitem.%s' % i)
            except:
                pass
        meta = dict((k, v) for k, v in meta.iteritems() if not v == '')
        if 'title' not in meta:
            meta['title'] = xbmc.getInfoLabel('listitem.label')
        icon = xbmc.getInfoLabel('listitem.icon')
        item = xbmcgui.ListItem(path=video,
                                iconImage=icon,
                                thumbnailImage=icon)
        if content == "music":
            try:
                meta['artist'] = xbmc.getInfoLabel('listitem.artist')
                item.setInfo(type='Music',
                             infoLabels={
                                 'title': meta['title'],
                                 'artist': meta['artist']
                             })
            except:
                item.setInfo(type='Video', infoLabels=meta)
        else:
            item.setInfo(type='Video', infoLabels=meta)

    elif type(item).__name__ == 'dict':
        item.setInfo(type='Video', infoLabels=meta)

    else:
        pass

    playback = False
    if showbusy:
        Show_Busy()

# if a plugin path is sent we try activate window
    if video.startswith('plugin://'):
        try:
            dolog('Attempting to play via xbmc.Player().play() method')
            player.play(video)
            playback = Check_Playback(ignore_dp, timeout)
        except:
            dolog(Last_Error())

# If an XBMC action has been sent through we do an executebuiltin command
    elif video.startswith('ActivateWindow') or video.startswith(
            'RunAddon') or video.startswith('RunScript') or video.startswith(
                'PlayMedia'):
        try:
            dolog('Attempting to play via xbmc.executebuiltin method')
            xbmc.executebuiltin('%s' % video)
            playback = Check_Playback(ignore_dp, timeout)
        except:
            dolog(Last_Error())

    elif ',' in video:
        # Standard xbmc.player method (a comma in url seems to throw urlresolver off)
        try:
            dolog('Attempting to play via xbmc.Player.play() method')
            player.play('%s' % video, item)
            playback = Check_Playback(ignore_dp, timeout)

# Attempt to resolve via urlresolver
        except:
            try:
                dolog('Attempting to resolve via urlresolver module')
                dolog('video = %s' % video)
                hmf = urlresolver.HostedMediaFile(url=video,
                                                  include_disabled=False,
                                                  include_universal=True)
                if hmf.valid_url() == True:
                    video = hmf.resolve()
                    dolog('### VALID URL, RESOLVED: %s' % video)
                player.play('%s' % video, item)
                playback = Check_Playback(ignore_dp, timeout)
            except:
                dolog(Last_Error())

# Play from a db entry - untested
    elif video.isdigit():
        dolog('### Video is digit, presuming it\'s a db item')
        command = (
            '{"jsonrpc": "2.0", "id":"1", "method": "Player.Open","params":{"item":{"channelid":%s}}}'
            % url)
        xbmc.executeJSONRPC(command)
        playback = Check_Playback(ignore_dp, timeout)

    else:
        # Attempt to resolve via urlresolver
        try:
            dolog('Attempting to resolve via urlresolver module')
            dolog('video = %s' % video)
            hmf = urlresolver.HostedMediaFile(url=video,
                                              include_disabled=False,
                                              include_universal=True)
            if hmf.valid_url() == True:
                video = hmf.resolve()
                dolog('### VALID URL, RESOLVED: %s' % video)
            player.play('%s' % video, item)
            playback = Check_Playback(ignore_dp, timeout)

# Standard xbmc.player method
        except:
            try:
                dolog('Attempting to play via xbmc.Player.play() method')
                player.play('%s' % video, item)
                playback = Check_Playback(ignore_dp, timeout)
            except:
                dolog(Last_Error())

    dolog('Playback status: %s' % playback)
    Show_Busy(False)
    counter = 1
    dialogprogress = xbmc.getCondVisibility('Window.IsActive(progressdialog)')
    if not ignore_dp:
        while dialogprogress:
            dp.create('Playback Good', 'Closing dialog...')
            dolog('Attempting to close dp #%s' % counter)
            dp.close()
            xbmc.sleep(1000)
            counter += 1
            dialogprogress = xbmc.getCondVisibility(
                'Window.IsActive(progressdialog)')

    return playback
Example #8
0
def Extract(_in, _out, dp=None):
    """
This function will extract a zip or tar file and return true or false so unlike the
builtin xbmc function "Extract" this one will pause code until it's completed the action.

CODE: koding.Extract(src,dst,[dp])
dp is optional, by default it is set to false

AVAILABLE PARAMS:

    (*) src    - This is the source file, the actual zip/tar. Make sure this is a full path to
    your zip file and also make sure you're not using "special://". This extract function
    is only compatible with .zip/.tar/.tar.gz files

    (*) dst    - This is the destination folder, make sure it's a physical path and not
    "special://...". This needs to be a FULL path, if you want it to extract to the same
    location as where the zip is located you still have to enter the full path.

    dp - This is optional, if you pass through the dp function as a DialogProgress()
    then you'll get to see the status of the extraction process. If you choose not to add
    this paramater then you'll just get a busy spinning circle icon until it's completed.
    See the example below for a dp example.

EXAMPLE CODE:
dp = xbmcgui.DialogProgress()
dp.create('Extracting Zip','Please Wait')
if koding.Extract(src,dst,dp):
    dialog.ok('YAY IT WORKED!','Successful extraction complete')
else:
    dialog.ok('BAD NEWS!','UH OH SOMETHING WENT HORRIBLY WRONG')
~"""
    import zipfile
    import tarfile

    nFiles = 0
    count = 0

    if os.path.exists(_in):
        if zipfile.is_zipfile(_in):
            zin = zipfile.ZipFile(_in, 'r')
            nFiles = float(len(zin.infolist()))
            contents = zin.infolist()

        elif tarfile.is_tarfile(_in):
            zin = tarfile.open(_in)
            contents = [tarinfo for tarinfo in zin.getmembers()]
            nFiles = float(len(contents))

        if nFiles > 0:
            if dp:
                try:
                    for item in contents:
                        count += 1
                        update = count / nFiles * 100
                        dp.update(int(update))
                        zin.extract(item, _out)
                    zin.close()
                    return True

                except:
                    xbmc.log(Last_Error())
                    return False
            else:
                try:
                    zin.extractall(_out)
                    return True
                except:
                    xbmc.log(Last_Error())
                    return False

        else:
            xbmc.log('NOT A VALID ZIP OR TAR FILE: %s' % _in)
    else:
        dialog.ok(this_module.getLocalizedString(30965),
                  this_module.getLocalizedString(30815) % _in)