diff --git a/benchmark b/benchmark index 55d95e4..4da48f6 100755 --- a/benchmark +++ b/benchmark @@ -1,11 +1,11 @@ #!/usr/bin/env python -import os.path -import time import json +import os.path +import random +import time import numpy -import random os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'docbow_project.settings') diff --git a/debian/control b/debian/control index 918855e..cc55bdd 100644 --- a/debian/control +++ b/debian/control @@ -2,32 +2,32 @@ Source: docbow Maintainer: Benjamin Dauvergne Section: python Priority: optional -Build-Depends: python3-setuptools, - python3-all, - debhelper-compat (= 12), - dh-python, - openssl, - python3-django (>= 1:1.11), - yelp-tools, - yelp-xsl +Build-Depends: debhelper-compat (= 12), + dh-python, + openssl, + python3-all, + python3-django (>= 1:1.11), + python3-setuptools, + yelp-tools, + yelp-xsl, Standards-Version: 3.9.6 Homepage: https://dev.entrouvert.org/projects/docbow Package: docbow Architecture: all -Suggests: postgresql -Depends: ${python3:Depends}, - ${misc:Depends}, - python3-django (>= 1:1.11), - python3-bs4, - python3-django-journal (>= 2.0.0), - python3-django-picklefield, - python3-django-tables2, - python3-requests, - python3-magic, - python3-psycopg2, - python3-django-watson (>= 1.2.0), - uwsgi, - uwsgi-plugin-python3 -Recommends: python3-django-mellon +Suggests: postgresql, +Depends: python3-bs4, + python3-django (>= 1:1.11), + python3-django-journal (>= 2.0.0), + python3-django-picklefield, + python3-django-tables2, + python3-django-watson (>= 1.2.0), + python3-magic, + python3-psycopg2, + python3-requests, + uwsgi, + uwsgi-plugin-python3, + ${misc:Depends}, + ${python3:Depends}, +Recommends: python3-django-mellon, Description: Document Box Wallone diff --git a/debian/dirs b/debian/dirs index d572cb7..e3825fb 100644 --- a/debian/dirs +++ b/debian/dirs @@ -1,10 +1,10 @@ etc/docbow -usr/share/docbow/templates etc/nginx/sites-available usr/lib/docbow +usr/share/docbow/templates +var/lib/docbow/collectstatic var/lib/docbow/media var/lib/docbow/static -var/lib/docbow/collectstatic var/lib/docbow/templates -var/run/docbow var/log/docbow +var/run/docbow diff --git a/debian/install b/debian/install index 4f9be58..c4a01df 100644 --- a/debian/install +++ b/debian/install @@ -2,4 +2,4 @@ debian/conf/docbow.nginx /etc/nginx/sites-available/ debian/conf/magic /usr/share/docbow debian/debian_config.py /usr/lib/docbow debian/docbow-manage /usr/bin -debian/uwsgi.ini /etc/docbow \ No newline at end of file +debian/uwsgi.ini /etc/docbow diff --git a/docbow-ctl b/docbow-ctl index 5c836e7..0b6514b 100755 --- a/docbow-ctl +++ b/docbow-ctl @@ -1,7 +1,7 @@ #!/usr/bin/env python -import sys import os +import sys if __name__ == '__main__': from django.core.management import execute_from_command_line diff --git a/docbow_project/docbow/__init__.py b/docbow_project/docbow/__init__.py index 29dc409..694b77d 100644 --- a/docbow_project/docbow/__init__.py +++ b/docbow_project/docbow/__init__.py @@ -5,7 +5,4 @@ class AppConfig(django.apps.AppConfig): name = 'docbow_project.docbow' def ready(self): - from . import signals - - -default_app_config = 'docbow_project.docbow.AppConfig' + pass diff --git a/docbow_project/docbow/actions.py b/docbow_project/docbow/actions.py index 32a1be9..35c754f 100644 --- a/docbow_project/docbow/actions.py +++ b/docbow_project/docbow/actions.py @@ -1,8 +1,9 @@ import csv + from django.core.exceptions import PermissionDenied from django.http import HttpResponse -from django.utils.encoding import force_str, force_text -from django.utils.translation import ugettext as _ +from django.utils.encoding import force_str +from django.utils.translation import gettext as _ def export_as_csv(modeladmin, request, queryset): @@ -13,7 +14,7 @@ def export_as_csv(modeladmin, request, queryset): raise PermissionDenied opts = modeladmin.model._meta response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename=%s.csv' % force_text(opts).replace('.', '_') + response['Content-Disposition'] = 'attachment; filename=%s.csv' % force_str(opts).replace('.', '_') writer = csv.writer(response) field_names = [field.name for field in opts.fields] m2m_field_names = [m2m_field.name for m2m_field in opts.many_to_many] @@ -21,11 +22,11 @@ def export_as_csv(modeladmin, request, queryset): writer.writerow(field_names + m2m_field_names) # Write data rows for obj in queryset: - values = [force_text(getattr(obj, field)) for field in field_names] + values = [force_str(getattr(obj, field)) for field in field_names] for m2m_field in m2m_field_names: value = getattr(obj, m2m_field) - value = u','.join(map(force_text, value.all())) - values.append(force_text(value)) + value = ','.join(map(force_str, value.all())) + values.append(force_str(value)) writer.writerow(map(lambda x: force_str(x), values)) return response diff --git a/docbow_project/docbow/admin.py b/docbow_project/docbow/admin.py index 7b50505..7dfdde7 100644 --- a/docbow_project/docbow/admin.py +++ b/docbow_project/docbow/admin.py @@ -1,28 +1,22 @@ -# -*- coding: utf-8 -*- - import django.contrib.admin as admin -from django.utils.translation import ugettext as _ -from django.contrib.auth import admin as auth_admin, models as auth_models from django.conf import settings +from django.contrib.auth import admin as auth_admin +from django.contrib.auth import models as auth_models from django.core.exceptions import PermissionDenied -from django.urls import reverse, NoReverseMatch -from django.conf.urls import url +from django.urls import NoReverseMatch, re_path, reverse from django.utils.safestring import mark_safe +from django.utils.translation import gettext as _ try: import thread except ImportError: import _thread as thread + import django_journal.admin -from docbow_project.docbow import models -from docbow_project.docbow import forms -from docbow_project.docbow import views -from docbow_project.docbow import notification -from docbow_project.docbow import actions -from docbow_project.docbow import auth_views +from docbow_project.docbow import actions, auth_views, forms, models, notification, views -TITLE = u"Plate-forme sécurisée d'échange de documents" +TITLE = "Plate-forme sécurisée d'échange de documents" class DocbowAdminSite(admin.AdminSite): @@ -74,7 +68,7 @@ class MailingListAdmin(admin.ModelAdmin): """Show delete actions only if user has delete rights Show activation actions only if user has rights to change mailing lists """ - a = super(MailingListAdmin, self).get_actions(request) + a = super().get_actions(request) if request.user.has_perm('docbow.delete_mailinglist'): a['delete_selected'] = self.get_action('delete_selected') if request.user.has_perm('docbow.change_mailinglist'): @@ -88,8 +82,8 @@ class AttachedFileAdmin(admin.ModelAdmin): return {} def get_urls(self): - urls = super(AttachedFileAdmin, self).get_urls() - attached_file_urls = [url(r'^(.+)/download/$', self.download)] + urls = super().get_urls() + attached_file_urls = [re_path(r'^(.+)/download/$', self.download)] return attached_file_urls + urls def download(self, request, object_id): @@ -139,17 +133,17 @@ class DocbowUserAdmin(auth_admin.UserAdmin): inlines += [UserSAMLIdentifierInlineAdmin] def get_groups(self, user): - return u', '.join(group.name for group in user.groups.all()) + return ', '.join(group.name for group in user.groups.all()) get_groups.short_description = _('groups') def get_lists(self, user): - return u', '.join(_list.name for _list in user.mailing_lists.all()) + return ', '.join(_list.name for _list in user.mailing_lists.all()) get_lists.short_description = _('mailing lists') def get_actions(self, request): - a = super(DocbowUserAdmin, self).get_actions(request) + a = super().get_actions(request) if request.user.has_perm('auth.delete_docbowuser'): a['delete_selected'] = self.get_action('delete_selected') if request.user.has_perm('auth.change_docbowuser'): @@ -193,7 +187,7 @@ class InboxAdmin(MailboxAdmin): def queryset(self, request): '''Only show input mailboxes''' - qs = super(InboxAdmin, self).queryset(request) + qs = super().queryset(request) qs = qs.filter(outbox=False) return qs @@ -205,7 +199,7 @@ class OutboxAdmin(MailboxAdmin): def queryset(self, request): '''Only show output mailboxes''' - qs = super(OutboxAdmin, self).queryset(request) + qs = super().queryset(request) qs = qs.filter(outbox=True) return qs @@ -223,7 +217,7 @@ class AutomaticForwardingAdmin(admin.ModelAdmin): def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name in ('originaly_to_user', 'forward_to_user'): kwargs['queryset'] = models.non_guest_users() - return super(AutomaticForwardingAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) + return super().formfield_for_foreignkey(db_field, request, **kwargs) class FileTypeAttachedFileKindAdmin(admin.TabularInline): @@ -262,12 +256,12 @@ class NotificationAdmin(admin.ModelAdmin): def object_link(self, obj): if obj is not None: - url = u'{0}:{1}_{2}_change'.format( + url = '{}:{}_{}_change'.format( self.admin_site.name, obj.__class__._meta.app_label, obj.__class__._meta.model_name ) try: url = reverse(url, args=(obj.id,)) - return u'{1}'.format(url, obj) + return f'{obj}' except NoReverseMatch: pass return '' diff --git a/docbow_project/docbow/app_settings.py b/docbow_project/docbow/app_settings.py index cb5d252..6375336 100644 --- a/docbow_project/docbow/app_settings.py +++ b/docbow_project/docbow/app_settings.py @@ -1,4 +1,4 @@ -class AppSettings(object): +class AppSettings: __DEFAULTS = { 'PERSONAL_EMAIL': True, 'MOBILE_PHONE': True, @@ -26,20 +26,20 @@ class AppSettings(object): @property def DOCBOW_MENU(self): - from django.utils.translation import ugettext_noop + from django.utils.translation import gettext_noop return getattr( self.settings, 'DOCBOW_MENU', [ - ('send-file-selector', ugettext_noop('send-file_menu')), - ('inbox', ugettext_noop('inbox_menu')), - ('outbox', ugettext_noop('outbox_menu')), - ('docbow_admin:index', ugettext_noop('admin_menu')), - ('profile', ugettext_noop('profile_menu')), - ('mailing-lists', ugettext_noop('mailing-lists')), - ('help', ugettext_noop('help_menu')), - ('contact', ugettext_noop('contact_menu')), + ('send-file-selector', gettext_noop('send-file_menu')), + ('inbox', gettext_noop('inbox_menu')), + ('outbox', gettext_noop('outbox_menu')), + ('docbow_admin:index', gettext_noop('admin_menu')), + ('profile', gettext_noop('profile_menu')), + ('mailing-lists', gettext_noop('mailing-lists')), + ('help', gettext_noop('help_menu')), + ('contact', gettext_noop('contact_menu')), ], ) diff --git a/docbow_project/docbow/auth_backend.py b/docbow_project/docbow/auth_backend.py index 6fcc97e..7057aca 100644 --- a/docbow_project/docbow/auth_backend.py +++ b/docbow_project/docbow/auth_backend.py @@ -33,7 +33,6 @@ class DelegationAuthBackend: try: - import mellon.backends class DocbowMellonAuthBackend(mellon.backends.SAMLBackend): @@ -47,7 +46,7 @@ try: set_auth_hash_getter(user, delegate) return user except User.DoesNotExist: - return super(DocbowMellonAuthBackend, self).get_user(user_id) + return super().get_user(user_id) except ImportError: pass diff --git a/docbow_project/docbow/auth_urls.py b/docbow_project/docbow/auth_urls.py index 73d2e3b..91311a0 100644 --- a/docbow_project/docbow/auth_urls.py +++ b/docbow_project/docbow/auth_urls.py @@ -1,44 +1,39 @@ -from django.conf.urls import url from django.contrib.auth import views as auth_views -from django.urls import reverse_lazy +from django.urls import path, re_path, reverse_lazy -from docbow_project.docbow import views -from docbow_project.docbow import forms from docbow_project.docbow import auth_views as docbow_auth_views - +from docbow_project.docbow import forms, views urlpatterns = [ - url( - r'^login/$', docbow_auth_views.login, {'template_name': 'registration/login.html'}, name='auth_login' - ), - url( - r'^logout/$', + path('login/', docbow_auth_views.login, {'template_name': 'registration/login.html'}, name='auth_login'), + path( + 'logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='auth_logout', ), - url(r'^password/change/$', views.password_change, name='auth_password_change'), - url( - r'^password/change/done/$', + path('password/change/', views.password_change, name='auth_password_change'), + path( + 'password/change/done/', auth_views.PasswordChangeDoneView.as_view(), name='auth_password_change_done', ), - url( - r'^password/reset/$', + path( + 'password/reset/', auth_views.PasswordResetView.as_view( success_url=reverse_lazy('auth_password_reset_done'), form_class=forms.PasswordResetFormWithLogging, ), name='auth_password_reset', ), - url( + re_path( r'^password/reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P.+)/$', auth_views.PasswordResetConfirmView.as_view(), name='auth_password_reset_confirm', ), - url( - r'^password/reset/complete/$', + path( + 'password/reset/complete/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete', ), - url(r'^password/reset/done/$', views.password_reset_done, name='auth_password_reset_done'), + path('password/reset/done/', views.password_reset_done, name='auth_password_reset_done'), ] diff --git a/docbow_project/docbow/auth_views.py b/docbow_project/docbow/auth_views.py index 11be7ff..d67685e 100644 --- a/docbow_project/docbow/auth_views.py +++ b/docbow_project/docbow/auth_views.py @@ -5,7 +5,6 @@ from django.contrib.auth import views as auth_views from django.http import HttpResponseRedirect from django.shortcuts import resolve_url - if 'mellon' in settings.INSTALLED_APPS: from mellon.utils import get_idps else: diff --git a/docbow_project/docbow/cbv.py b/docbow_project/docbow/cbv.py index 251bb8a..9f2561b 100644 --- a/docbow_project/docbow/cbv.py +++ b/docbow_project/docbow/cbv.py @@ -1,23 +1,23 @@ -class FormWithRequestMixin(object): +class FormWithRequestMixin: def get_form_kwargs(self, **kwargs): - kwargs = super(FormWithRequestMixin, self).get_form_kwargs(**kwargs) + kwargs = super().get_form_kwargs(**kwargs) kwargs['request'] = self.request return kwargs -class FormWithPrefixMixin(object): +class FormWithPrefixMixin: # deprecated after Django 1.6 prefix = None def get_form_kwargs(self, **kwargs): - kwargs = super(FormWithPrefixMixin, self).get_form_kwargs(**kwargs) + kwargs = super().get_form_kwargs(**kwargs) kwargs['prefix'] = self.prefix return kwargs class FormWithPostTarget(FormWithPrefixMixin): def get_form_kwargs(self, **kwargs): - kwargs = super(FormWithPostTarget, self).get_form_kwargs(**kwargs) + kwargs = super().get_form_kwargs(**kwargs) if not self.is_post_target(): kwargs.pop('data', None) kwargs.pop('files', None) diff --git a/docbow_project/docbow/decorators.py b/docbow_project/docbow/decorators.py index 1244e9b..c6f4e39 100644 --- a/docbow_project/docbow/decorators.py +++ b/docbow_project/docbow/decorators.py @@ -1,9 +1,9 @@ from functools import wraps -from django.shortcuts import redirect from django.contrib import messages -from django.utils.translation import ugettext as _ +from django.shortcuts import redirect from django.utils.cache import patch_cache_control +from django.utils.translation import gettext as _ from django.views.decorators.cache import never_cache as old_never_cache diff --git a/docbow_project/docbow/email_utils.py b/docbow_project/docbow/email_utils.py index 1a12db6..0fcbd60 100644 --- a/docbow_project/docbow/email_utils.py +++ b/docbow_project/docbow/email_utils.py @@ -1,8 +1,7 @@ import re from email.header import decode_header, make_header -from django.utils.encoding import force_text - +from django.utils.encoding import force_str # check spaces between encoded_words (and strip them) sre = re.compile(r'\?=[ \t]+=\?') @@ -13,7 +12,7 @@ mre = re.compile(r'=\?[^?]*?\?[bq]\?[^? \t]*?\?=', re.I) def decode_mime(m): # substitute matching encoded_word with force_text equiv. h = decode_header(m.group(0)) - u = force_text(make_header(h)) + u = force_str(make_header(h)) return u diff --git a/docbow_project/docbow/fields.py b/docbow_project/docbow/fields.py index 1ef767b..09685fa 100644 --- a/docbow_project/docbow/fields.py +++ b/docbow_project/docbow/fields.py @@ -1,10 +1,10 @@ from django.contrib.auth.models import User -from django.forms import ValidationError, MultipleChoiceField -from django.utils.translation import ugettext as _ +from django.forms import MultipleChoiceField, ValidationError +from django.utils.translation import gettext as _ from docbow_project.docbow import pyuca -from docbow_project.docbow.models import username, MailingList -from docbow_project.docbow.widgets import ForcedValueWidget, FilteredSelectMultiple +from docbow_project.docbow.models import MailingList, username +from docbow_project.docbow.widgets import FilteredSelectMultiple, ForcedValueWidget def order_choices(choices): @@ -22,7 +22,7 @@ def order_field_choices(field): print(field.choices) -class Func2Iter(object): +class Func2Iter: '''Transform a generator producing function into an iterator''' def __init__(self, func): @@ -40,7 +40,7 @@ class RecipientField(MultipleChoiceField): self.user_qs = kwargs.pop('user_qs', User.objects.filter()) self.user_qs = self.user_qs.filter(is_active=True, delegations_by__isnull=True) self.list_qs = kwargs.pop('list_qs', MailingList.objects.active()) - super(RecipientField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._choices = self.widget.choices = Func2Iter(self.get_recipients_choices) def reset_choices(self): @@ -79,7 +79,7 @@ class RecipientField(MultipleChoiceField): def clean(self, value): '''Validate that the value is not empty.''' - value = super(RecipientField, self).clean(value) + value = super().clean(value) if not value: - raise ValidationError(_(u'you must set at least one user recipient or one list recipient...')) + raise ValidationError(_('you must set at least one user recipient or one list recipient...')) return value diff --git a/docbow_project/docbow/forms.py b/docbow_project/docbow/forms.py index 78b52da..0470bc1 100644 --- a/docbow_project/docbow/forms.py +++ b/docbow_project/docbow/forms.py @@ -1,60 +1,49 @@ -import os.path -import hmac +import collections import datetime import hashlib +import hmac import logging -import collections +import os.path import urllib.parse - -from django.forms import ( - ModelForm, - Form, - Textarea, - EmailField, - CharField, - ModelChoiceField, - ModelMultipleChoiceField, -) from django import forms -from django.contrib.auth.models import User -from django.utils.translation import ugettext as _ -from django.contrib.admin.widgets import FilteredSelectMultiple as AdminFilteredSelectMultiple -from django.forms import ValidationError from django.conf import settings +from django.contrib.admin.widgets import FilteredSelectMultiple as AdminFilteredSelectMultiple +from django.contrib.auth.forms import PasswordChangeForm, PasswordResetForm +from django.contrib.auth.models import User from django.db.models.query import Q -from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm -from django.utils.encoding import force_text - +from django.forms import CharField, EmailField, Form, ModelChoiceField, ModelForm, Textarea, ValidationError +from django.utils.encoding import force_str +from django.utils.translation import gettext as _ from django_journal import journal as django_journal - +from docbow_project.docbow import app_settings, fields, models, notification, pyuca, widgets +from docbow_project.docbow.fields import RecipientField +from docbow_project.docbow.middleware import get_extra from docbow_project.docbow.models import ( - Document, - username, - MailingList, - Content, AttachedFile, AutomaticForwarding, + Content, DocbowProfile, - non_guest_users, - is_guest, + Document, FileTypeAttachedFileKind, + MailingList, + is_guest, + non_guest_users, + username, ) -from docbow_project.docbow.widgets import TextInpuWithPredefinedValues, JqueryFileUploadInput -from docbow_project.docbow.fields import RecipientField +from docbow_project.docbow.utils import a2_wscall, mime_types_to_extensions, truncate_filename from docbow_project.docbow.validators import phone_normalize, validate_fr_be_phone -from docbow_project.docbow.middleware import get_extra -from docbow_project.docbow.utils import mime_types_to_extensions, truncate_filename, a2_wscall -from docbow_project.docbow import fields, app_settings, models, widgets -from docbow_project.docbow import notification, pyuca -from docbow_project.docbow.widgets import FilteredSelectMultiple - +from docbow_project.docbow.widgets import ( + FilteredSelectMultiple, + JqueryFileUploadInput, + TextInpuWithPredefinedValues, +) logger = logging.getLogger(__name__) -class RecipientForm(object): +class RecipientForm: """ Base form mixin for forms containing a RecipienField, i.e. all forms for sending documents. @@ -67,7 +56,7 @@ class RecipientForm(object): if user_qs is None: user_qs = non_guest_users() list_qs = kwargs.pop('list_qs', MailingList.objects.active()) - super(RecipientForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.fields['recipients'].user = user self.fields['recipients'].user_qs = user_qs self.fields['recipients'].list_qs = list_qs @@ -98,7 +87,7 @@ class ForwardingForm(RecipientForm, Form): .order_by('last_name', 'first_name', 'username') .distinct() ) - super(ForwardingForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if len(delegations) > 1: self.fields['sender'].queryset = delegations self.fields['sender'].label_from_instance = lambda y: username(y) @@ -106,7 +95,7 @@ class ForwardingForm(RecipientForm, Form): del self.fields['sender'] def clean(self): - cleaned_data = super(ForwardingForm, self).clean() + cleaned_data = super().clean() if not cleaned_data.get('sender'): cleaned_data['sender'] = self.default_sender return cleaned_data @@ -150,9 +139,9 @@ class FileForm(RecipientForm, ModelForm): initial['recipients'] = ['user-%s' % doc.sender.id] if doc.extra_senders.exists(): initial['recipients'] += ['user-%s' % sender.pk for sender in doc.extra_senders.all()] - initial['comment'] = u'Re: ' + doc.comment + initial['comment'] = 'Re: ' + doc.comment - super(FileForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.content_fields = [] if self.attached_file_kinds: insert_index = 2 @@ -215,23 +204,23 @@ class FileForm(RecipientForm, ModelForm): def clean(self): '''Validate that there is at least one file attached to this mailing.''' - cleaned_data = super(FileForm, self).clean() + cleaned_data = super().clean() for field, attached_file_kind in self.content_fields: upload_id, upload_files = self.cleaned_data.get(field, (None, [])) max_files = attached_file_kind.cardinality min_files = attached_file_kind.minimum errors = [] if max_files and len(upload_files) > max_files: - errors.append(_(u'You must attach at most %d file(s).') % max_files) + errors.append(_('You must attach at most %d file(s).') % max_files) if min_files and len(upload_files) < min_files: - errors.append(_(u'You must attach at least %d file(s).') % min_files) + errors.append(_('You must attach at least %d file(s).') % min_files) for upload_file in upload_files: if not attached_file_kind.match_file(upload_file): mime_types = attached_file_kind.get_mime_types() file_name = os.path.basename(upload_file.name) - msg = _( - u'The file name "{file_name}" does not match the patterns "{extensions}".' - ).format(file_name=file_name, extensions=mime_types_to_extensions(mime_types)) + msg = _('The file name "{file_name}" does not match the patterns "{extensions}".').format( + file_name=file_name, extensions=mime_types_to_extensions(mime_types) + ) errors.append(msg) if errors: self._errors[field] = self.error_class(errors) @@ -253,7 +242,7 @@ class FileForm(RecipientForm, ModelForm): self.instance.reply_to = self.reply_to if self.user != self.instance.sender: self.instance.real_sender = username(self.user) - return super(FileForm, self).save(commit=commit) + return super().save(commit=commit) def save_attachments(self): """Create a new AttachedFile object for each uploaded file; and attach @@ -327,7 +316,7 @@ class DelegationForm(Form): self.user = kwargs.pop('user', None) self.delegatees = kwargs.pop('delegatees', []) self._request = kwargs.pop('request') - super(DelegationForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) qs = non_guest_users() if self.user: qs = qs.exclude(id=self.user.id) @@ -338,7 +327,7 @@ class DelegationForm(Form): del self.fields['existing_user'] def clean(self): - cleaned_data = super(DelegationForm, self).clean() + cleaned_data = super().clean() ok1 = bool(cleaned_data.get('first_name')) ok2 = bool(cleaned_data.get('last_name')) ok3 = bool(cleaned_data.get('email')) @@ -364,7 +353,7 @@ class DelegationForm(Form): raise ValidationError(_('A delegation with the same email already exists')) qs = non_guest_users().filter(email=email) if qs.exists(): - list_of_names = u', '.join([user.get_full_name() for user in qs]) + list_of_names = ', '.join([user.get_full_name() for user in qs]) self.data = {} self.is_bound = False raise ValidationError( @@ -411,7 +400,7 @@ class AutomaticForwardingForm(ModelForm): def clean(self): '''Validate that the forwarding rule contains at least one recipient.''' - cleaned_data = super(AutomaticForwardingForm, self).clean() + cleaned_data = super().clean() if not cleaned_data.get('forward_to_user') and not cleaned_data.get('forward_to_list'): raise ValidationError(_('A forwarding rule must have at least one recipient, person or list.')) return cleaned_data @@ -456,7 +445,7 @@ class ProfileForm(ModelForm): if not self.instance or self.instance.mobile_phone != mobile_phone: date = datetime.date.today() code = hmac.new( - force_bytes(settings.SECRET_KEY), force_text(date) + mobile_phone, hashlib.sha1 + force_bytes(settings.SECRET_KEY), force_str(date) + mobile_phone, hashlib.sha1 ).hexdigest() code = '%06d' % (int(code, 16) % 1000000) key = '%s-code' % self.prefix if self.prefix else 'code' @@ -495,10 +484,11 @@ class ProfileForm(ModelForm): import unicodedata + from django.contrib.auth.tokens import default_token_generator from django.contrib.sites.shortcuts import get_current_site -from django.utils.http import urlsafe_base64_encode from django.utils.encoding import force_bytes +from django.utils.http import urlsafe_base64_encode def _unicode_ci_compare(s1, s2): @@ -605,7 +595,7 @@ class PasswordResetFormWithLogging(PasswordResetForm): class PasswordChangeFormWithLogging(PasswordChangeForm): def save(self, *args, **kwargs): - super(PasswordChangeFormWithLogging, self).save(*args, **kwargs) + super().save(*args, **kwargs) django_journal.record('password-change', 'changed its email', user=self.user, ip=get_extra()['ip']) @@ -626,7 +616,7 @@ class FilterForm(forms.Form): def __init__(self, *args, **kwargs): request = kwargs.pop('request') outbox = kwargs.pop('outbox', False) - super(FilterForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.fields['search_terms'].widget.attrs['data-boxtype'] = 'outbox' if outbox else 'inbox' for field in ('sort', 'page'): @@ -634,7 +624,7 @@ class FilterForm(forms.Form): self.fields[field] = forms.CharField(initial=request.GET.get(field), widget=forms.HiddenInput) def clean(self): - cleaned_data = super(FilterForm, self).clean() + cleaned_data = super().clean() if ( cleaned_data.get('not_before') and cleaned_data.get('not_after') @@ -657,7 +647,7 @@ class EmailForm(ModelForm): fields = ('email',) def __init__(self, *args, **kwargs): - super(EmailForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.initial['email'] = '' self.initial['old_email'] = self.instance.email @@ -668,7 +658,7 @@ class EmailForm(ModelForm): return password def clean(self): - cleaned_data = super(EmailForm, self).clean() + cleaned_data = super().clean() email = cleaned_data.get('email') email2 = cleaned_data.get('email2') if email and email2 and email != email2: @@ -695,11 +685,11 @@ class NotificationPreferencesForm(Form): for np in models.NotificationPreference.objects.filter(user=self.user): if not np.value: self.initials[np.filetype_id].remove(np.kind) - super(NotificationPreferencesForm, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) for filetype in self.filetypes: key = 'filetype-%s' % filetype.id self.fields[key] = forms.MultipleChoiceField( - label=force_text(filetype), + label=force_str(filetype), choices=self.choices, initial=self.initials[filetype.id], widget=widgets.CheckboxMultipleSelect, diff --git a/docbow_project/docbow/management/commands/add-list.py b/docbow_project/docbow/management/commands/add-list.py index db739f6..bd6f343 100644 --- a/docbow_project/docbow/management/commands/add-list.py +++ b/docbow_project/docbow/management/commands/add-list.py @@ -3,7 +3,7 @@ import locale from django.contrib.auth.models import User from django.core.management.base import BaseCommand, CommandError from django.db import transaction -from django.utils.encoding import force_text +from django.utils.encoding import force_str from docbow_project.docbow.models import MailingList @@ -17,7 +17,6 @@ def get_object(model, ref): class Command(BaseCommand): - help = '''Create or update a list''' def add_arguments(self, parser): @@ -42,7 +41,7 @@ class Command(BaseCommand): locale.setlocale(locale.LC_ALL, '') locale_encoding = locale.nl_langinfo(locale.CODESET) mailing_list, created = MailingList.objects.get_or_create( - name=force_text(options['ml_name'], locale_encoding) + name=force_str(options['ml_name'], locale_encoding) ) try: for l in options['add_list']: diff --git a/docbow_project/docbow/management/commands/add-user.py b/docbow_project/docbow/management/commands/add-user.py index 544536f..b574b4b 100644 --- a/docbow_project/docbow/management/commands/add-user.py +++ b/docbow_project/docbow/management/commands/add-user.py @@ -1,11 +1,11 @@ from optparse import make_option -from django.contrib.auth.models import User, Group +from django.contrib.auth.models import Group, User from django.core.management.base import BaseCommand, CommandError from django.db import transaction -from django.utils.encoding import force_text +from django.utils.encoding import force_str -from docbow_project.docbow.models import MailingList, DocbowProfile +from docbow_project.docbow.models import DocbowProfile, MailingList def get_object(model, ref): @@ -49,11 +49,11 @@ List and groups can be referred by name or by id. raise CommandError('username argument is mandatory') user, created = User.objects.get_or_create(username=args[0]) if options['first_name']: - user.first_name = force_text(options['first_name'], 'utf-8') + user.first_name = force_str(options['first_name'], 'utf-8') if options['last_name']: - user.last_name = force_text(options['last_name'], 'utf-8') + user.last_name = force_str(options['last_name'], 'utf-8') if options['email']: - user.email = force_text(options['email'], 'utf-8') + user.email = force_str(options['email'], 'utf-8') if options['activate'] is not None: user.is_active = options['activate'] if options['superuser'] is not None: @@ -78,8 +78,8 @@ List and groups can be referred by name or by id. raise CommandError('group %r does not exist' % g) profile, created = DocbowProfile.objects.get_or_create(user=user) if options['mobile_phone']: - profile.mobile_phone = force_text(options['mobile_phone'], 'utf-8') + profile.mobile_phone = force_str(options['mobile_phone'], 'utf-8') if options['personal_email']: - profile.personal_email = force_text(options['personal_email'], 'utf-8') + profile.personal_email = force_str(options['personal_email'], 'utf-8') user.save() profile.save() diff --git a/docbow_project/docbow/management/commands/archive.py b/docbow_project/docbow/management/commands/archive.py index f03443d..4795119 100644 --- a/docbow_project/docbow/management/commands/archive.py +++ b/docbow_project/docbow/management/commands/archive.py @@ -1,17 +1,17 @@ -import shutil import csv +import datetime as dt import os import os.path -import datetime as dt +import shutil import time -from django.core.management.base import BaseCommand, CommandError import django.contrib.auth.models as auth_models -from django.db import transaction from django.conf import settings +from django.core.management.base import BaseCommand, CommandError +from django.db import transaction -from ... import models from ....log import models as log_models +from ... import models class Command(BaseCommand): @@ -50,7 +50,7 @@ class Command(BaseCommand): csv_handle.writerow(dict(zip(csv_handle.fieldnames, csv_handle.fieldnames))) logs = log_models.LogLine.objects.all() for log in logs: - d = dict([(header, getattr(log, header)) for header in headers]) + d = {header: getattr(log, header) for header in headers} d['timestamp'] = d['timestamp'].isoformat() self.dict_to_utf8(d) csv_handle.writerow(d) diff --git a/docbow_project/docbow/management/commands/clean-documents.py b/docbow_project/docbow/management/commands/clean-documents.py index b7ed75e..8aee525 100644 --- a/docbow_project/docbow/management/commands/clean-documents.py +++ b/docbow_project/docbow/management/commands/clean-documents.py @@ -1,4 +1,5 @@ from django.core.management.base import BaseCommand + from ... import models diff --git a/docbow_project/docbow/management/commands/docbow_dumpdata.py b/docbow_project/docbow/management/commands/docbow_dumpdata.py index bb66064..84970e8 100644 --- a/docbow_project/docbow/management/commands/docbow_dumpdata.py +++ b/docbow_project/docbow/management/commands/docbow_dumpdata.py @@ -1,11 +1,11 @@ +from optparse import make_option + +from django.core import serializers from django.core.exceptions import ImproperlyConfigured from django.core.management.base import BaseCommand, CommandError -from django.core import serializers -from django.db import router, DEFAULT_DB_ALIAS +from django.db import DEFAULT_DB_ALIAS, router from django.utils.datastructures import SortedDict -from optparse import make_option - class Command(BaseCommand): option_list = BaseCommand.option_list + ( diff --git a/docbow_project/docbow/management/commands/dump-users-csv.py b/docbow_project/docbow/management/commands/dump-users-csv.py index 8e15480..c8bdbaa 100644 --- a/docbow_project/docbow/management/commands/dump-users-csv.py +++ b/docbow_project/docbow/management/commands/dump-users-csv.py @@ -1,11 +1,9 @@ import csv -from django.core.management.base import BaseCommand, CommandError import django.contrib.auth.models as auth_models +from django.core.management.base import BaseCommand, CommandError from django.db import transaction -from ... import models - class Command(BaseCommand): args = '' diff --git a/docbow_project/docbow/management/commands/forward-docs.py b/docbow_project/docbow/management/commands/forward-docs.py index 90528dc..901a7e0 100644 --- a/docbow_project/docbow/management/commands/forward-docs.py +++ b/docbow_project/docbow/management/commands/forward-docs.py @@ -13,7 +13,7 @@ def valid_date(s): try: return date_to_aware_datetime(datetime.strptime(s, '%Y-%m-%d')) except ValueError: - msg = "Not a valid date: '{0}'.".format(s) + msg = f"Not a valid date: '{s}'." raise argparse.ArgumentTypeError(msg) diff --git a/docbow_project/docbow/management/commands/list-lists.py b/docbow_project/docbow/management/commands/list-lists.py index 58d58de..6f8ec63 100644 --- a/docbow_project/docbow/management/commands/list-lists.py +++ b/docbow_project/docbow/management/commands/list-lists.py @@ -1,10 +1,10 @@ -import sys import locale +import sys from optparse import make_option from django.core.management.base import BaseCommand from django.db import transaction -from django.utils.encoding import force_text +from django.utils.encoding import force_str from ...models import MailingList from ...unicodecsv import UnicodeWriter @@ -13,7 +13,7 @@ from ...unicodecsv import UnicodeWriter def print_table(table): col_width = [max(len(x) for x in col) for col in zip(*table)] for line in table: - line = u'| ' + u' | '.join(u'{0:>{1}}'.format(x, col_width[i]) for i, x in enumerate(line)) + u' |' + line = '| ' + ' | '.join('{0:>{1}}'.format(x, col_width[i]) for i, x in enumerate(line)) + ' |' print(line) @@ -35,7 +35,7 @@ class Command(BaseCommand): for mailing_list in mailing_lists: tables.append( map( - force_text, + force_str, ( mailing_list.id, mailing_list.name, diff --git a/docbow_project/docbow/management/commands/list-users.py b/docbow_project/docbow/management/commands/list-users.py index 768bd8e..0bea538 100644 --- a/docbow_project/docbow/management/commands/list-users.py +++ b/docbow_project/docbow/management/commands/list-users.py @@ -1,11 +1,11 @@ -import sys import locale +import sys from optparse import make_option from django.contrib.auth.models import User from django.core.management.base import BaseCommand from django.db import transaction -from django.utils.encoding import force_text +from django.utils.encoding import force_str from ...models import DocbowProfile from ...unicodecsv import UnicodeWriter @@ -14,7 +14,7 @@ from ...unicodecsv import UnicodeWriter def print_table(table): col_width = [max(len(x) for x in col) for col in zip(*table)] for line in table: - line = u'| ' + u' | '.join(u'{0:>{1}}'.format(x, col_width[i]) for i, x in enumerate(line)) + u' |' + line = '| ' + ' | '.join('{0:>{1}}'.format(x, col_width[i]) for i, x in enumerate(line)) + ' |' print(line) @@ -55,7 +55,7 @@ class Command(BaseCommand): personal_email = '' tables.append( map( - force_text, + force_str, ( user.id, user.username, diff --git a/docbow_project/docbow/management/commands/load-users-csv.py b/docbow_project/docbow/management/commands/load-users-csv.py index 392bf59..b7ad838 100644 --- a/docbow_project/docbow/management/commands/load-users-csv.py +++ b/docbow_project/docbow/management/commands/load-users-csv.py @@ -1,19 +1,19 @@ import csv import os.path -from optparse import make_option -import unicodedata import random import sys +import unicodedata +from optparse import make_option -from django.core.management.base import BaseCommand, CommandError from django.contrib.auth import models as auth_models -from django.utils.encoding import force_text +from django.core.management.base import BaseCommand, CommandError +from django.utils.encoding import force_str from ... import models def strip_accents(s): - return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn')) + return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn') def keep_letters(s): @@ -25,11 +25,11 @@ def unicode_csv_reader(utf8_csv_data, dialect=csv.excel, **kwargs): csv_reader = csv.reader(utf8_csv_data, dialect=dialect, **kwargs) for row in csv_reader: # decode UTF-8 back to Unicode, cell by cell: - yield [force_text(cell, 'utf-8') for cell in row] + yield [force_str(cell, 'utf-8') for cell in row] def csv_to_list(s): - return filter(None, map(str.strip, s.split(u','))) + return filter(None, map(str.strip, s.split(','))) # Utilise seulement des majuscules et des chiffres, sauf i,l et 1, O et 0 @@ -73,22 +73,22 @@ class Command(BaseCommand): data['username'] = username if 'profil' not in data: - default_profiles = csv_to_list(','.join(map(force_text, options.get('profile', [])))) + default_profiles = csv_to_list(','.join(map(force_str, options.get('profile', [])))) data['profil'] = default_profiles else: data['profil'] = csv_to_list(data['profil']) if 'groupe' not in data: - default_groups = csv_to_list(','.join(map(force_text, options.get('group', [])))) + default_groups = csv_to_list(','.join(map(force_str, options.get('group', [])))) data['groupe'] = default_groups else: data['groupe'] = csv_to_list(data['groupe']) if not data.get('password'): if options.get('password'): - data['password'] = force_text(options['password'], 'utf8') + data['password'] = force_str(options['password'], 'utf8') elif options.get('generate_password', False): - data['password'] = force_text(create_password()) + data['password'] = force_str(create_password()) def handle(self, *args, **options): if len(args) == 0: diff --git a/docbow_project/docbow/management/commands/sendfile.py b/docbow_project/docbow/management/commands/sendfile.py index 075a688..d0c074d 100644 --- a/docbow_project/docbow/management/commands/sendfile.py +++ b/docbow_project/docbow/management/commands/sendfile.py @@ -2,12 +2,12 @@ import locale import os.path from django.contrib.auth.models import User +from django.core.files import File from django.core.management.base import BaseCommand, CommandError from django.db import transaction -from django.core.files import File -from django.utils.encoding import force_text +from django.utils.encoding import force_str -from docbow_project.docbow.models import MailingList, FileType, Document, AttachedFile +from docbow_project.docbow.models import AttachedFile, Document, FileType, MailingList def get_object(model, ref, name='name'): @@ -19,7 +19,6 @@ def get_object(model, ref, name='name'): class Command(BaseCommand): - help = '''Send a document''' def add_arguments(self, parser): @@ -37,27 +36,27 @@ class Command(BaseCommand): if 'sender' not in options: raise CommandError('missing --sender parameter') try: - sender = get_object(User, force_text(options['sender'], locale_encoding), 'username') + sender = get_object(User, force_str(options['sender'], locale_encoding), 'username') except User.DoesNotExist: raise CommandError('user %r does not exist' % options['sender']) to_lists = [] try: for l in options.get('to_list') or []: - l = get_object(MailingList, force_text(l, locale_encoding)) + l = get_object(MailingList, force_str(l, locale_encoding)) to_lists.append(l) except MailingList.DoesNotExist: raise CommandError('list %r does not exist' % l) to_users = [] try: for l in options.get('to_user') or []: - l = get_object(User, force_text(l, locale_encoding), 'username') + l = get_object(User, force_str(l, locale_encoding), 'username') to_users.append(l) except User.DoesNotExist: raise CommandError('user %r does not exist' % l) if 'filetype' not in options: raise CommandError('missing --filetype parameter') try: - filetype = get_object(FileType, force_text(options['filetype'], locale_encoding)) + filetype = get_object(FileType, force_str(options['filetype'], locale_encoding)) except FileType.DoesNotExist: raise CommandError('filetype %r does not exist' % options['filetype']) if not to_users and not to_lists: @@ -73,6 +72,6 @@ class Command(BaseCommand): if not os.path.isfile(arg): raise CommandError('file %r does not exist') AttachedFile.objects.create( - name=force_text(arg, locale_encoding), content=File(open(arg)), document=document + name=force_str(arg, locale_encoding), content=File(open(arg)), document=document ) document.post() diff --git a/docbow_project/docbow/middleware.py b/docbow_project/docbow/middleware.py index 3281cd2..456a266 100644 --- a/docbow_project/docbow/middleware.py +++ b/docbow_project/docbow/middleware.py @@ -1,6 +1,6 @@ -import threading import logging import sys +import threading from django.utils.deprecation import MiddlewareMixin diff --git a/docbow_project/docbow/migrations/0001_initial.py b/docbow_project/docbow/migrations/0001_initial.py index f3c3603..2ae9d87 100644 --- a/docbow_project/docbow/migrations/0001_initial.py +++ b/docbow_project/docbow/migrations/0001_initial.py @@ -1,16 +1,13 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import django.utils.timezone -from django.conf import settings -import docbow_project.docbow.models import django.core.validators +import django.utils.timezone import picklefield.fields +from django.conf import settings +from django.db import migrations, models + +import docbow_project.docbow.models class Migration(migrations.Migration): - dependencies = [ ('auth', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), @@ -465,7 +462,7 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='filetypeattachedfilekind', - unique_together=set([('name', 'file_type')]), + unique_together={('name', 'file_type')}, ), migrations.AddField( model_name='document', @@ -536,7 +533,7 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='delegation', - unique_together=set([('by', 'to')]), + unique_together={('by', 'to')}, ), migrations.AddField( model_name='automaticforwarding', diff --git a/docbow_project/docbow/migrations/0002_auto_20190711_1812.py b/docbow_project/docbow/migrations/0002_auto_20190711_1812.py index 8fa84bd..60e2aac 100644 --- a/docbow_project/docbow/migrations/0002_auto_20190711_1812.py +++ b/docbow_project/docbow/migrations/0002_auto_20190711_1812.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models -from django.conf import settings +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('docbow', '0001_initial'), ] diff --git a/docbow_project/docbow/migrations/0003_auto_20200319_1129.py b/docbow_project/docbow/migrations/0003_auto_20200319_1129.py index f92867e..fca072c 100644 --- a/docbow_project/docbow/migrations/0003_auto_20200319_1129.py +++ b/docbow_project/docbow/migrations/0003_auto_20200319_1129.py @@ -1,11 +1,7 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('docbow', '0002_auto_20190711_1812'), ] diff --git a/docbow_project/docbow/migrations/0004_external_identifier.py b/docbow_project/docbow/migrations/0004_external_identifier.py index b6a899d..238947e 100644 --- a/docbow_project/docbow/migrations/0004_external_identifier.py +++ b/docbow_project/docbow/migrations/0004_external_identifier.py @@ -1,11 +1,7 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('docbow', '0003_auto_20200319_1129'), ] diff --git a/docbow_project/docbow/migrations/0005_soft_delete.py b/docbow_project/docbow/migrations/0005_soft_delete.py index 8a50387..a490352 100644 --- a/docbow_project/docbow/migrations/0005_soft_delete.py +++ b/docbow_project/docbow/migrations/0005_soft_delete.py @@ -1,12 +1,9 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-07-21 12:30 -from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('docbow', '0004_external_identifier'), ] diff --git a/docbow_project/docbow/migrations/0006_extra_senders.py b/docbow_project/docbow/migrations/0006_extra_senders.py index 8c25dfb..c06db53 100644 --- a/docbow_project/docbow/migrations/0006_extra_senders.py +++ b/docbow_project/docbow/migrations/0006_extra_senders.py @@ -1,13 +1,10 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-12-10 14:33 -from __future__ import unicode_literals from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('docbow', '0005_soft_delete'), diff --git a/docbow_project/docbow/migrations/0007_filetype_extra_senders.py b/docbow_project/docbow/migrations/0007_filetype_extra_senders.py index 7a324c1..d9403b3 100644 --- a/docbow_project/docbow/migrations/0007_filetype_extra_senders.py +++ b/docbow_project/docbow/migrations/0007_filetype_extra_senders.py @@ -1,12 +1,9 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-02-24 12:49 -from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('docbow', '0006_extra_senders'), ] diff --git a/docbow_project/docbow/migrations/0008_auto_20230613_1353.py b/docbow_project/docbow/migrations/0008_auto_20230613_1353.py index c0b2387..817b164 100644 --- a/docbow_project/docbow/migrations/0008_auto_20230613_1353.py +++ b/docbow_project/docbow/migrations/0008_auto_20230613_1353.py @@ -1,11 +1,9 @@ # Generated by Django 3.2.16 on 2023-06-13 11:53 from django.db import migrations, models -import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ ('docbow', '0007_filetype_extra_senders'), ] diff --git a/docbow_project/docbow/models.py b/docbow_project/docbow/models.py index f5a969f..06b7f47 100644 --- a/docbow_project/docbow/models.py +++ b/docbow_project/docbow/models.py @@ -1,47 +1,47 @@ -import os import datetime as dt -import itertools -import random -import hashlib import html +import itertools +import os +import random import re +import time import urllib.parse from collections import defaultdict -import time -from django.db.models import ( - Model, - ForeignKey, - DateTimeField, - CharField, - FileField, - ManyToManyField, - TextField, - Manager, - BooleanField, - OneToOneField, - Q, - EmailField, - PositiveSmallIntegerField, - CASCADE, - PositiveIntegerField, -) -from django.contrib.auth.models import User, Group from django.conf import settings -from django.template.defaultfilters import slugify -from django.utils.translation import ugettext_lazy as _, pgettext_lazy -from django.urls import reverse -from picklefield.fields import PickledObjectField -from django.utils.html import strip_tags -from django.utils.timezone import now, utc +from django.contrib.auth.models import Group, User +from django.db.models import ( + CASCADE, + BooleanField, + CharField, + DateTimeField, + EmailField, + FileField, + ForeignKey, + Manager, + ManyToManyField, + Model, + OneToOneField, + PositiveIntegerField, + PositiveSmallIntegerField, + Q, + TextField, +) from django.forms import ValidationError -from django.utils.encoding import force_text +from django.template.defaultfilters import slugify +from django.urls import reverse +from django.utils.encoding import force_str +from django.utils.html import strip_tags from django.utils.safestring import mark_safe - +from django.utils.timezone import now, utc +from django.utils.translation import gettext_lazy as _ +from django.utils.translation import pgettext_lazy from django_journal import journal as django_journal -from docbow_project.docbow.validators import validate_phone -from docbow_project.docbow.utils import file_match_mime_types +from picklefield.fields import PickledObjectField + from docbow_project.docbow import app_settings +from docbow_project.docbow.utils import file_match_mime_types +from docbow_project.docbow.validators import validate_phone DOCBOW_APP = _('docbow') DOCBOW_APP = _('Docbow_App') @@ -74,7 +74,7 @@ class ContentManager(Manager): return self.get(description=description) -class NameNaturalKey(object): +class NameNaturalKey: """Model mixin to export the name of a model as a natural key. The name field MUST be unique.""" @@ -178,7 +178,7 @@ def username(user): if user.first_name or user.last_name: d = dict(last_name='', first_name='') d.update(user.__dict__) - return u'{last_name} {first_name}'.format(**d) + return '{last_name} {first_name}'.format(**d) return user.username @@ -210,9 +210,7 @@ FORWARD_PERMISSION = 'FORWARD_DOCUMENT' class DocumentManager(Manager): def get_query_set(self): '''Prefetch as much as possible.''' - return ( - super(DocumentManager, self).get_query_set().select_related().prefetch_related('attached_files') - ) + return super().get_query_set().select_related().prefetch_related('attached_files') class Document(Model): @@ -278,7 +276,7 @@ class Document(Model): kind = attached_file.kind name = attached_file.filename() url = attached_file.link() - links.append(u'%s' % (url, name)) + links.append('%s' % (url, name)) if kind and kind.name != last_kind_name: links[-1] = kind.name + ' : ' + links[-1] last_kind_name = kind.name @@ -292,11 +290,11 @@ class Document(Model): def group_human_to(self): '''Return a sorted list of display names for list recipients.''' - return sorted(map(force_text, self.to_list.all())) + return sorted(map(force_str, self.to_list.all())) def human_to(self): '''Return a sorted list of display names for all recipients.''' - return sorted(list(map(username, self.to_user.all())) + list(map(force_text, self.to_list.all()))) + return sorted(list(map(username, self.to_user.all())) + list(map(force_str, self.to_list.all()))) def recipients(self): """Return a comma separated sorted list of display names for all @@ -363,7 +361,7 @@ class Document(Model): for user in to: Mailbox.objects.get_or_create(owner=user, document=self) if '--direct--' not in to_with_origins[user] or len(to_with_origins[user]) > 1: - lists = u', '.join(m.name for m in to_with_origins[user] if m != '--direct--') + lists = ', '.join(m.name for m in to_with_origins[user] if m != '--direct--') if '--direct--' in to_with_origins[user]: django_journal.record( 'delivery', @@ -481,11 +479,11 @@ class DocumentForwarded(Model): def __str__(self): if self.automatic: - return _(u'forwarded document {from_document} as {to_document} on {date} automatically').format( + return _('forwarded document {from_document} as {to_document} on {date} automatically').format( from_document=self.from_document, to_document=self.to_document, date=self.date ) else: - return _(u'forwarded document {from_document} as {to_document} on {date}').format( + return _('forwarded document {from_document} as {to_document} on {date}').format( from_document=self.from_document, to_document=self.to_document, date=self.date ) @@ -498,7 +496,7 @@ def list_to_csv(l, mapping_func=None): """ if mapping_func: l = map(mapping_func, l) - return u', '.join(map(force_text, l)) + return ', '.join(map(force_str, l)) class AutomaticForwarding(Model): @@ -655,7 +653,7 @@ class Delegation(Model): unique_together = (('by', 'to'),) def __str__(self): - return u'delegation from {0}:{0.id} to {1}:{1.id}'.format(self.by, self.to) + return 'delegation from {0}:{0.id} to {1}:{1.id}'.format(self.by, self.to) @property def guest_delegate(self): @@ -747,7 +745,7 @@ class Mailbox(Model): verbose_name_plural = _('Mailboxes') def __str__(self): - return _(u'mailbox entry {id} of user {user}:{user.id} created on ' u'{date} for {document}').format( + return _('mailbox entry {id} of user {user}:{user.id} created on ' '{date} for {document}').format( id=self.id, user=self.owner, date=self.date, document=self.document ) @@ -802,7 +800,7 @@ class SendingLimitation(Model): def __str__(self): return _( - u'sending limitation for list {mailing_list} to filetypes' u'{filetypes} and lists {lists}' + 'sending limitation for list {mailing_list} to filetypes' '{filetypes} and lists {lists}' ).format( mailing_list=self.mailing_list, filetypes=list_to_csv(self.filetypes.all()), @@ -836,8 +834,8 @@ class DocbowProfile(Model): def __str__(self): return _( - u'docbow profile of {user}:{user.id} with mobile phone ' - u'{mobile_phone} and personal email {personal_email}' + 'docbow profile of {user}:{user.id} with mobile phone ' + '{mobile_phone} and personal email {personal_email}' ).format(user=self.user, mobile_phone=self.mobile_phone, personal_email=self.personal_email) @@ -881,7 +879,7 @@ class Notification(Model): ordering = ('-id',) def __str__(self): - return _(u'notification {0}:{1}').format(self.kind, self.id) + return _('notification {0}:{1}').format(self.kind, self.id) class NotificationPreference(Model): @@ -916,13 +914,13 @@ class DocumentAdapter(watson.SearchAdapter): yield attached_file.name def get_title(self, obj): - return u' '.join(self.gather_strings(obj))[:1000] + return ' '.join(self.gather_strings(obj))[:1000] def get_description(self, obj): - return u' '.join(self.gather_strings(obj)) + return ' '.join(self.gather_strings(obj)) def get_content(self, obj): - return u'' + return '' watson.register(Document, DocumentAdapter) diff --git a/docbow_project/docbow/notification.py b/docbow_project/docbow/notification.py index 322bb87..a1f9b4c 100644 --- a/docbow_project/docbow/notification.py +++ b/docbow_project/docbow/notification.py @@ -2,19 +2,18 @@ import importlib import logging from django.conf import settings -from django.template.loader import render_to_string, TemplateDoesNotExist from django.core.mail import EmailMultiAlternatives -from django.utils.translation import ugettext_lazy as _ -from django.utils.encoding import force_text +from django.template.loader import TemplateDoesNotExist, render_to_string +from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ from django_journal import journal as django_journal -from docbow_project.docbow import models -from docbow_project.docbow import app_settings +from docbow_project.docbow import app_settings, models logger = logging.getLogger(__name__) -class BaseNotifier(object): +class BaseNotifier: def __init__(self): # accumulate preferences of users first self.filter = set() @@ -106,7 +105,7 @@ class SMSNotifier(BaseNotifier): body_template = 'docbow/sms-notification_{kind}_body.txt' def __init__(self): - super(SMSNotifier, self).__init__() + super().__init__() self.mobile_phones = dict() def process(self, notification): @@ -175,7 +174,7 @@ def process_notifications(): notifier.process(notification) except Exception as e: failures.append( - u'Exception %r when handling with notifier %r' % (force_text(e), notifier.__class__) + 'Exception %r when handling with notifier %r' % (force_str(e), notifier.__class__) ) logger.exception( 'Exception when handling notification %r with notifier %r', notification, notifier @@ -203,5 +202,5 @@ def process_notifications(): 'error', 'unable to finish sending ' 'notification with notifier {notifier}, error: {error}', notifier=notifier.__class__, - error=force_text(e), + error=force_str(e), ) diff --git a/docbow_project/docbow/ods.py b/docbow_project/docbow/ods.py index af860b3..eb4840d 100644 --- a/docbow_project/docbow/ods.py +++ b/docbow_project/docbow/ods.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # w.c.s. - web application for online forms # Copyright (C) 2005-2013 Entr'ouvert @@ -27,8 +26,7 @@ except ImportError: ET = None -from django.utils.encoding import force_text - +from django.utils.encoding import force_str OFFICE_NS = 'urn:oasis:names:tc:opendocument:xmlns:office:1.0' TABLE_NS = 'urn:oasis:names:tc:opendocument:xmlns:table:1.0' @@ -36,7 +34,7 @@ TEXT_NS = 'urn:oasis:names:tc:opendocument:xmlns:text:1.0' XLINK_NS = 'http://www.w3.org/1999/xlink' -class Workbook(object): +class Workbook: def __init__(self, encoding='utf-8'): self.sheets = [] self.encoding = encoding @@ -83,14 +81,14 @@ class Workbook(object): z.close() -class WorkSheet(object): +class WorkSheet: def __init__(self, workbook, name): self.cells = {} self.name = name self.workbook = workbook def write(self, row, column, value, hint=None): - if not row in self.cells: + if row not in self.cells: self.cells[row] = {} self.cells[row][column] = WorkCell(self, value, hint=hint) @@ -109,10 +107,10 @@ class WorkSheet(object): return root -class WorkCell(object): +class WorkCell: def __init__(self, worksheet, value, hint=None): if type(value) is not str: - value = force_text(value, 'utf-8') + value = force_str(value, 'utf-8') self.value = value self.worksheet = worksheet self.hint = hint diff --git a/docbow_project/docbow/profile_views.py b/docbow_project/docbow/profile_views.py index 842b617..9c2d13d 100644 --- a/docbow_project/docbow/profile_views.py +++ b/docbow_project/docbow/profile_views.py @@ -1,24 +1,16 @@ import urllib.parse -from django.shortcuts import redirect -from django.views.generic.edit import UpdateView, FormView -from django.views.generic.base import TemplateResponseMixin, View from django.contrib import messages from django.contrib.auth.models import User from django.core.exceptions import ImproperlyConfigured -from django.utils.translation import ugettext as _ -from django.http import HttpResponseRedirect from django.db.transaction import atomic - +from django.http import HttpResponseRedirect +from django.utils.translation import gettext as _ +from django.views.generic.base import TemplateResponseMixin, View +from django.views.generic.edit import FormView, UpdateView from django_journal.models import Journal -import requests - -from docbow_project.docbow import models -from docbow_project.docbow import forms -from docbow_project.docbow import cbv -from docbow_project.docbow import utils -from docbow_project.docbow import app_settings +from docbow_project.docbow import app_settings, cbv, forms, models, utils class ProfileView(cbv.FormWithRequestMixin, cbv.FormWithPostTarget, UpdateView): @@ -38,7 +30,7 @@ class ProfileView(cbv.FormWithRequestMixin, cbv.FormWithPostTarget, UpdateView): def form_valid(self, form): self.request.record('update-profile', 'modified its profile', **form.cleaned_data) - return super(ProfileView, self).form_valid(form) + return super().form_valid(form) class DelegateView(cbv.FormWithPostTarget, FormView): @@ -48,7 +40,7 @@ class DelegateView(cbv.FormWithPostTarget, FormView): prefix = 'delegate' def __init__(self, *args, **kwargs): - super(DelegateView, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def add_journal_to_delegations(self, delegations): delegations__to = [delegation.to for delegation in delegations] @@ -75,7 +67,7 @@ class DelegateView(cbv.FormWithPostTarget, FormView): return qs def get_form_kwargs(self, **kwargs): - kwargs = super(DelegateView, self).get_form_kwargs(**kwargs) + kwargs = super().get_form_kwargs(**kwargs) kwargs['user'] = self.request.user kwargs['delegatees'] = [delegation.to for delegation in self.delegations] kwargs['request'] = self.request @@ -109,7 +101,6 @@ class DelegateView(cbv.FormWithPostTarget, FormView): # delete guest accounts if delegation.guest_delegate: - if 'mellon' in app_settings.settings.INSTALLED_APPS and delegate_user.saml_identifiers.count(): err, json_data, err_desc = utils.a2_wscall( urllib.parse.urljoin( @@ -135,17 +126,17 @@ class DelegateView(cbv.FormWithPostTarget, FormView): return True for delegation in self.delegations: username = delegation.to.username - if 'delegate-delete-{username}.x'.format(username=username) in self.request.POST: + if f'delegate-delete-{username}.x' in self.request.POST: return True return False @atomic def post(self, request, *args, **kwargs): if 'delegate-create' in request.POST: - return super(DelegateView, self).post(request, *args, **kwargs) + return super().post(request, *args, **kwargs) for delegation in self.delegations: username = delegation.to.username - if 'delegate-delete-{username}.x'.format(username=username) in self.request.POST: + if f'delegate-delete-{username}.x' in self.request.POST: return self.delete(delegation) return self.get(request, *args, **kwargs) @@ -226,10 +217,10 @@ class DelegateView(cbv.FormWithPostTarget, FormView): request.record( 'create-delegation', 'created delegation to ' 'user {delegated}', delegated=delegate_user ) - return super(DelegateView, self).form_valid(form) + return super().form_valid(form) def get_context_data(self, **kwargs): - ctx = super(DelegateView, self).get_context_data(**kwargs) + ctx = super().get_context_data(**kwargs) ctx['delegations'] = self.delegations ctx['received_delegations'] = self.request.user.delegations_by.all() ctx['delegate_to_existing_user'] = app_settings.DELEGATE_TO_EXISTING_USER @@ -248,10 +239,10 @@ class PasswordChangeView(cbv.FormWithPostTarget, FormView): def form_valid(self, form): messages.info(self.request, _('Password changed')) form.save() - return super(PasswordChangeView, self).form_valid(form) + return super().form_valid(form) def get_form_kwargs(self, **kwargs): - kwargs = super(PasswordChangeView, self).get_form_kwargs(**kwargs) + kwargs = super().get_form_kwargs(**kwargs) kwargs['user'] = self.request.user return kwargs @@ -268,7 +259,7 @@ class EmailView(cbv.FormWithPostTarget, UpdateView): def form_valid(self, form): messages.info(self.request, _('Email changed')) self.request.record('update-email', 'modified its email', **form.cleaned_data) - return super(EmailView, self).form_valid(form) + return super().form_valid(form) class NotificationPreferenceView(cbv.FormWithPostTarget, cbv.FormWithRequestMixin, FormView): @@ -280,16 +271,16 @@ class NotificationPreferenceView(cbv.FormWithPostTarget, cbv.FormWithRequestMixi def form_valid(self, form): form.save() messages.info(self.request, _('Notification preferences saved')) - return super(NotificationPreferenceView, self).form_valid(form) + return super().form_valid(form) def get_context_data(self, **kwargs): - ctx = super(NotificationPreferenceView, self).get_context_data(**kwargs) + ctx = super().get_context_data(**kwargs) ctx['mobile_phone'] = app_settings.MOBILE_PHONE ctx['mobile_phone_paragraph'] = _( - u'If You would like to receive a SMS alert each ' - u'time your inbox receives a document, provide your ' - u'mobile phone number. If you do not fill this field ' - u'you won\'t receive any SMS alert' + 'If You would like to receive a SMS alert each ' + 'time your inbox receives a document, provide your ' + 'mobile phone number. If you do not fill this field ' + 'you won\'t receive any SMS alert' ) return ctx @@ -312,7 +303,7 @@ class FullProfileView(TemplateResponseMixin, View): if models.is_guest(request.user): self.subviews = filter(lambda s: s[0] != 'delegate_form', self.subviews) print(self.subviews) - return super(FullProfileView, self).dispatch(request, *args, **kwargs) + return super().dispatch(request, *args, **kwargs) def post(self, request, *args, **kwargs): ctx = {} diff --git a/docbow_project/docbow/pyuca.py b/docbow_project/docbow/pyuca.py index e403b12..dead48a 100644 --- a/docbow_project/docbow/pyuca.py +++ b/docbow_project/docbow/pyuca.py @@ -72,7 +72,6 @@ class Trie: class Collator: def __init__(self, filename): - self.table = Trie() self.load(filename) @@ -109,7 +108,6 @@ class Collator: self.table.add(integer_points, collElements) def sort_key(self, string): - collation_elements = [] lookup_key = [ord(ch) for ch in string] diff --git a/docbow_project/docbow/signals.py b/docbow_project/docbow/signals.py index ce664ab..37811db 100644 --- a/docbow_project/docbow/signals.py +++ b/docbow_project/docbow/signals.py @@ -1,13 +1,13 @@ +from django.contrib.auth import models as auth_models from django.contrib.auth.models import User from django.contrib.auth.signals import user_logged_in, user_logged_out -from django.db.models.signals import post_save as db_post_save, m2m_changed -from django.contrib.auth import models as auth_models -from django.utils.translation import ugettext_noop as N_ +from django.db.models.signals import m2m_changed +from django.db.models.signals import post_save as db_post_save from django.dispatch import receiver +from django.utils.translation import gettext_noop as N_ from django_journal import journal as django_journal -from docbow_project.docbow import models -from docbow_project.docbow import middleware +from docbow_project.docbow import middleware, models def logged_in_handler(sender, request, user, **kwargs): diff --git a/docbow_project/docbow/sms_carrier_ovh.py b/docbow_project/docbow/sms_carrier_ovh.py index 8327369..50dbf77 100644 --- a/docbow_project/docbow/sms_carrier_ovh.py +++ b/docbow_project/docbow/sms_carrier_ovh.py @@ -1,22 +1,21 @@ -import logging import json - -from django.utils.http import urlencode +import logging from urllib.request import urlopen from django.conf import settings -from django.utils.encoding import force_text +from django.utils.encoding import force_str +from django.utils.http import urlencode from django_journal import journal as django_journal logger = logging.getLogger(__name__) -class OVHSMSCarrier(object): +class OVHSMSCarrier: URL = 'https://www.ovh.com/cgi-bin/sms/http2sms.cgi' SMS_CLASS = 1 def send_sms(self, to, message, sms_class=None, no_stop=True): - payload = force_text(message).encode('utf-8') + payload = force_str(message).encode('utf-8') sms_class = sms_class or self.SMS_CLASS to = ','.join([t.replace('+', '00') for t in to]) params = { diff --git a/docbow_project/docbow/static/error404.html b/docbow_project/docbow/static/error404.html index d31d516..8362db9 100644 --- a/docbow_project/docbow/static/error404.html +++ b/docbow_project/docbow/static/error404.html @@ -1,15 +1,15 @@ - - - Plate-forme sécurisée d'échange de documents — -Connexion - + + + Plate-forme sécurisée d'échange de documents — + Connexion + - -
-

