PEP8 cleanups.

This commit is contained in:
Roberto Rosario
2015-08-19 14:50:44 -04:00
parent 683e54fea1
commit 68f3c6eee7
49 changed files with 1078 additions and 216 deletions

View File

@@ -10,7 +10,9 @@ from .permissions import permission_acl_view, permission_acl_edit
def get_kwargs_factory(variable_name):
def get_kwargs(context):
content_type = ContentType.objects.get_for_model(context[variable_name])
content_type = ContentType.objects.get_for_model(
context[variable_name]
)
return {
'app_label': '"{}"'.format(content_type.app_label),
'model': '"{}"'.format(content_type.model),

View File

@@ -2,7 +2,9 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url
from .views import ACLCreateView, ACLDeleteView, ACLListView, ACLPermissionsView
from .views import (
ACLCreateView, ACLDeleteView, ACLListView, ACLPermissionsView
)
urlpatterns = patterns(
'acls.views',

View File

@@ -11,6 +11,7 @@ from ..settings import setting_login_method
TEST_ADMIN_EMAIL = 'admin@admin.com'
TEST_ADMIN_PASSWORD = 'test_admin_password'
TEST_ADMIN_USERNAME = 'test_admin'
TEST_EMAIL_AUTHENTICATION_BACKEND = 'authentication.auth.email_auth_backend.EmailAuthBackend'
class UserLoginTestCase(TestCase):
@@ -43,7 +44,7 @@ class UserLoginTestCase(TestCase):
self.assertEqual(response.status_code, 200)
def test_email_login(self):
with self.settings(AUTHENTICATION_BACKENDS=('authentication.auth.email_auth_backend.EmailAuthBackend',)):
with self.settings(AUTHENTICATION_BACKENDS=(TEST_EMAIL_AUTHENTICATION_BACKEND,)):
setting_login_method.value = 'email'
logged_in = self.client.login(
@@ -78,7 +79,7 @@ class UserLoginTestCase(TestCase):
self.assertEqual(response.status_code, 200)
def test_email_login_via_views(self):
with self.settings(AUTHENTICATION_BACKENDS=('authentication.auth.email_auth_backend.EmailAuthBackend',)):
with self.settings(AUTHENTICATION_BACKENDS=(TEST_EMAIL_AUTHENTICATION_BACKEND,)):
setting_login_method.value = 'email'
response = self.client.get(reverse('documents:document_list'))
self.assertRedirects(

View File

@@ -118,7 +118,9 @@ class APICheckedoutDocumentView(generics.RetrieveDestroyAPIView):
filtered_documents = documents
return DocumentCheckout.objects.filter(
document__pk__in=filtered_documents.values_list('pk', flat=True)
document__pk__in=filtered_documents.values_list(
'pk', flat=True
)
)
elif self.request.method == 'DELETE':
return DocumentCheckout.objects.all()
@@ -155,7 +157,10 @@ class APICheckedoutDocumentView(generics.RetrieveDestroyAPIView):
)
except PermissionDenied:
AccessControlList.objects.check_access(
permission_document_checkin_override, request.user, document
permission_document_checkin_override, request.user,
document
)
return super(APICheckedoutDocumentView, self).delete(request, *args, **kwargs)
return super(
APICheckedoutDocumentView, self
).delete(request, *args, **kwargs)

View File

@@ -10,6 +10,7 @@ def check_if_new_versions_allowed(sender, **kwargs):
if not DocumentCheckout.objects.are_document_new_versions_allowed(kwargs['instance'].document):
raise NewDocumentVersionNotAllowed(
_(
'New versions not allowed for the checkedout document: %s' % kwargs['instance'].document
'New versions not allowed for the checkedout document: %s'
% kwargs['instance'].document
)
)

View File

@@ -15,13 +15,53 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DocumentCheckout',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('checkout_datetime', models.DateTimeField(auto_now_add=True, verbose_name='Check out date and time')),
('expiration_datetime', models.DateTimeField(help_text='Amount of time to hold the document checked out in minutes.', verbose_name='Check out expiration date and time')),
('user_object_id', models.PositiveIntegerField(null=True, blank=True)),
('block_new_version', models.BooleanField(default=True, help_text='Do not allow new version of this document to be uploaded.', verbose_name='Block new version upload')),
('document', models.ForeignKey(verbose_name='Document', to='documents.Document', unique=True)),
('user_content_type', models.ForeignKey(blank=True, to='contenttypes.ContentType', null=True)),
(
'id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True
)
),
(
'checkout_datetime',
models.DateTimeField(
auto_now_add=True,
verbose_name='Check out date and time'
)
),
(
'expiration_datetime',
models.DateTimeField(
help_text='Amount of time to hold the document '
'checked out in minutes.',
verbose_name='Check out expiration date and time'
)
),
(
'user_object_id',
models.PositiveIntegerField(null=True, blank=True)
),
(
'block_new_version',
models.BooleanField(
default=True,
help_text='Do not allow new version of this document '
'to be uploaded.',
verbose_name='Block new version upload'
)
),
(
'document',
models.ForeignKey(
verbose_name='Document', to='documents.Document',
unique=True
)
),
(
'user_content_type',
models.ForeignKey(
blank=True, to='contenttypes.ContentType', null=True
)
),
],
options={
'verbose_name': 'Document checkout',

View File

@@ -16,7 +16,10 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='documentcheckout',
name='user',
field=models.ForeignKey(verbose_name='User', blank=True, to=settings.AUTH_USER_MODEL, null=True),
field=models.ForeignKey(
verbose_name='User', blank=True, to=settings.AUTH_USER_MODEL,
null=True
),
preserve_default=True,
),
]

