From 17693dd95e5fdfcd1a52320a7259e87abee332de Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Tue, 21 Jun 2011 17:25:26 +0200 Subject: [PATCH] Added dates support for all objects by the admin application: * Creation date, * Last modification date updated on each call to save() fixed #144 --- admin/migrations/0010_fill_alias_domain.py | 1 - ...d_domain_dates__add_field_domainalias_d.py | 141 ++++++++++++++++++ admin/migrations/0012_fill_object_dates.py | 121 +++++++++++++++ admin/models.py | 47 +++++- templates/admin/domains.html | 16 +- templates/admin/domaliases.html | 10 +- templates/admin/mailboxes.html | 14 +- templates/admin/mbaliases.html | 12 +- 8 files changed, 339 insertions(+), 23 deletions(-) create mode 100644 admin/migrations/0011_auto__add_objectdates__add_field_domain_dates__add_field_domainalias_d.py create mode 100644 admin/migrations/0012_fill_object_dates.py diff --git a/admin/migrations/0010_fill_alias_domain.py b/admin/migrations/0010_fill_alias_domain.py index bad4d465d..24fe2505f 100644 --- a/admin/migrations/0010_fill_alias_domain.py +++ b/admin/migrations/0010_fill_alias_domain.py @@ -9,7 +9,6 @@ class Migration(DataMigration): def forwards(self, orm): "Write your forwards methods here." for alias in orm.Alias.objects.all(): - print alias.address alias.domain = alias.mboxes.all()[0].domain alias.save() diff --git a/admin/migrations/0011_auto__add_objectdates__add_field_domain_dates__add_field_domainalias_d.py b/admin/migrations/0011_auto__add_objectdates__add_field_domain_dates__add_field_domainalias_d.py new file mode 100644 index 000000000..3c03c24ad --- /dev/null +++ b/admin/migrations/0011_auto__add_objectdates__add_field_domain_dates__add_field_domainalias_d.py @@ -0,0 +1,141 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding model 'ObjectDates' + db.create_table('admin_objectdates', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('creation', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('last_modification', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + )) + db.send_create_signal('admin', ['ObjectDates']) + + # Adding field 'Domain.dates' + db.add_column('admin_domain', 'dates', self.gf('django.db.models.fields.related.ForeignKey')(default=-1, to=orm['admin.ObjectDates']), keep_default=False) + + # Adding field 'DomainAlias.dates' + db.add_column('admin_domainalias', 'dates', self.gf('django.db.models.fields.related.ForeignKey')(default=-1, to=orm['admin.ObjectDates']), keep_default=False) + + # Adding field 'Alias.dates' + db.add_column('admin_alias', 'dates', self.gf('django.db.models.fields.related.ForeignKey')(default=-1, to=orm['admin.ObjectDates']), keep_default=False) + + # Adding field 'Mailbox.dates' + db.add_column('admin_mailbox', 'dates', self.gf('django.db.models.fields.related.ForeignKey')(default=-1, to=orm['admin.ObjectDates']), keep_default=False) + + + def backwards(self, orm): + + # Deleting model 'ObjectDates' + db.delete_table('admin_objectdates') + + # Deleting field 'Domain.dates' + db.delete_column('admin_domain', 'dates_id') + + # Deleting field 'DomainAlias.dates' + db.delete_column('admin_domainalias', 'dates_id') + + # Deleting field 'Alias.dates' + db.delete_column('admin_alias', 'dates_id') + + # Deleting field 'Mailbox.dates' + db.delete_column('admin_mailbox', 'dates_id') + + + models = { + 'admin.alias': { + 'Meta': {'object_name': 'Alias'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '254'}), + 'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}), + 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'extmboxes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mboxes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['admin.Mailbox']", 'symmetrical': 'False'}) + }, + 'admin.domain': { + 'Meta': {'object_name': 'Domain'}, + 'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'quota': ('django.db.models.fields.IntegerField', [], {}) + }, + 'admin.domainalias': { + 'Meta': {'object_name': 'DomainAlias'}, + 'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}) + }, + 'admin.extension': { + 'Meta': {'object_name': 'Extension'}, + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'admin.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'dates': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.ObjectDates']"}), + 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}), + 'gid': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'quota': ('django.db.models.fields.IntegerField', [], {}), + 'uid': ('django.db.models.fields.IntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'admin.objectdates': { + 'Meta': {'object_name': 'ObjectDates'}, + 'creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modification': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['admin'] diff --git a/admin/migrations/0012_fill_object_dates.py b/admin/migrations/0012_fill_object_dates.py new file mode 100644 index 000000000..e86049e31 --- /dev/null +++ b/admin/migrations/0012_fill_object_dates.py @@ -0,0 +1,121 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +def create_od(orm, obj): + od = orm.ObjectDates() + od.save() + obj.dates = od + obj.save() + +class Migration(DataMigration): + + def forwards(self, orm): + "Write your forwards methods here." + for domain in orm.Domain.objects.all(): + create_od(orm, domain) + for domalias in orm.DomainAlias.objects.all(): + create_od(orm, domainalias) + for mbox in orm.Mailbox.objects.all(): + create_od(orm, mbox) + for mbalias in orm.Alias.objects.all(): + create_od(orm, mbalias) + + def backwards(self, orm): + "Write your backwards methods here." + orm.ObjectDates.objects.all().delete() + + models = { + 'admin.alias': { + 'Meta': {'object_name': 'Alias'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '254'}), + 'dates': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['admin.ObjectDates']", 'unique': 'True'}), + 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'extmboxes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mboxes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['admin.Mailbox']", 'symmetrical': 'False'}) + }, + 'admin.domain': { + 'Meta': {'object_name': 'Domain'}, + 'dates': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['admin.ObjectDates']", 'unique': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'quota': ('django.db.models.fields.IntegerField', [], {}) + }, + 'admin.domainalias': { + 'Meta': {'object_name': 'DomainAlias'}, + 'dates': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['admin.ObjectDates']", 'unique': 'True'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}) + }, + 'admin.extension': { + 'Meta': {'object_name': 'Extension'}, + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'admin.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'dates': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['admin.ObjectDates']", 'unique': 'True'}), + 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}), + 'gid': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'quota': ('django.db.models.fields.IntegerField', [], {}), + 'uid': ('django.db.models.fields.IntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'admin.objectdates': { + 'Meta': {'object_name': 'ObjectDates'}, + 'creation': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modification': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['admin'] diff --git a/admin/models.py b/admin/models.py index 4d59008e0..744eef5e0 100644 --- a/admin/models.py +++ b/admin/models.py @@ -24,7 +24,45 @@ class AdminError(Exception): """String representation""" return self.value -class Domain(models.Model): +class ObjectDates(models.Model): + """Dates recording for admin objects + + This table keeps creation and last modification dates for Domains, + domain aliases, mailboxes and aliases objects. + """ + creation = models.DateTimeField(auto_now_add=True) + last_modification = models.DateTimeField(auto_now=True) + + @staticmethod + def set_for_object(obj): + """Initialize or update dates for a given object. + + :param obj: an admin object (Domain, Mailbox, etc) + """ + try: + dates = getattr(obj, "dates") + except ObjectDates.DoesNotExist: + dates = ObjectDates() + dates.save() + obj.dates = dates + +class DatesAware(models.Model): + """Abstract model to support dates + + Inherit from this model to automatically add the "dates" feature + to another model. It defines the appropriate field and handles + saves. + """ + dates = models.ForeignKey(ObjectDates) + + class Meta: + abstract = True + + def save(self, *args, **kwargs): + ObjectDates.set_for_object(self) + super(DatesAware, self).save(*args, **kwargs) + +class Domain(DatesAware): name = models.CharField(_('name'), max_length=100, help_text=_("The domain name")) quota = models.IntegerField(help_text=_("Default quota in MB applied to mailboxes")) @@ -68,7 +106,7 @@ class Domain(models.Model): def __str__(self): return self.name -class DomainAlias(models.Model): +class DomainAlias(DatesAware): name = models.CharField(_("name"), max_length=100, unique=True, help_text=_("The alias name")) target = models.ForeignKey(Domain, verbose_name=_('target'), @@ -81,7 +119,7 @@ class DomainAlias(models.Model): ("view_domaliases", "View domain aliases"), ) -class Mailbox(models.Model): +class Mailbox(DatesAware): name = models.CharField(_('name'), max_length=100, help_text=_("First name and last name of mailbox owner")) address = models.CharField(_('address'), max_length=100, @@ -175,6 +213,7 @@ class Mailbox(models.Model): except IntegrityError: raise AdminError(_("Mailbox with this address already exists")) self.user = user + if kwargs.has_key("password") and kwargs["password"] != u"é": self.password = crypt_password(kwargs["password"]) self.uid = pwd.getpwnam(parameters.get_admin("VIRTUAL_UID")).pw_uid @@ -213,7 +252,7 @@ class Mailbox(models.Model): "enabled" : self.user.is_active } -class Alias(models.Model): +class Alias(DatesAware): address = models.CharField(_('address'), max_length=254, help_text=_("The alias address (without the domain part). For a 'catch-all' address, just enter an * character.")) domain = models.ForeignKey(Domain) diff --git a/templates/admin/domains.html b/templates/admin/domains.html index 92f87c618..6b1c29ef0 100644 --- a/templates/admin/domains.html +++ b/templates/admin/domains.html @@ -17,16 +17,20 @@ - - - - - - + + + + + + + + {% for dom in domains %} + + diff --git a/templates/admin/domaliases.html b/templates/admin/domaliases.html index 62c38741c..caa280c94 100644 --- a/templates/admin/domaliases.html +++ b/templates/admin/domaliases.html @@ -8,15 +8,19 @@ {% else %}
{% trans "Name" %}{% trans "Domain aliases" %}{% trans "Mailboxes" %}{% trans "Mailbox aliases" %}{% trans "Quota" %}{% trans "Enabled" %}{% trans "Actions" %}{% trans "Created" %}{% trans "Last modified" %}{% trans "Domain aliases" %}{% trans "Mailboxes" %}{% trans "Mailbox aliases" %}{% trans "Quota" %}{% trans "Enabled" %}{% trans "Actions" %}
{{ dom.name }}{{ dom.dates.creation }}{{ dom.dates.last_modification }} {{ dom.domainalias_set.all|length }} {{ dom.mailbox_set.all|length }} {{ dom.mbalias_counter }}
- + - - + + + + {% for domalias in domaliases %} + + diff --git a/templates/admin/mailboxes.html b/templates/admin/mailboxes.html index 3165a7496..f10912a4e 100644 --- a/templates/admin/mailboxes.html +++ b/templates/admin/mailboxes.html @@ -8,17 +8,21 @@ {% else %}
{% trans "Name" %}{% trans "Name" %} {% trans "Targeted domain" %}{% trans "Enabled" %}{% trans "Actions" %}{% trans "Created" %}{% trans "Last modified" %}{% trans "Enabled" %}{% trans "Actions" %}
{{ domalias.name }} {{ domalias.target.name }}{{ domalias.dates.creation }}{{ domalias.dates.last_modification }} {{ domalias.enabled|yesno }} {% domalias_actions user domalias.id %}
- - - - + + + + + + {% for mb in mailboxes %} - + + + diff --git a/templates/admin/mbaliases.html b/templates/admin/mbaliases.html index 94ea9407b..d9b3a3d57 100644 --- a/templates/admin/mbaliases.html +++ b/templates/admin/mbaliases.html @@ -8,10 +8,12 @@ {% else %}
{% trans "Name" %} {% trans "Address" %}{% trans "Defined aliases" %}{% trans "Quota" %}{{ "Enabled"|gender:"f" }}{% trans "Name" %}{% trans "Created" %}{% trans "Last modified" %}{% trans "Aliases" %}{% trans "Quota" %}{{ "Enabled"|gender:"f" }} {% trans "Actions" %}
{{ mb.name }} {{ mb.full_address }}{{ mb.name }}{{ mb.dates.creation }}{{ mb.dates.last_modification }} {{ mb.alias_set.all|length }} {{ mb.quota }} {% trans "MB" %} {{ mb.user.is_active|yesno:_("yes,no") }}
- - - - + + + + + + {% for alias in aliases %} + +
{% trans "Address" %}{% trans "Target(s)" %}{% trans "Enabled" %}{% trans "Actions" %}{% trans "Address" %}{% trans "Target(s)" %}{% trans "Created" %}{% trans "Last modified" %}{% trans "Enabled" %}{% trans "Actions" %}
{{ alias.dates.creation }}{{ alias.dates.last_modification }} {{ alias.enabled|yesno }} {% if alias.ui_disabled %}--{% else %}{% mbalias_actions user alias %}{% endif %}