How to automate with python software sessions with assigned unique dynamic parameter? - python

I've tried to automate UCL Enchance tasks, but after selection of file from list each consecutive session has unique dynamic parameter for any task. I programmed using SWAPY32bit.exe tool for pywinauto. How to automate software with unique parameters for any task?
UCL Enhance Home Page - UCL Phonetics and Linguistics
www.phon.ucl.ac.uk/resource/sfs/enhance.php
from pywinauto.application import Application
from pywinauto.timings import Timings
import time
app = Application().Start(cmd_line=u'"C:\\Program Files\\SFS\\Enhance\\enhance.exe"')
afxbd = app[u'Untitled - UCLEnhance']
afxbd.Wait('ready')
time.sleep(3)
menu_item = afxbd.MenuItem(u'&File->&1 File.wav')
menu_item.Select()
time.sleep(3)
app = Application().Start(cmd_line=u'"C:\\Program Files\\SFS\\Enhance\\enhance.exe"')
afxbd = app[u'File.wav - UCLEnhance']
menu_item = afxbd.MenuItem(u'&File->&Save Original &As...\tCtrl+S')
menu_item.Select()

The following code should work for you (tested on pywinauto 0.6.0):
from pywinauto.application import Application
import time
app = Application().Start(cmd_line=u'"C:\\Program Files\\SFS\\Enhance\\enhance.exe"')
main_window = app[u'Untitled - UCLEnhance']
main_window.wait('ready')
# further actions can be done in a loop for every input file
main_window.menu_select('&File->Open...')
app.OpenDialog.Edit.set_text(ur'C:\Program Files\SFS\Enhance\six.wav')
app.OpenDialog.Open.click_input()
app.OpenDialog.wait_not('visible')
main_window = app.window(title_re='.* - UCLEnhance')
main_window.wait('ready')
# time.sleep(...) might be necessary here
main_window.Toolbar.press_button(11) # 'Enhance' button
# WM_CHECK is handled incorrectly so use WM_CLICK to check the option
app.Enhancement.SpeechLevelRadioButton.check_by_click()
app.Enhancement.OK.click()
app.Enhancement.OK.wait_not('visible')
Hope it helps.
P.S. SWAPY is useful for simple scenarios, but more complicated cases require reading documentation and some experience in desktop GUI automation (this is really not easy sometimes). Feel free to ask more questions.
P.P.S. Very similar and more readable code using backend='uia' (MS UI Automation technology):
from pywinauto.application import Application
app = Application(backend='uia').start(cmd_line=u'"C:\\Program Files\\SFS\\Enhance\\enhance.exe"')
main_window = app[u'Untitled - UCLEnhance']
main_window.wait('ready')
main_window.menu_select('&File->Open...')
main_window.OpenDialog.Edit.type_keys(ur'C:\Program Files\SFS\Enhance\six.wav{ENTER}', with_spaces=True)
main_window.OpenDialog.wait_not('visible')
main_window = app.window(title_re='.* - UCLEnhance')
main_window.wait('ready')
main_window.Toolbar.Enhance.click()
main_window.Enhancement.SpeechLevelRadioButton.invoke()
main_window.Enhancement.OK.click()
main_window.Enhancement.OK.wait_not('visible')

Related

pywinauto - how to right-click in systemtray, select an item then subitem

I have an application in the hidden part of the systray in Windows 10. I am trying to connect to the application, right-click on it, and then select something like "About". I understand that once I have the target application, I need to connect to the application, which I do in line 25 of the code, but I cannot get further from there.
This is the code I have so far:
from pywinauto import Application
import time
app = Application(backend="uia").connect(path="explorer.exe")
systemTray = app.window(class_name="Shell_TrayWnd")
systemTray.child_window(title="Notification Chevron").click_input(button="left")
#systemTray.print_control_identifiers()
time.sleep(0.25)
list_box = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
list_box_win = list_box.window(class_name="NotifyIconOverflowWindow")
list_box_win.wait('visible', timeout=30, retry_interval=3)
# List all the icons in the systray
for notification_area in list_box_win.children():
for app_in_tray in notification_area.children():
print(str(app_in_tray))
target_app = list_box_win.child_window(title="TrayStatus Pro Trial 4.6\r\nCaps Lock: Off")
target_app.wait('visible', timeout=30, retry_interval=3)
target_app.click_input(button="right")
target_app.target_app.print_control_identifiers()
target_app.dump_tree()
sysapp = Application().connect(path='TrayStatus.exe')
sysapp.menu_select('About') #This part fails
Application() class represents the application and sometime it fails to identify the window. Having said that, you have not mentioned the backend of the application at the beginning you have used UIA backend so figure out for the line sysapp = Application().connect(path='TrayStatus.exe') as well and add, Also adding timeout=10 parameter to the connect() works many times.
Still if the above option doesn't not work for you then try using Desktop class.
again you can mention backend of your choice and compatibility, there is no such way to identify backend of application.
window2 = Desktop(backend="win32").window(title='title of the rayStatus.exe window')
you will need to import -
from pywinauto import Desktop.
Finally you can print the titile of windows using
list_window = Desktop().windows()
for window in list_window:
window.window_texts() # this should print the all open window names on desktop

