Added list accounts changelist actions and display HTML emails on mailer
This commit is contained in:
parent
708758880d
commit
7d1e4d1451
2
TODO.md
2
TODO.md
|
@ -427,3 +427,5 @@ Case
|
||||||
# bill changelist: dates: (closed_on, created_on, updated_on)
|
# bill changelist: dates: (closed_on, created_on, updated_on)
|
||||||
|
|
||||||
# Resource data inline show info: link to monitor data, and history chart: link to monitor data of each item
|
# Resource data inline show info: link to monitor data, and history chart: link to monitor data of each item
|
||||||
|
|
||||||
|
# DIsplay message email content nicelly
|
||||||
|
|
|
@ -18,7 +18,7 @@ from . import settings
|
||||||
|
|
||||||
|
|
||||||
def list_contacts(modeladmin, request, queryset):
|
def list_contacts(modeladmin, request, queryset):
|
||||||
ids = queryset.values_list('id', flat=True)
|
ids = queryset.order_by().values_list('id', flat=True).distinct()
|
||||||
if not ids:
|
if not ids:
|
||||||
messages.warning(request, "Select at least one account.")
|
messages.warning(request, "Select at least one account.")
|
||||||
return
|
return
|
||||||
|
@ -28,6 +28,17 @@ def list_contacts(modeladmin, request, queryset):
|
||||||
list_contacts.short_description = _("List contacts")
|
list_contacts.short_description = _("List contacts")
|
||||||
|
|
||||||
|
|
||||||
|
def list_accounts(modeladmin, request, queryset):
|
||||||
|
accounts = queryset.order_by().values_list('account_id', flat=True).distinct()
|
||||||
|
if not accounts:
|
||||||
|
messages.warning(request, "Select at least one instance.")
|
||||||
|
return
|
||||||
|
url = reverse('admin:contacts_contact_changelist')
|
||||||
|
url += '?id__in=%s' % ','.join(map(str, accounts))
|
||||||
|
return redirect(url)
|
||||||
|
list_accounts.short_description = _("List accounts")
|
||||||
|
|
||||||
|
|
||||||
def service_report(modeladmin, request, queryset):
|
def service_report(modeladmin, request, queryset):
|
||||||
# TODO resources
|
# TODO resources
|
||||||
accounts = []
|
accounts = []
|
||||||
|
|
|
@ -13,6 +13,7 @@ from django.shortcuts import redirect
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
from orchestra.admin.utils import admin_date, insertattr, admin_link
|
from orchestra.admin.utils import admin_date, insertattr, admin_link
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin, AccountAdmin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin, AccountAdmin
|
||||||
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
actions = [
|
actions = [
|
||||||
actions.manage_lines, actions.download_bills, actions.close_bills, actions.send_bills,
|
actions.manage_lines, actions.download_bills, actions.close_bills, actions.send_bills,
|
||||||
actions.amend_bills, actions.bill_report, actions.service_report,
|
actions.amend_bills, actions.bill_report, actions.service_report,
|
||||||
actions.close_send_download_bills,
|
actions.close_send_download_bills, list_accounts,
|
||||||
]
|
]
|
||||||
change_readonly_fields = ('account_link', 'type', 'is_open', 'amend_of_link', 'amend_links')
|
change_readonly_fields = ('account_link', 'type', 'is_open', 'amend_of_link', 'amend_links')
|
||||||
readonly_fields = ('number', 'display_total', 'is_sent', 'display_payment_state')
|
readonly_fields = ('number', 'display_total', 'is_sent', 'display_payment_state')
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from orchestra.admin import AtLeastOneRequiredInlineFormSet, ExtendedModelAdmin
|
from orchestra.admin import AtLeastOneRequiredInlineFormSet, ExtendedModelAdmin
|
||||||
from orchestra.admin.actions import SendEmail
|
from orchestra.admin.actions import SendEmail
|
||||||
from orchestra.admin.utils import insertattr, change_url
|
from orchestra.admin.utils import insertattr, change_url
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdmin, AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdmin, AccountAdminMixin
|
||||||
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ class ContactAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
'fields': ('address', ('zipcode', 'city'), 'country')
|
'fields': ('address', ('zipcode', 'city'), 'country')
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
actions = [SendEmail(),]
|
actions = (SendEmail(), list_accounts)
|
||||||
|
|
||||||
def dispaly_name(self, contact):
|
def dispaly_name(self, contact):
|
||||||
return str(contact)
|
return str(contact)
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||||
from orchestra.admin.utils import change_url
|
from orchestra.admin.utils import change_url
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||||
|
|
||||||
from .forms import DatabaseCreationForm, DatabaseUserChangeForm, DatabaseUserCreationForm
|
from .forms import DatabaseCreationForm, DatabaseUserChangeForm, DatabaseUserCreationForm
|
||||||
|
@ -42,6 +43,7 @@ class DatabaseAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||||
filter_horizontal = ['users']
|
filter_horizontal = ['users']
|
||||||
filter_by_account_fields = ('users',)
|
filter_by_account_fields = ('users',)
|
||||||
list_prefetch_related = ('users',)
|
list_prefetch_related = ('users',)
|
||||||
|
actions = (list_accounts,)
|
||||||
|
|
||||||
def display_users(self, db):
|
def display_users(self, db):
|
||||||
links = []
|
links = []
|
||||||
|
@ -90,6 +92,7 @@ class DatabaseUserAdmin(SelectAccountAdminMixin, ChangePasswordAdminMixin, Exten
|
||||||
readonly_fields = ('account_link', 'display_databases',)
|
readonly_fields = ('account_link', 'display_databases',)
|
||||||
filter_by_account_fields = ('databases',)
|
filter_by_account_fields = ('databases',)
|
||||||
list_prefetch_related = ('databases',)
|
list_prefetch_related = ('databases',)
|
||||||
|
actions = (list_accounts,)
|
||||||
|
|
||||||
def display_databases(self, user):
|
def display_databases(self, user):
|
||||||
links = []
|
links = []
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
from orchestra.admin.utils import admin_link, change_url
|
from orchestra.admin.utils import admin_link, change_url
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
from orchestra.utils import apps
|
from orchestra.utils import apps
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
change_readonly_fields = ('name', 'serial')
|
change_readonly_fields = ('name', 'serial')
|
||||||
search_fields = ('name', 'account__username')
|
search_fields = ('name', 'account__username')
|
||||||
add_form = BatchDomainCreationAdminForm
|
add_form = BatchDomainCreationAdminForm
|
||||||
actions = (edit_records, set_soa)
|
actions = (edit_records, set_soa, list_accounts)
|
||||||
change_view_actions = (view_zone, edit_records)
|
change_view_actions = (view_zone, edit_records)
|
||||||
|
|
||||||
top_link = admin_link('top')
|
top_link = admin_link('top')
|
||||||
|
|
|
@ -80,15 +80,15 @@ class ValidateZoneMixin(object):
|
||||||
def clean(self):
|
def clean(self):
|
||||||
""" Checks if everything is consistent """
|
""" Checks if everything is consistent """
|
||||||
super(ValidateZoneMixin, self).clean()
|
super(ValidateZoneMixin, self).clean()
|
||||||
if any(formset.errors):
|
if any(self.errors):
|
||||||
return
|
return
|
||||||
if formset.instance.name:
|
if self.instance.name:
|
||||||
records = []
|
records = []
|
||||||
for form in formset.forms:
|
for form in self.forms:
|
||||||
data = form.cleaned_data
|
data = form.cleaned_data
|
||||||
if data and not data['DELETE']:
|
if data and not data['DELETE']:
|
||||||
records.append(data)
|
records.append(data)
|
||||||
domain = domain_for_validation(formset.instance, records)
|
domain = domain_for_validation(self.instance, records)
|
||||||
validators.validate_zone(domain.render_zone())
|
validators.validate_zone(domain.render_zone())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -273,14 +273,14 @@ class Record(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
VALIDATORS = {
|
VALIDATORS = {
|
||||||
MX: validators.validate_mx_record,
|
MX: (validators.validate_mx_record,),
|
||||||
NS: validators.validate_zone_label,
|
NS: (validators.validate_zone_label,),
|
||||||
A: validate_ipv4_address,
|
A: (validate_ipv4_address,),
|
||||||
AAAA: validate_ipv6_address,
|
AAAA: (validate_ipv6_address,),
|
||||||
CNAME: validators.validate_zone_label,
|
CNAME: (validators.validate_zone_label,),
|
||||||
TXT: validate_ascii,
|
TXT: (validate_ascii, validators.validate_quoted_record),
|
||||||
SRV: validators.validate_srv_record,
|
SRV: (validators.validate_srv_record,),
|
||||||
SOA: validators.validate_soa_record,
|
SOA: (validators.validate_soa_record,),
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = models.ForeignKey(Domain, verbose_name=_("domain"), related_name='records')
|
domain = models.ForeignKey(Domain, verbose_name=_("domain"), related_name='records')
|
||||||
|
@ -300,12 +300,13 @@ class Record(models.Model):
|
||||||
if self.type != self.TXT:
|
if self.type != self.TXT:
|
||||||
self.value = self.value.lower().strip()
|
self.value = self.value.lower().strip()
|
||||||
if self.type:
|
if self.type:
|
||||||
try:
|
for validator in self.VALIDATORS.get(self.type, []):
|
||||||
self.VALIDATORS[self.type](self.value)
|
try:
|
||||||
except ValidationError as error:
|
validator(self.value)
|
||||||
raise ValidationError({
|
except ValidationError as error:
|
||||||
'value': error,
|
raise ValidationError({
|
||||||
})
|
'value': error,
|
||||||
|
})
|
||||||
|
|
||||||
def get_ttl(self):
|
def get_ttl(self):
|
||||||
return self.ttl or settings.DOMAINS_DEFAULT_TTL
|
return self.ttl or settings.DOMAINS_DEFAULT_TTL
|
||||||
|
|
|
@ -107,6 +107,16 @@ def validate_soa_record(value):
|
||||||
raise ValidationError(msg)
|
raise ValidationError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_quoted_record(value):
|
||||||
|
value = value.strip()
|
||||||
|
if ' ' in value and (value[0] != '"' or value[-1] != '"'):
|
||||||
|
raise ValidationError(
|
||||||
|
_("This record value contains spaces, you must enclose the string in double quotes; "
|
||||||
|
"otherwise, individual words will be separately quoted and break up the record "
|
||||||
|
"into multiple parts.")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_zone(zone):
|
def validate_zone(zone):
|
||||||
""" Ultimate zone file validation using named-checkzone """
|
""" Ultimate zone file validation using named-checkzone """
|
||||||
zone_name = zone.split()[0][:-1]
|
zone_name = zone.split()[0][:-1]
|
||||||
|
|
|
@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||||
from orchestra.admin.actions import disable
|
from orchestra.admin.actions import disable
|
||||||
from orchestra.admin.utils import admin_link
|
from orchestra.admin.utils import admin_link
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||||
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ class ListAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedModel
|
||||||
add_form = ListCreationForm
|
add_form = ListCreationForm
|
||||||
list_select_related = ('account', 'address_domain',)
|
list_select_related = ('account', 'address_domain',)
|
||||||
filter_by_account_fields = ['address_domain']
|
filter_by_account_fields = ['address_domain']
|
||||||
actions = (disable,)
|
actions = (disable, list_accounts)
|
||||||
|
|
||||||
address_domain_link = admin_link('address_domain', order='address_domain__name')
|
address_domain_link = admin_link('address_domain', order='address_domain__name')
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||||
from orchestra.admin.actions import disable
|
from orchestra.admin.actions import disable
|
||||||
from orchestra.admin.utils import admin_link, change_url
|
from orchestra.admin.utils import admin_link, change_url
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||||
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
|
||||||
add_form = MailboxCreationForm
|
add_form = MailboxCreationForm
|
||||||
form = MailboxChangeForm
|
form = MailboxChangeForm
|
||||||
list_prefetch_related = ('addresses__domain',)
|
list_prefetch_related = ('addresses__domain',)
|
||||||
actions = (disable,)
|
actions = (disable, list_accounts)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(MailboxAdmin, self).__init__(*args, **kwargs)
|
super(MailboxAdmin, self).__init__(*args, **kwargs)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import base64
|
||||||
|
import email
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
@ -29,6 +32,21 @@ class MessageAdmin(admin.ModelAdmin):
|
||||||
)
|
)
|
||||||
list_filter = ('state', 'priority', 'retries')
|
list_filter = ('state', 'priority', 'retries')
|
||||||
list_prefetch_related = ('logs__id')
|
list_prefetch_related = ('logs__id')
|
||||||
|
fieldsets = (
|
||||||
|
(None, {
|
||||||
|
'fields': ('state', 'priority', ('retries', 'last_retry_delta'),
|
||||||
|
'display_full_subject', 'display_to_address', 'display_from_address',
|
||||||
|
'display_content'),
|
||||||
|
}),
|
||||||
|
(_("Edit"), {
|
||||||
|
'classes': ('collapse',),
|
||||||
|
'fields': ('subject', 'to_address', 'from_address', 'content'),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
readonly_fields = (
|
||||||
|
'retries', 'last_retry_delta', 'display_full_subject', 'display_to_address',
|
||||||
|
'display_from_address', 'display_content',
|
||||||
|
)
|
||||||
|
|
||||||
colored_state = admin_colored('state', colors=COLORS)
|
colored_state = admin_colored('state', colors=COLORS)
|
||||||
created_at_delta = admin_date('created_at')
|
created_at_delta = admin_date('created_at')
|
||||||
|
@ -52,6 +70,37 @@ class MessageAdmin(admin.ModelAdmin):
|
||||||
num_logs.admin_order_field = 'logs__count'
|
num_logs.admin_order_field = 'logs__count'
|
||||||
num_logs.allow_tags = True
|
num_logs.allow_tags = True
|
||||||
|
|
||||||
|
def display_content(self, instance):
|
||||||
|
part = email.message_from_string(instance.content)
|
||||||
|
payload = part.get_payload()
|
||||||
|
if isinstance(payload, list):
|
||||||
|
for part in payload:
|
||||||
|
payload = part.get_payload()
|
||||||
|
if part.get_content_type() == 'text/html':
|
||||||
|
# prioritize HTML
|
||||||
|
payload = '<div style="padding-left:110px">%s</div>' % payload
|
||||||
|
break
|
||||||
|
if part.get('Content-Transfer-Encoding') == 'base64':
|
||||||
|
payload = base64.b64decode(payload)
|
||||||
|
payload = payload.decode(part.get_charsets()[0])
|
||||||
|
if part.get_content_type() == 'text/plain':
|
||||||
|
payload = payload.replace('\n', '<br>')
|
||||||
|
return payload
|
||||||
|
display_content.short_description = _("Content")
|
||||||
|
display_content.allow_tags = True
|
||||||
|
|
||||||
|
def display_full_subject(self, instance):
|
||||||
|
return instance.subject
|
||||||
|
display_full_subject.short_description = _("Subject")
|
||||||
|
|
||||||
|
def display_from_address(self, instance):
|
||||||
|
return instance.from_address
|
||||||
|
display_from_address.short_description = _("From address")
|
||||||
|
|
||||||
|
def display_to_address(self, instance):
|
||||||
|
return instance.to_address
|
||||||
|
display_to_address.short_description = _("To address")
|
||||||
|
|
||||||
def get_urls(self):
|
def get_urls(self):
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
urls = super(MessageAdmin, self).get_urls()
|
urls = super(MessageAdmin, self).get_urls()
|
||||||
|
@ -77,6 +126,7 @@ class MessageAdmin(admin.ModelAdmin):
|
||||||
kwargs['widget'] = forms.TextInput(attrs={'size':'100'})
|
kwargs['widget'] = forms.TextInput(attrs={'size':'100'})
|
||||||
return super(MessageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
return super(MessageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class SMTPLogAdmin(admin.ModelAdmin):
|
class SMTPLogAdmin(admin.ModelAdmin):
|
||||||
list_display = (
|
list_display = (
|
||||||
'id', 'message_link', 'colored_result', 'date_delta', 'log_message'
|
'id', 'message_link', 'colored_result', 'date_delta', 'log_message'
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
from orchestra.admin.utils import admin_link, admin_date, change_url
|
from orchestra.admin.utils import admin_link, admin_date, change_url
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
from orchestra.utils.humanize import naturaldate
|
from orchestra.utils.humanize import naturaldate
|
||||||
|
|
||||||
|
@ -49,13 +50,18 @@ class MetricStorageInline(admin.TabularInline):
|
||||||
class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
list_display = (
|
list_display = (
|
||||||
'id', 'service_link', 'account_link', 'content_object_link',
|
'id', 'service_link', 'account_link', 'content_object_link',
|
||||||
'display_registered_on', 'display_billed_until', 'display_cancelled_on', 'display_metric'
|
'display_registered_on', 'display_billed_until', 'display_cancelled_on',
|
||||||
|
'display_metric'
|
||||||
|
)
|
||||||
|
list_filter = (
|
||||||
|
ActiveOrderListFilter, IgnoreOrderListFilter, BilledOrderListFilter, 'service'
|
||||||
)
|
)
|
||||||
list_filter = (ActiveOrderListFilter, IgnoreOrderListFilter, BilledOrderListFilter, 'service')
|
|
||||||
default_changelist_filters = (
|
default_changelist_filters = (
|
||||||
('ignore', '0'),
|
('ignore', '0'),
|
||||||
)
|
)
|
||||||
actions = (BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored, report)
|
actions = (
|
||||||
|
BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored, report, list_accounts
|
||||||
|
)
|
||||||
change_view_actions = (BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored)
|
change_view_actions = (BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored)
|
||||||
date_hierarchy = 'registered_on'
|
date_hierarchy = 'registered_on'
|
||||||
inlines = (MetricStorageInline,)
|
inlines = (MetricStorageInline,)
|
||||||
|
@ -111,7 +117,9 @@ class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
display_billed_until.admin_order_field = 'billed_until'
|
display_billed_until.admin_order_field = 'billed_until'
|
||||||
|
|
||||||
def display_metric(self, order):
|
def display_metric(self, order):
|
||||||
""" dispalys latest metric value, don't uses latest() because not loosing prefetch_related """
|
"""
|
||||||
|
dispalys latest metric value, don't uses latest() because not loosing prefetch_related
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
metric = order.metrics.all()[0]
|
metric = order.metrics.all()[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ChangeViewActionsMixin, ExtendedModelAdmin
|
from orchestra.admin import ChangeViewActionsMixin, ExtendedModelAdmin
|
||||||
from orchestra.admin.utils import admin_colored, admin_link
|
from orchestra.admin.utils import admin_colored, admin_link
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
||||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ class TransactionAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||||
actions.process_transactions, actions.mark_as_executed, actions.mark_as_secured,
|
actions.process_transactions, actions.mark_as_executed, actions.mark_as_secured,
|
||||||
actions.mark_as_rejected,
|
actions.mark_as_rejected,
|
||||||
)
|
)
|
||||||
actions = change_view_actions + (actions.report,)
|
actions = change_view_actions + (actions.report, list_accounts)
|
||||||
filter_by_account_fields = ('bill', 'source')
|
filter_by_account_fields = ('bill', 'source')
|
||||||
change_readonly_fields = ('amount', 'currency')
|
change_readonly_fields = ('amount', 'currency')
|
||||||
readonly_fields = (
|
readonly_fields = (
|
||||||
|
|
|
@ -2,6 +2,7 @@ from django.contrib import admin
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
from orchestra.admin.utils import insertattr
|
from orchestra.admin.utils import insertattr
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
from orchestra.contrib.services.models import Service
|
from orchestra.contrib.services.models import Service
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ class ContractedPlanAdmin(AccountAdminMixin, admin.ModelAdmin):
|
||||||
list_filter = ('plan__name',)
|
list_filter = ('plan__name',)
|
||||||
list_select_related = ('plan', 'account')
|
list_select_related = ('plan', 'account')
|
||||||
search_fields = ('account__username', 'plan__name', 'id')
|
search_fields = ('account__username', 'plan__name', 'id')
|
||||||
|
actions = (list_accounts,)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Plan, PlanAdmin)
|
admin.site.register(Plan, PlanAdmin)
|
||||||
|
|
|
@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||||
from orchestra.admin.actions import disable
|
from orchestra.admin.actions import disable
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ class SaaSAdmin(SelectPluginAdminMixin, ChangePasswordAdminMixin, AccountAdminMi
|
||||||
plugin = SoftwareService
|
plugin = SoftwareService
|
||||||
plugin_field = 'service'
|
plugin_field = 'service'
|
||||||
plugin_title = 'Software as a Service'
|
plugin_title = 'Software as a Service'
|
||||||
actions = (disable,)
|
actions = (disable, list_accounts)
|
||||||
|
|
||||||
def display_site_domain(self, saas):
|
def display_site_domain(self, saas):
|
||||||
site_domain = saas.get_site_domain()
|
site_domain = saas.get_site_domain()
|
||||||
|
|
|
@ -14,7 +14,8 @@ from .. import settings
|
||||||
class PhpListSaaSBackend(ServiceController):
|
class PhpListSaaSBackend(ServiceController):
|
||||||
"""
|
"""
|
||||||
Creates a new phplist instance on a phpList multisite installation.
|
Creates a new phplist instance on a phpList multisite installation.
|
||||||
The site is created by means of creating a new database per phpList site, but all sites share the same code.
|
The site is created by means of creating a new database per phpList site,
|
||||||
|
but all sites share the same code.
|
||||||
|
|
||||||
<tt>// config/config.php
|
<tt>// config/config.php
|
||||||
$site = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
|
$site = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
|
||||||
|
@ -28,7 +29,8 @@ class PhpListSaaSBackend(ServiceController):
|
||||||
def _save(self, saas, server):
|
def _save(self, saas, server):
|
||||||
admin_link = 'https://%s/admin/' % saas.get_site_domain()
|
admin_link = 'https://%s/admin/' % saas.get_site_domain()
|
||||||
print('admin_link:', admin_link)
|
print('admin_link:', admin_link)
|
||||||
admin_content = requests.get(admin_link, verify=settings.SAAS_PHPLIST_VERIFY_SSL).content.decode('utf8')
|
admin_content = requests.get(admin_link, verify=settings.SAAS_PHPLIST_VERIFY_SSL)
|
||||||
|
admin_content = admin_content.content.decode('utf8')
|
||||||
if admin_content.startswith('Cannot connect to Database'):
|
if admin_content.startswith('Cannot connect to Database'):
|
||||||
raise RuntimeError("Database is not yet configured")
|
raise RuntimeError("Database is not yet configured")
|
||||||
install = re.search(r'([^"]+firstinstall[^"]+)', admin_content)
|
install = re.search(r'([^"]+firstinstall[^"]+)', admin_content)
|
||||||
|
@ -68,7 +70,7 @@ class PhpListSaaSBackend(ServiceController):
|
||||||
--execute='UPDATE phplist_admin SET password="%(digest)s" where ID=1; \\
|
--execute='UPDATE phplist_admin SET password="%(digest)s" where ID=1; \\
|
||||||
UPDATE phplist_user_user SET password="%(digest)s" where ID=1;' \\
|
UPDATE phplist_user_user SET password="%(digest)s" where ID=1;' \\
|
||||||
%(db_name)s""") % context
|
%(db_name)s""") % context
|
||||||
print(cmd)
|
print('cmd:', cmd)
|
||||||
sshrun(server.get_address(), cmd)
|
sshrun(server.get_address(), cmd)
|
||||||
|
|
||||||
def save(self, saas):
|
def save(self, saas):
|
||||||
|
|
|
@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||||
from orchestra.admin.actions import disable
|
from orchestra.admin.actions import disable
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||||
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende
|
||||||
form = SystemUserChangeForm
|
form = SystemUserChangeForm
|
||||||
ordering = ('-id',)
|
ordering = ('-id',)
|
||||||
change_view_actions = (set_permission, disable)
|
change_view_actions = (set_permission, disable)
|
||||||
actions = (delete_selected,) + change_view_actions
|
actions = (delete_selected, list_accounts) + change_view_actions
|
||||||
|
|
||||||
def display_main(self, user):
|
def display_main(self, user):
|
||||||
return user.is_main
|
return user.is_main
|
||||||
|
|
|
@ -4,6 +4,7 @@ from django.contrib.auth.admin import UserAdmin
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
|
|
||||||
from .forms import VPSChangeForm, VPSCreationForm
|
from .forms import VPSChangeForm, VPSCreationForm
|
||||||
|
@ -37,6 +38,7 @@ class VPSAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
'fields': ('password1', 'password2',)
|
'fields': ('password1', 'password2',)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
actions = (list_accounts,)
|
||||||
|
|
||||||
def get_urls(self):
|
def get_urls(self):
|
||||||
useradmin = UserAdmin(VPS, self.admin_site)
|
useradmin = UserAdmin(VPS, self.admin_site)
|
||||||
|
|
|
@ -6,6 +6,7 @@ from django.utils.translation import ugettext, ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
from orchestra.admin.utils import change_url, get_modeladmin
|
from orchestra.admin.utils import change_url, get_modeladmin
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
from orchestra.forms.widgets import DynamicHelpTextSelect
|
from orchestra.forms.widgets import DynamicHelpTextSelect
|
||||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||||
|
@ -58,6 +59,7 @@ class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin)
|
||||||
plugin = AppType
|
plugin = AppType
|
||||||
plugin_field = 'type'
|
plugin_field = 'type'
|
||||||
plugin_title = _("Web application type")
|
plugin_title = _("Web application type")
|
||||||
|
actions = (list_accounts,)
|
||||||
|
|
||||||
def display_websites(self, webapp):
|
def display_websites(self, webapp):
|
||||||
websites = []
|
websites = []
|
||||||
|
|
|
@ -5,10 +5,10 @@ from django.db.models import Q
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
from orchestra.admin import ExtendedModelAdmin
|
from orchestra.admin import ExtendedModelAdmin
|
||||||
from orchestra.admin.actions import disable
|
from orchestra.admin.actions import disable
|
||||||
from orchestra.admin.utils import admin_link, change_url
|
from orchestra.admin.utils import admin_link, change_url
|
||||||
|
from orchestra.contrib.accounts.actions import list_accounts
|
||||||
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
||||||
from orchestra.forms.widgets import DynamicHelpTextSelect
|
from orchestra.forms.widgets import DynamicHelpTextSelect
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
||||||
filter_by_account_fields = ['domains']
|
filter_by_account_fields = ['domains']
|
||||||
list_prefetch_related = ('domains', 'content_set__webapp')
|
list_prefetch_related = ('domains', 'content_set__webapp')
|
||||||
search_fields = ('name', 'account__username', 'domains__name', 'content__webapp__name')
|
search_fields = ('name', 'account__username', 'domains__name', 'content__webapp__name')
|
||||||
actions = (disable,)
|
actions = (disable, list_accounts)
|
||||||
|
|
||||||
def display_domains(self, website):
|
def display_domains(self, website):
|
||||||
domains = []
|
domains = []
|
||||||
|
|
Loading…
Reference in New Issue