I'm trying to develop a simple digital signage system with raspberry-pi computer. What I'm actually trying to do is open a web page (which carrying information to be displayed) in full screen mode and refresh this page at certain interval of time. I came across some web view codes in python using "gtk" and "webkit" I managed to open a url in full screen mode, but I dont know how to use reload function as per my needs. Please help me.
Besides the two ways that are already described using a cron job (not an elegant way) or using javascript, it is also possible to schedule the reload in the python script.
from gi.repository import Gtk, GLib
from gi.repository import WebKit2
class ReloadView:
def __init__(self):
window = Gtk.Window()
window.connect('delete-event',Gtk.main_quit)
self.view = WebKit2.WebView()
self.view.load_uri('http://example.net')
GLib.timeout_add_seconds(5, self.reload) #every 5 seconds
window.add(self.view)
window.fullscreen()
window.show_all()
def reload(self):
self.view.reload()
#self.view.reload_bypass_cache() for complete reload
return True
if __name__ == "__main__":
ReloadView()
Gtk.main()
Please check out this resource that seems to have some valid solutions for your problem: https://raspberrypi.stackexchange.com/questions/6981/auto-refresh-for-midori
These scheduled actions are usually handled by cron jobs, but there is nothing preventing you from writing your own simple action scheduler.
edit: alternatively if you control the website itself, you could set the website itself to refresh with a certain interval. The ways to do this are described here: How to reload page every 5 second?
Related
I'm working with PyQt (as a Python beginner).
I need to be able to take screenshots of a website on a headless system.
I was using PhantomJS earlier for another project, but they dropped Flash support in 1.5 and I don't want to rely on a deprecated 1.4 version for my new project.
So I'm using PyQt to do my stuff on my own.
I'm able to take a screenshot of a website with a given url, no problem.
But I keep having the "blue dice" flash plugin icon on flash placeholder (yes, javascript and plugins are activated)
self.settings.setAttribute(QtWebKit.QWebSettings.PluginsEnabled,True)
self.settings.setAttribute(QtWebKit.QWebSettings.JavascriptEnabled,True)
I'm making some test on a Youtube video page, here is an example of my issues:
The second part, that may be related to the first one:
How can I tell PyQt to wait few seconds before taking the screenshot ?
As you can see on the example, images on the right are still unloaded, because they are loaded using javascript and data attribute and in my script, I take the screenshot on the loadFinished signal (onLoad() javascript equivalent)).
My first guess was simply to
time.sleep(2)
Before calling my capture method, but it's not working. I'm assuming that the Webkit loading is also asleep during this sleep time, preventing anything to load on the page.
I tried to create a custom signal, but then I still don't know how to trigger it without sleeping.
My last guess is that I need to thread my application. Am I right?
If you have any hint/script to help me displaying flash content and/or to add a setTimeout like signal, I would be really grateful!
Thanks in advance for you help.
EDIT:
Just a quick edit to add my solution:
timeoutTimer = QTimer()
timeoutTimer.setInterval(3000) # wait for 3secs
timeoutTimer.setSingleShot(True)
timeoutTimer.timeout.connect(theMethodToCallOnTimeout)
About the flash thing: it looks like the flash player is broken on OSX (maybe related to a 32/64 bits issue).
If you time.sleep you are freezing the whole application, instead, you can use a QTimer, QEventLoop, QThread, etc. Here is the PyQt4 version:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
class browser(QWebView):
def __init__(self, parent=None):
super(browser, self).__init__(parent)
self.timerScreen = QTimer()
self.timerScreen.setInterval(2000)
self.timerScreen.setSingleShot(True)
self.timerScreen.timeout.connect(self.takeScreenshot)
self.loadFinished.connect(self.timerScreen.start)
self.load(QUrl("http://www.google.com/ncr"))
def takeScreenshot(self):
image = QImage(self.page().mainFrame().contentsSize(), QImage.Format_ARGB32)
painter = QPainter(image)
self.page().mainFrame().render(painter)
painter.end()
image.save(self.title() + ".png")
sys.exit()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = browser()
app.exec_()
I recommend using selenium. It is made for doing web automation, screenshots, and testing. Because it uses firefox it is very easy to have full flash support. It can also be run in a headless mode. The code below works at taking a screenshot of a web page with flash like the youtube video you had. You can see the screenshot it took below. A few things to keep in mind. selenium has a save_screenshot method which you can see is commented out in the code. I didn't use it because it wasn't taking proper screenshot of flash components, you can correct this by using the technique in Taking screenshot of flash object using Selenium with Webdriver. I chose though to just take a screenshot of the screen using the imagemagic import command. This is a screenshot tool that works in Linux. You can check out Take a screenshot via a python script. [Linux] and Get screenshot on Windows with Python? for other approaches of taking screenshots.
code
import time, selenium.webdriver, subprocess
browser = selenium.webdriver.Firefox()
browser.get('http://www.youtube.com/watch?v=bFEoMO0pc7k')
time.sleep(6)
#browser.save_screenshot('test.png')
subprocess.check_output('import -window root screen.png', shell=True)
browser.quit()
screenshot
Hey everyone I'm having a hard time automating a specific application. Using pywinauto I want to automate clicking, keypresses, etc. to login and benchmark this application but for some reason I can't find any control identifiers for this application. Am I doing something wrong? I used this same method with task manager and other applications and this works fine.
Important Documentation:
Code Example
Class Doc
Code:
import pywinauto
app = pywinauto.application.Application()
window_handle = pywinauto.findwindows.find_windows(title = u'Name of application')
#print window_handle #makes sure to see if handle exists
window = app.window_(handle = window_handle[0])
print window.Children() #first approach
print app.top_window_()._ctrl_identifiers() #second approach
Output:
>>>[]
>>>{}
Has this happened to anyone before and has found a way around it? Should I just resort to using pywin32 instead? Thank you!
Turns out the application does have control identifiers I just needed to get past the first screen. Using window.TypeKeys("{TAB}{TAB}{ENTER}") I was able to navigate past the home screen with keypresses and into the actual application which had all the identifiers.
Useful Links if anyone encounters this problem.
What is a control Identifier?
I'm on OSX using Python 2.x, Selenium & Firefox
I'm automating testing a javascript webapp with Python & Selenium.
One of the links (Add File) in the application opens up a non-browser firefox window titled "File Upload" which looks like (/is?) a Finder window.
Is there a way that I could locate and control this window from my python script? I know Selenium can't do it, but I wondering if it might be possible with something like 'import applescript' and if so how?
I found atomac which allows me to control mac apps through their accessibility controls (which needed to be enabled on Mavericks for Aptana in System Preferences -> Security & Privacy -> Privacy -> Accessibility). Cool tool, but the documentation is pretty sparse. The examples provided on the page above got me to the point where I could close the window via the cancel button, but I had to review the function definitions in atomac's AXClasses.py to figure out the rest. Here's the solution.
import atomac, time
from atomac.AXKeyCodeConstants import *
# to allow me to make firefox frontmost while testing
time.sleep(5)
# get a reference to the running app
firefox = atomac.getAppRefByLocalizedName('Firefox')
# get the window of the reference
firefoxwindow = firefox.windowsR()[0]
# send key sequence to go to my home folder
firefoxwindow.sendKeyWithModifiers('h',[COMMAND,SHIFT])
# send key sequence to select first file there
firefoxwindow.sendKeyWithModifiers('a',[COMMAND])
# press the now active Open button
openbutton = firefoxwindow.buttons('Open')[0]
openbutton.Press()
It's theoretically possible, but really awkward. I'll give you a bunch of links--not ideal, I know, but you could write a book on this.
You'd need to start by enabling AppleScript control of the GUI. Then you'll want to read up on how to control the GUI from within Applescript. However, you wanted to use Python and not AppleScript, so then you'll need to install PyObjC, which is a Python to Cocoa bridge. You'd need to use the Scripting Bridge framework and figure out (from the extremely thin documentation) how to translate the AppleScript docs to Python.
I am currently using the Python Webkit DOM Bindings to interact with a website programmatically and that's working for me.
The only problem is that it insists on opening a GTK window to display the page. Has somebody figured out a way to prevent it from opening a window? I.e. to use it in a headless way?
I'm initializing the view like this:
wv = pywebkitgtk.WebView(1024, 768, url=url)
which implicitly opens the GTK window and then I have an onload event-handler to manipulate the DOM.
I first thought of subclassing WebView, but that's not possible because it is a compiled class.
Any other ideas?
I'm the developer responsible for pythonwebkit, and I have a great deal of expertise covering these areas across several platforms. Realistically, you really, really want a completely "headless" WebKit port. In pythonwebkit that actually shouldn't be too hard to do, as there are only three "entry point" functions (one for window, one for document, and one for XMLHTTPRequest).
Really, somebody should do a proper "completely headless" port of WebKit. There already is an example program which is pretty close in WebKit's source tree, maybe that will get you started.
I've been using PyQT. PyQTWebView runs on Webkit and works great. Check out Ghost.py to get started, or use PyQT's API directly. Runs fully headless, and supports a decently recent build of Webkit.
You could try using Xvfb. I like using the command line and setting my display manually, but if you don't like that you could use this: http://cgoldberg.github.io/xvfbwrapper/
Can you get a handle to the GTK window and then call window.hide()? Otherwise, you might just have to use the full Webkit library.
Create a window and add the webview there, and never show the window..
I have webviews running without showing them, and can call a show_all if I need to show them.
web_view = pywebkitgtk.WebView()
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
sw = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
sw.add(web_view)
window.add(sw)
#window.show_all()
I have created a service which display a sort of splash screen on the desktop of a specific user and only when that user is logged in (kiosk user).
That splash screen, once entered a valid code, will tell that to the service and the service goes to sleep for an x amount of time (depending of the code).
The splash screen simply quits. Now when the service wakes up it sees that the splash is no longer there and so start it up.
This all is working, the only problem is that the launched application does not have focus, i.e. if I am working in notepad and the time is up, the splash screen is displayed (full screen though) behind notepad.
I only have to worry about Windows Vista, I am coding in Python using win32 extensions but I believe this problem lies in CreateProcessAsUser when called from the LocalSystem account.
Update:
The 'problem' is actually an on purpose limitation to prevent 'irritating' applications like mine from stealing focus.
You can change the behaviour by setting:
win32gui.SystemParametersInfo(win32con.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0)
which is equivalent in temporarily setting the registry value:
HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundLockTimeout
This must be done as the user itself, so either build it in the app you are launching or build an launching helper for the app you want to launch.
However an application might want to prevent getting it's focus stolen by using some API call which I don't remember right now.
A probably good solution would be to find all window handles currently from that user and then use each of these handles to use win32gui.ShowWindow(handle, command) to minimize it.
Although for this particular problem setting the locktimeout setting was enough.
If anyone wonders how I managed to launch an application to a desktop from a service, here is a link to the code.
Have you tried launching another processes than your own from the service to see if it gets focus? Like notepad and see if it steals focus from your browser? If so perhaps its the program that can take back the focus when it starts.
I otherwise beilive it's the wShowWindow attribute from the STARTUPINFO struct the lpStartupInfo points to that should control it. You also need STARTF_USESHOWWINDOW in dwFlags to use nShowWindow. The values should be SW_SHOW i think, they are listed for the ShowWindow function if you want to try other.
For various very legitimated reasons, Microsoft would rather not see a service launching an app and stealing focus, however I found the following work around to still accomplish what I want.
The original intend is to have a kiosk like application hindered by a pass code like splash screen, which upon entering a 8 character code closes the splash screen for a period time as in the pass code defined. Originally the actual application to use was started by the autostart folder.
However I now rewrote it that it is launched from my service, this way I can hide the application by launching an helper application from the service that just hides the program and launches the splash screen, upon exiting the splash screen the program is returned to the previous state.