def setCookiesFromUrl(self, cookieList, url): # logger.debug('?set cookies for %s' % url) _url = url.toString() # discard cookies unless url matches one of: # /displayauth, /conductor, /slides.json, # /display_ctrl.json, /screen.manifest if not re.search( r'/displayauth|/conductor|/slides\.json|/display_ctrl\.json|/screen\.manifest', _url): # logger.debug("nay") return False # cookies accepted # logger.debug("ay") try: cookies_to_store = [] for cookie in cookieList: # do not store session cookies if not cookie.isSessionCookie(): cookies_to_store.append(cookie.toRawForm().__str__()) # logger.debug(_url +" : "+ ", ".join(cookies_to_store)) # save to file f = open(self.cookiejar_file,'w') f.write("\n".join(cookies_to_store)) f.close() logger.debug('stored %d cookie(s) from "%s"' % ( len(cookies_to_store), _url)) # publish cookies to Qt self.setAllCookies(cookieList) except Exception, e: logger.error(e) return False
def refresh(self): """Refresh the webView and update cache. The refresh signal will kill the running process, which hopefully will be restored by a background daemon in production environment. The refresh signal will not activate if the process has been alive less than 10 minutes. This is the time frame in which the JavaScript display control will send this signal for a given timer. The offline cache will not cleared. For the JavaScript and other assets to be updated, the manifest revision needs to be updated. First attempted to do soft reload, by self.page().triggerAction(QtWebKit.QWebPage.ReloadAndBypassCache, True) ..but the newly loaded pages were not cached anymore. Perhaps this would work by calling window.applicationCache.update() followed by window.applicationCache.swapCache() ? """ time_alive = time() - self.startup_time if time_alive > 600: # if process has been up for more than 10 minutes, kill pid self.forceRefresh() else: logger.debug("ignoring refresh signal - booted less than 10 minutes ago")
def get_token(self, hostname): """Reads authentication key and calculates token.""" try: keyfile = settings.AUTHKEY_FILE f = open(keyfile, 'r') key = f.read().strip() f.close() token = hostname+":"+hashlib.sha1(hostname+":"+key).hexdigest() return token except Exception, e: # suppress warning to debug level, as this feature is not yet used logger.debug("Failed to read authentication key: " + str(e)) return None
def get_token(self, hostname): """Reads authentication key and calculates token.""" try: keyfile = settings.AUTHKEY_FILE f = open(keyfile, 'r') key = f.read().strip() f.close() token = hostname + ":" + hashlib.sha1(hostname + ":" + key).hexdigest() return token except Exception, e: # suppress warning to debug level, as this feature is not yet used logger.debug("Failed to read authentication key: " + str(e)) return None
def _runscript(self, scriptname): """Execute a shell script """ logger.debug("executing script %s" % scriptname) try: p = Popen(scriptname, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate() if len(stdout) > 0: logger.debug(stdout) if len(stderr) > 0: # it is quite annoying to get the xset usage # constantly flooding the debug log #logger.error(stderr) logger.warn(stderr[0:36]) except Exception, e: logger.error(e)
def __init__(self, page, **kwargs): QtCore.QObject.__init__(self) self.page = page self.hostname = kwargs.get('hostname') # add the proxy object "display" to window self.page.mainFrame().addToJavaScriptWindowObject("display", self) # set the kiosk hostname self.page.mainFrame().evaluateJavaScript( """ if (window.displayCtrl) { window.displayCtrl.hostname = "%s"; } else { // waiting for server-side components to make it to master //console.log("no window.displayCtrl"); } """ % self.hostname) self.powerOn() logger.debug("Initialised Display %s" % self.hostname)
def javaScriptConsoleMessage(self, message, lineNumber, sourceID): """Catches JavaScript console messages and errors from a QWebPage. Differentiates between normal messages and errors by matching 'Error' in the string. """ msg_tmpl = '(%s:%i)\n%s' % (sourceID, lineNumber, '%s') # strip Warning, Info match = re.search('Info: (.*)',message) if match: logger.info(msg_tmpl % match.group(1)) return match = re.search('Warning: (.*)',message) if match: logger.warn(msg_tmpl % match.group(1)) return match = re.search('Error|Exception',message) if match: logger.error(msg_tmpl % message) return logger.debug(msg_tmpl % message)
def javaScriptConsoleMessage(self, message, lineNumber, sourceID): """Catches JavaScript console messages and errors from a QWebPage. Differentiates between normal messages and errors by matching 'Error' in the string. """ msg_tmpl = '(%s:%i)\n%s' % (sourceID, lineNumber, '%s') # strip Warning, Info match = re.search('Info: (.*)', message) if match: logger.info(msg_tmpl % match.group(1)) return match = re.search('Warning: (.*)', message) if match: logger.warn(msg_tmpl % match.group(1)) return match = re.search('Error|Exception', message) if match: logger.error(msg_tmpl % message) return logger.debug(msg_tmpl % message)
def __init__(self, centralwidget, **kwargs): """MainWebView loads the page, and attaches interfaces to it. Keyword arguments: - url - hostname - use_repl NOTE: all QWebSettings must be set before setUrl() is called! """ QtWebKit.QWebView.__init__(self, centralwidget) self.setObjectName("webView0") # store keyword arguments to options self.options = kwargs use_repl = self.options.get('use_repl') # if IIVARI_CACHE_PATH is None, caching is disabled cache_path = __builtin__.IIVARI_CACHE_PATH # set custom WebPage to log JavaScript messages self.setPage(MainWebPage()) # initialize REPL here to attach to console log early if use_repl is True: self.repl = Repl(page=self.page()) # get token for network request authentication hostname = self.options.get('hostname') token = self.get_token(hostname) # set custom NetworkAccessManager for cookie management and network error logging self.page().setNetworkAccessManager(MainNetworkAccessManager(token=token)) # attach a Display object to JavaScript window.display after page has loaded self.page().loadFinished[bool].connect(self.create_display) # use QWebSettings for this webView qsettings = self.settings() #qsettings = QWebSettings.globalSettings() # enable Javascript qsettings.setAttribute(QWebSettings.JavascriptEnabled, True) """ Enable application to work in offline mode. Use HTML5 cache manifest for static content, and jquery.offline for dynamic JSON content. @see http://diveintohtml5.info/offline.html """ if cache_path is not None: qsettings.enablePersistentStorage(cache_path) # uncertain whether LocalContentCanAccessRemoteUrls is needed even when using offline cache # FIXME: check, and disable this if unneeded. qsettings.setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True) #qsettings.setAttribute( # QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) # write qsettings to log logger.debug("\n * ".join([ ' --- QWebSettings ---', 'OfflineWebApplicationCache: %s' % ( qsettings.testAttribute( QWebSettings.OfflineWebApplicationCacheEnabled)), 'LocalStorage: %s' % ( qsettings.testAttribute( QWebSettings.LocalStorageEnabled)), 'offlineWebApplicationCachePath: %s' % ( qsettings.offlineWebApplicationCachePath()), 'offlineWebApplicationCacheQuota: %i' % ( qsettings.offlineWebApplicationCacheQuota()), 'LocalContentCanAccessRemoteUrls: %s' % ( qsettings.testAttribute( QWebSettings.LocalContentCanAccessRemoteUrls)), ])) # set URL and launch the request url = self.options.get('url') logger.info("url: %s" % url) self.setUrl(QtCore.QUrl(url))
def stop(self): logger.debug("exiting REPL") self.detach() self._stopped = True self.exit() # exit QThread
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ from PySide import QtCore from logging import getLogger, StreamHandler, DEBUG import iivari.logger logger = getLogger(__name__) try: import readline except: logger.debug("no readline support") pass class Repl(QtCore.QThread): """READ - EVAL - PRINT - LOOP JavaScript console. JavaScript is halted while waiting for input from user. """ page = None console = None # StreamHandler _stopped = True def __init__(self, page): QtCore.QThread.__init__(self) self.page = page
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ from PySide import QtCore from logging import getLogger, StreamHandler, DEBUG import iivari.logger logger = getLogger(__name__) try: import readline except: logger.debug("no readline support") pass class Repl(QtCore.QThread): """READ - EVAL - PRINT - LOOP JavaScript console. JavaScript is halted while waiting for input from user. """ page = None console = None # StreamHandler _stopped = True def __init__(self, page): QtCore.QThread.__init__(self) self.page = page
def __init__(self, centralwidget, **kwargs): """MainWebView loads the page, and attaches interfaces to it. Keyword arguments: - url - hostname - use_repl NOTE: all QWebSettings must be set before setUrl() is called! """ QtWebKit.QWebView.__init__(self, centralwidget) self.setObjectName("webView0") # store keyword arguments to options self.options = kwargs use_repl = self.options.get('use_repl') # if IIVARI_CACHE_PATH is None, caching is disabled cache_path = __builtin__.IIVARI_CACHE_PATH # set custom WebPage to log JavaScript messages self.setPage(MainWebPage()) # initialize REPL here to attach to console log early if use_repl is True: self.repl = Repl(page=self.page()) # get token for network request authentication hostname = self.options.get('hostname') token = self.get_token(hostname) # set custom NetworkAccessManager for cookie management and network error logging self.page().setNetworkAccessManager( MainNetworkAccessManager(token=token)) # attach a Display object to JavaScript window.display after page has loaded self.page().loadFinished[bool].connect(self.create_display) # use QWebSettings for this webView qsettings = self.settings() #qsettings = QWebSettings.globalSettings() # enable Javascript qsettings.setAttribute(QWebSettings.JavascriptEnabled, True) """ Enable application to work in offline mode. Use HTML5 cache manifest for static content, and jquery.offline for dynamic JSON content. @see http://diveintohtml5.info/offline.html """ if cache_path is not None: qsettings.enablePersistentStorage(cache_path) # uncertain whether LocalContentCanAccessRemoteUrls is needed even when using offline cache # FIXME: check, and disable this if unneeded. qsettings.setAttribute( QWebSettings.LocalContentCanAccessRemoteUrls, True) #qsettings.setAttribute( # QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) # write qsettings to log logger.debug("\n * ".join([ ' --- QWebSettings ---', 'OfflineWebApplicationCache: %s' % (qsettings.testAttribute( QWebSettings.OfflineWebApplicationCacheEnabled)), 'LocalStorage: %s' % (qsettings.testAttribute(QWebSettings.LocalStorageEnabled)), 'offlineWebApplicationCachePath: %s' % (qsettings.offlineWebApplicationCachePath()), 'offlineWebApplicationCacheQuota: %i' % (qsettings.offlineWebApplicationCacheQuota()), 'LocalContentCanAccessRemoteUrls: %s' % (qsettings.testAttribute( QWebSettings.LocalContentCanAccessRemoteUrls)), ])) # set URL and launch the request url = self.options.get('url') logger.info("url: %s" % url) self.setUrl(QtCore.QUrl(url))