Win32com interfacing with Reflection Desktop - python

I run a number of python scripts and programs to aggregate and edit data in Attachmate Extra. My company was on an old version of Attachmate Extra until recently. I'm testing the new version (Reflection Desktop v. 16.2) and my scripts no longer work. I built them with the aid of the helpful advice on this link. I would like to be able to control (scrape, write, etc) screens on the new version.
Here's where I currently am. Running this code creates the a new window:
system = win32com.client.Dispatch("ReflectionIBM.Session")
system.Visible = True
...but then from there I cannot do any of the commands I previously used. Running this, for example
system.MoveCursor(11, 65)
creates a new tab in the emulator that doesn't connect to a session.
I've looked all around the Reflection documentation for an answer. This page led me to believe the old session method is no longer necessary but I'm not sure. I think I'm wrapping the correct object, and the documentation says that legacy commands still work, but I haven't figured out how to link them.
For reference, here are the lines I was using previously to connect to Attachmate:
system = win32com.client.Dispatch("EXTRA.System")
sess0 = system.ActiveSession
Screen = sess0.Screen
Any help is appreciated. I've been scouring the win32com browser for a list commands and looking through the registry to find available classes but I don't know what to look for. Thank you!
EDIT:
I previously used a couple of functions to read, write, and move the cursor around within Attachmate. Example:
def write(screen,row,col,text):
screen.row = row
screen.col = col
screen.SendKeys(text)
write(screen, 10, 65, "test")
Is there a way to get this working again in Reflection?

I still do not know why this works the way it does. In VBA the GetObject method works on "Reflection Workspace" but in python that did not produce any usable attributes that I could find. For python, to get the active session object I had to use EXTRA.System:
from win32com.client.gencache import EnsureDispatch
screen = EnsureDispatch("EXTRA.System").ActiveSession.Screen
From there the code seems generally the same as VBA with
screen.GetString(row, col, len)
screen.PutString(data, row, col)
screen.SendKeys('<PF1>')
for interacting with the host.
After more documentation reading and more trial and error I solved it. "EXTRA.System" is kept for legacy reasons so technically will still work. However, to connect to an active session of Reflection this worked:
system = win32com.client.GetObject('Reflection Workspace')
then to get the active view:
screen = system.GetObject("Frame").SelectedView.Control.Screen
or a specific numbered view:
screen = system.GetObject("Frame").view(1).Control.Screen
The code for interacting with Reflection also has changed and now looks like:
screen.GetText(row, col, len)
screen.PutText2(data, row, col)
screen.SendControlKey(ControlKeyCode)
The documentation for ControlKeyCode does not seem to provide the codes for the control keys. However, you can find the definitions in the Visual Basic Object Browser that comes with Reflection. In Reflection, on the macros tab, click Visual Basic, then press F2 and search for ControlKeyCode. A list of them should show up. For example, mine shows ControlKey_F1=10.
screen.SendKeys("N")
can still be used to send individual key strokes such as the N key but SendControlKey seems to have replaced the command keys such as Enter, Page Up, and the Function keys.

Have launched python package py_reflection in this regards,
How to start:
Install the package via pip:
py -m pip install py_reflection
Run the package (Run the commands below in terminal):
python
>>>from py_reflection import app
>>>app.run()
Api Endpoint and their description: ** All of the endpoints have a common parameter view_idx(integer, optional). Use this parameter to toggle between session in emulator.
/send_keys: Use this endpoint to press keys in the emulator. Parameters to pass: text(string), x(integer), y(integer)
/get_text: Use this endpoint to get text from a specific coordinate. Parameters to pass: x(integer), y(integer)
/press_key: Use this endpoint to press special control keys: Parameters to pass: control_key(string all in caps). Available control keys: 'F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12','F13','F14','F15','F16','F17','F18','F19','TAB','DELETE','LEFT','DOWN','UP','RIGHT','PAGEUP','PAGEDOWN','CLEAR','END','ENTER'
/get_text_coordinates: Use this endpoint to get coordinates of text present in emulator screen. Parameters to pass: text(string), total_row_count(integer, optional), total_column_count(integer, optional)
/check_text_present: Use this endpoint to check if given text present in emulator screen. Parameters to pass: text(string), total_row_count(integer, optional), total_column_count(integer, optional)
/move_cursor: Use this endpoint to move cursor to specified coordinate. Parameters to pass: x(integer), y(integer)
/get_view_count: Use this endpoint to get number of sessions opened in emulator.
More info at pypi.org

Related

Python script is unable find registry keys value in HKEY_LOCAL_MACHINE

