strip qtnetwork in favour of urllib as it handles proxies better

This commit is contained in:
Damien Elmes 2009-06-25 06:29:38 +09:00
parent 7ee6032b81
commit 4d624d286b
4 changed files with 83 additions and 161 deletions

View file

@ -4,8 +4,8 @@
from PyQt4.QtGui import * from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
from PyQt4.QtNetwork import *
import ankiqt, simplejson, time, cStringIO, zipfile, tempfile, os, re import ankiqt, simplejson, time, cStringIO, zipfile, tempfile, os, re
import traceback, urllib2
from ankiqt.ui.utils import saveGeom, restoreGeom, showInfo from ankiqt.ui.utils import saveGeom, restoreGeom, showInfo
from anki.utils import fmtTimeSpan from anki.utils import fmtTimeSpan
@ -47,53 +47,16 @@ class GetShared(QDialog):
self.limit) self.limit)
def fetchData(self): def fetchData(self):
h = QHttp(self) try:
h.connect(h, SIGNAL("requestFinished(int,bool)"), self.onReqFin) sock = urllib2.urlopen(
h.connect(h, SIGNAL("proxyAuthenticationRequired(QNetworkProxy," "http://anki.ichi2.net/file/search?t=%d" % self.type)
"QAuthenticator*)"), self.allList = simplejson.loads(unicode(sock.read()))
self.onProxyAuth) except:
h.setHost("anki.ichi2.net") showInfo(_("Unable to connect to server.\n\n") +
#h.setHost("localhost", 8001) traceback.format_exc())
self.conId = h.get("/file/search?t=%d" % self.type)
self.http = h
self.parent.setProgressParent(self)
self.parent.startProgress()
def onProxyAuth(self, proxy, auth):
auth.setUser(self.parent.config['proxyUser'])
auth.setPassword(self.parent.config['proxyPass'])
def onReqFin(self, id, err):
"List fetched."
if id != self.conId:
return
self.parent.finishProgress()
self.parent.setProgressParent(None)
self.form.search.setFocus()
if err:
errorString = self.http.errorString()
else:
# double check ... make sure http status code was valid
# this is to counter bugs in handling proxy responses
respHeader = self.http.lastResponse()
if respHeader.isValid():
statusCode = respHeader.statusCode()
if statusCode < 200 or statusCode >= 300:
err = True
errorString = respHeader.reasonPhrase()
else:
err = True
errorString = "Invalid HTTP header received!"
if err:
if self.parent.config['proxyHost']:
errorString += "\n" + _("Please check the proxy settings.")
showInfo(_("Unable to connect to server.") + "\n" +
errorString, parent=self)
self.close() self.close()
return return
data = self.http.readAll() self.form.search.setFocus()
self.allList = simplejson.loads(unicode(data))
self.typeChanged() self.typeChanged()
self.limit() self.limit()
@ -186,83 +149,80 @@ class GetShared(QDialog):
if self.type == 0: if self.type == 0:
if not self.parent.saveAndClose(hideWelcome=True, parent=self): if not self.parent.saveAndClose(hideWelcome=True, parent=self):
return QDialog.accept(self) return QDialog.accept(self)
h = QHttp(self) (fd, tmpname) = tempfile.mkstemp(prefix="anki")
h.connect(h, SIGNAL("requestFinished(int,bool)"), self.onReqFin2) tmpfile = os.fdopen(fd, "w+b")
h.connect(h, SIGNAL("dataReadProgress(int,int)"), self.dataRead) cnt = 0
h.connect(h, SIGNAL("proxyAuthenticationRequired(QNetworkProxy,"
"QAuthenticator*)"),
self.onProxyAuth)
h.setHost("anki.ichi2.net")
#h.setHost("localhost", 8001)
self.conId = h.get("/file/get?id=%d" % self.curRow[R_ID])
self.http = h
self.parent.setProgressParent(self)
self.parent.startProgress()
def dataRead(self, done, total):
self.parent.updateProgress(label=_("Downloaded %dKB") %
(done/1024),
process=False)
def onReqFin2(self, id, err):
"File fetched."
if id != self.conId:
return
try: try:
self.parent.finishProgress() self.parent.setProgressParent(self)
self.parent.setProgressParent(None) self.parent.startProgress()
if err: try:
showInfo(_("Unable to connect to server.") + "\n" + sock = urllib2.urlopen(
self.http.errorString(), parent=self) "http://anki.ichi2.net/file/get?id=%d" %
self.curRow[R_ID])
while 1:
data = sock.read(65536)
if not data:
break
cnt += len(data)
tmpfile.write(data)
self.parent.updateProgress(
label=_("Downloaded %dKB") % (cnt/1024.0))
except:
showInfo(_("Unable to connect to server.\n\n") +
traceback.format_exc())
self.close() self.close()
return return
data = self.http.readAll()
ext = os.path.splitext(self.curRow[R_FNAME])[1]
if ext == ".zip":
f = cStringIO.StringIO()
f.write(data)
z = zipfile.ZipFile(f)
else:
z = None
tit = self.curRow[R_TITLE]
tit = re.sub("[^][A-Za-z0-9 ()\-]", "", tit)
tit = tit[0:40]
if self.type == 0:
# deck
dd = self.parent.documentDir
p = os.path.join(dd, tit + ".anki")
if os.path.exists(p):
tit += "%d" % time.time()
for l in z.namelist():
if l == "shared.anki":
dpath = os.path.join(dd, tit + ".anki")
open(dpath, "wb").write(z.read(l))
elif l.startswith("shared.media/"):
try:
os.mkdir(os.path.join(dd, tit + ".media"))
except OSError:
pass
open(os.path.join(dd, tit + ".media",
os.path.basename(l)),"wb").write(z.read(l))
self.parent.loadDeck(dpath)
else:
pd = self.parent.pluginsFolder()
if z:
for l in z.infolist():
if not l.file_size:
continue
try:
os.makedirs(os.path.join(
pd, os.path.dirname(l.filename)))
except OSError:
pass
open(os.path.join(pd, l.filename), "wb").\
write(z.read(l.filename))
else:
open(os.path.join(pd, tit + ext), "wb").write(data)
showInfo(_("Plugin downloaded. Please restart Anki."),
parent=self)
return
finally: finally:
self.parent.setProgressParent(None)
self.parent.finishProgress()
QDialog.accept(self) QDialog.accept(self)
# file is fetched
tmpfile.seek(0)
self.handleFile(tmpfile)
QDialog.accept(self)
def handleFile(self, file):
ext = os.path.splitext(self.curRow[R_FNAME])[1]
if ext == ".zip":
z = zipfile.ZipFile(file)
else:
z = None
tit = self.curRow[R_TITLE]
tit = re.sub("[^][A-Za-z0-9 ()\-]", "", tit)
tit = tit[0:40]
if self.type == 0:
# deck
dd = self.parent.documentDir
p = os.path.join(dd, tit + ".anki")
if os.path.exists(p):
tit += "%d" % time.time()
for l in z.namelist():
if l == "shared.anki":
dpath = os.path.join(dd, tit + ".anki")
open(dpath, "wb").write(z.read(l))
elif l.startswith("shared.media/"):
try:
os.mkdir(os.path.join(dd, tit + ".media"))
except OSError:
pass
open(os.path.join(dd, tit + ".media",
os.path.basename(l)),"wb").write(z.read(l))
self.parent.loadDeck(dpath)
else:
pd = self.parent.pluginsFolder()
if z:
for l in z.infolist():
if not l.file_size:
continue
try:
os.makedirs(os.path.join(
pd, os.path.dirname(l.filename)))
except OSError:
pass
open(os.path.join(pd, l.filename), "wb").\
write(z.read(l.filename))
else:
open(os.path.join(pd, tit + ext), "wb").write(file.read())
showInfo(_("Plugin downloaded. Please restart Anki."),
parent=self)

View file

@ -2763,46 +2763,8 @@ Consider backing up your media directory first."""))
########################################################################## ##########################################################################
def setupProxy(self): def setupProxy(self):
from PyQt4.QtNetwork import QNetworkProxy, QNetworkProxyFactory, QNetworkProxyQuery
class MyQNetworkProxyFactory(QNetworkProxyFactory):
def __init__(self, host, port, user, password):
QNetworkProxyFactory.__init__(self)
self.host=host
self.port=port
self.user=user
self.password=password
def makeProxy(self, proxyType):
proxy = QNetworkProxy()
proxy.setType(proxyType)
proxy.setHostName(self.host)
proxy.setPort(self.port)
if self.user:
proxy.setUser(self.user)
proxy.setPassword(self.password)
return proxy
def queryProxy(self, proxyQuery):
proxyList = []
if self.host:
proxyList.append(self.makeProxy(QNetworkProxy.HttpProxy))
proxyList.append(self.makeProxy(QNetworkProxy.HttpCachingProxy))
proxyList += QNetworkProxyFactory.systemProxyForQuery(proxyQuery)
return proxyList
import urllib2 import urllib2
if self.config['proxyHost']: if self.config['proxyHost']:
# qt
QNetworkProxyFactory.setApplicationProxyFactory(
MyQNetworkProxyFactory(
self.config['proxyHost'],
self.config['proxyPort'],
self.config['proxyUser'],
self.config['proxyPass']
)
)
# python
proxy = "http://" proxy = "http://"
if self.config['proxyUser']: if self.config['proxyUser']:
proxy += (self.config['proxyUser'] + ":" + proxy += (self.config['proxyUser'] + ":" +

View file

@ -34,7 +34,7 @@
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>1</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
@ -54,7 +54,7 @@
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>3</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="frameShape"> <property name="frameShape">

View file

@ -63,7 +63,7 @@ OPTIONS = {
'iconfile': 'ankiqt/mac/anki.icns', 'iconfile': 'ankiqt/mac/anki.icns',
"includes": ["sip", "cgi", "encodings", "encodings.utf_8", "includes": ["sip", "cgi", "encodings", "encodings.utf_8",
"encodings.shift_jis", "_multibytecodec", "encodings.shift_jis", "_multibytecodec",
"PyQt4.QtNetwork", "platform"], "platform"],
'packages': ["sqlalchemy", "pysqlite2", "simplejson"], 'packages': ["sqlalchemy", "pysqlite2", "simplejson"],
'excludes': ['_gtkagg', '_tkagg', "_wxagg", 'excludes': ['_gtkagg', '_tkagg', "_wxagg",
"wx", "_wx", "wx", "_wx",