diff options
author | Chenxiong Qi <qcxhome@gmail.com> | 2022-09-14 09:29:25 +0800 |
---|---|---|
committer | Hossein <hossein@libreoffice.org> | 2022-10-13 15:41:40 +0200 |
commit | 665d1633c9e08da85fae179e62923211bc07c480 (patch) | |
tree | cd6d451f6b57b21f086278be851ae8b69fe0f57f | |
parent | 5956cecdf61846671f7d028ad60623e1e840ad3f (diff) |
tdf#143123 port DocumentHandling examples to Python
This port keeps the similarity with Java ones as much as possible.
examples.html is also updated by adding the Python examples.
Signed-off-by: Chenxiong Qi <qcxhome@gmail.com>
Change-Id: I2af26aaf42f5408bf254a4e0507442200f843661
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139887
Tested-by: Jenkins
Reviewed-by: Hossein <hossein@libreoffice.org>
-rw-r--r-- | odk/Package_examples.mk | 6 | ||||
-rw-r--r-- | odk/examples/examples.html | 36 | ||||
-rw-r--r-- | odk/examples/python/DocumentHandling/DocumentConverter.py | 91 | ||||
-rw-r--r-- | odk/examples/python/DocumentHandling/DocumentLoader.py (renamed from odk/examples/python/DocumentLoader/DocumentLoader.py) | 42 | ||||
-rw-r--r-- | odk/examples/python/DocumentHandling/DocumentPrinter.py | 71 | ||||
-rw-r--r-- | odk/examples/python/DocumentHandling/DocumentSaver.py | 81 | ||||
-rw-r--r-- | odk/examples/python/DocumentHandling/README.md | 56 | ||||
-rw-r--r-- | odk/examples/python/DocumentHandling/tests/hello.odt | bin | 0 -> 8471 bytes | |||
-rw-r--r-- | odk/examples/python/DocumentLoader/README.md | 12 |
9 files changed, 374 insertions, 21 deletions
diff --git a/odk/Package_examples.mk b/odk/Package_examples.mk index 6749bcdcc798..457aea37e166 100644 --- a/odk/Package_examples.mk +++ b/odk/Package_examples.mk @@ -541,6 +541,12 @@ $(eval $(call gb_Package_add_files_with_dir,odk_examples,$(SDKDIRNAME)/examples, python/toolpanel/toolpanel.component \ python/toolpanel/toolpanel.py \ python/toolpanel/toolpanels/poc.xdl \ + python/DocumentHandling/DocumentConverter.py \ + python/DocumentHandling/DocumentLoader.py \ + python/DocumentHandling/DocumentPrinter.py \ + python/DocumentHandling/DocumentSaver.py \ + python/DocumentHandling/README.md \ + python/DocumentHandling/tests/hello.odt \ )) # vim: set noet sw=4 ts=4: diff --git a/odk/examples/examples.html b/odk/examples/examples.html index 9a1bf3de6b3a..2b23080961fb 100644 --- a/odk/examples/examples.html +++ b/odk/examples/examples.html @@ -423,6 +423,42 @@ </table> </td> </tr> + <tr> + <td> + <table class="table4"> + <tbody> + <tr class="thead"> + <td class="cell20">Document Handling Examples</td> + <td class="cell80">Description</td> + </tr> + <tr> + <td class="cell20"> + <a href="python/DocumentHandling/" title="link to the source directory of the Python DocumentHandling examples">DocumentConverter</a> + </td> + <td class="cell80">The program offers a service that converts arbitrary documents to a favored document type.</td> + </tr> + <tr> + <td class="cell20"> + <a href="python/DocumentHandling/" title="link to the source directory of the Python DocumentHandling examples">DocumentLoader</a> + </td> + <td class="cell80">The DocumentLoader can open a new or an existing document.</td> + </tr> + <tr> + <td class="cell20"> + <a href="python/DocumentHandling/" title="link to the source directory of the Python DocumentHandling examples">DocumentPrinter</a> + </td> + <td class="cell80">The DocumentPrinter allows you to print the favored pages of a specified document on your favored printer.</td> + </tr> + <tr> + <td class="cell20"> + <a href="python/DocumentHandling/" title="link to the source directory of the Python DocumentHandling examples">DocumentSaver</a> + </td> + <td class="cell80">The DocumentSaver shows how to save a document and how you can change the type of your document.</td> + </tr> + </tbody> + </table> + </td> + </tr> <tr> <td> <table class="table3"> diff --git a/odk/examples/python/DocumentHandling/DocumentConverter.py b/odk/examples/python/DocumentHandling/DocumentConverter.py new file mode 100644 index 000000000000..a1f54fca9102 --- /dev/null +++ b/odk/examples/python/DocumentHandling/DocumentConverter.py @@ -0,0 +1,91 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +import argparse +import os +import sys +from os.path import abspath, basename, isdir, join, splitext + +import uno +import unohelper +from com.sun.star.beans import PropertyValue +from com.sun.star.connection import NoConnectException + +PROG = "$OFFICE_PROGRAM_PATH/python {}".format(basename(sys.argv[0])) +SOFFICE_CONNECTION_URI = "uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext" + + +def connect_soffice(): + """Connect to remote running LibreOffice""" + local_context = uno.getComponentContext() + resolver = local_context.ServiceManager.createInstanceWithContext( + "com.sun.star.bridge.UnoUrlResolver", local_context + ) + try: + remote_context = resolver.resolve(SOFFICE_CONNECTION_URI) + except NoConnectException: + raise Exception("Cannot establish a connection to LibreOffice.") + + return remote_context.ServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", remote_context + ) + + +def convert(src_file, dest_file, to_type): + src_url = "file://{}".format(src_file).replace("\\", "/") + dest_url = "file://{}".format(dest_file).replace("\\", "/") + + soffice = connect_soffice() + doc = soffice.loadComponentFromURL( + src_url, "_blank", 0, (PropertyValue(Name="Hidden", Value=True),) + ) + + opts = ( + PropertyValue(Name="Overwrite", Value=True), + PropertyValue(Name="FilterName", Value=to_type), + ) + try: + doc.storeAsURL(dest_url, opts); + finally: + doc.dispose() + + +def is_dir(value): + if not isdir(value): + raise argparse.ArgumentTypeError("{} is not a directory.".format(value)) + return value + + +def main(): + parser = argparse.ArgumentParser(description="Document Converter", prog=PROG) + parser.add_argument("from_dir", + type=is_dir, + help="Convert documents searched from this directory recursively") + parser.add_argument("to_type", help="Type to convert to, example: MS Word 97.") + parser.add_argument("extension", + help="Extension of the converted document, examples: doc, docx") + parser.add_argument("output_dir", + type=is_dir, + help="Converted document is stored into this directory") + + args = parser.parse_args() + + for dir_path, dir_names, file_names in os.walk(args.from_dir): + for name in file_names: + src_file = join(abspath(dir_path), name) + dest_file = "{}.{}".format(join(args.output_dir, splitext(name)[0]), args.extension) + convert(src_file, dest_file, args.to_type) + print("Converted", src_file, "to", dest_file) + + +if __name__ == "__main__": + main() + + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/odk/examples/python/DocumentLoader/DocumentLoader.py b/odk/examples/python/DocumentHandling/DocumentLoader.py index 521b63ce9066..a88f3ad0d724 100644 --- a/odk/examples/python/DocumentLoader/DocumentLoader.py +++ b/odk/examples/python/DocumentHandling/DocumentLoader.py @@ -7,18 +7,32 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # +import argparse import uno from com.sun.star.connection import NoConnectException -from os.path import isfile, abspath -from sys import argv, exit +from os.path import isfile, abspath, basename +from sys import argv + + +def is_file(value): + if not isfile(value): + raise argparse.ArgumentTypeError("{} could not be opened".format(value)) + return value + + +PROG = "$OFFICE_PROGRAM_PATH/python {}".format(basename(argv[0])) + if __name__ == "__main__": - if len(argv) < 2: - print("usage: $OFFICE_PROGRAM_PATH/python DocumentLoader.py <path>") - exit(1) - if not isfile(argv[1]): - print("%s could not be opened" % argv[1]) - exit(1) + parser = argparse.ArgumentParser(prog=PROG) + parser.add_argument("--writer", action="store_true", required=False, help="Open an empty Writer document") + parser.add_argument("--calc", action="store_true", required=False, help="Open an empty Calc document") + parser.add_argument("--draw", action="store_true", required=False, help="Open an empty Draw document") + parser.add_argument("path", + type=is_file, + nargs="?", + help="Path to a document to load. If omitted, an empty document is opened accordingly.") + args = parser.parse_args() # UNO component context for initializing the Python runtime localContext = uno.getComponentContext() @@ -36,7 +50,17 @@ if __name__ == "__main__": desktop = context.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", context) - url = uno.systemPathToFileUrl(abspath(argv[1])) + + if args.path: + url = uno.systemPathToFileUrl(abspath(args.path)) + elif args.writer: + url = "private:factory/swriter" + elif args.calc: + url = "private:factory/scalc" + elif args.draw: + url = "private:factory/sdraw" + else: + url = "private:factory/swriter" # Load a LibreOffice document, and automatically display it on the screen xComp = desktop.loadComponentFromURL(url, "_blank", 0, tuple([])) diff --git a/odk/examples/python/DocumentHandling/DocumentPrinter.py b/odk/examples/python/DocumentHandling/DocumentPrinter.py new file mode 100644 index 000000000000..d9a4e29632c7 --- /dev/null +++ b/odk/examples/python/DocumentHandling/DocumentPrinter.py @@ -0,0 +1,71 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +import argparse +import sys +from os.path import abspath, basename + +import uno +import unohelper +from com.sun.star.beans import PropertyValue +from com.sun.star.connection import NoConnectException + +PROG = "$OFFICE_PROGRAM_PATH/python {}".format(basename(sys.argv[0])) +SOFFICE_CONNECTION_URI = "uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext" + + +def connect_soffice(): + """Connect to remote running LibreOffice + + :return: an object representing the remote LibreOffice instance. + """ + local_context = uno.getComponentContext() + resolver = local_context.ServiceManager.createInstanceWithContext( + "com.sun.star.bridge.UnoUrlResolver", local_context + ) + try: + remote_context = resolver.resolve(SOFFICE_CONNECTION_URI) + except NoConnectException: + raise Exception("Cannot establish a connection to LibreOffice.") + + return remote_context.ServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", remote_context + ) + + +def print_(doc_path, printer, pages): + soffice = connect_soffice() + doc_url = "file://{}".format(abspath(doc_path)).replace("\\", "/") + # Load a Writer document, which will be automatically displayed + doc = soffice.loadComponentFromURL(doc_url, "_blank", 0, tuple([])) + try: + doc.setPrinter((PropertyValue(Name="Name", Value=printer),)) + print_opts = ( + PropertyValue(Name="Pages", Value=pages), + ) + doc.print(print_opts) + finally: + doc.dispose() + + +def main(): + parser = argparse.ArgumentParser(description="Document Printer", prog=PROG) + parser.add_argument("printer", help="Printer name") + parser.add_argument("doc_path", help="Path to a document to be printed") + parser.add_argument("pages", help="Page range to be printed, e.g. 1-3") + + args = parser.parse_args() + print_(args.doc_path, args.printer, args.pages) + + +if __name__ == "__main__": + main() + + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/odk/examples/python/DocumentHandling/DocumentSaver.py b/odk/examples/python/DocumentHandling/DocumentSaver.py new file mode 100644 index 000000000000..e7d8010a231a --- /dev/null +++ b/odk/examples/python/DocumentHandling/DocumentSaver.py @@ -0,0 +1,81 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +import argparse +import sys +from os.path import basename, abspath + +import uno +import unohelper +from com.sun.star.beans import PropertyValue +from com.sun.star.connection import NoConnectException + +""" +The purpose of this example is to open a specified text document and save this +file to a specified URL. The type of the saved file is "writer8". +""" + +PROG = "$OFFICE_PROGRAM_PATH/python {}".format(basename(sys.argv[0])) +SOFFICE_CONNECTION_URI = "uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext" + + +def connect_soffice(): + """Connect to remote running LibreOffice + + :return: an object representing the remote LibreOffice instance. + """ + local_context = uno.getComponentContext() + resolver = local_context.ServiceManager.createInstanceWithContext( + "com.sun.star.bridge.UnoUrlResolver", local_context + ) + try: + remote_context = resolver.resolve(SOFFICE_CONNECTION_URI) + except NoConnectException: + raise Exception("Cannot establish a connection to LibreOffice.") + + return remote_context.ServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", remote_context + ) + + +def save_doc(src, dest): + src_url = "file://{}".format(abspath(src)).replace("\\", "/") + dest_url = "file://{}".format(abspath(dest)).replace("\\", "/") + + soffice = connect_soffice() + doc = soffice.loadComponentFromURL( + src_url, "_blank", 0, (PropertyValue(Name="Hidden", Value=True),) + ) + + save_opts = ( + PropertyValue(Name="Overwrite", Value=True), + PropertyValue(Name="FilterName", Value="writer8"), + ) + try: + doc.storeAsURL(dest_url, save_opts) + print("Document", src, "saved under", dest) + finally: + doc.dispose() + print("Document closed!") + + +def main(): + parser = argparse.ArgumentParser(description="Document Saver", prog=PROG) + parser.add_argument("src", help="Path to a Word document to be saved, e.g. path/to/hello.doc") + parser.add_argument("dest", help="Save the document to here, e.g. path/to/hello.odt") + + args = parser.parse_args() + save_doc(args.src, args.dest) + + +if __name__ == "__main__": + main() + + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/odk/examples/python/DocumentHandling/README.md b/odk/examples/python/DocumentHandling/README.md new file mode 100644 index 000000000000..7e0e8aa43e4f --- /dev/null +++ b/odk/examples/python/DocumentHandling/README.md @@ -0,0 +1,56 @@ +# Document Handling Examples + +These examples are somehow similar to DocumentLoader in C++ and Java. +To get started, first start LibreOffice listening on port 2083 + + $OFFICE_PROGRAM_PATH/soffice "--accept=socket,port=2083;urp;" + +Each example script accepts `-h` to show the usage, e.g. + + $OFFICE_PROGRAM_PATH/python DocumentLoader.py -h + +You should use `setsdkenv_unix` for Unix/Linux and `setsdkenv_windows.bat` for +Windows. In this way, the LibreOffice internal Python interpreter will be used. + +## Document Converter + +```bash +$OFFICE_PROGRAM_PATH/python DocumentConverter.py ./tests/ "MS Word 97" doc /tmp/ +``` + +This command searches LibreOffice documents recursively under directory +`./tests` and convert every found document to format Microsoft Word 97. The +converted document can be found under directory `/tmp`. + +## Document Loader + +```bash +$OFFICE_PROGRAM_PATH/python DocumentLoader.py ./tests/hello.odt +``` + +This command opens document `./tests/hello.odt` in a separate window. + +This script also accepts option to open an empty document. For example, to open +an empty spreadsheet document: + +```bash +$OFFICE_PROGRAM_PATH/python DocumentLoader.py --calc +``` + +## Document Printer + +```bash +$OFFICE_PROGRAM_PATH/python DocumentPrinter.py myprinter ./tests/hello.odt "1-3" +``` + +This command prints the first three pages of document `./tests/hello.odt` on +printer `myprinter `. You can also specify the page range in various format, +e.g. `1,3-5`. + +## Document Saver + +```bash +$OFFICE_PROGRAM_PATH/python DocumentSaver.py path/to/hello.doc path/to/hello.odt +``` + +This command saves a Word document `hello.doc` as an OpenDocument file `hello.odt`. diff --git a/odk/examples/python/DocumentHandling/tests/hello.odt b/odk/examples/python/DocumentHandling/tests/hello.odt Binary files differnew file mode 100644 index 000000000000..dd72ae9ec4aa --- /dev/null +++ b/odk/examples/python/DocumentHandling/tests/hello.odt diff --git a/odk/examples/python/DocumentLoader/README.md b/odk/examples/python/DocumentLoader/README.md deleted file mode 100644 index d95c933ab9c1..000000000000 --- a/odk/examples/python/DocumentLoader/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# DocumentLoader -This example is somehow similar to DocumentLoader in C++ and Java. -to get started, first start LibreOffice listening on port 2083 - - $OFFICE_PROGRAM_PATH/soffice "--accept=socket,port=2083;urp;" - -The syntax to run this example is: - - $OFFICE_PROGRAM_PATH/python DocumentLoader.py <path> - -You should use 'setsdkenv_unix' for Unix/Linux and setsdkenv_windows.bat for Windows. In this way, -the LibreOffice internal Python interpreter will be used. |