diff --git a/mayan/apps/common/apps.py b/mayan/apps/common/apps.py index a415d5e7c3..aee19c5aaa 100644 --- a/mayan/apps/common/apps.py +++ b/mayan/apps/common/apps.py @@ -20,10 +20,10 @@ from .handlers import ( user_locale_profile_session_config, user_locale_profile_create ) from .links import ( - link_about, link_code, link_current_user_details, link_current_user_edit, - link_current_user_locale_profile_edit, link_documentation, link_filters, - link_forum, link_license, link_packages_licenses, link_setup, link_support, - link_tools + link_about, link_check_version, link_code, link_current_user_details, + link_current_user_edit, link_current_user_locale_profile_edit, + link_documentation, link_filters, link_forum, link_license, + link_packages_licenses, link_setup, link_support, link_tools ) from .literals import DELETE_STALE_UPLOADS_INTERVAL from .menus import menu_about, menu_main, menu_tools, menu_user @@ -123,6 +123,7 @@ class CommonApp(MayanAppConfig): links=( link_about, link_support, link_documentation, link_forum, link_code, link_license, link_packages_licenses, + link_check_version ) ) diff --git a/mayan/apps/common/exceptions.py b/mayan/apps/common/exceptions.py new file mode 100644 index 0000000000..54a297ca1f --- /dev/null +++ b/mayan/apps/common/exceptions.py @@ -0,0 +1,16 @@ +from __future__ import unicode_literals + + +class BaseCommonException(Exception): + """ + Base exception for the common app + """ + pass + + +class NotLatestVersion(BaseCommonException): + """ + The installed version is not the latest available version + """ + def __init__(self, upstream_version): + self.upstream_version = upstream_version diff --git a/mayan/apps/common/links.py b/mayan/apps/common/links.py index 35c48647e6..e4407c6d4b 100644 --- a/mayan/apps/common/links.py +++ b/mayan/apps/common/links.py @@ -8,6 +8,10 @@ from navigation import Link link_about = Link( icon='fa fa-info', text=_('About this'), view='common:about_view' ) +link_check_version = Link( + icon='fa fa-refresh', text=_('Check for updates'), + view='common:check_version_view' +) link_current_user_details = Link( icon='fa fa-user', text=_('User details'), view='common:current_user_details' diff --git a/mayan/apps/common/literals.py b/mayan/apps/common/literals.py index ca8bee1dcc..af4bd308ad 100644 --- a/mayan/apps/common/literals.py +++ b/mayan/apps/common/literals.py @@ -4,7 +4,8 @@ from django.utils.translation import ugettext_lazy as _ DELETE_STALE_UPLOADS_INTERVAL = 60 * 10 # 10 minutes - +MAYAN_PYPI_NAME = 'mayan-edms' +PYPI_URL = 'https://pypi.python.org/pypi' TIME_DELTA_UNIT_DAYS = 'days' TIME_DELTA_UNIT_HOURS = 'hours' TIME_DELTA_UNIT_MINUTES = 'minutes' diff --git a/mayan/apps/common/urls.py b/mayan/apps/common/urls.py index 94be8df7ce..403aadd7df 100644 --- a/mayan/apps/common/urls.py +++ b/mayan/apps/common/urls.py @@ -5,7 +5,7 @@ from django.views.i18n import javascript_catalog, set_language from .api_views import APIContentTypeList from .views import ( - AboutView, CurrentUserDetailsView, CurrentUserEditView, + AboutView, CheckVersionView, CurrentUserDetailsView, CurrentUserEditView, CurrentUserLocaleProfileDetailsView, CurrentUserLocaleProfileEditView, FaviconRedirectView, FilterResultListView, FilterSelectView, HomeView, LicenseView, PackagesLicensesView, SetupListView, ToolsListView, @@ -15,6 +15,10 @@ from .views import ( urlpatterns = [ url(r'^$', HomeView.as_view(), name='home'), url(r'^about/$', AboutView.as_view(), name='about_view'), + url( + r'^check_version/$', CheckVersionView.as_view(), + name='check_version_view' + ), url(r'^license/$', LicenseView.as_view(), name='license_view'), url( r'^packages/licenses/$', PackagesLicensesView.as_view(), diff --git a/mayan/apps/common/utils.py b/mayan/apps/common/utils.py index 1f03bc2e23..1ef8f55199 100644 --- a/mayan/apps/common/utils.py +++ b/mayan/apps/common/utils.py @@ -5,17 +5,32 @@ import os import shutil import tempfile import types +import xmlrpclib from django.conf import settings from django.utils.datastructures import MultiValueDict from django.utils.http import urlquote as django_urlquote from django.utils.http import urlencode as django_urlencode +import mayan + +from .exceptions import NotLatestVersion +from .literals import MAYAN_PYPI_NAME, PYPI_URL from .settings import setting_temporary_directory logger = logging.getLogger(__name__) +def check_version(): + pypi = xmlrpclib.ServerProxy(PYPI_URL) + versions = pypi.package_releases(MAYAN_PYPI_NAME) + + if versions[0] != mayan.__version__: + raise NotLatestVersion(upstream_version=versions[0]) + else: + return True + + # http://stackoverflow.com/questions/123198/how-do-i-copy-a-file-in-python def copyfile(source, destination, buffer_size=1024 * 1024): """ diff --git a/mayan/apps/common/views.py b/mayan/apps/common/views.py index 1d63537e7b..ff52af047e 100644 --- a/mayan/apps/common/views.py +++ b/mayan/apps/common/views.py @@ -13,6 +13,7 @@ from django.utils.translation import ugettext_lazy as _, ugettext from django.views.generic import RedirectView, TemplateView from .classes import Filter +from .exceptions import NotLatestVersion from .forms import ( FilterForm, LicenseForm, LocaleProfileForm, LocaleProfileForm_view, PackagesLicensesForm, UserForm, UserForm_view @@ -25,12 +26,33 @@ from .generics import ( # NOQA SimpleView ) from .menus import menu_tools, menu_setup +from .utils import check_version class AboutView(TemplateView): template_name = 'appearance/about.html' +class CheckVersionView(SimpleView): + template_name = 'appearance/generic_template.html' + + def get_extra_context(self): + try: + check_version() + except NotLatestVersion as exception: + message = _( + 'The version you are using is outdated. The latest version ' + 'is {}'.format(exception.upstream_version) + ) + else: + message = _('Your version is up-to-date.') + + return { + 'title': _('Check for updates'), + 'content': message + } + + class CurrentUserDetailsView(SingleObjectDetailView): form_class = UserForm_view