Plate-forme sécurisée d'échange de documents

-

La page recherchée n'existes pas. Retournez à la page d'acceuil pour continuer votre navigation.

-
- + +
+

Plate-forme sécurisée d'échange de documents

+

La page recherchée n'existes pas. Retournez à la page d'acceuil pour continuer votre navigation.

+
+ diff --git a/docbow_project/docbow/static/error500.html b/docbow_project/docbow/static/error500.html index 7c11aea..dfe13a8 100644 --- a/docbow_project/docbow/static/error500.html +++ b/docbow_project/docbow/static/error500.html @@ -2,14 +2,14 @@ - - Plate-forme sécurisée d'échange de documents — -Connexion - + + Plate-forme sécurisée d'échange de documents — + Connexion + - -
-

Plate-forme sécurisée d'échange de documents

+ +
+

Plate-forme sécurisée d'échange de documents

-

Une erreur est survenue. Les équipes de maintenance de la plate-forme en ont -été avertie. Nous veillerons à la corriger dans les plus brefs délais.

-
- +

Une erreur est survenue. Les équipes de maintenance de la plate-forme en ont + été avertie. Nous veillerons à la corriger dans les plus brefs délais.

+
+ diff --git a/docbow_project/docbow/tables.py b/docbow_project/docbow/tables.py index c626f3d..aac2caf 100644 --- a/docbow_project/docbow/tables.py +++ b/docbow_project/docbow/tables.py @@ -1,10 +1,6 @@ -# -*- coding: utf-8 -*- -from django.utils.translation import ugettext_lazy as _ -from django.utils.safestring import mark_safe - - import django_tables2 as tables - +from django.utils.safestring import mark_safe +from django.utils.translation import gettext_lazy as _ from docbow_project.docbow import models @@ -72,7 +68,6 @@ class OutboxBaseTable(tables.Table): class OutboxTrashTable(OutboxBaseTable): - restore = tables.TemplateColumn( template_name='docbow/outbox_restore_column.html', orderable=False, verbose_name=_('Restore') ) @@ -133,7 +128,7 @@ class InboxCsvTable(tables.Table): class InboxBaseTable(tables.Table): - seen = tables.BooleanColumn(accessor='seen', yesno=u' ,✔', verbose_name=' ', orderable=False) + seen = tables.BooleanColumn(accessor='seen', yesno=' ,✔', verbose_name=' ', orderable=False) filetype = tables.Column(accessor='filetype', verbose_name=_('type_header')) filenames = tables.Column(accessor='filenames', verbose_name=_('filename_header'), orderable=False) recipients = tables.TemplateColumn( @@ -167,7 +162,6 @@ class InboxBaseTable(tables.Table): class InboxTrashTable(InboxBaseTable): - restore = tables.TemplateColumn( template_name='docbow/inbox_restore_column.html', orderable=False, verbose_name=_('Restore') ) diff --git a/docbow_project/docbow/templates/404.html b/docbow_project/docbow/templates/404.html index b8b55cf..10e6104 100644 --- a/docbow_project/docbow/templates/404.html +++ b/docbow_project/docbow/templates/404.html @@ -1,5 +1,5 @@ {% include "base.html" %} {% block content %} -Page introuvable + Page introuvable {% endblock %} diff --git a/docbow_project/docbow/templates/admin/auth/docbowuser/change_form.html b/docbow_project/docbow/templates/admin/auth/docbowuser/change_form.html index a165624..e139a71 100644 --- a/docbow_project/docbow/templates/admin/auth/docbowuser/change_form.html +++ b/docbow_project/docbow/templates/admin/auth/docbowuser/change_form.html @@ -1,11 +1,11 @@ {% extends "admin/change_form.html" %} {% load i18n %} {% block object-tools %} -{% if change %}{% if not is_popup %} - -{% endif %}{% endif %} + {% if change %}{% if not is_popup %} + + {% endif %}{% endif %} {% endblock %} diff --git a/docbow_project/docbow/templates/base.html b/docbow_project/docbow/templates/base.html index 68c1c6d..da3545d 100644 --- a/docbow_project/docbow/templates/base.html +++ b/docbow_project/docbow/templates/base.html @@ -2,19 +2,19 @@ {% load i18n %} {% block rawcontent %} -{% if messages %} -
    - {% for message in messages %} - {{ message }} - {% endfor %} -
