mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
Merge branch 'master' into nvd3
This commit is contained in:
+3
-3
@@ -41,16 +41,16 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Modoboa'
|
||||
copyright = u'2013, Antoine Nguyen'
|
||||
copyright = u'2014, Antoine Nguyen'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
version = '1.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0.1'
|
||||
release = '1.1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -242,6 +242,17 @@ Modoboa should connect to your LDAP server. They are described just below:
|
||||
| |server is an Active | |
|
||||
| |Directory one | |
|
||||
+--------------------+---------------------------------+--------------------+
|
||||
|Administrator groups|Members of those LDAP Posix | |
|
||||
| |groups will be created ad domain | |
|
||||
| |administrators. Use ';' | |
|
||||
| |characters to separate groups. | |
|
||||
+--------------------+---------------------------------+--------------------+
|
||||
|Groups search base |The distinguished name of the | |
|
||||
| |search base used to find groups | |
|
||||
| | | |
|
||||
| | | |
|
||||
+--------------------+---------------------------------+--------------------+
|
||||
|
||||
|
||||
If you need additional parameters, you will find a detailled
|
||||
documentation `here <http://packages.python.org/django-auth-ldap/>`_.
|
||||
@@ -250,12 +261,14 @@ Once the authentication is properly configured, the users defined in
|
||||
your LDAP directory will be able to connect to Modoboa, the associated
|
||||
domain and mailboxes will be automatically created if needed.
|
||||
|
||||
.. note::
|
||||
The first time a user connects to Modoboa, a local account is created
|
||||
if the LDAP username is a valid email address. By default, this
|
||||
account belongs to the *SimpleUsers* group and it has a mailbox.
|
||||
|
||||
Users created automatically from an LDAP directory belongs to the
|
||||
*SimpleUsers* group and have a mailbox. To do so, usernames have to
|
||||
be valid email addresses. If not, LDAP users won't be able to
|
||||
access Modoboa.
|
||||
To automatically create domain administrators, you can use the
|
||||
**Administrator groups** setting. If a LDAP user belongs to one the
|
||||
listed groups, its local account will belong to the *DomainAdmins*
|
||||
group. In this case, the username is not necessarily an email address.
|
||||
|
||||
Users will also be able to update their LDAP password directly from
|
||||
Modoboa.
|
||||
|
||||
@@ -46,7 +46,7 @@ listing page: *relay domain* and *relay domain alias*.
|
||||
The extension is compatible with the *amavis* and *limits*
|
||||
ones. Resellers will be able to create both new objects.
|
||||
|
||||
To tell Postfix this feature exists, you must generate two new map
|
||||
Replace <driver> by the name of the database you use.To tell Postfix this feature exists, you must generate two new map
|
||||
files and then update your configuration.
|
||||
|
||||
To generate the map files, run the following command::
|
||||
@@ -55,7 +55,23 @@ To generate the map files, run the following command::
|
||||
|
||||
Replace values between ``<>`` by yours.
|
||||
|
||||
Edit the :file:`/etc/postfix/main.cf` file.
|
||||
Edit the :file:`/etc/postfix/main.cf` file and copy the following
|
||||
lines inside::
|
||||
|
||||
relay_domains = <driver>:/etc/postfix/maps/sql-relaydomains.cf
|
||||
transport_maps =
|
||||
<driver>:/etc/postfix/maps/sql-relaydomains-transport.cf
|
||||
<driver>:/etc/postfix/maps/sql-relaydomain-aliases-transport.cf
|
||||
|
||||
smtpd_recipient_restrictions =
|
||||
permit_mynetworks
|
||||
reject_unauth_destination
|
||||
check_recipient_access
|
||||
<driver>:/etc/postfix/maps/sql-relay-recipient-verification.cf
|
||||
|
||||
Replace ``<driver>`` by the name of the database you use.
|
||||
|
||||
Reload postfix.
|
||||
|
||||
.. _amavis_frontend:
|
||||
|
||||
@@ -311,12 +327,11 @@ configuration files as follows:
|
||||
|
||||
``/etc/postfix/main.cf``::
|
||||
|
||||
transport_maps = mysql:/etc/postfix/maps/sql-transport.cf
|
||||
virtual_alias_maps = mysql:/etc/postfix/maps/sql-aliases.cf
|
||||
mysql:/etc/postfix/mapfiles/sql-domain-aliases-mailboxes.cf,
|
||||
mysql:/etc/postfix/mapfiles/sql-email2email.cf,
|
||||
mysql:/etc/postfix/maps/sql-autoreplies.cf,
|
||||
mysql:/etc/postfix/mapfiles/sql-catchall-aliases.cf
|
||||
transport_maps = mysql:/etc/postfix/maps/sql-autoreplies-transport.cf
|
||||
virtual_alias_maps = <driver>:/etc/postfix/maps/sql-aliases.cf
|
||||
<driver>:/etc/postfix/mapfiles/sql-domain-aliases-mailboxes.cf,
|
||||
<driver>:/etc/postfix/maps/sql-autoreplies.cf,
|
||||
<driver>:/etc/postfix/mapfiles/sql-catchall-aliases.cf
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -327,7 +342,8 @@ configuration files as follows:
|
||||
autoreply unix - n n - - pipe
|
||||
flags= user=vmail:<group> argv=<modoboa_site>/manage.py autoreply $sender $mailbox
|
||||
|
||||
``<modoboa_site>`` is the path of your Modoboa instance.
|
||||
Replace ``<driver>`` by the name of the database you
|
||||
use. ``<modoboa_site>`` is the path of your Modoboa instance.
|
||||
|
||||
Then, create the requested map files::
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ Finally, follow the common procedure::
|
||||
|
||||
.. _1.1.0:
|
||||
|
||||
1.1.0: FIXME
|
||||
============
|
||||
1.1.0: relay domains and better passwords encryption
|
||||
====================================================
|
||||
|
||||
Due to code refactoring, some modifications need to be done into
|
||||
:file:`settings.py`:
|
||||
@@ -72,7 +72,9 @@ Due to code refactoring, some modifications need to be done into
|
||||
'modoboa.extensions.sievefilters',
|
||||
)
|
||||
|
||||
#. Add ``'modoboa.extensions.postfix_relay_domains'`` to ``MODOBOA_APPS``
|
||||
#. Add ``'modoboa.extensions.postfix_relay_domains'`` to
|
||||
``MODOBOA_APPS``, just before
|
||||
``'modoboa.extensions.limits'``
|
||||
|
||||
#. ``AUTH_USER_MODEL`` must be set to ``core.User``
|
||||
|
||||
@@ -81,6 +83,7 @@ Due to code refactoring, some modifications need to be done into
|
||||
|
||||
Then, run the following commands to migrate your installation::
|
||||
|
||||
$ python manage.py syncdb
|
||||
$ python manage.py migrate core 0001 --fake
|
||||
$ python manage.py migrate
|
||||
$ python manage.py collectstatic
|
||||
|
||||
@@ -44,14 +44,26 @@ Then, edit the ``inbox`` namespace and add the following lines::
|
||||
special_use = \Trash
|
||||
}
|
||||
|
||||
It ensures all the special mailboxes will be automaticaly created for
|
||||
new accounts.
|
||||
With dovecot 2.1+, it ensures all the special mailboxes will be
|
||||
automaticaly created for new accounts.
|
||||
|
||||
For dovecot 2.0 and older, use the `autocreate
|
||||
<http://wiki2.dovecot.org/Plugins/Autocreate>`_ plugin.
|
||||
|
||||
.. _fs_operations:
|
||||
|
||||
Operations on the file system
|
||||
-----------------------------
|
||||
|
||||
.. warning::
|
||||
|
||||
Modoboa needs to access the ``dovecot`` binary to check its
|
||||
version. To find the binary path, we use the ``which`` command
|
||||
first and then try known locations (:file:`/usr/sbin/dovecot` and
|
||||
:file:`/usr/local/sbin/dovecot`). If you installed dovecot in a
|
||||
custom location, please tell us where the binary is by using the
|
||||
``DOVECOT_LOOKUP_PATH`` setting (see :file:`settings.py`).
|
||||
|
||||
Three operation types are considered:
|
||||
|
||||
#. Mailbox creation
|
||||
@@ -443,15 +455,9 @@ Use the following configuration in the :file:`/etc/postfix/main.cf` file
|
||||
virtual_transport = dovecot
|
||||
dovecot_destination_recipient_limit = 1
|
||||
|
||||
virtual_minimum_uid = <vmail user id>
|
||||
virtual_gid_maps = static:<vmail group id>
|
||||
virtual_uid_maps = static:<vmail user id>
|
||||
virtual_mailbox_base = /var/vmail
|
||||
|
||||
relay_domains =
|
||||
virtual_mailbox_domains = <driver>:/etc/postfix/sql-domains.cf
|
||||
virtual_alias_domains = <driver>:/etc/postfix/sql-domain-aliases.cf
|
||||
virtual_mailbox_maps = <driver>:/etc/postfix/sql-mailboxes.cf
|
||||
virtual_alias_maps = <driver>:/etc/postfix/sql-aliases.cf,
|
||||
<driver>:/etc/postfix/sql-domain-aliases-mailboxes.cf,
|
||||
<driver>:/etc/postfix/sql-catchall-aliases.cf
|
||||
|
||||
@@ -104,13 +104,6 @@ class DomainsAliasesMap(MapFile):
|
||||
sqlite = "SELECT dom.name FROM admin_domain dom INNER JOIN admin_domainalias domal ON dom.id=domal.target_id WHERE domal.name='%s' AND domal.enabled=1 AND dom.enabled=1"
|
||||
|
||||
|
||||
class MailboxesMap(MapFile):
|
||||
filename = 'sql-mailboxes.cf'
|
||||
mysql = "SELECT 1 FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user user ON mb.user_id=user.id WHERE dom.enabled=1 AND dom.name='%d' AND user.is_active=1 AND mb.address='%u'"
|
||||
postgres = "SELECT 1 FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user u ON mb.user_id=u.id WHERE dom.enabled AND dom.name='%d' AND u.is_active AND mb.address='%u'"
|
||||
sqlite = "SELECT 1 FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id INNER JOIN core_user user ON mb.user_id=user.id WHERE dom.enabled=1 AND dom.name='%d' AND user.is_active=1 AND mb.address='%u'"
|
||||
|
||||
|
||||
class AliasesMap(MapFile):
|
||||
filename = 'sql-aliases.cf'
|
||||
mysql = "(SELECT concat(mb.address, '@', dom.name) FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE mb.id IN (SELECT al_mb.mailbox_id FROM admin_alias_mboxes al_mb INNER JOIN admin_alias al ON al_mb.alias_id=al.id INNER JOIN admin_domain dom ON al.domain_id=dom.id WHERE dom.name='%d' AND dom.enabled=1 AND al.address='%u' AND al.enabled=1)) UNION (SELECT concat(al.address, '@', dom.name) FROM admin_alias al INNER JOIN admin_domain dom ON al.domain_id=dom.id WHERE al.id IN (SELECT al_al.to_alias_id FROM admin_alias_aliases al_al INNER JOIN admin_alias al ON al_al.from_alias_id=al.id INNER JOIN admin_domain dom ON al.domain_id=dom.id WHERE dom.name='%d' AND dom.enabled=1 AND al.address='%u' AND al.enabled=1)) UNION (SELECT al.extmboxes FROM admin_alias al INNER JOIN admin_domain dom ON al.domain_id=dom.id WHERE dom.name='%d' AND dom.enabled=1 AND al.address='%u' AND al.enabled=1 AND al.extmboxes<>'')"
|
||||
@@ -141,7 +134,7 @@ class MaintainMap(MapFile):
|
||||
|
||||
class TransportMap(MapFile):
|
||||
category = "autoreply"
|
||||
filename = 'sql-transport.cf'
|
||||
filename = 'sql-autoreplies-transport.cf'
|
||||
mysql = "SELECT method FROM postfix_autoreply_transport WHERE domain='%s'"
|
||||
postgres = "SELECT method FROM postfix_autoreply_transport WHERE domain='%s'"
|
||||
sqlite = "SELECT method FROM postfix_autoreply_transport WHERE domain='%s'"
|
||||
@@ -155,20 +148,36 @@ class AutoRepliesMap(MapFile):
|
||||
sqlite = "SELECT full_address, autoreply_address FROM postfix_autoreply_alias WHERE full_address='%s'"
|
||||
|
||||
|
||||
class RelayDomainsMap(MapFile):
|
||||
category = "relaydomains"
|
||||
filename = "sql-relaydomains.cf"
|
||||
mysql = "SELECT name FROM postfix_relay_domains_relaydomain WHERE name='%s' AND enabled=1"
|
||||
postgres = "SELECT name FROM postfix_relay_domains_relaydomain WHERE name='%s' AND enabled"
|
||||
sqlite = "SELECT name FROM postfix_relay_domains_relaydomain WHERE name='%s' AND enabled=1"
|
||||
|
||||
|
||||
class RelayDomainsTransportMap(MapFile):
|
||||
category = "relaydomains"
|
||||
filename = "sql-relaydomains-transport.cf"
|
||||
mysql = "SELECT CONCAT(srv.name, ':') FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id WHERE rdom.enabled=1 AND rdom.name='%s'"
|
||||
postgres = "SELECT srv.name || ':' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id WHERE rdom.enabled AND rdom.name='%s'"
|
||||
sqlite = "SELECT srv.name || ':' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id WHERE rdom.enabled=1 AND rdom.name='%s'"
|
||||
mysql = "SELECT CONCAT(srv.name, ':[', rdom.target_host, ']') FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id WHERE rdom.enabled=1 AND rdom.name='%s'"
|
||||
postgres = "SELECT srv.name || ':[' || rdom.target_host || ']' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id WHERE rdom.enabled AND rdom.name='%s'"
|
||||
sqlite = "SELECT srv.name || ':[' || rdom.target_host || ']' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id WHERE rdom.enabled=1 AND rdom.name='%s'"
|
||||
|
||||
|
||||
class RelayDomainAliasesTransportMap(MapFile):
|
||||
category = "relaydomains"
|
||||
filename = "sql-relaydomain-aliases-transport.cf"
|
||||
mysql = "SELECT CONCAT(srv.name, ':') FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id INNER JOIN postfix_relay_domains_relaydomainalias AS rdomalias ON rdom.id=rdomalias.target_id WHERE rdom.enabled=1 AND rdomalias.enabled=1 AND rdomalias.name='%s'"
|
||||
postgres = "SELECT srv.name || ':' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id INNER JOIN postfix_relay_domains_relaydomainalias AS rdomalias ON rdom.id=rdomalias.target_id WHERE rdom.enabled AND rdomalias.enabled AND rdomalias.name='%s'"
|
||||
sqlite = "SELECT srv.name || ':' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id INNER JOIN postfix_relay_domains_relaydomainalias AS rdomalias ON rdom.id=rdomalias.target_id WHERE rdom.enabled=1 AND rdomalias.enabled=1 AND rdomalias.name='%s'"
|
||||
mysql = "SELECT CONCAT(srv.name, ':[', rdom.target_host, ']') FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id INNER JOIN postfix_relay_domains_relaydomainalias AS rdomalias ON rdom.id=rdomalias.target_id WHERE rdom.enabled=1 AND rdomalias.enabled=1 AND rdomalias.name='%s'"
|
||||
postgres = "SELECT srv.name || ':[' || rdom.target_host || ']' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id INNER JOIN postfix_relay_domains_relaydomainalias AS rdomalias ON rdom.id=rdomalias.target_id WHERE rdom.enabled AND rdomalias.enabled AND rdomalias.name='%s'"
|
||||
sqlite = "SELECT srv.name || ':[' || rdom.target_host || ']' FROM postfix_relay_domains_service AS srv INNER JOIN postfix_relay_domains_relaydomain AS rdom ON rdom.service_id=srv.id INNER JOIN postfix_relay_domains_relaydomainalias AS rdomalias ON rdom.id=rdomalias.target_id WHERE rdom.enabled=1 AND rdomalias.enabled=1 AND rdomalias.name='%s'"
|
||||
|
||||
|
||||
class RelayRecipientVerification(MapFile):
|
||||
category = "relaydomains"
|
||||
filename = "sql-relay-recipient-verification.cf"
|
||||
mysql = "SELECT 'reject_unverified_recipient' FROM postfix_relay_domains_relaydomain WHERE verify_recipients=1 AND name='%d'"
|
||||
postgres = "SELECT 'reject_unverified_recipient' FROM postfix_relay_domains_relaydomain WHERE verify_recipients AND name='%d'"
|
||||
sqlite = "SELECT 'reject_unverified_recipient' FROM postfix_relay_domains_relaydomain WHERE verify_recipients=1 AND name='%d'"
|
||||
|
||||
|
||||
class PostfixMapsCommand(Command):
|
||||
|
||||
@@ -172,6 +172,8 @@ SOUTH_TESTS_MIGRATE = False
|
||||
|
||||
#MODOBOA_CUSTOM_LOGO = os.path.join(MEDIA_URL, "custom_logo.png")
|
||||
|
||||
#DOVECOT_LOOKUP_PATH = ('/path/to/dovecot', )
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'modoboa.lib.authbackends.SimpleBackend',
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import datetime
|
||||
from optparse import make_option
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
from modoboa.core import load_settings
|
||||
from modoboa.core import load_core_settings
|
||||
from modoboa.core.models import Log
|
||||
from modoboa.lib import parameters
|
||||
|
||||
@@ -37,7 +37,7 @@ class Command(BaseCommand):
|
||||
l.addHandler(logging.StreamHandler())
|
||||
self.verbose = options["verbose"]
|
||||
|
||||
load_settings()
|
||||
load_core_settings()
|
||||
log_maximum_age = int(parameters.get_admin("LOG_MAXIMUM_AGE"))
|
||||
self.__vprint("Deleting logs older than %d days..." % log_maximum_age)
|
||||
limit = timezone.now() - datetime.timedelta(log_maximum_age)
|
||||
|
||||
@@ -17,7 +17,7 @@ from django.contrib.auth.models import (
|
||||
from django.contrib.auth.hashers import make_password, is_password_usable
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.lib.exceptions import (
|
||||
PermDeniedException, InternalError, BadRequest
|
||||
PermDeniedException, InternalError, BadRequest, Conflict
|
||||
)
|
||||
from modoboa.lib.sysutils import exec_cmd
|
||||
from modoboa.core.extensions import exts_pool
|
||||
@@ -325,6 +325,12 @@ class User(PermissionsMixin):
|
||||
_("You can't import an account with a role greater than yours")
|
||||
)
|
||||
self.username = row[1].strip()
|
||||
try:
|
||||
User.objects.get(username=self.username)
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
raise Conflict
|
||||
if role == "SimpleUsers":
|
||||
if (len(row) < 8 or not row[7].strip()):
|
||||
raise BadRequest(
|
||||
|
||||
@@ -20,7 +20,7 @@ def get_password_hasher(scheme):
|
||||
"""
|
||||
try:
|
||||
scheme = scheme.replace('-', '')
|
||||
hasher = globals()['%sHasher' % scheme]
|
||||
except AttributeError:
|
||||
hasher = globals()['%sHasher' % scheme.upper()]
|
||||
except KeyError:
|
||||
hasher = PLAINHasher
|
||||
return hasher
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.lib.webutils import render_to_json_response
|
||||
from modoboa.lib.emailutils import sendmail_simple, sendmail_fromfile
|
||||
from modoboa.lib.decorators import needs_mailbox
|
||||
from modoboa.extensions.admin.lib import needs_mailbox
|
||||
|
||||
|
||||
@login_required
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from modoboa.lib.formutils import YesNoField, SeparatorField
|
||||
from modoboa.lib.sysutils import exec_cmd
|
||||
from modoboa.lib import parameters
|
||||
import os
|
||||
|
||||
|
||||
class AdminParametersForm(parameters.AdminParametersForm):
|
||||
@@ -46,9 +48,19 @@ class AdminParametersForm(parameters.AdminParametersForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AdminParametersForm, self).__init__(*args, **kwargs)
|
||||
hide_fields = False
|
||||
dpath = None
|
||||
code, output = exec_cmd("which dovecot")
|
||||
if not code:
|
||||
dpath = output.strip()
|
||||
else:
|
||||
known_paths = getattr(
|
||||
settings, "DOVECOT_LOOKUP_PATH",
|
||||
("/usr/sbin/dovecot", "/usr/local/sbin/dovecot")
|
||||
)
|
||||
for fpath in known_paths:
|
||||
if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
|
||||
dpath = fpath
|
||||
if dpath:
|
||||
try:
|
||||
code, version = exec_cmd("%s --version" % dpath)
|
||||
except OSError:
|
||||
|
||||
@@ -1 +1 @@
|
||||
[{"pk": 1, "model": "admin.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": false, "last_login": "2012-05-03 16:58:51", "groups": [], "user_permissions": [], "password": "{CRYPT}dTTsGDkA5ZHKg", "email": "", "date_joined": "2012-01-26 15:19:25"}}, {"pk": 2, "model": "admin.user", "fields": {"username": "admin@demo.local", "first_name": "Demo", "last_name": "Administrator", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2012-05-24 05:00:12", "groups": [1], "user_permissions": [], "password": "{CRYPT}SJ2bQWwabfH/6", "email": "admin@demo.local", "date_joined": "2012-05-03 16:50:15"}}, {"pk": 4, "model": "admin.user", "fields": {"username": "user@demo.local", "first_name": "Demo", "last_name": "User", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2012-05-03 16:56:50", "groups": [2], "user_permissions": [], "password": "{CRYPT}2iAFXtxUA6.7Y", "email": "user@demo.local", "date_joined": "2012-05-03 16:56:50"}}, {"pk": 2, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "domain"], "object_id": 1}}, {"pk": 3, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 2}}, {"pk": 4, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "mailbox"], "object_id": 1}}, {"pk": 5, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "alias"], "object_id": 1}}, {"pk": 6, "model": "admin.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "domain"], "object_id": 1}}, {"pk": 7, "model": "admin.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "mailbox"], "object_id": 1}}, {"pk": 8, "model": "admin.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "user"], "object_id": 2}}, {"pk": 9, "model": "admin.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "alias"], "object_id": 1}}, {"pk": 13, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 4}}, {"pk": 14, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "mailbox"], "object_id": 3}}, {"pk": 15, "model": "admin.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "mailbox"], "object_id": 3}}, {"pk": 16, "model": "admin.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "user"], "object_id": 4}}, {"pk": 1, "model": "admin.objectdates", "fields": {"creation": "2012-05-03 16:49:40", "last_modification": "2012-05-03 16:49:40"}}, {"pk": 2, "model": "admin.objectdates", "fields": {"creation": "2012-05-03 16:50:15", "last_modification": "2012-05-03 16:50:36"}}, {"pk": 3, "model": "admin.objectdates", "fields": {"creation": "2012-05-03 16:50:15", "last_modification": "2012-05-03 16:50:15"}}, {"pk": 4, "model": "admin.objectdates", "fields": {"creation": "2012-05-03 16:51:04", "last_modification": "2012-05-03 16:51:04"}}, {"pk": 5, "model": "admin.objectdates", "fields": {"creation": "2012-05-03 16:56:50", "last_modification": "2012-05-03 16:56:50"}}, {"pk": 1, "model": "admin.domain", "fields": {"dates": 1, "enabled": true, "name": "demo.local", "quota": 10}}, {"pk": 1, "model": "admin.mailbox", "fields": {"dates": 2, "quota": 10, "user": 2, "domain": 1, "address": "admin"}}, {"pk": 3, "model": "admin.mailbox", "fields": {"dates": 5, "quota": 10, "user": 4, "domain": 1, "address": "user"}}, {"pk": 1, "model": "admin.alias", "fields": {"dates": 3, "enabled": true, "domain": 1, "mboxes": [1], "address": "postmaster", "extmboxes": ""}}, {"pk": 1, "model": "admin.extension", "fields": {"enabled": true, "name": "limits"}}, {"pk": 2, "model": "admin.extension", "fields": {"enabled": true, "name": "postfix_autoreply"}}, {"pk": 3, "model": "admin.extension", "fields": {"enabled": true, "name": "stats"}}, {"pk": 4, "model": "admin.extension", "fields": {"enabled": true, "name": "amavis"}}, {"pk": 5, "model": "admin.extension", "fields": {"enabled": true, "name": "webmail"}}, {"pk": 6, "model": "admin.extension", "fields": {"enabled": true, "name": "sievefilters"}}, {"pk": "admin@demo.local", "model": "admin.Quota", "fields": {"mbox": 1, "username": "admin@demo.local", "bytes": 0, "messages": 0}}, {"pk": "user@demo.local", "model": "admin.Quota", "fields": {"mbox": 3, "username": "user@demo.local", "bytes": 0, "messages": 0}}]
|
||||
[{"pk": 1, "model": "core.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": false, "last_login": "2012-05-03T16:58:51+01:00", "groups": [], "user_permissions": [], "password": "{CRYPT}dTTsGDkA5ZHKg", "email": "", "date_joined": "2012-01-26T15:19:25+01:00"}}, {"pk": 2, "model": "core.user", "fields": {"username": "admin@demo.local", "first_name": "Demo", "last_name": "Administrator", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2012-05-24T05:00:12+01:00", "groups": [1], "user_permissions": [], "password": "{CRYPT}SJ2bQWwabfH/6", "email": "admin@demo.local", "date_joined": "2012-05-03T16:50:15+01:00"}}, {"pk": 4, "model": "core.user", "fields": {"username": "user@demo.local", "first_name": "Demo", "last_name": "User", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2012-05-03T16:56:50+01:00", "groups": [2], "user_permissions": [], "password": "{CRYPT}2iAFXtxUA6.7Y", "email": "user@demo.local", "date_joined": "2012-05-03T16:56:50+01:00"}}, {"pk": 2, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "domain"], "object_id": 1}}, {"pk": 3, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["core", "user"], "object_id": 2}}, {"pk": 4, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "mailbox"], "object_id": 1}}, {"pk": 5, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "alias"], "object_id": 1}}, {"pk": 6, "model": "core.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "domain"], "object_id": 1}}, {"pk": 7, "model": "core.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "mailbox"], "object_id": 1}}, {"pk": 8, "model": "core.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["core", "user"], "object_id": 2}}, {"pk": 9, "model": "core.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "alias"], "object_id": 1}}, {"pk": 13, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["core", "user"], "object_id": 4}}, {"pk": 14, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "mailbox"], "object_id": 3}}, {"pk": 15, "model": "core.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["admin", "mailbox"], "object_id": 3}}, {"pk": 16, "model": "core.objectaccess", "fields": {"is_owner": false, "user": 2, "content_type": ["core", "user"], "object_id": 4}}, {"pk": 1, "model": "admin.objectdates", "fields": {"creation": "2012-05-03T16:49:40+01:00", "last_modification": "2012-05-03T16:49:40+01:00"}}, {"pk": 2, "model": "admin.objectdates", "fields": {"creation": "2012-05-03T16:50:15+01:00", "last_modification": "2012-05-03T16:50:36+01:00"}}, {"pk": 3, "model": "admin.objectdates", "fields": {"creation": "2012-05-03T16:50:15+01:00", "last_modification": "2012-05-03T16:50:15+01:00"}}, {"pk": 4, "model": "admin.objectdates", "fields": {"creation": "2012-05-03T16:51:04+01:00", "last_modification": "2012-05-03T16:51:04+01:00"}}, {"pk": 5, "model": "admin.objectdates", "fields": {"creation": "2012-05-03T16:56:50+01:00", "last_modification": "2012-05-03T16:56:50+01:00"}}, {"pk": 1, "model": "admin.domain", "fields": {"dates": 1, "enabled": true, "name": "demo.local", "quota": 10}}, {"pk": 1, "model": "admin.mailbox", "fields": {"dates": 2, "quota": 10, "user": 2, "domain": 1, "address": "admin"}}, {"pk": 3, "model": "admin.mailbox", "fields": {"dates": 5, "quota": 10, "user": 4, "domain": 1, "address": "user"}}, {"pk": 1, "model": "admin.alias", "fields": {"dates": 3, "enabled": true, "domain": 1, "mboxes": [1], "address": "postmaster", "extmboxes": ""}}, {"pk": 1, "model": "core.extension", "fields": {"enabled": true, "name": "limits"}}, {"pk": 2, "model": "core.extension", "fields": {"enabled": true, "name": "postfix_autoreply"}}, {"pk": 3, "model": "core.extension", "fields": {"enabled": true, "name": "stats"}}, {"pk": 4, "model": "core.extension", "fields": {"enabled": true, "name": "amavis"}}, {"pk": 5, "model": "core.extension", "fields": {"enabled": true, "name": "webmail"}}, {"pk": 6, "model": "core.extension", "fields": {"enabled": true, "name": "sievefilters"}}, {"pk": 7, "model": "core.extension", "fields": {"enabled": true, "name": "postfix_relay_domains"}}, {"pk": "admin@demo.local", "model": "admin.quota", "fields": {"mbox": 1, "username": "admin@demo.local", "bytes": 0, "messages": 0}}, {"pk": "user@demo.local", "model": "admin.quota", "fields": {"mbox": 3, "username": "user@demo.local", "bytes": 0, "messages": 0}}]
|
||||
|
||||
@@ -2,7 +2,9 @@ import reversion
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.lib.exceptions import PermDeniedException, BadRequest
|
||||
from modoboa.lib.exceptions import (
|
||||
PermDeniedException, BadRequest, Conflict
|
||||
)
|
||||
from .base import AdminObject
|
||||
from .domain import Domain
|
||||
from .mailbox import Mailbox
|
||||
@@ -155,6 +157,12 @@ class Alias(AdminObject):
|
||||
raise BadRequest(_("Domain '%s' does not exist" % domname))
|
||||
if not user.can_access(domain):
|
||||
raise PermDeniedException
|
||||
try:
|
||||
Alias.objects.get(address=localpart, domain__name=domain)
|
||||
except Alias.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
raise Conflict
|
||||
self.address = localpart
|
||||
self.domain = domain
|
||||
self.enabled = (row[2].strip() == 'True')
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.db.models.manager import Manager
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from django.contrib.contenttypes import generic
|
||||
from modoboa.lib import events, parameters
|
||||
from modoboa.lib.exceptions import BadRequest
|
||||
from modoboa.lib.exceptions import BadRequest, Conflict
|
||||
from modoboa.core.models import User, ObjectAccess
|
||||
from .base import AdminObject
|
||||
|
||||
@@ -131,9 +131,24 @@ class Domain(AdminObject):
|
||||
return self.name
|
||||
|
||||
def from_csv(self, user, row):
|
||||
"""Create a new domain from a CSV entry.
|
||||
|
||||
The expected fields order is the following::
|
||||
|
||||
"domain", name, quota, enabled
|
||||
|
||||
:param ``core.User`` user: user creating the domain
|
||||
:param str row: a list containing domain's definition
|
||||
"""
|
||||
if len(row) < 4:
|
||||
raise BadRequest(_("Invalid line"))
|
||||
self.name = row[1].strip()
|
||||
try:
|
||||
Domain.objects.get(name=self.name)
|
||||
except Domain.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
raise Conflict
|
||||
try:
|
||||
self.quota = int(row[2].strip())
|
||||
except ValueError:
|
||||
|
||||
@@ -38,12 +38,13 @@ class DomainAlias(AdminObject):
|
||||
if len(row) < 4:
|
||||
raise BadRequest(_("Invalid line"))
|
||||
self.name = row[1].strip()
|
||||
try:
|
||||
Domain.objects.get(name=self.name)
|
||||
except Domain.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
raise Conflict(_("A domain %s already exists" % self.name))
|
||||
for model in [DomainAlias, Domain]:
|
||||
try:
|
||||
model.objects.get(name=self.name)
|
||||
except model.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
raise Conflict
|
||||
domname = row[2].strip()
|
||||
try:
|
||||
self.target = Domain.objects.get(name=domname)
|
||||
|
||||
@@ -187,11 +187,6 @@ class PermissionsTestCase(ModoTestCase):
|
||||
account = User.objects.get(username="superadmin2@test.com")
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
self.ajax_get(
|
||||
reverse("modoboa.extensions.admin.views.identity.delaccount",
|
||||
args=[account.id]),
|
||||
{}, 403
|
||||
)
|
||||
self.ajax_post(
|
||||
reverse("modoboa.extensions.admin.views.identity.delaccount",
|
||||
args=[account.id]), {}, 403
|
||||
|
||||
@@ -20,17 +20,27 @@ class ExportTestCase(ModoTestCase):
|
||||
{"filename": "test.csv"}
|
||||
)
|
||||
|
||||
def assertListEqual(self, list1, list2):
|
||||
list2 = list2.split('\r\n')
|
||||
for entry in list1.split('\r\n'):
|
||||
if not entry:
|
||||
continue
|
||||
self.assertIn(entry, list2)
|
||||
|
||||
def test_export_identities(self):
|
||||
response = self.__export_identities()
|
||||
self.assertEqual(response.content, "account;admin;{CRYPT}dTTsGDkA5ZHKg;;;True;SuperAdmins;;\r\naccount;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com\r\naccount;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10\r\nalias;alias@test.com;True;user@test.com\r\nforward;forward@test.com;True;user@external.com\r\ndlist;postmaster@test.com;True;toto@titi.com;test@truc.fr\r\n")
|
||||
self.assertListEqual(
|
||||
"account;admin;{CRYPT}dTTsGDkA5ZHKg;;;True;SuperAdmins;;\r\naccount;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com\r\naccount;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10\r\nalias;alias@test.com;True;user@test.com\r\nforward;forward@test.com;True;user@external.com\r\ndlist;postmaster@test.com;True;toto@titi.com;test@truc.fr\r\n",
|
||||
response.content.strip()
|
||||
)
|
||||
|
||||
def test_export_simpleusers(self):
|
||||
response = self.__export_identities(
|
||||
idtfilter="account", grpfilter="SimpleUsers"
|
||||
)
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"account;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10"
|
||||
self.assertListEqual(
|
||||
"account;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10",
|
||||
response.content.strip()
|
||||
)
|
||||
|
||||
def test_export_superadmins(self):
|
||||
@@ -46,9 +56,9 @@ class ExportTestCase(ModoTestCase):
|
||||
response = self.__export_identities(
|
||||
idtfilter="account", grpfilter="DomainAdmins"
|
||||
)
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"account;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com"
|
||||
self.assertListEqual(
|
||||
"account;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com",
|
||||
response.content.strip()
|
||||
)
|
||||
|
||||
def test_export_aliases(self):
|
||||
|
||||
@@ -49,7 +49,7 @@ domainalias;test.alias;test.com;True
|
||||
"sourcefile": f
|
||||
}
|
||||
)
|
||||
self.assertIn('A domain test.alias already exists', resp.content)
|
||||
self.assertIn('Object already exists: domainalias', resp.content)
|
||||
|
||||
def test_identities_import(self):
|
||||
f = ContentFile(b"""
|
||||
|
||||
@@ -122,7 +122,7 @@ def importdata(request, formclass=ImportDataForm):
|
||||
fct = fct[0]
|
||||
try:
|
||||
fct(request.user, row, form.cleaned_data)
|
||||
except IntegrityError, e:
|
||||
except Conflict:
|
||||
if form.cleaned_data["continue_if_exists"]:
|
||||
continue
|
||||
raise Conflict(
|
||||
|
||||
@@ -12,7 +12,6 @@ from modoboa.lib.webutils import NavigationParameters
|
||||
from modoboa.extensions.amavis.models import Users, Policy
|
||||
|
||||
|
||||
|
||||
def selfservice(ssfunc=None):
|
||||
"""Decorator used to expose views to the 'self-service' feature
|
||||
|
||||
@@ -121,7 +120,7 @@ def create_user_and_policy(name):
|
||||
|
||||
:param str name: name
|
||||
"""
|
||||
policy = Policy.objects.create(policy_name=name)
|
||||
policy = Policy.objects.create(policy_name=name[:32])
|
||||
Users.objects.create(
|
||||
email="@%s" % name, fullname=name,
|
||||
priority=7, policy=policy
|
||||
@@ -134,7 +133,7 @@ def create_user_and_use_policy(name, policy_name):
|
||||
:param str name: user record name
|
||||
:param str policy_name: policy name
|
||||
"""
|
||||
policy = Policy.objects.get(policy_name=policy_name)
|
||||
policy = Policy.objects.get(policy_name=policy_name[:32])
|
||||
Users.objects.create(
|
||||
email="@%s" % name, fullname=name,
|
||||
priority=7, policy=policy
|
||||
@@ -152,7 +151,7 @@ def update_user_and_policy(oldname, newname):
|
||||
u = Users.objects.get(email="@%s" % oldname)
|
||||
u.email = "@%s" % newname
|
||||
u.fullname = newname
|
||||
u.policy.policy_name = newname
|
||||
u.policy.policy_name = newname[:32]
|
||||
u.policy.save()
|
||||
u.save()
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class Msgrcpt(models.Model):
|
||||
|
||||
|
||||
class Policy(models.Model):
|
||||
policy_name = models.CharField(max_length=96, blank=True)
|
||||
policy_name = models.CharField(max_length=32, blank=True)
|
||||
virus_lover = models.CharField(max_length=3, blank=True, null=True)
|
||||
spam_lover = models.CharField(max_length=3, blank=True, null=True)
|
||||
unchecked_lover = models.CharField(max_length=3, blank=True, null=True)
|
||||
|
||||
@@ -1 +1 @@
|
||||
[{"pk": 1, "model": "limits.limitspool", "fields": {"user": 2}}, {"pk": 1, "model": "limits.limit", "fields": {"curvalue": 0, "name": "domain_admins_limit", "pool": 1, "maxvalue": -2}}, {"pk": 2, "model": "limits.limit", "fields": {"curvalue": 0, "name": "domains_limit", "pool": 1, "maxvalue": -2}}, {"pk": 3, "model": "limits.limit", "fields": {"curvalue": 0, "name": "domain_aliases_limit", "pool": 1, "maxvalue": -2}}, {"pk": 4, "model": "limits.limit", "fields": {"curvalue": 0, "name": "mailboxes_limit", "pool": 1, "maxvalue": 5}}, {"pk": 5, "model": "limits.limit", "fields": {"curvalue": 0, "name": "mailbox_aliases_limit", "pool": 1, "maxvalue": 5}},{"pk": 3, "model": "auth.group", "fields": {"name": "Resellers", "permissions": [["add_user", "admin", "user"], ["change_user", "admin", "user"], ["delete_user", "admin", "user"], ["view_domains", "admin", "domain"], ["add_mailbox", "admin", "mailbox"], ["change_mailbox", "admin", "mailbox"], ["delete_mailbox", "admin", "mailbox"], ["add_alias", "admin", "alias"], ["change_alias", "admin", "alias"], ["delete_alias", "admin", "alias"], ["view_mailboxes", "admin", "mailbox"], ["view_aliases", "admin", "alias"], ["view_domaliases", "admin", "domainalias"], ["add_domainalias", "admin", "domainalias"], ["change_domainalias", "admin", "domainalias"], ["delete_domainalias", "admin", "domainalias"],["view_permissions", "auth", "permission"], ["view_domains", "admin", "domain"], ["add_domain", "admin", "domain"], ["change_domain", "admin", "domain"], ["delete_domain", "admin", "domain"]]}}]
|
||||
[{"pk": 1, "model": "limits.limitspool", "fields": {"user": 2}}, {"pk": 1, "model": "limits.limit", "fields": {"curvalue": 0, "name": "domain_admins_limit", "pool": 1, "maxvalue": -2}}, {"pk": 2, "model": "limits.limit", "fields": {"curvalue": 0, "name": "domains_limit", "pool": 1, "maxvalue": -2}}, {"pk": 3, "model": "limits.limit", "fields": {"curvalue": 0, "name": "domain_aliases_limit", "pool": 1, "maxvalue": -2}}, {"pk": 4, "model": "limits.limit", "fields": {"curvalue": 0, "name": "mailboxes_limit", "pool": 1, "maxvalue": 5}}, {"pk": 5, "model": "limits.limit", "fields": {"curvalue": 0, "name": "mailbox_aliases_limit", "pool": 1, "maxvalue": 5}},{"pk": 3, "model": "auth.group", "fields": {"name": "Resellers", "permissions": [["add_user", "core", "user"], ["change_user", "core", "user"], ["delete_user", "core", "user"], ["view_domains", "admin", "domain"], ["add_mailbox", "admin", "mailbox"], ["change_mailbox", "admin", "mailbox"], ["delete_mailbox", "admin", "mailbox"], ["add_alias", "admin", "alias"], ["change_alias", "admin", "alias"], ["delete_alias", "admin", "alias"], ["view_mailboxes", "admin", "mailbox"], ["view_aliases", "admin", "alias"], ["view_domaliases", "admin", "domainalias"], ["add_domainalias", "admin", "domainalias"], ["change_domainalias", "admin", "domainalias"], ["delete_domainalias", "admin", "domainalias"], ["view_domains", "admin", "domain"], ["add_domain", "admin", "domain"], ["change_domain", "admin", "domain"], ["delete_domain", "admin", "domain"]]}}]
|
||||
@@ -27,6 +27,8 @@ class PostfixAutoreply(ModoExtension):
|
||||
|
||||
def init(self):
|
||||
from modoboa.extensions.admin.models import Domain
|
||||
from modoboa.extensions.postfix_autoreply.general_callbacks \
|
||||
import onDomainCreated, onMailboxCreated
|
||||
|
||||
for dom in Domain.objects.all():
|
||||
try:
|
||||
|
||||
@@ -30,9 +30,12 @@ class ARmessageForm(forms.ModelForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ARmessageForm, self).__init__(*args, **kwargs)
|
||||
self.fields.keyOrder = ['subject', 'content', 'fromdate', 'untildate', 'enabled']
|
||||
self.fields.keyOrder = [
|
||||
'subject', 'content', 'fromdate', 'untildate', 'enabled'
|
||||
]
|
||||
if 'instance' in kwargs and kwargs['instance'] is not None:
|
||||
self.fields['fromdate'].initial = kwargs['instance'].fromdate
|
||||
self.fields['fromdate'].initial = \
|
||||
kwargs['instance'].fromdate.replace(second=0, microsecond=0)
|
||||
self.fields['untildate'].initial = kwargs['instance'].untildate
|
||||
|
||||
def clean(self):
|
||||
@@ -46,7 +49,7 @@ class ARmessageForm(forms.ModelForm):
|
||||
raise forms.ValidationError(self._errors)
|
||||
if self.cleaned_data["fromdate"] is not None:
|
||||
if self.cleaned_data["fromdate"] < timezone.now():
|
||||
self._errrors["fromdate"] = self.error_class([_("This date is over")])
|
||||
self._errors["fromdate"] = self.error_class([_("This date is over")])
|
||||
del self.cleaned_data['fromdate']
|
||||
else:
|
||||
self.cleaned_data['fromdate'] = timezone.now()
|
||||
@@ -54,7 +57,8 @@ class ARmessageForm(forms.ModelForm):
|
||||
if self.cleaned_data["untildate"] < timezone.now():
|
||||
self._errors["untildate"] = self.error_class([_("This date is over")])
|
||||
del self.cleaned_data['untildate']
|
||||
elif self.cleaned_data['untildate'] < self.cleaned_data['fromdate']:
|
||||
elif 'fromdate' in self.cleaned_data and \
|
||||
self.cleaned_data['untildate'] < self.cleaned_data['fromdate']:
|
||||
self._errors["untildate"] = \
|
||||
self.error_class([_("Must be greater than start date")])
|
||||
del self.cleaned_data['untildate']
|
||||
|
||||
@@ -12,7 +12,7 @@ from modoboa.extensions.postfix_autoreply.models import ARmessage, ARhistoric
|
||||
|
||||
|
||||
def send_autoreply(sender, mailbox, armessage):
|
||||
if armessage.fromdate < timezone.now():
|
||||
if armessage.fromdate > timezone.now():
|
||||
return
|
||||
if armessage.untildate is not None \
|
||||
and armessage.untildate < timezone.now():
|
||||
|
||||
@@ -39,18 +39,20 @@ variables = ["sent", "recv", "bounced", "reject", "spam", "virus",
|
||||
|
||||
|
||||
class LogParser(object):
|
||||
|
||||
def __init__(self, options, workdir, year=None):
|
||||
"""Constructor
|
||||
"""
|
||||
self.logfile = options["logfile"]
|
||||
self.debug = options["debug"]
|
||||
self.verbose = options["verbose"]
|
||||
try:
|
||||
self.f = open(self.logfile)
|
||||
except IOError, errno:
|
||||
if options["debug"]:
|
||||
print "%s" % errno
|
||||
except IOError as errno:
|
||||
self._dprint("%s" % errno)
|
||||
sys.exit(1)
|
||||
self.workdir = workdir
|
||||
self.__year = year
|
||||
self.debug = options["debug"]
|
||||
self.verbose = options["verbose"]
|
||||
self.cfs = ['AVERAGE', 'MAX']
|
||||
|
||||
curtime = time.localtime()
|
||||
@@ -59,16 +61,74 @@ class LogParser(object):
|
||||
self.curmonth = curtime.tm_mon
|
||||
|
||||
self.data = {}
|
||||
domains = Domain.objects.all()
|
||||
self.domains = []
|
||||
for dom in domains:
|
||||
for dom in Domain.objects.all():
|
||||
self.domains += [str(dom.name)]
|
||||
self.data[str(dom.name)] = {}
|
||||
self.data["global"] = {}
|
||||
|
||||
self.workdict = {}
|
||||
self.lupdates = {}
|
||||
self.line_expr = re.compile("(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+([-\w]+)\s+(\w+)/?\w*[[](\d+)[]]:\s+(.*)")
|
||||
self._s_date_expr = \
|
||||
re.compile(r"(?P<month>\w+)\s+(?P<day>\d+)\s+(?P<hour>\d+):(?P<min>\d+):(?P<sec>\d+)(?P<eol>.*)")
|
||||
self._hp_date_expr = \
|
||||
re.compile(r"(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)T(?P<hour>\d+):(?P<min>\d+):(?P<sec>\d+)\.\d+\+\d+:\d+(?P<eol>.*)")
|
||||
self.date_expr = None
|
||||
self.line_expr = \
|
||||
re.compile(r"\s+([-\w]+)\s+(\w+)/?\w*[[](\d+)[]]:\s+(.*)")
|
||||
self._id_expr = re.compile(r"(\w+): (.*)")
|
||||
self._prev_se = -1
|
||||
self._prev_mi = -1
|
||||
self._prev_ho = -1
|
||||
self.cur_t = 0
|
||||
|
||||
def _dprint(self, msg):
|
||||
"""Print a debug message if required.
|
||||
|
||||
:param str msg: debug message
|
||||
"""
|
||||
if not self.debug:
|
||||
return
|
||||
print msg
|
||||
|
||||
def _parse_date(self, line):
|
||||
"""Try to match a date inside :kw:`line` and to convert it to
|
||||
a timestamp.
|
||||
|
||||
We try different date format until we find valid one. We then
|
||||
store it for future use.
|
||||
|
||||
:param str line: a log entry
|
||||
:return: the remaining part of the line or None
|
||||
"""
|
||||
match = None
|
||||
if self.date_expr is None:
|
||||
for expr in [self._s_date_expr, self._hp_date_expr]:
|
||||
match = expr.match(line)
|
||||
if match is not None:
|
||||
self.date_expr = expr
|
||||
break
|
||||
else:
|
||||
match = self.date_expr.match(line)
|
||||
if match is None:
|
||||
return None
|
||||
ho = match.group("hour")
|
||||
mi = match.group("min")
|
||||
se = match.group("sec")
|
||||
se = int(int(se) / rrdstep) # rrd step is one-minute => se = 0
|
||||
if self._prev_se != se or self._prev_mi != mi or self._prev_ho != ho:
|
||||
mo = match.group("month")
|
||||
da = match.group("day")
|
||||
try:
|
||||
ye = match.group("year")
|
||||
except IndexError:
|
||||
ye = self.year(mo)
|
||||
self.cur_t = str2Time(ye, mo, da, ho, mi, se)
|
||||
self.cur_t = self.cur_t - self.cur_t % rrdstep
|
||||
self._prev_mi = mi
|
||||
self._prev_ho = ho
|
||||
self._prev_se = se
|
||||
return match.group('eol')
|
||||
|
||||
def init_rrd(self, fname, m):
|
||||
"""init_rrd
|
||||
@@ -119,8 +179,7 @@ class LogParser(object):
|
||||
m = t - (t % rrdstep)
|
||||
if not os.path.exists(fname):
|
||||
self.lupdates[fname] = self.init_rrd(fname, m)
|
||||
if self.debug:
|
||||
print "[rrd] create new RRD file %s" % fname
|
||||
self._dprint("[rrd] create new RRD file %s" % fname)
|
||||
else:
|
||||
if not fname in self.lupdates:
|
||||
self.lupdates[fname] = rrdtool.last(str(fname))
|
||||
@@ -164,21 +223,21 @@ class LogParser(object):
|
||||
self.lupdates[fname] = m
|
||||
return True
|
||||
|
||||
def initcounters(self, dom, cur_t):
|
||||
def initcounters(self, dom):
|
||||
init = {}
|
||||
for v in variables:
|
||||
init[v] = 0
|
||||
self.data[dom][cur_t] = init
|
||||
self.data[dom][self.cur_t] = init
|
||||
|
||||
def inc_counter(self, dom, cur_t, counter, val=1):
|
||||
def inc_counter(self, dom, counter, val=1):
|
||||
if dom is not None and dom in self.domains:
|
||||
if not cur_t in self.data[dom]:
|
||||
self.initcounters(dom, cur_t)
|
||||
self.data[dom][cur_t][counter] += val
|
||||
if not self.cur_t in self.data[dom]:
|
||||
self.initcounters(dom)
|
||||
self.data[dom][self.cur_t][counter] += val
|
||||
|
||||
if not cur_t in self.data["global"]:
|
||||
self.initcounters("global", cur_t)
|
||||
self.data["global"][cur_t][counter] += val
|
||||
if not self.cur_t in self.data["global"]:
|
||||
self.initcounters("global")
|
||||
self.data["global"][self.cur_t][counter] += val
|
||||
|
||||
def year(self, month):
|
||||
"""Return the appropriate year
|
||||
@@ -203,82 +262,76 @@ class LogParser(object):
|
||||
return self.__year - 1
|
||||
return self.__year
|
||||
|
||||
def process(self):
|
||||
id_expr = re.compile("([0-9A-F]+): (.*)")
|
||||
prev_se = -1
|
||||
prev_mi = -1
|
||||
prev_ho = -1
|
||||
for line in self.f.readlines():
|
||||
m = self.line_expr.match(line)
|
||||
if not m:
|
||||
continue
|
||||
(mo, da, ho, mi, se, host, prog, pid, log) = m.groups()
|
||||
se = int(int(se) / rrdstep) # rrd step is one-minute => se = 0
|
||||
def _parse_line(self, line):
|
||||
"""Parse a single log line.
|
||||
|
||||
if prev_se != se or prev_mi != mi or prev_ho != ho:
|
||||
cur_t = str2Time(self.year(mo), mo, da, ho, mi, se)
|
||||
cur_t = cur_t - cur_t % rrdstep
|
||||
prev_mi = mi
|
||||
prev_ho = ho
|
||||
prev_se = se
|
||||
m = id_expr.match(log)
|
||||
if m:
|
||||
(line_id, line_log) = m.groups()
|
||||
:param str line: log line
|
||||
"""
|
||||
line = self._parse_date(line)
|
||||
if line is None:
|
||||
return
|
||||
m = self.line_expr.match(line)
|
||||
if not m:
|
||||
return
|
||||
host, prog, pid, log = m.groups()
|
||||
m = self._id_expr.match(log)
|
||||
if m is None:
|
||||
self._dprint("Unknown line format: %s" % log)
|
||||
return
|
||||
(line_id, line_log) = m.groups()
|
||||
if line_id == "NOQUEUE":
|
||||
addrto = re.match("reject: .*from=<.*> to=<[^@]+@([^>]+)>", line_log)
|
||||
if addrto and addrto.group(1) in self.domains:
|
||||
self.inc_counter(addrto.group(1), 'reject')
|
||||
return
|
||||
m = re.search("message-id=<([^>]*)>", line_log)
|
||||
if m is not None:
|
||||
self.workdict[line_id] = {'from': m.group(1), 'size': 0}
|
||||
return
|
||||
m = re.search("from=<([^>]*)>, size=(\d+)", line_log)
|
||||
if m is not None:
|
||||
self.workdict[line_id] = {
|
||||
'from': m.group(1), 'size': string.atoi(m.group(2))
|
||||
}
|
||||
return
|
||||
|
||||
m = re.search("message-id=<([^>]*)>", line_log)
|
||||
if m:
|
||||
self.workdict[line_id] = {'from': m.group(1), 'size': 0}
|
||||
continue
|
||||
|
||||
m = re.search("from=<([^>]*)>, size=(\d+)", line_log)
|
||||
if m:
|
||||
self.workdict[line_id] = {'from': m.group(1),
|
||||
'size': string.atoi(m.group(2))}
|
||||
continue
|
||||
|
||||
m = re.search("to=<([^>]*)>.*status=(\S+)", line_log)
|
||||
if m:
|
||||
if not line_id in self.workdict:
|
||||
if self.debug:
|
||||
print "Inconsistent mail (%s: %s), skipping" % (line_id, m.group(1))
|
||||
continue
|
||||
if not m.group(2) in variables:
|
||||
if self.debug:
|
||||
print "Unsupported status %s, skipping" % m.group(2)
|
||||
continue
|
||||
|
||||
addrfrom = re.match("([^@]+)@(.+)", self.workdict[line_id]['from'])
|
||||
if addrfrom is not None and addrfrom.group(2) in self.domains:
|
||||
self.inc_counter(addrfrom.group(2), cur_t, 'sent')
|
||||
self.inc_counter(addrfrom.group(2), cur_t, 'size_sent',
|
||||
self.workdict[line_id]['size'])
|
||||
addrto = re.match("([^@]+)@(.+)", m.group(1))
|
||||
domname = addrto.group(2) if addrto is not None else None
|
||||
if m.group(2) == "sent":
|
||||
self.inc_counter(addrto.group(2), cur_t, 'recv')
|
||||
self.inc_counter(addrto.group(2), cur_t, 'size_recv',
|
||||
self.workdict[line_id]['size'])
|
||||
else:
|
||||
self.inc_counter(domname, cur_t, m.group(2))
|
||||
continue
|
||||
|
||||
if self.debug:
|
||||
print "Unknown line format: %s" % line_log
|
||||
m = re.search("to=<([^>]*)>.*status=(\S+)", line_log)
|
||||
if m is not None:
|
||||
if not line_id in self.workdict:
|
||||
self._dprint("Inconsistent mail (%s: %s), skipping" \
|
||||
% (line_id, m.group(1)))
|
||||
return
|
||||
if not m.group(2) in variables:
|
||||
self._dprint("Unsupported status %s, skipping" % m.group(2))
|
||||
return
|
||||
addrfrom = re.match("([^@]+)@(.+)", self.workdict[line_id]['from'])
|
||||
if addrfrom is not None and addrfrom.group(2) in self.domains:
|
||||
self.inc_counter(addrfrom.group(2), 'sent')
|
||||
self.inc_counter(addrfrom.group(2), 'size_sent',
|
||||
self.workdict[line_id]['size'])
|
||||
addrto = re.match("([^@]+)@(.+)", m.group(1))
|
||||
domname = addrto.group(2) if addrto is not None else None
|
||||
if m.group(2) == "sent":
|
||||
self.inc_counter(addrto.group(2), 'recv')
|
||||
self.inc_counter(addrto.group(2), 'size_recv',
|
||||
self.workdict[line_id]['size'])
|
||||
else:
|
||||
m = re.match("NOQUEUE: reject: .*from=<(.*)> to=<([^>]*)>", log)
|
||||
if m:
|
||||
addrto = re.match("([^@]+)@(.+)", m.group(2))
|
||||
if addrto and addrto.group(2) in self.domains:
|
||||
self.inc_counter(addrto.group(2), cur_t, 'reject')
|
||||
continue
|
||||
if self.debug:
|
||||
print "Unknown line format: %s" % log
|
||||
self.inc_counter(domname, m.group(2))
|
||||
return
|
||||
self._dprint("Unknown line format: %s" % line_log)
|
||||
|
||||
def process(self):
|
||||
"""Process the log file.
|
||||
|
||||
We parse it and then generate standard graphics (day, week,
|
||||
month).
|
||||
"""
|
||||
for line in self.f.readlines():
|
||||
self._parse_line(line)
|
||||
|
||||
# Sort everything by time
|
||||
G = Grapher()
|
||||
for dom, data in self.data.iteritems():
|
||||
if self.debug:
|
||||
print "[rrd] dealing with domain %s" % dom
|
||||
self._dprint("[rrd] dealing with domain %s" % dom)
|
||||
for t in sorted(data.keys()):
|
||||
self.update_rrd(dom, t)
|
||||
|
||||
|
||||
@@ -582,8 +582,8 @@ def save_attachment(f):
|
||||
def clean_attachments(attlist):
|
||||
"""Remove all attachments from the filesystem
|
||||
|
||||
:param attlist: a list of 2-uple. Each element must contain the following information :
|
||||
(random name, real name).
|
||||
:param attlist: a list of 2-uple. Each element must contain the
|
||||
following information : (random name, real name).
|
||||
"""
|
||||
for att in attlist:
|
||||
fullpath = os.path.join(settings.MEDIA_ROOT, "webmail", att["tmpname"])
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"pk": 2,
|
||||
"model": "lib.parameter",
|
||||
"fields": {
|
||||
"name": "admin.PASSWORD_SCHEME",
|
||||
"name": "core.PASSWORD_SCHEME",
|
||||
"value": "crypt"
|
||||
}
|
||||
},
|
||||
@@ -11,7 +11,7 @@
|
||||
"pk": 3,
|
||||
"model": "lib.parameter",
|
||||
"fields": {
|
||||
"name": "admin.ITEMS_PER_PAGE",
|
||||
"name": "core.ITEMS_PER_PAGE",
|
||||
"value": "30"
|
||||
}
|
||||
},
|
||||
@@ -19,23 +19,15 @@
|
||||
"pk": 4,
|
||||
"model": "lib.parameter",
|
||||
"fields": {
|
||||
"name": "general.DEFAULT_TOP_REDIRECTION",
|
||||
"name": "core.DEFAULT_TOP_REDIRECTION",
|
||||
"value": "user"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "lib.parameter",
|
||||
"fields": {
|
||||
"name": "general.SECRET_KEY",
|
||||
"value": "abcdefghijklmnop"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 8,
|
||||
"model": "lib.parameter",
|
||||
"fields": {
|
||||
"name": "admin.AUTHENTICATION_TYPE",
|
||||
"name": "core.AUTHENTICATION_TYPE",
|
||||
"value": "local"
|
||||
}
|
||||
},
|
||||
|
||||
+12
-15
@@ -56,21 +56,18 @@ def grant_access_to_object(user, obj, is_owner=False):
|
||||
else:
|
||||
return
|
||||
|
||||
try:
|
||||
ObjectAccess.objects.create(user=user, content_type=ct,
|
||||
object_id=obj.id, is_owner=is_owner)
|
||||
if is_owner:
|
||||
from modoboa.core.models import User
|
||||
for su in User.objects.filter(is_superuser=True):
|
||||
if su == user:
|
||||
continue
|
||||
try:
|
||||
ObjectAccess.objects.create(user=su, content_type=ct, object_id=obj.id)
|
||||
except IntegrityError:
|
||||
pass
|
||||
|
||||
except IntegrityError, e:
|
||||
raise ModoboaException(_("Failed to grant access (%s)" % str(e)))
|
||||
ObjectAccess.objects.create(
|
||||
user=user, content_type=ct, object_id=obj.id, is_owner=is_owner
|
||||
)
|
||||
if not is_owner:
|
||||
return
|
||||
from modoboa.core.models import User
|
||||
for su in User.objects.filter(is_superuser=True):
|
||||
if su == user:
|
||||
continue
|
||||
ObjectAccess.objects.get_or_create(
|
||||
user=su, content_type=ct, object_id=obj.id
|
||||
)
|
||||
|
||||
|
||||
def grant_access_to_objects(user, objects, ct):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-12-15 10:20+0100\n"
|
||||
"PO-Revision-Date: 2013-09-27 00:07+0200\n"
|
||||
"POT-Creation-Date: 2013-12-22 23:15+0100\n"
|
||||
"PO-Revision-Date: 2013-12-23 00:56+0100\n"
|
||||
"Last-Translator: Alberto Berti <alberto@metapensiero.it>\n"
|
||||
"Language-Team: ITALIANO <LL@li.org>\n"
|
||||
"Language: it\n"
|
||||
@@ -49,23 +49,23 @@ msgstr "Schema password predefinito"
|
||||
|
||||
#: core/app_settings.py:51
|
||||
msgid "md5crypt (weak)"
|
||||
msgstr ""
|
||||
msgstr "md5crypt (debole)"
|
||||
|
||||
#: core/app_settings.py:52
|
||||
msgid "sha256 (weak)"
|
||||
msgstr ""
|
||||
msgstr "sha256 (debole)"
|
||||
|
||||
#: core/app_settings.py:53
|
||||
msgid "md5 (weak)"
|
||||
msgstr ""
|
||||
msgstr "md5 (debole)"
|
||||
|
||||
#: core/app_settings.py:54
|
||||
msgid "crypt (weak)"
|
||||
msgstr ""
|
||||
msgstr "crypt (debole)"
|
||||
|
||||
#: core/app_settings.py:55
|
||||
msgid "plain (weak)"
|
||||
msgstr ""
|
||||
msgstr "plain (debole)"
|
||||
|
||||
#: core/app_settings.py:57
|
||||
msgid "Scheme used to crypt mailbox passwords"
|
||||
@@ -74,13 +74,13 @@ msgstr ""
|
||||
|
||||
#: core/app_settings.py:61
|
||||
msgid "Rounds"
|
||||
msgstr ""
|
||||
msgstr "Cicli"
|
||||
|
||||
#: core/app_settings.py:64
|
||||
msgid ""
|
||||
"Number of rounds to use (only used by sha256crypt and sha512crypt). Must be "
|
||||
"between 1000 and 999999999, inclusive."
|
||||
msgstr ""
|
||||
msgstr "Numero di cicli da utilizzare (valido per sha256crypt e sha512crypt). Dev'essere tra 1000 e 999999999, inclusivo."
|
||||
|
||||
#: core/app_settings.py:70
|
||||
msgid "Secret key"
|
||||
@@ -159,14 +159,12 @@ msgstr ""
|
||||
"DN')"
|
||||
|
||||
#: core/app_settings.py:121
|
||||
#, fuzzy
|
||||
msgid "Users search base"
|
||||
msgstr "Ricerca base"
|
||||
msgstr "Base ricerca per gli utenti"
|
||||
|
||||
#: core/app_settings.py:123
|
||||
#, fuzzy
|
||||
msgid "The distinguished name of the search base used to find users"
|
||||
msgstr "Nome particolare della ricerca base"
|
||||
msgstr "L'identificativo (dn:) della base di ricerca utilizzata per cercare gli utenti"
|
||||
|
||||
#: core/app_settings.py:128
|
||||
msgid "Search filter"
|
||||
@@ -210,25 +208,22 @@ msgid "Tell if the LDAP server is an Active Directory one"
|
||||
msgstr "Segnala se il server LDAP è una Active Directory"
|
||||
|
||||
#: core/app_settings.py:154
|
||||
#, fuzzy
|
||||
msgid "Administrator groups"
|
||||
msgstr "Amministratori"
|
||||
msgstr "Gruppi degli amministratori"
|
||||
|
||||
#: core/app_settings.py:157
|
||||
msgid ""
|
||||
"Members of those LDAP Posix groups will be created as domain administrators. "
|
||||
"Use ';' characters to separate groups."
|
||||
msgstr ""
|
||||
msgstr "Gli appartenenti a questi gruppi LDAP Posix avranno i privilegi di amministratori di dominio. Utilizza il carattere ';' per separare valori multipli."
|
||||
|
||||
#: core/app_settings.py:164
|
||||
#, fuzzy
|
||||
msgid "Groups search base"
|
||||
msgstr "Ricerca base"
|
||||
msgstr "Base ricerca per i gruppi"
|
||||
|
||||
#: core/app_settings.py:167
|
||||
#, fuzzy
|
||||
msgid "The distinguished name of the search base used to find groups"
|
||||
msgstr "Nome particolare della ricerca base"
|
||||
msgstr "L'identificatore (dn:) della base di ricerca utilizzato per trovare i gruppi"
|
||||
|
||||
#: core/app_settings.py:172
|
||||
#: extensions/admin/templates/admin/editdomainform.html:7
|
||||
@@ -270,9 +265,8 @@ msgid "Invalid syntax"
|
||||
msgstr "Sintassi errata"
|
||||
|
||||
#: core/app_settings.py:233
|
||||
#, fuzzy
|
||||
msgid "Invalid rounds number"
|
||||
msgstr "Richiesta non valida"
|
||||
msgstr "Numero di cicli non valido"
|
||||
|
||||
#: core/app_settings.py:256
|
||||
msgid "This field is required"
|
||||
@@ -322,14 +316,12 @@ msgid "Passwords mismatch"
|
||||
msgstr "La password non corrisponde"
|
||||
|
||||
#: core/models.py:50
|
||||
#, fuzzy
|
||||
msgid "password"
|
||||
msgstr "Password"
|
||||
msgstr "password"
|
||||
|
||||
#: core/models.py:52
|
||||
#, fuzzy
|
||||
msgid "last login"
|
||||
msgstr "Ultimo login"
|
||||
msgstr "ultimo login"
|
||||
|
||||
#: core/models.py:81
|
||||
msgid "You can't delete your own account"
|
||||
@@ -513,7 +505,7 @@ msgstr "Aggiorna le informazioni personali"
|
||||
#: extensions/admin/views/identity.py:197
|
||||
#: extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html:9
|
||||
#: extensions/postfix_relay_domains/views.py:63
|
||||
#: extensions/sievefilters/views.py:163 extensions/webmail/views.py:170
|
||||
#: extensions/sievefilters/views.py:166 extensions/webmail/views.py:170
|
||||
#: extensions/webmail/views.py:205
|
||||
msgid "Update"
|
||||
msgstr "Aggiorna"
|
||||
@@ -613,9 +605,8 @@ msgid "Web based console to manage domains, accounts and aliases"
|
||||
msgstr "Interfaccia web per l'amministrazione di domini, account e alias"
|
||||
|
||||
#: extensions/admin/__init__.py:55
|
||||
#, fuzzy
|
||||
msgid "Administration"
|
||||
msgstr "Amministratori"
|
||||
msgstr "Amministrazione"
|
||||
|
||||
#: extensions/admin/__init__.py:79
|
||||
#: extensions/admin/templates/admin/domains.html:2
|
||||
@@ -668,15 +659,14 @@ msgid "The UNIX account who owns mailboxes on the filesystem"
|
||||
msgstr "L'account UNIX a cui appartengono le caselle postali nel filsystem"
|
||||
|
||||
#: extensions/admin/app_settings.py:26
|
||||
#, fuzzy
|
||||
msgid "Default domain quota"
|
||||
msgstr "Limiti predefiniti"
|
||||
msgstr "Quota predefinita per il domini"
|
||||
|
||||
#: extensions/admin/app_settings.py:29
|
||||
msgid ""
|
||||
"Default quota (in MB) applied to freshly created domains with no value "
|
||||
"specified. A value of 0 means no quota."
|
||||
msgstr ""
|
||||
msgstr "Quota predefinita (in MB) applicata ai nuovi domini che non la specificano. Un valore 0 implica nessuna quota."
|
||||
|
||||
#: extensions/admin/app_settings.py:36
|
||||
msgid "Automatic account removal"
|
||||
@@ -690,19 +680,17 @@ msgstr ""
|
||||
#: extensions/admin/app_settings.py:69 extensions/admin/forms/account.py:178
|
||||
#: extensions/admin/forms/domain.py:56
|
||||
msgid "Must be a positive integer"
|
||||
msgstr ""
|
||||
msgstr "Dev'essere un intero positivo"
|
||||
|
||||
#: extensions/admin/lib.py:28
|
||||
#, fuzzy
|
||||
msgid "A mailbox is required"
|
||||
msgstr "È richiesta una quota"
|
||||
msgstr "É necessaria una casella"
|
||||
|
||||
#: extensions/admin/forms/account.py:21
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The user's name. Must be a valid e-mail address for simple users or "
|
||||
"administrators with a mailbox."
|
||||
msgstr "L'utente '%s' deve avere un indirizzo email valido"
|
||||
msgstr "Il nome dell'utente. Dev'essere un indirizzo e-mail per gli utenti semplici o gli amministratori che posseggono una casella"
|
||||
|
||||
#: extensions/admin/forms/account.py:26
|
||||
msgid "Role"
|
||||
@@ -839,11 +827,10 @@ msgid "No recipient defined"
|
||||
msgstr "Non è stato definito un destinatario"
|
||||
|
||||
#: extensions/admin/forms/domain.py:20
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Default quota in MB applied to mailboxes. Leave empty to use the default "
|
||||
"value."
|
||||
msgstr "Quota in MB predefinita applicata alle caselle di posta"
|
||||
msgstr "Quota in MB predefinita applicata alle caselle di posta. Lascialo vuoto se vuoi applicare il valore predefinito."
|
||||
|
||||
#: extensions/admin/forms/domain.py:29
|
||||
msgid ""
|
||||
@@ -856,23 +843,21 @@ msgstr ""
|
||||
#: extensions/admin/forms/domain.py:75
|
||||
#: extensions/postfix_relay_domains/forms.py:50
|
||||
#: extensions/postfix_relay_domains/forms.py:70
|
||||
#, fuzzy
|
||||
msgid "domain alias"
|
||||
msgstr "Alias del dominio"
|
||||
msgstr "alias del dominio"
|
||||
|
||||
#: extensions/admin/forms/domain.py:82 extensions/admin/forms/domain.py:98
|
||||
#: extensions/postfix_relay_domains/forms.py:58
|
||||
#: extensions/postfix_relay_domains/forms.py:78
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "A %s with this name already exists"
|
||||
msgstr "Un alias con questo nome esiste già"
|
||||
msgstr "Un %s con questo nome esiste già"
|
||||
|
||||
#: extensions/admin/forms/domain.py:92
|
||||
#: extensions/postfix_relay_domains/forms.py:49
|
||||
#: extensions/postfix_relay_domains/forms.py:71
|
||||
#, fuzzy
|
||||
msgid "domain"
|
||||
msgstr "Domini"
|
||||
msgstr "dominio"
|
||||
|
||||
#: extensions/admin/forms/domain.py:176
|
||||
msgid "Create a domain administrator"
|
||||
@@ -1032,14 +1017,13 @@ msgid "Check to activate this domain"
|
||||
msgstr "Seleziona per attivare questo dominio"
|
||||
|
||||
#: extensions/admin/models/domain.py:61
|
||||
#, fuzzy
|
||||
msgid "Domain"
|
||||
msgstr "Domini"
|
||||
msgstr "Dominio"
|
||||
|
||||
#: extensions/admin/models/domain.py:140
|
||||
#, python-format
|
||||
msgid "Invalid quota value for domain '%s'"
|
||||
msgstr ""
|
||||
msgstr "Valore della quota non valido per il dominio '%s'"
|
||||
|
||||
#: extensions/admin/models/domain_alias.py:11
|
||||
#: extensions/postfix_relay_domains/models.py:160
|
||||
@@ -1056,9 +1040,9 @@ msgid "The domain this alias points to"
|
||||
msgstr "Il dominio a cui punta questo alias"
|
||||
|
||||
#: extensions/admin/models/domain_alias.py:46
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "A domain %s already exists"
|
||||
msgstr "La casella di posta %s esiste già"
|
||||
msgstr "Esiste già un dominio %s"
|
||||
|
||||
#: extensions/admin/models/domain_alias.py:51
|
||||
#, python-format
|
||||
@@ -1090,9 +1074,8 @@ msgid "MB"
|
||||
msgstr "MB"
|
||||
|
||||
#: extensions/admin/templates/admin/domain_options_form.html:5
|
||||
#, fuzzy
|
||||
msgid "You can't create a new domain administrator"
|
||||
msgstr "Crea un amministratore di dominio"
|
||||
msgstr "Non ti è possibile creare un amministratore di dominio"
|
||||
|
||||
#: extensions/admin/templates/admin/domains_table.html:7
|
||||
#: extensions/admin/templates/admin/identities_table.html:7
|
||||
@@ -1102,7 +1085,7 @@ msgstr "Tag"
|
||||
#: extensions/admin/templates/admin/domains_table.html:8
|
||||
#: extensions/admin/templates/admin/identities_table.html:8
|
||||
#: extensions/admin/templates/admin/listing.html:17
|
||||
#: extensions/sievefilters/views.py:93
|
||||
#: extensions/sievefilters/views.py:95
|
||||
#: extensions/sievefilters/templates/sievefilters/filter.html:17
|
||||
#: extensions/sievefilters/templates/sievefilters/guieditor.html:5
|
||||
#: extensions/webmail/templatetags/webmail_tags.py:101
|
||||
@@ -1257,7 +1240,7 @@ msgstr "Un alias con questo nome esiste già"
|
||||
#: extensions/admin/views/domain.py:129 extensions/admin/views/identity.py:131
|
||||
#: extensions/admin/views/identity.py:158
|
||||
#: extensions/postfix_relay_domains/views.py:32
|
||||
#: extensions/sievefilters/views.py:141 extensions/sievefilters/views.py:230
|
||||
#: extensions/sievefilters/views.py:144 extensions/sievefilters/views.py:233
|
||||
#: extensions/webmail/views.py:151
|
||||
msgid "Create"
|
||||
msgstr "Crea"
|
||||
@@ -1374,7 +1357,7 @@ msgstr[0] "Account cancellato"
|
||||
msgstr[1] "Account cancellati"
|
||||
|
||||
#: extensions/admin/views/import.py:39
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Provide a CSV file where lines respect one of the following formats:\n"
|
||||
"<ul>\n"
|
||||
@@ -1389,10 +1372,10 @@ msgstr ""
|
||||
"Fornire un file CSV le cui righe rispettino uno dei seguenti formati:\n"
|
||||
"<ul>\n"
|
||||
" <li><em>dominio; nome; quota; abilitato</em></li>\n"
|
||||
" <li><em>aliasdominio; nome; dominio target; abilitato<em></li>\n"
|
||||
" <li><em>aliasdominio; nome; dominio di destinazione; abilitato<em></li>\n"
|
||||
" %s\n"
|
||||
"</ul>\n"
|
||||
"<p>Il primo elemento di ogni riga è obbligatorio e deve essere uguale a "
|
||||
"quello dei valori precedenti.</p>\n"
|
||||
"<p>Il primo elemento di ogni riga è obbligatorio e deve essere uguale a quello dei valori precedenti.</p>\n"
|
||||
"\n"
|
||||
"<p>Come separatore puoi utilizzare un carattere diverso.</p>\n"
|
||||
|
||||
@@ -1411,7 +1394,6 @@ msgid "%d objects imported successfully"
|
||||
msgstr "%d oggetti importati correttamente"
|
||||
|
||||
#: extensions/admin/views/import.py:153
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Provide a CSV file where lines respect one of the following formats:\n"
|
||||
"<ul>\n"
|
||||
@@ -1428,15 +1410,12 @@ msgid ""
|
||||
msgstr ""
|
||||
"Fornire un file CSV le cui righe rispettino uno dei seguenti formati:\n"
|
||||
"<ul>\n"
|
||||
"<li><em>account; loginname; password; nome; cognome; abilitato; group; "
|
||||
"indirizzo[, dominio, ...]</em></li>\n"
|
||||
"<li><em>account; id utente; password; nome; cognome; abilitato; gruppo; indirizzo; quota; [, dominio, ...]</em></li>\n"
|
||||
"<li><em>alias; indirizzo; abilitato; destinatario interno</em></li>\n"
|
||||
"<li><em>forward; indirizzo; abilitato; destinatario esterno</em></li>\n"
|
||||
"<li><em>dlist; indirizzo; abilitato; destinatario; destinatario; ...</em></"
|
||||
"li>\n"
|
||||
"<li><em>dlist; indirizzo; abilitato; destinatario; destinatario; ...</em></li>\n"
|
||||
"</ul>\n"
|
||||
"<p>Il primo elemento di ogni riga è obbligatorio e deve essere uguale a "
|
||||
"quello dei valori precedenti.</p>\n"
|
||||
"<p>Il primo elemento di ogni riga è obbligatorio e deve essere uguale a quello dei valori precedenti.</p>\n"
|
||||
"\n"
|
||||
"<p>Come separatore puoi utilizzare un carattere diverso.</p>\n"
|
||||
|
||||
@@ -1558,9 +1537,8 @@ msgid "pending requests"
|
||||
msgstr "richieste in sospeso"
|
||||
|
||||
#: extensions/amavis/general_callbacks.py:124
|
||||
#, fuzzy
|
||||
msgid "Pending requests"
|
||||
msgstr "richieste in sospeso"
|
||||
msgstr "Richieste in sospeso"
|
||||
|
||||
#: extensions/amavis/general_callbacks.py:134
|
||||
msgid "Content filter"
|
||||
@@ -1576,12 +1554,12 @@ msgid "Virus filter"
|
||||
msgstr "Filtro virus"
|
||||
|
||||
#: extensions/amavis/models.py:94 extensions/amavis/models.py:102
|
||||
#: extensions/amavis/models.py:110 extensions/sievefilters/views.py:290
|
||||
#: extensions/amavis/models.py:110 extensions/sievefilters/views.py:293
|
||||
msgid "yes"
|
||||
msgstr "si"
|
||||
|
||||
#: extensions/amavis/models.py:95 extensions/amavis/models.py:103
|
||||
#: extensions/amavis/models.py:111 extensions/sievefilters/views.py:294
|
||||
#: extensions/amavis/models.py:111 extensions/sievefilters/views.py:297
|
||||
msgid "no"
|
||||
msgstr "no"
|
||||
|
||||
@@ -1631,7 +1609,7 @@ msgstr ""
|
||||
|
||||
#: extensions/amavis/sql_listing.py:31
|
||||
msgid "Score"
|
||||
msgstr ""
|
||||
msgstr "Punteggio"
|
||||
|
||||
#: extensions/amavis/sql_listing.py:35
|
||||
#: extensions/amavis/templatetags/amavis_tags.py:75
|
||||
@@ -1708,9 +1686,8 @@ msgid "Quarantine management"
|
||||
msgstr "Gestione quarantena"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:3
|
||||
#, fuzzy
|
||||
msgid "Select"
|
||||
msgstr "Seleziona un file"
|
||||
msgstr "Seleziona"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:9
|
||||
msgid "Spam"
|
||||
@@ -1721,7 +1698,6 @@ msgid "Virus"
|
||||
msgstr "Virus"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:11
|
||||
#, fuzzy
|
||||
msgid "Bad Header"
|
||||
msgstr "Intestazione errata"
|
||||
|
||||
@@ -1730,9 +1706,8 @@ msgid "Bad MIME"
|
||||
msgstr "MIME errato"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:13
|
||||
#, fuzzy
|
||||
msgid "Banned"
|
||||
msgstr "Filtro banned"
|
||||
msgstr "Banditi"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:18
|
||||
#: extensions/amavis/templatetags/amavis_tags.py:19
|
||||
@@ -1754,32 +1729,27 @@ msgstr "Tutti i messaggi"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:31
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
msgstr "Tutti"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:32
|
||||
#, fuzzy
|
||||
msgid "Spam only"
|
||||
msgstr "Spam"
|
||||
msgstr "Solo messaggi di spam"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:33
|
||||
#, fuzzy
|
||||
msgid "Virus only"
|
||||
msgstr "Virus"
|
||||
msgstr "Solo messaggi con virus"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:34
|
||||
#, fuzzy
|
||||
msgid "Bad Header only"
|
||||
msgstr "Intestazione errata"
|
||||
msgstr "Solo messaggi con intestazione errata"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:35
|
||||
#, fuzzy
|
||||
msgid "Bad MIME only"
|
||||
msgstr "MIME errato"
|
||||
msgstr "Solo messaggi con struttura MIME errata"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:36
|
||||
#, fuzzy
|
||||
msgid "Banned only"
|
||||
msgstr "Filtro banned"
|
||||
msgstr "Solo messaggi banditi"
|
||||
|
||||
#: extensions/amavis/templates/amavis/notifications/pending_requests.html:1
|
||||
#, python-format
|
||||
@@ -1954,23 +1924,21 @@ msgstr ""
|
||||
"destinatario"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:20
|
||||
#, fuzzy
|
||||
msgid "Default subject"
|
||||
msgstr "Editor predefinito"
|
||||
msgstr "Oggetto predefinito"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:21
|
||||
msgid "I'm off"
|
||||
msgstr ""
|
||||
msgstr "Sono via"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:23
|
||||
msgid ""
|
||||
"Default subject used when an auto-reply message is created automatically"
|
||||
msgstr ""
|
||||
msgstr "Oggetto predefinito utilizzato nei messaggi di risposta automatica"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:28
|
||||
#, fuzzy
|
||||
msgid "Default content"
|
||||
msgstr "Editor predefinito"
|
||||
msgstr "Corpo del messaggio predefinito"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:30
|
||||
#, python-format
|
||||
@@ -1980,18 +1948,21 @@ msgid ""
|
||||
"Best regards,\n"
|
||||
"%(name)s\n"
|
||||
msgstr ""
|
||||
"Al momento non posso rispondere. Risponderò al mio ritorno.\n"
|
||||
"\n"
|
||||
"Distinti saluti,\n"
|
||||
"%(name)s\n"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:36
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Default content used when an auto-reply message is created automatically. "
|
||||
"The '%(name)s' macro will be replaced by the user's full name."
|
||||
msgstr ""
|
||||
msgstr "Corpo del messaggio predefinito per i messaggi di risposta automatica. La macro '%(name)s' verrà sostituita con il nome dell'utente. "
|
||||
|
||||
#: extensions/postfix_autoreply/forms.py:13
|
||||
#, fuzzy
|
||||
msgid "Activate your auto reply from this date"
|
||||
msgstr "Attiva la tua risposta automatica fino a questa data"
|
||||
msgstr "Attiva la risposta automatica da questa data"
|
||||
|
||||
#: extensions/postfix_autoreply/forms.py:19
|
||||
msgid "Until"
|
||||
@@ -2007,9 +1978,8 @@ msgid "This date is over"
|
||||
msgstr "Questa data è passata"
|
||||
|
||||
#: extensions/postfix_autoreply/forms.py:59
|
||||
#, fuzzy
|
||||
msgid "Must be greater than start date"
|
||||
msgstr "è maggiore di"
|
||||
msgstr "Dev'essere successiva alla data di inizio"
|
||||
|
||||
#: extensions/postfix_autoreply/general_callbacks.py:33
|
||||
#: extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html:2
|
||||
@@ -2018,11 +1988,11 @@ msgstr "Messaggio di risposta automatica"
|
||||
|
||||
#: extensions/postfix_autoreply/general_callbacks.py:118
|
||||
msgid "Enable auto-reply"
|
||||
msgstr ""
|
||||
msgstr "Abilita la risposta automatica"
|
||||
|
||||
#: extensions/postfix_autoreply/general_callbacks.py:120
|
||||
msgid "Enable or disable Postfix auto-reply"
|
||||
msgstr ""
|
||||
msgstr "Abilita o disabilita la risposta automatica di Postfix"
|
||||
|
||||
#: extensions/postfix_autoreply/models.py:20
|
||||
msgid "subject"
|
||||
@@ -2054,65 +2024,54 @@ msgstr "Definisci un messaggio da inviare automaticamente quando sei via"
|
||||
|
||||
#: extensions/postfix_relay_domains/__init__.py:72
|
||||
msgid "Relay domains support for Postfix"
|
||||
msgstr ""
|
||||
msgstr "Supporto ai \"domini relè\" per Postfix"
|
||||
|
||||
#: extensions/postfix_relay_domains/__init__.py:89
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:100
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:16
|
||||
#, fuzzy
|
||||
msgid "Relay domains"
|
||||
msgstr "Nuovo dominio"
|
||||
msgstr "Domini relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/app_settings.py:10
|
||||
msgid "Postfix's master.cf path"
|
||||
msgstr ""
|
||||
msgstr "Percorso del file master.cf di Postfix"
|
||||
|
||||
#: extensions/postfix_relay_domains/app_settings.py:12
|
||||
#, fuzzy
|
||||
msgid "Path to the master.cf configuration file"
|
||||
msgstr "Percorso del file di log"
|
||||
msgstr "Percorso del file di configurazione master.cf"
|
||||
|
||||
#: extensions/postfix_relay_domains/forms.py:15
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Alias(es) of this relay domain. Indicate only one name per input, press "
|
||||
"ENTER to add a new input."
|
||||
msgstr ""
|
||||
"Alias per questo dominio. Inserire un solo nome alla volta, premere INVIO "
|
||||
"per aggiungere un nuovo elemento"
|
||||
msgstr "Alias per questo dominio relè. Inserisci un solo nome per casella, premi INVIO per aggiungere un nuovo elemento."
|
||||
|
||||
#: extensions/postfix_relay_domains/forms.py:51
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:93
|
||||
#, fuzzy
|
||||
msgid "relay domain alias"
|
||||
msgstr "Alias del dominio"
|
||||
msgstr "Alias del dominio relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/forms.py:69
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:92
|
||||
#, fuzzy
|
||||
msgid "relay domain"
|
||||
msgstr "Nuovo dominio"
|
||||
msgstr "Dominio relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:35
|
||||
#, fuzzy
|
||||
msgid "Add relay domain"
|
||||
msgstr "Aggiungi dominio"
|
||||
msgstr "Aggiungi dominio relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:101
|
||||
#, fuzzy
|
||||
msgid "Maximum number of relay domains this user can create"
|
||||
msgstr "Numero massimo di domini che questo utente può creare"
|
||||
msgstr "Numero massimo di domini relè che questo utente può creare"
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:103
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:24
|
||||
#, fuzzy
|
||||
msgid "Relay domain aliases"
|
||||
msgstr "Alias del dominio"
|
||||
msgstr "Alias del dominio relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:104
|
||||
#, fuzzy
|
||||
msgid "Maximum number of relay domain aliases this user can create"
|
||||
msgstr "Numero massimo di alias di dominio che questo utente può creare"
|
||||
msgstr "Numero massimo di alias di un dominio relè che questo utente può creare"
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:111
|
||||
msgid ""
|
||||
@@ -2121,80 +2080,70 @@ msgid ""
|
||||
"em></li>\n"
|
||||
"<li><em>relaydomainalias; name; target; enabled</em></li>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<li><em>dominio relè; nome; host di destinazione; servizio; abilitato; verifica caselle</em></li>\n"
|
||||
"<li><em> alias dominio relè; nome; destinazione; abilitato</em></li>\n"
|
||||
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:19
|
||||
#, fuzzy
|
||||
msgid "Maximum number of allowed relay domains for a new administrator"
|
||||
msgstr "Numero massimo di domini consentiti per un nuovo amministratore"
|
||||
msgstr "Numero massimo di domini relè consentiti per un nuovo amministratore"
|
||||
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:27
|
||||
#, fuzzy
|
||||
msgid "Maximum number of allowed relay domain aliases for a new administrator"
|
||||
msgstr ""
|
||||
"Numero massimo di alias di dominio consentiti per un nuovo amministratore"
|
||||
msgstr "Numero massimo di alias di dominio relè consentiti per un nuovo amministratore"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:59
|
||||
#, fuzzy
|
||||
msgid "The service name"
|
||||
msgstr "Il nome dell'alias"
|
||||
msgstr "Il nome del servizio"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:80
|
||||
#, fuzzy
|
||||
msgid "target host"
|
||||
msgstr "destinazione"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:81
|
||||
#, fuzzy
|
||||
msgid "Remote destination of this domain"
|
||||
msgstr "Seleziona per attivare questo dominio"
|
||||
msgstr "Destinazione remota per questo dominio"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:89
|
||||
#, fuzzy
|
||||
msgid "verify recipients"
|
||||
msgstr "Destinatari"
|
||||
msgstr "Verifica destinatari"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:90
|
||||
msgid "Check for valid recipients"
|
||||
msgstr ""
|
||||
msgstr "Verifica validità destinatari"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:103
|
||||
#, fuzzy
|
||||
msgid "Relay Domain"
|
||||
msgstr "Nuovo dominio"
|
||||
msgstr "Dominio relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:164
|
||||
#, fuzzy
|
||||
msgid "The relay domain this alias points to"
|
||||
msgstr "Il dominio a cui punta questo alias"
|
||||
msgstr "Il dominio relè a cui punta questo alias"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:195
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Relay domain %s does not exist"
|
||||
msgstr "Il dominio '%s' non esiste"
|
||||
msgstr "Il dominio relè '%s' non esiste"
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:26
|
||||
#, fuzzy
|
||||
msgid "Relay domain created"
|
||||
msgstr "Dominio creato"
|
||||
msgstr "Dominio relè creato"
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:31
|
||||
#, fuzzy
|
||||
msgid "New relay domain"
|
||||
msgstr "Nuovo dominio"
|
||||
msgstr "Nuovo dominio relè"
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:54
|
||||
#, fuzzy
|
||||
msgid "Relay domain modified"
|
||||
msgstr "Dominio modificato"
|
||||
msgstr "Dominio relè modificato"
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:77
|
||||
#, fuzzy
|
||||
msgid "Relay domain deleted"
|
||||
msgstr "Dominio cancellato"
|
||||
msgstr "Dominio relè cancellato"
|
||||
|
||||
#: extensions/postfix_relay_domains/templates/postfix_relay_domains/service_field.html:2
|
||||
msgid "Scan"
|
||||
msgstr ""
|
||||
msgstr "Cerca"
|
||||
|
||||
#: extensions/sievefilters/__init__.py:12
|
||||
msgid "Plugin to easily create server-side filters"
|
||||
@@ -2315,53 +2264,53 @@ msgstr ""
|
||||
msgid "Not enough space on server"
|
||||
msgstr "Non c'è spazio sufficiente nel server"
|
||||
|
||||
#: extensions/sievefilters/views.py:78
|
||||
#: extensions/sievefilters/views.py:80
|
||||
msgid "Failed to retrieve filters set"
|
||||
msgstr "Recupero delle impostazioni di filtro fallito"
|
||||
|
||||
#: extensions/sievefilters/views.py:138
|
||||
#: extensions/sievefilters/views.py:141
|
||||
#: extensions/sievefilters/templatetags/sfilters_tags.py:33
|
||||
msgid "New filter"
|
||||
msgstr "Nuovo filtro"
|
||||
|
||||
#: extensions/sievefilters/views.py:146
|
||||
#: extensions/sievefilters/views.py:149
|
||||
msgid "Filter created"
|
||||
msgstr "Filtro creato"
|
||||
|
||||
#: extensions/sievefilters/views.py:160
|
||||
#: extensions/sievefilters/views.py:163
|
||||
#: extensions/sievefilters/templatetags/sfilters_tags.py:78
|
||||
msgid "Edit filter"
|
||||
msgstr "Modifica filtro"
|
||||
|
||||
#: extensions/sievefilters/views.py:169
|
||||
#: extensions/sievefilters/views.py:172
|
||||
msgid "Filter modified"
|
||||
msgstr "Filtro modificato"
|
||||
|
||||
#: extensions/sievefilters/views.py:192
|
||||
#: extensions/sievefilters/views.py:195
|
||||
msgid "Filter removed"
|
||||
msgstr "Filtro eliminato"
|
||||
|
||||
#: extensions/sievefilters/views.py:193
|
||||
#: extensions/sievefilters/views.py:196
|
||||
msgid "Failed to remove filter"
|
||||
msgstr "Rimozione del filtro fallita"
|
||||
|
||||
#: extensions/sievefilters/views.py:208
|
||||
#: extensions/sievefilters/views.py:211
|
||||
msgid "Filters set saved"
|
||||
msgstr "Gruppo filtri salvato"
|
||||
|
||||
#: extensions/sievefilters/views.py:224
|
||||
#: extensions/sievefilters/views.py:227
|
||||
msgid "Filters set created"
|
||||
msgstr "Gruppo filtri creato"
|
||||
|
||||
#: extensions/sievefilters/views.py:228
|
||||
#: extensions/sievefilters/views.py:231
|
||||
msgid "Create a new filters set"
|
||||
msgstr "Crea un nuovo gruppo di filtri"
|
||||
|
||||
#: extensions/sievefilters/views.py:247
|
||||
#: extensions/sievefilters/views.py:250
|
||||
msgid "Filters set deleted"
|
||||
msgstr "Gruppo filtri eliminato"
|
||||
|
||||
#: extensions/sievefilters/views.py:260
|
||||
#: extensions/sievefilters/views.py:263
|
||||
msgid "Filters set activated"
|
||||
msgstr "Gruppo filtri attivato"
|
||||
|
||||
@@ -2649,13 +2598,12 @@ msgid "Automatic folder refresh rate (in seconds)"
|
||||
msgstr "Frequenza di aggiornamento automatico delle cartelle (in secondi)"
|
||||
|
||||
#: extensions/webmail/app_settings.py:103
|
||||
#, fuzzy
|
||||
msgid "Mailboxes container's width"
|
||||
msgstr "Proprietario delle caselle postali"
|
||||
msgstr "Larghezza del contenitore delle caselle"
|
||||
|
||||
#: extensions/webmail/app_settings.py:104
|
||||
msgid "The width of the mailbox list container"
|
||||
msgstr ""
|
||||
msgstr "Larghezza della lista delle caselle"
|
||||
|
||||
#: extensions/webmail/app_settings.py:111
|
||||
msgid "Trash folder"
|
||||
@@ -2703,7 +2651,7 @@ msgstr "Signature delle e-mail personalizzato dall'utente"
|
||||
|
||||
#: extensions/webmail/app_settings.py:160
|
||||
msgid "Value must be a positive integer (> 0)"
|
||||
msgstr ""
|
||||
msgstr "Il valore dev'essere un intero positivo"
|
||||
|
||||
#: extensions/webmail/exceptions.py:20
|
||||
msgid "Server response"
|
||||
@@ -2889,9 +2837,9 @@ msgid "Remove the selected mailbox"
|
||||
msgstr "Elimina la cartella di posta selezionata"
|
||||
|
||||
#: lib/dbutils.py:36
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Connection to database %s not configured"
|
||||
msgstr "Connessione ad amavis fallita: %s"
|
||||
msgstr "La connessione con il database %s non è configurata"
|
||||
|
||||
#: lib/exceptions.py:67
|
||||
#, python-format
|
||||
@@ -2997,36 +2945,3 @@ msgstr "Ricordami"
|
||||
#: templates/registration/login.html:36
|
||||
msgid "Log in"
|
||||
msgstr "Registrati"
|
||||
|
||||
#~ msgid "An alias with this name already exists"
|
||||
#~ msgstr "Esiste già un alias con questo nome"
|
||||
|
||||
#~ msgid "A domain with this name already exists"
|
||||
#~ msgstr "Esiste già un dominio con questo nome"
|
||||
|
||||
#~ msgid "Edit domain"
|
||||
#~ msgstr "Modifica dominio"
|
||||
|
||||
#~ msgid "%d pending requests"
|
||||
#~ msgstr "%d richieste in sospeso"
|
||||
|
||||
#~ msgid "Content Class"
|
||||
#~ msgstr "Classe dei contenuti"
|
||||
|
||||
#~ msgid "Nothing"
|
||||
#~ msgstr "Nulla"
|
||||
|
||||
#~ msgid "Bad request"
|
||||
#~ msgstr "Richiesta sbagliata"
|
||||
|
||||
#~ msgid "Undefined action"
|
||||
#~ msgstr "Azione non definita"
|
||||
|
||||
#~ msgid "User preferences"
|
||||
#~ msgstr "Preferenze utente"
|
||||
|
||||
#~ msgid "Per-user settings"
|
||||
#~ msgstr "Impostazioni per-utente"
|
||||
|
||||
#~ msgid "You need a mailbox in order to define a forward"
|
||||
#~ msgstr "Hai bisogno di una casella di posta per definire un inoltro"
|
||||
|
||||
@@ -7,9 +7,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-12-15 10:16+0100\n"
|
||||
"PO-Revision-Date: 2013-09-27 00:07+0200\n"
|
||||
"Last-Translator: Giancarlo Gaifas <lallo@artiemestieri.tn.it>\n"
|
||||
"POT-Creation-Date: 2013-12-22 23:16+0100\n"
|
||||
"PO-Revision-Date: 2013-12-23 00:58+0100\n"
|
||||
"Last-Translator: Alberto Berti <alberto@metapensiero.it>\n"
|
||||
"Language-Team: Italiano <LL@li.org>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -73,7 +73,7 @@ msgstr "Nascondi le intestazioni"
|
||||
|
||||
#: extensions/postfix_relay_domains/static/postfix_relay_domains/js/relay_domains.js:49
|
||||
msgid "Services updated"
|
||||
msgstr ""
|
||||
msgstr "Servizi aggiornati"
|
||||
|
||||
#: extensions/sievefilters/static/sievefilters/js/lib.js:14
|
||||
msgid "Remove this filter?"
|
||||
@@ -135,13 +135,9 @@ msgid "Cancel"
|
||||
msgstr "Elimina"
|
||||
|
||||
#: static/js/global.js:314
|
||||
#, fuzzy
|
||||
msgid "Internal error"
|
||||
msgstr "Errore interno"
|
||||
|
||||
#: static/js/searchbar.js:20
|
||||
msgid "Search..."
|
||||
msgstr "Ricerca ..."
|
||||
|
||||
#~ msgid "Message deleted"
|
||||
#~ msgstr "Messaggio eliminato"
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
#
|
||||
# Translators:
|
||||
# ddu17 <dduponchelle@gmail.com>, 2013
|
||||
# lusitan <lusitan@hushmail.com>, 2013
|
||||
# mikec <miguelmclara@gmail.com>, 2012
|
||||
# mikec <miguelmclara@gmail.com>, 2013
|
||||
# Sandra Ribeiro <sandrarib@gmail.com>, 2012-2013
|
||||
@@ -13,14 +14,13 @@ msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-12-15 10:21+0100\n"
|
||||
"PO-Revision-Date: 2013-10-04 21:10+0000\n"
|
||||
"Last-Translator: ddu17 <dduponchelle@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/"
|
||||
"modoboa/language/pt_PT/)\n"
|
||||
"Language: pt_PT\n"
|
||||
"PO-Revision-Date: 2013-12-23 11:25+0000\n"
|
||||
"Last-Translator: lusitan <lusitan@hushmail.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/modoboa/language/pt_PT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_PT\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: core/__init__.py:52 core/__init__.py:53
|
||||
@@ -55,23 +55,23 @@ msgstr "Esquema pré-definido para passwords"
|
||||
|
||||
#: core/app_settings.py:51
|
||||
msgid "md5crypt (weak)"
|
||||
msgstr ""
|
||||
msgstr "md5crypt (fraco)"
|
||||
|
||||
#: core/app_settings.py:52
|
||||
msgid "sha256 (weak)"
|
||||
msgstr ""
|
||||
msgstr "sha256 (fraco)"
|
||||
|
||||
#: core/app_settings.py:53
|
||||
msgid "md5 (weak)"
|
||||
msgstr ""
|
||||
msgstr "md5 (fraco)"
|
||||
|
||||
#: core/app_settings.py:54
|
||||
msgid "crypt (weak)"
|
||||
msgstr ""
|
||||
msgstr "crypt (fraco)"
|
||||
|
||||
#: core/app_settings.py:55
|
||||
msgid "plain (weak)"
|
||||
msgstr ""
|
||||
msgstr "plain (fraco)"
|
||||
|
||||
#: core/app_settings.py:57
|
||||
msgid "Scheme used to crypt mailbox passwords"
|
||||
@@ -149,9 +149,7 @@ msgstr "\"Bind DN\""
|
||||
msgid ""
|
||||
"The distinguished name to use when binding to the LDAP server. Leave empty "
|
||||
"for an anonymous bind"
|
||||
msgstr ""
|
||||
"O nome único usado para fazer o \"bind\" ao servidor LDAP. Deixar vario "
|
||||
"para \"bind\" anónimo"
|
||||
msgstr "O nome único usado para fazer o \"bind\" ao servidor LDAP. Deixar vario para \"bind\" anónimo"
|
||||
|
||||
#: core/app_settings.py:113
|
||||
msgid "Bind password"
|
||||
@@ -159,18 +157,15 @@ msgstr "Password para bind"
|
||||
|
||||
#: core/app_settings.py:115
|
||||
msgid "The password to use when binding to the LDAP server (with 'Bind DN')"
|
||||
msgstr ""
|
||||
"A password usada para fazer o \"bind\" ao servidor LDAP (com 'Bind DN')"
|
||||
msgstr "A password usada para fazer o \"bind\" ao servidor LDAP (com 'Bind DN')"
|
||||
|
||||
#: core/app_settings.py:121
|
||||
#, fuzzy
|
||||
msgid "Users search base"
|
||||
msgstr "Base de pesquisa"
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:123
|
||||
#, fuzzy
|
||||
msgid "The distinguished name of the search base used to find users"
|
||||
msgstr "O nome único para a pesquisa base"
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:128
|
||||
msgid "Search filter"
|
||||
@@ -180,9 +175,7 @@ msgstr "Filtro de pesquisa"
|
||||
msgid ""
|
||||
"An optional filter string (e.g. '(objectClass=person)'). In order to be "
|
||||
"valid, it must be enclosed in parentheses."
|
||||
msgstr ""
|
||||
"Um filtro opcional (ex: '(objetClass=person)'). Tem de estar entre "
|
||||
"parênteses para ser válido"
|
||||
msgstr "Um filtro opcional (ex: '(objetClass=person)'). Tem de estar entre parênteses para ser válido"
|
||||
|
||||
#: core/app_settings.py:135
|
||||
msgid "User DN template"
|
||||
@@ -193,9 +186,7 @@ msgstr "Template DN de utilizador"
|
||||
msgid ""
|
||||
"The template used to construct a user's DN. It should contain one "
|
||||
"placeholder (ie. %(user)s)"
|
||||
msgstr ""
|
||||
"O template usado para construir o DN (nome único). Deve apenas conter um "
|
||||
"'placeholder' (ex: %(user)s) "
|
||||
msgstr "O template usado para construir o DN (nome único). Deve apenas conter um 'placeholder' (ex: %(user)s) "
|
||||
|
||||
#: core/app_settings.py:142
|
||||
msgid "Password attribute"
|
||||
@@ -214,25 +205,22 @@ msgid "Tell if the LDAP server is an Active Directory one"
|
||||
msgstr "Especificar se o servidor LDAP e um Active Directory"
|
||||
|
||||
#: core/app_settings.py:154
|
||||
#, fuzzy
|
||||
msgid "Administrator groups"
|
||||
msgstr "Administradores"
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:157
|
||||
msgid ""
|
||||
"Members of those LDAP Posix groups will be created as domain administrators. "
|
||||
"Use ';' characters to separate groups."
|
||||
"Members of those LDAP Posix groups will be created as domain administrators."
|
||||
" Use ';' characters to separate groups."
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:164
|
||||
#, fuzzy
|
||||
msgid "Groups search base"
|
||||
msgstr "Base de pesquisa"
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:167
|
||||
#, fuzzy
|
||||
msgid "The distinguished name of the search base used to find groups"
|
||||
msgstr "O nome único para a pesquisa base"
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:172
|
||||
#: extensions/admin/templates/admin/editdomainform.html:7
|
||||
@@ -261,9 +249,7 @@ msgstr "Redirecionamento pré-definido"
|
||||
|
||||
#: core/app_settings.py:190
|
||||
msgid "The default redirection used when no application is specified"
|
||||
msgstr ""
|
||||
"O redirecionamento padrão usado quando nenhuma aplicação se encontra "
|
||||
"especificada"
|
||||
msgstr "O redirecionamento padrão usado quando nenhuma aplicação se encontra especificada"
|
||||
|
||||
#: core/app_settings.py:218
|
||||
msgid "Key must be either 16, 24, or 32 bytes long"
|
||||
@@ -274,9 +260,8 @@ msgid "Invalid syntax"
|
||||
msgstr "Sintax inválida"
|
||||
|
||||
#: core/app_settings.py:233
|
||||
#, fuzzy
|
||||
msgid "Invalid rounds number"
|
||||
msgstr "Pedido inválido"
|
||||
msgstr ""
|
||||
|
||||
#: core/app_settings.py:256
|
||||
msgid "This field is required"
|
||||
@@ -326,14 +311,12 @@ msgid "Passwords mismatch"
|
||||
msgstr "Passwords não coincidem"
|
||||
|
||||
#: core/models.py:50
|
||||
#, fuzzy
|
||||
msgid "password"
|
||||
msgstr "Password"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:52
|
||||
#, fuzzy
|
||||
msgid "last login"
|
||||
msgstr "Último login"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:81
|
||||
msgid "You can't delete your own account"
|
||||
@@ -366,9 +349,7 @@ msgstr "O simple utilizador '%s' deve ter endereço de e-mail válido"
|
||||
#: core/models.py:335
|
||||
#, python-format
|
||||
msgid "username and email fields must not differ for '%s'"
|
||||
msgstr ""
|
||||
"Os campos nome de utilizador e endereço de email não deve ser diferente para "
|
||||
"'%s'"
|
||||
msgstr "Os campos nome de utilizador e endereço de email não deve ser diferente para '%s'"
|
||||
|
||||
#: core/models.py:404 extensions/admin/models/alias.py:33
|
||||
#: extensions/admin/models/domain.py:32
|
||||
@@ -583,31 +564,15 @@ msgid ""
|
||||
"\n"
|
||||
"<h3>Welcome to the online demo!</h3>\n"
|
||||
"<p><b>Warning:</b> the demo's concent is resetted every two hours.</p>\n"
|
||||
"<p>To try the demo, the following users are available (<i>username/password</"
|
||||
"i>): </p>\n"
|
||||
"<p>To try the demo, the following users are available (<i>username/password</i>): </p>\n"
|
||||
"<ul>\n"
|
||||
" <li>A super administrator : <b>admin/password</b></li>\n"
|
||||
" <li>A domain administrator : <b>admin@demo.local/admin</b></li>\n"
|
||||
" <li>A simple user : <b>user@demo.local/user</b></li>\n"
|
||||
"</ul>\n"
|
||||
"<p>Please report any issue or give any suggestion to \n"
|
||||
" <a href=\"https://groups.google.com/forum/#!forum/modoboa-users\">the "
|
||||
"mailing list</a>.</p>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<h3>Bem-vindo à demo online!</h3>\n"
|
||||
"<p><b>Aviso:</b> os conteúdos desta demo são limpos a cada duas horas.</p>\n"
|
||||
"<p>Para experimentar a demo, estão disponíveis os seguintes utilizadores "
|
||||
"(<i>username/password</i>): </p>\n"
|
||||
"<ul>\n"
|
||||
" <li>Super administrador: <b>admin/password</b></li>\n"
|
||||
" <li>Administrador de domínio: <b>admin@demo.local/admin</b></li>\n"
|
||||
" <li>Utilizador básico: <b>user@demo.local/user</b></li>\n"
|
||||
"</ul>\n"
|
||||
"<p>Para reportar qualquer problema ou apresentar uma sugestão, utilize o "
|
||||
"seguinte link \n"
|
||||
" <a href=\"https://groups.google.com/forum/#!forum/modoboa-users\">mailing "
|
||||
"list</a>.</p>\n"
|
||||
" <a href=\"https://groups.google.com/forum/#!forum/modoboa-users\">the mailing list</a>.</p>\n"
|
||||
msgstr "\n<h3>Bem-vindo à demo online!</h3>\n<p><b>Aviso:</b> os conteúdos desta demo são limpos a cada duas horas.</p>\n<p>Para experimentar a demo, estão disponíveis os seguintes utilizadores (<i>username/password</i>): </p>\n<ul>\n <li>Super administrador: <b>admin/password</b></li>\n <li>Administrador de domínio: <b>admin@demo.local/admin</b></li>\n <li>Utilizador básico: <b>user@demo.local/user</b></li>\n</ul>\n<p>Para reportar qualquer problema ou apresentar uma sugestão, utilize o seguinte link \n <a href=\"https://groups.google.com/forum/#!forum/modoboa-users\">mailing list</a>.</p>\n"
|
||||
|
||||
#: extensions/admin/__init__.py:48
|
||||
msgid "Administration console"
|
||||
@@ -618,9 +583,8 @@ msgid "Web based console to manage domains, accounts and aliases"
|
||||
msgstr "Consola baseada na web para gestão de domínios, contas e aliases"
|
||||
|
||||
#: extensions/admin/__init__.py:55
|
||||
#, fuzzy
|
||||
msgid "Administration"
|
||||
msgstr "Administradores"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/__init__.py:79
|
||||
#: extensions/admin/templates/admin/domains.html:2
|
||||
@@ -660,9 +624,7 @@ msgstr "Lidar com caixas de correio no sistema de ficheiros"
|
||||
msgid ""
|
||||
"Rename or remove mailboxes on the filesystem when they get renamed or "
|
||||
"removed within Modoboa"
|
||||
msgstr ""
|
||||
"Renomear ou remover as caixas de correio no sistema de ficheiros quando "
|
||||
"estas são renomeadas no Modoboa"
|
||||
msgstr "Renomear ou remover as caixas de correio no sistema de ficheiros quando estas são renomeadas no Modoboa"
|
||||
|
||||
#: extensions/admin/app_settings.py:20
|
||||
msgid "Mailboxes ower"
|
||||
@@ -673,9 +635,8 @@ msgid "The UNIX account who owns mailboxes on the filesystem"
|
||||
msgstr "A conta UNIX que detém as caixas de correio no sistema de ficheiros"
|
||||
|
||||
#: extensions/admin/app_settings.py:26
|
||||
#, fuzzy
|
||||
msgid "Default domain quota"
|
||||
msgstr "Limites predefinidos"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/app_settings.py:29
|
||||
msgid ""
|
||||
@@ -689,8 +650,7 @@ msgstr "Remoção automática de conta"
|
||||
|
||||
#: extensions/admin/app_settings.py:38
|
||||
msgid "When a mailbox is removed, also remove the associated account"
|
||||
msgstr ""
|
||||
"Ao remover uma caixa de correio estará também a remover a conta associada"
|
||||
msgstr "Ao remover uma caixa de correio estará também a remover a conta associada"
|
||||
|
||||
#: extensions/admin/app_settings.py:69 extensions/admin/forms/account.py:178
|
||||
#: extensions/admin/forms/domain.py:56
|
||||
@@ -698,16 +658,14 @@ msgid "Must be a positive integer"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/lib.py:28
|
||||
#, fuzzy
|
||||
msgid "A mailbox is required"
|
||||
msgstr "É necessário uma quota"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/forms/account.py:21
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The user's name. Must be a valid e-mail address for simple users or "
|
||||
"administrators with a mailbox."
|
||||
msgstr "O simple utilizador '%s' deve ter endereço de e-mail válido"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/forms/account.py:26
|
||||
msgid "Role"
|
||||
@@ -750,10 +708,7 @@ msgid ""
|
||||
"Quota in MB for this mailbox. Define a custom value or use domain's default "
|
||||
"one. Leave empty to define an unlimited value (not allowed for domain "
|
||||
"administrators)."
|
||||
msgstr ""
|
||||
"Quota em MB para esta caixa de correio. Definir uma valor personalizado ou "
|
||||
"usar o valor predefinido pelo domínio. Deixar em branco para definir uma "
|
||||
"valor ilimitado (não permitido para administradores do domínio)."
|
||||
msgstr "Quota em MB para esta caixa de correio. Definir uma valor personalizado ou usar o valor predefinido pelo domínio. Deixar em branco para definir uma valor ilimitado (não permitido para administradores do domínio)."
|
||||
|
||||
#: extensions/admin/forms/account.py:123 extensions/admin/forms/domain.py:26
|
||||
#: extensions/admin/templates/admin/domains_table.html:6
|
||||
@@ -766,10 +721,7 @@ msgid ""
|
||||
"Alias(es) of this mailbox. Indicate only one address per input, press ENTER "
|
||||
"to add a new input. Use the '*' character to create a 'catchall' alias (ex: "
|
||||
"*@domain.tld)."
|
||||
msgstr ""
|
||||
"Alias(es) desta caixa de correio. Indique apenas um endereço por entrada, "
|
||||
"clique ENTER para adicionar uma nova entrada. Use o '*' para criar um alias "
|
||||
"'catchall' (ex: *@domain.tld)."
|
||||
msgstr "Alias(es) desta caixa de correio. Indique apenas um endereço por entrada, clique ENTER para adicionar uma nova entrada. Use o '*' para criar um alias 'catchall' (ex: *@domain.tld)."
|
||||
|
||||
#: extensions/admin/forms/account.py:187 extensions/admin/forms/account.py:217
|
||||
#: extensions/admin/forms/alias.py:65
|
||||
@@ -806,9 +758,7 @@ msgstr "Endereço de e-mail"
|
||||
msgid ""
|
||||
"The distribution list address. Use the '*' character to create a 'catchall' "
|
||||
"address (ex: *@domain.tld)."
|
||||
msgstr ""
|
||||
"Os endereços da lista de distribuição. Use o '*' para criar um endereço "
|
||||
"'catchall' (Ex: *@domain.tld)."
|
||||
msgstr "Os endereços da lista de distribuição. Use o '*' para criar um endereço 'catchall' (Ex: *@domain.tld)."
|
||||
|
||||
#: extensions/admin/forms/alias.py:23
|
||||
msgid "Recipients"
|
||||
@@ -818,9 +768,7 @@ msgstr "Destinatários"
|
||||
msgid ""
|
||||
"Mailbox(es) this alias will point to. Indicate only one address per input, "
|
||||
"press ENTER to add a new input."
|
||||
msgstr ""
|
||||
"Caixa(s) de correio para o qual este 'alias' aponta. Indicar apenas um "
|
||||
"endereço por entrada, pressionar ENTER para acrescentar uma nova entrada."
|
||||
msgstr "Caixa(s) de correio para o qual este 'alias' aponta. Indicar apenas um endereço por entrada, pressionar ENTER para acrescentar uma nova entrada."
|
||||
|
||||
#: extensions/admin/forms/alias.py:68
|
||||
msgid "You don't have access to this domain"
|
||||
@@ -845,40 +793,35 @@ msgid "No recipient defined"
|
||||
msgstr "Sem destinatário definido"
|
||||
|
||||
#: extensions/admin/forms/domain.py:20
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Default quota in MB applied to mailboxes. Leave empty to use the default "
|
||||
"value."
|
||||
msgstr "Quota em MB aplicada por defeito às caixas de correio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/forms/domain.py:29
|
||||
msgid ""
|
||||
"Alias(es) of this domain. Indicate only one name per input, press ENTER to "
|
||||
"add a new input."
|
||||
msgstr ""
|
||||
"Alias(es) deste domínio. Indicar apenas um nome por entrada, pressionar "
|
||||
"ENTER para acrescentar uma nova entrada."
|
||||
msgstr "Alias(es) deste domínio. Indicar apenas um nome por entrada, pressionar ENTER para acrescentar uma nova entrada."
|
||||
|
||||
#: extensions/admin/forms/domain.py:75
|
||||
#: extensions/postfix_relay_domains/forms.py:50
|
||||
#: extensions/postfix_relay_domains/forms.py:70
|
||||
#, fuzzy
|
||||
msgid "domain alias"
|
||||
msgstr "Aliases de domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/forms/domain.py:82 extensions/admin/forms/domain.py:98
|
||||
#: extensions/postfix_relay_domains/forms.py:58
|
||||
#: extensions/postfix_relay_domains/forms.py:78
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "A %s with this name already exists"
|
||||
msgstr "Já existe um 'alias' com este nome"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/forms/domain.py:92
|
||||
#: extensions/postfix_relay_domains/forms.py:49
|
||||
#: extensions/postfix_relay_domains/forms.py:71
|
||||
#, fuzzy
|
||||
msgid "domain"
|
||||
msgstr "Domínios"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/forms/domain.py:176
|
||||
msgid "Create a domain administrator"
|
||||
@@ -892,9 +835,7 @@ msgstr "Criar automaticamente um administrador para este domínio"
|
||||
msgid ""
|
||||
"The administrator's name. Don't include the domain's name here, it will be "
|
||||
"automatically appended."
|
||||
msgstr ""
|
||||
"O nome do administrador. Não inclua o nome do domínio já que este será "
|
||||
"automaticamente anexado."
|
||||
msgstr "O nome do administrador. Não inclua o nome do domínio já que este será automaticamente anexado."
|
||||
|
||||
#: extensions/admin/forms/domain.py:193
|
||||
msgid "Create aliases"
|
||||
@@ -935,16 +876,13 @@ msgstr "Conservar cópias locais"
|
||||
|
||||
#: extensions/admin/forms/forward.py:20
|
||||
msgid "Forward messages and store copies into your local mailbox"
|
||||
msgstr ""
|
||||
"Reencaminhar mensagens e armazenar cópias na sua caixa de correio local"
|
||||
msgstr "Reencaminhar mensagens e armazenar cópias na sua caixa de correio local"
|
||||
|
||||
#: extensions/admin/forms/forward.py:38
|
||||
msgid ""
|
||||
"You can't define a forward to a local destination. Please ask your "
|
||||
"administrator to create an alias instead."
|
||||
msgstr ""
|
||||
"Não é possível definir um reencaminhamento para um destino local. Por favor "
|
||||
"informe-se junto de um administrador para criar um alias."
|
||||
msgstr "Não é possível definir um reencaminhamento para um destino local. Por favor informe-se junto de um administrador para criar um alias."
|
||||
|
||||
#: extensions/admin/forms/import_.py:6 extensions/webmail/forms.py:26
|
||||
msgid "Select a file"
|
||||
@@ -972,11 +910,9 @@ msgstr "endereços"
|
||||
|
||||
#: extensions/admin/models/alias.py:18
|
||||
msgid ""
|
||||
"The alias address (without the domain part). For a 'catch-all' address, just "
|
||||
"enter an * character."
|
||||
msgstr ""
|
||||
"O endereço do alias (sem a parte do domínio). Para um endereço 'cath-all', "
|
||||
"digite apenas o caractere *"
|
||||
"The alias address (without the domain part). For a 'catch-all' address, just"
|
||||
" enter an * character."
|
||||
msgstr "O endereço do alias (sem a parte do domínio). Para um endereço 'cath-all', digite apenas o caractere *"
|
||||
|
||||
#: extensions/admin/models/alias.py:24
|
||||
msgid "mailboxes"
|
||||
@@ -1037,9 +973,8 @@ msgid "Check to activate this domain"
|
||||
msgstr "Marcar para ativar este domínio"
|
||||
|
||||
#: extensions/admin/models/domain.py:61
|
||||
#, fuzzy
|
||||
msgid "Domain"
|
||||
msgstr "Domínios"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/models/domain.py:140
|
||||
#, python-format
|
||||
@@ -1061,9 +996,9 @@ msgid "The domain this alias points to"
|
||||
msgstr "O domínio para o qual este alias irá apontar"
|
||||
|
||||
#: extensions/admin/models/domain_alias.py:46
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "A domain %s already exists"
|
||||
msgstr "Caixa de correio %s já existe"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/models/domain_alias.py:51
|
||||
#, python-format
|
||||
@@ -1095,9 +1030,8 @@ msgid "MB"
|
||||
msgstr "MB"
|
||||
|
||||
#: extensions/admin/templates/admin/domain_options_form.html:5
|
||||
#, fuzzy
|
||||
msgid "You can't create a new domain administrator"
|
||||
msgstr "Criar um administrador de domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/admin/templates/admin/domains_table.html:7
|
||||
#: extensions/admin/templates/admin/identities_table.html:7
|
||||
@@ -1379,7 +1313,7 @@ msgstr[0] "Conta eliminada"
|
||||
msgstr[1] "Contas eliminadas"
|
||||
|
||||
#: extensions/admin/views/import.py:39
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Provide a CSV file where lines respect one of the following formats:\n"
|
||||
"<ul>\n"
|
||||
@@ -1387,15 +1321,9 @@ msgid ""
|
||||
" <li><em>domainalias; name; targeted domain; enabled</em></li>\n"
|
||||
" %s\n"
|
||||
"</ul>\n"
|
||||
"<p>The first element of each line is mandatory and must be equal to one of "
|
||||
"the previous values.</p>\n"
|
||||
"<p>The first element of each line is mandatory and must be equal to one of the previous values.</p>\n"
|
||||
"<p>You can use a different character as separator.</p>\n"
|
||||
msgstr ""
|
||||
"Forneça um ficheiro CSV cujas linhas respeitem um dos seguintes formatos:⏎ "
|
||||
"<ul>⏎ <li><em>domain; name; quota; enabled</em></li>⏎ <li><em>domainalias; "
|
||||
"name; targeted domain; enabled</em></li>⏎ </ul>⏎ <p>O primeiro elemento de "
|
||||
"cada linha é obrigatório e deve ser igual a um dos valores anteriores.</p>⏎ "
|
||||
"<p>Pode utilizar um caractere diferente como separador.</p>⏎\n"
|
||||
|
||||
#: extensions/admin/views/import.py:50
|
||||
msgid "Import domains"
|
||||
@@ -1412,33 +1340,18 @@ msgid "%d objects imported successfully"
|
||||
msgstr "%d objetos importados com sucesso"
|
||||
|
||||
#: extensions/admin/views/import.py:153
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Provide a CSV file where lines respect one of the following formats:\n"
|
||||
"<ul>\n"
|
||||
"<li><em>account; loginname; password; first name; last name; enabled; group; "
|
||||
"address; quota; [, domain, ...]</em></li>\n"
|
||||
"<li><em>account; loginname; password; first name; last name; enabled; group; address; quota; [, domain, ...]</em></li>\n"
|
||||
"<li><em>alias; address; enabled; internal recipient</em></li>\n"
|
||||
"<li><em>forward; address; enabled; external recipient</em></li>\n"
|
||||
"<li><em>dlist; address; enabled; recipient; recipient; ...</em></li>\n"
|
||||
"</ul>\n"
|
||||
"<p>The first element of each line is mandatory and must be equal to one of "
|
||||
"the previous values.</p>\n"
|
||||
"<p>The first element of each line is mandatory and must be equal to one of the previous values.</p>\n"
|
||||
"\n"
|
||||
"<p>You can use a different character as separator.</p>\n"
|
||||
msgstr ""
|
||||
"Forneça um ficheiro CSV cujas linhas respeitem um dos seguintes formatos:⏎\n"
|
||||
"<ul>⏎\n"
|
||||
"<li><em>account; loginname; password; first name; last name; enabled; group; "
|
||||
"address[, domain, ...]</em></li>⏎\n"
|
||||
"<li><em>alias; address; enabled; internal recipient</em></li>⏎\n"
|
||||
"<li><em>forward; address; enabled; external recipient</em></li>⏎\n"
|
||||
"<li><em>dlist; address; enabled; recipient; recipient; ...</em></li>⏎\n"
|
||||
"</ul>⏎\n"
|
||||
"<p>O primeiro elemento de cada linha é obrigatório e deve ser igual a um dos "
|
||||
"valores anteriores..</p>⏎\n"
|
||||
"⏎\n"
|
||||
"<p>Pode utilizar um caractere diferente como separador.</p>⏎\n"
|
||||
|
||||
#: extensions/admin/views/import.py:165
|
||||
msgid "Import identities"
|
||||
@@ -1466,9 +1379,7 @@ msgstr "Idade maxima da messagem"
|
||||
|
||||
#: extensions/amavis/app_settings.py:16
|
||||
msgid "Quarantine messages maximum age (in days) before deletion"
|
||||
msgstr ""
|
||||
"Tempo máximo que as mensagens ficam na quarentena (em dias) até serem "
|
||||
"eliminadas"
|
||||
msgstr "Tempo máximo que as mensagens ficam na quarentena (em dias) até serem eliminadas"
|
||||
|
||||
#: extensions/amavis/app_settings.py:19
|
||||
msgid "Messages releasing"
|
||||
@@ -1480,9 +1391,7 @@ msgstr "Remover mensagens libertadas"
|
||||
|
||||
#: extensions/amavis/app_settings.py:24
|
||||
msgid "Remove messages marked as released while cleaning up the database"
|
||||
msgstr ""
|
||||
"Remova as mensagens, marcadas como enviadas, durante a limpeza da base de "
|
||||
"dados"
|
||||
msgstr "Remova as mensagens, marcadas como enviadas, durante a limpeza da base de dados"
|
||||
|
||||
#: extensions/amavis/app_settings.py:28
|
||||
msgid "Amavis connection mode"
|
||||
@@ -1561,9 +1470,8 @@ msgid "pending requests"
|
||||
msgstr "pedidos pendentes"
|
||||
|
||||
#: extensions/amavis/general_callbacks.py:124
|
||||
#, fuzzy
|
||||
msgid "Pending requests"
|
||||
msgstr "pedidos pendentes"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/general_callbacks.py:134
|
||||
msgid "Content filter"
|
||||
@@ -1596,9 +1504,7 @@ msgstr "predifinido"
|
||||
|
||||
#: extensions/amavis/models.py:98
|
||||
msgid "Bypass virus checks or not. Choose 'default' to use global settings."
|
||||
msgstr ""
|
||||
"Ignorar a verificação de vírus ou não. Escolher 'predefinido' para utilizar "
|
||||
"as definições gerais."
|
||||
msgstr "Ignorar a verificação de vírus ou não. Escolher 'predefinido' para utilizar as definições gerais."
|
||||
|
||||
#: extensions/amavis/models.py:101
|
||||
msgid "Spam filter"
|
||||
@@ -1606,9 +1512,7 @@ msgstr "Filtro de spam"
|
||||
|
||||
#: extensions/amavis/models.py:106
|
||||
msgid "Bypass spam checks or not. Choose 'default' to use global settings."
|
||||
msgstr ""
|
||||
"Ignorar filtros de spam ou não. Escolher 'predefinido' para utilizar as "
|
||||
"definições gerais."
|
||||
msgstr "Ignorar filtros de spam ou não. Escolher 'predefinido' para utilizar as definições gerais."
|
||||
|
||||
#: extensions/amavis/models.py:109
|
||||
msgid "Banned filter"
|
||||
@@ -1616,9 +1520,7 @@ msgstr "Ficheiros proibidos"
|
||||
|
||||
#: extensions/amavis/models.py:114
|
||||
msgid "Bypass banned checks or not. Choose 'default' to use global settings."
|
||||
msgstr ""
|
||||
"Ignorar a verificação de ficheiros proibidos. Escolher 'predefinido' para "
|
||||
"utilizar as definições gerais."
|
||||
msgstr "Ignorar a verificação de ficheiros proibidos. Escolher 'predefinido' para utilizar as definições gerais."
|
||||
|
||||
#: extensions/amavis/models.py:144
|
||||
msgid "Spam marker"
|
||||
@@ -1626,11 +1528,9 @@ msgstr "Marcador spam"
|
||||
|
||||
#: extensions/amavis/models.py:146
|
||||
msgid ""
|
||||
"Modify spam subject using the specified text. Choose 'default' to use global "
|
||||
"settings."
|
||||
msgstr ""
|
||||
"Modifique o assunto de spam usando o texto especificado. Escolha 'default' "
|
||||
"para usar as configurações globais."
|
||||
"Modify spam subject using the specified text. Choose 'default' to use global"
|
||||
" settings."
|
||||
msgstr "Modifique o assunto de spam usando o texto especificado. Escolha 'default' para usar as configurações globais."
|
||||
|
||||
#: extensions/amavis/sql_listing.py:31
|
||||
msgid "Score"
|
||||
@@ -1711,9 +1611,8 @@ msgid "Quarantine management"
|
||||
msgstr "Gestão de Quarentena"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:3
|
||||
#, fuzzy
|
||||
msgid "Select"
|
||||
msgstr "Escolha um ficheiro"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:9
|
||||
msgid "Spam"
|
||||
@@ -1724,18 +1623,16 @@ msgid "Virus"
|
||||
msgstr "Vírus"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:11
|
||||
#, fuzzy
|
||||
msgid "Bad Header"
|
||||
msgstr "Cabeçalho inválido"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:12
|
||||
msgid "Bad MIME"
|
||||
msgstr "Formato MIME inválido"
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:13
|
||||
#, fuzzy
|
||||
msgid "Banned"
|
||||
msgstr "Ficheiros proibidos"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:18
|
||||
#: extensions/amavis/templatetags/amavis_tags.py:19
|
||||
@@ -1760,29 +1657,24 @@ msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:32
|
||||
#, fuzzy
|
||||
msgid "Spam only"
|
||||
msgstr "Spam"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:33
|
||||
#, fuzzy
|
||||
msgid "Virus only"
|
||||
msgstr "Vírus"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:34
|
||||
#, fuzzy
|
||||
msgid "Bad Header only"
|
||||
msgstr "Cabeçalho inválido"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:35
|
||||
#, fuzzy
|
||||
msgid "Bad MIME only"
|
||||
msgstr "Formato MIME inválido"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/main_action_bar.html:36
|
||||
#, fuzzy
|
||||
msgid "Banned only"
|
||||
msgstr "Ficheiros proibidos"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/amavis/templates/amavis/notifications/pending_requests.html:1
|
||||
#, python-format
|
||||
@@ -1792,12 +1684,8 @@ msgid ""
|
||||
msgid_plural ""
|
||||
"\n"
|
||||
"%(counter)s release requests are pending for action.\n"
|
||||
msgstr[0] ""
|
||||
"\n"
|
||||
"%(counter)s pedido de libertação pendente\n"
|
||||
msgstr[1] ""
|
||||
"\n"
|
||||
"%(counter)s pedidos de libertação pendentes\n"
|
||||
msgstr[0] "\n%(counter)s pedido de libertação pendente\n"
|
||||
msgstr[1] "\n%(counter)s pedidos de libertação pendentes\n"
|
||||
|
||||
#: extensions/amavis/templates/amavis/notifications/pending_requests.html:6
|
||||
msgid "Sketch:"
|
||||
@@ -1850,10 +1738,9 @@ msgid "Domain admins"
|
||||
msgstr "Administradores de domínio"
|
||||
|
||||
#: extensions/limits/app_settings.py:15
|
||||
msgid "Maximum number of allowed domain administrators for a new administrator"
|
||||
msgstr ""
|
||||
"Número máximo permitido de administradores de domínio para um novo "
|
||||
"administrador"
|
||||
msgid ""
|
||||
"Maximum number of allowed domain administrators for a new administrator"
|
||||
msgstr "Número máximo permitido de administradores de domínio para um novo administrador"
|
||||
|
||||
#: extensions/limits/app_settings.py:21
|
||||
msgid "Maximum number of allowed domains for a new administrator"
|
||||
@@ -1861,8 +1748,7 @@ msgstr "Número máximo permitido de domínios para novo administrador"
|
||||
|
||||
#: extensions/limits/app_settings.py:27
|
||||
msgid "Maximum number of allowed domain aliases for a new administrator"
|
||||
msgstr ""
|
||||
"Número máximo permitido de aliases de domínio para um novo administrador"
|
||||
msgstr "Número máximo permitido de aliases de domínio para um novo administrador"
|
||||
|
||||
#: extensions/limits/app_settings.py:33
|
||||
msgid "Maximum number of allowed mailboxes for a new administrator"
|
||||
@@ -1903,8 +1789,7 @@ msgstr "Recursos insuficientes"
|
||||
|
||||
#: extensions/limits/models.py:15
|
||||
msgid "Maximum number of domain administrators this user can create"
|
||||
msgstr ""
|
||||
"Número máximo de administradores de domínio que este utilizador pode criar"
|
||||
msgstr "Número máximo de administradores de domínio que este utilizador pode criar"
|
||||
|
||||
#: extensions/limits/models.py:18
|
||||
msgid "Maximum number of domains this user can create"
|
||||
@@ -1920,8 +1805,7 @@ msgstr "Número máximo de caixas de correio que este utilizador por criar"
|
||||
|
||||
#: extensions/limits/models.py:26
|
||||
msgid "Maximum number of mailbox aliases this user can create"
|
||||
msgstr ""
|
||||
"Número máximo de aliases para caixas de correio que este utilizador por criar"
|
||||
msgstr "Número máximo de aliases para caixas de correio que este utilizador por criar"
|
||||
|
||||
#: extensions/limits/models.py:136
|
||||
msgid "undefined"
|
||||
@@ -1949,14 +1833,11 @@ msgstr "Tempo limite de resposta automática"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:16
|
||||
msgid "Timeout in seconds between two auto-replies to the same recipient"
|
||||
msgstr ""
|
||||
"Tempo limite em segundos entre duas respostas automáticas para o mesmo "
|
||||
"destinatário"
|
||||
msgstr "Tempo limite em segundos entre duas respostas automáticas para o mesmo destinatário"
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:20
|
||||
#, fuzzy
|
||||
msgid "Default subject"
|
||||
msgstr "Editor predefinido"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:21
|
||||
msgid "I'm off"
|
||||
@@ -1968,9 +1849,8 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:28
|
||||
#, fuzzy
|
||||
msgid "Default content"
|
||||
msgstr "Editor predefinido"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_autoreply/app_settings.py:30
|
||||
#, python-format
|
||||
@@ -1989,9 +1869,8 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_autoreply/forms.py:13
|
||||
#, fuzzy
|
||||
msgid "Activate your auto reply from this date"
|
||||
msgstr "Ativar o seu aviso de ausência até esta data"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_autoreply/forms.py:19
|
||||
msgid "Until"
|
||||
@@ -2007,9 +1886,8 @@ msgid "This date is over"
|
||||
msgstr "Esta data ultrapassa"
|
||||
|
||||
#: extensions/postfix_autoreply/forms.py:59
|
||||
#, fuzzy
|
||||
msgid "Must be greater than start date"
|
||||
msgstr "é maior do que"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_autoreply/general_callbacks.py:33
|
||||
#: extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html:2
|
||||
@@ -2059,138 +1937,113 @@ msgstr ""
|
||||
#: extensions/postfix_relay_domains/__init__.py:89
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:100
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:16
|
||||
#, fuzzy
|
||||
msgid "Relay domains"
|
||||
msgstr "Novo domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/app_settings.py:10
|
||||
msgid "Postfix's master.cf path"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/app_settings.py:12
|
||||
#, fuzzy
|
||||
msgid "Path to the master.cf configuration file"
|
||||
msgstr "Caminho para o ficheiro log"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/forms.py:15
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Alias(es) of this relay domain. Indicate only one name per input, press "
|
||||
"ENTER to add a new input."
|
||||
msgstr ""
|
||||
"Alias(es) deste domínio. Indicar apenas um nome por entrada, pressionar "
|
||||
"ENTER para acrescentar uma nova entrada."
|
||||
|
||||
#: extensions/postfix_relay_domains/forms.py:51
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:93
|
||||
#, fuzzy
|
||||
msgid "relay domain alias"
|
||||
msgstr "Aliases de domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/forms.py:69
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:92
|
||||
#, fuzzy
|
||||
msgid "relay domain"
|
||||
msgstr "Novo domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:35
|
||||
#, fuzzy
|
||||
msgid "Add relay domain"
|
||||
msgstr "Adicionar domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:101
|
||||
#, fuzzy
|
||||
msgid "Maximum number of relay domains this user can create"
|
||||
msgstr "Número máximo de domínios que este utilizador pode criar"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:103
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:24
|
||||
#, fuzzy
|
||||
msgid "Relay domain aliases"
|
||||
msgstr "Aliases de domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:104
|
||||
#, fuzzy
|
||||
msgid "Maximum number of relay domain aliases this user can create"
|
||||
msgstr "Número máximo de aliases de domínio que este utilizador pode criar"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/general_callbacks.py:111
|
||||
msgid ""
|
||||
"\n"
|
||||
"<li><em>relaydomain; name; target host; service; enabled; verify recipients</"
|
||||
"em></li>\n"
|
||||
"<li><em>relaydomain; name; target host; service; enabled; verify recipients</em></li>\n"
|
||||
"<li><em>relaydomainalias; name; target; enabled</em></li>\n"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:19
|
||||
#, fuzzy
|
||||
msgid "Maximum number of allowed relay domains for a new administrator"
|
||||
msgstr "Número máximo permitido de domínios para novo administrador"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/limits_callbacks.py:27
|
||||
#, fuzzy
|
||||
msgid "Maximum number of allowed relay domain aliases for a new administrator"
|
||||
msgstr ""
|
||||
"Número máximo permitido de aliases de domínio para um novo administrador"
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:59
|
||||
#, fuzzy
|
||||
msgid "The service name"
|
||||
msgstr "O nome do 'alias'"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:80
|
||||
#, fuzzy
|
||||
msgid "target host"
|
||||
msgstr "alvo"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:81
|
||||
#, fuzzy
|
||||
msgid "Remote destination of this domain"
|
||||
msgstr "Marcar para ativar este domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:89
|
||||
#, fuzzy
|
||||
msgid "verify recipients"
|
||||
msgstr "Destinatários"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:90
|
||||
msgid "Check for valid recipients"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:103
|
||||
#, fuzzy
|
||||
msgid "Relay Domain"
|
||||
msgstr "Novo domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:164
|
||||
#, fuzzy
|
||||
msgid "The relay domain this alias points to"
|
||||
msgstr "O domínio para o qual este alias irá apontar"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/models.py:195
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Relay domain %s does not exist"
|
||||
msgstr "O domínio '%s' não existe"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:26
|
||||
#, fuzzy
|
||||
msgid "Relay domain created"
|
||||
msgstr "Domínio criado"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:31
|
||||
#, fuzzy
|
||||
msgid "New relay domain"
|
||||
msgstr "Novo domínio"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:54
|
||||
#, fuzzy
|
||||
msgid "Relay domain modified"
|
||||
msgstr "Domínio alterado"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/views.py:77
|
||||
#, fuzzy
|
||||
msgid "Relay domain deleted"
|
||||
msgstr "Domínio criado"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/postfix_relay_domains/templates/postfix_relay_domains/service_field.html:2
|
||||
msgid "Scan"
|
||||
@@ -2387,8 +2240,7 @@ msgstr "ativo"
|
||||
#: extensions/sievefilters/templates/sievefilters/index.html:94
|
||||
msgid ""
|
||||
"No filters set defined yet. You must create one in order to define filters."
|
||||
msgstr ""
|
||||
"Não existem grupos de filtros. Terá de criar um para poder definir filtros."
|
||||
msgstr "Não existem grupos de filtros. Terá de criar um para poder definir filtros."
|
||||
|
||||
#: extensions/sievefilters/templatetags/sfilters_tags.py:15
|
||||
msgid "New filters set"
|
||||
@@ -2645,9 +2497,8 @@ msgid "Automatic folder refresh rate (in seconds)"
|
||||
msgstr "Taxa de actualização automática de pastas (em segundos)"
|
||||
|
||||
#: extensions/webmail/app_settings.py:103
|
||||
#, fuzzy
|
||||
msgid "Mailboxes container's width"
|
||||
msgstr "Detentor das Caixas de Correio (Owner)"
|
||||
msgstr ""
|
||||
|
||||
#: extensions/webmail/app_settings.py:104
|
||||
msgid "The width of the mailbox list container"
|
||||
@@ -2885,9 +2736,9 @@ msgid "Remove the selected mailbox"
|
||||
msgstr "Eliminar caixa de correio selecionada"
|
||||
|
||||
#: lib/dbutils.py:36
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Connection to database %s not configured"
|
||||
msgstr "Não foi possível estabelecer ligação com o amavis: %s"
|
||||
msgstr ""
|
||||
|
||||
#: lib/exceptions.py:67
|
||||
#, python-format
|
||||
@@ -2993,36 +2844,3 @@ msgstr "Lembrar-me"
|
||||
#: templates/registration/login.html:36
|
||||
msgid "Log in"
|
||||
msgstr "Entrar"
|
||||
|
||||
#~ msgid "An alias with this name already exists"
|
||||
#~ msgstr "Já existe um alias com este nome"
|
||||
|
||||
#~ msgid "A domain with this name already exists"
|
||||
#~ msgstr "Este nome de domínio já existe"
|
||||
|
||||
#~ msgid "Edit domain"
|
||||
#~ msgstr "Editar domínio"
|
||||
|
||||
#~ msgid "%d pending requests"
|
||||
#~ msgstr "%d pedidos pendentes"
|
||||
|
||||
#~ msgid "Content Class"
|
||||
#~ msgstr "Tipo de Conteúdo"
|
||||
|
||||
#~ msgid "Nothing"
|
||||
#~ msgstr "Nenhum"
|
||||
|
||||
#~ msgid "Bad request"
|
||||
#~ msgstr "Pedido inválido"
|
||||
|
||||
#~ msgid "Undefined action"
|
||||
#~ msgstr "Ação indefinida"
|
||||
|
||||
#~ msgid "User preferences"
|
||||
#~ msgstr "Preferências do utilizador"
|
||||
|
||||
#~ msgid "Per-user settings"
|
||||
#~ msgstr "Configurações por usuário"
|
||||
|
||||
#~ msgid "You need a mailbox in order to define a forward"
|
||||
#~ msgstr "Precisa de uma caixa de correio para definir um reencaminhamento"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
#
|
||||
# Translators:
|
||||
# lusitan <lusitan@hushmail.com>, 2013
|
||||
# mikec <miguelmclara@gmail.com>, 2012
|
||||
# Sandra Ribeiro <sandrarib@gmail.com>, 2013
|
||||
msgid ""
|
||||
@@ -10,14 +11,13 @@ msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-12-15 10:16+0100\n"
|
||||
"PO-Revision-Date: 2013-06-03 17:44+0000\n"
|
||||
"Last-Translator: Sandra Ribeiro <sandrarib@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/"
|
||||
"modoboa/language/pt_PT/)\n"
|
||||
"Language: pt_PT\n"
|
||||
"PO-Revision-Date: 2013-12-23 11:22+0000\n"
|
||||
"Last-Translator: lusitan <lusitan@hushmail.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/modoboa/language/pt_PT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_PT\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: extensions/admin/static/admin/js/admin.js:32
|
||||
@@ -36,9 +36,7 @@ msgstr "Esta operação irá remover TODOS os dados associados a este domínio."
|
||||
msgid ""
|
||||
"This operation will remove all data associated to this domain, excepting "
|
||||
"accounts."
|
||||
msgstr ""
|
||||
"Esta operação irá remover TODOS os dados associados a este domínio, excepto "
|
||||
"as contas."
|
||||
msgstr "Esta operação irá remover TODOS os dados associados a este domínio, excepto as contas."
|
||||
|
||||
#: extensions/admin/static/admin/js/admin.js:222
|
||||
msgid "No domain administrator defined"
|
||||
@@ -76,7 +74,7 @@ msgstr "Esconder cabeçalho completo"
|
||||
|
||||
#: extensions/postfix_relay_domains/static/postfix_relay_domains/js/relay_domains.js:49
|
||||
msgid "Services updated"
|
||||
msgstr ""
|
||||
msgstr "Atualizados os serviços"
|
||||
|
||||
#: extensions/sievefilters/static/sievefilters/js/lib.js:14
|
||||
msgid "Remove this filter?"
|
||||
@@ -138,28 +136,9 @@ msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: static/js/global.js:314
|
||||
#, fuzzy
|
||||
msgid "Internal error"
|
||||
msgstr "Erro Interno"
|
||||
msgstr "Erro interno"
|
||||
|
||||
#: static/js/searchbar.js:20
|
||||
msgid "Search..."
|
||||
msgstr "Pesquisar..."
|
||||
|
||||
#~ msgid "Message deleted"
|
||||
#~ msgstr "Mensagem apagada"
|
||||
|
||||
#~ msgid "Delete this domain?"
|
||||
#~ msgstr "Apagar este domínio?"
|
||||
|
||||
#~ msgid "Delete this account?"
|
||||
#~ msgstr "Apagar esta conta?"
|
||||
|
||||
#~ msgid "Delete this list?"
|
||||
#~ msgstr "Apagar esta lista?"
|
||||
|
||||
#~ msgid "Delete this forward?"
|
||||
#~ msgstr "Apagar este reencaminhamento?"
|
||||
|
||||
#~ msgid "Delete this alias?"
|
||||
#~ msgstr "Apagar este alias?"
|
||||
|
||||
@@ -49,6 +49,6 @@ pre {
|
||||
margin-left: 10px;
|
||||
margin-right: 20px;
|
||||
font-weight: bold;
|
||||
width: 6.38%;
|
||||
padding: 2px 0;
|
||||
width: 7.5%;
|
||||
padding: 0 0 2px 0;
|
||||
}
|
||||
Reference in New Issue
Block a user