From: NeilBrown Date: Fri, 26 May 2023 05:36:55 +0000 (+1000) Subject: doc-to-text: don't wait for conversion to complete. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=9b8fd8f6949845317f9f47c5fb8a4c61d8a540b8;p=edlib.git doc-to-text: don't wait for conversion to complete. If permitted by called, don't start the conversion to text until a notification arrives. This requires getting multipart to forward doc:replaced notifications. Signed-off-by: NeilBrown --- diff --git a/doc-multipart.c b/doc-multipart.c index b801a0b4..50ce4a17 100644 --- a/doc-multipart.c +++ b/doc-multipart.c @@ -662,6 +662,15 @@ DEF_CMD(mp_notify_viewers) return 1; } +DEF_CMD(mp_doc_replaced) +{ + /* Something changed in a component, report that the + * whole doc changed - simplest for now. + */ + pane_notify("doc:replaced", ci->home); + return 1; +} + static void mp_resize(struct mp_info *mpi safe, int size) { if (mpi->parts_size >= size) @@ -695,6 +704,7 @@ DEF_CMD(mp_add) pane_add_notify(ci->home, ci->focus, "Notify:Close"); home_call(ci->focus, "doc:request:doc:notify-viewers", ci->home); + home_call(ci->focus, "doc:request:doc:replaced", ci->home); return 1; } @@ -827,6 +837,7 @@ static void mp_init_map(void) key_add(mp_map, "Free", &mp_free); key_add(mp_map, "Notify:Close", &mp_notify_close); key_add(mp_map, "doc:notify-viewers", &mp_notify_viewers); + key_add(mp_map, "doc:replaced", &mp_doc_replaced); key_add(mp_map, "multipart-add", &mp_add); key_add(mp_map, "debug:validate-marks", &mp_val_marks); key_add(mp_map, "doc:multipart:get-part", &mp_get_part); diff --git a/python/lib-doc-to-text.py b/python/lib-doc-to-text.py index 0746175f..ef93cc1a 100644 --- a/python/lib-doc-to-text.py +++ b/python/lib-doc-to-text.py @@ -10,7 +10,84 @@ import subprocess import tempfile import os -def doc_to_text(key, home, focus, str1, comm2, **a): +class doc_pane(edlib.Pane): + def __init__(self, focus, path, newpath, delayed): + edlib.Pane.__init__(self, focus) + self.doc = focus + self.path = path + self.add_notify(focus, "Close") + self.newpath = newpath + focus.call("doc:replace", 1, "(Converting content to text...)\n") + if delayed: + self.call("doc:request:convert-now") + else: + self.handle_visible("key", focus) + + def handle_visible(self, key, focus, **a): + "handle:convert-now" + pipe = subprocess.Popen(["/usr/bin/lowriter", "--convert-to", "txt:Text", + self.path], close_fds=True, + cwd = os.path.dirname(self.path), + stdout=subprocess.PIPE, stderr = subprocess.PIPE, + stdin =subprocess.DEVNULL) + fd = pipe.stdout.fileno() + self.pipe = pipe + fcntl.fcntl(fd, fcntl.F_SETFL, + fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK) + self.call("event:read", pipe.stdout.fileno(), self.read) + + def handle_close(self, key, **a): + "handle:Close" + try: + os.unlink(self.path) + except FileNotFoundError: + pass + try: + os.unlink(self.newpath) + except FileNotFoundError: + pass + return 1 + + def handle_doc_close(self, key, focus, **a): + "handle:Notify:Close" + if focus == self.doc: + self.doc = None + if self.pipe: + self.pipe.kill() + return 1 + + def read(self, key, **a): + if not self.pipe: + return edlib.Efalse + try: + r = os.read(self.pipe.stdout.fileno(), 65536) + except IOError: + return 1 + if r: + # Not interesting in any output, just in EOF + return 1 + + out, err = self.pipe.communicate() + self.pipe = None + if err: + edlib.LOG("doc-to-text:", err.decode("utf-8","ignore")) + try: + with open(self.newpath, 'rb') as fp: + out = fp.read() + except: + out = (b"DOC coversions failed:\n" + err) + + if self.doc: + m = edlib.Mark(self.doc) + m2 = m.dup() + m.step(1) + self.doc.call("doc:set-ref", m2) + self.doc.call("doc:replace", 1, out.decode("utf-8", 'ignore'), + m, m2) + self.close() + return edlib.Efalse + +def doc_to_text(key, home, focus, num, str1, comm2, **a): if not str1 or '.' not in str1: # we need a file name to get an extension @@ -24,26 +101,10 @@ def doc_to_text(key, home, focus, str1, comm2, **a): os.close(fd) newpath = path[:path.rindex('.')] + ".txt" - p = subprocess.Popen(["/usr/bin/lowriter", "--convert-to", "txt:Text", - path], close_fds=True, - cwd = os.path.dirname(path), - stdout=subprocess.PIPE, stderr = subprocess.PIPE, - stdin =subprocess.DEVNULL) - out,err = p.communicate() - if err: - edlib.LOG("doctotext:", err.decode("utf-8", 'ignore')) - - try: - with open(newpath, 'rb') as fp: - out = fp.read() - os.unlink(newpath) - except: - out = (b"DOC conversion failed:\n" + err) - os.unlink(path) - - doc = focus.call("doc:from-text", "office-document", - out.decode("utf-8", 'ignore'), - ret='pane') + doc = focus.call("doc:from-text", "office-document", "", ret='pane') + + doc_pane(doc, path, newpath, num) + comm2("cb", doc) return 1