mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
refactor addon downloading into separate file
This commit is contained in:
parent
1788cd2fac
commit
7796aaf4d5
2 changed files with 81 additions and 62 deletions
|
@ -14,6 +14,7 @@ import aqt.forms
|
||||||
import aqt
|
import aqt
|
||||||
from anki.sync import httpCon
|
from anki.sync import httpCon
|
||||||
import aqt.sync # monkey-patches httplib2
|
import aqt.sync # monkey-patches httplib2
|
||||||
|
from aqt.downloader import download
|
||||||
|
|
||||||
# in the future, it would be nice to save the addon id and unzippped file list
|
# in the future, it would be nice to save the addon id and unzippped file list
|
||||||
# to the config so that we can clear up all files and check for updates
|
# to the config so that we can clear up all files and check for updates
|
||||||
|
@ -149,68 +150,12 @@ class GetAddons(QDialog):
|
||||||
openLink(aqt.appShared + "addons/")
|
openLink(aqt.appShared + "addons/")
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
try:
|
|
||||||
code = int(self.form.code.text())
|
|
||||||
except ValueError:
|
|
||||||
showWarning(_("Invalid code."))
|
|
||||||
return
|
|
||||||
QDialog.accept(self)
|
QDialog.accept(self)
|
||||||
# create downloader thread
|
# create downloader thread
|
||||||
self.thread = AddonDownloader(code)
|
ret = download(self.mw, self.form.code.text())
|
||||||
self.connect(self.thread, SIGNAL("recv"), self.onRecv)
|
if not ret:
|
||||||
self.recvBytes = 0
|
return
|
||||||
self.thread.start()
|
data, fname = ret
|
||||||
self.mw.progress.start(immediate=True)
|
self.mw.addonManager.install(data, fname)
|
||||||
while not self.thread.isFinished():
|
|
||||||
self.mw.app.processEvents()
|
|
||||||
self.thread.wait(100)
|
|
||||||
if not self.thread.error:
|
|
||||||
# success
|
|
||||||
self.mw.addonManager.install(self.thread.data, self.thread.fname)
|
|
||||||
self.mw.progress.finish()
|
self.mw.progress.finish()
|
||||||
showInfo(_("Download successful. Please restart Anki."))
|
showInfo(_("Download successful. Please restart Anki."))
|
||||||
else:
|
|
||||||
self.mw.progress.finish()
|
|
||||||
showWarning(_("Download failed: %s") % self.thread.error)
|
|
||||||
|
|
||||||
def onRecv(self, total):
|
|
||||||
self.mw.progress.update(label="%dKB downloaded" % (total/1024))
|
|
||||||
|
|
||||||
class AddonDownloader(QThread):
|
|
||||||
|
|
||||||
def __init__(self, code):
|
|
||||||
QThread.__init__(self)
|
|
||||||
self.code = code
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
# setup progress handler
|
|
||||||
self.byteUpdate = time.time()
|
|
||||||
self.recvTotal = 0
|
|
||||||
def canPost():
|
|
||||||
if (time.time() - self.byteUpdate) > 0.1:
|
|
||||||
self.byteUpdate = time.time()
|
|
||||||
return True
|
|
||||||
def recvEvent(bytes):
|
|
||||||
self.recvTotal += bytes
|
|
||||||
if canPost():
|
|
||||||
self.emit(SIGNAL("recv"), self.recvTotal)
|
|
||||||
addHook("httpRecv", recvEvent)
|
|
||||||
con = httpCon()
|
|
||||||
try:
|
|
||||||
resp, cont = con.request(
|
|
||||||
aqt.appShared + "download/%d" % self.code)
|
|
||||||
except Exception, e:
|
|
||||||
self.error = unicode(e[0], "utf8", "ignore")
|
|
||||||
return
|
|
||||||
finally:
|
|
||||||
remHook("httpRecv", recvEvent)
|
|
||||||
if resp['status'] == '200':
|
|
||||||
self.error = None
|
|
||||||
self.fname = re.match("attachment; filename=(.+)",
|
|
||||||
resp['content-disposition']).group(1)
|
|
||||||
self.data = cont
|
|
||||||
elif resp['status'] == '403':
|
|
||||||
self.error = _("Invalid code.")
|
|
||||||
else:
|
|
||||||
self.error = _("Error downloading: %s") % resp['status']
|
|
||||||
|
|
74
aqt/downloader.py
Normal file
74
aqt/downloader.py
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
import time, re
|
||||||
|
from aqt.qt import *
|
||||||
|
from anki.sync import httpCon
|
||||||
|
from aqt.utils import showWarning
|
||||||
|
from anki.hooks import addHook, remHook
|
||||||
|
import aqt.sync # monkey-patches httplib2
|
||||||
|
|
||||||
|
def download(mw, code):
|
||||||
|
"Download addon/deck from AnkiWeb. On success caller must stop progress diag."
|
||||||
|
# check code is valid
|
||||||
|
try:
|
||||||
|
code = int(code)
|
||||||
|
except ValueError:
|
||||||
|
showWarning(_("Invalid code."))
|
||||||
|
return
|
||||||
|
# create downloading thread
|
||||||
|
thread = Downloader(code)
|
||||||
|
def onRecv():
|
||||||
|
mw.progress.update(label="%dKB downloaded" % (thread.recvTotal/1024))
|
||||||
|
mw.connect(thread, SIGNAL("recv"), onRecv)
|
||||||
|
thread.start()
|
||||||
|
mw.progress.start(immediate=True)
|
||||||
|
while not thread.isFinished():
|
||||||
|
mw.app.processEvents()
|
||||||
|
thread.wait(100)
|
||||||
|
if not thread.error:
|
||||||
|
# success
|
||||||
|
return thread.data, thread.fname
|
||||||
|
else:
|
||||||
|
mw.progress.finish()
|
||||||
|
showWarning(_("Download failed: %s") % thread.error)
|
||||||
|
|
||||||
|
class Downloader(QThread):
|
||||||
|
|
||||||
|
def __init__(self, code):
|
||||||
|
QThread.__init__(self)
|
||||||
|
self.code = code
|
||||||
|
self.error = None
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# setup progress handler
|
||||||
|
self.byteUpdate = time.time()
|
||||||
|
self.recvTotal = 0
|
||||||
|
def canPost():
|
||||||
|
if (time.time() - self.byteUpdate) > 0.1:
|
||||||
|
self.byteUpdate = time.time()
|
||||||
|
return True
|
||||||
|
def recvEvent(bytes):
|
||||||
|
self.recvTotal += bytes
|
||||||
|
if canPost():
|
||||||
|
self.emit(SIGNAL("recv"))
|
||||||
|
addHook("httpRecv", recvEvent)
|
||||||
|
con = httpCon()
|
||||||
|
try:
|
||||||
|
resp, cont = con.request(
|
||||||
|
aqt.appShared + "download/%d" % self.code)
|
||||||
|
except Exception, e:
|
||||||
|
self.error = unicode(e[0], "utf8", "ignore")
|
||||||
|
return
|
||||||
|
finally:
|
||||||
|
remHook("httpRecv", recvEvent)
|
||||||
|
if resp['status'] == '200':
|
||||||
|
self.error = None
|
||||||
|
self.fname = re.match("attachment; filename=(.+)",
|
||||||
|
resp['content-disposition']).group(1)
|
||||||
|
self.data = cont
|
||||||
|
elif resp['status'] == '403':
|
||||||
|
self.error = _("Invalid code.")
|
||||||
|
else:
|
||||||
|
self.error = _("Error downloading: %s") % resp['status']
|
Loading…
Reference in a new issue