mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
Merge extensions and information pages.
Check updates for extensions too.
This commit is contained in:
@@ -72,15 +72,16 @@ def check_for_new_version(request, include_all):
|
||||
"""
|
||||
Check if a new version of Modoboa is available.
|
||||
"""
|
||||
from modoboa.core.utils import new_version_available
|
||||
from modoboa.core.utils import check_for_updates
|
||||
|
||||
if not request.user.is_superuser:
|
||||
return []
|
||||
if new_version_available(request) is None:
|
||||
status, extensions = check_for_updates(request)
|
||||
if not status:
|
||||
return [{"id": "newversionavailable"}] if include_all else []
|
||||
return [{
|
||||
"id": "newversionavailable",
|
||||
"url": reverse("core:index") + "#info/",
|
||||
"text": _("New Modoboa version available"),
|
||||
"text": _("One or more updates are available"),
|
||||
"level": "info",
|
||||
}]
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
from django.conf import settings
|
||||
from django.conf.urls import include
|
||||
|
||||
from versionfield.constants import DEFAULT_NUMBER_BITS
|
||||
from versionfield.version import Version
|
||||
|
||||
from modoboa.lib.api_client import ModoAPIClient
|
||||
|
||||
|
||||
class ModoExtension(object):
|
||||
|
||||
@@ -101,14 +106,29 @@ class ExtensionsPool(object):
|
||||
extinstance.load()
|
||||
return result
|
||||
|
||||
def list_all(self):
|
||||
def list_all(self, check_new_versions=False):
|
||||
"""List all defined extensions."""
|
||||
result = []
|
||||
if check_new_versions:
|
||||
new_extensions = ModoAPIClient().list_extensions()
|
||||
new_extensions = dict(
|
||||
(ext["name"], ext["version"]) for ext in new_extensions
|
||||
)
|
||||
else:
|
||||
new_extensions = {}
|
||||
for extname, extdef in self.extensions.iteritems():
|
||||
if not extdef["show"]:
|
||||
continue
|
||||
infos = self.get_extension_infos(extname)
|
||||
infos["id"] = extname
|
||||
local_version = Version(infos["version"], DEFAULT_NUMBER_BITS)
|
||||
pkgname = infos["name"].replace("_", "-")
|
||||
if pkgname in new_extensions:
|
||||
infos["last_version"] = new_extensions[pkgname]
|
||||
last_version = Version(
|
||||
new_extensions[pkgname], DEFAULT_NUMBER_BITS)
|
||||
if last_version > local_version:
|
||||
infos["update"] = True
|
||||
result += [infos]
|
||||
return sorted(result, key=lambda i: i["name"])
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
|
||||
<h2>{% trans "Extensions" %} <small>{% trans "The extension(s) you are using" %}</small></h2><hr />
|
||||
<table id="extensions" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Version" %}</th>
|
||||
<th>{% trans "Description" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for extension in extensions %}
|
||||
<tr>
|
||||
<td>{{ extension.label }}</td>
|
||||
<td>{{ extension.version }}</td>
|
||||
<td>{{ extension.description }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,25 +1,50 @@
|
||||
{% load i18n core_tags lib_tags %}
|
||||
<h2>{% trans "Information" %} <small>{% trans "Various information about Modoboa" %}</small></h2><hr>
|
||||
{% if new_version %}
|
||||
{% if update_avail %}
|
||||
<div class="alert alert-block alert-success">
|
||||
<h4>{% trans "An update is available!" %}</h4>
|
||||
{% blocktrans with version=new_version.version changelog_url=new_version.changelog_url %}
|
||||
Modoboa <strong>{{ version }}</strong> is available for download. The list of all changes is available <a href="{{ changelog_url }}" target="_blank">here</a>.
|
||||
{% endblocktrans %}
|
||||
<h4>{% trans "One or more updates are available!" %}</h4>
|
||||
<p>{% trans "Check the following list to find the component(s) that can be updated." %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="alert alert-info">Modoboa <strong>{% get_version %}</strong> {% trans "is currently in use." %}</div>
|
||||
|
||||
<h3>{% trans "Applications" %}</h3>
|
||||
<table id="extensions" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Installed version" %}</th>
|
||||
<th>{% trans "Last version" %}</th>
|
||||
<th>{% trans "Description" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for extension in extensions %}
|
||||
<tr{% if extension.update %} class="success"{% endif %}>
|
||||
<td>{{ extension.label }}</td>
|
||||
<td>{{ extension.version }}</td>
|
||||
<td>{% if extension.update %}<strong>{% if extension.changelog_url %}<a href="{{ extension.changelog_url }}">{{ extension.last_version }}</a>{% else %}{{ extension.last_version }}{% endif %}</strong>{% else %}{{ extension.last_version }}{% endif %}</td>
|
||||
<td>{{ extension.description }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>{% trans "Active users" %}</h3>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Group name" %}</th>
|
||||
<th>{% trans "Last login" %}</th>
|
||||
</tr>
|
||||
{% connected_users as users %}{% for u in users %}<tr>
|
||||
<td>{{ u.username }}</td>
|
||||
<td>{{ u.group }}</td>
|
||||
<td>{{ u.last_login }}</td>
|
||||
</tr>{% endfor %}
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Group name" %}</th>
|
||||
<th>{% trans "Last login" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% connected_users as users %}{% for u in users %}
|
||||
<tr>
|
||||
<td>{{ u.username }}</td>
|
||||
<td>{{ u.group }}</td>
|
||||
<td>{{ u.last_login }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -46,11 +46,6 @@ def extensions_menu(selection, user):
|
||||
@register.simple_tag
|
||||
def admin_menu(selection, user):
|
||||
entries = [
|
||||
{"name": "extensions",
|
||||
"class": "ajaxnav",
|
||||
"url": "extensions/",
|
||||
"label": _("Extensions"),
|
||||
"img": ""},
|
||||
{"name": "info",
|
||||
"class": "ajaxnav",
|
||||
"url": "info/",
|
||||
@@ -151,7 +146,7 @@ def visirule(field):
|
||||
% (rule["field"], rule["value"])
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
@register.assignment_tag
|
||||
def get_version():
|
||||
import pkg_resources
|
||||
return pkg_resources.get_distribution("modoboa").version
|
||||
|
||||
@@ -15,8 +15,6 @@ urlpatterns = patterns(
|
||||
name="parameter_listl"),
|
||||
url(r'^core/parameters/save/$', 'modoboa.core.views.admin.saveparameters',
|
||||
name="parameter_save"),
|
||||
url(r'^core/extensions/$', 'modoboa.core.views.admin.viewextensions',
|
||||
name="extension_list"),
|
||||
url(r'^core/info/$', 'modoboa.core.views.admin.information',
|
||||
name="information"),
|
||||
url(r'^core/logs/$', 'modoboa.core.views.admin.logs', name="log_list"),
|
||||
|
||||
+21
-3
@@ -1,13 +1,31 @@
|
||||
"""Utility functions."""
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django.contrib.sites.models import get_current_site
|
||||
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib.api_client import ModoAPIClient
|
||||
|
||||
|
||||
def new_version_available(request):
|
||||
def check_for_updates(request):
|
||||
"""Check if a new version of Modoboa is available."""
|
||||
if parameters.get_admin("CHECK_NEW_VERSIONS") == "no":
|
||||
return None
|
||||
return ModoAPIClient().current_version(get_current_site(request))
|
||||
return False, []
|
||||
client = ModoAPIClient()
|
||||
extensions = exts_pool.list_all(True)
|
||||
extensions = [{
|
||||
"label": "Modoboa",
|
||||
"description": _("The core part of Modoboa"),
|
||||
"update": client.new_core_version(get_current_site(request)),
|
||||
"last_version": client.latest_core_version,
|
||||
"changelog_url": client.changelog_url,
|
||||
"version": client.local_core_version
|
||||
}] + extensions
|
||||
update_avail = False
|
||||
for extension in extensions:
|
||||
if "update" in extension:
|
||||
update_avail = True
|
||||
break
|
||||
return update_avail, extensions
|
||||
|
||||
@@ -8,8 +8,9 @@ from django.shortcuts import render
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from modoboa.core.models import Log
|
||||
from modoboa.core.utils import new_version_available
|
||||
from modoboa.core.utils import check_for_updates
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.lib.listing import get_sort_order, get_listing_page
|
||||
from modoboa.lib.web_utils import (
|
||||
@@ -51,25 +52,14 @@ def saveparameters(request):
|
||||
return render_to_json_response(_("Parameters saved"))
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def viewextensions(request, tplname='core/extensions.html'):
|
||||
"""List available extensions."""
|
||||
from modoboa.core.extensions import exts_pool
|
||||
|
||||
exts = exts_pool.list_all()
|
||||
return render_to_json_response({
|
||||
"callback": "extensions",
|
||||
"content": _render_to_string(request, tplname, {"extensions": exts})
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def information(request, tplname="core/information.html"):
|
||||
status, extensions = check_for_updates(request)
|
||||
return render_to_json_response({
|
||||
"content": render_to_string(tplname, {
|
||||
"new_version": new_version_available(request)
|
||||
"update_avail": status,
|
||||
"extensions": extensions,
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ class ModoAPIClient(object):
|
||||
settings.MODOBOA_API_URL if api_url is None
|
||||
else api_url
|
||||
)
|
||||
self._local_core_version = None
|
||||
self._latest_core_version = None
|
||||
self.changelog_url = None
|
||||
|
||||
def __send_request(self, url, params=None):
|
||||
"""Send a request to the API."""
|
||||
@@ -35,18 +38,34 @@ class ModoAPIClient(object):
|
||||
return None
|
||||
return resp.json()
|
||||
|
||||
def current_version(self, site):
|
||||
@property
|
||||
def local_core_version(self):
|
||||
"""Return the version installed locally."""
|
||||
if self._local_core_version is None:
|
||||
self._local_core_version = pkg_resources.get_distribution(
|
||||
"modoboa").version
|
||||
return self._local_core_version
|
||||
|
||||
@property
|
||||
def latest_core_version(self):
|
||||
"""Return the latest core version."""
|
||||
if self._latest_core_version is None:
|
||||
return self._local_core_version
|
||||
return self._latest_core_version
|
||||
|
||||
def new_core_version(self, site):
|
||||
"""Check the latest version."""
|
||||
client_version = pkg_resources.get_distribution("modoboa").version
|
||||
url = os.path.join(self._api_url, "current_version/")
|
||||
params = {"client_version": client_version, "site": site}
|
||||
params = {"client_version": self.local_core_version, "site": site}
|
||||
resp = self.__send_request(url, params)
|
||||
if resp is None:
|
||||
return None
|
||||
version = Version(resp["version"], DEFAULT_NUMBER_BITS)
|
||||
if version <= Version(client_version, DEFAULT_NUMBER_BITS):
|
||||
return None
|
||||
return resp
|
||||
if version <= Version(self.local_core_version, DEFAULT_NUMBER_BITS):
|
||||
return False
|
||||
self._latest_core_version = resp["version"]
|
||||
self.changelog_url = resp["changelog_url"]
|
||||
return True
|
||||
|
||||
def list_extensions(self):
|
||||
"""List all official extensions."""
|
||||
|
||||
Reference in New Issue
Block a user