def run(self): # setup progress handler self.byteUpdate = time.time() self.recvTotal = 0 def recvEvent(bytes): self.recvTotal += bytes self.recv.emit() addHook("httpRecv", recvEvent) client = AnkiRequestsClient() try: resp = client.get(aqt.appShared + "download/%d" % self.code) if resp.status_code == 200: data = client.streamContent(resp) elif resp.status_code in (403, 404): self.error = _("Invalid code") return else: self.error = _("Error downloading: %s" % resp.status_code) return except Exception as e: exc = traceback.format_exc() try: self.error = str(e[0]) except: self.error = str(exc) return finally: remHook("httpRecv", recvEvent) self.fname = re.match("attachment; filename=(.+)", resp.headers['content-disposition']).group(1) self.data = data
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.recv.emit() addHook("httpRecv", recvEvent) con = httpCon() try: resp, cont = con.request( aqt.appShared + "download/%d" % self.code) except Exception as e: exc = traceback.format_exc() try: self.error = str(e[0]) except: self.error = str(exc) 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']
def run(self): # setup progress handler self.byteUpdate = time.time() self.recvTotal = 0 def recvEvent(bytes): self.recvTotal += bytes self.recv.emit() addHook("httpRecv", recvEvent) client = AnkiRequestsClient() try: resp = client.get(aqt.appShared + "download/%s?v=2.1" % self.code) if resp.status_code == 200: data = client.streamContent(resp) elif resp.status_code in (403, 404): self.error = _( "Invalid code, or add-on not available for your version of Anki." ) return else: self.error = _("Unexpected response code: %s" % resp.status_code) return except Exception as e: self.error = _( "Please check your internet connection.") + "\n\n" + str(e) return finally: remHook("httpRecv", recvEvent) self.fname = re.match("attachment; filename=(.+)", resp.headers['content-disposition']).group(1) self.data = data
def run(self): # setup progress handler self.byteUpdate = time.time() self.recvTotal = 0 def recvEvent(bytes): self.recvTotal += bytes self.recv.emit() addHook("httpRecv", recvEvent) client = AnkiRequestsClient() try: resp = client.get( aqt.appShared + "download/%d" % self.code) if resp.status_code == 200: data = client.streamContent(resp) elif resp.status_code in (403,404): self.error = _("Invalid code") return else: self.error = _("Error downloading: %s" % resp.status_code) return except Exception as e: exc = traceback.format_exc() try: self.error = str(e[0]) except: self.error = str(exc) return finally: remHook("httpRecv", recvEvent) self.fname = re.match("attachment; filename=(.+)", resp.headers['content-disposition']).group(1) self.data = data
def main(): from . import common as ivideo # menu ivideo.config_menu() ivideo.browser_menu() # remove remHook("profileLoaded", main)
def onSave(self): remHook("reset", self.onReset) self.editor.saveNow() self.browser.externalNid = None self.browser.form.splitter.widget(1).setVisible(True) self.browser.editor.setNote(self.browser.card.note(reload=True)) saveGeom(self, "browsereditcurrent") aqt.dialogs.close("BrowserEditCurrent")
def reject(self): """ On cancel, disable the button and call our registered callback. """ remHook("BOSS_KEY", self.onBossKey) self.findChild(QDialogButtonBox, 'buttons').setDisabled(True) self._on_cancel()
def on_sync(state): showInfo("on_sync") try: if (state == 'findMedia'): print('anki:ready', end='', flush=True) remHook('sync', on_sync) except Exception as error: showInfo("on sync error" + str(error))
def accept(self): remHook('reset', self.onReset) row = self.form.list.currentRow() if row < 0: showInfo(_("Please select something.")) return self.name = self.names[self.form.list.currentRow()] QDialog.accept(self)
def reject(self): remHook('reset', self.onReset) remHook('currentModelChanged', self.onReset) clearAudioQueue() self.editor.setNote(None) self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.reset() QDialog.reject(self)
def onSave(self): remHook("reset", self.onReset) self.editor.saveNow() self.editor.setNote(None) r = self.mw.reviewer r.card.load() self.mw.moveToState("review") saveGeom(self, "editcurrent") self.close()
def _tearDownHooks(self): try: # 2.1.20+ from aqt.gui_hooks import profile_will_close profile_will_close.remove(self.close) except (ImportError, ModuleNotFoundError): from anki.hooks import remHook remHook("unloadProfile", self.close)
def closeEvent(self, event): if mw.pm.profile is not None: self.deckChooser.cleanup() saveGeom(self, "imgoccedit") self.visible = False self.svg_edit = None del (self.svg_edit_anim) # might not be gc'd remHook("unloadProfile", self.onProfileUnload) QDialog.reject(self)
def init_fastwq_menu(): try: menu.clear() except RuntimeError: remHook('config.update', init_fastwq_menu) return # Query Selected action = QAction(_('QUERY_SELECTED'), browser) action.triggered.connect(lambda: query_from_browser(browser)) action.setShortcut(QKeySequence(my_shortcut)) menu.addAction(action) # Options action = QAction(_('OPTIONS'), browser) def _show_options(): model_id = -1 for note_id in browser.selectedNotes(): note = browser.mw.col.getNote(note_id) model_id = note.model()['id'] break show_options(browser, model_id) action.triggered.connect(_show_options) menu.addAction(action) # Default configs menu.addSeparator() b = False for m in sorted(browser.mw.col.models.all(), key=itemgetter("name")): conf = config.get_maps(m['id']) conf = { 'list': [conf], 'def': 0 } if isinstance(conf, list) else conf maps_list = conf['list'] if len(maps_list) > 1: submenu = menu.addMenu(m['name']) for i, maps in enumerate(maps_list): submenu.addAction( _OK_ICON if i == conf['def'] else _NULL_ICON, _('CONFIG_INDEX') % (i + 1) if isinstance( maps, list) else maps['name'], lambda mid=m['id'], i=i: set_options_def(mid, i)) b = True if b: menu.addSeparator() # # check update # action = QAction(_('CHECK_UPDATE'), browser) # action.triggered.connect(lambda: check_updates(background=False, parent=browser)) # menu.addAction(action) # About action = QAction(_('ABOUT'), browser) action.triggered.connect(lambda: show_about_dialog(browser)) menu.addAction(action)
def accept(self): saveGeom(self, self.geomKey) remHook("reset", self.onReset) row = self.form.list.currentRow() if row < 0: showInfo(_("Please select something.")) return self.name = self.names[self.form.list.currentRow()] QDialog.accept(self)
def cleanup(self): remHook('reset', self.onReset) remHook('currentModelChanged', self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset()
def createMenu(): from .lib.com.lovac42.anki.gui import toolbar name = conf.get("menu_name", "&Stats") js_menu = toolbar.getMenu(mw, name) a = QAction(mw) a.setText("Kanji Stats") a.triggered.connect(onKanjiStats) js_menu.addAction(a) remHook(ADDON_NAME+".configLoaded", createMenu)
def stop(): #global audio_speed if not Config.play: return if Config.show_notif: CustomMessageBox.showWithTimeout(0.5, "Automatically flip cards: stop", "Message") Config.play = False hooks.remHook("showQuestion",show_question) if Config.timer is not None: Config.timer.stop() Config.timer = None Config.audio_speed = 1.0
def onSave(self): remHook("reset", self.onReset) self.editor.saveNow() self.editor.setNote(None) r = self.mw.reviewer r.card.load() r.keep = True self.mw.moveToState("review") saveGeom(self, "editcurrent") self.close()
def auto_space_switch(auto_space_obj): old_auto_space_flag = get_auto_space_flag() # 获取旧标志 new_auto_space_flag = not old_auto_space_flag # 获取新标志 set_auto_space(new_auto_space_flag) # 更新 auto_space 配置 if new_auto_space_flag is True: # 通过钩子 prepareQA,在重新加载 QA 时更新文本 addHook("prepareQA", auto_space) else: remHook("prepareQA", auto_space) new_auto_space_name = get_auto_space_name() auto_space_obj.setText(new_auto_space_name)
def onReset(self): try: n = self.editor.note n.load() except: remHook("reset", self.onReset) self.editor.setNote(None) self.mw.reset() self.close() return self.editor.setNote(n)
def _reject(self): remHook('reset', self.onReset) remHook('currentModelChanged', self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() saveGeom(self, "add") aqt.dialogs.markClosed("AddCards") QDialog.reject(self)
def _reject(self) -> None: remHook("reset", self.onReset) remHook("currentModelChanged", self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() saveGeom(self, "add") aqt.dialogs.markClosed("AddCards") QDialog.reject(self)
def onAddDeck(self): row = self.form.list.currentRow() if row < 0: default = self.form.filter.text() else: default = self.names[self.form.list.currentRow()] n = getOnlyText(_("New deck name:"), default=default) if n: self.mw.col.decks.id(n) self.name = n # make sure we clean up reset hook when manually exiting remHook('reset', self.onReset) QDialog.accept(self)
def reject(self): if not self.canClose(): return remHook('reset', self.onReset) remHook('currentModelChanged', self.onReset) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.setNote(None) self.modelChooser.cleanup() self.mw.maybeReset() saveGeom(self, "add") aqt.dialogs.close("AddCards") QDialog.reject(self)
def _reject(self): remHook('reset', self.onReset) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.setNote(None) self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() saveGeom(self, "add") aqt.dialogs.close(self._UID) if not self.forceClose: #not shutdown del aqt.dialogs._dialogs[self._UID] QDialog.reject(self)
def closeEvent(self, event): if mw.pm.profile is not None: self.deckChooser.cleanup() saveGeom(self, "imgoccedit") self.visible = False self.svg_edit = None del(self.svg_edit_anim) # might not be gc'd try: from aqt.gui_hooks import profile_will_close profile_will_close.append(self.onProfileUnload) except (ImportError, ModuleNotFoundError): remHook("unloadProfile", self.onProfileUnload) QDialog.reject(self)
def _onSave(self): remHook("reset", self.onReset) r = self.mw.reviewer try: r.card.load() except: # card was removed by clayout pass else: self.mw.reviewer.cardQueue.append(self.mw.reviewer.card) self.mw.moveToState("review") saveGeom(self, "editcurrent") aqt.dialogs.close("EditCurrent")
def _reject(self): remHook("reset", self.onReset) remHook("currentModelChanged", self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() saveGeom(self, "ankidown") aqt.dialogs.markClosed("Ankidown-Importer") tooltip("Added {} Notes".format(self.tally), period=1000) QDialog.reject(self)
def unload(self): self.signals.unloaded.emit() # TODO: is this necessary? throws errors for now ↓ # self.signals.disconnect() if not self._loaded: return try: self.save() except (FileNotFoundError, ConfigError) as e: # Corner case: Closing Anki after add-on uninstall print(e) self._loaded = self._dirty = self._ready = False remHook("unloadProfile", self.unload)
def onSave(self): remHook("reset", self.onReset) self.editor.saveNow() self.editor.setNote(None) r = self.mw.reviewer try: r.card.load() except TypeError: # card was removed by clayout pass else: self.mw.reviewer.cardQueue.append(self.mw.reviewer.card) self.mw.moveToState("review") saveGeom(self, "editcurrent")
def onReset(self): # lazy approach for now: throw away edits try: n = self.editor.note n.load()#reload in case the model changed except: # card's been deleted remHook("reset", self.onReset) self.editor.setNote(None) self.mw.reset() aqt.dialogs.markClosed("EditCurrent") self.close() return self.editor.setNote(n)
def onReset(self): # lazy approach for now: throw away edits try: n = self.mw.reviewer.card.note() n.load() except: # card's been deleted remHook("reset", self.onReset) self.editor.setNote(None) self.mw.reset() aqt.dialogs.close("EditCurrent") self.close() return self.editor.setNote(n)
def _reject(self): """Close the window. Don't check whether data will be lost""" remHook('reset', self.onReset) remHook('currentModelChanged', self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() saveGeom(self, "add") aqt.dialogs.markClosed("AddCards") QDialog.reject(self)
def _saveAndClose(self): remHook("reset", self.onReset) r = self.mw.reviewer try: r.card.load() except: # card was removed by clayout pass else: self.mw.reviewer.cardQueue.append(self.mw.reviewer.card) self.editor.cleanup() self.mw.moveToState("review") saveGeom(self, "editcurrent") aqt.dialogs.markClosed("EditCurrent") QDialog.reject(self)
def myReject(self): if not self.canClose(): return remHook('reset', self.onReset) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.setNote(None) self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() # save geometry of current dialog if self.dialogName == "AddCards": saveGeom(self, "add") else: saveGeom(self, "add2") # close dialog dialogs.close(self.dialogName) QDialog.reject(self)
def run(self): # init this first so an early crash doesn't cause an error # in the main thread self.syncMsg = "" self.uname = "" try: self.col = Collection(self.path, log=True) except: self.fireEvent("corrupt") return self.server = RemoteServer(self.hkey, hostNum=self.hostNum) self.client = Syncer(self.col, self.server) self.sentTotal = 0 self.recvTotal = 0 def syncEvent(type): self.fireEvent("sync", type) def syncMsg(msg): self.fireEvent("syncMsg", msg) def sendEvent(bytes): if not self._abort: self.sentTotal += bytes self.fireEvent("send", str(self.sentTotal)) elif self._abort == 1: self._abort = 2 raise Exception("sync cancelled") def recvEvent(bytes): if not self._abort: self.recvTotal += bytes self.fireEvent("recv", str(self.recvTotal)) elif self._abort == 1: self._abort = 2 raise Exception("sync cancelled") addHook("sync", syncEvent) addHook("syncMsg", syncMsg) addHook("httpSend", sendEvent) addHook("httpRecv", recvEvent) # run sync and catch any errors try: self._sync() except: err = traceback.format_exc() self.fireEvent("error", err) finally: # don't bump mod time unless we explicitly save self.col.close(save=False) remHook("sync", syncEvent) remHook("syncMsg", syncMsg) remHook("httpSend", sendEvent) remHook("httpRecv", recvEvent)
def run(self): # init this first so an early crash doesn't cause an error # in the main thread self.syncMsg = "" self.uname = "" try: self.col = Collection(self.path, log=True) except: self.fireEvent("corrupt") return self.server = RemoteServer(self.hkey) self.client = Syncer(self.col, self.server) self.sentTotal = 0 self.recvTotal = 0 # throttle updates; qt doesn't handle lots of posted events well self.byteUpdate = time.time() def syncEvent(type): self.fireEvent("sync", type) def syncMsg(msg): self.fireEvent("syncMsg", msg) def canPost(): if (time.time() - self.byteUpdate) > 0.1: self.byteUpdate = time.time() return True def sendEvent(bytes): self.sentTotal += bytes if canPost(): self.fireEvent("send", str(self.sentTotal)) def recvEvent(bytes): self.recvTotal += bytes if canPost(): self.fireEvent("recv", str(self.recvTotal)) addHook("sync", syncEvent) addHook("syncMsg", syncMsg) addHook("httpSend", sendEvent) addHook("httpRecv", recvEvent) # run sync and catch any errors try: self._sync() except: err = traceback.format_exc() self.fireEvent("error", err) finally: # don't bump mod time unless we explicitly save self.col.close(save=False) remHook("sync", syncEvent) remHook("syncMsg", syncMsg) remHook("httpSend", sendEvent) remHook("httpRecv", recvEvent)
def run(self): self.col = Collection(self.path) self.server = RemoteServer(self.hkey) self.client = Syncer(self.col, self.server) self.sentTotal = 0 self.recvTotal = 0 # throttle updates; qt doesn't handle lots of posted events well self.byteUpdate = time.time() def syncEvent(type): self.fireEvent("sync", type) def canPost(): if (time.time() - self.byteUpdate) > 0.1: self.byteUpdate = time.time() return True def sendEvent(bytes): self.sentTotal += bytes if canPost(): self.fireEvent("send", self.sentTotal) def recvEvent(bytes): self.recvTotal += bytes if canPost(): self.fireEvent("recv", self.recvTotal) addHook("sync", syncEvent) addHook("httpSend", sendEvent) addHook("httpRecv", recvEvent) # run sync and catch any errors try: self._sync() except: err = traceback.format_exc() print err self.fireEvent("error", err) finally: # don't bump mod time unless we explicitly save self.col.close(save=False) remHook("sync", syncEvent) remHook("httpSend", sendEvent) remHook("httpRecv", recvEvent)
def cleanup(self): remHook('reset', self.onReset)
def cleanup(self): remHook('currentModelChanged', self.onModelChange)
def reject(self): remHook('reset', self.onReset) if not self.cancel: return self.accept() QDialog.reject(self)
def reject(self): saveGeom(self, self.geomKey) remHook('reset', self.onReset) if not self.cancel: return self.accept() QDialog.reject(self)
def accept(self): self.exporter.includeSched = ( self.frm.includeSched.isChecked()) self.exporter.includeMedia = ( self.frm.includeMedia.isChecked()) self.exporter.includeTags = ( self.frm.includeTags.isChecked()) if not self.frm.deck.currentIndex(): self.exporter.did = None else: name = self.decks[self.frm.deck.currentIndex()] self.exporter.did = self.col.decks.id(name) if (self.isApkg and self.exporter.includeSched and not self.exporter.did): verbatim = True # it's a verbatim apkg export, so place on desktop instead of # choosing file; use homedir if no desktop usingHomedir = False file = os.path.join(QStandardPaths.writableLocation( QStandardPaths.DesktopLocation), "collection.apkg") if not os.path.exists(os.path.dirname(file)): usingHomedir = True file = os.path.join(QStandardPaths.writableLocation( QStandardPaths.HomeLocation), "collection.apkg") if os.path.exists(file): if usingHomedir: question = _("%s already exists in your home directory. Overwrite it?") else: question = _("%s already exists on your desktop. Overwrite it?") if not askUser(question % "collection.apkg"): return else: verbatim = False # Get deck name and remove invalid filename characters deck_name = self.decks[self.frm.deck.currentIndex()] deck_name = re.sub('[\\\\/?<>:*|"^]', '_', deck_name) filename = '{0}{1}'.format(deck_name, self.exporter.ext) while 1: file = getSaveFile(self, _("Export"), "export", self.exporter.key, self.exporter.ext, fname=filename) if not file: return if checkInvalidFilename(os.path.basename(file), dirsep=False): continue break self.hide() if file: self.mw.progress.start(immediate=True) try: f = open(file, "wb") f.close() except (OSError, IOError) as e: showWarning(_("Couldn't save file: %s") % str(e)) else: os.unlink(file) exportedMedia = lambda cnt: self.mw.progress.update( label=ngettext("Exported %d media file", "Exported %d media files", cnt) % cnt ) addHook("exportedMediaFiles", exportedMedia) self.exporter.exportInto(file) remHook("exportedMediaFiles", exportedMedia) if verbatim: if usingHomedir: msg = _("A file called %s was saved in your home directory.") else: msg = _("A file called %s was saved on your desktop.") msg = msg % "collection.apkg" period = 5000 else: period = 3000 if self.isTextNote: msg = ngettext("%d note exported.", "%d notes exported.", self.exporter.count) % self.exporter.count else: msg = ngettext("%d card exported.", "%d cards exported.", self.exporter.count) % self.exporter.count tooltip(msg, period=period) finally: self.mw.progress.finish() QDialog.accept(self)
def mpv_add_to_queue(path): if m is None: mpv_init() m.command("loadfile", path, "append-play") def mpv_clear_queue(): if m is None: return m.command("stop") def mpv_kill(*args): global m if m is None: return m.command("quit") m = None hooks.remHook("unloadProfile", sound.stopMplayer) hooks.addHook("unloadProfile", mpv_kill) sound._player = mpv_add_to_queue sound._queueEraser = mpv_clear_queue
def accept(self): self.exporter.includeSched = ( self.frm.includeSched.isChecked()) self.exporter.includeMedia = ( self.frm.includeMedia.isChecked()) self.exporter.includeTags = ( self.frm.includeTags.isChecked()) self.exporter.includeHTML = ( self.frm.includeHTML.isChecked()) if not self.frm.deck.currentIndex(): self.exporter.did = None else: name = self.decks[self.frm.deck.currentIndex()] self.exporter.did = self.col.decks.id(name) if self.isVerbatim: name = time.strftime("-%Y-%m-%d@%H-%M-%S", time.localtime(time.time())) deck_name = _("collection")+name else: # Get deck name and remove invalid filename characters deck_name = self.decks[self.frm.deck.currentIndex()] deck_name = re.sub('[\\\\/?<>:*|"^]', '_', deck_name) if not self.isVerbatim and self.isApkg and self.exporter.includeSched and self.col.schedVer() == 2: showInfo("Please switch to the regular scheduler before exporting a single deck .apkg with scheduling.") return filename = '{0}{1}'.format(deck_name, self.exporter.ext) while 1: file = getSaveFile(self, _("Export"), "export", self.exporter.key, self.exporter.ext, fname=filename) if not file: return if checkInvalidFilename(os.path.basename(file), dirsep=False): continue break self.hide() if file: self.mw.progress.start(immediate=True) try: f = open(file, "wb") f.close() except (OSError, IOError) as e: showWarning(_("Couldn't save file: %s") % str(e)) else: os.unlink(file) exportedMedia = lambda cnt: self.mw.progress.update( label=ngettext("Exported %d media file", "Exported %d media files", cnt) % cnt ) addHook("exportedMediaFiles", exportedMedia) self.exporter.exportInto(file) remHook("exportedMediaFiles", exportedMedia) period = 3000 if self.isVerbatim: msg = _("Collection exported.") else: if self.isTextNote: msg = ngettext("%d note exported.", "%d notes exported.", self.exporter.count) % self.exporter.count else: msg = ngettext("%d card exported.", "%d cards exported.", self.exporter.count) % self.exporter.count tooltip(msg, period=period) finally: self.mw.progress.finish() QDialog.accept(self)
def cleanup(self): remHook("reset", self.onReset)
def teardownHooks(self): remHook("reset", self.onReset) remHook("editTimer", self.refreshCurrentCard) remHook("editFocusLost", self.refreshCurrentCard) remHook("undoState", self.onUndoState)
def cleanup(self): remHook("reset", self.onReset) remHook("currentModelChanged", self.onReset) self.modelChooser.cleanup() saveGeom(self, "changeModel")
def reject(self): self.modelChooser.cleanup() self.deck.cleanup() remHook("currentModelChanged", self.modelChanged) QDialog.reject(self)
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: exc = traceback.format_exc() try: self.error = unicode(e[0], "utf8", "ignore") except: self.error = exc 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']