How to connect to the running windwows application with pywinauto?

I'm having a problem connecting to a running window application that was opened in the browser via citrix links. I have a snippet of the window name here.
How can I find out if pywinauto can see the running window of the application?
Which code do I need for this?
My code doesn't work:
import pywinauto
from pywinauto.application import Application
app = Application(backend='uia').connect(title = 'Applikationsmenü - Produktivsystem der
LogSys-Applikation für XY')
Use process Id, see sample code
from pywinauto import application
from pywinauto.application import Application
# add your exe name here; you can get via Task Manager
yourExeName = ""
# get PID of your running process
pid = application.process_from_module(module = yourExeName)
# use Pid to connect
app = Application(backend='uia').connect(process = pid)

Selenium Webdriver Chrome creating to many Threads

i'm having some trouble about this WallBoard webapp (Python) that i have to fix, i hope i can be very clear of what the problem is so its easy for you to understand and help me.
So, the app has 3 pages, Main Page, Calls Waiting, Tickets. It is used by support team in this company to track calls of the day and tickets too.
So when i run this app with VS Code, its behavior is absolutely normal. App logs to another website to retrieve calls information, and Database to retrieve Tickets information. After some time session expires (retrieving calls information) but app detects and logs in again.
When i start the app at IIS(8.5) EVERY 17min the app gets restarted for no reason, and after a few hours of this i have 40 to 50 Google Chrome Threads taking all my memory from the machine it is hosted in...
I don't believe it is a problem with IIS, i think it is responding like this for some reason and i can't find out.
Here is the code for the WallBoard App
from datetime import datetime
from flask import Flask, g, render_template
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import pypyodbc as pyodbc
import time
import sys, socket
from funcs import *
from config import *
from querys import *
from cachetools import LRUCache
from apscheduler.schedulers.background import BackgroundScheduler
# Init
app = Flask(__name__)
app.debug = True
# Globals
CALLS_WAITING_CACHE = LRUCache(maxsize=20)
TICKETS_CACHE = LRUCache(maxsize=20)
op = Options()
op.binary_location = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
op.add_argument("--headless")
op.add_argument("--disable-gpu")
browser = webdriver.Chrome(chrome_options=op, executable_path=r'C:\Python34\Scripts\chromedriver.exe')
with open('log.txt', 'a') as f:
print('Walboard Starting! - ' + str(datetime.now()), file=f)
def login():
# Here i log in to the website where i get calls information
###################################################################
#app.before_request
def before_request():
"""Before Request"""
g.request_start_time = time.time()
g.request_time = lambda: "%.5f" % (time.time() - g.request_start_time)
####################################################################
#app.route('/')
def index():
"""Landing Page"""
return render_template("landing.html",
dashboard_name='TSU WallBoard',
css_folder='/static/css/',
CallsWaiting_Page='/callswaiting',
Tickets_Page='/tickets'
)
####################################################################
def calls_waiting():
# Here i take the information and store in in cache thanks to cachetools
############################################################################
#app.route('/callswaiting')
def calls_wainting_render():
# Here i take information from cache and show it in the webpage of the app
####################################################################
def tickets():
# Here i do the same with tickets, load from DB and store in cache
#app.route('/tickets')
def tickets_render():
# Here i load tickets from cache and show them in Web Page
##########################################################
# Login to avaya website
login()
time.sleep(3)
# Get calls and store in cache
calls_waiting()
# Get tickets and store in cache
tickets()
# Create scheduler obj
sched = BackgroundScheduler(daemon=True)
# Create Jobs
sched.add_job(calls_waiting, 'interval', seconds=refresh_time_calls,
max_instances=1, id='calls_waiting')
sched.add_job(tickets, 'interval', seconds=refresh_time_tickets,
max_instances=1, id='tickets')
# Start scheduler
sched.start()
with open('log.txt', 'a') as f:
print('WallBoard Started! - ' + str(datetime.now()), file=f)
if __name__ == "__main__":
app.run()
So at this point i'm completely lost, i have done hours of research trying to find what the problem is but still no luck.
I took out the code inside because it was too big but if necessary i can provide it.
I was using PhantomJS but i was always getting the Warning that is deprecated and i decided to change do ChromeDrive but the problem still remains.
Can it be with BackgroundScheduler? because i'm starting to think that each time IIS force the app to restart, it creates more Jobs and doesn't kill the others.
I appreciate all the help and tips, and i am really sorry for this long post!
I took this screenShot after 10min of running, i will update with new one in the morning

Pywebview blocks flask app unless I open two webviews

I built a python desktop webapp with a fairly simple flask backend which I'm currently serving simply through Chrome. I'm trying to package it using pywebview, but I ran into an intestesting roadblock.
I have code that looks like this in the main file of my package:
import os
import sys
from flasher import app
import httplib
import webview
import threading
def start_prod_server():
runserver(debug=False, reloader=False)
def start_gui():
webview.create_window("MyAppName", "http://localhost:5000", height=1000)
def runserver(debug=True, reloader=False):
port = int(os.environ.get('PORT', 5000))
url = "http://localhost:{}".format(port)
print("ready!")
app.run(host='::', port=port, debug=debug, use_reloader=reloader)
if __name__ == '__main__':
t = threading.Thread(target=start_prod_server)
t.daemon = True
t.start()
# This never works
threading.Timer(1.5, start_gui).start()
sys.exit()
This fails almost systematically, the window shows up blank and the backend doesn't respond to anything (including requests from a separate desktop browser).
I discovered accidentally that if I start two webview threads, it always works:
if __name__ == '__main__':
t = threading.Thread(target=start_prod_server)
t.daemon = True
t.start()
# This works every time
threading.Timer(1.5, start_gui).start()
threading.Timer(1.5, start_gui).start()
sys.exit()
What could be causing this? My understanding of threading in Python is fairly limited, so I'm not sure where to look. Is this likely to be a bug in pywebview, or am I doing something wrong with my threads?
I'm also open to suggestions of alternatives for the webview part, but I want to keep the python/flask part since the app already works fine as it is.
Well, after a bit of digging, I think I found the solution myself.
For whatever reason, webview.create_window() wasn't navigating to the page and getting stuck. Opening up the second window was causing both windows to navigate to the url and allowing the app to continue. (I still haven't understood why)
The problem is solved simply by adding webview.load_url("http://localhost:5000") like so:
if __name__ == '__main__':
t = threading.Thread(target=start_prod_server)
t.daemon = True
t.start()
threading.Timer(1.5, start_gui).start()
webview.load_url("http://localhost:5000")
sys.exit()
Any insight as to why this happens is still welcome though... In the source for pywebview, the two methods are making the exact same call to self.browser.web_browser.Navigate(url)

xmms2 track change detection for pynotify?

I have written this little script to show current track playing on xmms2 on a notification widget using xmms client and pynotify, so when i run it i can see the widget popup with current artist and title using xmmsclient methods.
Can anybody give some hints about how to detect track change to notify automatically without having to run the script manually?
You connect the client library to a main loop, and register as a listener via the broadcast_ playback_current_id method. If you want the currently playing id when the script starts as well you can call the playback_current_id method.
Here is a small adaptation of tutorial6 in the xmms2-tutorial.git which uses the GLib Mainloop to drive the connection:
import xmmsclient
import xmmsclient.glib
import os
import sys
import gobject
def cb(result):
if not result.is_error():
print "Current: %(artist)s - %(title)s" % result.value()
ml = gobject.MainLoop(None, False)
xc = xmmsclient.XMMS("stackoverflow")
xc.connect()
conn = xmmsclient.glib.GLibConnector(xc)
xc.broadcast_playback_current_id(lambda r: xc.medialib_get_info(r.value(), cb))
ml.run()

Categories