Пример #1
0
class StdConfigItemNumber(StdConfigItemBase):
    def __init__(self, fmt, udm, min, max, step, *args):
        self._fmt = fmt
        self._udm = udm
        self._min = min
        self._max = max
        self._step = step
        self._val = None
        self._dia = None
        StdConfigItemBase.__init__(self, *args)

    def label_end_get(self, url, user_data):
        if self._udm:
            return ini.get(self._sec, self._opt) + ' ' + self._udm
        else:
            return ini.get(self._sec, self._opt)

    def item_selected(self, url, user_data):
        self._val = ini.get_float(self._sec, self._opt)
        self._dia = EmcDialog(style='minimal', title=self._lbl, text='')
        self._dia.button_add(_('Ok'), self._btn_ok_cb)
        self._dia.button_add(None, self._btn_plus_cb, icon='icon/plus')
        self._dia.button_add(None, self._btn_minus_cb, icon='icon/minus')
        self._dia.button_add(_('Cancel'), self._btn_canc_cb)
        self._dia_text_update()

    def _dia_text_update(self):
        val = (self._fmt % self._val) + ' ' + self._udm
        self._dia.text_set('<br><br><br><center><bigger>%s</bigger></center>' %
                           val)

    def _btn_plus_cb(self, btn):
        self._val += self._step
        self._val = min(self._val, self._max)
        self._dia_text_update()

    def _btn_minus_cb(self, btn):
        self._val -= self._step
        self._val = max(self._val, self._min)
        self._dia_text_update()

    def _btn_canc_cb(self, btn):
        self._dia.delete()

    def _btn_ok_cb(self, btn):
        val = self._fmt % self._val
        ini.set(self._sec, self._opt, val)
        self._dia.delete()
        StdConfigItemBase.__done__(self)
Пример #2
0
class Test_Url(GenericItemClass):

    url1 = 'http://ipv4.download.thinkbroadband.com/5MB.zip'
    url2 = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/' \
           'resources/pdf/dummy.pdf'

    def __init__(self):
        super().__init__()
        self.dia = None
        self.dload = None

    def item_selected(self, url, user_data):
        self.dia = EmcDialog(style='progress',
                             title=user_data,
                             text='Press start to test a 5MB download')
        self.dia.button_add('Close', lambda b: self.dia.delete())
        self.dia.button_add('delete()', self.delete_btn_cb)
        self.dia.button_add('To file (5M)', self.start_btn_cb, self.url1)
        self.dia.button_add('To mem (13K)', self.start_btn_cb, self.url2)

    def start_btn_cb(self, btn, url):
        self.dia.text_set('Download started...')
        dest = '::tmp::' if url == self.url1 else '::mem::'
        self.dload = EmcUrl(url,
                            dest=dest,
                            done_cb=self.done_cb,
                            prog_cb=self.prog_cb,
                            decode=None,
                            parent=self.dia)

    def delete_btn_cb(self, btn):
        if self.dload:
            self.dload.delete()

    def done_cb(self, url, success, dest):
        print("DONE", success)
        if success and url.dest == '::mem::':
            size = len(dest)
            self.dia.text_set(
                'Download successfully completed to Memory<br>'
                'First bytes: {}<br>Download size: {} bytes'.format(
                    dest[:10], size))
        elif success and os.path.exists(dest):
            size = utils.hum_size(os.path.getsize(dest))
            self.dia.text_set('Download successfully completed to<br>{}<br>'
                              'File size: {} '.format(dest, size))
        else:
            self.dia.text_set("Error !!")
        self.dload = None

    def prog_cb(self, url, total, received):
        print("PROGRESS", url, total, received)
        self.dia.progress_set(received / total if total else 0)
Пример #3
0
class Test_Exe(GenericItemClass):

    path = os.path.dirname(__file__)
    infinite_path = os.path.join(path, 'infinite.py')

    def __init__(self):
        super().__init__()
        self.dia = None
        self.exe = None

    def item_selected(self, url, user_data):
        self.dia = EmcDialog(title='EmcExe test',
                             text='Press a button to run a command')
        self.dia.button_add('Close', lambda b: self.dia.delete())
        self.dia.button_add('delete()', lambda b: self.exe.delete())
        self.dia.button_add('"wrong"', self.run_btn_cb, ('wrong', ))
        self.dia.button_add('"infinite.py"', self.run_btn_cb,
                            (sys.executable, self.infinite_path))
        self.dia.button_add('"ls -l"', self.run_btn_cb, ('ls', '-l'))
        self.dia.button_add('"ls"', self.run_btn_cb, ('ls', ))

    def run_btn_cb(self, btn, pars):
        cmd = pars[0]
        params = pars[1:]
        self.exe = EmcExe(cmd,
                          params,
                          grab_output=True,
                          done_cb=self.exe_done_cb,
                          parent=self.dia,
                          asd1='asd_1',
                          asd2='asd_2')
        self.dia.text_set('Running: "{} {}"<br><br>'.format(
            cmd, ' '.join(params)))

    def exe_done_cb(self, exit_code, output, asd1, asd2):
        assert asd1 == 'asd_1'
        assert asd2 == 'asd_2'
        print("OUT", exit_code, output)
        self.dia.text_append('Process completed<br>'
                             'exit_code: {}<br>'
                             'output: {}'.format(exit_code, repr(output)))
