diff --git a/picard/browser/browser.py b/picard/browser/browser.py index aa87d9d17..032a84b55 100644 --- a/picard/browser/browser.py +++ b/picard/browser/browser.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # # Picard, the next-generation MusicBrainz tagger -# Copyright (C) 2004 Robert Kaye -# Copyright (C) 2006 Lukáš Lalinský +# Copyright (C) 2007 Lukáš Lalinský # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -18,95 +17,42 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -from PyQt4 import QtCore -import BaseHTTPServer -import httplib -import socket -import urllib +from PyQt4 import QtCore, QtNetwork -class TaggerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): +class BrowserIntegration(QtNetwork.QTcpServer): + """Simple HTTP server for web browser integration.""" - def __init__(self,conn,addr,server): - BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, conn, addr, server) + def __init__(self, parent=None): + QtNetwork.QTcpServer.__init__(self, parent) + self.connect(self, QtCore.SIGNAL("newConnection()"), self.accept_connection) - def do_POST(self): - self.send_error(405, "POST not supported") - - def do_HEAD(self): - self.send_error(405, "HEAD not supported") - - def do_GET(self): - action, args = urllib.splitquery(self.path) - parsed_args = dict(arg.split("=") for arg in args.split('&')) - if action.startswith("/"): - action = action[1:] - self.server.integration.action(action, parsed_args) - self.send_response(200) - self.send_header("Content-Type", "text/plain; charset=utf-8") - self.end_headers() - self.wfile.write( - '
' - 'Nothing to see here!') - - def do_QUIT(self): - self.server.integration.exit_thread = True - self.send_response(200) - self.end_headers() - - def log_message(self, format, *args): - pass - - -class TaggerServer(BaseHTTPServer.HTTPServer): - - allow_reuse_address = False - - def __init__(self, integration, addr, handlerClass): - BaseHTTPServer.HTTPServer.__init__(self, addr, handlerClass) - self.integration = integration - - -class BrowserIntegration(QtCore.QThread): - - def __init__(self): - QtCore.QThread.__init__(self) - self.exit_thread = False - def start(self): - self.log.debug("Starting the browser integration") - QtCore.QThread.start(self) - + self.port = 8000 + while self.port < 65535: + self.log.debug("Starting the browser integration (port %d)", self.port) + if self.listen(QtNetwork.QHostAddress(QtNetwork.QHostAddress.Any), self.port): + break + def stop(self): self.log.debug("Stopping the browser integration") - if self.isRunning(): - if self.server: - conn = httplib.HTTPConnection( - "%s:%d" % self.server.server_address) - conn.request("QUIT", "/") - conn.getresponse() - self.wait() + self.close() - def action(self, action, args): - self.log.debug( - "Browser integration event: action=%r, args=%r", action, args) - if action == "init": - self.emit(QtCore.SIGNAL("init(int)"), args) - elif action == "openalbum": - self.tagger.thread_assist.proxy_to_main( - self.tagger.load_album, args["id"]) - else: - self.log.warning("Unknown browser integration event %r", action) + def process_request(self): + conn = self.sender() + line = str(conn.readLine()) + conn.write("HTTP/1.x 200 OK\r\nCache-Control: max-age=0\r\n\r\nNothing to see here.") + conn.disconnectFromHost() + line = line.split() + self.log.debug("Browser integration request: %r", line) + if line[0] == "GET": + action, args = line[1].split("?") + args = dict(a.split("=") for a in args.split("&")) + if action == "/openalbum": + self.tagger.load_album(args["id"]) + else: + self.log.error("Unknown browser integration request: %r", action) - def run(self): - self.port = 8056 - self.server = None - while not self.server: - try: - self.server = TaggerServer( - self, ("127.0.0.1", self.port), TaggerRequestHandler) - except socket.error: - self.port += 1 - self.action("init", self.port) - while not self.exit_thread: - self.server.handle_request() + def accept_connection(self): + conn = self.nextPendingConnection() + self.connect(conn, QtCore.SIGNAL("readyRead()"), self.process_request) diff --git a/picard/tagger.py b/picard/tagger.py index fba96bca1..10587a29b 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -172,8 +172,6 @@ class Tagger(QtGui.QApplication): ] self.saved_icon = QtGui.QIcon(":/images/track-saved.png") - self.browser_integration.start() - def setup_logging(self): """Setup loggers.""" self.log = logging.getLogger() @@ -265,6 +263,7 @@ class Tagger(QtGui.QApplication): self.xmlws.download('ftp.musicbrainz.org', 80, '/pub/musicbrainz/users/luks/picard-qt/version.txt', self._check_version_request_finished) def run(self): + self.browser_integration.start() self.window.show() self.check_version() res = self.exec_()