diff --git a/ankiqt/config.py b/ankiqt/config.py index 6b2018561..8c8d4302d 100644 --- a/ankiqt/config.py +++ b/ankiqt/config.py @@ -91,6 +91,10 @@ class Config(dict): 'recentColours': ["#000000", "#0000ff"], 'preventEditUntilAnswer': False, 'numBackups': 30, + 'proxyHost': '', + 'proxyPort': 8080, + 'proxyUser': '', + 'proxyPass': '', } for (k,v) in fields.items(): if not self.has_key(k): diff --git a/ankiqt/ui/getshared.py b/ankiqt/ui/getshared.py index 1e72c6e16..9d48126ea 100644 --- a/ankiqt/ui/getshared.py +++ b/ankiqt/ui/getshared.py @@ -50,6 +50,9 @@ class GetShared(QDialog): def fetchData(self): h = QHttp(self) h.connect(h, SIGNAL("requestFinished(int,bool)"), self.onReqFin) + h.connect(h, SIGNAL("proxyAuthenticationRequired(QNetworkProxy," + "QAuthenticator*)"), + self.onProxyAuth) h.setHost("anki.ichi2.net") #h.setHost("localhost", 8001) self.conId = h.get("/file/search?t=%d" % self.type) @@ -57,6 +60,10 @@ class GetShared(QDialog): 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: @@ -158,6 +165,9 @@ class GetShared(QDialog): def accept(self): h = QHttp(self) h.connect(h, SIGNAL("requestFinished(int,bool)"), self.onReqFin2) + 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]) diff --git a/ankiqt/ui/main.py b/ankiqt/ui/main.py index 0a57e4951..6697f812c 100644 --- a/ankiqt/ui/main.py +++ b/ankiqt/ui/main.py @@ -46,6 +46,7 @@ class AnkiQt(QMainWindow): self.setLang() self.setupFonts() self.setupBackupDir() + self.setupProxy() self.setupMainWindow() self.setupSystemHacks() self.setupSound() @@ -2480,6 +2481,34 @@ Consider backing up your media directory first.""")) self.mainWin.optionsBox.layout().setSpacing(10) self.mainWin.optionsBox.layout().setContentsMargins(4, 10, 4, 4) + # Proxy support + ########################################################################## + + def setupProxy(self): + from PyQt4.QtNetwork import QNetworkProxy + import urllib2 + if self.config['proxyHost']: + # qt + proxy = QNetworkProxy() + proxy.setType(QNetworkProxy.HttpProxy) + proxy.setHostName(self.config['proxyHost']) + proxy.setPort(self.config['proxyPort']) + if self.config['proxyUser']: + proxy.setUser(self.config['proxyUser']) + proxy.setPass(self.config['proxyPass']) + QNetworkProxy.setApplicationProxy(proxy) + # python + proxy = "http://" + if self.config['proxyUser']: + proxy += (self.config['proxyUser'] + ":" + + self.config['proxyPass'] + "@") + proxy += (self.config['proxyHost'] + ":" + + str(self.config['proxyPort'])) + os.environ["http_proxy"] = proxy + proxy_handler = urllib2.ProxyHandler() + opener = urllib2.build_opener(proxy_handler) + urllib2.install_opener(opener) + # Misc ########################################################################## diff --git a/ankiqt/ui/preferences.py b/ankiqt/ui/preferences.py index ce5a0466e..8f42f3de3 100644 --- a/ankiqt/ui/preferences.py +++ b/ankiqt/ui/preferences.py @@ -2,7 +2,7 @@ # Copyright: Damien Elmes # License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html -import copy, sys +import copy, sys, os from PyQt4.QtGui import * from PyQt4.QtCore import * import anki, anki.utils @@ -12,7 +12,8 @@ from ankiqt import ui import ankiqt.forms tabs = ("Display", - "SaveAndSync", + "Network", + "Saving", "Advanced") class Preferences(QDialog): @@ -47,13 +48,13 @@ class Preferences(QDialog): self.supportedLanguages.sort() self.connect(self.dialog.buttonBox, SIGNAL("helpRequested()"), self.helpRequested) self.setupLang() - self.setupSync() + self.setupNetwork() self.setupSave() self.setupAdvanced() self.show() def accept(self): - self.updateSync() + self.updateNetwork() self.updateSave() self.updateAdvanced() self.config['interfaceLang'] = self.origConfig['interfaceLang'] @@ -81,17 +82,27 @@ class Preferences(QDialog): self.parent.setLang() self.dialog.retranslateUi(self) - def setupSync(self): + def setupNetwork(self): self.dialog.syncOnOpen.setChecked(self.config['syncOnLoad']) self.dialog.syncOnClose.setChecked(self.config['syncOnClose']) self.dialog.syncUser.setText(self.config['syncUsername']) self.dialog.syncPass.setText(self.config['syncPassword']) + self.dialog.proxyHost.setText(self.config['proxyHost']) + self.dialog.proxyPort.setMinimum(1) + self.dialog.proxyPort.setMaximum(65535) + self.dialog.proxyPort.setValue(self.config['proxyPort']) + self.dialog.proxyUser.setText(self.config['proxyUser']) + self.dialog.proxyPass.setText(self.config['proxyPass']) - def updateSync(self): + def updateNetwork(self): self.config['syncOnLoad'] = self.dialog.syncOnOpen.isChecked() self.config['syncOnClose'] = self.dialog.syncOnClose.isChecked() self.config['syncUsername'] = unicode(self.dialog.syncUser.text()) self.config['syncPassword'] = unicode(self.dialog.syncPass.text()) + self.config['proxyHost'] = unicode(self.dialog.proxyHost.text()) + self.config['proxyPort'] = int(self.dialog.proxyPort.value()) + self.config['proxyUser'] = unicode(self.dialog.proxyUser.text()) + self.config['proxyPass'] = unicode(self.dialog.proxyPass.text()) def setupSave(self): self.dialog.saveAfterEveryNum.setValue(self.config['saveAfterAnswerNum']) @@ -99,6 +110,19 @@ class Preferences(QDialog): self.dialog.saveAfterAdding.setChecked(self.config['saveAfterAdding']) self.dialog.saveAfterAddingNum.setValue(self.config['saveAfterAddingNum']) self.dialog.saveWhenClosing.setChecked(self.config['saveOnClose']) + self.dialog.numBackups.setValue(self.config['numBackups']) + self.connect(self.dialog.openBackupFolder, + SIGNAL("linkActivated(QString)"), + self.onOpenBackup) + + def onOpenBackup(self): + path = os.path.join(self.config.configPath, "backups") + if sys.platform == "win32": + anki.latex.call(["explorer", path.encode( + sys.getfilesystemencoding())], + wait=False) + else: + QDesktopServices.openUrl(QUrl("file://" + path)) def updateSave(self): self.config['saveAfterAnswer'] = self.dialog.saveAfterEvery.isChecked() @@ -106,6 +130,7 @@ class Preferences(QDialog): self.config['saveAfterAdding'] = self.dialog.saveAfterAdding.isChecked() self.config['saveAfterAddingNum'] = self.dialog.saveAfterAddingNum.value() self.config['saveOnClose'] = self.dialog.saveWhenClosing.isChecked() + self.config['numBackups'] = self.dialog.numBackups.value() def setupAdvanced(self): self.dialog.showEstimates.setChecked(not self.config['suppressEstimates']) diff --git a/designer/preferences.ui b/designer/preferences.ui index f9caae078..347e6a909 100644 --- a/designer/preferences.ui +++ b/designer/preferences.ui @@ -6,7 +6,7 @@ 0 0 320 - 399 + 419 @@ -130,19 +130,16 @@ - Save && Sync + Network - + - 6 - - - 9 + 10 - 6 + 10 0 @@ -155,23 +152,6 @@ 0 - - - - <h1>Autosaving</h1> - - - - - - - Save when closing - - - true - - - @@ -180,46 +160,6 @@ 6 - - - - Save after answering - - - true - - - - - - - - - - cards - - - - - - - Save after adding - - - true - - - - - - - - - - facts - - - @@ -293,6 +233,71 @@ + + + + <h1>Proxy</h1> + + + + + + + 6 + + + + + Host + + + + + + + + + + Username + + + + + + + + + + Password + + + + + + + QLineEdit::Password + + + + + + + Port + + + + + + + + 60 + 0 + + + + + + @@ -306,6 +311,191 @@ + + + + Some settings will take effect after you restart Anki. + + + Qt::AlignCenter + + + + + + + + Saving + + + + 10 + + + + + <h1>Autosaving</h1> + + + + + + + 6 + + + + + Save after answering + + + true + + + + + + + + 60 + 16777215 + + + + + + + + Save after adding + + + true + + + + + + + + 60 + 16777215 + + + + + + + + Save when closing + + + true + + + + + + + cards + + + + + + + facts + + + + + + + + + <h1>Backups</h1>Decks are backed up when they are opened, and only if they have been modified since the last backup. + + + true + + + + + + + + + Keep + + + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + + + + + backups of each deck + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + <a href="backups">Open backup folder</a> + + + + + + + Qt::Vertical + + + + 20 + 59 + + + + + + + + Some settings will take effect after you restart Anki. + + + Qt::AlignCenter + + + @@ -415,7 +605,6 @@ - tabWidget interfaceLang label_2 showDivider @@ -423,21 +612,27 @@ showEstimates showProgress preventEdits - saveWhenClosing - saveAfterEvery - saveAfterEveryNum - saveAfterAdding - saveAfterAddingNum syncUser syncPass syncOnOpen syncOnClose + proxyHost + proxyPort + proxyUser + proxyPass + saveAfterEvery + saveAfterEveryNum + saveAfterAdding + saveAfterAddingNum + saveWhenClosing + numBackups alternativeTheme showTimer showTray showStudyOptions addZeroSpace buttonBox + tabWidget @@ -473,37 +668,5 @@ - - saveAfterEvery - toggled(bool) - saveAfterEveryNum - setEnabled(bool) - - - 113 - 68 - - - 116 - 68 - - - - - saveAfterAdding - toggled(bool) - saveAfterAddingNum - setEnabled(bool) - - - 99 - 68 - - - 116 - 68 - - -