Exemple #1
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
Exemple #2
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)
#----------------------------------------------------------------
Exemple #3
0
def Dependency_Check(addon_id = 'all', recursive = False):
    """
This will return a list of all dependencies required by an add-on.
This information is grabbed directly from the currently installed addon.xml,
an individual add-on id or a list of add-on id's.

CODE:  Dependency_Check([addon_id, recursive])

AVAILABLE PARAMS:

    addon_id  -  This is optional, if not set it will return a list of every
    dependency required from all installed add-ons. If you only want to
    return results of one particular add-on then send through the id.

    recursive  -  By default this is set to False but if set to true and you
    also send through an individual addon_id it will return all dependencies
    required for that addon id AND the dependencies of the dependencies.

EXAMPLE CODE:
current_id = xbmcaddon.Addon().getAddonInfo('id')
dependencies = koding.Dependency_Check(addon_id=current_id, recursive=True)
clean_text = ''
for item in dependencies:
    clean_text += item+'\n'
koding.Text_Box('Modules required for %s'%current_id,clean_text)
~"""
    import xbmcaddon
    import re
    from filetools      import Text_File
    from systemtools    import Data_Type 
    
    processed    = []
    depfiles     = []    
    
    if addon_id == 'all':
        addon_id = os.listdir(ADDONS)
    elif Data_Type(addon_id) == 'str':
        addon_id = [addon_id]

    for name in addon_id:
        try:
            addon_path = xbmcaddon.Addon(id=name).getAddonInfo('path')
        except:
            addon_path = os.path.join(ADDONS, name)
        if not name in processed:
            processed.append(name)

    # Get list of master dependencies
        depfiles = Check_Deps(addon_path,[name])
        
    # Recursively check all other dependencies
        depchecks = depfiles
        if recursive:
            while len(depchecks):
                for depfile in depfiles:
                    if depfile not in processed:
                        try:
                            dep_path = xbmcaddon.Addon(id=depfile).getAddonInfo('path')
                        except:
                            dep_path = os.path.join(ADDONS,depfile)
                        newdepfiles = Check_Deps(dep_path, depfiles)
                    # Pass through the path of sub-dependency and add items to master list and list to check
                        for newdep in newdepfiles:
                            if not (newdep in depchecks) and not (newdep in processed):
                                depchecks.append(newdep)
                            if not newdep in depfiles:
                                depfiles.append(newdep)
                    processed.append(depfile)
                    depchecks.remove(depfile)
                if name in depchecks:
                    depchecks.remove(name)
    return processed[1:]
