Updated plugin notifications

This commit is contained in:
Kovid Goyal 2011-06-14 13:17:11 -06:00
parent f4e5714391
commit 230cfe0877
2 changed files with 93 additions and 47 deletions

View File

@ -27,7 +27,6 @@ def partial(*args, **kwargs):
_keep_refs.append(ans) _keep_refs.append(ans)
return ans return ans
class LibraryViewMixin(object): # {{{ class LibraryViewMixin(object): # {{{
def __init__(self, db): def __init__(self, db):
@ -145,6 +144,7 @@ class UpdateLabel(QLabel): # {{{
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
QLabel.__init__(self, *args, **kwargs) QLabel.__init__(self, *args, **kwargs)
self.setCursor(Qt.PointingHandCursor)
def contextMenuEvent(self, e): def contextMenuEvent(self, e):
pass pass
@ -182,14 +182,6 @@ class StatusBar(QStatusBar): # {{{
self.defmsg.setText(self.default_message) self.defmsg.setText(self.default_message)
self.clearMessage() self.clearMessage()
def new_version_available(self, ver, url):
msg = (u'<span style="color:red; font-weight: bold">%s: <a'
' href="update:%s">%s<a></span>') % (
_('Update found'), ver, ver)
self.update_label.setText(msg)
self.update_label.setCursor(Qt.PointingHandCursor)
self.update_label.setVisible(True)
def get_version(self): def get_version(self):
dv = os.environ.get('CALIBRE_DEVELOP_FROM', None) dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
v = __version__ v = __version__
@ -257,12 +249,6 @@ class LayoutMixin(object): # {{{
self.setStatusBar(self.status_bar) self.setStatusBar(self.status_bar)
self.status_bar.update_label.linkActivated.connect(self.update_link_clicked) self.status_bar.update_label.linkActivated.connect(self.update_link_clicked)
def update_link_clicked(self, url):
url = unicode(url)
if url.startswith('update:'):
version = url.partition(':')[-1]
self.update_found(version, force=True)
def finalize_layout(self): def finalize_layout(self):
self.status_bar.initialize(self.system_tray_icon) self.status_bar.initialize(self.system_tray_icon)
self.book_details.show_book_info.connect(self.iactions['Show Book Details'].show_book_info) self.book_details.show_book_info.connect(self.iactions['Show Book Details'].show_book_info)

View File