- -{% endif %} -
-

{% trans "site_title" %}

- {% block content %} - {% endblock %} -
+ {% if messages %} +
    + {% for message in messages %} + {{ message }} + {% endfor %} +
+ + {% endif %} +
+

{% trans "site_title" %}

+ {% block content %} + {% endblock %} +
{% endblock %} diff --git a/docbow_project/docbow/templates/base_raw.html b/docbow_project/docbow/templates/base_raw.html index 096b75a..69f55de 100644 --- a/docbow_project/docbow/templates/base_raw.html +++ b/docbow_project/docbow/templates/base_raw.html @@ -1,24 +1,24 @@ {% load i18n %} +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - + {% trans "site_title" %} — {% block title %}{% endblock %} {% block jquery_script %} - + {% endblock %} {% block extra_scripts %} {% endblock %} - + - -{% block rawcontent %} -{% endblock %} -{% block endscripts %} -{% endblock %} - + + {% block rawcontent %} + {% endblock %} + {% block endscripts %} + {% endblock %} + diff --git a/docbow_project/docbow/templates/docbow/base_user.html b/docbow_project/docbow/templates/docbow/base_user.html index 537cc65..f56b744 100644 --- a/docbow_project/docbow/templates/docbow/base_user.html +++ b/docbow_project/docbow/templates/docbow/base_user.html @@ -3,50 +3,50 @@ {% load docbow %} {% block rawcontent %} -
-