Как сохранить экземпляр python qtwebkit работающим и постоянным?

Мне нужно, чтобы мой скрипт Python QtWebKit продолжал работать и прослушивал дальнейшие команды. Прямо сейчас, если пользователь подключается и отправляет команду на сервер, сценарий на стороне сервера просто запускается и завершается после завершения.

Например, если пользователь вводит URL-адрес для перехода, QtWebKit извлекает URL-адрес и отображает его. В какой-то момент в будущем они могут захотеть отправить команду входа и просмотреть скриншот этой страницы. Сценарий запускается, переходит по URL-адресу и входит в систему, а также делает снимок экрана этой страницы.

Есть ли способ сохранить сценарий для прослушивания будущих команд без необходимости начинать с самого начала?

Что ожидается: пользователь отправляет команду на сервер, QtWebKit загружает URL-адрес и остается открытым. Пользователь отправляет команду для входа в систему и создания снимка экрана, а QtWebKit входит в систему и делает снимок экрана без перезапуска сценария.

Особый случай здесь заключается в том, что пользователь не знает заранее точную последовательность команд, которые он хочет выполнить. Таким образом, пользователь не может написать по буквам от А до Я и запустить сценарий сразу.


person bkbkbk    schedule 19.09.2012    source источник


Ответы (1)


Я использовал Twisted для настройки простого сервера xmlrpc в качестве бэкэнда, он постоянный и имеет задачу создавать новые экземпляры браузеров webkit на основе PyQt/PySide, если это необходимо, или повторно использовать существующие. Отдельное внешнее веб-приложение, которое является «посредником» между пользователем и внутренним приложением, отправляет команды на скрученный сервер xmlrpc вместе с session_id, по которому скрученный сервер может искать, есть ли у session_id уже запущенный браузер, или необходимо создать новый экземпляр. Вот простой пример:

# -*- coding: utf-8 -*-
from pyvirtualdisplay import Display
display = Display(visible=False, size=(1024, 768), color_depth=24)
display.start()

from PySide.QtGui import QApplication
app = QApplication([])
import qt4reactor
qt4reactor.install()

from twisted.web import server
from twisted.web.xmlrpc import XMLRPC
from twisted.internet import defer
from PySide.QtWebKit import QWebView, QWebPage
from PySide.QtNetwork import QNetworkAccessManager, QNetworkRequest
from PySide.QtCore import QUrl, QByteArray


class Browser(object):

    def __init__(self):
        self.network_manager = QNetworkAccessManager()

        self.web_page = QWebPage()
        self.web_page.setNetworkAccessManager(self.network_manager)

        self.web_view = QWebView()
        self.web_view.setPage(self.web_page)
        self.web_view.loadFinished.connect(self._load_finished)

    def _load_finished(self, ok):
        # the page is loaded
        frame = self.web_view.page().mainFrame()
        self.deferred_request.callback(frame.toHtml())

    def _make_request(self, url):
        request = QNetworkRequest()
        request.setUrl(QUrl(url))
        return request

    def perform(self, request_data):
        # say request_data is a dict having keys: 'url', 'post_data'
        self.deferred_request = defer.Deferred()
        request = self._make_request(request_data['url'])
        self.web_view.load(request)

        return self.deferred_request


class TestXMLRPCServer(XMLRPC):

    def __init__(self):
        XMLRPC.__init__(self, allowNone=True)
        self.browser_instances = dict()

    def xmlrpc_open(self, request_data, session_id):
        print session_id, request_data
        try:
            browser = self.browser_instances[session_id]
            print 'using existing instance'
        except KeyError:
            browser = Browser()
            self.browser_instances[session_id] = browser
            print 'new instance created'

        return browser.perform(request_data)


def start_server(port=1234):
    from twisted.internet import reactor
    r = TestXMLRPCServer()
    reactor.listenTCP(port, server.Site(r))
    reactor.run()


if __name__ == '__main__':
    start_server()

И клиент просто для проверки работоспособности:

# -*- coding: utf-8 -*-
import xmlrpclib

def test_server(port=1234):
    s = xmlrpclib.Server('http://localhost:{0}/'.format(port))
    session_id = 'a1b2c3d4e5f6'
    html = s.open({'url': 'http://www.google.com'}, session_id)
    print unicode(html).encode('utf-8')
    html = s.open({'url': 'http://www.ubuntu.com'}, session_id)
    print unicode(html).encode('utf-8')

    session_id = 'f6e5d4c3b2a1'
    html = s.open({'url': 'http://www.yahoo.com'}, session_id)
    print unicode(html).encode('utf-8')

if __name__ == '__main__':
    test_server()
person andrean    schedule 20.09.2012
comment
Андреан, ты все еще активен на SO? Я хотел поговорить с вами об этом коде, который вы опубликовали. - person KJW; 04.12.2012
comment
конечно, я могу быть в сети после 18:00 по Гринвичу + 1, когда я возвращаюсь домой с работы. - person andrean; 04.12.2012