Added MS-Windows path finding for uno.py. Fixed to read file as UTF-8 to avoid MS-Windows native encoding problem. Fixed the module matching problem that removes all the source files when doing --get at the second time.

This commit is contained in:
依瑪貓 2016-12-02 09:03:01 +08:00
parent 5f7db9004d
commit 3aea24b725

View File

@ -8,9 +8,23 @@ import os
import sys import sys
import time import time
# Finds uno.py for MS-Windows
is_found_uno = False
for p in sys.path:
if os.path.exists(os.path.join(p, "uno.py")):
is_found_uno = True
break
if not is_found_uno:
cand = sys.executable
while cand != os.path.dirname(cand):
cand = os.path.dirname(cand)
if os.path.exists(os.path.join(cand, "uno.py")):
sys.path.append(cand)
break
import uno import uno
from com.sun.star.connection import NoConnectException from com.sun.star.connection import NoConnectException
def main(): def main():
""" The main program. """ """ The main program. """
t_start = time.time() t_start = time.time()
@ -28,32 +42,41 @@ def main():
print >> sys.stderr, "Done. %02d:%02d elapsed." % \ print >> sys.stderr, "Done. %02d:%02d elapsed." % \
(int((time.time() - t_start) / 60), (time.time() - t_start) % 60) (int((time.time() - t_start) / 60), (time.time() - t_start) % 60)
def parse_args(): def parse_args():
""" Parses the arguments. """ """ Parses the arguments. """
global args global args
parser = argparse.ArgumentParser(description="Synchronize the local Basic scripts with OpenOffice Basic.") parser = argparse.ArgumentParser(
parser.add_argument("projdir", metavar="dir", nargs="?", description=("Synchronize the local Basic scripts"
default=os.getcwd(), " with OpenOffice Basic."))
help="The project source directory (default to the current directory).") parser.add_argument(
parser.add_argument("library", metavar="Library", nargs="?", "projdir", metavar="dir", nargs="?", default=os.getcwd(),
help="The Library to upload/download the macros (default to the name of the directory).") help=("The project source directory"
parser.add_argument("--get", action="store_true", " (default to the current directory)."))
parser.add_argument(
"library", metavar="Library", nargs="?",
help=("The Library to upload/download the macros"
" (default to the name of the directory)."))
parser.add_argument(
"--get", action="store_true",
help="Downloads the macros instead of upload.") help="Downloads the macros instead of upload.")
parser.add_argument("-r", "--run", metavar="Module.Macro", parser.add_argument(
"-r", "--run", metavar="Module.Macro",
help="The macro to run after the upload, if any.") help="The macro to run after the upload, if any.")
parser.add_argument("-v", "--version", parser.add_argument(
action="version", version="%(prog)s 0.1") "-v", "--version", action="version", version="%(prog)s 0.1")
args = parser.parse_args() args = parser.parse_args()
# Obtains the absolute path # Obtains the absolute path
args.projdir = os.path.abspath(args.projdir) args.projdir = os.path.abspath(args.projdir)
# Obtains the library name from the path # Obtains the library name from the path
if args.library == None: if args.library is None:
args.library = os.path.basename(args.projdir) args.library = os.path.basename(args.projdir)
return return
def sync_macros(oo): def sync_macros(oo):
""" Synchronize the Basic macros. """ """ Synchronize the Basic macros. """
global args global args
@ -64,7 +87,8 @@ def sync_macros(oo):
if args.get: if args.get:
modules = read_basic_modules(libraries, args.library) modules = read_basic_modules(libraries, args.library)
if len(modules) == 0: if len(modules) == 0:
print >> sys.stderr, "ERROR: Library " + args.library + " does not exist" print >> sys.stderr, \
"ERROR: Library " + args.library + " does not exist"
return return
update_source_dir(args.projdir, modules) update_source_dir(args.projdir, modules)
@ -72,18 +96,23 @@ def sync_macros(oo):
else: else:
modules = read_in_source_dir(args.projdir) modules = read_in_source_dir(args.projdir)
if len(modules) == 0: if len(modules) == 0:
print >> sys.stderr, "ERROR: Found no source macros in " + args.projdir print >> sys.stderr, \
"ERROR: Found no source macros in " + args.projdir
return return
update_basic_modules(libraries, args.library, modules) update_basic_modules(libraries, args.library, modules)
if args.run != None: if args.run is not None:
factory = oo.service_manager.DefaultContext.getByName( factory = oo.service_manager.DefaultContext.getByName(
"/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") "/singletons/com.sun.star.script.provider."
"theMasterScriptProviderFactory")
provider = factory.createScriptProvider("") provider = factory.createScriptProvider("")
script = provider.getScript( script = provider.getScript(
"vnd.sun.star.script:" + args.library + "." + args.run + "?language=Basic&location=application") "vnd.sun.star.script:"
+ args.library + "." + args.run
+ "?language=Basic&location=application")
script.invoke((), (), ()) script.invoke((), (), ())
return return
def read_in_source_dir(projdir): def read_in_source_dir(projdir):
""" Reads-in the source macros. """ """ Reads-in the source macros. """
modules = {} modules = {}
@ -92,10 +121,11 @@ def read_in_source_dir(projdir):
if os.path.isfile(path) and entry.lower().endswith(".vb"): if os.path.isfile(path) and entry.lower().endswith(".vb"):
modname = entry[0:-3] modname = entry[0:-3]
f = open(path) f = open(path)
modules[modname] = f.read() modules[modname] = f.read().decode("utf-8")
f.close() f.close()
return modules return modules
def update_source_dir(projdir, modules): def update_source_dir(projdir, modules):
""" Updates the source macros. """ """ Updates the source macros. """
curmods = {} curmods = {}
@ -105,7 +135,7 @@ def update_source_dir(projdir, modules):
modname = entry[0:-3] modname = entry[0:-3]
curmods[modname] = entry curmods[modname] = entry
for modname in sorted(modules.keys()): for modname in sorted(modules.keys()):
if not curmods.has_key(modname): if modname not in curmods:
path = os.path.join(projdir, modname + ".vb") path = os.path.join(projdir, modname + ".vb")
f = open(path, "w") f = open(path, "w")
f.write(modules[modname]) f.write(modules[modname])
@ -120,12 +150,13 @@ def update_source_dir(projdir, modules):
print >> sys.stderr, curmods[modname] + " updated." print >> sys.stderr, curmods[modname] + " updated."
f.close() f.close()
for modname in sorted(curmods.keys()): for modname in sorted(curmods.keys()):
if not modules.has_key(modname): if modname not in modules:
path = os.path.join(projdir, curmods[modname]) path = os.path.join(projdir, curmods[modname])
os.remove(path) os.remove(path)
print >> sys.stderr, curmods[modname] + " removed." print >> sys.stderr, curmods[modname] + " removed."
return return
def read_basic_modules(libraries, libname): def read_basic_modules(libraries, libname):
""" Reads the OpenOffice Basic macros from the macros storage. """ """ Reads the OpenOffice Basic macros from the macros storage. """
modules = {} modules = {}
@ -137,6 +168,7 @@ def read_basic_modules(libraries, libname):
modules[modname] = library.getByName(modname).encode("utf-8") modules[modname] = library.getByName(modname).encode("utf-8")
return modules return modules
def update_basic_modules(libraries, libname, modules): def update_basic_modules(libraries, libname, modules):
""" Updates the OpenOffice Basic macros storage. """ """ Updates the OpenOffice Basic macros storage. """
if not libraries.hasByName(libname): if not libraries.hasByName(libname):
@ -151,22 +183,23 @@ def update_basic_modules(libraries, libname, modules):
library = libraries.getByName(libname) library = libraries.getByName(libname)
curmods = sorted(library.getElementNames()) curmods = sorted(library.getElementNames())
for modname in sorted(modules.keys()): for modname in sorted(modules.keys()):
if not modname in curmods: if modname not in curmods:
library.insertByName(modname, modules[modname]) library.insertByName(modname, modules[modname])
print >> sys.stderr, "Module " + modname + " added." print >> sys.stderr, "Module " + modname + " added."
elif modules[modname] != library.getByName(modname).encode("utf-8"): elif modules[modname] != library.getByName(modname):
library.replaceByName(modname, modules[modname]) library.replaceByName(modname, modules[modname])
print >> sys.stderr, "Module " + modname + " updated." print >> sys.stderr, "Module " + modname + " updated."
for modname in curmods: for modname in curmods:
if not modules.has_key(modname): if modname not in modules:
library.removeByName(modname) library.removeByName(modname)
print >> sys.stderr, "Module " + modname + " removed." print >> sys.stderr, "Module " + modname + " removed."
if libraries.isModified(): if libraries.isModified():
libraries.storeLibraries() libraries.storeLibraries()
return return
class OpenOffice: class OpenOffice:
"""The OpenOffice connection.""" """ The OpenOffice connection. """
def __init__(self): def __init__(self):
"""Initializes the object.""" """Initializes the object."""
@ -185,7 +218,8 @@ class OpenOffice:
url_resolver = local_service_manager.createInstanceWithContext( url_resolver = local_service_manager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", local_context) "com.sun.star.bridge.UnoUrlResolver", local_context)
# Obtains the context # Obtains the context
url = "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" url = ("uno:socket,host=localhost,port=2002;"
"urp;StarOffice.ComponentContext")
while True: while True:
try: try:
self.bootstrap_context = url_resolver.resolve(url) self.bootstrap_context = url_resolver.resolve(url)
@ -207,7 +241,7 @@ class OpenOffice:
ooexec = os.path.join(os.path.dirname(uno.__file__), "soffice.exe") ooexec = os.path.join(os.path.dirname(uno.__file__), "soffice.exe")
DETACHED_PROCESS = 0x00000008 DETACHED_PROCESS = 0x00000008
Popen([ooexec, "-accept=socket,host=localhost,port=2002;urp;"], Popen([ooexec, "-accept=socket,host=localhost,port=2002;urp;"],
close_fds=True, creationflags=DETACHED_PROCESS) close_fds=True, creationflags=DETACHED_PROCESS)
time.sleep(2) time.sleep(2)
return return
@ -223,11 +257,12 @@ class OpenOffice:
os.setsid() os.setsid()
ooexec = os.path.join(os.path.dirname(uno.__file__), "soffice.bin") ooexec = os.path.join(os.path.dirname(uno.__file__), "soffice.bin")
try: try:
os.execl(ooexec, ooexec, os.execl(
ooexec, ooexec,
"-accept=socket,host=localhost,port=2002;urp;") "-accept=socket,host=localhost,port=2002;urp;")
except OSError: except OSError:
sys.stderr.write(ooexec sys.stderr.write(
+ ": Failed to run the OpenOffice server.\n") ooexec + ": Failed to run the OpenOffice server.\n")
sys.exit(1) sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":