Пример #4
0
class EmcFolderSelector(object):
    """
    Open a dialog that allow the user to choose a path on the filesystem.

    Args:
       title:
          The (optional) dialog title.
       done_cb:
          The (mandatory) function to call when the selection is done.
          Signature: func(path, **kargs)
       **kargs:
          Any other keyword arguments will be passed back in the done_cd func
    """

    def __init__(self, title=None, done_cb=None, **kargs):
        self._user_cb = done_cb
        self._user_kargs = kargs

        self._dialog = EmcDialog(title or _('Source Selector'), style='list')
        self._dialog.button_add(_('Select'), self._btn_select_cb)
        self._dialog.button_add(_('Browse'), self._btn_browse_cb, default=True)

        self.populate_devices()

    def populate_devices(self):
        self._dialog.list_clear()

        # other storage devices
        for dev in storage.list_devices():
            if dev.is_mounted:
                it = self._dialog.list_item_append(dev.label, dev.icon)
                it.data['root'] = it.data['path'] = dev.mount_point
        self._dialog.list_go()

    def populate_folder(self, root, folder):
        if folder == '':  # back in '/'
            self.populate_devices()
            return

        try:
            folders = os.listdir(folder)
        except PermissionError:
            EmcDialog(style='error', text=_('Permission denied'))
            return

        self._dialog.list_clear()

        # back item
        parent = os.path.normpath(os.path.join(folder, '..'))
        it = self._dialog.list_item_append(_('Back'), 'icon/back')
        it.data['root'] = root
        it.data['path'] = parent if parent != folder else ''  # back in '/'

        # folders
        for fname in utils.natural_sort(folders):
            fullpath = os.path.join(folder, fname)
            if fname[0] != '.' and os.path.isdir(fullpath):
                it = self._dialog.list_item_append(fname, 'icon/folder')
                it.data['root'] = root
                it.data['path'] = fullpath

        self._dialog.list_go()

    def _btn_browse_cb(self, btn):
        it = self._dialog.list_item_selected_get()
        if len(it.data['path']) < len(it.data['root']):
            self.populate_devices()
        else:
            self.populate_folder(it.data['root'], it.data['path'])

    def _btn_select_cb(self, btn):
        path = self._dialog.list_item_selected_get().data['path']
        if path and callable(self._user_cb):
            self._user_cb('file://' + path, **self._user_kargs)
        self._dialog.delete()
Пример #5
0
class CastPanel(object):
    def __init__(self, pid=None, name=None, lang=DEFAULT_INFO_LANG):
        self.pid = pid
        self.info = None

        tmdb = TMDBv3(lang=lang)
        if name:
            tmdb.person_search(name, self._search_done_cb)
        elif pid:
            tmdb.get_cast_info(self.pid, self._fetch_done_cb)
        self._dia = EmcDialog(style='minimal',
                              title=_('Fetching info'),
                              content='image/tmdb_logo.png',
                              spinner=True)

    def _search_done_cb(self, tmdb, result):
        # TODO manage errors
        self.pid = result['results'][0]['id']
        tmdb.get_cast_info(self.pid, self._fetch_done_cb)

    def _fetch_done_cb(self, tmdb, result):
        self.info = result
        self._dia.delete()

        text = ''
        if self.info.get('biography'):
            text += '%s<br><br>' % self.info['biography'].replace('\n', '<br>')
        if self.info.get('birthday'):
            text += '<name>%s:</name> %s<br>' % (_('Birthday'),
                                                 self.info['birthday'])
        if self.info.get('deathday'):
            text += '<name>%s:</name> %s<br>' % (_('Deathday'),
                                                 self.info['deathday'])
        if self.info.get('place_of_birth'):
            text += '<name>%s:</name> %s<br>' % (_('Place of birth'),
                                                 self.info['place_of_birth'])

        self._dia = EmcDialog(title=self.info['name'],
                              style='panel',
                              content=self.info['profile_path'],
                              text=text)

        # merge cast and crew in a single movies list
        movies = {}  # key: tmdbid val: tmdb-data-dict + 'jobs'
        for movie in self.info['credits']['crew']:
            tid = movie['id']
            if tid in movies:
                movies[tid]['jobs'].append(movie.get('job'))
            else:
                movie['jobs'] = [movie.get('job')]
                movies[tid] = movie

        for movie in self.info['credits']['cast']:
            tid = movie['id']
            if tid in movies:
                movies[tid]['character'] = movie.get('character')
            else:
                movies[tid] = movie

        self._dia.button_add(
            _('Movies (%s)') % len(movies),
            lambda b: self.movies_dialog(movies))
        num = len(self.info['images']['profiles'])
        self._dia.button_add(
            _('Photos (%s)') % num, lambda b: self.photos_dialog())

    def photos_dialog(self):
        dia = EmcDialog(style='image_list_portrait', title=self.info['name'])
        for image in self.info['images']['profiles']:
            dia.list_item_append(None, image['file_path'])
        dia.list_go()

    def movies_dialog(self, movies):
        dia = EmcDialog(style='list', title=self.info['name'])
        for movie in sorted(movies.values(), key=itemgetter('title')):
            label = '<big>{}</big>'.format(movie['title'])
            if 'character' in movie:
                label += ' <i>{} <big>{}</big></i>'.format(
                    _('as'), movie['character'])
            if 'jobs' in movie:
                label += ' <i>({})</i>'.format(', '.join(movie['jobs']))
            dia.list_item_append(label, movie.get('poster_path'))
        dia.list_go()