View File

@@ -23,5 +23,7 @@ class Migration(migrations.Migration):
]
operations = [
migrations.RunPython(move_from_content_type_user_to_foreign_key_field_user),
migrations.RunPython(
move_from_content_type_user_to_foreign_key_field_user
),
]

View File

@@ -23,7 +23,9 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='documentcheckout',
name='user',
field=models.ForeignKey(verbose_name='User', to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
verbose_name='User', to=settings.AUTH_USER_MODEL
),
preserve_default=True,
),
]

View File

@@ -11,7 +11,8 @@ from common.literals import TIME_DELTA_UNIT_CHOICES
class SplitTimeDeltaWidget(forms.widgets.MultiWidget):
"""
A Widget that splits a timedelta input into three <input type="text"> boxes.
A Widget that splits a timedelta input into three <input type="text">
boxes.
"""
def __init__(self, attrs=None):

View File

@@ -18,8 +18,8 @@ class ModelAttribute(object):
return result
except IndexError:
# We were passed a model instance, try again using the model of the
# instance
# We were passed a model instance, try again using the model of
# the instance
# If we are already in the model class, exit with an error
if model.__class__ == models.base.ModelBase:
@@ -30,16 +30,24 @@ class ModelAttribute(object):
@classmethod
def get_choices_for(cls, model, type_names=None):
return [
(attribute.name, attribute) for attribute in cls.get_for(model, type_names)
(
attribute.name, attribute
) for attribute in cls.get_for(model, type_names)
]
@classmethod
def help_text_for(cls, model, type_names=None):
result = []
for count, attribute in enumerate(cls.get_for(model, type_names), 1):
result.append('{}) {}'.format(count, unicode(attribute.get_display(show_name=True))))
result.append(
'{}) {}'.format(
count, unicode(attribute.get_display(show_name=True))
)
)
return ' '.join([ugettext('Available attributes: '), ', '.join(result)])
return ' '.join(
[ugettext('Available attributes: '), ', '.join(result)]
)
def get_display(self, show_name=False):
if self.description:

View File

@@ -101,7 +101,9 @@ class CompressedFile(object):
filename for filename in zfobj.namelist() if not filename.endswith('/')
]
return (
SimpleUploadedFile(name=filename, content=zfobj.read(filename)) for filename in filenames
SimpleUploadedFile(
name=filename, content=zfobj.read(filename)
) for filename in filenames
)
except zipfile.BadZipfile:
raise NotACompressedFile

View File

@@ -54,7 +54,9 @@ class DetailForm(forms.ModelForm):
self.fields[field_name].help_text = ''
for field_name, field in self.fields.items():
self.fields[field_name].widget.attrs.update({'readonly': 'readonly'})
self.fields[field_name].widget.attrs.update(
{'readonly': 'readonly'}
)
class ChoiceForm(forms.Form):

View File

