I'm trying to script my OpenOffice document (Writer in my case) to do some simple things with widgets. Namely I'd like to copy text from widget to widget. For this I want to get one component and than get text from it.
I've been trying to do sth like this:
document = ThisComponent.CurrentController.Frame
oDocument = ThisComponent
oTextBoxFrom = document.getByName("Text Box 1") # 1
oTextBoxFrom = oDocument.getByName("Text Box 1") # 2
Neither version #1 nor #2 work. VB compiler spits out that "Text Box 1" is not accessible, however I have that component in my form. My guess is that I'm trying to get this component from a wrong place, eg. not it's frame. I just can't figure out what is the structure of the document.
This seems like a pretty easy task, however I'm unable to find any OpenOffice specification as for accessing OO UNO objects from VB, or python.
Good day.
if you choose use a VB, you must know this:
VBA : Compatibility between OpenOffice.org Basic and VBA relates to
the OpenOffice.org Basic language as well as the runtime library. The
OpenOffice.org API and the Dialog Editor are not compatible with VBA
(standardizing these interfaces would have made many of the concepts
provided in OpenOffice.org impossible).
if it will be python:
OpenOffice.org 3.1 ships with the Python scripting language, version
2.6.1. Older OpenOffice.org ships with Python version 2.3.4. This Python distribution comes with the Uno module, which connects the UNO
API to the python scripting language. To run this version of Python on
Linux, you can go directly to the OpenOffice.org PATH. And as one
would expect with any distribution of Python, OOo-Python can be run
from the command line as well. If you already have a separate Python
2.6 installation, you can import the uno module (the Python-UNO bridge) to it using these instructions. If you already have a
different version of Python installed on Windows, you can also access
the UNO API using the COM bridge instead of the Python bridge.
Requires the add-on pywin32 module so Python can talk to COM. Note
that while the UNO API is uniform, the implementation by the two
bridges is slightly different, so the syntax required by each is also
sometimes different.
Python UNO bridge
upd: ooobloger might help you with understanding of python and uno integration.
i don't have experience with openoffice scripting but i found thes examples, note they never use getByName on the document itself but always on some part of it.
docCalc = ThisComponent
maFeuille = docCalc.Sheets.getByName("leCSV")
....
for f = 0 to lesFamilles.Count -1' chaque famille
nomFam = lesFamilles.ElementNames(f)
uneFamille = lesFamilles.getByName(nomFam)
...
monDocument.TextTables.hasByName("Finances")
...
lesSections = monDocument.TextSections
sectA = lesSections.getByName("Aline")
you can find the rest in this large pdf at http://oqei.free.fr/echange/VBA/Programmation_OpenOffice_org_3_ed1_v1.pdf ,it's in french but code is universal eh ?
Hope it helps..
Related
I'm developing a tool for a utility group with very high-security standards (for obvious reasons). This tool runs inside ESRI's ArcMap Application (Using the ArcMap API - ArcPy). ArcFM is Software installed on top of ArcMap and is used for utility based analytics (ArcFM has a license separate from ArcMap). The tool I'm developing requires ArcPy (Python) to check-out the ArcFM license using PyWin32 (see snippet below)
#ArcFM licensing
import win32com.client
app = win32com.client.Dispatch("Miner.Framework.Dispatch.MMAppInitializeDispatch")
runtime = win32com.client.Dispatch("Miner.Framework.Dispatch.MMRuntimeEnvironmentDispatch")
app.Initialize(0x5)
#end ArcFm licensing
In order to use some of the ArcFM functionalities within the tool I'm developing, the ArcFM license must first be check-out inside the script.
This snippet checks out the license to ArcFM so I can access ArcFM functions outside of the GUI. The IT Director of the Utility Group has been hesitant to install PyWIN on their machines as he/she is concerned that it will give users too much access to there own computers.
From my understanding, Win32 won't give users "extra" access to their computers (it only allows them to access features through the API). For example, if a user doesn't have rights to access registry-keys, Win32 (or PyWin32) will not bypass any security settings assigned to that user profile.
Do I understand this correctly? Is there anything I missed?
[GitHub]: mhammond/pywin32 - Python for Windows (pywin32) Extensions (emphasis is mine) states:
This is the readme for the Python for Win32 (pywin32) extensions, which provides access to many of the Windows APIs from Python.
So, PyWin32 is a Python wrapper over WINAPIs (it just allows them to be called from Python in a friendly manner). Regardless of it (not) being installed on a Python installation, the WINAPIs are still there and can be accessed from:
C
Python as well (e.g. using [Python 3]: ctypes - A foreign function library for Python), but the code would be much:
Longer (all kinds of conversions are required)
Less readable (lots of "maintenance" code - not related to the business logic)
Error prone
You could check [SO]: Get the title of a window of another program using the process name (#CristiFati's answer) for difference between the 2 approaches (also check (the last part of) [SO]: python win32service - Getting triggered startup information for service (#CristiFati's answer)).
Other languages
Since Pywin32 doesn't have an official doc page, I'll be referencing the next best thing (that I found): [ActiveState.Docs]: PyWin32 Documentation.
Examples:
Since you mentioned registry:
[ActiveState.Docs]: win32api.RegOpenKeyEx wraps [MS.Docs]: RegOpenKeyExW function
But maybe it's not the best example, as registry functions are also available via [Python 3]: winreg - Windows registry access (which is part of Python's standard library)
Another one (that has something to do with security):
[ActiveState.Docs]: win32security.LogonUserEx wraps [MS.Docs]: LogonUserExW function
Bottom line
There are NO additional privileges (rights) granted (by default) by PyWin32.
However I'm trying to find a reason for management's concern towards having PyWin32 installed.
Generally, experts (in the WINAPI area) would most likely know:
C (number of devs is decreasing)
Win internals (not very many here either)
General computer (low level) knowledge
From the 3 above, such users would know what the implications of calling an WINAPI (and if not, they would easily know where / what to search / investigate in order to get answers)
From these users' PoV, it makes no difference. But since PyWin32 modules can be queried for their content:
>>> import win32security
>>>
>>> print([name for name in dir(win32security) if callable(getattr(win32security, name))])
['ACL', 'AcceptSecurityContext', 'AcquireCredentialsHandle', 'AdjustTokenGroups', 'AdjustTokenPrivileges', 'AllocateLocallyUniqueId', 'CheckTokenMembership', 'ConvertSecurityDescriptorToStringSecurityDescriptor', 'ConvertSidToStringSid', 'ConvertStringSecurityDescriptorToSecurityDescriptor', 'ConvertStringSidToSid', 'CreateRestrictedToken', 'CreateWellKnownSid', 'CredHandleType', 'CryptEnumProviders', 'CtxtHandleType', 'DsBind', 'DsCrackNames', 'DsGetDcName', 'DsGetSpn', 'DsListDomainsInSite', 'DsListInfoForServer', 'DsListRoles', 'DsListServersForDomainInSite', 'DsListServersInSite', 'DsListSites', 'DsUnBind', 'DsWriteAccountSpn', 'DuplicateToken', 'DuplicateTokenEx', 'EnumerateSecurityPackages', 'GetBinarySid', 'GetFileSecurity', 'GetKernelObjectSecurity', 'GetNamedSecurityInfo', 'GetPolicyHandle', 'GetSecurityInfo', 'GetTokenInformation', 'GetUserObjectSecurity', 'ImpersonateAnonymousToken', 'ImpersonateLoggedOnUser', 'ImpersonateNamedPipeClient', 'ImpersonateSelf', 'InitializeSecurityContext', 'IsTokenRestricted', 'LogonUser', 'LogonUserEx', 'LookupAccountName', 'LookupAccountSid', 'LookupPrivilegeDisplayName', 'LookupPrivilegeName', 'LookupPrivilegeValue', 'LsaAddAccountRights', 'LsaCallAuthenticationPackage', 'LsaClose', 'LsaConnectUntrusted', 'LsaDeregisterLogonProcess', 'LsaEnumerateAccountRights', 'LsaEnumerateAccountsWithUserRight', 'LsaEnumerateLogonSessions', 'LsaGetLogonSessionData', 'LsaLookupAuthenticationPackage', 'LsaOpenPolicy', 'LsaQueryInformationPolicy', 'LsaRegisterLogonProcess', 'LsaRegisterPolicyChangeNotification', 'LsaRemoveAccountRights', 'LsaRetrievePrivateData', 'LsaSetInformationPolicy', 'LsaStorePrivateData', 'LsaUnregisterPolicyChangeNotification', 'MapGenericMask', 'OpenProcessToken', 'OpenThreadToken', 'PyCredHandleType', 'PyCtxtHandleType', 'PySecBufferDescType', 'PySecBufferType', 'QuerySecurityPackageInfo', 'RevertToSelf', 'SECURITY_ATTRIBUTES', 'SECURITY_DESCRIPTOR', 'SID', 'SecBufferDescType', 'SecBufferType', 'SetFileSecurity', 'SetKernelObjectSecurity', 'SetNamedSecurityInfo', 'SetSecurityInfo', 'SetThreadToken', 'SetTokenInformation', 'SetUserObjectSecurity', 'TranslateName', 'error']
that might get one of the other kind of users, ideas.
So the (arguable: false) concern, is that a great power (including the one of knowledge) is shared with users that might not have the great responsibility required to handle that power. In some cases, that could lead (dramatizing a bit) to disaster (and whether is because of mistake or malintent isn't very relevant).
To draw a parallel with a real life scenario: having a dummy lock on your door (or the wallet in the shoe at the beach):
Will stop ~90%+ of the thieves (the mediocre ones)
Will have no effect against the real masters
Introduction
I recently started working on a legacy product, under Linux, which incorporates a builtin TCL shell. Due to company limitations, I can't gain control to "behind the scenes" and all of the code I can write must be run under this TCL shell, handling the pre-defined clumsy TCL API of the product.
I found myself wondering a few times whether it will be possible to patch some Python into this setup, as some solutions seem more legitimate in Python than in TCL. By patching Python I mean: either calling the Python code from the TCL code itself (which can be done with Elmer, for example), or to use Python from outside of the product to wrap the TCL API (for which I found no "classic" solution).
The Problem
Given that the product already has an existing TCL shell in it, most solutions I browsed through (e.g. Tkinter) can't be used to run the TCL code from Python. I need to "inject" the code to the existing shell.
Solutions Considered
As a solution, I thought about bringing up a simple server on the TCL side which runs simple commands it receives from the Python side. I wrote a small demo and it worked. This enabled me to write a nice, class based, wrapper in Python for the clumsy TCL API, also manage a command queue, etc.
Another two solutions I thought of is forking the software from Python and playing with the read/write file descriptors or connecting through FIFO rather than a socket.
However, I wondered whether I'm actually doing it right or can you suggest a better solution?
Thanks in advance.
First:
If you just want a class based OO system to write your code in, you don't need python, Tcl can do OO just fine. (built in with 8.6, but there are quite a few options to get OO features, classes etc. in older versions too, e.g. Tcllibs SNIT or STOOOP
If you still feel Python is the superior tool for the task at hand (e.g. due to better library support for some tasks), you can 'remote control' the Tcl interpreter using the Tcllib comm package. This needs a working event loop in the Tcl shell you want to control, but otherwise it is pretty simple to do.
In your Tcl shell, install the Tcllib comm package.
(ask again if you need help with that)
Once you have that, start the comm server in your Tcl shell.
package require comm
set id [::comm::comm self]
# write ID to a file
set fd [open idfile.txt w]
puts $fd $id
close $fd
proc stop_server {} {set ::forever 1 }
# enter the event loop
vwait forever
On the python side, you do nearly the same, just in Tkinter code.
Basically like this:
import Tkinter
interp = Tkinter.Tcl()
interp.eval('package require comm')
# load the id
with open('idfile.txt') as fd:
comm_id = fd.read().strip()
result = interp.eval(
'comm::comm send {0!s} {1!s}'.format(comm_id, '{puts "Hello World"}')
Using that python code and your shell, you should see Hello World printed in your shell.
Read the comm manual for more details, how to secure things, get callbacks etc. comm
If you don't like the tkinter burden, you can implement the wire procotol for comm too, should not be too hard in Twisted or with the new async support in Python 3.x.
The on the wire protocol is documented in:
comm wire protocol
I will try to keep this question as tight as possible, but if it seems that I am saying insane things, it is almost certainly because I am ignorant of some key point, so please do correct me.
I am writing a program, in a Windows environment, that will interface with an existing application that has a COM interface to allow 3rd-party software to interact with it.
I have read all of the documentation for this application, and it says that there is a TLB file that defines the functions and data available via COM.
How do I use the TLB file with python? How do I discover the progID of the application so that I can interface with it (this isn't given in the documentation).
I'm pretty lost. I have a fair amount of experience with Python, but I am completely new to developing in a Windows environment. Any help would be enormously helpful. I have been reading all the documentation on win32com, but I still have no clue what to do, as no one addresses -- as far as I have seen -- bringing in a TLB file.
The questions asked is to link the custom TLB file with COM client to be developed in python. I have done a small example code for my COM server developed in C# and same is accessed by python client using "comtypes" package.
The below snippet of code gives:
import comtypes.client as CC
import comtypes
ccHandle = CC.CreateObject("CSharpServer.InterfaceImplementation")
print (ccHandle)
import comtypes.gen.CSharpServer as CS
InterfaceHandle = ccHandle.QueryInterface(CS.IManagedInterface)
print ("output of PrintHi function = ", InterfaceHandle.PrintHi("World"))
The above python script is for the C# COM server code available at http://msdn.microsoft.com/en-us/library/aa645738(v=vs.71).aspx (refer to the File 1: CSharpServer.cs).
OK, it's been a while since I've done this, and I'm not a COM expert by any means. Read the COM chapter from Python Programming on Windows to see how to do this. Follow along with the examples (trying things out against Excel) to get a feel of how things work.
First off, install the PyWin32 Extensions if you haven't already. This is the package that gives you pythonwin.exe and the COM interface modules. Get it from here.
Then you are going to open the "COM Makepy Utility" from PythonWin's Tools menu. Browse through the list of registered COM components (some will be typelibs, others DLLs) until you identify the one you have (you have to do a bit of detective work). Click OK to generate the Python glue code. You will then need to run it again with the -i command-line argmument to generate the boilerplate code so your python script can use this glue. Here's a paraphrase of the O'Reilly example for the Microsoft Excel Object library:
import win32com.client
from win32com.client import gencache
gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 2)
earlyBound = win32com.client.Dispatch("Excel.Application")
lateBound = win32com.client.dynamic.Dispatch("Excel.Application")
print earlyBound.ActiveCell()
Using early-bound objects is optional, but it does improve performance.
To find the ProgID is again a bit of detective work, although this answer seems to imply it's going to be hard. Try poking around the HKEY_CLASSES_ROOT hive of the registry with RegEdit to see if you see a ProgID that looks promising.
I'm trying to extract some version information from a DLL using python. I read this question:
Python windows File Version attribute
It was helpful, but I also need to get the 'Assembly version' from the DLL. It's there when I right click and look on the versions tab, but not sure how I extract this with python.
On this page:
http://timgolden.me.uk/python/win32_how_do_i/get_dll_version.html
Tim Golden says:
You can use the slightly more messy
language-dependent code in the demos
which come with pywin32 to find the
strings in the box beneath it.
Can someone point me to the example that might be useful? I looked in the win32api directories but there's nothing obvious. Would I find a solution there?
If you would rather not introduce a dependency on Python.Net, you can also use the win32 api directly:
from win32api import GetFileVersionInfo, LOWORD, HIWORD
def get_version_number (filename):
info = GetFileVersionInfo (filename, "\\")
ms = info['FileVersionMS']
ls = info['FileVersionLS']
return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls)
Source: http://timgolden.me.uk/python/win32_how_do_i/get_dll_version.html
I'm not sure you can get at this information by using native code. The usual way of obtaining the assembly info is by running .Net code (e.g. C#). So I'm guessing in order to be able to do the same from python you'll need to run some .Net python interpreter. See for example http://pythonnet.github.io/
In Python 2.6, I used matplotlib to make some simple graphs. However, it is incompatible with Python 3.1.
What are some alternative modules that can accomplish the same thing without being very complex?
You say you want to create some simple graphs but haven't really said how simple or what sort of graphs you want. So long as they aren't too complex you might want to consider using the Google Chart API.
e.g.
That has some advantages: you just have to construct a URL that describes the desired chart so there shouldn't be any issues using it from Python 3.x. Of course there are disadvantages also: you need to have an internet connection when generating the chart, and you might not have the chart styles you have been using with matplotlib.
If you don't want to construct the URLs directly there is at least one Python wrapper for the charts API. It doesn't work directly on Python 3.x, but running it through 2to3 seems to convert it successfully.
A stable version supporting Python 3 has since been released: official announcement.
I wrote a small example that runs in python 3 and uses the google chart api (as suggested by Duncan, I wrote the solution after seeing this post).
It is not ideal since it adds a dependency one a 3rd party that might break backward compatibility at any time, but the graphs are nice and there is absolutely no added dependency on the python code. Worth considering for not 'mission critical code'.
You can find/download the example here. Here is the graph that it generates from data in a .xml file:
# build the query with template parameters
query ="http://chart.apis.google.com/chart?chxl=0:__X_LABELS__&chxp=__X_LABELS_POS__&chxr=0,__MIN_TIME__,__MAX_TIME__|1,__MIN_WEIGHT__,__MAX_WEIGHT__&chxs=0,676767,11.5,0,lt,676767|1,676767,11.5,0,lt,676767&chxt=x,y&chs=800x300&cht=lc&chco=3072F3&chds=__MIN_WEIGHT__,__MAX_WEIGHT__&chd=t:__COMMASEP_WEIGHT__&chdl=Weight&chdlp=b&chls=2,4,1&chma=5,5,5,25&chtt=Your+Weight+Timeline"
[...]
# relace template with data
query = query.replace('__X_LABELS__', strXLabels)
query = query.replace('__X_LABELS_POS__', strXLabelsPos)
query = query.replace('__MIN_TIME__', str(min(lst_dateEpoch)))
query = query.replace('__MAX_TIME__', str(max(lst_dateEpoch)))
[...]
# use 'urllib.request' to download the data & write to file
sock = urllib.request.urlopen(query)
image_bytes = sock.read()
sock.close()
fh = open('Weight_GoogleGraphApi.png', 'wb')
fh.write(image_bytes)
fh.close()
Maybe PyQwt? They claim 3.x compatibility. I've only used Qwt (the C++ lib PyQwt is based on) but I found it fairly useful.
rpy2 is providing access to the graphics capabilities of R, and rpy2 is becoming compatible with Python 3 (thanks to the help of Google for funding Greg over the summer).
Code against the current dev branch is in a patch queue.
edit: rpy2 2.2.0 is working with Python 3.2
MathGL (GPL plotting library) have Python interface which work with Python 3 too.
Matplotlib binaries for python 3.x (windows) are avaliable. http://www.lfd.uci.edu/~gohlke/pythonlibs/
As an alternative to installing subversion to grab the source, Numpy's SF files page has the latest copy of 1.5 in a few different (Windows-friendly) formats:
http://sourceforge.net/projects/numpy/files/NumPy/1.5.0b1/
There are at least two graphing libraries using PyQt, namely PyQwt and PyQtGraph. I've been using PyQwt with Python 2.6 for a few weeks now and it is quite handy. The documentation isn't great, and most of the time I need to refer to either the Qwt docs or the examples - although the times I've had to look at the docs have been few and far between, it is VERY easy to use. I tried building it against python 3.1 just now though without success. I coulnd't find the tar package for 5.2.1 which is the only version compatible with python 3.0 and there isn't anything on MacPorts for that either.
There is also a fairly complete looking list of plotting libraries on at python.org http://wiki.python.org/moin/NumericAndScientific/Plotting