Ejemplo n.º 1
0
def _reload_service():
    database.close()

    with gui.progress(_.RELOAD_SERVICE, percent=100) as progress:
        set_kodi_string('_gpio_reload', '1')

        for i in range(5):
            xbmc.sleep(1000)
            if not get_kodi_string('_gpio_reload'):
                break
Ejemplo n.º 2
0
    def setup_buttons():
        log.debug('Setting up buttons')

        try:
            database.connect()

            Button.update(status=Button.Status.INACTIVE,
                          error=None).where(Button.enabled == True).execute()
            Button.update(status=Button.Status.DISABLED,
                          error=None).where(Button.enabled == False).execute()
            btns = list(Button.select().where(Button.enabled == True))

            buttons = []
            for btn in btns:
                if not btn.has_callbacks():
                    continue

                try:
                    button = gpiozero.Button(btn.pin,
                                             pull_up=btn.pull_up,
                                             bounce_time=btn.bounce_time
                                             or None,
                                             hold_time=btn.hold_time,
                                             hold_repeat=btn.hold_repeat)

                    if btn.when_pressed:
                        button.when_pressed = lambda function=btn.when_pressed: callback(
                            function)

                    if btn.when_released:
                        button.when_released = lambda function=btn.when_released: callback(
                            function)

                    if btn.when_held:
                        button.when_held = lambda function=btn.when_held: callback(
                            function)
                except Exception as e:
                    log.exception(e)
                    btn.status = Button.Status.ERROR
                    btn.error = e
                else:
                    btn.status = Button.Status.ACTIVE
                    buttons.append(button)

                btn.save()

            return buttons
        except Exception as e:
            log.debug(e)
            return []
        finally:
            database.close()
    def epgs(self, refresh=True):
        epg_path = os.path.join(self.output_path, EPG_FILE_NAME)
        working_path = os.path.join(self.working_path, EPG_FILE_NAME)
        epg_path_tmp = os.path.join(self.working_path, EPG_FILE_NAME + '_tmp')

        if not refresh and xbmcvfs.exists(epg_path) and xbmcvfs.exists(
                working_path):
            return working_path

        start_time = time.time()
        database.connect()

        try:
            progress = gui.progressbg() if self.forced else None

            epgs = list(EPG.select().where(EPG.enabled == True).order_by(
                EPG.id))
            EPG.update({
                EPG.start_index: 0,
                EPG.end_index: 0,
                EPG.results: []
            }).where(EPG.enabled == False).execute()

            if settings.getBool('remove_epg_orphans', True):
                epg_ids = Channel.epg_ids()
            else:
                epg_ids = None

            if self._playlist_epgs:
                epg_urls = [x.path.lower() for x in epgs]
                for url in self._playlist_epgs:
                    if url.lower() not in epg_urls:
                        epg = EPG(source_type=EPG.TYPE_URL,
                                  path=url,
                                  enabled=1)
                        epgs.append(epg)
                        epg_urls.append(url.lower())

            with FileIO(epg_path_tmp, 'wb') as _out:
                _out.write(b'<?xml version="1.0" encoding="UTF-8"?><tv>')

                for count, epg in enumerate(epgs):
                    count += 1

                    if progress:
                        progress.update(
                            int(count * (100 / len(epgs))),
                            'Merging EPG ({}/{})'.format(count, len(epgs)),
                            _(epg.label, _bold=True))

                    file_index = _out.tell()

                    epg_start = time.time()
                    try:
                        log.debug('Processing: {}'.format(epg.path))
                        self._process_source(epg, METHOD_EPG, self.tmp_file)
                        with FileIO(self.tmp_file, 'rb') as _in:
                            parser = XMLParser(_out, epg_ids)
                            parser.parse(_in, epg)
                    except Exception as e:
                        log.exception(e)
                        result = [int(time.time()), EPG.ERROR, str(e)]
                    else:
                        result = [
                            int(time.time()), EPG.OK,
                            '{} ({:.2f}s)'.format(parser.epg_count(),
                                                  time.time() - epg_start)
                        ]
                        epg.results.insert(0, result)

                    if result[1] == EPG.ERROR:
                        _seek_file(_out, file_index)

                        if epg.start_index > 0:
                            if copy_partial_data(working_path, _out,
                                                 epg.start_index,
                                                 epg.end_index):
                                log.debug(
                                    'Last used XML data loaded successfully')
                                epg.start_index = file_index
                                epg.end_index = _out.tell()
                            else:
                                log.debug('Failed to load last XML data')
                                epg.start_index = 0
                                epg.end_index = 0
                                _seek_file(_out, file_index)

                        if epg.results and epg.results[0][1] == EPG.ERROR:
                            epg.results[0] = result
                        else:
                            epg.results.insert(0, result)

                    epg.results = epg.results[:3]
                    if epg.id:
                        epg.save()
                    remove_file(self.tmp_file)

                _out.write(b'</tv>')

            remove_file(working_path)
            shutil.move(epg_path_tmp, working_path)

            _safe_copy(working_path, epg_path)
        finally:
            database.close()
            if progress: progress.close()
            remove_file(self.tmp_file)
            remove_file(epg_path_tmp)

        log.debug('EPG Merge Time: {0:.2f}'.format(time.time() - start_time))

        return working_path
    def playlists(self, refresh=True):
        playlist_path = os.path.join(self.output_path, PLAYLIST_FILE_NAME)
        working_path = os.path.join(self.working_path, PLAYLIST_FILE_NAME)

        if not refresh and xbmcvfs.exists(playlist_path) and xbmcvfs.exists(
                working_path):
            return working_path

        start_time = time.time()
        database.connect()

        try:
            progress = gui.progressbg() if self.forced else None

            playlists = list(Playlist.select().where(
                Playlist.enabled == True).order_by(Playlist.order))
            Playlist.update({
                Playlist.results: []
            }).where(Playlist.enabled == False).execute()
            Channel.delete().where(
                Channel.custom == False,
                Channel.playlist.not_in(playlists)).execute()

            for count, playlist in enumerate(playlists):
                count += 1

                if progress:
                    progress.update(
                        int(count * (100 / len(playlists))),
                        'Merging Playlist ({}/{})'.format(
                            count, len(playlists)),
                        _(playlist.label, _bold=True))

                playlist_start = time.time()

                error = None
                try:
                    log.debug('Processing: {}'.format(playlist.path))

                    if playlist.source_type != Playlist.TYPE_CUSTOM:
                        self._process_source(playlist, METHOD_PLAYLIST,
                                             self.tmp_file)

                        with database.db.atomic() as transaction:
                            try:
                                added = self._process_playlist(
                                    playlist, self.tmp_file)
                            except:
                                transaction.rollback()
                                raise
                    else:
                        added = len(playlist.channels)
                except AddonError as e:
                    error = e
                except Error as e:
                    error = e
                    log.exception(e)
                except Exception as e:
                    error = e
                    log.exception(e)
                else:
                    playlist.results.insert(0, [
                        int(time.time()), Playlist.OK,
                        '{} Channels ({:.2f}s)'.format(
                            added,
                            time.time() - playlist_start)
                    ])
                    error = None

                if error:
                    result = [int(time.time()), Playlist.ERROR, str(error)]
                    if playlist.results and playlist.results[0][
                            1] == Playlist.ERROR:
                        playlist.results[0] = result
                    else:
                        playlist.results.insert(0, result)

                remove_file(self.tmp_file)

                playlist.results = playlist.results[:3]
                playlist.save()

            count = 0
            starting_ch_no = settings.getInt('start_ch_no', 1)

            with codecs.open(working_path, 'w', encoding='utf8') as outfile:
                outfile.write(u'#EXTM3U')

                group_order = settings.get('group_order')
                if group_order:
                    outfile.write(u'\n\n#EXTGRP:{}'.format(group_order))

                chno = starting_ch_no
                tv_groups = []
                for channel in Channel.playlist_list(radio=False):
                    if channel.chno is None:
                        channel.chno = chno
                    chno = channel.chno + 1

                    tv_groups.extend(channel.groups)

                    outfile.write(u'\n\n')
                    outfile.write(channel.get_lines())
                    count += 1

                chno = starting_ch_no
                for channel in Channel.playlist_list(radio=True):
                    if channel.chno is None:
                        channel.chno = chno
                    chno = channel.chno + 1

                    new_groups = []
                    for group in channel.groups:
                        count = 1
                        while group in tv_groups:
                            group = _(_.RADIO_GROUP, group=group)
                            if count > 1:
                                group = u'{} #{}'.format(group, count)
                            count += 1
                        new_groups.append(group)

                    channel.groups = new_groups

                    outfile.write(u'\n\n')
                    outfile.write(channel.get_lines())
                    count += 1

                if count == 0:
                    outfile.write(u'\n\n#EXTINF:-1,EMPTY PLAYLIST\nhttp')

            log.debug('Wrote {} Channels'.format(count))
            Playlist.after_merge()
            _safe_copy(working_path, playlist_path)
        finally:
            database.close()
            if progress: progress.close()
            remove_file(self.tmp_file)

        log.debug('Playlist Merge Time: {0:.2f}'.format(time.time() -
                                                        start_time))

        return working_path