Пример #6
0
class KeyboardModule(EmcModule):
    name = 'input_keyb'
    label = _('Input - Keyboard')
    icon = 'icon/keyboard'
    info = _('The keyboard module lets you control the application using '
             'your keyboard, or any other device that act as a keyboard.')

    def __init__(self):
        DBG('Init module')

        self.grab_key_func = None

        # set up default bindings
        section = 'keyboard'
        if not ini.has_section(section):
            ini.add_section(section)
            defs = EmcGui.instance().default_keymap_get()
            for key, event in defs.items():
                ini.set(section, key, event)

        # read mapping from config
        self.keys = dict()
        for key, event in ini.get_options(section):
            DBG('Map key "%s" to event %s' % (key, event))
            self.keys[key] = event

        # add an entry in the config gui section
        config_gui.root_item_add('keyb',
                                 50,
                                 _('Keyboard'),
                                 icon='icon/keyboard',
                                 callback=self.config_panel_cb)

        # ask the gui to forward key events to us
        EmcGui.instance().key_down_connect(self._key_down_cb)

    def __shutdown__(self):
        DBG('Shutdown module')
        config_gui.root_item_del('keyb')
        EmcGui.instance().key_down_connect(None)

    def _key_down_cb(self, key):
        DBG('Key: %s' % key)
        key = key.lower()

        # if grabbed request call the grab function, else emit the signal
        if self.grab_key_func and callable(self.grab_key_func):
            self.grab_key_func(key)
        else:
            try:
                input_events.event_emit(self.keys[key])
            except KeyError:
                print('Not mapped key: ' + key)

    # ---- config panel stuff ----
    class KeyItemClass(EmcItemClass):
        def item_selected(self, url, data):
            key, event, mod = data
            txt = '%s<br><br>%s ⇾ %s' % (
                _('Are you sure you want to remove the mapping?'), key, event)
            EmcDialog(style='yesno',
                      title=_('Remove key'),
                      text=txt,
                      done_cb=self._remove_confirmed,
                      user_data=data)

        def _remove_confirmed(self, dia):
            key, event, mod = dia.data_get()

            # remove key from mapping and from config
            mod.keys.pop(key, None)
            ini.remove_option('keyboard', key)

            # kill the dialog and refresh the browser
            bro = config_gui.browser_get()
            bro.refresh(hard=True)
            dia.delete()

        def label_get(self, url, data):
            key, event, mod = data
            return key

        def label_end_get(self, url, data):
            key, event, mod = data
            return event

        def icon_get(self, url, data):
            return 'icon/key'

    def config_panel_cb(self):
        bro = config_gui.browser_get()
        bro.page_add('config://keyb/', _('Keyboard'), None, self.populate_keyb)

    def populate_keyb(self, browser, url):
        config_gui.standard_item_action_add(_('Add a new key'),
                                            icon='icon/plus',
                                            cb=self._add_item_cb)
        for key, event in sorted(self.keys.items(), key=lambda x: x[1]):
            browser.item_add(self.KeyItemClass(), 'config://keyb/button',
                             (key, event, self))

    def _add_item_cb(self):
        # grab the next pressed key and show the first dialog
        self.grab_key_func = self.grabbed_key_func
        self.dia = EmcDialog(title=_('Add a new key'),
                             style='cancel',
                             text=_('Press a key on your keyboard'),
                             canc_cb=self.ungrab_key)

    def ungrab_key(self, dialog):
        self.grab_key_func = None
        dialog.delete()

    def grabbed_key_func(self, key):
        # ungrab remote keys & delete the first dialog
        self.grab_key_func = None
        self.pressed_key = key
        self.dia.delete()

        # create the dialog to choose the event to bind
        dia = EmcDialog(title=_('Choose an event to bind'),
                        style='list',
                        done_cb=self.event_choosed_cb)
        for event in input_events.STANDARD_EVENTS.split():
            dia.list_item_append(event)
        dia.list_go()

    def event_choosed_cb(self, dia):
        event = str(dia.list_item_selected_get().label)
        key = str(self.pressed_key)

        # save the pressed key in mapping and config
        self.keys[key] = event
        ini.set('keyboard', key, event)

        # kill the dialog and refresh the browser
        dia.delete()
        bro = config_gui.browser_get()
        bro.refresh(hard=True)