I am continuously facing a problem that my python script is not working on (HKLM: HKEY_LOCAL_MACHINE), i have written a small script in python to search windows registry key values. when i perform searching through CMD it shows the key value that i want, i also noticed that my script works properly on older windows registry vales entries in HKLM but for the new ones it doesn't shows anything.
That's my script written in python to check windows registry values.
from winreg import *
key_to_read = input("Enter Path:") #Path: Software\AbcKey
key = input("HKLM or HKCU:") #Hive Name: HKLM\HKCU
if key == 'HKLM':
a = -2147483646
else:
a = -2147483647
try:
aReg = ConnectRegistry(None, a)
k = OpenKey(aReg, key_to_read)
print("Registry key value found.")
except:
print("Nothing found on the given path.")
If you need to write keys and values to HKLM hive, then you either have to use a completely different language other than Python, or you have to use some other API other than "winreg", as winreg has a major defect that severely limits what you can do in the Registry, that most other languages have no problem with.
It just fails to make them. It also throws a WinError 5, "access denied", but that is misleading and will only lead you down a dark alley. You can even configure your account not only as local admin, but full-on "god mode", elevating your account further to system level access, run as part of the operating system, etc., and still no love.
IF it is "permissions", then it is solely in the calls internally to winreg, and / or security flag options that must be passed in -- NOT your actual account permissions or any special environment configuration settings. However, I have tried every combination (winreg.REG_WRITE / winreg.WIN_ALL_ACCESS / winreg.WIN64, etc), but nothing works when pointed to HKLM hive. Writing to HKCU is just fine. Meanwhile, I can manually modify Registy settings in HKLM, or do it with C# and .NET Framework classes, OR C# with dark, unmanaged C# with direct access to Win32 (advapi32.dll), no problem.
I guess Microsoft just happens to be more friendly with their own languages :)

Changing Windows Registry to Change Mouse Pointer with Python Not Updating Mouse Pointer

I am making a simple program that changes the mouse pointer in Windows to a custom .cur image using Python (yes I know you can easily do this via Control Panel but I am using this as a learning tool).
Here is the sample code I used to re-write the registry (will fix wildcard import in final version):
from winreg import *
k = OpenKey(HKEY_CURRENT_USER, 'Control Panel\Cursors',0, KEY_ALL_ACCESS)
SetValueEx(k, 'Arrow',0, REG_SZ, '%SYSTEMROOT%\\Cursors\\rick_serious.cur')
At this point, the registry updates successfully. However, the mouse pointer does not get updated.
After extensive googling, I found this article that explains you need to call a function to "update" the cursor:
link
However, I'm lost as to how to use the SystemParametersInfo function in Python. I came across pypiwin32. However, when I go to the documentation and search for SystemParametersInfo, there is no "SPI_SETCURSORS" action available (as explained in that article).
Is there another way to SPI_SETCURSORS?
If it's possible to do it with this library and I'm not seeing it, could you provide an example as I find this documentation hard to read.
I know the 3 lines of code above don't look like much but several hours of research went into it. Thank you in advance.
I found a way using ctypes. The following line of code updates the cursor which is what you do after setting the registry. The parameters were obtained from Microsoft's website:
import ctypes
ctypes.windll.user32.SystemParametersInfoA(0x0057, 0, None, 0)

Python in Filemaker Pro

I was hoping to calculate fields using some rather complicated functions, which I don't think I can realistically write in filemaker.
I would prefer to write a script to extract data into python, perform some procedures and then import it back into filemaker (so a user can see the results "live" in layouts, without having to leave filemaker).
Is this possible in Filemaker Pro?
That python module is meant to work with FileMaker server: send GET/POST requests, get back response in XML, and parse it. Technically you can use it to do a lot (add and delete records, run scripts, etc.) but in your case it won't fit.
There are some plug-ins that can execute shell commands, so this way you can call Python from a command line. Other than that you cannot do this.
But in some time (a few months) there will be a FileMaker plug-in with embedded Python :)
I have a FileMaker plug-in called bBox that executes Python code. Mac OS X only, but a free download at http://beezwax.net/bbox.
It has these Python related functions:
bBox_PythonCompile ( mode; script )
bBox_PythonExecute ( mode )
bBox_PythonFinalize
bBox_PythonGetVar ( name {; asType) }
bBox_PythonSetVar ( name; value {; asType} )
A few parts are admittedly still a bit rough. The types that the GetVar and SetVar functions can work with are limited, for example. But the code has been out for a while with only a few reported issues, all since fixed.
I've worked with a couple solutions that used pyFilemaker with good results. It isn't getting much attention these days. On the other hand, there haven't been many external changes to FileMaker's XML interface either.
You may want to checkout PyFileMaker (python object wrapper for FM.) It enables you to access/edit FileMaker server database.

MongoDB: how to get db.stats() from API

