diff --git a/rhodecode/apps/debug_style/views.py b/rhodecode/apps/debug_style/views.py --- a/rhodecode/apps/debug_style/views.py +++ b/rhodecode/apps/debug_style/views.py @@ -102,6 +102,11 @@ Check if we should use full-topic or min 'date': datetime.datetime.now(), }, + 'update_available': { + 'current_ver': '4.23.0', + 'latest_ver': '4.24.0', + }, + 'exception': { 'email_prefix': '[RHODECODE ERROR]', 'exc_id': exc_traceback['exc_id'], diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -33,9 +33,9 @@ from email.utils import formatdate import rhodecode from rhodecode.lib import audit_logger -from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask +from rhodecode.lib.celerylib import get_logger, async_task, RequestContextTask, run_task from rhodecode.lib import hooks_base -from rhodecode.lib.utils2 import safe_int, str2bool +from rhodecode.lib.utils2 import safe_int, str2bool, aslist from rhodecode.model.db import ( Session, IntegrityError, true, Repository, RepoGroup, User) @@ -338,15 +338,39 @@ def repo_maintenance(repoid): @async_task(ignore_result=True) -def check_for_update(): +def check_for_update(send_email_notification=True, email_recipients=None): from rhodecode.model.update import UpdateModel + from rhodecode.model.notification import EmailNotificationModel + + log = get_logger(check_for_update) update_url = UpdateModel().get_update_url() cur_ver = rhodecode.__version__ try: data = UpdateModel().get_update_data(update_url) - latest = data['versions'][0] - UpdateModel().store_version(latest['version']) + + current_ver = UpdateModel().get_stored_version(fallback=cur_ver) + latest_ver = data['versions'][0]['version'] + UpdateModel().store_version(latest_ver) + + if send_email_notification: + log.debug('Send email notification is enabled. ' + 'Current RhodeCode version: %s, latest known: %s', current_ver, latest_ver) + if UpdateModel().is_outdated(current_ver, latest_ver): + + email_kwargs = { + 'current_ver': current_ver, + 'latest_ver': latest_ver, + } + + (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email( + EmailNotificationModel.TYPE_UPDATE_AVAILABLE, **email_kwargs) + + email_recipients = aslist(email_recipients, sep=',') or \ + [user.email for user in User.get_all_super_admins()] + run_task(send_email, email_recipients, subject, + email_body_plaintext, email_body) + except Exception: pass diff --git a/rhodecode/model/notification.py b/rhodecode/model/notification.py --- a/rhodecode/model/notification.py +++ b/rhodecode/model/notification.py @@ -343,6 +343,7 @@ class EmailNotificationModel(BaseModel): TYPE_PASSWORD_RESET_CONFIRMATION = 'password_reset_confirmation' TYPE_EMAIL_TEST = 'email_test' TYPE_EMAIL_EXCEPTION = 'exception' + TYPE_UPDATE_AVAILABLE = 'update_available' TYPE_TEST = 'test' email_types = { @@ -352,6 +353,8 @@ class EmailNotificationModel(BaseModel): 'rhodecode:templates/email_templates/test.mako', TYPE_EMAIL_EXCEPTION: 'rhodecode:templates/email_templates/exception_tracker.mako', + TYPE_UPDATE_AVAILABLE: + 'rhodecode:templates/email_templates/update_available.mako', TYPE_EMAIL_TEST: 'rhodecode:templates/email_templates/email_test.mako', TYPE_REGISTRATION: diff --git a/rhodecode/model/update.py b/rhodecode/model/update.py --- a/rhodecode/model/update.py +++ b/rhodecode/model/update.py @@ -60,11 +60,11 @@ class UpdateModel(BaseModel): Session().add(setting) Session().commit() - def get_stored_version(self): + def get_stored_version(self, fallback=None): obj = SettingsModel().get_setting_by_name(self.UPDATE_SETTINGS_KEY) if obj: return obj.app_settings_value - return '0.0.0' + return fallback or '0.0.0' def _sanitize_version(self, version): """ diff --git a/rhodecode/templates/email_templates/update_available.mako b/rhodecode/templates/email_templates/update_available.mako new file mode 100644 --- /dev/null +++ b/rhodecode/templates/email_templates/update_available.mako @@ -0,0 +1,32 @@ +## -*- coding: utf-8 -*- +<%inherit file="base.mako"/> + +<%def name="subject()" filter="n,trim,whitespace_filter"> +New Version of RhodeCode is available ! + + +## plain text version of the email. Empty by default +<%def name="body_plaintext()" filter="n,trim"> +A new version of RhodeCode is available! + +Your version: ${current_ver} +New version: ${latest_ver} + +Release notes: + +https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html + + +## BODY GOES BELOW + +

A new version of RhodeCode is available!

+
+Your version: ${current_ver}
+New version: ${latest_ver}
+ +

Release notes

+ + + https://docs.rhodecode.com/RhodeCode-Enterprise/release-notes/release-notes-${latest_ver}.html + +