diff --git a/addons/fastwq/gui/common.py b/addons/fastwq/gui/common.py index 96bb682..b7f2bc1 100644 --- a/addons/fastwq/gui/common.py +++ b/addons/fastwq/gui/common.py @@ -36,8 +36,11 @@ __all__ = ['show_options', 'check_updates', 'show_fm_dialog', 'show_about_dialog def check_updates(): '''check add-on last version''' try: - if not ankihub.update([Endpoint.check_version], False, Endpoint.version): + state = ankihub.update([Endpoint.check_version], False, Endpoint.version) + if state == 0: showInfo(_('LATEST_VERSION')) + elif state == -1: + showInfo(_('CHECK_FAILURE')) except: showInfo(_('CHECK_FAILURE')) diff --git a/addons/fastwq/libs/ankihub.py b/addons/fastwq/libs/ankihub.py index 1b0fd7c..676ce00 100644 --- a/addons/fastwq/libs/ankihub.py +++ b/addons/fastwq/libs/ankihub.py @@ -1,42 +1,29 @@ -from PyQt4 import QtCore,QtGui -import httplib -import urllib2 +try: + import httplib +except: + import http.client as httplib +try: + import urllib2 +except: + import urllib.request as urllib2 import json import os import sys import zipfile import traceback import io -from AnkiHub.updates import Ui_DialogUpdates -from AnkiHub.markdown2 import markdown import aqt from aqt import mw +from aqt.qt import * from anki.hooks import addHook from anki.utils import isMac, isWin from ..context import APP_ICON +from .AnkiHub.updates import Ui_DialogUpdates +from .AnkiHub.markdown2 import markdown # taken from Anki's aqt/profiles.py def defaultBase(): - ''' - print(mw.pm.addonFolder()) - if isWin: - loc = QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.DocumentsLocation) - return os.path.join(loc, "Anki") - elif isMac: - return os.path.expanduser("~/Documents/Anki") - else: - p = os.path.expanduser("~/Anki") - if os.path.exists(p): - return p - else: - loc = QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.DocumentsLocation) - if loc[:-1] == QtGui.QDesktopServices.storageLocation( - QtGui.QDesktopServices.HomeLocation): - return os.path.expanduser("~/Documents/Anki") - else: - return os.path.join(loc, "Anki") - ''' path = mw.pm.addonFolder() return os.path.dirname(os.path.abspath(path)) @@ -45,53 +32,37 @@ headers = {"User-Agent": "AnkiHub"} dataPath = os.path.join(defaultBase(),'.fastwq_2.0.x_ankihub.json') -class DialogUpdates(QtGui.QDialog, Ui_DialogUpdates): - def __init__(self, parent, data, oldData, callback, automaticAnswer=None,install=False): - QtGui.QDialog.__init__(self,parent) +class DialogUpdates(QDialog, Ui_DialogUpdates): + + def __init__(self, parent, data, oldData, callback, install=False): + QDialog.__init__(self,parent) self.setModal(True) self.setWindowFlags( self.windowFlags() & - ~QtCore.Qt.WindowContextHelpButtonHint + ~Qt.WindowContextHelpButtonHint ) self.setWindowIcon(APP_ICON) self.setupUi(self) totalSize = sum(map(lambda x:x['size'],data['assets'])) - def answer(doUpdate,answ): + def answer(): self.update.setEnabled(False) - #self.dont.setEnabled(False) - #self.always.setEnabled(False) - #self.never.setEnabled(False) - callback(doUpdate,answ,self.appendHtml,self.finish,install) + callback(self.appendHtml, self.finish, install) self.html = u'' self.appendHtml(markdown(data['body'])) #if not automaticAnswer: - self.connect(self.update,QtCore.SIGNAL('clicked()'), - lambda:answer(True,'ask')) - #self.connect(self.dont,QtCore.SIGNAL('clicked()'), - # lambda:answer(False,'ask')) - #self.connect(self.always,QtCore.SIGNAL('clicked()'), - # lambda:answer(True,'always')) - #self.connect(self.never,QtCore.SIGNAL('clicked()'), - # lambda:answer(False,'never')) - #else: - #self.update.setEnabled(False) - #self.dont.setEnabled(False) - #self.always.setEnabled(False) - #self.never.setEnabled(False) - # answer(True,automaticAnswer) + self.update.clicked.connect(lambda:answer()) fromVersion = '' if 'tag_name' in oldData: fromVersion = u'from {0} '.format(oldData['tag_name']) self.labelUpdates.setText( - unicode(self.labelUpdates.text()).format( + str(self.labelUpdates.text()).format( data['name'], fromVersion, data['tag_name'])) - def appendHtml(self,html='',temp=''): self.html += html self.textBrowser.setHtml(u'{0}{1}{2}'.format(self.html, temp, u'
')) @@ -122,101 +93,77 @@ def installZipFile(data, fname): z.extract(n, base) return True + def asset(a): return { 'url': a['browser_download_url'], 'size': a['size'] } -profileLoaded = True -def _profileLoaded(): - profileLoaded = True -addHook("profileLoaded",_profileLoaded) +def updateSingle(repositories, path, data): + def callback(appendHtml, onReady, install): + for asset in data['assets']: + code = asset['url'] + p, fname = os.path.split(code) + appendHtml(temp='
Downloading {1}: {0}%
'.format(0,fname)) + urlthread = UrlThread(code) + urlthread.start() + urlthread.join() + response = urlthread.response#urllib2.urlopen(code) + meta = response.info() + file_size = int(meta.get("Content-Length")) + d = buffer('') + dl = 0 + i = 0 + lastPercent = None + while True: + dkb = response.read(1024) + if not dkb: + break + dl += len(dkb) + d += dkb + if dl*100/file_size>i: + lastPercent = int(dl*100/file_size) + i = lastPercent+1 + appendHtml(temp='
Downloading {1}: {0}%
'.format(lastPercent,fname)) + QApplication.instance().processEvents() + appendHtml('
Downloading {1}: 100%
'.format(int(dl*100/file_size),fname)) + appendHtml('Installing ...
') + if not installZipFile(d, fname): + appendHtml('Corrupt file
') + else: + repositories[path] = data + repositories[path]['update'] = 'ask' + with open(dataPath,'w') as f: + json.dump(repositories,f,indent=2) + f.close() + appendHtml('Done.
Please restart Anki.
') + onReady() # close the AnkiHub update window -def updateSingle(repositories,path,data): - def callback(doUpdate,answer,appendHtml,onReady,install): - if doUpdate: - for asset in data['assets']: - code = asset['url'] - p, fname = os.path.split(code) - response = urllib2.urlopen(code) - meta = response.info() - file_size = int(meta.getheaders("Content-Length")[0]) - d = buffer('') - dl = 0 - i = 0 - lastPercent = None - while True: - dkb = response.read(1024) - if not dkb: - break - dl += len(dkb) - d += dkb - if dl*100/file_size>i: - lastPercent = int(dl*100/file_size) - i = lastPercent+1 - appendHtml(temp='
Downloading {1}: {0}%
'.format(lastPercent,fname)) - QtGui.QApplication.instance().processEvents() - appendHtml('
Downloading {1}: 100%
'.format(int(dl*100/file_size),fname)) - def installData(): - if install: - filesBefore = aqt.mw.addonManager.files() - #directoriesBefore = aqt.mw.addonManager.directories() - appendHtml('Installing ...
') - if not installZipFile(d,fname): - appendHtml('Corrupt file
') - else: - repositories[path] = data - repositories[path]['update'] = answer - with open(dataPath,'w') as file: - json.dump(repositories,file,indent=2) - file.close() - if install: - appendHtml('Executing new scripts...
') - newFiles = set(aqt.mw.addonManager.files()) - set(filesBefore) - #newDirectories = set(aqt.mw.addonManager.directories()) - set(directoriesBefore) - for file in newFiles: - try: - __import__(file.replace(".py", "")) - except: - traceback.print_exc() - #for directory in newDirectories: - # try: - # __import__(directory) - # except: - # traceback.print_exc() - aqt.mw.addonManager.rebuildAddonsMenu() - appendHtml('Done.
') - onReady() # close the AnkiHub update window - else: - appendHtml('Done.
Please restart Anki.
') - onReady() # close the AnkiHub update window - - installData() - else: - repositories[path]['update'] = answer - with open(dataPath,'w') as file: - json.dump(repositories,file,indent=2) - file.close() - onReady() return callback -datas = [] -def update(add=[],install=False, VERSION='v0.0.0'): +def update(add=[], install=False, VERSION='v0.0.0'): + # progress win + progresswin = QProgressDialog('Update Checking...', 'FastWQ - Updater', 0, 0, mw) + progresswin.setWindowModality(Qt.ApplicationModal) + progresswin.setCancelButton(None) + progresswin.setWindowFlags( + progresswin.windowFlags() & + ~Qt.WindowContextHelpButtonHint + ) + progresswin.setWindowIcon(APP_ICON) + progresswin.resize(280, 60) + progresswin.show() + # conn = httplib.HTTPSConnection("api.github.com") try: - with open(dataPath,'r') as file: - repositories = json.load(file) - file.close() + with open(dataPath,'r') as f: + repositories = json.load(f) + f.close() except: repositories = {} - # 'dayjaby/AnkiHub': { - # 'id': 4089471, - # 'update': 'ask' - # } - #} for a in add: if a not in repositories: @@ -225,92 +172,115 @@ def update(add=[],install=False, VERSION='v0.0.0'): 'update': 'ask' } - ret = False for path,repository in repositories.items(): username,repositoryName = path.split('/') - if repository['update'] != 'never': - try: - url = "https://api.github.com/repos/{0}/releases/latest".format(path) - responseData = urllib2.urlopen(url, timeout=10).read() - release = json.loads(responseData) - datas.append(responseData) - except Exception as e: - datas.append(e) - release = {} + try: + urlthread = UrlThread("https://api.github.com/repos/{0}/releases/latest".format(path)) + urlthread.start() + urlthread.join() + release = json.loads(urlthread.response.read()) + except Exception as e: + release = {} - if 'id' in release: - if release['id'] != repository['id']: - data = { - 'id': release['id'], - 'name': repositoryName, - 'tag_name': release['tag_name'], - 'body': '### {0}\n'.format(release['name']) + release['body'], - 'assets': [asset(release['assets'][0])],#map(asset,release['assets']), - 'update': 'ask' - } - if 'tag_name' in repository: - oldVersion = map(int,repository['tag_name'][1:].split('.')) - while len(oldVersion)<3: - oldVersion.append(0) - else: - oldVersion = map(int,VERSION[1:].split('.'))#[0,0,0] - newVersion = map(int,data['tag_name'][1:].split('.')) - isMinor = len(newVersion)>2 and newVersion[2]>0 - while len(newVersion)<3: - newVersion.append(0) - i = oldVersion[2]+1 - if oldVersion[0]2 and newVersion[2]>0 + while len(newVersion)<3: + newVersion.append(0) + i = oldVersion[2]+1 + if oldVersion[0]{0}{1}{2}'.format(self.html, temp, u'
')) @@ -129,101 +93,77 @@ def installZipFile(data, fname): z.extract(n, base) return True + def asset(a): return { 'url': a['browser_download_url'], 'size': a['size'] } -profileLoaded = True -def _profileLoaded(): - profileLoaded = True -addHook("profileLoaded",_profileLoaded) +def updateSingle(repositories, path, data): + def callback(appendHtml, onReady, install): + for asset in data['assets']: + code = asset['url'] + p, fname = os.path.split(code) + appendHtml(temp='
Downloading {1}: {0}%
'.format(0,fname)) + urlthread = UrlThread(code) + urlthread.start() + urlthread.join() + response = urlthread.response#urllib2.urlopen(code) + meta = response.info() + file_size = int(meta.get("Content-Length")) + d = b'' + dl = 0 + i = 0 + lastPercent = None + while True: + dkb = response.read(1024) + if not dkb: + break + dl += len(dkb) + d += dkb + if dl*100/file_size>i: + lastPercent = int(dl*100/file_size) + i = lastPercent+1 + appendHtml(temp='
Downloading {1}: {0}%
'.format(lastPercent,fname)) + QApplication.instance().processEvents() + appendHtml('
Downloading {1}: 100%
'.format(int(dl*100/file_size),fname)) + appendHtml('Installing ...
') + if not installZipFile(d, fname): + appendHtml('Corrupt file
') + else: + repositories[path] = data + repositories[path]['update'] = 'ask' + with open(dataPath,'w') as f: + json.dump(repositories,f,indent=2) + f.close() + appendHtml('Done.
Please restart Anki.
') + onReady() # close the AnkiHub update window -def updateSingle(repositories,path,data): - def callback(doUpdate,answer,appendHtml,onReady,install): - if doUpdate: - for asset in data['assets']: - code = asset['url'] - p, fname = os.path.split(code) - response = urllib2.urlopen(code) - meta = response.info() - file_size = int(meta.get("Content-Length")) - d = b'' - dl = 0 - i = 0 - lastPercent = None - while True: - dkb = response.read(1024) - if not dkb: - break - dl += len(dkb) - d += dkb - if dl*100/file_size>i: - lastPercent = int(dl*100/file_size) - i = lastPercent+1 - appendHtml(temp='
Downloading {1}: {0}%
'.format(lastPercent,fname)) - QApplication.instance().processEvents() - appendHtml('
Downloading {1}: 100%
'.format(int(dl*100/file_size),fname)) - def installData(): - if install: - filesBefore = aqt.mw.addonManager.files() - #directoriesBefore = aqt.mw.addonManager.directories() - appendHtml('Installing ...
') - if not installZipFile(d,fname): - appendHtml('Corrupt file
') - else: - repositories[path] = data - repositories[path]['update'] = answer - with open(dataPath,'w') as file: - json.dump(repositories,file,indent=2) - file.close() - if install: - appendHtml('Executing new scripts...
') - newFiles = set(aqt.mw.addonManager.files()) - set(filesBefore) - #newDirectories = set(aqt.mw.addonManager.directories()) - set(directoriesBefore) - for file in newFiles: - try: - __import__(file.replace(".py", "")) - except: - traceback.print_exc() - #for directory in newDirectories: - # try: - # __import__(directory) - # except: - # traceback.print_exc() - aqt.mw.addonManager.rebuildAddonsMenu() - appendHtml('Done.
') - onReady() # close the AnkiHub update window - else: - appendHtml('Done.
Please restart Anki.
') - onReady() # close the AnkiHub update window - - installData() - else: - repositories[path]['update'] = answer - with open(dataPath,'w') as file: - json.dump(repositories,file,indent=2) - file.close() - onReady() return callback -datas = [] -def update(add=[],install=False, VERSION='v0.0.0'): +def update(add=[], install=False, VERSION='v0.0.0'): + # progress win + progresswin = QProgressDialog('Update Checking...', 'FastWQ - Updater', 0, 0, mw) + progresswin.setWindowModality(Qt.ApplicationModal) + progresswin.setCancelButton(None) + progresswin.setWindowFlags( + progresswin.windowFlags() & + ~Qt.WindowContextHelpButtonHint + ) + progresswin.setWindowIcon(APP_ICON) + progresswin.resize(280, 60) + progresswin.show() + # conn = httplib.HTTPSConnection("api.github.com") try: - with open(dataPath,'r') as file: - repositories = json.load(file) - file.close() + with open(dataPath,'r') as f: + repositories = json.load(f) + f.close() except: repositories = {} - # 'dayjaby/AnkiHub': { - # 'id': 4089471, - # 'update': 'ask' - # } - #} for a in add: if a not in repositories: @@ -232,95 +172,115 @@ def update(add=[],install=False, VERSION='v0.0.0'): 'update': 'ask' } - ret = False for path,repository in repositories.items(): username,repositoryName = path.split('/') - if repository['update'] != 'never': - try: - url = "https://api.github.com/repos/{0}/releases/latest".format(path) - responseData = urllib2.urlopen(url, timeout=10).read() - release = json.loads(responseData) - datas.append(responseData) - except Exception as e: - datas.append(e) - release = {} + try: + urlthread = UrlThread("https://api.github.com/repos/{0}/releases/latest".format(path)) + urlthread.start() + urlthread.join() + release = json.loads(urlthread.response.read()) + except Exception as e: + release = {} - if 'id' in release: - if release['id'] != repository['id']: - data = { - 'id': release['id'], - 'name': repositoryName, - 'tag_name': release['tag_name'], - 'body': '### {0}\n'.format(release['name']) + release['body'], - 'assets': [asset(release['assets'][1])],#map(asset,release['assets']), - 'update': 'ask' - } - if 'tag_name' in repository: - oldVersion = map(int,repository['tag_name'][1:].split('.')) - oldVersion = [x for x in oldVersion] - while len(oldVersion)<3: - oldVersion.append(0) - else: - oldVersion = map(int,VERSION[1:].split('.'))#[0,0,0] - oldVersion = [x for x in oldVersion] - newVersion = map(int,data['tag_name'][1:].split('.')) - newVersion = [x for x in newVersion] - isMinor = len(newVersion)>2 and newVersion[2]>0 - while len(newVersion)<3: - newVersion.append(0) - i = oldVersion[2]+1 - if oldVersion[0]2 and newVersion[2]>0 + while len(newVersion)<3: + newVersion.append(0) + i = oldVersion[2]+1 + if oldVersion[0]