I'm trying to get results of db.stats() mongo shell command in my python code (for monitoring purposes).
But unlike for example serverStatus I can't do db.command('stats'). I was not able to find any API equivalent in mongodb docs. I've also tried variations with db.$cmd but none of that worked.
So,
Small question: how can I get results of db.stats() (number of connections/objects, size of data & indexes, etc) in my python code?
Bigger question: can anyone explain why some of shell commands are easily accessible from API, while others are not? It's very annoying: some admin-related tools are accessible via db.$cmd.sys, some via db.command, some via ...? Is there some standard or explanation of this situation?
PS: mongodb 2.0.2, pymongo 2.1.0, python 2.7
The Javascript shell's stats command helper actually invokes a command named dbstats, which you can run from PyMongo using the Database.command method. The easiest way to find out what command a shell helper will run is to invoke the shell helper without parentheses -- this will print out the Javascript code it runs:
> db.stats
function (scale) {
return this.runCommand({dbstats:1, scale:scale});
}
As for why some commands have helpers and others do not, it's largely a question of preference, time, and perceived frequency of use by the driver authors. You can run any command by name with Database.command, which is just a convenience wrapper around db.$cmd.find_one. You can find a full list of commands at List of Database Commands. You can also submit a patch against PyMongo to add a helper method for commands you find that you need to invoke frequently but aren't supported by PyMongo yet.

Writing/Reading arrays of Data in Open Office using Python. Anyone have any example code?

So I have written a class that makes it extremely easy to interface with either Excel or Gnumeric using Python, and would like to extend the class to include Open Office as well. I could do this in 30 minutes if I just had the ability to do the following:
Set a single value on an arbitrary
sheet and workbook
Get a single value
on an arbitrary sheet and workbook
If these are slow/there is a way to do the following, I also need to be able to:
set/get an array '''
set/get a matrix '''
ALSO, the ability to create and rename sheets would be great.
This is a shoutout if anyone has worked on this before. If they give me the information, I will reference them at the top of the file
My project can be found here: https://sourceforge.net/projects/pyworkbooks/ and I encourage you to check it out.
As a matter of fact, to acess OpenOffice or LibreOffice via Python one has to go through an absolutely opaque amount of boiler plate inherited from the StarOffice times - never properly documented (one feels) or simplified since then.
I had once lectured on this subject, and I took almot 40 minutes, just to retrieve the parts of my lecture to set up the example bellow.
On the other hand it just worked with the latest LibreOffice version - 3.3 - I am confident it works for OpenOffice as well (but I would not advice anyone to stick to OpenOffice, it is an Oracle dead end at this point)
The example bellow use the slow method of connecting to a running LibreOffice instance from the "outside". This is extremely slow - you will have to refer to the documentation on how to make it work as a macro from "within" the program, for better performance. (it is really slow in this way).
However, this method allows you to explore the methods available to developers using a Python terminal and introspection.
The first poorly documented part is that you have to start Open/LibreOffice with:
soffice "-accept=socket,host=0,port=2002;urp;"
For connections to be accepted. Then, create a new spreadsheet through its interface
and with the python interpreter that comes with the Office Suite run the following code
(either interactively or as a script):
import uno
import socket # only needed on win32-OOo3.0.0
# get the uno component context from the PyUNO runtime
localContext = uno.getComponentContext()
# create the UnoUrlResolver
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext )
# connect to the running office
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
# get the central desktop object
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
# access the current writer document
model = desktop.getCurrentComponent()
try:
sheets = model.getSheets()
except Exception:
raise TypeError("Model retrived was not a spreadsheet")
sheet1 = getattr(sheets, sheets.ElementNames[0])
# At this point, you can use "dir" to check the methods and
# attributes available for the sheet
# the methots "getCellByPosition, to retrieve a cell object,
# which has "getFormula" and "setFormula"
# methods.
for i in xrange(10):
for j in xrange(10):
cell = sheet1.getCellByPosition(i, j)
cell.setFormula(str(i * j))
c1 = sheet1.getCellByPosition(1,1)
As you can see, the connecting part of this is boilerplate I got somewhere else years ago, and I doubt any living person could find any rationale in such stuff.
Once you get down to the "sheets" object, though, the attributes and methods on the object start to make sense.
There is a complete developer manual online, that even could allow one to understand the connection part:
http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide
The inter-process API for connecting to LibreOffice (and also OpenOffice and StarOffice) is called UNO. It is documented at the LibreOffice API documentation site.
As jsbueno says, it expects that a daemon is running to communicate with. The command-line arguments to the ‘soffice’ command starting the daemon determine what host and port values you need to supply in your UNO calls.
You could also try ezodf This was the best python odf library I found
You can use pyoo. Here is my answer to similar question https://stackoverflow.com/a/27082610/886607

Categories