From: Jan Szejko Date: Fri, 1 Jul 2016 12:26:27 +0000 (+0200) Subject: style X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/1c4c468783e5f380324c29ebc3b2c452da8cc2a0 style --- diff --git a/NOTICE b/NOTICE index 815f1c90..c99b6d86 100644 --- a/NOTICE +++ b/NOTICE @@ -1,9 +1,9 @@ - + FNP Redakcja Copyright © 2010 Fundacja Nowoczesna Polska - - For full list of contributors see AUTHORS file. + + For full list of contributors see AUTHORS file. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by diff --git a/README.md b/README.md index 93ffb1c4..64cebfb4 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,3 @@ JavaScript (wymagany node.js i xsltproc): $ npm install $ ./node_modules/.bin/mocha -u tdd $(find -name *_test.js) - \ No newline at end of file diff --git a/apps/apiclient/models.py b/apps/apiclient/models.py index d3c8f620..b311878c 100644 --- a/apps/apiclient/models.py +++ b/apps/apiclient/models.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django.db import models from django.contrib.auth.models import User @@ -16,5 +17,3 @@ class OAuthConnection(models.Model): o = cls(user=user) o.save() return o - - diff --git a/apps/apiclient/tests.py b/apps/apiclient/tests.py index 2247054b..13cd4a50 100644 --- a/apps/apiclient/tests.py +++ b/apps/apiclient/tests.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ This file demonstrates two different styles of tests (one doctest and one unittest). These will both pass when you run "manage.py test". @@ -7,6 +8,7 @@ Replace these with more appropriate tests for your application. from django.test import TestCase + class SimpleTest(TestCase): def test_basic_addition(self): """ @@ -20,4 +22,3 @@ Another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 True """} - diff --git a/apps/apiclient/urls.py b/apps/apiclient/urls.py index 55cc4669..4a323075 100755 --- a/apps/apiclient/urls.py +++ b/apps/apiclient/urls.py @@ -1,6 +1,8 @@ +# -*- coding: utf-8 -*- from django.conf.urls import patterns, url -urlpatterns = patterns('apiclient.views', +urlpatterns = patterns( + 'apiclient.views', url(r'^oauth/$', 'oauth', name='apiclient_oauth'), url(r'^oauth_callback/$', 'oauth_callback', name='apiclient_oauth_callback'), ) diff --git a/apps/apiclient/views.py b/apps/apiclient/views.py index 88f4b49b..0dbaf5ac 100644 --- a/apps/apiclient/views.py +++ b/apps/apiclient/views.py @@ -22,7 +22,7 @@ def oauth(request): raise Exception("Invalid response %s." % resp['status']) request_token = dict(urlparse.parse_qsl(content)) - + conn = OAuthConnection.get(request.user) # this might reset existing auth! conn.access = False @@ -31,7 +31,7 @@ def oauth(request): conn.save() url = "%s?oauth_token=%s&oauth_callback=%s" % ( - WL_AUTHORIZE_URL, + WL_AUTHORIZE_URL, request_token['oauth_token'], request.build_absolute_uri(reverse("apiclient_oauth_callback")), ) diff --git a/apps/build/management/commands/build.py b/apps/build/management/commands/build.py index 50097cff..c2751442 100644 --- a/apps/build/management/commands/build.py +++ b/apps/build/management/commands/build.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os from subprocess import call from optparse import make_option @@ -7,27 +8,31 @@ from django.core.management import call_command class Command(BaseCommand): - + option_list = BaseCommand.option_list + ( - make_option('--node-bin-path', + make_option( + '--node-bin-path', action='store', dest='node_bin_path', type='string', default=None, help='Path to node binary'), - make_option('--npm-bin', + make_option( + '--npm-bin', action='store', dest='npm_bin', type='string', default='npm', help='Path to npm binary'), - make_option('--editor-npm-env', + make_option( + '--editor-npm-env', action='store', dest='editor_npm_env', type='string', default=None, help='Destination path of npm environment, defaults to ./node_modules'), - make_option('--editor-optimize', + make_option( + '--editor-optimize', action='store', dest='editor_optimize', type='string', @@ -48,7 +53,7 @@ class Command(BaseCommand): assert os.path.isdir(npm_env) os.symlink(npm_env, os.path.join(rng_base_dir, 'node_modules')) try: - call([options['npm_bin'], 'install'], cwd = rng_base_dir) + call([options['npm_bin'], 'install'], cwd=rng_base_dir) except OSError: raise CommandError('Something went wrong, propably npm binary not found. Tried: %s' % options['npm_bin']) @@ -56,9 +61,9 @@ class Command(BaseCommand): if options['node_bin_path']: # grunt needs npm binary to be foundable in PATH os.environ['PATH'] = '%s:%s' % (options['node_bin_path'], os.environ['PATH']) - args = ['./node_modules/.bin/grunt', 'build', '--output-dir=%s' % build_dir] + args = ['./node_modules/.bin/grunt', 'build', '--output-dir=%s' % build_dir] if options['editor_optimize']: args.append('--optimize=%s' % options['editor_optimize']) - call(args, cwd = rng_base_dir) + call(args, cwd=rng_base_dir) - call_command('collectstatic', interactive = False, ignore_patterns = ['editor']) + call_command('collectstatic', interactive=False, ignore_patterns=['editor']) diff --git a/apps/catalogue/__init__.py b/apps/catalogue/__init__.py index c53f0e73..9012566c 100644 --- a/apps/catalogue/__init__.py +++ b/apps/catalogue/__init__.py @@ -1 +1 @@ - # pragma: no cover +# pragma: no cover diff --git a/apps/catalogue/admin.py b/apps/catalogue/admin.py index f8cda9fe..ff7f18da 100644 --- a/apps/catalogue/admin.py +++ b/apps/catalogue/admin.py @@ -1,7 +1,9 @@ +# -*- coding: utf-8 -*- from django.contrib import admin from catalogue import models + class BookAdmin(admin.ModelAdmin): list_display = ['title', 'public', '_published', '_new_publishable', 'project'] list_filter = ['public', '_published', '_new_publishable', 'project'] diff --git a/apps/catalogue/constants.py b/apps/catalogue/constants.py index 0c842324..2f479164 100644 --- a/apps/catalogue/constants.py +++ b/apps/catalogue/constants.py @@ -6,11 +6,12 @@ TRIM_BEGIN = " TRIM_BEGIN " TRIM_END = " TRIM_END " -MASTERS = ['powiesc', - 'opowiadanie', - 'liryka_l', - 'liryka_lp', - 'dramat_wierszowany_l', - 'dramat_wierszowany_lp', - 'dramat_wspolczesny', - ] +MASTERS = [ + 'powiesc', + 'opowiadanie', + 'liryka_l', + 'liryka_lp', + 'dramat_wierszowany_l', + 'dramat_wierszowany_lp', + 'dramat_wspolczesny', +] diff --git a/apps/catalogue/ebook_utils.py b/apps/catalogue/ebook_utils.py index c16b2958..8b7d80f0 100644 --- a/apps/catalogue/ebook_utils.py +++ b/apps/catalogue/ebook_utils.py @@ -11,9 +11,8 @@ class RedakcjaDocProvider(DocProvider): self.publishable = publishable def by_slug(self, slug): - return IOFile.from_string(Book.objects.get(dc_slug=slug - ).materialize(publishable=self.publishable - ).encode('utf-8')) + return IOFile.from_string( + Book.objects.get(dc_slug=slug).materialize(publishable=self.publishable).encode('utf-8')) def serve_file(file_path, name, mime_type): diff --git a/apps/catalogue/feeds.py b/apps/catalogue/feeds.py index 4884a4cd..1eb421b0 100644 --- a/apps/catalogue/feeds.py +++ b/apps/catalogue/feeds.py @@ -3,6 +3,7 @@ from django.contrib.syndication.views import Feed from django.shortcuts import get_object_or_404 from catalogue.models import Book, Chunk + class PublishTrackFeed(Feed): title = u"Planowane publikacje" link = "/" @@ -22,8 +23,7 @@ class PublishTrackFeed(Feed): def items(self, obj): tag, published = obj - books = Book.objects.filter(public=True, _on_track__gte=tag.ordering - ).order_by('-_on_track', 'title') + books = Book.objects.filter(public=True, _on_track__gte=tag.ordering).order_by('-_on_track', 'title') if published is not None: books = books.filter(_published=published) return books diff --git a/apps/catalogue/forms.py b/apps/catalogue/forms.py index 85f92efc..7830b4f9 100644 --- a/apps/catalogue/forms.py +++ b/apps/catalogue/forms.py @@ -11,6 +11,7 @@ from django.utils.translation import ugettext_lazy as _ from catalogue.constants import MASTERS from catalogue.models import Book, Chunk, Template + class DocumentCreateForm(forms.ModelForm): """ Form used for creating new documents. @@ -23,8 +24,8 @@ class DocumentCreateForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(DocumentCreateForm, self).__init__(*args, **kwargs) - self.fields['slug'].widget.attrs={'class': 'autoslug'} - self.fields['title'].widget.attrs={'class': 'autoslug-source'} + self.fields['slug'].widget.attrs = {'class': 'autoslug'} + self.fields['title'].widget.attrs = {'class': 'autoslug-source'} self.fields['template'].queryset = Template.objects.filter(is_main=True) def clean(self): @@ -46,15 +47,16 @@ class DocumentsUploadForm(forms.Form): Form used for uploading new documents. """ file = forms.FileField(required=True, label=_('ZIP file')) - dirs = forms.BooleanField(label=_('Directories are documents in chunks'), - widget = forms.CheckboxInput(attrs={'disabled':'disabled'})) + dirs = forms.BooleanField( + label=_('Directories are documents in chunks'), + widget=forms.CheckboxInput(attrs={'disabled': 'disabled'})) def clean(self): - file = self.cleaned_data['file'] + zip_file = self.cleaned_data['zip_file'] import zipfile try: - z = self.cleaned_data['zip'] = zipfile.ZipFile(file) + z = self.cleaned_data['zip'] = zipfile.ZipFile(zip_file) except zipfile.BadZipfile: raise forms.ValidationError("Should be a ZIP file.") if z.testzip(): @@ -67,10 +69,10 @@ class ChunkForm(forms.ModelForm): """ Form used for editing a chunk. """ - user = forms.ModelChoiceField(queryset= - User.objects.annotate(count=Count('chunk')). - order_by('last_name', 'first_name'), required=False, - label=_('Assigned to')) + user = forms.ModelChoiceField( + queryset=User.objects.annotate(count=Count('chunk')).order_by('last_name', 'first_name'), + required=False, + label=_('Assigned to')) class Meta: model = Chunk @@ -79,9 +81,9 @@ class ChunkForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(ChunkForm, self).__init__(*args, **kwargs) - self.fields['gallery_start'].widget.attrs={'class': 'number-input'} - self.fields['slug'].widget.attrs={'class': 'autoslug'} - self.fields['title'].widget.attrs={'class': 'autoslug-source'} + self.fields['gallery_start'].widget.attrs = {'class': 'number-input'} + self.fields['slug'].widget.attrs = {'class': 'autoslug'} + self.fields['title'].widget.attrs = {'class': 'autoslug-source'} def clean_slug(self): slug = self.cleaned_data['slug'] @@ -113,13 +115,11 @@ class BookAppendForm(forms.Form): Form for appending a book to another book. It means moving all chunks from book A to book B and deleting A. """ - append_to = forms.ModelChoiceField(queryset=Book.objects.all(), - label=_("Append to")) + append_to = forms.ModelChoiceField(queryset=Book.objects.all(), label=_("Append to")) def __init__(self, book, *args, **kwargs): - ret = super(BookAppendForm, self).__init__(*args, **kwargs) + super(BookAppendForm, self).__init__(*args, **kwargs) self.fields['append_to'].queryset = Book.objects.exclude(pk=book.pk) - return ret class BookForm(forms.ModelForm): @@ -130,20 +130,18 @@ class BookForm(forms.ModelForm): exclude = ['project'] def __init__(self, *args, **kwargs): - ret = super(BookForm, self).__init__(*args, **kwargs) + super(BookForm, self).__init__(*args, **kwargs) self.fields['slug'].widget.attrs.update({"class": "autoslug"}) self.fields['title'].widget.attrs.update({"class": "autoslug-source"}) - return ret class ReadonlyBookForm(BookForm): """Form used for not editing a Book.""" def __init__(self, *args, **kwargs): - ret = super(ReadonlyBookForm, self).__init__(*args, **kwargs) + super(ReadonlyBookForm, self).__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs.update({"readonly": True}) - return ret class ChooseMasterForm(forms.Form): diff --git a/apps/catalogue/management/commands/__init__.py b/apps/catalogue/management/commands/__init__.py index e6f146f8..d3792afa 100644 --- a/apps/catalogue/management/commands/__init__.py +++ b/apps/catalogue/management/commands/__init__.py @@ -16,15 +16,20 @@ class XmlUpdaterCommand(BaseCommand): In a subclass, provide an XmlUpdater class in the `updater' attribute. """ option_list = BaseCommand.option_list + ( - make_option('-q', '--quiet', action='store_false', dest='verbose', + make_option( + '-q', '--quiet', action='store_false', dest='verbose', default=True, help='Less output'), - make_option('-d', '--dry-run', action='store_true', dest='dry_run', + make_option( + '-d', '--dry-run', action='store_true', dest='dry_run', default=False, help="Don't actually touch anything"), - make_option('-u', '--username', dest='username', metavar='USER', + make_option( + '-u', '--username', dest='username', metavar='USER', help='Assign commits to this user (required, preferably yourself).'), ) args = "[slug]..." + updater = NotImplemented + def handle(self, *args, **options): verbose = options.get('verbose') dry_run = options.get('dry_run') diff --git a/apps/catalogue/management/commands/assign_from_redmine.py b/apps/catalogue/management/commands/assign_from_redmine.py index 9f7b12d4..234795c8 100644 --- a/apps/catalogue/management/commands/assign_from_redmine.py +++ b/apps/catalogue/management/commands/assign_from_redmine.py @@ -3,7 +3,6 @@ import csv from optparse import make_option import re -import sys import urllib import urllib2 @@ -22,12 +21,15 @@ REDAKCJA_URL = 'http://redakcja.wolnelektury.pl/documents/' class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('-r', '--redakcja', dest='redakcja', metavar='URL', + make_option( + '-r', '--redakcja', dest='redakcja', metavar='URL', help='Base URL of Redakcja documents', default=REDAKCJA_URL), - make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, + make_option( + '-q', '--quiet', action='store_false', dest='verbose', default=True, help='Less output'), - make_option('-f', '--force', action='store_true', dest='force', default=False, + make_option( + '-f', '--force', action='store_true', dest='force', default=False, help='Force assignment overwrite'), ) help = 'Imports ticket assignments from Redmine.' @@ -123,7 +125,6 @@ class Command(BaseCommand): if ticket_done: done_tickets += 1 - # Print results print print "Results:" @@ -147,7 +148,5 @@ class Command(BaseCommand): print " %s (%d tickets)" % (name, unknown_users[name]) print - transaction.commit() transaction.leave_transaction_management() - diff --git a/apps/catalogue/management/commands/fixdc.py b/apps/catalogue/management/commands/fixdc.py index 3f997d0c..564773e9 100644 --- a/apps/catalogue/management/commands/fixdc.py +++ b/apps/catalogue/management/commands/fixdc.py @@ -9,32 +9,35 @@ from catalogue.management import XmlUpdater from catalogue.management.commands import XmlUpdaterCommand +def fix_wluri(elem, change, verbose): + try: + WLURI.strict(elem.text) + except ValidationError: + correct_field = unicode(WLURI.from_slug( + WLURI(elem.text.strip()).slug)) + try: + WLURI.strict(correct_field) + except ValidationError: + # Can't make a valid WLURI out of it, leave as is. + return False + if verbose: + print "Changing %s from %s to %s" % ( + elem.tag, elem.text, correct_field + ) + elem.text = correct_field + return True + + class FixDC(XmlUpdater): commit_desc = "auto-fixing DC" retain_publishable = True only_first_chunk = True - def fix_wluri(elem, change, verbose): - try: - WLURI.strict(elem.text) - except ValidationError: - correct_field = unicode(WLURI.from_slug( - WLURI(elem.text.strip()).slug)) - try: - WLURI.strict(correct_field) - except ValidationError: - # Can't make a valid WLURI out of it, leave as is. - return False - if verbose: - print "Changing %s from %s to %s" % ( - elem.tag, elem.text, correct_field - ) - elem.text = correct_field - return True for field in BookInfo.FIELDS: if field.validator == WLURI: XmlUpdater.fixes_elements('.//' + field.uri)(fix_wluri) + # unused @XmlUpdater.fixes_elements(".//" + RDFNS("Description")) def fix_rdfabout(elem, change, verbose): correct_about = change.tree.book.correct_about() diff --git a/apps/catalogue/management/commands/import_wl.py b/apps/catalogue/management/commands/import_wl.py index 5f603883..8991c3a3 100644 --- a/apps/catalogue/management/commands/import_wl.py +++ b/apps/catalogue/management/commands/import_wl.py @@ -19,8 +19,7 @@ WL_API = 'http://www.wolnelektury.pl/api/books/' class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help='Less output'), + make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, help='Less output'), ) help = 'Imports XML files from WL.' @@ -65,15 +64,15 @@ class Command(BaseCommand): previous_books = slugs.get(info.slug) if previous_books: if len(previous_books) > 1: - print self.style.ERROR("There is more than one book " - "with slug %s:"), + print self.style.ERROR("There is more than one book with slug %s:"), previous_book = previous_books[0] comm = previous_book.slug else: previous_book = None comm = '*' - print book_count, info.slug , '-->', comm - Book.import_xml_text(xml_text, title=info.title[:255], + print book_count, info.slug, '-->', comm + Book.import_xml_text( + xml_text, title=info.title[:255], slug=info.slug[:128], previous_book=previous_book, commit_args=commit_args) book_count += 1 @@ -85,7 +84,5 @@ class Command(BaseCommand): book_count, ) print - transaction.commit() transaction.leave_transaction_management() - diff --git a/apps/catalogue/management/commands/merge_books.py b/apps/catalogue/management/commands/merge_books.py index aec113ed..d1482667 100644 --- a/apps/catalogue/management/commands/merge_books.py +++ b/apps/catalogue/management/commands/merge_books.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- from optparse import make_option -import sys -from django.contrib.auth.models import User from django.core.management.base import BaseCommand from django.core.management.color import color_style from django.db import transaction -from slughifi import slughifi from catalogue.models import Book @@ -26,34 +23,40 @@ def common_prefix(texts): class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('-s', '--slug', dest='new_slug', metavar='SLUG', + make_option( + '-s', '--slug', dest='new_slug', metavar='SLUG', help='New slug of the merged book (defaults to common part of all slugs).'), - make_option('-t', '--title', dest='new_title', metavar='TITLE', + make_option( + '-t', '--title', dest='new_title', metavar='TITLE', help='New title of the merged book (defaults to common part of all titles).'), - make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, + make_option( + '-q', '--quiet', action='store_false', dest='verbose', default=True, help='Less output'), - make_option('-g', '--guess', action='store_true', dest='guess', default=False, + make_option( + '-g', '--guess', action='store_true', dest='guess', default=False, help='Try to guess what merges are needed (but do not apply them).'), - make_option('-d', '--dry-run', action='store_true', dest='dry_run', default=False, + make_option( + '-d', '--dry-run', action='store_true', dest='dry_run', default=False, help='Dry run: do not actually change anything.'), - make_option('-f', '--force', action='store_true', dest='force', default=False, + make_option( + '-f', '--force', action='store_true', dest='force', default=False, help='On slug conflict, hide the original book to archive.'), ) help = 'Merges multiple books into one.' args = '[slug]...' - def print_guess(self, dry_run=True, force=False): from collections import defaultdict from pipes import quote import re - + def read_slug(slug): - res = [] - res.append((re.compile(ur'__?(przedmowa)$'), -1)) - res.append((re.compile(ur'__?(cz(esc)?|ksiega|rozdzial)__?(?P\d*)$'), None)) - res.append((re.compile(ur'__?(rozdzialy__?)?(?P\d*)-'), None)) - + res = [ + (re.compile(ur'__?(przedmowa)$'), -1), + (re.compile(ur'__?(cz(esc)?|ksiega|rozdzial)__?(?P\d*)$'), None), + (re.compile(ur'__?(rozdzialy__?)?(?P\d*)-'), None), + ] + for r, default in res: m = r.search(slug) if m: @@ -63,12 +66,12 @@ class Command(BaseCommand): except IndexError: return default, slug[:start] return None, slug - + def file_to_title(fname): """ Returns a title-like version of a filename. """ parts = (p.replace('_', ' ').title() for p in fname.split('__')) return ' / '.join(parts) - + merges = defaultdict(list) slugs = [] for b in Book.objects.all(): @@ -76,17 +79,17 @@ class Command(BaseCommand): n, ns = read_slug(b.slug) if n is not None: merges[ns].append((n, b)) - + conflicting_slugs = [] for slug in sorted(merges.keys()): merge_list = sorted(merges[slug]) if len(merge_list) < 2: continue - + merge_slugs = [b.slug for i, b in merge_list] if slug in slugs and slug not in merge_slugs: conflicting_slugs.append(slug) - + title = file_to_title(slug) print "./manage.py merge_books %s%s--title=%s --slug=%s \\\n %s\n" % ( '--dry-run ' if dry_run else '', @@ -94,7 +97,7 @@ class Command(BaseCommand): quote(title), slug, " \\\n ".join(merge_slugs) ) - + if conflicting_slugs: if force: print self.style.NOTICE('# These books will be archived:') @@ -103,9 +106,7 @@ class Command(BaseCommand): for slug in conflicting_slugs: print '#', slug - def handle(self, *slugs, **options): - self.style = color_style() force = options.get('force') @@ -148,7 +149,6 @@ class Command(BaseCommand): if slugs[0] != new_slug and Book.objects.filter(slug=new_slug).exists(): self.style.ERROR('Book already exists, skipping!') - if dry_run and verbose: print self.style.NOTICE('DRY RUN: nothing will be changed.') print @@ -212,7 +212,5 @@ class Command(BaseCommand): chunk.slug = chunk_slugs[j] chunk.save() - transaction.commit() transaction.leave_transaction_management() - diff --git a/apps/catalogue/managers.py b/apps/catalogue/managers.py index 4f804b84..0097cb32 100644 --- a/apps/catalogue/managers.py +++ b/apps/catalogue/managers.py @@ -1,5 +1,7 @@ +# -*- coding: utf-8 -*- from django.db import models + class VisibleManager(models.Manager): def get_query_set(self): return super(VisibleManager, self).get_query_set().exclude(_hidden=True) diff --git a/apps/catalogue/models/__init__.py b/apps/catalogue/models/__init__.py index faa2d384..c08246e8 100755 --- a/apps/catalogue/models/__init__.py +++ b/apps/catalogue/models/__init__.py @@ -12,6 +12,7 @@ from catalogue.models.listeners import * from django.contrib.auth.models import User as AuthUser + class User(AuthUser): class Meta: proxy = True diff --git a/apps/catalogue/models/book.py b/apps/catalogue/models/book.py index 83db3057..6f47642c 100755 --- a/apps/catalogue/models/book.py +++ b/apps/catalogue/models/book.py @@ -137,7 +137,7 @@ class Book(models.Model): return instance def make_chunk_slug(self, proposed): - """ + """ Finds a chunk slug not yet used in the book. """ slugs = set(c.slug for c in self) @@ -200,10 +200,10 @@ class Book(models.Model): # and move the gallery starts if gm.was_merged: - for chunk in self[len(self) - len_other:]: - old_start = chunk.gallery_start or 1 - chunk.gallery_start = old_start + gm.dest_size - gm.num_deleted - chunk.save() + for chunk in self[len(self) - len_other:]: + old_start = chunk.gallery_start or 1 + chunk.gallery_start = old_start + gm.dest_size - gm.num_deleted + chunk.save() other.delete() @@ -388,7 +388,7 @@ class Book(models.Model): return changes def materialize(self, publishable=False, changes=None): - """ + """ Get full text of the document compiled from chunks. Takes the current versions of all texts or versions most recently tagged for publishing, diff --git a/apps/catalogue/models/chunk.py b/apps/catalogue/models/chunk.py index 70e185bb..b8c5674a 100755 --- a/apps/catalogue/models/chunk.py +++ b/apps/catalogue/models/chunk.py @@ -53,7 +53,7 @@ class Chunk(dvcs_models.Document): @models.permalink def get_absolute_url(self): - return ("wiki_editor", [self.book.slug, self.slug]) + return "wiki_editor", [self.book.slug, self.slug] def pretty_name(self, book_length=None): title = self.book.title @@ -63,7 +63,6 @@ class Chunk(dvcs_models.Document): title += " (%d/%d)" % (self.number, book_length) return title - # Creating and manipulation # ========================= @@ -75,8 +74,8 @@ class Chunk(dvcs_models.Document): while not new_chunk: new_slug = self.book.make_chunk_slug(slug) try: - new_chunk = self.book.chunk_set.create(number=self.number+1, - slug=new_slug[:50], title=title[:255], **kwargs) + new_chunk = self.book.chunk_set.create( + number=self.number+1, slug=new_slug[:50], title=title[:255], **kwargs) except IntegrityError: pass return new_chunk @@ -88,7 +87,6 @@ class Chunk(dvcs_models.Document): else: return cls.objects.get(book__slug=book_slug, slug=chunk_slug) - # State & cache # ============= @@ -124,6 +122,6 @@ class Chunk(dvcs_models.Document): def refresh(self): """This should be done offline.""" - self.changed - self.hidden - self.short_html + self.changed() + self.hidden() + self.short_html() diff --git a/apps/catalogue/models/listeners.py b/apps/catalogue/models/listeners.py index 532f1e79..b40cdc28 100755 --- a/apps/catalogue/models/listeners.py +++ b/apps/catalogue/models/listeners.py @@ -50,4 +50,3 @@ def listener_create(sender, instance, created, **kwargs): if created: instance.chunk_set.create(number=1, slug='1') models.signals.post_save.connect(listener_create, sender=Book) - diff --git a/apps/catalogue/models/template.py b/apps/catalogue/models/template.py index dded859e..f4056fc7 100644 --- a/apps/catalogue/models/template.py +++ b/apps/catalogue/models/template.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django.db import models diff --git a/apps/catalogue/signals.py b/apps/catalogue/signals.py index 62ca5145..c161147e 100644 --- a/apps/catalogue/signals.py +++ b/apps/catalogue/signals.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django.dispatch import Signal post_publish = Signal() diff --git a/apps/catalogue/tasks.py b/apps/catalogue/tasks.py index c386c22b..d71542c3 100644 --- a/apps/catalogue/tasks.py +++ b/apps/catalogue/tasks.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from celery.task import task from django.utils import translation @@ -11,6 +12,7 @@ def _refresh_by_pk(cls, pk, language=None): finally: translation.activate(prev_language) + def refresh_instance(instance): _refresh_by_pk.delay(type(instance), instance.pk, translation.get_language()) diff --git a/apps/catalogue/templatetags/book_list.py b/apps/catalogue/templatetags/book_list.py index 14149e84..6e64ed61 100755 --- a/apps/catalogue/templatetags/book_list.py +++ b/apps/catalogue/templatetags/book_list.py @@ -1,6 +1,6 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import -from re import split from django.db.models import Q, Count from django import template from django.utils.translation import ugettext_lazy as _ @@ -12,10 +12,10 @@ register = template.Library() class ChunksList(object): def __init__(self, chunk_qs): - #self.chunk_qs = chunk_qs#.annotate( - #book_length=Count('book__chunk')).select_related( - #'book')#, 'stage__name', - #'user') + # self.chunk_qs = chunk_qs#.annotate( + # book_length=Count('book__chunk')).select_related( + # 'book')#, 'stage__name', + # 'user') self.chunk_qs = chunk_qs.select_related('book__hidden') self.book_qs = chunk_qs.values('book_id') @@ -111,7 +111,7 @@ def document_list_filter(request, **kwargs): chunks = chunks.filter(_states_dict[state]) chunks = foreign_filter(chunks, arg_or_GET('user'), 'user', User, 'username') - chunks = foreign_filter(chunks, arg_or_GET('stage'), 'stage', Chunk.tag_model, 'slug') + chunks = foreign_filter(chunks, arg_or_GET('stage'), 'stage', Chunk.tag_model) chunks = search_filter(chunks, arg_or_GET('title'), ['book__title', 'title']) chunks = foreign_filter(chunks, arg_or_GET('project'), 'book__project', Project, 'pk') return chunks diff --git a/apps/catalogue/templatetags/catalogue.py b/apps/catalogue/templatetags/catalogue.py index 7f372f7d..2ff6f3de 100644 --- a/apps/catalogue/templatetags/catalogue.py +++ b/apps/catalogue/templatetags/catalogue.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import from django.core.urlresolvers import reverse @@ -39,4 +40,3 @@ def main_tabs(context): @register.filter def nice_name(user): return user.get_full_name() or user.username - diff --git a/apps/catalogue/templatetags/common_tags.py b/apps/catalogue/templatetags/common_tags.py index ccaf03bf..b547801d 100755 --- a/apps/catalogue/templatetags/common_tags.py +++ b/apps/catalogue/templatetags/common_tags.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django import template register = template.Library() diff --git a/apps/catalogue/templatetags/set_get_parameter.py b/apps/catalogue/templatetags/set_get_parameter.py index b3d44d73..d4e1a88f 100755 --- a/apps/catalogue/templatetags/set_get_parameter.py +++ b/apps/catalogue/templatetags/set_get_parameter.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from re import split from django import template @@ -21,7 +22,7 @@ Using 'django.core.context_processors.request' is required. class SetGetParameter(template.Node): def __init__(self, values): self.values = values - + def render(self, context): request = template.Variable('request').resolve(context) params = request.GET.copy() @@ -31,7 +32,7 @@ class SetGetParameter(template.Node): del(params[key]) else: params[key] = template.Variable(value).resolve(context) - return '?%s' % params.urlencode() + return '?%s' % params.urlencode() @register.tag diff --git a/apps/catalogue/templatetags/wall.py b/apps/catalogue/templatetags/wall.py index 28671fb7..9b607e47 100755 --- a/apps/catalogue/templatetags/wall.py +++ b/apps/catalogue/templatetags/wall.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import from datetime import timedelta @@ -44,15 +45,14 @@ def changes_wall(user=None, max_len=None, day=None): for item in qs: tag = 'stage' if item.tags.count() else 'change' chunk = item.tree - w = WallItem(tag) + w = WallItem(tag) if user and item.author != user: w.header = _('Related edit') else: w.header = _('Edit') w.title = chunk.pretty_name() w.summary = item.description - w.url = reverse('wiki_editor', - args=[chunk.book.slug, chunk.slug]) + '?diff=%d' % item.revision + w.url = reverse('wiki_editor', args=[chunk.book.slug, chunk.slug]) + '?diff=%d' % item.revision w.timestamp = item.created_at w.user = item.author w.user_name = item.author_name @@ -95,7 +95,7 @@ def comments_wall(user=None, max_len=None, day=None): next_day = day + timedelta(1) qs = qs.filter(submit_date__gte=day, submit_date__lt=next_day) for item in qs: - w = WallItem('comment') + w = WallItem('comment') w.header = _('Comment') w.title = item.content_object w.summary = item.comment @@ -143,6 +143,7 @@ def wall(context, user=None, max_len=100): comments_wall(user, max_len), ], max_len)} + @register.inclusion_tag("catalogue/wall.html", takes_context=True) def day_wall(context, day): return { diff --git a/apps/catalogue/tests/book.py b/apps/catalogue/tests/book.py index df6f3b4f..4138b8f1 100644 --- a/apps/catalogue/tests/book.py +++ b/apps/catalogue/tests/book.py @@ -42,13 +42,11 @@ class ManipulationTests(TestCase): self.assertEqual(self.book2.materialize(), 'book 2') def test_split_book(self): - self.book1.chunk_set.create(number=2, title='Second chunk', - slug='book3') + self.book1.chunk_set.create(number=2, title='Second chunk', slug='book3') self.book1[1].commit('I survived!') self.assertEqual(len(self.book1), 2) self.book1.split() - self.assertEqual(set([b.slug for b in Book.objects.all()]), - set(['book2', '1', 'book3'])) + self.assertEqual(set([b.slug for b in Book.objects.all()]), {'book2', '1', 'book3'}) self.assertEqual( Book.objects.get(slug='book3').materialize(), 'I survived!') diff --git a/apps/catalogue/tests/gallery.py b/apps/catalogue/tests/gallery.py index ad0dfd7d..47dfae79 100644 --- a/apps/catalogue/tests/gallery.py +++ b/apps/catalogue/tests/gallery.py @@ -18,11 +18,10 @@ class GalleryAppendTests(TestCase): def setUp(self): self.user = User.objects.create(username='tester') self.book1 = Book.create(self.user, 'book 1', slug='book1') - self.book1.chunk_set.create(number=2, title='Second chunk', - slug='book 1 / 2') - c=self.book1[1] - c.gallery_start=3 - + self.book1.chunk_set.create(number=2, title='Second chunk', slug='book 1 / 2') + c = self.book1[1] + c.gallery_start = 3 + self.scandir = join(settings.MEDIA_ROOT, settings.IMAGE_DIR) if not exists(self.scandir): makedirs(self.scandir) @@ -35,31 +34,29 @@ class GalleryAppendTests(TestCase): f.close() book.gallery = basename(d) - def test_both_indexed(self): self.book2 = Book.create(self.user, 'book 2', slug='book2') - self.book2.chunk_set.create(number=2, title='Second chunk of second book', - slug='book 2 / 2') + self.book2.chunk_set.create(number=2, title='Second chunk of second book', slug='book 2 / 2') c = self.book2[1] c.gallery_start = 3 c.save() - - print "gallery starts:",self.book2[0].gallery_start, self.book2[1].gallery_start + + print "gallery starts:", self.book2[0].gallery_start, self.book2[1].gallery_start self.make_gallery(self.book1, { - '1-0001_1l' : 'aa', - '1-0001_2r' : 'bb', - '1-0002_1l' : 'cc', - '1-0002_2r' : 'dd', - }) + '1-0001_1l': 'aa', + '1-0001_2r': 'bb', + '1-0002_1l': 'cc', + '1-0002_2r': 'dd', + }) self.make_gallery(self.book2, { - '1-0001_1l' : 'dd', # the same, should not be moved - '1-0001_2r' : 'ff', - '2-0002_1l' : 'gg', - '2-0002_2r' : 'hh', - }) + '1-0001_1l': 'dd', # the same, should not be moved + '1-0001_2r': 'ff', + '2-0002_1l': 'gg', + '2-0002_2r': 'hh', + }) self.book1.append(self.book2) @@ -75,26 +72,25 @@ class GalleryAppendTests(TestCase): '2-0001_2r', '3-0002_1l', '3-0002_2r', - ]) + ]) self.assertEqual((4, 6), (self.book1[2].gallery_start, self.book1[3].gallery_start)) - - + def test_none_indexed(self): self.book2 = Book.create(self.user, 'book 2', slug='book2') self.make_gallery(self.book1, { - '0001_1l' : 'aa', - '0001_2r' : 'bb', - '0002_1l' : 'cc', - '0002_2r' : 'dd', - }) + '0001_1l': 'aa', + '0001_2r': 'bb', + '0002_1l': 'cc', + '0002_2r': 'dd', + }) self.make_gallery(self.book2, { - '0001_1l' : 'ee', - '0001_2r' : 'ff', - '0002_1l' : 'gg', - '0002_2r' : 'hh', - }) + '0001_1l': 'ee', + '0001_2r': 'ff', + '0002_1l': 'gg', + '0002_2r': 'hh', + }) self.book1.append(self.book2) @@ -110,25 +106,23 @@ class GalleryAppendTests(TestCase): '1-0001_2r', '1-0002_1l', '1-0002_2r', - ]) - + ]) - def test_none_indexed(self): - import nose.tools + def test_none_indexed2(self): self.book2 = Book.create(self.user, 'book 2', slug='book2') self.make_gallery(self.book1, { - '1-0001_1l' : 'aa', - '1-0001_2r' : 'bb', - '1002_1l' : 'cc', - '1002_2r' : 'dd', - }) + '1-0001_1l': 'aa', + '1-0001_2r': 'bb', + '1002_1l': 'cc', + '1002_2r': 'dd', + }) self.make_gallery(self.book2, { - '0001_1l' : 'ee', - '0001_2r' : 'ff', - '0002_1l' : 'gg', - '0002_2r' : 'hh', - }) + '0001_1l': 'ee', + '0001_2r': 'ff', + '0002_1l': 'gg', + '0002_2r': 'hh', + }) self.book1.append(self.book2) @@ -144,5 +138,4 @@ class GalleryAppendTests(TestCase): '1-0001_2r', '1-0002_1l', '1-0002_2r', - ]) - + ]) diff --git a/apps/catalogue/tests/xml_updater.py b/apps/catalogue/tests/xml_updater.py index 9fb5a4a0..2db8d80f 100644 --- a/apps/catalogue/tests/xml_updater.py +++ b/apps/catalogue/tests/xml_updater.py @@ -17,7 +17,7 @@ class XmlUpdaterTests(TestCase): class SimpleUpdater(XmlUpdater): @XmlUpdater.fixes_elements('.//' + DCNS('title')) def fix_title(element, **kwargs): - element.text = element.text + " fixed" + element.text += " fixed" return True def setUp(self): @@ -31,5 +31,4 @@ class XmlUpdaterTests(TestCase): self.assertEqual( Book.objects.get(slug='test-book').wldocument( publishable=False).book_info.title, - self.title + " fixed" - ) + self.title + " fixed") diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index ec43053f..8f580514 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -6,7 +6,8 @@ from catalogue.feeds import PublishTrackFeed from catalogue.views import GalleryView, GalleryPackageView -urlpatterns = patterns('catalogue.views', +urlpatterns = patterns( + 'catalogue.views', url(r'^$', RedirectView.as_view(url='catalogue/')), url(r'^catalogue/$', 'document_list', name='catalogue_document_list'), @@ -14,7 +15,7 @@ urlpatterns = patterns('catalogue.views', url(r'^user/(?P[^/]+)/$', 'user', name='catalogue_user'), url(r'^users/$', 'users', name='catalogue_users'), url(r'^activity/$', 'activity', name='catalogue_activity'), - url(r'^activity/(?P\d{4}-\d{2}-\d{2})/$', + url(r'^activity/(?P\d{4}-\d{2}-\d{2})/$', 'activity', name='catalogue_activity'), url(r'^upload/$', @@ -26,15 +27,13 @@ urlpatterns = patterns('catalogue.views', 'create_missing', name='catalogue_create_missing'), url(r'^book/(?P[^/]+)/publish$', 'publish', name="catalogue_publish"), - #url(r'^(?P[^/]+)/publish/(?P\d+)$', 'publish', name="catalogue_publish"), + # url(r'^(?P[^/]+)/publish/(?P\d+)$', 'publish', name="catalogue_publish"), url(r'^book/(?P[^/]+)/$', 'book', name="catalogue_book"), - url(r'^book/(?P[^/]+)/gallery/$', - login_required()(GalleryView.as_view()), - name="catalogue_book_gallery"), + url(r'^book/(?P[^/]+)/gallery/$', login_required()(GalleryView.as_view()), name="catalogue_book_gallery"), url(r'^book/(?P[^/]+)/gallery/package$', - permission_required('catalogue.change_book')(GalleryPackageView.as_view()), - name="catalogue_book_gallery_package"), + permission_required('catalogue.change_book')(GalleryPackageView.as_view()), + name="catalogue_book_gallery_package"), url(r'^book/(?P[^/]+)/xml$', 'book_xml', name="catalogue_book_xml"), url(r'^book/(?P[^/]+)/txt$', 'book_txt', name="catalogue_book_txt"), url(r'^book/(?P[^/]+)/html$', 'book_html', name="catalogue_book_html"), diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index 2ba0fb6d..3bee9107 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -101,7 +101,7 @@ def create_missing(request, slug=None): if request.method == "POST": form = forms.DocumentCreateForm(request.POST, request.FILES) if form.is_valid(): - + if request.user.is_authenticated(): creator = request.user else: @@ -395,14 +395,14 @@ def chunk_mass_edit(request): if request.method == 'POST': ids = map(int, filter(lambda i: i.strip() != '', request.POST.get('ids').split(','))) chunks = map(lambda i: Chunk.objects.get(id=i), ids) - + stage = request.POST.get('stage') if stage: try: stage = Chunk.tag_model.objects.get(slug=stage) except Chunk.DoesNotExist: stage = None - + for c in chunks: c.stage = stage @@ -414,7 +414,7 @@ def chunk_mass_edit(request): user = User.objects.get(username=username) except User.DoesNotExist, e: user = None - + for c in chunks: c.user = user diff --git a/apps/catalogue/xml_tools.py b/apps/catalogue/xml_tools.py index 242714b6..75cb2d8c 100644 --- a/apps/catalogue/xml_tools.py +++ b/apps/catalogue/xml_tools.py @@ -14,7 +14,7 @@ class ParseError(BaseException): def _trim(text, trim_begin=True, trim_end=True): - """ + """ Cut off everything before RE_TRIM_BEGIN and after RE_TRIM_END, so that eg. one big XML file can be compiled from many small XML files. """ @@ -26,7 +26,7 @@ def _trim(text, trim_begin=True, trim_end=True): def compile_text(parts): - """ + """ Compiles full text from an iterable of parts, trimming where applicable. """ @@ -103,7 +103,7 @@ def split_xml(text): name_elem = deepcopy(element) for tag in 'extra', 'motyw', 'pa', 'pe', 'pr', 'pt', 'uwaga': for a in name_elem.findall('.//' + tag): - a.text='' + a.text = '' del a[:] name = etree.tostring(name_elem, method='text', encoding='utf-8').strip() @@ -123,15 +123,11 @@ def split_xml(text): while parent[0] is not element: del parent[0] element, parent = parent, parent.getparent() - chunks[:0] = [[name, - unicode(etree.tostring(copied, encoding='utf-8'), 'utf-8') - ]] + chunks[:0] = [[name, unicode(etree.tostring(copied, encoding='utf-8'), 'utf-8')]] parts = src.findall('.//naglowek_rozdzial') - chunks[:0] = [[u'początek', - unicode(etree.tostring(src, encoding='utf-8'), 'utf-8') - ]] + chunks[:0] = [[u'początek', unicode(etree.tostring(src, encoding='utf-8'), 'utf-8')]] for ch in chunks[1:]: ch[1] = add_trim_begin(ch[1]) diff --git a/apps/cover/forms.py b/apps/cover/forms.py index 4c718862..969d13a8 100755 --- a/apps/cover/forms.py +++ b/apps/cover/forms.py @@ -9,6 +9,7 @@ from django import forms from django.utils.translation import ugettext_lazy as _ from cover.models import Image + class ImageAddForm(forms.ModelForm): class Meta: model = Image @@ -41,13 +42,12 @@ class ReadonlyImageEditForm(ImageEditForm): """Form used for not editing a Book.""" def __init__(self, *args, **kwargs): - ret = super(ReadonlyImageEditForm, self).__init__(*args, **kwargs) + super(ReadonlyImageEditForm, self).__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs.update({"readonly": True}) - return ret def save(self, *args, **kwargs): - raise AssertionError, "ReadonlyImageEditForm should not be saved." + raise AssertionError("ReadonlyImageEditForm should not be saved.") class FlickrForm(forms.Form): @@ -56,7 +56,7 @@ class FlickrForm(forms.Form): def clean_source_url(self): def normalize_html(html): return re.sub('[\t\n]', '', html) - + url = self.cleaned_data['source_url'] m = re.match(r'(https?://)?(www\.|secure\.)?flickr\.com/photos/(?P[^/]+)/(?P\d+)/?', url) if not m: diff --git a/apps/cover/models.py b/apps/cover/models.py index d4432c2c..c7657f31 100644 --- a/apps/cover/models.py +++ b/apps/cover/models.py @@ -3,9 +3,6 @@ # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -import re -from urlparse import urljoin -from django.conf import settings from django.core.files.base import ContentFile from django.db import models from django.db.models.signals import post_save @@ -20,8 +17,8 @@ class Image(models.Model): author = models.CharField(max_length=255, verbose_name=_('author')) license_name = models.CharField(max_length=255, verbose_name=_('license name')) license_url = models.URLField(max_length=255, blank=True, verbose_name=_('license URL')) - source_url = models.URLField(verbose_name=_('source URL'), null = True) - download_url = models.URLField(unique=True, verbose_name=_('image download URL'), null = True) + source_url = models.URLField(verbose_name=_('source URL'), null=True) + download_url = models.URLField(unique=True, verbose_name=_('image download URL'), null=True) file = models.ImageField(upload_to='cover/image', editable=True, verbose_name=_('file')) class Meta: @@ -33,7 +30,7 @@ class Image(models.Model): @models.permalink def get_absolute_url(self): - return ('cover_image', [self.id]) + return 'cover_image', [self.id] def get_full_url(self): return "http://%s%s" % (Site.objects.get_current().domain, self.get_absolute_url()) @@ -44,5 +41,3 @@ def download_image(sender, instance, **kwargs): if instance.pk and not instance.file: t = URLOpener().open(instance.download_url).read() instance.file.save("%d.jpg" % instance.pk, ContentFile(t)) - - \ No newline at end of file diff --git a/apps/cover/tests.py b/apps/cover/tests.py index 2f5b304e..b3be63b9 100644 --- a/apps/cover/tests.py +++ b/apps/cover/tests.py @@ -17,4 +17,5 @@ class FlickrTests(TestCase): self.assertEqual(form.cleaned_data['title'], u"Pirate Stańczyk") self.assertEqual(form.cleaned_data['license_name'], "CC BY 2.0") self.assertEqual(form.cleaned_data['license_url'], "http://creativecommons.org/licenses/by/2.0/deed.en") - self.assertEqual(form.cleaned_data['download_url'], "https://farm8.staticflickr.com/7069/6941928577_415844c58e_o.jpg") + self.assertEqual(form.cleaned_data['download_url'], + "https://farm8.staticflickr.com/7069/6941928577_415844c58e_o.jpg") diff --git a/apps/cover/urls.py b/apps/cover/urls.py index f1a48d35..31d0c65a 100644 --- a/apps/cover/urls.py +++ b/apps/cover/urls.py @@ -6,13 +6,12 @@ from django.conf.urls import patterns, url -urlpatterns = patterns('cover.views', +urlpatterns = patterns( + 'cover.views', url(r'^preview/$', 'preview_from_xml', name='cover_preview'), url(r'^preview/(?P[^/]+)/$', 'preview', name='cover_preview'), - url(r'^preview/(?P[^/]+)/(?P[^/]+)/$', - 'preview', name='cover_preview'), - url(r'^preview/(?P[^/]+)/(?P[^/]+)/(?P\d+)/$', - 'preview', name='cover_preview'), + url(r'^preview/(?P[^/]+)/(?P[^/]+)/$', 'preview', name='cover_preview'), + url(r'^preview/(?P[^/]+)/(?P[^/]+)/(?P\d+)/$', 'preview', name='cover_preview'), url(r'^image/$', 'image_list', name='cover_image_list'), url(r'^image/(?P\d+)/?$', 'image', name='cover_image'), diff --git a/apps/dvcs/models.py b/apps/dvcs/models.py index eba2c386..662a6455 100644 --- a/apps/dvcs/models.py +++ b/apps/dvcs/models.py @@ -1,9 +1,9 @@ +# -*- coding: utf-8 -*- from datetime import datetime import os.path from django.contrib.auth.models import User from django.core.files.base import ContentFile -from django.core.files.storage import FileSystemStorage from django.db import models, transaction from django.db.models.base import ModelBase from django.utils.translation import ugettext_lazy as _ @@ -17,8 +17,7 @@ from dvcs.storage import GzipFileSystemStorage class Tag(models.Model): """A tag (e.g. document stage) which can be applied to a Change.""" name = models.CharField(_('name'), max_length=64) - slug = models.SlugField(_('slug'), unique=True, max_length=64, - null=True, blank=True) + slug = models.SlugField(_('slug'), unique=True, max_length=64, null=True, blank=True) ordering = models.IntegerField(_('ordering')) _object_cache = {} @@ -61,38 +60,39 @@ models.signals.pre_save.connect(Tag.listener_changed, sender=Tag) def data_upload_to(instance, filename): return "%d/%d" % (instance.tree.pk, instance.pk) + class Change(models.Model): """ Single document change related to previous change. The "parent" - argument points to the version against which this change has been + argument points to the version against which this change has been recorded. Initial text will have a null parent. - + Data file contains a gzipped text of the document. """ author = models.ForeignKey(User, null=True, blank=True, verbose_name=_('author')) - author_name = models.CharField(_('author name'), max_length=128, - null=True, blank=True, - help_text=_("Used if author is not set.") - ) - author_email = models.CharField(_('author email'), max_length=128, - null=True, blank=True, - help_text=_("Used if author is not set.") - ) + author_name = models.CharField( + _('author name'), max_length=128, + null=True, blank=True, + help_text=_("Used if author is not set.")) + author_email = models.CharField( + _('author email'), max_length=128, + null=True, blank=True, + help_text=_("Used if author is not set.")) revision = models.IntegerField(_('revision'), db_index=True) - parent = models.ForeignKey('self', - null=True, blank=True, default=None, - verbose_name=_('parent'), - related_name="children") + parent = models.ForeignKey( + 'self', + null=True, blank=True, default=None, + verbose_name=_('parent'), related_name="children") - merge_parent = models.ForeignKey('self', - null=True, blank=True, default=None, - verbose_name=_('merge parent'), - related_name="merge_children") + merge_parent = models.ForeignKey( + 'self', + null=True, blank=True, default=None, + verbose_name=_('merge parent'), + related_name="merge_children") description = models.TextField(_('description'), blank=True, default='') - created_at = models.DateTimeField(editable=False, db_index=True, - default=datetime.now) + created_at = models.DateTimeField(editable=False, db_index=True, default=datetime.now) publishable = models.BooleanField(_('publishable'), default=False) class Meta: @@ -109,7 +109,7 @@ class Change(models.Model): if self.author: return "%s %s <%s>" % ( self.author.first_name, - self.author.last_name, + self.author.last_name, self.author.email) else: return "%s <%s>" % ( @@ -117,7 +117,6 @@ class Change(models.Model): self.author_email ) - def save(self, *args, **kwargs): """ take the next available revision number if none yet @@ -136,9 +135,7 @@ class Change(models.Model): f.close() return unicode(text, 'utf-8') - def merge_with(self, other, author=None, - author_name=None, author_email=None, - description=u"Automatic merge."): + def merge_with(self, other, author=None, author_name=None, author_email=None, description=u"Automatic merge."): """Performs an automatic merge after straying commits.""" assert self.tree_id == other.tree_id # same tree if other.parent_id == self.pk: @@ -205,26 +202,29 @@ def create_change_model(model): class DocumentMeta(ModelBase): - "Metaclass for Document models." - def __new__(cls, name, bases, attrs): + """Metaclass for Document models.""" + def __new__(mcs, name, bases, attrs): - model = super(DocumentMeta, cls).__new__(cls, name, bases, attrs) + model = super(DocumentMeta, mcs).__new__(mcs, name, bases, attrs) if not model._meta.abstract: # create a real Tag object and `stage' fk model.tag_model = create_tag_model(model) - models.ForeignKey(model.tag_model, verbose_name=_('stage'), + models.ForeignKey( + model.tag_model, verbose_name=_('stage'), null=True, blank=True).contribute_to_class(model, 'stage') # create real Change model and `head' fk model.change_model = create_change_model(model) - models.ForeignKey(model.change_model, - null=True, blank=True, default=None, - verbose_name=_('head'), - help_text=_("This document's current head."), - editable=False).contribute_to_class(model, 'head') + models.ForeignKey( + model.change_model, + null=True, blank=True, default=None, + verbose_name=_('head'), + help_text=_("This document's current head."), + editable=False).contribute_to_class(model, 'head') - models.ForeignKey(User, null=True, blank=True, editable=False, + models.ForeignKey( + User, null=True, blank=True, editable=False, verbose_name=_('creator'), related_name="created_%s" % name.lower() ).contribute_to_class(model, 'creator') @@ -239,7 +239,8 @@ class Document(models.Model): # default repository path REPO_PATH = os.path.join(settings.MEDIA_ROOT, 'dvcs') - user = models.ForeignKey(User, null=True, blank=True, + user = models.ForeignKey( + User, null=True, blank=True, verbose_name=_('user'), help_text=_('Work assignment.')) class Meta: @@ -257,8 +258,7 @@ class Document(models.Model): change = self.change_set.get(pk=change) return change.materialize() - def commit(self, text, author=None, author_name=None, author_email=None, - publishable=False, **kwargs): + def commit(self, text, author=None, author_name=None, author_email=None, publishable=False, **kwargs): """Commits a new revision. This will automatically merge the commit into the main branch, @@ -286,12 +286,13 @@ class Document(models.Model): # set stage to next tag after the commited one self.stage = max(tags, key=lambda t: t.ordering).get_next() - change = self.change_set.create(author=author, - author_name=author_name, - author_email=author_email, - description=kwargs.get('description', ''), - publishable=publishable, - parent=parent) + change = self.change_set.create( + author=author, + author_name=author_name, + author_email=author_email, + description=kwargs.get('description', ''), + publishable=publishable, + parent=parent) change.tags = tags change.data.save('', ContentFile(text.encode('utf-8'))) @@ -299,9 +300,10 @@ class Document(models.Model): if self.head: # merge new change as new head - self.head = self.head.merge_with(change, author=author, - author_name=author_name, - author_email=author_email) + self.head = self.head.merge_with( + change, author=author, + author_name=author_name, + author_email=author_email) else: self.head = change self.save() diff --git a/apps/dvcs/signals.py b/apps/dvcs/signals.py index 5da075be..8aedb8c7 100755 --- a/apps/dvcs/signals.py +++ b/apps/dvcs/signals.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django.dispatch import Signal post_commit = Signal() diff --git a/apps/dvcs/storage.py b/apps/dvcs/storage.py index 6bb5b595..1572439e 100755 --- a/apps/dvcs/storage.py +++ b/apps/dvcs/storage.py @@ -1,6 +1,7 @@ +# -*- coding: utf-8 -*- from zlib import compress, decompress -from django.core.files.base import ContentFile, File +from django.core.files.base import ContentFile from django.core.files.storage import FileSystemStorage diff --git a/apps/dvcs/tests/__init__.py b/apps/dvcs/tests/__init__.py index 868f00a3..64c074d0 100755 --- a/apps/dvcs/tests/__init__.py +++ b/apps/dvcs/tests/__init__.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals from nose.tools import * from django.test import TestCase from dvcs.models import Document @@ -11,30 +13,30 @@ class ADocument(Document): class DocumentModelTests(TestCase): def assertTextEqual(self, given, expected): - return self.assertEqual(given, expected, - "Expected '''%s'''\n differs from text: '''%s'''" % (expected, given) - ) + return self.assertEqual( + given, expected, + "Expected '''%s'''\n differs from text: '''%s'''" % (expected, given)) def test_empty_file(self): doc = ADocument.objects.create() - self.assertTextEqual(doc.materialize(), u"") + self.assertTextEqual(doc.materialize(), "") def test_single_commit(self): doc = ADocument.objects.create() - doc.commit(text=u"Ala ma kota", description="Commit #1") - self.assertTextEqual(doc.materialize(), u"Ala ma kota") + doc.commit(text="Ala ma kota", description="Commit #1") + self.assertTextEqual(doc.materialize(), "Ala ma kota") def test_chained_commits(self): doc = ADocument.objects.create() - text1 = u""" + text1 = """ Line #1 Line #2 is cool """ - text2 = u""" + text2 = """ Line #1 Line #2 is hot """ - text3 = u""" + text3 = """ Line #1 ... is hot Line #3 ate Line #2 @@ -51,20 +53,20 @@ class DocumentModelTests(TestCase): def test_parallel_commit_noconflict(self): doc = ADocument.objects.create() - text1 = u""" + text1 = """ Line #1 Line #2 """ - text2 = u""" + text2 = """ Line #1 is hot Line #2 """ - text3 = u""" + text3 = """ Line #1 Line #2 Line #3 """ - text_merged = u""" + text_merged = """ Line #1 is hot Line #2 Line #3 @@ -74,28 +76,29 @@ class DocumentModelTests(TestCase): c1 = doc.commit(description="Commit #2", text=text2) commits = doc.change_set.count() c2 = doc.commit(description="Commit #3", text=text3, parent=base) - self.assertEqual(doc.change_set.count(), commits + 2, - u"Parallel commits should create an additional merge commit") + self.assertEqual( + doc.change_set.count(), commits + 2, + "Parallel commits should create an additional merge commit") self.assertTextEqual(doc.materialize(), text_merged) def test_parallel_commit_conflict(self): doc = ADocument.objects.create() - text1 = u""" + text1 = """ Line #1 Line #2 Line #3 """ - text2 = u""" + text2 = """ Line #1 Line #2 is hot Line #3 """ - text3 = u""" + text3 = """ Line #1 Line #2 is cool Line #3 """ - text_merged = u""" + text_merged = """ Line #1 <<<<<<< Line #2 is hot @@ -108,41 +111,41 @@ class DocumentModelTests(TestCase): c1 = doc.commit(description="Commit #2", text=text2) commits = doc.change_set.count() c2 = doc.commit(description="Commit #3", text=text3, parent=base) - self.assertEqual(doc.change_set.count(), commits + 2, - u"Parallel commits should create an additional merge commit") + self.assertEqual( + doc.change_set.count(), commits + 2, + "Parallel commits should create an additional merge commit") self.assertTextEqual(doc.materialize(), text_merged) - def test_multiple_parallel_commits(self): - text_a1 = u""" + text_a1 = """ Line #1 Line #2 Line #3 """ - text_a2 = u""" + text_a2 = """ Line #1 * Line #2 Line #3 """ - text_b1 = u""" + text_b1 = """ Line #1 Line #2 ** Line #3 """ - text_c1 = u""" + text_c1 = """ Line #1 Line #2 Line #3 *** """ - text_merged = u""" + text_merged = """ Line #1 * Line #2 ** @@ -150,7 +153,6 @@ class DocumentModelTests(TestCase): Line #3 *** """ - doc = ADocument.objects.create() c1 = doc.commit(description="Commit A1", text=text_a1) c2 = doc.commit(description="Commit A2", text=text_a2, parent=c1) @@ -158,7 +160,6 @@ class DocumentModelTests(TestCase): c4 = doc.commit(description="Commit C1", text=text_c1, parent=c1) self.assertTextEqual(doc.materialize(), text_merged) - def test_prepend_history(self): doc1 = ADocument.objects.create() doc2 = ADocument.objects.create() @@ -175,4 +176,3 @@ class DocumentModelTests(TestCase): with self.assertRaises(AssertionError): doc.prepend_history(doc) self.assertTextEqual(doc.materialize(), 'Commit 1') - diff --git a/apps/email_mangler/templatetags/email.py b/apps/email_mangler/templatetags/email.py index 376117a8..b7233fb1 100755 --- a/apps/email_mangler/templatetags/email.py +++ b/apps/email_mangler/templatetags/email.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ @@ -17,8 +18,8 @@ def email_link(email): at = escape(_('at')) dot = escape(_('dot')) mangled = "%s %s %s" % (name, at, (' %s ' % dot).join(domain.split('.'))) - return mark_safe("%(mangled)s" % { + return mark_safe( + "%(mangled)s" % { 'name': name.encode('rot13'), 'domain': domain.encode('rot13'), 'mangled': mangled, diff --git a/apps/fileupload/forms.py b/apps/fileupload/forms.py index f5e10699..368c0ab3 100644 --- a/apps/fileupload/forms.py +++ b/apps/fileupload/forms.py @@ -1,4 +1,6 @@ +# -*- coding: utf-8 -*- from django import forms + class UploadForm(forms.Form): files = forms.FileField() diff --git a/apps/fileupload/templatetags/upload_tags.py b/apps/fileupload/templatetags/upload_tags.py index aefce2e3..a924a603 100644 --- a/apps/fileupload/templatetags/upload_tags.py +++ b/apps/fileupload/templatetags/upload_tags.py @@ -1,7 +1,9 @@ +# -*- coding: utf-8 -*- from django import template register = template.Library() + @register.simple_tag def upload_js(): return """ @@ -13,10 +15,15 @@ def upload_js(): {%=file.name%} {%=o.formatFileSize(file.size)%} {% if (file.error) { %} - {%=locale.fileupload.error%} {%=locale.fileupload.errors[file.error] || file.error%} + + {%=locale.fileupload.error%} + {%=locale.fileupload.errors[file.error] || file.error%} + {% } else if (o.files.valid && !i) { %} -
+
+
+
{% if (!o.options.autoUpload) { %}