From 6d05a6ec2093e7eeb15b7eefecb0c402814649a2 Mon Sep 17 00:00:00 2001 From: DYefremov Date: Fri, 17 Jun 2022 17:53:39 +0300 Subject: [PATCH] lazy xmltv loading --- app/tools/epg.py | 14 +++++++------- app/ui/epg/epg.py | 10 +++++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/tools/epg.py b/app/tools/epg.py index 5e043a15..193c35df 100644 --- a/app/tools/epg.py +++ b/app/tools/epg.py @@ -237,7 +237,7 @@ class XmlTvReader(Reader): @run_task def download(self, clb=None): - """ Downloads and processes an XMLTV file. """ + """ Downloads an XMLTV file. """ res = urlparse(self._url) if not all((res.scheme, res.netloc)): log(f"{self.__class__.__name__} [download] error: Invalid URL {self._url}") @@ -310,15 +310,13 @@ class XmlTvReader(Reader): import gzip with gzip.open(self._path, "rb") as gzf: - self.process_data(gzf) + log("Processing XMLTV data...") + for n in ET.iterparse(gzf): + yield from self.process_node(n) + log("XMLTV data parsing is complete.") except OSError as e: log(f"{self.__class__.__name__} [parse] error: {e}") - def process_data(self, data): - log("Processing XMLTV data...") - list(map(self.process_node, ET.iterparse(data))) - log("XMLTV data parsing is complete.") - def process_node(self, node): event, element = node if element.tag == self.CH_TAG: @@ -352,6 +350,8 @@ class XmlTvReader(Reader): if all((start, stop, title)): events.append(self.Event(start, stop, title, desc)) + yield node + def to_epg_dat(self): """ Converts and saves imported data to 'epg.dat' file. """ raise ValueError("Not implemented yet!") diff --git a/app/ui/epg/epg.py b/app/ui/epg/epg.py index b0358923..04530bc8 100644 --- a/app/ui/epg/epg.py +++ b/app/ui/epg/epg.py @@ -69,20 +69,24 @@ class EpgCache(dict): self.init() - @run_task + @run_idle def init(self): if self._src is EpgSource.XML: url = self._settings.epg_xml_source gz_file = f"{self._settings.profile_data_path}epg{os.sep}epg.gz" self._reader = XmlTvReader(gz_file, url) + def process_data(): + gen = self._reader.parse() + GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW) + if os.path.isfile(gz_file): # Difference calculation between the current time and file modification. dif = datetime.now() - datetime.fromtimestamp(os.path.getmtime(gz_file)) # We will update daily. -> Temporarily!!! - self._reader.download(self._reader.parse) if dif.days > 0 else self._reader.parse() + self._reader.download(process_data) if dif.days > 0 else process_data() else: - self._reader.download(self._reader.parse) + self._reader.download(process_data) elif self._src is EpgSource.DAT: self._reader = EPG.DatReader(f"{self._settings.profile_data_path}epg{os.sep}epg.dat") self._reader.download()