PEP8 compliance and cleanup.

This commit is contained in:
Antoine Nguyen
2013-09-30 22:03:05 +02:00
parent bbddac3953
commit 8bc0bfcae2
6 changed files with 112 additions and 105 deletions
+22 -13
View File
@@ -2,18 +2,20 @@
import time
import re
import os
import time, random, hashlib
import time
import random
import hashlib
import lxml.html
from lxml import etree
from django.conf import settings
from django.template.loader import render_to_string
from django.template import Template, Context
from django.utils.translation import ugettext as _
from modoboa.lib.webutils import _render
from modoboa.lib.emailutils import decode
attached_map = {}
class MBconnector(object):
def __init__(self, address, port):
self.address = address
@@ -22,6 +24,7 @@ class MBconnector(object):
def messages_count(self, **kwargs):
pass
class Page(object):
def __init__(self, pageid, id_start, id_stop, items,
items_per_page, has_previous, has_next,
@@ -53,6 +56,7 @@ class Page(object):
lid += 1
return lid
class Paginator(object):
def __init__(self, total, elems_per_page):
self.total = total
@@ -65,7 +69,7 @@ class Paginator(object):
id_start = self.elems_per_page * page + 1
id_stop = id_start + self.elems_per_page - 1
return (id_start, id_stop)
def getpage(self, page):
if page < 1:
return None
@@ -85,6 +89,7 @@ class Paginator(object):
p.paginator = self
return p
class EmailListing(object):
def __init__(self, baseurl=None, folder=None, elems_per_page=40,
@@ -113,21 +118,25 @@ class EmailListing(object):
def render_navbar(page, baseurl=None):
if page is None:
return ""
context = {"page": page, "STATIC_URL": settings.STATIC_URL, "baseurl": baseurl}
context = {
"page": page, "STATIC_URL": settings.STATIC_URL, "baseurl": baseurl
}
return render_to_string("common/pagination_bar.html", context)
def fetch(self, request, id_start, id_stop):
table = self.tbltype(request,
self.mbc.fetch(start=id_start, stop=id_stop,
mbox=self.folder,
nbelems=self.elems_per_page))
table = self.tbltype(
request,
self.mbc.fetch(start=id_start, stop=id_stop,
mbox=self.folder,
nbelems=self.elems_per_page)
)
tpl = Template("""
<form method="POST" id="listingform">
{{ table }}
</form>""")
return tpl.render(
Context({
"table" : table.render(withheader=self.show_listing_headers)
"table": table.render(withheader=self.show_listing_headers)
})
)
@@ -139,10 +148,11 @@ class EmailListing(object):
listing = self.fetch(request, page.id_start, page.id_stop)
return dict(listing=listing, navbar=self.render_navbar(page, self.baseurl))
def parse_search_parameters(request):
if request.GET.has_key("pattern"):
if 'pattern' in request.GET:
request.session["pattern"] = re.escape(request.GET["pattern"])
if request.GET.has_key("criteria"):
if 'criteria' in request.GET:
request.session["criteria"] = request.GET["criteria"]
else:
request.session["criteria"] = ["from_addr"]
@@ -150,4 +160,3 @@ def parse_search_parameters(request):
for p in ["pattern", "criteria"]:
if p in request.session.keys():
del request.session[p]
+29 -15
View File
@@ -8,19 +8,20 @@ from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
class CreationWizard(object):
def __init__(self, done_cb):
self.steps = []
self.done_cb = done_cb
def add_step(self, cls, title, buttons, formtpl=None, new_args=None):
self.steps += [dict(cls=cls, title=title, buttons=buttons,
self.steps += [dict(cls=cls, title=title, buttons=buttons,
formtpl=formtpl, new_args=new_args)]
def create_forms(self, data=None):
for step in self.steps:
args = []
if step.has_key("new_args") and step["new_args"]:
if 'new_args' in step and step["new_args"]:
args += step["new_args"]
if data:
args.append(data)
@@ -46,6 +47,7 @@ class CreationWizard(object):
def get_title(self, stepid):
return "%d. %s" % (stepid + 1, self.steps[stepid]["title"])
class DynamicForm(object):
def _create_field(self, typ, name, value=None, pos=None):
@@ -66,12 +68,13 @@ class DynamicForm(object):
ndata = self.data.copy()
values.reverse()
for v in values:
if self.fields.has_key(v[0]):
if v[0] in self.fields:
continue
self._create_field(typ, v[0])
ndata[v[0]] = v[1]
self.data = ndata
class TabForms(object):
"""
Simple forms container
@@ -99,21 +102,21 @@ class TabForms(object):
fd["instance"] = classes[fd["id"]](*args, **kwargs)
else:
fd["instance"] = fd["cls"](*args, **kwargs)
map(lambda fd: self.forms.remove(fd), to_remove)
self.forms = [form for form in self.forms if not form in to_remove]
if self.forms:
self.active_id = self.forms[0]["id"]
def _before_is_valid(self, form):
return True
def is_valid(self, mandatory_only=False, optional_only=False):
to_remove = []
for f in self.forms:
if mandatory_only and \
(not f.has_key("mandatory") or not f["mandatory"]):
(not 'mandatory' in f or not f["mandatory"]):
continue
elif optional_only and \
(f.has_key("mandatory") and f["mandatory"]):
('mandatory' in f and f["mandatory"]):
continue
if not self._before_is_valid(f):
to_remove.append(f)
@@ -121,7 +124,7 @@ class TabForms(object):
if not f["instance"].is_valid():
self.active_id = f["id"]
return False
map(lambda fd: self.forms.remove(fd), to_remove)
self.forms = [f for f in self.forms if not f in to_remove]
return True
def save(self, *args, **kwargs):
@@ -132,7 +135,7 @@ class TabForms(object):
if f["id"] == tabid:
self.forms.remove(f)
break
def __iter__(self):
return self.forward()
@@ -144,6 +147,7 @@ class TabForms(object):
# Custom fields from here
#
def is_valid_host(host):
"""IDN compatible domain validator
"""
@@ -152,6 +156,7 @@ def is_valid_host(host):
is_valid_host._re = re.compile(r'^([0-9a-z][-\w]*[0-9a-z]\.)+[a-z0-9\-]{2,15}$')
return bool(is_valid_host._re.match(host))
def validate_domain_name(value):
if not is_valid_host(value):
raise ValidationError(_('Enter a valid domain name'), 'invalid')
@@ -162,8 +167,8 @@ class DomainNameField(CharField):
A subclass of CharField that only accepts a valid domain name.
"""
default_error_messages = {
'invalid' : _('Enter a valid domain name')
}
'invalid': _('Enter a valid domain name')
}
default_validators = [validate_domain_name]
@@ -179,16 +184,23 @@ class CustomRadioInput(RadioInput):
else:
label_for = ''
choice_label = conditional_escape(force_unicode(self.choice_label))
return mark_safe(u'<label class="radio inline" %s>%s %s</label>' % (label_for, self.tag(), choice_label))
return mark_safe(
u'<label class="radio inline" %s>%s %s</label>'
% (label_for, self.tag(), choice_label)
)
class InlineRadioRenderer(RadioSelect.renderer):
def __iter__(self):
for i, choice in enumerate(self.choices):
yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i)
yield CustomRadioInput(
self.name, self.value, self.attrs.copy(), choice, i
)
def render(self):
return mark_safe(u'\n'.join([u'%s\n' % force_unicode(w) for w in self]))
return mark_safe(
u'\n'.join([u'%s\n' % force_unicode(w) for w in self])
)
class InlineRadioSelect(RadioSelect):
@@ -203,6 +215,8 @@ class SeparatorField(Field):
class YesNoField(ChoiceField):
def __init__(self, *args, **kwargs):
kwargs["choices"] = [("yes", ugettext_lazy("Yes")), ("no", ugettext_lazy("No"))]
kwargs["choices"] = [
("yes", ugettext_lazy("Yes")), ("no", ugettext_lazy("No"))
]
kwargs["widget"] = InlineRadioSelect
super(YesNoField, self).__init__(*args, **kwargs)
+23 -11
View File
@@ -70,14 +70,14 @@ class GenericParametersForm(forms.Form):
class AdminParametersForm(GenericParametersForm):
def _load_initial_values(self):
from models import Parameter
from .models import Parameter
names = ["%s.%s" % (self.app, name.upper()) for name in self.fields.keys()]
for p in Parameter.objects.filter(name__in=names):
self.fields[p.shortname].initial = p.value
def save(self):
from models import Parameter
from .models import Parameter
from modoboa.lib.formutils import SeparatorField
for name, value in self.cleaned_data.items():
@@ -111,7 +111,7 @@ class UserParametersForm(GenericParametersForm):
def _load_initial_values(self):
if self.user is None:
return
from models import UserParameter
from .models import UserParameter
names = ["%s.%s" % (self.app, name.upper()) for name in self.fields.keys()]
for p in UserParameter.objects.filter(user=self.user, name__in=names):
@@ -122,7 +122,7 @@ class UserParametersForm(GenericParametersForm):
return True
def save(self):
from models import UserParameter
from .models import UserParameter
from modoboa.lib.formutils import SeparatorField
for name, value in self.cleaned_data.items():
@@ -141,7 +141,7 @@ class UserParametersForm(GenericParametersForm):
def register(formclass, label):
"""Register a form class containing parameters
formclass must inherit from ``AdminParametersForm`` of
formclass must inherit from ``AdminParametersForm`` or
``UserParametersForm``.
:param formclass: a form class
@@ -155,7 +155,9 @@ def register(formclass, label):
level = 'U'
else:
raise RuntimeError("Unknown parameter class")
_params[level][formclass.app] = {"label": label, "form": formclass, "defaults": {}}
_params[level][formclass.app] = {
"label": label, "form": formclass, "defaults": {}
}
form = formclass()
for name, field in form.fields.items():
if type(field) is SeparatorField:
@@ -198,7 +200,7 @@ def __guess_extension():
def save_admin(name, value, app=None):
from models import Parameter
from .models import Parameter
if app is None:
app = __guess_extension()
@@ -215,7 +217,7 @@ def save_admin(name, value, app=None):
def save_user(user, name, value, app=None):
from models import UserParameter
from .models import UserParameter
if app is None:
app = __guess_extension()
@@ -240,7 +242,7 @@ def get_admin(name, app=None, raise_error=True):
:param app: the application owning the parameter
:return: the corresponding value as a string
"""
from models import Parameter
from .models import Parameter
if app is None:
app = __guess_extension()
@@ -267,7 +269,7 @@ def get_user(user, name, app=None, raise_error=True):
:param app: the application owning the parameter
:return: the corresponding value as a string
"""
from models import UserParameter
from .models import UserParameter
if app is None:
app = __guess_extension()
@@ -284,7 +286,13 @@ def get_user(user, name, app=None, raise_error=True):
return p.value.decode("unicode_escape")
def get_sorted_apps(level, first="admin"):
def get_sorted_apps(level, first="core"):
"""Retrieve the sorted list of all registerd applications.
:param str level: application level
:param str first: force the first item of the result
:rtype: list
"""
sorted_apps = []
if first in _params[level]:
sorted_apps.append(first)
@@ -296,6 +304,10 @@ def get_sorted_apps(level, first="admin"):
def get_admin_forms(*args, **kwargs):
"""Get all admin level forms.
Generates an instance of each declared form.
"""
for app in get_sorted_apps('A'):
formdef = _params['A'][app]
yield {"label": formdef["label"],
+13 -18
View File
@@ -4,29 +4,24 @@
This module extra functions/shortcuts to communicate with the system
(executing commands, etc.)
"""
import logging
import logging.handlers
import subprocess
from modoboa.lib import parameters
def exec_cmd(cmd, sudo_user=None, **kwargs):
import subprocess
def exec_cmd(cmd, sudo_user=None, **kwargs):
"""Execute a shell command.
Run a command using the current user. Set :keyword:`sudo_user` if
you need different privileges.
:param str cmd: the command to execute
:param str sudo_user: a valid system username
:rtype: tuple
:return: return code, command output
"""
if sudo_user is not None:
cmd = "sudo -u %s %s" % (sudo_user, cmd)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, **kwargs)
output = p.communicate()[0]
return p.returncode, output
def __log(msg, facility=logging.handlers.SysLogHandler.LOG_AUTH):
logger = logging.getLogger('modoboa')
logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address='/dev/log', facility=facility)
formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def log_warning(msg):
logger = __log(msg)
logger.warning(msg)
+23 -35
View File
@@ -16,6 +16,7 @@ from django.template import Template, RequestContext, Context
from django.template.loader import render_to_string
from templatetags.libextras import render_link
class Column(object):
"""Simple column representation
"""
@@ -24,7 +25,7 @@ class Column(object):
self.sortable = True
for k, v in kwargs.iteritems():
setattr(self, k, v)
def __unicode__(self):
try:
label = getattr(self, "label")
@@ -51,6 +52,7 @@ class Column(object):
except AttributeError:
pass
class SelectionColumn(Column):
"""Specific column: selection
@@ -64,7 +66,7 @@ class SelectionColumn(Column):
def render(self, value, selection):
return "<input type='checkbox' id='%(id)s' name='select_%(value)s' value='%(value)s' %(checked)s/>" \
% {'id': self.name, 'value': value,
% {'id': self.name, 'value': value,
"checked": "checked=''" if selection else ""}
def transform(self, row, col, table):
@@ -72,9 +74,10 @@ class SelectionColumn(Column):
col["value"] = self.render(row[table.idkey], selection)
col["safe"] = True
class ImgColumn(Column):
"""Specific column: image
This kind of column only contains images tags (<img>).
"""
def __str__(self):
@@ -86,7 +89,7 @@ class ImgColumn(Column):
def render(self, value):
if type(value) in [list, tuple]:
return "".join(map(lambda i: "<img src='%s' />" % i, value))
return "".join(["<img src='%s' />" % i for i in value])
return "<img src='%s' />" % value
def transform(self, row, col, table):
@@ -100,6 +103,7 @@ class ImgColumn(Column):
pass
col["safe"] = True
class DivColumn(Column):
def __str__(self):
return ""
@@ -111,6 +115,7 @@ class DivColumn(Column):
col["value"] = self.render()
col["safe"] = True
class ActionColumn(Column):
def render(self, fct, user, rowid):
return fct(user, rowid)
@@ -119,10 +124,11 @@ class ActionColumn(Column):
col["value"] = self.render(self.defvalue, table.request.user, row[table.idkey])
col["safe"] = True
class LinkColumn(Column):
def render(self, rowid, value):
linkdef = dict(label=value, modal=self.modal)
if type(self.urlpattern) == dict:
if type(self.urlpattern) is dict:
t, value = rowid.split(":")
linkdef.update(url=reverse(self.urlpattern[t], args=[value]),
modalcb=self.modalcb[t])
@@ -135,12 +141,15 @@ class LinkColumn(Column):
col["value"] = self.render(row[table.idkey], row[self.name])
col["safe"] = True
class Table(object):
tableid = ""
def __init__(self, request, rows={}):
def __init__(self, request, rows=None):
self.columns = []
self.request = request
if rows is None:
rows = {}
try:
order = getattr(self, "cols_order")
except AttributeError:
@@ -168,13 +177,13 @@ class Table(object):
self.rows = []
trcpt = 0
for row in rows:
nrow = {"id" : row[self.idkey], "cols" : [], "trcpt" : trcpt}
nrow = {"id": row[self.idkey], "cols": [], "trcpt": trcpt}
for name in ["style", "options"]:
if row.has_key(name):
if name in row:
nrow[name] = row[name]
for c in self.columns:
newcol = {"name" : c.name}
newcol = {"name": c.name}
for key in ["width", "align", "cssclass"]:
try:
newcol[key] = getattr(c, key)
@@ -184,7 +193,7 @@ class Table(object):
nrow["cols"] += [newcol]
self.rows += [nrow]
trcpt += 1
def _rows_from_model(self, objects, include_type_in_id=False):
rows = []
for obj in objects:
@@ -232,32 +241,11 @@ class Table(object):
</table>
""")
return t.render(RequestContext(self.request, {
"table" : self, "tableid" : self.tableid, "styles" : styles,
"withheader" : withheader
}))
"table": self, "tableid": self.tableid, "styles": styles,
"withheader": withheader
}))
t = Template("""
<div class="alert alert-info">%s</div>
""" % _("No entries to display"))
return t.render(Context())
def render_head(self, request):
t = Template("""
<table id="{{ tableid }}">
{% include "common/table_head.html" %}
</table>
""")
return t.render(Context({
"table" : self, "tableid" : "%s_head" % self.tableid
}))
def render_body(self, request):
t = Template("""
<table id="{{ tableid }}">
{% include "common/table_body.html" %}
</table>
""")
return t.render(Context({
"table" : self, "tableid" : "%s_body" % self.tableid
}))
+2 -13
View File
@@ -15,23 +15,12 @@ from django.utils import simplejson
from django.conf import settings
def _render(request, tpl, user_context):
"""Custom rendering function
def _render_to_string(request, tpl, user_context):
"""Custom rendering function.
Just a wrapper which automatically adds a RequestContext instance
(useful to use settings variables like STATIC_URL inside templates)
"""
return render_to_response(
tpl, user_context,
context_instance=template.RequestContext(request)
)
def _render_to_string(request, tpl, user_context):
"""Custom rendering function
Same as _render.
"""
return render_to_string(tpl, user_context,
context_instance=template.RequestContext(request))