@ -3,22 +3,34 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import traceback import traceback
from PyQt4.Qt import QThread, pyqtSignal, Qt, QUrl, QDialog, QGridLayout, \ from PyQt4.Qt import (QThread, pyqtSignal, Qt, QUrl, QDialog, QGridLayout,
QLabel, QCheckBox, QDialogButtonBox, QIcon, QPixmap QLabel, QCheckBox, QDialogButtonBox, QIcon, QPixmap)
import mechanize import mechanize
from calibre.constants import __appname__, __version__, iswindows, isosx from calibre.constants import (__appname__, __version__, iswindows, isosx,
isportable)
from calibre import browser from calibre import browser
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.gui2 import config, dynamic, open_url from calibre.gui2 import config, dynamic, open_url
from calibre.gui2.dialogs.plugin_updater import get_plugin_updates_available from calibre.gui2.dialogs.plugin_updater import get_plugin_updates_available
URL = 'http://status.calibre-ebook.com/latest' URL = 'http://status.calibre-ebook.com/latest'
NO_CALIBRE_UPDATE = '-0.0.0'
VSEP = '|'
def get_newest_version():
br = browser()
req = mechanize.Request(URL)
req.add_header('CALIBRE_VERSION', __version__)
req.add_header('CALIBRE_OS',
'win' if iswindows else 'osx' if isosx else 'oth')
req.add_header('CALIBRE_INSTALL_UUID', prefs['installation_uuid'])
version = br.open(req).read().strip()
return version
class CheckForUpdates(QThread): class CheckForUpdates(QThread):
update_found = pyqtSignal(object) update_found = pyqtSignal(object)
plugin_update_found = pyqtSignal(object)
INTERVAL = 24*60*60 INTERVAL = 24*60*60
def __init__(self, parent): def __init__(self, parent):
@ -26,29 +38,29 @@ class CheckForUpdates(QThread):
def run(self): def run(self):
while True: while True:
calibre_update_version = NO_CALIBRE_UPDATE
plugins_update_found = 0
try: try:
br = browser() version = get_newest_version()
req = mechanize.Request(URL)
req.add_header('CALIBRE_VERSION', __version__)
req.add_header('CALIBRE_OS',
'win' if iswindows else 'osx' if isosx else 'oth')
req.add_header('CALIBRE_INSTALL_UUID', prefs['installation_uuid'])
version = br.open(req).read().strip()
if version and version != __version__ and len(version) < 10: if version and version != __version__ and len(version) < 10:
self.update_found.emit(version) calibre_update_version = version
except: except:
traceback.print_exc() traceback.print_exc()
try: try:
update_plugins = get_plugin_updates_available() update_plugins = get_plugin_updates_available()
if update_plugins: if update_plugins is not None:
self.plugin_update_found.emit(update_plugins) plugins_update_found = len(update_plugins)
except: except:
traceback.print_exc() traceback.print_exc()
if (calibre_update_version != NO_CALIBRE_UPDATE or
plugins_update_found > 0):
self.update_found.emit('%s%s%d'%(calibre_update_version,
VSEP, plugins_update_found))
self.sleep(self.INTERVAL) self.sleep(self.INTERVAL)
class UpdateNotification(QDialog): class UpdateNotification(QDialog):
def __init__(self, version, parent=None): def __init__(self, calibre_version, plugin_updates, parent=None):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
self.resize(400, 250) self.resize(400, 250)
self.l = QGridLayout() self.l = QGridLayout()
@ -62,7 +74,8 @@ class UpdateNotification(QDialog):
'See the <a href="http://calibre-ebook.com/whats-new' 'See the <a href="http://calibre-ebook.com/whats-new'
'">new features</a>.') + '<p>'+_('Update <b>only</b> if one of the ' '">new features</a>.') + '<p>'+_('Update <b>only</b> if one of the '
'new features or bug fixes is important to you. ' 'new features or bug fixes is important to you. '
'If the current version works well for you, do not update.'))%(__appname__, version)) 'If the current version works well for you, do not update.'))%(
__appname__, calibre_version))
self.label.setOpenExternalLinks(True) self.label.setOpenExternalLinks(True)
self.label.setWordWrap(True) self.label.setWordWrap(True)
self.setWindowTitle(_('Update available!')) self.setWindowTitle(_('Update available!'))
@ -78,18 +91,30 @@ class UpdateNotification(QDialog):
b = self.bb.addButton(_('&Get update'), self.bb.AcceptRole) b = self.bb.addButton(_('&Get update'), self.bb.AcceptRole)
b.setDefault(True) b.setDefault(True)
b.setIcon(QIcon(I('arrow-down.png'))) b.setIcon(QIcon(I('arrow-down.png')))
if plugin_updates > 0:
b = self.bb.addButton(_('Update &plugins'), self.bb.ActionRole)
b.setIcon(QIcon(I('plugins/plugin_updater.png')))
b.clicked.connect(self.get_plugins, type=Qt.QueuedConnection)
self.bb.addButton(self.bb.Cancel) self.bb.addButton(self.bb.Cancel)
self.l.addWidget(self.bb, 2, 0, 1, -1) self.l.addWidget(self.bb, 2, 0, 1, -1)
self.bb.accepted.connect(self.accept) self.bb.accepted.connect(self.accept)
self.bb.rejected.connect(self.reject) self.bb.rejected.connect(self.reject)
dynamic.set('update to version %s'%version, False) dynamic.set('update to version %s'%calibre_version, False)
def get_plugins(self):
from calibre.gui2.dialogs.plugin_updater import (PluginUpdaterDialog,
FILTER_UPDATE_AVAILABLE)
d = PluginUpdaterDialog(self.parent(),
initial_filter=FILTER_UPDATE_AVAILABLE)
d.exec_()
def show_future(self, *args): def show_future(self, *args):
config.set('new_version_notification', bool(self.cb.isChecked())) config.set('new_version_notification', bool(self.cb.isChecked()))
def accept(self): def accept(self):
url = 'http://calibre-ebook.com/download_'+\ url = ('http://calibre-ebook.com/download_' +
('windows' if iswindows else 'osx' if isosx else 'linux') ('portable' if isportable else 'windows' if iswindows
else 'osx' if isosx else 'linux'))
open_url(QUrl(url)) open_url(QUrl(url))
QDialog.accept(self) QDialog.accept(self)
@ -101,33 +126,68 @@ class UpdateMixin(object):
self.update_checker = CheckForUpdates(self) self.update_checker = CheckForUpdates(self)
self.update_checker.update_found.connect(self.update_found, self.update_checker.update_found.connect(self.update_found,
type=Qt.QueuedConnection) type=Qt.QueuedConnection)
self.update_checker.plugin_update_found.connect(self.plugin_update_found,
type=Qt.QueuedConnection)
self.update_checker.start() self.update_checker.start()
def update_found(self, version, force=False): def update_found(self, version, force=False):
os = 'windows' if iswindows else 'osx' if isosx else 'linux' try:
url = 'http://calibre-ebook.com/download_%s'%os calibre_version, plugin_updates = version.split(VSEP)
self.status_bar.new_version_available(version, url) plugin_updates = int(plugin_updates)
except:
traceback.print_exc()
return
has_calibre_update = calibre_version and calibre_version != NO_CALIBRE_UPDATE
has_plugin_updates = plugin_updates > 0
if not has_calibre_update and not has_plugin_updates:
self.status_bar.update_label.setVisible(False)
return
if has_calibre_update:
plt = u''
if has_plugin_updates:
plt = ' (%d plugin updates)'%plugin_updates
msg = (u'<span style="color:red; font-weight: bold">%s: '
u'<a href="update:%s">%s%s</a></span>') % (
_('Update found'), version, calibre_version, plt)
else:
msg = (u'<a href="update:%s">%d %s</a>')%(version, plugin_updates,
_('updated plugins'))
self.status_bar.update_label.setText(msg)
self.status_bar.update_label.setVisible(True)
if force or (config.get('new_version_notification') and \ if has_plugin_updates:
dynamic.get('update to version %s'%version, True)): self.plugin_update_found(plugin_updates)
self._update_notification__ = UpdateNotification(version,
parent=self)
self._update_notification__.show()
def plugin_update_found(self, updates, icon_only=False): if has_calibre_update:
if force or (config.get('new_version_notification') and \
dynamic.get('update to version %s'%calibre_version, True)):
self._update_notification__ = UpdateNotification(calibre_version,
plugin_updates, parent=self)
self._update_notification__.show()
elif has_plugin_updates:
if force:
from calibre.gui2.dialogs.plugin_updater import (PluginUpdaterDialog,
FILTER_UPDATE_AVAILABLE)
d = PluginUpdaterDialog(self,
initial_filter=FILTER_UPDATE_AVAILABLE)
d.exec_()
def plugin_update_found(self, number_of_updates):
# Change the plugin icon to indicate there are updates available # Change the plugin icon to indicate there are updates available
plugin = self.iactions.get('Plugin Updates', None) plugin = self.iactions.get('Plugin Updates', None)
if not plugin: if not plugin:
return return
if updates: if number_of_updates:
plugin.qaction.setText(_('Plugin Updates')+'*') plugin.qaction.setText(_('Plugin Updates')+'*')
plugin.qaction.setIcon(QIcon(I('plugins/plugin_updater_updates.png'))) plugin.qaction.setIcon(QIcon(I('plugins/plugin_updater_updates.png')))
plugin.qaction.setToolTip(_('There are %d plugin updates available')%len(updates)) plugin.qaction.setToolTip(
_('There are %d plugin updates available')%number_of_updates)
else: else:
plugin.qaction.setText(_('Plugin Updates')) plugin.qaction.setText(_('Plugin Updates'))
plugin.qaction.setIcon(QIcon(I('plugins/plugin_updater.png'))) plugin.qaction.setIcon(QIcon(I('plugins/plugin_updater.png')))
plugin.qaction.setToolTip(_('Install and configure user plugins')) plugin.qaction.setToolTip(_('Install and configure user plugins'))
def update_link_clicked(self, url):
url = unicode(url)
if url.startswith('update:'):
version = url[len('update:'):]
self.update_found(version, force=True)