def test_search_populated(self):
        @route.Route.register
        def results(_, search_query):
            self.assertEqual(search_query, "Rock")
            yield Listitem.from_dict(results, "listitem one")
            yield Listitem.from_dict(results, "listitem two")

        params = dict(_route=results.route.path)
        session_id = hash_params(params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            dbstore = db.setdefault(session_id, [])
            dbstore.append("Pop")
            db.flush()

        with testing.mock_keyboard("Rock"):
            listitems = search.SavedSearches.test(search=True,
                                                  execute_delayed=True,
                                                  **params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_id, db)
            self.assertIn("Rock", db[session_id])
            self.assertIn("Pop", db[session_id])

        self.assertEqual(len(listitems), 2)
        self.assertEqual(listitems[0].label, "listitem one")
        self.assertEqual(listitems[1].label, "listitem two")
예제 #2
0
def delete_ovpn(*args, **kwargs):
    ovpnfiles = {}
    with storage.PersistentDict('vpn') as db:
        try:
            ovpnfiles = db['ovpnfiles']
        except KeyError:
            db['ovpnfiles'] = ovpnfiles
        db.flush()

    if len(ovpnfiles) == 0:
        return None

    configs = []
    ovpnfileslist = []
    for name, configfilepath in list(ovpnfiles.items()):
        configs.append(name)
        ovpnfileslist.append(configfilepath)

    idx = xbmcgui.Dialog().select(
        Script.localize(30360),
        configs)

    if idx < 0:
        return ''

    Script.log('Select: [%s]' % ovpnfileslist[idx])
    new_ovpnfiles = {}
    for name, configfilepath in list(ovpnfiles.items()):
        if configfilepath != ovpnfileslist[idx]:
            new_ovpnfiles[name] = configfilepath
    with storage.PersistentDict('vpn') as db:
        db['ovpnfiles'] = new_ovpnfiles
        db.flush()
예제 #3
0
def import_ovpn(*args, **kwargs):
    path = xbmcgui.Dialog().browse(1,
                                   Script.localize(30342),
                                   'files',
                                   mask='.ovpn|.conf',
                                   enableMultiple=False)

    if path and os.path.exists(path) and os.path.isfile(path):
        Script.log('OpenVPN: Import: [%s]' % path)

        keyboard = xbmc.Keyboard(default='',
                                 heading=Script.localize(30348),
                                 hidden=False)
        keyboard.doModal()
        if keyboard.isConfirmed() and len(keyboard.getText()) > 0:
            name = keyboard.getText()

            ovpnfiles = {}
            with storage.PersistentDict('vpn') as db:
                ovpnfiles = db['ovpnfiles']
                db.flush()

            if name in ovpnfiles and not xbmcgui.Dialog().yesno(
                    'OpenVPN', Script.localize(30349)):
                xbmcgui.Dialog().ok('OpenVPN', Script.localize(30350))

            else:
                ovpnfiles[name] = path
                with storage.PersistentDict('vpn') as db:
                    db['ovpnfiles'] = ovpnfiles
                    db.flush()
        else:
            xbmcgui.Dialog().ok('OpenVPN', Script.localize(30351))
    def test_saved_remove(self):
        # noinspection PyUnusedLocal
        @route.Route.register
        def results(_, search_query):
            pass

        params = dict(_route=results.route.path)
        session_id = hash_params(params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            dbstore = db.setdefault(session_id, [])
            dbstore.append("Rock")
            dbstore.append("Pop")
            db.flush()

        listitems = search.SavedSearches.test(remove_entry="Rock",
                                              execute_delayed=True,
                                              **params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_id, db)
            self.assertNotIn("Rock", db[session_id])
            self.assertIn("Pop", db[session_id])

        self.assertEqual(len(listitems), 2)
        self.assertIn("Search", listitems[0].label)
        self.assertEqual(listitems[1].label, "Pop")
예제 #5
0
    def test_saved_not_firstload(self):
        # noinspection PyUnusedLocal
        @route.Route.register
        def results(_, search_query):
            pass

        params = dict(_route=results.route.path)
        session_id = hash_params(params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            dbstore = db.setdefault(session_id, [])
            dbstore.append("Rock")
            dbstore.append("Pop")
            db.flush()

        with testing.mock_keyboard("Rock"):
            listitems = search.saved_searches.test(execute_delayed=True,
                                                   **params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_id, db)
            self.assertIn("Rock", db[session_id])
            self.assertIn("Pop", db[session_id])

        self.assertEqual(len(listitems), 3)
        self.assertIn("Search", listitems[0].label)
        self.assertEqual(listitems[1].label, "Rock")
        self.assertEqual(listitems[2].label, "Pop")
예제 #6
0
    def test_persistents(self):
        with storage.PersistentDict(self.filename) as db:
            db["persistent"] = "true"
            self.assertIn("persistent", db)

        with storage.PersistentDict(self.filename) as db:
            self.assertIn("persistent", db)
            self.assertEqual(db["persistent"], "true")
예제 #7
0
    def test_ttl(self):
        with open(self.path, "wb") as db:
            pickle.dump({"one": 1, "two": 2}, db, protocol=2)

        with storage.PersistentDict(self.filename) as db:
            self.assertIn("one", db)
            self.assertIn("two", db)

        time.sleep(2)
        with storage.PersistentDict(self.filename, 1) as db:
            self.assertNotIn("one", db)
            self.assertNotIn("two", db)
예제 #8
0
    def test_version_convert(self):
        with open(self.path, "wb") as db:
            pickle.dump({"one": 1, "two": 2}, db, protocol=2)

        with storage.PersistentDict(self.filename) as db:
            self.assertIn("one", db)
            self.assertIn("two", db)
예제 #9
0
def select_ovpn():
    ovpnfiles = {}
    with storage.PersistentDict('vpn') as db:
        try:
            ovpnfiles = db['ovpnfiles']
        except KeyError:
            db['ovpnfiles'] = ovpnfiles
        db.flush()

    if len(ovpnfiles) == 0:
        return None

    configs = []
    ovpnfileslist = []
    for name, configfilepath in list(ovpnfiles.items()):
        configs.append(name)
        ovpnfileslist.append(configfilepath)

    idx = xbmcgui.Dialog().select(
        Script.localize(30352),
        configs)
    if idx < 0:
        return ''

    Script.log('OpenVPN: Select conf: [%s]' % ovpnfileslist[idx])
    return ovpnfileslist[idx]
def move_favourite_item(plugin, direction, item_hash):
    """
    Callback function called when the user click
    on 'Move up/down' from a favourite item
    context menu
    """
    if direction == 'down':
        offset = 1
    elif direction == 'up':
        offset = -1

    with storage.PersistentDict("favourites.pickle") as db:
        item_to_move_id = item_hash
        item_to_move_order = db[item_hash]['params']['order']

        menu = []
        for item_hash, item_dict in db.items():
            item = (item_dict['params']['order'], item_hash, item_dict)

            menu.append(item)
        menu = sorted(menu, key=lambda x: x[0])

        for k in range(0, len(menu)):
            item = menu[k]
            item_hash = item[1]
            if item_to_move_id == item_hash:
                item_to_swap = menu[k + offset]
                item_to_swap_order = item_to_swap[0]
                item_to_swap_id = item_to_swap[1]
                db[item_to_move_id]['params']['order'] = item_to_swap_order
                db[item_to_swap_id]['params']['order'] = item_to_move_order
                xbmc.executebuiltin('XBMC.Container.Refresh()')
                break

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

    # Move all pickled existing favs in json file
    fav_pickle_fp = os.path.join(Script.get_info('profile'), "favourites.pickle")
    if xbmcvfs.exists(fav_pickle_fp):
        Script.log('Start favourites migration from pickle file to json file')
        new_fav_dict = {}
        with storage.PersistentDict("favourites.pickle") as db:
            new_fav_dict = dict(db)
        # Fix old fav
        for item_hash, item_dict in new_fav_dict.items():
            if 'params' in item_dict and isinstance(item_dict['params'], listing.Params):
                new_fav_dict[item_hash]['params'] = dict(new_fav_dict[item_hash]['params'])
                try:
                    del new_fav_dict[item_hash]['params']['item_dict']['params']
                except Exception:
                    pass
            if 'properties' in item_dict:
                if isinstance(item_dict['properties'], listing.Property):
                    new_fav_dict[item_hash]['properties'] = dict(new_fav_dict[item_hash]['properties'])
        fav_json_fp = os.path.join(Script.get_info('profile'), "favourites.json")
        with open(fav_json_fp, 'w') as f:
            json.dump(new_fav_dict, f, indent=4)
        xbmcvfs.delete(fav_pickle_fp)
예제 #12
0
def select_ovpn():
    ovpnfiles = {}
    with storage.PersistentDict('vpn') as db:
        try:
            ovpnfiles = db['ovpnfiles']
        except KeyError:
            db['ovpnfiles'] = ovpnfiles
        db.flush()

    if len(ovpnfiles) == 0:
        return None

    else:
        response = vpnlib.is_running(ip, port)
        Script.log('OpenVPN: Response from is_running: [%s] [%s] [%s]' %
                   (response[0], response[1], response[2]))
        if response[0]:
            # Le VPN est connecté
            disconnect_openvpn()

        configs = []
        ovpnfileslist = []
        for name, configfilepath in list(ovpnfiles.items()):
            configs.append(name)
            ovpnfileslist.append(configfilepath)

        idx = xbmcgui.Dialog().select(
            Script.localize(LABELS['Select OpenVPN configuration to run']),
            configs)
        if idx >= 0:
            Script.log('OpenVPN: Select conf: [%s]' % ovpnfileslist[idx])
            return ovpnfileslist[idx]
        else:
            return ''
예제 #13
0
def connect_openvpn(config, restart=False, sudopassword=None):
    with storage.PersistentDict('vpn') as db:
        Script.log('OpenVPN: Connecting OpenVPN configuration: [%s]' % config)

        if Script.setting.get_boolean('vpn.sudo') and \
                Script.setting.get_boolean('vpn.sudopsw') and sudopassword is None:

            keyboard = xbmc.Keyboard(default='',
                                     heading=Script.localize(
                                         LABELS['Enter your sudo password']),
                                     hidden=True)
            keyboard.doModal()
            if keyboard.isConfirmed():
                sudopassword = keyboard.getText()

        openvpn = vpnlib.OpenVPN(
            Script.setting.get_string('vpn.openvpnfilepath'),
            config,
            ip=ip,
            port=port,
            args=Script.setting.get_string('vpn.args'),
            sudo=Script.setting.get_boolean('vpn.sudo'),
            sudopwd=sudopassword,
            debug=True)

        try:
            if restart:
                openvpn.disconnect()
                db['status'] = "disconnected"
            openvpn.connect()
            utils.send_notification(Script.localize(
                LABELS['Started VPN connection']),
                                    title="OpenVPN",
                                    time=3000)

            db['status'] = "connected"
        except vpnlib.OpenVPNError as exception:
            if exception.errno == 1:
                db['status'] = "connected"

                if xbmcgui.Dialog().yesno(
                        'OpenVPN',
                        Script.localize(LABELS[
                            'An existing OpenVPN instance appears to be running.']
                                        ),
                        Script.localize(LABELS['Disconnect it?'])):

                    Script.log('OpenVPN: User has decided to restart OpenVPN')
                    connect_openvpn(config, True, sudopassword)
                else:
                    Script.log(
                        'OpenVPN: User has decided not to restart OpenVPN')
            else:
                xbmcgui.Dialog().ok(
                    'OpenVPN',
                    Script.localize(LABELS[
                        'An error has occurred whilst trying to connect OpenVPN']
                                    ))
                db['status'] = "failed"
        db.flush()
예제 #14
0
 def test_iter(self):
     with storage.PersistentDict(self.filename) as db:
         db.update({"one": 1, "two": 2})
         data = list(iter(db))
         self.assertEqual(len(data), 2)
         self.assertIn("one", data)
         self.assertIn("two", data)
예제 #15
0
 def test_items(self):
     with storage.PersistentDict(self.filename) as db:
         db.update({"one": 1, "two": 2})
         data = list(db.items())
         self.assertEqual(len(data), 2)
         expected = [("one", 1), ("two", 2)]
         for item in data:
             self.assertIn(item, expected)
    def test_saved_sessions(self):
        # noinspection PyUnusedLocal
        @route.Route.register
        def session_one(_, search_query):
            self.assertEqual(search_query, "Rock")
            yield Listitem.from_dict(session_one, "listitem one")
            yield Listitem.from_dict(session_one, "listitem two")

        # noinspection PyUnusedLocal
        @route.Route.register
        def session_two(_, search_query):
            self.assertEqual(search_query, "Pop")
            yield Listitem.from_dict(session_two, "listitem one")
            yield Listitem.from_dict(session_two, "listitem two")

        session_one_params = dict(_route=session_one.route.path)
        session_one_id = hash_params(session_one_params)

        session_two_params = dict(_route=session_two.route.path)
        session_two_id = hash_params(session_two_params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            dbstore = db.setdefault(session_one_id, [])
            dbstore.append("Jazz")
            dbstore = db.setdefault(session_two_id, [])
            dbstore.append("Chill")
            db.flush()

        with testing.mock_keyboard("Rock"):
            search.SavedSearches.test(search=True,
                                      execute_delayed=True,
                                      **session_one_params)

        with testing.mock_keyboard("Pop"):
            search.SavedSearches.test(search=True,
                                      execute_delayed=True,
                                      **session_two_params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_one_id, db)
            self.assertIn("Rock", db[session_one_id])
            self.assertNotIn("Pop", db[session_one_id])

            self.assertIn(session_two_id, db)
            self.assertIn("Pop", db[session_two_id])
            self.assertNotIn("Rock", db[session_two_id])
예제 #17
0
def import_ovpn(*args, **kwargs):
    path = xbmcgui.Dialog().browse(
        1,
        Script.localize(LABELS['Import OpenVPN configuration file']),
        'files',
        mask='.ovpn|.conf',
        enableMultiple=False)

    if path and os.path.exists(path) and os.path.isfile(path):
        Script.log('OpenVPN: Import: [%s]' % path)

        keyboard = xbmc.Keyboard(
            default='',
            heading=Script.localize(
                LABELS['Choose a name for OpenVPN configuration']),
            hidden=False)
        keyboard.doModal()
        if keyboard.isConfirmed() and len(keyboard.getText()) > 0:
            name = keyboard.getText()

            ovpnfiles = {}
            with storage.PersistentDict('vpn') as db:
                ovpnfiles = db['ovpnfiles']
                db.flush()

            if name in ovpnfiles and not xbmcgui.Dialog().yesno(
                    'OpenVPN',
                    Script.localize(LABELS[
                        'This OpenVPN configuration name already exists. Overwrite?']
                                    )):
                xbmcgui.Dialog().ok(
                    'OpenVPN', Script.localize(LABELS['Import cancelled']))

            else:
                ovpnfiles[name] = path
                with storage.PersistentDict('vpn') as db:
                    db['ovpnfiles'] = ovpnfiles
                    db.flush()
        else:
            xbmcgui.Dialog().ok(
                'OpenVPN',
                Script.localize(LABELS[
                    'Import failed. You must specify a name for the OpenVPN configuration']
                                ))
예제 #18
0
def connect_openvpn(config, restart=False, sudopassword=None):
    with storage.PersistentDict('vpn') as db:
        Script.log('OpenVPN: Connecting OpenVPN configuration: [%s]' % config)

        if Script.setting.get_boolean('vpn.sudo') and \
                Script.setting.get_boolean('vpn.sudopsw') and sudopassword is None:

            keyboard = xbmc.Keyboard(default='',
                                     heading=Script.localize(30353),
                                     hidden=True)
            keyboard.doModal()
            if keyboard.isConfirmed():
                sudopassword = keyboard.getText()

        openvpn = vpnlib.OpenVPN(
            Script.setting.get_string('vpn.openvpnfilepath'),
            config,
            ip=ip,
            port=port,
            args=Script.setting.get_string('vpn.args'),
            sudo=Script.setting.get_boolean('vpn.sudo'),
            sudopwd=sudopassword,
            debug=True)

        try:
            if restart:
                openvpn.disconnect()
                db['status'] = "disconnected"
            openvpn.connect()
            Script.notify(
                "OpenVPN",
                Script.localize(30354),
                display_time=3000)

            db['status'] = "connected"
        except vpnlib.OpenVPNError as exception:
            if exception.errno == 1:
                db['status'] = "connected"

                if xbmcgui.Dialog().yesno(
                        'OpenVPN',
                        Script.localize(30356),
                        Script.localize(30357)):

                    Script.log('OpenVPN: User has decided to restart OpenVPN')
                    connect_openvpn(config, True, sudopassword)
                else:
                    Script.log(
                        'OpenVPN: User has decided not to restart OpenVPN')
            else:
                xbmcgui.Dialog().ok(
                    'OpenVPN',
                    Script.localize(30358))
                db['status'] = "failed"
        db.flush()
예제 #19
0
def add_vpn_context(item):
    with storage.PersistentDict('vpn') as db:
        vpn_label = Script.localize(LABELS['Connect VPN'])
        if 'status' in db:
            if db['status'] == 'connected':
                vpn_label = Script.localize(LABELS['Disconnect VPN'])
        else:
            db['status'] = 'disconnected'
            db.flush()

        item.context.script(vpn_item_callback, vpn_label)
예제 #20
0
def delete_ovpn(*args, **kwargs):
    ovpnfiles = {}
    with storage.PersistentDict('vpn') as db:
        try:
            ovpnfiles = db['ovpnfiles']
        except KeyError:
            db['ovpnfiles'] = ovpnfiles
        db.flush()

    if len(ovpnfiles) == 0:
        return None

    else:
        response = vpnlib.is_running(ip, port)
        Script.log('OpenVPN: Response from is_running: [%s] [%s] [%s]' %
                   (response[0], response[1], response[2]))
        if response[0]:
            # Le VPN est connecté
            Script.log('OpenVPN: VPN still connected, we disconnect it')
            disconnect_openvpn()

        configs = []
        ovpnfileslist = []
        for name, configfilepath in list(ovpnfiles.items()):
            configs.append(name)
            ovpnfileslist.append(configfilepath)

        idx = xbmcgui.Dialog().select(
            Script.localize(LABELS['Select OpenVPN configuration to delete']),
            configs)
        if idx >= 0:
            Script.log('Select: [%s]' % ovpnfileslist[idx])
            new_ovpnfiles = {}
            for name, configfilepath in list(ovpnfiles.items()):
                if configfilepath != ovpnfileslist[idx]:
                    new_ovpnfiles[name] = configfilepath
            with storage.PersistentDict('vpn') as db:
                db['ovpnfiles'] = new_ovpnfiles
                db.flush()
        else:
            return ''
def rename_favourite_item(plugin, item_hash):
    """
    Callback function called when the user click
    on 'rename' from a favourite item
    context menu
    """
    item_label = utils.keyboard(plugin.localize(LABELS['Favorite name']),
                                xbmc.getInfoLabel('ListItem.Label'))

    # If user aborded do not edit this item
    if item_label == '':
        return False
    with storage.PersistentDict("favourites.pickle") as db:
        db[item_hash]['label'] = item_label
    xbmc.executebuiltin('XBMC.Container.Refresh()')
예제 #22
0
def disconnect_openvpn():
    with storage.PersistentDict('vpn') as db:
        Script.log('OpenVPN: Disconnecting OpenVPN')
        try:
            db['status'] = "disconnecting"
            response = vpnlib.is_running(ip, port)
            if response[0]:
                vpnlib.disconnect(ip, port)
                if response[1] is not None:
                    Script.notify('OpenVPN', Script.localize(30355))
            db['status'] = "disconnected"
            Script.log('OpenVPN: Disconnect OpenVPN successful')
        except vpnlib.OpenVPNError as exception:
            xbmcgui.Dialog().ok('OpenVPN', Script.localize(30358))
            Script.log('OpenVPN: OpenVPN error: ' + str(exception))
            db['status'] = "failed"
        db.flush()
    def test_first_load_canceled(self):
        # noinspection PyUnusedLocal
        @route.Route.register
        def results(_, search_query):
            pass

        params = dict(_route=results.route.path)
        session_id = hash_params(params)

        with testing.mock_keyboard(""):
            listitems = search.SavedSearches.test(first_load=True,
                                                  execute_delayed=True,
                                                  **params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_id, db)
            self.assertFalse(bool(db[session_id]))

        self.assertFalse(listitems)
    def test_first_load_invalid(self):
        @route.Route.register
        def results(_, search_query):
            self.assertEqual(search_query, "Rock")
            return False

        params = dict(_route=results.route.path)
        session_id = hash_params(params)

        with testing.mock_keyboard("Rock"):
            listitems = search.SavedSearches.test(first_load=True,
                                                  execute_delayed=True,
                                                  **params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_id, db)
            self.assertNotIn("Rock", db[session_id])

        self.assertFalse(listitems)
예제 #25
0
def vpn_item_callback(plugin):
    with storage.PersistentDict('vpn') as db:
        if 'status' not in db:
            db['status'] = "disconnected"

        elif db['status'] != "connected":
            ovpn = select_ovpn()
            if ovpn is None:
                import_ovpn()

            # Case when the user cancel the import dialog
            if ovpn is None:
                return False

            if len(ovpn) > 0:
                connect_openvpn(ovpn)

        elif db['status'] == "connected":
            disconnect_openvpn()
        db.flush()
        xbmc.executebuiltin('Container.Refresh()')
예제 #26
0
    def test_first_load(self):
        @route.Route.register
        def results(_, search_query):
            self.assertEqual(search_query, "Rock")
            yield Listitem.from_dict(results, "listitem one")
            yield Listitem.from_dict(results, "listitem two")

        params = dict(_route=results.route.path)
        session_id = hash_params(params)

        with testing.mock_keyboard("Rock"):
            listitems = search.saved_searches.test(first_load=True,
                                                   execute_delayed=True,
                                                   **params)

        with storage.PersistentDict(search.SEARCH_DB) as db:
            self.assertIn(session_id, db)
            self.assertIn("Rock", db[session_id])

        self.assertEqual(len(listitems), 2)
        self.assertEqual(listitems[0].label, "listitem one")
        self.assertEqual(listitems[1].label, "listitem two")
예제 #27
0
def add_context_menus_to_item(plugin, item, index, item_id, menu_id, menu_len):

    # Move up
    if index > 0:
        item.context.script(move_item,
                            plugin.localize(LABELS['Move up']),
                            direction='up',
                            item_id=item_id,
                            menu_id=menu_id)

    # Move down
    if index < menu_len - 1:
        item.context.script(move_item,
                            plugin.localize(LABELS['Move down']),
                            direction='down',
                            item_id=item_id,
                            menu_id=menu_id)

    # Hide
    item.context.script(hide_item,
                        plugin.localize(LABELS['Hide']),
                        item_id=item_id)

    # Connect/Disconnect VPN
    with storage.PersistentDict('vpn') as db:
        vpn_label = plugin.localize(LABELS['Connect VPN'])
        if 'status' in db:
            if db['status'] == 'connected':
                vpn_label = plugin.localize(LABELS['Disconnect VPN'])
        else:
            db['status'] = 'disconnected'
            db.flush()

        item.context.script(vpn.vpn_item_callback, vpn_label)

    return
def remove_favourite_item(plugin, item_hash):
    """
    Callback function called when the user click
    on 'remove' from a favourite item
    context menu
    """
    with storage.PersistentDict("favourites.pickle") as db:
        del db[item_hash]

        # We need to fix the order param
        # in order to not break the move up/down action
        menu = []
        for item_hash, item_dict in db.items():
            item = (item_dict['params']['order'], item_hash)

            menu.append(item)
        menu = sorted(menu, key=lambda x: x[0])

        for k in range(0, len(menu)):
            item = menu[k]
            item_hash = item[1]
            db[item_hash]['params']['order'] = k

    xbmc.executebuiltin('XBMC.Container.Refresh()')
예제 #29
0
 def test_del(self):
     with storage.PersistentDict(self.filename) as db:
         db.update({"one": 1, "two": 2})
         del db["one"]
         self.assertNotIn("one", db)
         self.assertIn("two", db)
예제 #30
0
 def test_len(self):
     with storage.PersistentDict(self.filename) as db:
         db.update({"one": 1, "two": 2})
         self.assertEqual(len(db), 2)