Exemple #4
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
Exemple #5
0
def Add_Dir(name,
            url='',
            mode='',
            folder=False,
            icon='',
            fanart='',
            description='',
            info_labels={},
            set_art={},
            set_property={},
            content_type='',
            context_items=None,
            context_override=False,
            playable=False):
    """
This allows you to create a list item/folder inside your add-on.
Please take a look at your addon default.py comments for more information
(presuming you created one at http://totalrevolution.tv)

TOP TIP: If you want to send multiple variables through to a function just
send through as a dictionary encapsulated in quotation marks. In the function
you can then use the following code to access them:

params = eval(url)
^ That will then give you a dictionary where you can just pull each variable and value from.

CODE: Add_Dir(name, url, mode, [folder, icon, fanart, description, info_labels, content_type, context_items, context_override, playable])

AVAILABLE PARAMS:

    (*) name  -  This is the name you want to show for the list item

    url   -  If the route (mode) you're calling requires extra paramaters
    to be sent through then this is where you add them. If the function is
    only expecting one item then you can send through as a simple string.
    Unlike many other Add_Dir functions Python Koding does allow for multiple
    params to be sent through in the form of a dictionary so let's say your
    function is expecting the 2 params my_time & my_date. You would send this info
    through as a dictionary like this:
    url={'my_time':'10:00', 'my_date':'01.01.1970'}
    
    If you send through a url starting with plugin:// the item will open up into
    that plugin path so for example:
    url='plugin://plugin.video.youtube/play/?video_id=FTI16i7APhU'

    mode  -  The mode you want to open when this item is clicked, this is set
    in your master_modes dictionary (see template add-on linked above)

    folder       -  This is an optional boolean, by default it's set to False.
    True will open into a folder rather than an executable command

    icon         -  The path to the thumbnail you want to use for this list item

    fanart       -  The path to the fanart you want to use for this list item

    description  - A description of your list item, it's skin dependant but this
    usually appears below the thumbnail

    info_labels  - You can send through any number of info_labels via this option.
    For full details on the infolabels available please check the pydocs here:
    http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcgui.html#ListItem-setInfo

    When passing through infolabels you need to use a dictionary in this format:
    {"genre":"comedy", "title":"test video"}
    
    set_art  -  Using the same format as info_labels you can set your artwork via
    a dictionary here. Full details can be found here:
    http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcgui.html#ListItem-setArt

    set_property  -  Using the same format as info_labels you can set your artwork via
    a dictionary here. Full details can be found here:
    http://kodi.wiki/view/InfoLabels#ListItem

    content_type - By default this will set the content_type for kodi to a blank string
    which is what Kodi expects for generic category listings. There are plenty of different
    types though and when set Kodi will perform different actions (such as access the
    database looking for season/episode information for the list item).

    WARNING: Setting the wrong content type for your listing can cause the system to
    log thousands of error reports in your log, cause the system to lag and make
    thousands of unnecessary db calls - sometimes resulting in a crash. You can find
    details on the content_types available here: http://forum.kodi.tv/showthread.php?tid=299107

    context_items - Add context items to your directory. The params you need to send through
    need to be in a list format of [(label, action,),] look at the example code below for
    more details.

    context_override - By default your context items will be added to the global context
    menu items but you can override this by setting this to True and then only your
    context menu items will show.

    playable  -  By default this is set to False but if set to True kodi will just try
    and play this item natively with no extra fancy functions.

EXAMPLE:
my_context = [('Music','xbmc.executebuiltin("ActivateWindow(music)")'),('Programs','xbmc.executebuiltin("ActivateWindow(programs)")')]
# ^ This is our two basic context menu items (music and programs)

Add_Dir(name='TEST DIRECTORY', url='', mode='test_directory', folder=True, context_items=my_context, context_override=True)
# ^ This will add a folder AND a context menu item for when bring up the menu (when focused on this directory).
# ^^ The context_override is set to True which means it will override the default Kodi context menu items.

Add_Dir(name='TEST ITEM', url='', mode='test_item', folder=False, context_items=my_context, context_override=False)
# ^ This will add an item to the list AND a context menu item for when bring up the menu (when focused on this item).
# ^^ The context_override is set to False which means the new items will appear alongside the default Kodi context menu items.
~"""
    from __init__ import dolog
    from systemtools import Data_Type
    from vartools import Convert_Special

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

    addon_handle = int(sys.argv[1])
    # Check we're in an appropriate section for the content type set
    dolog(xbmc.getInfoLabel('Window.Property(xmlfile)'))
    song_only_modes = ['songs', 'artist', 'album', 'song', 'music']
    video_only_modes = [
        'sets', 'tvshows', 'seasons', 'actors', 'directors', 'unknown',
        'video', 'set', 'movie', 'tvshow', 'season', 'episode'
    ]
    if xbmc.getInfoLabel(
            'Window.Property(xmlfile)'
    ) == 'MyVideoNav.xml' and content_type in song_only_modes:
        content_type = ''
    if xbmc.getInfoLabel(
            'Window.Property(xmlfile)'
    ) == 'MyMusicNav.xml' and content_type in video_only_modes:
        content_type = ''

    if description == '':
        description = this_module.getLocalizedString(30837)

    if Data_Type(url) == 'dict':
        url = repr(url)

    if Data_Type(info_labels) != 'dict':
        dialog.ok(
            'WRONG INFO LABELS',
            'Please check documentation, these should be sent through as a dictionary.'
        )

    if Data_Type(set_art) != 'dict':
        dialog.ok(
            'WRONG SET_ART',
            'Please check documentation, these should be sent through as a dictionary.'
        )

    if Data_Type(set_property) != 'dict':
        dialog.ok(
            'WRONG SET_PROPERTY',
            'Please check documentation, these should be sent through as a dictionary.'
        )

# Set the default title, filename and plot if not sent through already via info_labels
    try:
        title = info_labels["Title"]
        if title == '':
            info_labels["Title"] = name
    except:
        info_labels["Title"] = name

    try:
        filename = info_labels["FileName"]
        # if filename == '':
        #     info_labels["FileName"] = name
    except:
        info_labels["FileName"] = name

    try:
        plot = info_labels["plot"]
        if plot == '':
            info_labels["plot"] = description
    except:
        info_labels["plot"] = description
# Set default thumbnail image used for listing (if not sent through via set_art)
    try:
        set_art["icon"]
    except:
        set_art["icon"] = icon

# Set default Fanart if not already sent through via set_property
    try:
        set_property["Fanart_Image"]
    except:
        set_property["Fanart_Image"] = fanart

# Set the main listitem properties
    liz = xbmcgui.ListItem(label=str(name),
                           iconImage=str(icon),
                           thumbnailImage=str(icon))

    # Set the infolabels
    liz.setInfo(type=content_type, infoLabels=info_labels)

    # Set the artwork
    liz.setArt(set_art)

    # Loop through the set_property list and set each item in there
    for item in set_property.items():
        liz.setProperty(item[0], item[1])

# Add a context item (if details for context items are sent through)
    if context_items:
        liz.addContextMenuItems(context_items, context_override)

    u = sys.argv[0]
    u += "?mode=" + str(mode)
    u += "&url=" + Convert_Special(url, string=True)
    u += "&name=" + urllib.quote_plus(name)
    u += "&iconimage=" + urllib.quote_plus(icon)
    u += "&fanart=" + urllib.quote_plus(fanart)
    u += "&description=" + urllib.quote_plus(description)

    if url.startswith('plugin://'):
        xbmcplugin.addDirectoryItem(handle=addon_handle,
                                    url=url,
                                    listitem=liz,
                                    isFolder=True)

    elif folder:
        xbmcplugin.addDirectoryItem(handle=addon_handle,
                                    url=u,
                                    listitem=liz,
                                    isFolder=True)

    elif playable:
        liz.setProperty('IsPlayable', 'true')
        xbmcplugin.addDirectoryItem(handle=addon_handle,
                                    url=url,
                                    listitem=liz,
                                    isFolder=False)

    else:
        xbmcplugin.addDirectoryItem(handle=addon_handle,
                                    url=u,
                                    listitem=liz,
                                    isFolder=False)
Exemple #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')
# ----------------------------------------------------------------