@@ -4,11 +4,9 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ImproperlyConfigured
from django.http import Http404, HttpResponseRedirect
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView, TemplateView
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.views.generic.list import ListView
@@ -110,7 +108,9 @@ class AssignRemoveView(ExtraContextMixin, ViewPermissionCheckMixin, ObjectPermis
label = dict(flat_list)[selection]
if self.decode_content_type:
model, pk = selection.split(',')
selection_obj = ContentType.objects.get(model=model).get_object_for_this_type(pk=pk)
selection_obj = ContentType.objects.get(
model=model
).get_object_for_this_type(pk=pk)
else:
selection_obj = selection
@@ -202,7 +202,9 @@ class MultiFormView(FormView):
def get_forms(self, form_classes):
return dict(
[
(key, self._create_form(key, klass)) for key, klass in form_classes.items()
(
key, self._create_form(key, klass)
) for key, klass in form_classes.items()
]
)
@@ -270,7 +272,9 @@ class SingleObjectCreateView(ViewPermissionCheckMixin, ExtraContextMixin, Redire
try:
messages.success(
self.request,
_('%s created successfully.') % self.extra_context['object_name'].capitalize()
_(
'%s created successfully.'
) % self.extra_context['object_name'].capitalize()
)
except KeyError:
messages.success(
@@ -294,7 +298,8 @@ class SingleObjectDeleteView(ViewPermissionCheckMixin, ObjectPermissionCheckMixi
except Exception as exception:
try:
messages.error(
self.request, _('Error deleting %s.') % self.extra_context['object_name']
self.request,
_('Error deleting %s.') % self.extra_context['object_name']
)
except KeyError:
messages.error(
@@ -305,7 +310,10 @@ class SingleObjectDeleteView(ViewPermissionCheckMixin, ObjectPermissionCheckMixi
else:
try:
messages.success(
self.request, _('%s deleted successfully.') % self.extra_context['object_name'].capitalize()
self.request,
_(
'%s deleted successfully.'
) % self.extra_context['object_name'].capitalize()
)
except KeyError:
messages.success(
@@ -325,7 +333,10 @@ class SingleObjectEditView(ViewPermissionCheckMixin, ObjectPermissionCheckMixin,
try:
messages.error(
self.request, _('Error saving %s details.') % self.extra_context['object_name']
self.request,
_(
'Error saving %s details.'
) % self.extra_context['object_name']
)
except KeyError:
messages.error(
@@ -339,7 +350,10 @@ class SingleObjectEditView(ViewPermissionCheckMixin, ObjectPermissionCheckMixin,
try:
messages.success(
self.request, _('%s details saved successfully.') % self.extra_context['object_name'].capitalize()
self.request,
_(
'%s details saved successfully.'
) % self.extra_context['object_name'].capitalize()
)
except KeyError:
messages.success(
@@ -354,4 +368,3 @@ class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectList
def get_paginate_by(self, queryset):
return setting_paginate_by.value

View File

@@ -8,5 +8,7 @@ class AjaxRedirect(object):
def process_response(self, request, response):
if request.is_ajax():
if type(response) == HttpResponseRedirect:
response.status_code = getattr(settings, 'AJAX_REDIRECT_CODE', 302)
response.status_code = getattr(
settings, 'AJAX_REDIRECT_CODE', 302
)
return response

File diff suppressed because one or more lines are too long

View File

@@ -49,7 +49,8 @@ class ObjectListPermissionFilterMixin(object):
self.request.user, (self.object_permission,)
)
except PermissionDenied:
# No global permission, filter ther queryset per object + permission
# No global permission, filter ther queryset per object +
# permission
return AccessControlList.objects.filter_by_access(
self.object_permission, self.request.user, queryset
)
@@ -79,7 +80,9 @@ class ObjectPermissionCheckMixin(object):
self.get_permission_object()
)
return super(ObjectPermissionCheckMixin, self).dispatch(request, *args, **kwargs)
return super(
ObjectPermissionCheckMixin, self
).dispatch(request, *args, **kwargs)
class RedirectionMixin(object):
@@ -111,7 +114,9 @@ class RedirectionMixin(object):
)
)
return super(RedirectionMixin, self).dispatch(request, *args, **kwargs)
return super(
RedirectionMixin, self
).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(RedirectionMixin, self).get_context_data(**kwargs)
@@ -137,4 +142,6 @@ class ViewPermissionCheckMixin(object):
self.request.user, (self.view_permission,)
)
return super(ViewPermissionCheckMixin, self).dispatch(request, *args, **kwargs)
return super(
ViewPermissionCheckMixin, self
).dispatch(request, *args, **kwargs)

View File

@@ -9,7 +9,11 @@ from smart_settings import Namespace
namespace = Namespace(name='common', label=_('Common'))
setting_temporary_directory = namespace.add_setting(
global_name='COMMON_TEMPORARY_DIRECTORY', default=tempfile.gettempdir(),
help_text=_('Temporary directory used site wide to store thumbnails, previews and temporary files. If none is specified, one will be created using tempfile.mkdtemp()'),
help_text=_(
'Temporary directory used site wide to store thumbnails, previews '
'and temporary files. If none is specified, one will be created '
'using tempfile.mkdtemp()'
),
is_path=True
)
setting_shared_storage = namespace.add_setting(
@@ -20,5 +24,7 @@ setting_shared_storage = namespace.add_setting(
setting_paginate_by = namespace.add_setting(
global_name='COMMON_PAGINATE_BY',
default=40,
help_text=_('An integer specifying how many objects should be displayed per page.')
help_text=_(
'An integer specifying how many objects should be displayed per page.'
)
)

View File

@@ -100,7 +100,9 @@ def return_attrib(obj, attrib, arguments=None):
try:
if isinstance(attrib, types.FunctionType):
return attrib(obj)
elif isinstance(obj, types.DictType) or isinstance(obj, types.DictionaryType):
elif isinstance(
obj, types.DictType
) or isinstance(obj, types.DictionaryType):
return obj[attrib]
else:
result = reduce(getattr, attrib.split('.'), obj)
@@ -140,12 +142,13 @@ def urlquote(link=None, get=None):
assert link or get
if isinstance(link, dict):
# urlqoute({'key': 'value', 'key2': 'value2'}) --> key=value&key2=value2
# urlqoute({'key': 'value', 'key2': 'value2'}) -->
# key=value&key2=value2
assert not get, get
get = link
link = ''
assert isinstance(get, dict), 'wrong type "%s", dict required' % type(get)
# assert not (link.startswith('http://') or link.startswith('https://')), \
# assert not (link.startswith('http://') or link.startswith('https://')),
# 'This method should only quote the url path.
# It should not start with http(s):// (%s)' % (
# link)

View File

@@ -12,9 +12,6 @@ from django.utils.http import urlencode
from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView
from documents.search import document_search
from .classes import MissingItem
from .forms import (
LicenseForm, LocaleProfileForm, LocaleProfileForm_view,
UserForm, UserForm_view

View File

@@ -1,6 +1,5 @@
from __future__ import unicode_literals
from itertools import chain
import os
from django import forms
@@ -107,50 +106,6 @@ class PlainWidget(forms.widgets.Widget):
return mark_safe('%s' % value)
class ScrollableCheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
"""
Class for a form widget composed of a selection of checkboxes wrapped
in a div tag with automatic overflow to add scrollbars when the list
exceds the height of the div
"""
def render(self, name, value, attrs=None, choices=()):
if value is None:
value = []
has_id = attrs and 'id' in attrs
final_attrs = self.build_attrs(attrs, name=name)
# TODO: Move this styling to a CSS class
output = [
'<ul class="undecorated_list" style="margin-left: 5px; margin-top: 3px; margin-bottom: 3px;">'
]
# Normalize to strings
str_values = set([force_unicode(v) for v in value])
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
# If an ID attribute was given, add a numeric index as a suffix,
# so that the checkboxes don't all have the same ID attribute.
if has_id:
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
label_for = ' for="%s"' % final_attrs['id']
else:
label_for = ''
cb = forms.widgets.CheckboxInput(
final_attrs, check_test=lambda value: value in str_values
)
option_value = force_unicode(option_value)
rendered_cb = cb.render(name, option_value)
option_label = conditional_escape(force_unicode(option_label))
output.append(
'<li><label%s>%s %s</label></li>' % (
label_for, rendered_cb, option_label
)
)
output.append('</ul>')
return mark_safe(
'<div class="text_area_div">%s</div>' % '\n'.join(output)
)
class TextAreaDiv(forms.widgets.Widget):
"""
Class to define a form widget that simulates the behavior of a

View File

@@ -32,7 +32,9 @@ class DjangoGPGTestCase(TestCase):
# Test querying the keyservers
self.assertTrue(
TEST_KEY_ID in [key_stub.key_id for key_stub in self.gpg.query(TEST_UIDS)]
TEST_KEY_ID in [
key_stub.key_id for key_stub in self.gpg.query(TEST_UIDS)
]
)
# Receive a public key from the keyserver
@@ -40,5 +42,7 @@ class DjangoGPGTestCase(TestCase):
# Check that the received key is indeed in the keyring
self.assertTrue(
TEST_KEY_ID[-16:] in [key_stub.key_id for key_stub in Key.get_all(self.gpg)]
TEST_KEY_ID[-16:] in [
key_stub.key_id for key_stub in Key.get_all(self.gpg)
]
)

View File

@@ -1,6 +1,5 @@
from __future__ import absolute_import, unicode_literals
from datetime import datetime
import logging
from django.conf import settings

View File

@@ -51,10 +51,16 @@ def comment_delete(request, comment_id=None, comment_id_list=None):
)
previous = request.POST.get(
'previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
'previous', request.GET.get(
'previous', request.META.get(
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
)
)
)
next = request.POST.get(
'next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
'next', request.GET.get(
'next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))
)
)
if request.method == 'POST':
@@ -110,7 +116,11 @@ def comment_add(request, document_id):
post_action_redirect = None
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))))
next = request.POST.get(
'next', request.GET.get(
'next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))
)
)
if request.method == 'POST':
form = CommentForm(request.POST)
@@ -144,7 +154,8 @@ class DocumentCommentListView(SingleObjectListView):
)
except PermissionDenied:
AccessControlList.objects.check_access(
permission_comment_view, self.request.user, self.get_document()
permission_comment_view, self.request.user,
self.get_document()
)
return self.get_document().comments.all()

View File

@@ -61,7 +61,8 @@ class DocumentIndexingApp(MayanAppConfig):
)
)
SourceColumn(
source=IndexInstance, label=_('Document types'), attribute='get_document_types_names'
source=IndexInstance, label=_('Document types'),
attribute='get_document_types_names'
)
SourceColumn(
@@ -74,7 +75,9 @@ class DocumentIndexingApp(MayanAppConfig):
)
SourceColumn(
source=IndexTemplateNode, label=_('Has document links?'),
func=lambda context: two_state_template(context['object'].link_documents)
func=lambda context: two_state_template(
context['object'].link_documents
)
)
SourceColumn(

View File

@@ -20,7 +20,8 @@ class IndexInstanceNodeManager(models.Manager):
@staticmethod
def delete_empty_index_nodes_recursive(instance_node):
"""
Calls itself recursively deleting empty index instance nodes up to root
Calls itself recursively deleting empty index instance nodes up to
root
"""
if instance_node.get_children().count() == 0:

View File

@@ -15,11 +15,38 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Index',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(help_text='Internal name used to reference this index.', unique=True, max_length=64, verbose_name='Name')),
('title', models.CharField(help_text='The name that will be visible to users.', unique=True, max_length=128, verbose_name='Title')),
('enabled', models.BooleanField(default=True, help_text='Causes this index to be visible and updated when document data changes.', verbose_name='Enabled')),
('document_types', models.ManyToManyField(to='documents.DocumentType', verbose_name='Document types')),
(
'id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True
)
),
(
'name', models.CharField(
help_text='Internal name used to reference this index.',
unique=True, max_length=64, verbose_name='Name'
)
),
(
'title', models.CharField(
help_text='The name that will be visible to users.',
unique=True, max_length=128, verbose_name='Title'
)
),
(
'enabled', models.BooleanField(
default=True,
help_text='Causes this index to be visible and updated when document data changes.',
verbose_name='Enabled'
)
),
(
'document_types',
models.ManyToManyField(
to='documents.DocumentType',
verbose_name='Document types'
)
),
],
options={
'verbose_name': 'Index',
@@ -30,13 +57,43 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='IndexInstanceNode',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('value', models.CharField(max_length=128, verbose_name='Value', blank=True)),
('lft', models.PositiveIntegerField(editable=False, db_index=True)),
('rght', models.PositiveIntegerField(editable=False, db_index=True)),
('tree_id', models.PositiveIntegerField(editable=False, db_index=True)),
('level', models.PositiveIntegerField(editable=False, db_index=True)),
('documents', models.ManyToManyField(related_name='node_instances', verbose_name='Documents', to='documents.Document')),
(
'id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True
)
),
(
'value', models.CharField(
max_length=128, verbose_name='Value', blank=True
)
),
(
'lft', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'rght', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'tree_id', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'level', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'documents', models.ManyToManyField(
related_name='node_instances',
verbose_name='Documents', to='documents.Document'
)
),
],
options={
'verbose_name': 'Index node instance',
@@ -47,16 +104,64 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='IndexTemplateNode',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('expression', models.CharField(help_text='Enter a python string expression to be evaluated.', max_length=128, verbose_name='Indexing expression')),
('enabled', models.BooleanField(default=True, help_text='Causes this node to be visible and updated when document data changes.', verbose_name='Enabled')),
('link_documents', models.BooleanField(default=False, help_text='Check this option to have this node act as a container for documents and not as a parent for further nodes.', verbose_name='Link documents')),
('lft', models.PositiveIntegerField(editable=False, db_index=True)),
('rght', models.PositiveIntegerField(editable=False, db_index=True)),
('tree_id', models.PositiveIntegerField(editable=False, db_index=True)),
('level', models.PositiveIntegerField(editable=False, db_index=True)),
('index', models.ForeignKey(related_name='node_templates', verbose_name='Index', to='document_indexing.Index')),
('parent', mptt.fields.TreeForeignKey(blank=True, to='document_indexing.IndexTemplateNode', null=True)),
(
'id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True
)
),
(
'expression', models.CharField(
help_text='Enter a python string expression to be evaluated.',
max_length=128, verbose_name='Indexing expression'
)
),
(
'enabled', models.BooleanField(
default=True,
help_text='Causes this node to be visible and updated when document data changes.',
verbose_name='Enabled'
)
),
(
'link_documents', models.BooleanField(
default=False,
help_text='Check this option to have this node act as a container for documents and not as a parent for further nodes.',
verbose_name='Link documents'
)
),
(
'lft', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'rght', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'tree_id', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'level', models.PositiveIntegerField(
editable=False, db_index=True
)
),
(
'index', models.ForeignKey(
related_name='node_templates', verbose_name='Index',
to='document_indexing.Index'
)
),
(
'parent', mptt.fields.TreeForeignKey(
blank=True, to='document_indexing.IndexTemplateNode',
null=True
)
),
],
options={
'verbose_name': 'Index node template',
@@ -67,13 +172,20 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='indexinstancenode',
name='index_template_node',
field=models.ForeignKey(related_name='node_instance', verbose_name='Index template node', to='document_indexing.IndexTemplateNode'),
field=models.ForeignKey(
related_name='node_instance',
verbose_name='Index template node',
to='document_indexing.IndexTemplateNode'
),
preserve_default=True,
),
migrations.AddField(
model_name='indexinstancenode',
name='parent',
field=mptt.fields.TreeForeignKey(blank=True, to='document_indexing.IndexInstanceNode', null=True),
field=mptt.fields.TreeForeignKey(
blank=True, to='document_indexing.IndexInstanceNode',
null=True
),
preserve_default=True,
),
]

View File

@@ -14,7 +14,9 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='index',
name='label',
field=models.CharField(unique=True, max_length=128, verbose_name='Label'),
field=models.CharField(
unique=True, max_length=128, verbose_name='Label'
),
preserve_default=True,
),
]

View File

@@ -14,7 +14,11 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='index',
name='slug',
field=models.SlugField(null=True, max_length=128, blank=True, help_text='This values will be used by other apps to reference this index.', unique=True, verbose_name='Slug'),
field=models.SlugField(
null=True, max_length=128, blank=True,
help_text='This values will be used by other apps to reference this index.',
unique=True, verbose_name='Slug'
),
preserve_default=True,
),
]

View File

@@ -14,7 +14,11 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='index',
name='slug',
field=models.SlugField(default='', max_length=128, help_text='This values will be used by other apps to reference this index.', unique=True, verbose_name='Slug'),
field=models.SlugField(
default='', max_length=128,
help_text='This values will be used by other apps to reference this index.',
unique=True, verbose_name='Slug'
),
preserve_default=False,
),
]

View File

@@ -14,7 +14,10 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='indexinstancenode',
name='value',
field=models.CharField(db_index=True, max_length=128, verbose_name='Value', blank=True),
field=models.CharField(
db_index=True, max_length=128, verbose_name='Value',
blank=True
),
preserve_default=True,
),
]

View File

@@ -14,7 +14,10 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='indextemplatenode',
name='expression',
field=models.CharField(help_text="Enter a template to render. Use Django's default templating language (https://docs.djangoproject.com/en/1.7/ref/templates/builtins/)", max_length=128, verbose_name='Indexing expression'),
field=models.CharField(
help_text="Enter a template to render. Use Django's default templating language (https://docs.djangoproject.com/en/1.7/ref/templates/builtins/)",
max_length=128, verbose_name='Indexing expression'
),
preserve_default=True,
),
]

View File

@@ -71,7 +71,9 @@ class Index(models.Model):
def get_document_types_names(self):
return ', '.join(
[unicode(document_type) for document_type in self.document_types.all()] or ['None']
[
unicode(document_type) for document_type in self.document_types.all()
] or ['None']
)
class Meta:

View File

@@ -37,7 +37,8 @@ urlpatterns = patterns(
),
url(
r'^setup/index/(?P<pk>\d+)/document_types/$',
SetupIndexDocumentTypesView.as_view(), name='index_setup_document_types'
SetupIndexDocumentTypesView.as_view(),
name='index_setup_document_types'
),
url(
r'^setup/template/node/(?P<parent_pk>\d+)/create/child/$',
@@ -84,8 +85,8 @@ api_urls = patterns(
name='index-detail'
),
url(
r'^index/(?P<pk>[0-9]+)/template/$', APIIndexTemplateListView.as_view(),
name='index-template-detail'
r'^index/(?P<pk>[0-9]+)/template/$',
APIIndexTemplateListView.as_view(), name='index-template-detail'
),
url(r'^indexes/$', APIIndexListView.as_view(), name='index-list'),
url(

View File

@@ -15,7 +15,6 @@ from common.views import (
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
SingleObjectEditView, SingleObjectListView
)
from common.widgets import two_state_template
from documents.models import Document, DocumentType
from documents.permissions import permission_document_view
from documents.views import DocumentListView
@@ -33,7 +32,7 @@ from .permissions import (
permission_document_indexing_setup, permission_document_indexing_view
)
from .tasks import task_do_rebuild_all_indexes
from .widgets import index_instance_item_link, get_breadcrumbs, node_level
from .widgets import get_breadcrumbs
# Setup views

View File

@@ -21,7 +21,9 @@ def get_instance_link(index_instance_node, text=None, simple=False):
return template % {
'url': index_instance_node.get_absolute_url(),
'value': text if text else (index_instance_node if index_instance_node.parent else index_instance_node.index_template_node.index)
'value': text if text else (
index_instance_node if index_instance_node.parent else index_instance_node.index_template_node.index
)
}
@@ -50,7 +52,9 @@ def get_breadcrumbs(index_instance_node, simple=False, single_link=False, includ
# Return the entire breadcrumb path as a single HTML anchor
output.insert(
0, get_instance_link(
index_instance_node=index_instance_node, text=(' / '.join(result))
index_instance_node=index_instance_node, text=(
' / '.join(result)
)
)
)
return mark_safe(' '.join(output))
@@ -68,11 +72,13 @@ def index_instance_item_link(index_instance_item):
else:
icon_template = ''
return mark_safe('%(icon_template)s&nbsp;<a href="%(url)s">%(text)s</a>' % {
'url': index_instance_item.get_absolute_url(),
'icon_template': icon_template,
'text': index_instance_item
})
return mark_safe(
'%(icon_template)s&nbsp;<a href="%(url)s">%(text)s</a>' % {
'url': index_instance_item.get_absolute_url(),
'icon_template': icon_template,
'text': index_instance_item
}
)
def node_level(node):
@@ -83,8 +89,9 @@ def node_level(node):
return mark_safe(
''.join(
[
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' * (getattr(node, node._mptt_meta.level_attr) - 1),
'' if node.is_root_node() else '<i class="fa fa-level-up fa-rotate-90"></i> ',
'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' * (
getattr(node, node._mptt_meta.level_attr) - 1
), '' if node.is_root_node() else '<i class="fa fa-level-up fa-rotate-90"></i> ',
ugettext('Root') if node.is_root_node() else unicode(node)
]
)

View File

@@ -103,15 +103,6 @@ class PrintForm(forms.Form):
page_range = forms.CharField(label=_('Page range'), required=False)
class DocumentTypeFilenameForm(forms.ModelForm):
"""
Model class form to edit a document type filename
"""
class Meta:
fields = ('filename', 'enabled')
model = DocumentTypeFilename
class DocumentTypeFilenameForm_create(forms.ModelForm):
"""
Model class form to create a new document type filename

View File

@@ -1 +1 @@
from .literals import *
from .literals import * # NOQA

View File

@@ -1,6 +1,5 @@
from __future__ import unicode_literals
from django.conf import settings
from django.core.files import File
from django.test import TestCase

View File

@@ -21,8 +21,7 @@ from common.generics import (
SingleObjectEditView, SingleObjectListView
)
from common.mixins import MultipleInstanceActionMixin
from common.utils import encapsulate, pretty_size
from common.widgets import two_state_template
from common.utils import pretty_size
from converter.literals import (
DEFAULT_PAGE_NUMBER, DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
)
@@ -36,8 +35,8 @@ from .events import (
)
from .forms import (
DocumentDownloadForm, DocumentForm, DocumentPageForm, DocumentPreviewForm,
DocumentPropertiesForm, DocumentTypeFilenameForm,
DocumentTypeFilenameForm_create, DocumentTypeSelectForm, PrintForm
DocumentPropertiesForm, DocumentTypeSelectForm,
DocumentTypeFilenameForm_create, PrintForm
)
from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT
from .models import (

View File

@@ -8,7 +8,7 @@ from rest_api.filters import MayanObjectPermissionsFilter
from .classes import SearchModel
from .filters import RecentSearchUserFilter
from .models import RecentSearch
from .serializers import RecentSearchSerializer, SearchSerializer
from .serializers import RecentSearchSerializer
class APIRecentSearchListView(generics.ListAPIView):

View File

@@ -15,7 +15,3 @@ class RecentSearchSerializer(serializers.HyperlinkedModelSerializer):
fields = ('datetime_created', 'hits', 'query', 'url', 'user')
model = RecentSearch
read_only_fields = ('datetime_created', 'hits', 'query', 'user')
class SearchSerializer(serializers.Serializer):
results = serializers.CharField()

View File

@@ -6,8 +6,6 @@ import urlparse
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _
from common.generics import SimpleView, SingleObjectListView

View File

@@ -20,7 +20,8 @@ class EventsApp(MayanAppConfig):
SourceColumn(source=Action, label=_('Timestamp'), attribute='timestamp')
SourceColumn(source=Action, label=_('Actor'), attribute='actor')
SourceColumn(source=Action, label=_('Verb'),
SourceColumn(
source=Action, label=_('Verb'),
func=lambda context: event_type_link(context['object'])
)

View File

@@ -1,11 +1,8 @@
from __future__ import absolute_import, unicode_literals
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _
from common.generics import SingleObjectListView
from permissions import Permission
from .classes import PropertyNamespace
from .permissions import permission_installation_details
@@ -37,4 +34,3 @@ class NamespaceDetailView(SingleObjectListView):
def get_queryset(self):
return self.get_namespace().get_properties()

View File

@@ -16,7 +16,6 @@ from common.generics import (
AssignRemoveView, SingleObjectCreateView, SingleObjectEditView,
SingleObjectListView
)
from common.widgets import two_state_template
from documents.models import Document, DocumentType
from documents.permissions import permission_document_view
from documents.views import DocumentListView

View File

@@ -11,7 +11,7 @@ from fuse import FUSE, FuseOSError, Operations
from django.core import management
from django.core.cache import caches
from django.core.exceptions import MultipleObjectsReturned
from django.db.models import Count, Max
from django.db.models import Count
from document_indexing.models import Index, IndexInstanceNode
from documents.models import Document

View File

@@ -32,8 +32,14 @@ class UserManagementApp(MayanAppConfig):
APIEndPoint(app=self, version_string='1')
MetadataLookup(description=_('All the groups.'), name='group', value=Group.objects.all())
MetadataLookup(description=_('All the users.'), name='users', value=get_user_model().objects.all())
MetadataLookup(
description=_('All the groups.'), name='group',
value=Group.objects.all()
)
MetadataLookup(
description=_('All the users.'), name='users',
value=get_user_model().objects.all()
)
SourceColumn(
source=Group, label=_('Members'), attribute='user_set.count'
@@ -47,11 +53,15 @@ class UserManagementApp(MayanAppConfig):
)
SourceColumn(
source=User, label=_('Active'),
func=lambda context: two_state_template(context['object'].is_active)
func=lambda context: two_state_template(
context['object'].is_active
)
)
SourceColumn(
source=User, label=_('Has usable password?'),
func=lambda context: two_state_template(context['object'].has_usable_password())
func=lambda context: two_state_template(
context['object'].has_usable_password()
)
)
menu_multi_item.bind_links(

View File

@@ -14,7 +14,6 @@ from common.views import (
AssignRemoveView, SingleObjectCreateView, SingleObjectEditView,
SingleObjectListView
)
from common.widgets import two_state_template
from permissions import Permission
from .forms import PasswordForm, UserForm
@@ -47,7 +46,10 @@ def user_edit(request, user_id):
if user.is_superuser or user.is_staff:
messages.error(
request,
_('Super user and staff user editing is not allowed, use the admin interface for these cases.')
_(
'Super user and staff user editing is not allowed, use the '
'admin interface for these cases.'
)
)
return HttpResponseRedirect(
request.META.get(
@@ -106,7 +108,9 @@ def user_delete(request, user_id=None, user_id_list=None):
post_action_redirect = reverse('user_management:user_list')
elif user_id_list:
users = [
get_object_or_404(User, pk=user_id) for user_id in user_id_list.split(',')
get_object_or_404(
User, pk=user_id
) for user_id in user_id_list.split(',')
]
else:
messages.error(request, _('Must provide at least one user.'))
@@ -123,14 +127,24 @@ def user_delete(request, user_id=None, user_id_list=None):
for user in users:
try:
if user.is_superuser or user.is_staff:
messages.error(request, _('Super user and staff user deleting is not allowed, use the admin interface for these cases.'))
messages.error(
request,
_(
'Super user and staff user deleting is not '
'allowed, use the admin interface for these cases.'
)
)
else:
user.delete()
messages.success(request, _('User "%s" deleted successfully.') % user)
messages.success(
request, _('User "%s" deleted successfully.') % user
)
except Exception as exception:
messages.error(request, _('Error deleting user "%(user)s": %(error)s') % {
'user': user, 'error': exception
})
messages.error(
request, _('Error deleting user "%(user)s": %(error)s') % {
'user': user, 'error': exception
}
)
return HttpResponseRedirect(next)
@@ -145,8 +159,10 @@ def user_delete(request, user_id=None, user_id_list=None):
elif len(users) > 1:
context['title'] = _('Delete the users: %s?') % ', '.join([unicode(d) for d in users])
return render_to_response('appearance/generic_confirm.html', context,
context_instance=RequestContext(request))
return render_to_response(
'appearance/generic_confirm.html', context,
context_instance=RequestContext(request)
)
def user_multiple_delete(request):
@@ -166,7 +182,11 @@ def user_set_password(request, user_id=None, user_id_list=None):
users = [get_object_or_404(User, pk=user_id) for user_id in user_id_list.split(',')]
else:
messages.error(request, _('Must provide at least one user.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
return HttpResponseRedirect(
request.META.get(
'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)
)
)
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))))
@@ -181,15 +201,30 @@ def user_set_password(request, user_id=None, user_id_list=None):
for user in users:
try:
if user.is_superuser or user.is_staff:
messages.error(request, _('Super user and staff user password reseting is not allowed, use the admin interface for these cases.'))
messages.error(
request,
_(
'Super user and staff user password '
'reseting is not allowed, use the admin '
'interface for these cases.'
)
)
else:
user.set_password(password_1)
user.save()
messages.success(request, _('Successfull password reset for user: %s.') % user)
messages.success(
request, _(
'Successfull password reset for user: %s.'
) % user
)
except Exception as exception:
messages.error(request, _('Error reseting password for user "%(user)s": %(error)s') % {
'user': user, 'error': exception
})
messages.error(
request, _(
'Error reseting password for user "%(user)s": %(error)s'
) % {
'user': user, 'error': exception
}
)
return HttpResponseRedirect(next)
else:
@@ -243,10 +278,14 @@ class UserGroupsView(AssignRemoveView):
return get_object_or_404(User, pk=self.kwargs['pk'])
def left_list(self):
return AssignRemoveView.generate_choices(get_user_non_groups(self.get_object()))
return AssignRemoveView.generate_choices(
get_user_non_groups(self.get_object())
)
def right_list(self):
return AssignRemoveView.generate_choices(get_user_groups(self.get_object()))
return AssignRemoveView.generate_choices(
get_user_groups(self.get_object())
)
def remove(self, item):
item.user_set.remove(self.get_object())
@@ -297,7 +336,9 @@ def group_delete(request, group_id=None, group_id_list=None):
groups = [get_object_or_404(Group, pk=group_id)]
post_action_redirect = reverse('user_management:group_list')
elif group_id_list:
groups = [get_object_or_404(Group, pk=group_id) for group_id in group_id_list.split(',')]
groups = [
get_object_or_404(Group, pk=group_id) for group_id in group_id_list.split(',')
]
else:
messages.error(request, _('Must provide at least one group.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))
@@ -359,10 +400,16 @@ class GroupMembersView(AssignRemoveView):
return get_object_or_404(Group, pk=self.kwargs['pk'])
def left_list(self):
return AssignRemoveView.generate_choices(User.objects.exclude(groups=self.get_object()).exclude(is_staff=True).exclude(is_superuser=True))
return AssignRemoveView.generate_choices(
User.objects.exclude(
groups=self.get_object()
).exclude(is_staff=True).exclude(is_superuser=True)
)
def right_list(self):
return AssignRemoveView.generate_choices(self.get_object().user_set.all())
return AssignRemoveView.generate_choices(
self.get_object().user_set.all()
)
def remove(self, item):
self.get_object().user_set.remove(item)