test:
cd src
coverage run --branch --source='.' ./manage.py test; true
- rm -rf ../htmlcov
coverage html -d ../htmlcov.new
rm -rf ../htmlcov
mv ../htmlcov.new ../htmlcov
--i https://py.mdrn.pl:8443/simple/
-
coverage
-mock
sorl-thumbnail>=12.3,<12.4
# home-brewed & dependencies
-librarian==1.7.1
+librarian==1.7.2
# celery tasks
celery>=3.1.12,<3.2
pyenchant
# OAI-PMH
-pyoai==2.4.4
+pyoai==2.5.0
-## egenix-mx-base # Doesn't play nice with mx in dist-packages.
-sunburnt
+scorched==0.12
django-getpaid==1.8.0
deprecated
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django import template
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils.safestring import mark_safe
from ajaxable.utils import placeholdized
return mark_safe(template % {
'errors': field.errors,
'input': field,
- 'label': ('*' if field.field.required else '') + force_unicode(field.label),
- 'helptext': force_unicode(field.help_text),
+ 'label': ('*' if field.field.required else '') + force_text(field.label),
+ 'helptext': force_text(field.help_text),
})
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.shortcuts import render
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils.functional import Promise
from django.utils.http import urlquote_plus
import json
class LazyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Promise):
- return force_unicode(obj)
+ return force_text(obj)
return obj
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
WL_BASE = lazy(
- lambda: u'https://' + Site.objects.get_current().domain, unicode)()
+ lambda: 'https://' + Site.objects.get_current().domain, str)()
category_singular = {
'authors': 'author',
consumer_key = models.CharField(max_length=KEY_SIZE)
key = models.CharField(max_length=255)
- def __unicode__(self):
+ def __str__(self):
return u"Nonce %s for %s" % (self.key, self.consumer_key)
status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending')
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='consumers')
- def __unicode__(self):
+ def __str__(self):
return u"Consumer %s with key %s" % (self.name, self.key)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='tokens')
consumer = models.ForeignKey(Consumer)
- def __unicode__(self):
+ def __str__(self):
return u"%s Token %s for %s" % (self.get_token_type_display(), self.key, self.consumer)
import hashlib
import hmac
import json
-from StringIO import StringIO
+from io import BytesIO
from time import time
-from urllib import quote, urlencode
-from urlparse import parse_qs
+from urllib.parse import quote, urlencode, parse_qs
from django.contrib.auth.models import User
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.test.utils import override_settings
-from mock import patch
+from unittest.mock import patch
from api.models import Consumer, Token
from catalogue.models import Book, Tag
return data
def assert_response(self, url, name):
- content = self.client.get(url).content.rstrip()
+ content = self.client.get(url).content.decode('utf-8').rstrip()
filename = path.join(path.dirname(__file__), 'res', 'responses', name)
with open(filename) as f:
good_content = f.read().rstrip()
'composition8.xml',
open(path.join(
picture.tests.__path__[0], "files", slug + ".xml"
- )).read())
+ ), 'rb').read())
img = SimpleUploadedFile(
'kompozycja-8.png',
open(path.join(
picture.tests.__path__[0], "files", slug + ".png"
- )).read())
+ ), 'rb').read())
import_form = PictureImportForm({}, {
'picture_xml_file': xml,
quote(base_query, safe='')
])
h = hmac.new(
- quote(self.consumer_secret) + '&', raw, hashlib.sha1
+ (quote(self.consumer_secret) + '&').encode('latin1'),
+ raw.encode('latin1'),
+ hashlib.sha1
).digest()
- h = b64encode(h).rstrip('\n')
+ h = b64encode(h).rstrip(b'\n')
sign = quote(h)
query = "{}&oauth_signature={}".format(base_query, sign)
response = self.client.get('/api/oauth/request_token/?' + query)
- request_token_data = parse_qs(response.content)
+ request_token_data = parse_qs(response.content.decode('latin1'))
request_token = request_token_data['oauth_token'][0]
request_token_secret = request_token_data['oauth_token_secret'][0]
quote(base_query, safe='')
])
h = hmac.new(
- quote(self.consumer_secret) + '&' +
- quote(request_token_secret, safe=''),
- raw,
+ (quote(self.consumer_secret) + '&' +
+ quote(request_token_secret, safe='')).encode('latin1'),
+ raw.encode('latin1'),
hashlib.sha1
).digest()
- h = b64encode(h).rstrip('\n')
+ h = b64encode(h).rstrip(b'\n')
sign = quote(h)
query = u"{}&oauth_signature={}".format(base_query, sign)
response = self.client.get(u'/api/oauth/access_token/?' + query)
- access_token_data = parse_qs(response.content)
+ access_token_data = parse_qs(response.content.decode('latin1'))
access_token = access_token_data['oauth_token'][0]
self.assertTrue(
consumer=cls.consumer,
token_type=Token.ACCESS,
timestamp=time())
- cls.key = cls.consumer.secret + '&' + cls.token.secret
+ cls.key = (cls.consumer.secret + '&' + cls.token.secret).encode('latin1')
@classmethod
def tearDownClass(cls):
for (k, v) in sorted(sign_params.items())))
])
auth_params["oauth_signature"] = quote(b64encode(hmac.new(
- self.key, raw, hashlib.sha1).digest()).rstrip('\n'))
+ self.key,
+ raw.encode('latin1'),
+ hashlib.sha1
+ ).digest()).rstrip(b'\n'))
auth = 'OAuth realm="API", ' + ', '.join(
'{}="{}"'.format(k, v) for (k, v) in auth_params.items())
{"username": "test", "premium": True})
with patch('paypal.permissions.user_is_subscribed', return_value=True):
with patch('django.core.files.storage.Storage.open',
- return_value=StringIO("<epub>")):
+ return_value=BytesIO(b"<epub>")):
self.assertEqual(
self.signed('/api/epub/grandchild/').content,
- "<epub>")
+ b"<epub>")
def test_publish(self):
response = self.signed('/api/books/',
"headers": headers,
}
-def oauthlib_response((headers, body, status)):
+def oauthlib_response(response_tuple):
"""Creates a django.http.HttpResponse from (headers, body, status) tuple from OAuthlib."""
+ headers, body, status = response_tuple
response = HttpResponse(body, status=status)
for k, v in headers.items():
if k == 'Location':
new_api = self.request.query_params.get('new_api')
after = self.request.query_params.get('after', self.kwargs.get('after'))
count = self.request.query_params.get('count', self.kwargs.get('count'))
+ if count:
+ try:
+ count = int(count)
+ except TypeError:
+ raise Http404 # Fixme
if tags:
if self.kwargs.get('top_level'):
LICENSES['http://creativecommons.org/licenses/by-sa/3.0/deed.pl'] = \
LICENSES['http://creativecommons.org/licenses/by-sa/3.0/']
-for license, data in LICENSES.items():
+
+for license, data in list(LICENSES.items()):
LICENSES[license.replace('http://', 'https://')] = data
# Those will be generated only for books with own HTML.
def build(self, fieldfile):
book = fieldfile.instance
out = self.transform(book.wldocument(), fieldfile)
- fieldfile.save(None, File(open(out.get_filename())), save=False)
+ fieldfile.save(None, File(open(out.get_filename(), 'rb')), save=False)
self.set_file_permissions(fieldfile)
if book.pk is not None:
books = type(book).objects.filter(pk=book.pk)
from .models import Tag, Book
from os.path import getmtime
-import cPickle
+import pickle
from collections import defaultdict
BOOK_CATEGORIES = ('author', 'epoch', 'genre', 'kind')
_COUNTERS = None
-_COUNTER_TIME = None
+_COUNTER_TIME = 0
def get_top_level_related_tags(tags, categories=None):
global _COUNTERS, _COUNTER_TIME
# First, check that we have a valid and recent version of the counters.
if getmtime(settings.CATALOGUE_COUNTERS_FILE) > _COUNTER_TIME:
- for i in xrange(10):
+ for i in range(10):
try:
- with open(settings.CATALOGUE_COUNTERS_FILE) as f:
- _COUNTERS = cPickle.load(f)
+ with open(settings.CATALOGUE_COUNTERS_FILE, 'rb') as f:
+ _COUNTERS = pickle.load(f)
except (EOFError, ValueError):
if i < 9:
continue
"next": dict(next_combinations),
}
- with open(settings.CATALOGUE_COUNTERS_FILE, 'w') as f:
- cPickle.dump(counters, f)
+ with open(settings.CATALOGUE_COUNTERS_FILE, 'wb') as f:
+ pickle.dump(counters, f)
def get_audiobook_tags():
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from optparse import make_option
from django.contrib.sites.models import Site
from django.core.management.base import BaseCommand
-from catalogue import app_settings
from django.utils.functional import lazy
+from catalogue import app_settings
def ancestor_has_cover(book):
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
- help='Suppress output'),
- )
help = 'Checks cover sources and licenses.'
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-q', '--quiet', action='store_false', dest='verbose',
+ default=True, help='Suppress output')
+
def handle(self, **options):
from collections import defaultdict
import re
bad_license = defaultdict(list)
no_license = []
- re_license = re.compile(ur'.*,\s*(CC.*)')
+ re_license = re.compile(r'.*,\s*(CC.*)')
redakcja_url = app_settings.REDAKCJA_URL
good_license = re.compile("(%s)" % ")|(".join(
else:
no_license.append(book)
- print """%d books with no covers, %d with inherited covers.
+ print("""%d books with no covers, %d with inherited covers.
Bad licenses used: %s (%d covers without license).
%d covers not from %s.
""" % (
len(no_license),
len(not_redakcja),
redakcja_url,
- )
+ ))
if verbose:
if bad_license:
- print
- print "Bad license:"
- print "============"
+ print()
+ print("Bad license:")
+ print("============")
for lic, books in bad_license.items():
- print
- print lic
+ print()
+ print(lic)
for book in books:
- print full_url(book)
+ print(full_url(book))
if no_license:
- print
- print "No license:"
- print "==========="
+ print()
+ print("No license:")
+ print("===========")
for book in no_license:
- print
- print full_url(book)
- print book.extra_info.get('cover_by')
- print book.extra_info.get('cover_source')
- print book.extra_info.get('cover_url')
+ print()
+ print(full_url(book))
+ print(book.extra_info.get('cover_by'))
+ print(book.extra_info.get('cover_source'))
+ print(book.extra_info.get('cover_url'))
if not_redakcja:
- print
- print "Not from Redakcja or source missing:"
- print "===================================="
+ print()
+ print("Not from Redakcja or source missing:")
+ print("====================================")
for book in not_redakcja:
- print
- print full_url(book)
- print book.extra_info.get('cover_by')
- print book.extra_info.get('cover_source')
- print book.extra_info.get('cover_url')
+ print()
+ print(full_url(book))
+ print(book.extra_info.get('cover_by'))
+ print(book.extra_info.get('cover_source'))
+ print(book.extra_info.get('cover_url'))
if without_cover:
- print
- print "No cover:"
- print "========="
+ print()
+ print("No cover:")
+ print("=========")
for book in without_cover:
- print full_url(book)
+ print(full_url(book))
if with_ancestral_cover:
- print
- print "With ancestral cover:"
- print "====================="
+ print()
+ print("With ancestral cover:")
+ print("=====================")
for book in with_ancestral_cover:
- print full_url(book)
+ print(full_url(book))
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from optparse import make_option
from django.core.management.base import BaseCommand
-
-from catalogue.models import Book
from librarian import ParseError
+from catalogue.models import Book
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
- help='Suppress output'),
- make_option('-d', '--dry-run', action='store_true', dest='dry_run', default=False,
- help="Just check for problems, don't fix them"),
- )
help = 'Checks integrity of catalogue data.'
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-q', '--quiet', action='store_false', dest='verbose',
+ default=True, help='Suppress output')
+ parser.add_argument(
+ '-d', '--dry-run', action='store_true', dest='dry_run',
+ default=False, help="Just check for problems, don't fix them")
+
def handle(self, **options):
from django.db import transaction
info = book.wldocument().book_info
except ParseError:
if verbose:
- print "ERROR! Bad XML for book:", book.slug
- print "To resolve: republish."
- print
+ print("ERROR! Bad XML for book:", book.slug)
+ print("To resolve: republish.")
+ print()
else:
should_be = [p.slug for p in info.parts]
is_now = [p.slug for p in book.children.all().order_by('parent_number')]
if should_be != is_now:
if verbose:
- print "ERROR! Wrong children for book:", book.slug
- # print "Is: ", is_now
- # print "Should be:", should_be
+ print("ERROR! Wrong children for book:", book.slug)
+ # print("Is: ", is_now)
+ # print("Should be:", should_be)
from difflib import ndiff
- print '\n'.join(ndiff(is_now, should_be))
- print "To resolve: republish parent book."
- print
+ print('\n'.join(ndiff(is_now, should_be)))
+ print("To resolve: republish parent book.")
+ print()
# Check for ancestry.
parents = []
ancestors = list(book.ancestor.all())
if set(ancestors) != set(parents):
if options['verbose']:
- print "Wrong ancestry for book:", book
- print "Is: ", ", ".join(ancestors)
- print "Should be:", ", ".join(parents)
+ print("Wrong ancestry for book:", book)
+ print("Is: ", ", ".join(ancestors))
+ print("Should be:", ", ".join(parents))
if not options['dry_run']:
book.repopulate_ancestors()
if options['verbose']:
- print "Fixed."
+ print("Fixed.")
if options['verbose']:
- print
+ print()
# TODO: check metadata tags, reset counters
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import os
import sys
-from optparse import make_option
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.management.color import color_style
from django.core.files import File
from django.db import transaction
from librarian.picture import ImageStore
-# from wolnelektury.management.profile import profile
from catalogue.models import Book
from picture.models import Picture
-
from search.index import Index
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
- help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
- make_option('-f', '--force', action='store_true', dest='force', default=False,
- help='Overwrite works already in the catalogue'),
- make_option('-D', '--dont-build', dest='dont_build',
- metavar="FORMAT,...",
- help="Skip building specified formats"),
- make_option('-S', '--no-search-index', action='store_false', dest='search_index', default=True,
- help='Skip indexing imported works for search'),
- make_option('-p', '--picture', action='store_true', dest='import_picture', default=False,
- help='Import pictures'),
- )
help = 'Imports books from the specified directories.'
- args = 'directory [directory ...]'
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-q', '--quiet', action='store_false', dest='verbose', default=True,
+ help='Verbosity level; 0=minimal output, 1=normal output, 2=all output')
+ parser.add_argument(
+ '-f', '--force', action='store_true', dest='force',
+ default=False, help='Overwrite works already in the catalogue')
+ parser.add_argument(
+ '-D', '--dont-build', dest='dont_build', metavar="FORMAT,...",
+ help="Skip building specified formats")
+ parser.add_argument(
+ '-S', '--no-search-index', action='store_false',
+ dest='search_index', default=True,
+ help='Skip indexing imported works for search')
+ parser.add_argument(
+ '-p', '--picture', action='store_true', dest='import_picture',
+ default=False, help='Import pictures')
+ parser.add_argument('directory', nargs='+')
def import_book(self, file_path, options):
verbose = options.get('verbose')
save=False
)
if verbose:
- print "Importing %s.%s" % (file_base, ebook_format)
+ print("Importing %s.%s" % (file_base, ebook_format))
book.save()
def import_picture(self, file_path, options, continue_on_error=True):
try:
image_store = ImageStore(os.path.dirname(file_path))
picture = Picture.from_xml_file(file_path, image_store=image_store, overwrite=options.get('force'))
- except Exception, ex:
+ except Exception as ex:
if continue_on_error:
- print "%s: %s" % (file_path, ex)
+ print("%s: %s" % (file_path, ex))
return
else:
raise ex
return picture
- # @profile
@transaction.atomic
- def handle(self, *directories, **options):
+ def handle(self, **options):
self.style = color_style()
verbose = options.get('verbose')
try:
index.index_tags()
index.index.commit()
- except Exception, e:
+ except Exception as e:
index.index.rollback()
raise e
files_imported = 0
files_skipped = 0
- for dir_name in directories:
+ for dir_name in options['directory']:
if not os.path.isdir(dir_name):
- print self.style.ERROR("%s: Not a directory. Skipping." % dir_name)
+ print(self.style.ERROR("%s: Not a directory. Skipping." % dir_name))
else:
# files queue
files = sorted(os.listdir(dir_name))
continue
if verbose > 0:
- print "Parsing '%s'" % file_path
+ print("Parsing '%s'" % file_path)
else:
sys.stdout.write('.')
sys.stdout.flush()
files_imported += 1
except (Book.AlreadyExists, Picture.AlreadyExists):
- print self.style.ERROR(
+ print(self.style.ERROR(
'%s: Book or Picture already imported. Skipping. To overwrite use --force.' %
- file_path)
+ file_path))
files_skipped += 1
- except Book.DoesNotExist, e:
+ except Book.DoesNotExist as e:
if file_name not in postponed or postponed[file_name] < files_imported:
# push it back into the queue, maybe the missing child will show up
if verbose:
- print self.style.NOTICE('Waiting for missing children')
+ print(self.style.NOTICE('Waiting for missing children'))
files.append(file_name)
postponed[file_name] = files_imported
else:
raise e
# Print results
- print
- print "Results: %d files imported, %d skipped, %d total." % (
- files_imported, files_skipped, files_imported + files_skipped)
- print
+ print()
+ print("Results: %d files imported, %d skipped, %d total." % (
+ files_imported, files_skipped, files_imported + files_skipped))
+ print()
class Command(BaseCommand):
def handle(self, *args, **options):
for b in Book.objects.order_by('slug'):
- print b.slug
+ print(b.slug)
b.load_abstract()
b.save()
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from optparse import make_option
-
+import zipfile
from django.core.management.base import BaseCommand
from django.core.management.color import color_style
-import zipfile
-
from catalogue.models import Book, Tag
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-t', '--tags', dest='tags', metavar='SLUG,...',
- help='Use only books tagged with this tags'),
- make_option('-i', '--include', dest='include', metavar='SLUG,...',
- help='Include specific books by slug'),
- make_option('-e', '--exclude', dest='exclude', metavar='SLUG,...',
- help='Exclude specific books by slug')
- )
help = 'Prepare ZIP package with files of given type.'
- args = '[%s] output_path.zip' % '|'.join(Book.formats)
- def handle(self, ftype, path, **options):
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-t', '--tags', dest='tags', metavar='SLUG,...',
+ help='Use only books tagged with this tags')
+ parser.add_argument(
+ '-i', '--include', dest='include', metavar='SLUG,...',
+ help='Include specific books by slug')
+ parser.add_argument(
+ '-e', '--exclude', dest='exclude', metavar='SLUG,...',
+ help='Exclude specific books by slug')
+ parser.add_argument('ftype', metavar='|'.join(Book.formats))
+ parser.add_argument('path', metavar='output_path.zip')
+
+ def handle(self, **options):
self.style = color_style()
+ ftype = options['ftype']
+ path = options['path']
verbose = int(options.get('verbosity'))
tags = options.get('tags')
include = options.get('include')
if ftype in Book.formats:
field = "%s_file" % ftype
else:
- print self.style.ERROR('Unknown file type.')
+ print(self.style.ERROR('Unknown file type.'))
return
books = []
processed = skipped = 0
for book in books:
if verbose >= 2:
- print 'Parsing', book.slug
+ print('Parsing', book.slug)
content = getattr(book, field)
if not content:
if verbose >= 1:
- print self.style.NOTICE('%s has no %s file' % (book.slug, ftype))
+ print(self.style.NOTICE('%s has no %s file' % (book.slug, ftype)))
skipped += 1
continue
archive.write(content.path, str('%s.%s' % (book.slug, ftype)))
if not processed:
if skipped:
- print self.style.ERROR("No books with %s files found" % ftype)
+ print(self.style.ERROR("No books with %s files found" % ftype))
else:
- print self.style.ERROR("No books found")
+ print(self.style.ERROR("No books found"))
return
if verbose >= 1:
- print "%d processed, %d skipped" % (processed, skipped)
- print "Results written to %s" % path
+ print("%d processed, %d skipped" % (processed, skipped))
+ print("Results written to %s" % path)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from __future__ import print_function, unicode_literals
-
from django.core.management.base import BaseCommand
def handle(self, **options):
from catalogue.models import Book
from picture.models import Picture
- from urllib2 import urlopen, HTTPError, URLError
+ from urllib.request import urlopen, HTTPError, URLError
from django.core.urlresolvers import reverse
from django.contrib.sites.models import Site
if url:
try:
urlopen(url)
- except (HTTPError, URLError, ValueError), e:
+ except (HTTPError, URLError, ValueError) as e:
if clean:
clean = False
- print(unicode(obj).encode('utf-8'))
+ print(str(obj).encode('utf-8'))
print(('Na stronie: https://%s%s' % (domain, obj.get_absolute_url())).encode('utf-8'))
print(
('Administracja: https://%s%s' % (domain, reverse(admin_name, args=[obj.pk])))
+++ /dev/null
-# -*- coding: utf-8 -*-
-# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-import os.path
-
-from django.core.management.base import BaseCommand
-from django.db import transaction
-
-from catalogue.models import Book, BookMedia
-from catalogue.utils import ExistingFile
-
-
-class Command(BaseCommand):
- help = "Saves uploaded media with a given book and a given name. " \
- "If media has a source SHA1 info - matching media is replaced."
- args = 'path slug name'
-
- @transaction.atomic
- def handle(self, *args, **options):
- path, slug, name, part_name, index, parts_count = args
- index = int(index)
- parts_count = int(parts_count)
-
- book = Book.objects.get(slug=slug)
-
- root, ext = os.path.splitext(path)
- ext = ext.lower()
- if ext:
- ext = ext[1:]
- if ext == 'zip':
- ext = 'daisy'
-
- source_sha1 = BookMedia.read_source_sha1(path, ext)
- print "Source file SHA1:", source_sha1
- try:
- assert source_sha1
- bm = book.media.get(type=ext, source_sha1=source_sha1)
- print "Replacing media: %s (%s)" % (bm.name.encode('utf-8'), ext)
- except (AssertionError, BookMedia.DoesNotExist):
- bm = BookMedia(book=book, type=ext)
- print "Creating new media"
- bm.name = name
- bm.part_name = part_name
- bm.index = index
- bm.file.save(None, ExistingFile(path))
- bm.save(parts_count=parts_count)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from __future__ import print_function, unicode_literals
-
from django.conf import settings
from django.core.management.base import BaseCommand
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.core.management import BaseCommand
-
from catalogue.models import Tag
class Command(BaseCommand):
help = "Update description for given tag."
- args = 'category slug description_filename'
+
+ def add_arguments(self, parser):
+ parser.add_argument('category')
+ parser.add_argument('slug')
+ parser.add_argument('description_filename')
def handle(self, category, slug, description_filename, **options):
tag = Tag.objects.get(category=category, slug=slug)
verbose_name_plural = _('books')
app_label = 'catalogue'
- def __unicode__(self):
+ def __str__(self):
return self.title
def get_initial(self):
from sortify import sortify
self.sort_key = sortify(self.title)[:120]
- self.title = unicode(self.title) # ???
+ self.title = str(self.title) # ???
try:
author = self.authors().first().sort_key
index.index_tags()
if commit:
index.index.commit()
- except Exception, e:
+ except Exception as e:
index.index.rollback()
raise e
def publisher(self):
publisher = self.extra_info['publisher']
- if isinstance(publisher, basestring):
+ if isinstance(publisher, str):
return publisher
elif isinstance(publisher, list):
return ', '.join(publisher)
book = models.ForeignKey('Book', related_name='media')
source_sha1 = models.CharField(null=True, blank=True, max_length=40, editable=False)
- def __unicode__(self):
+ def __str__(self):
return "%s (%s)" % (self.name, self.file.name.split("/")[-1])
class Meta:
remove_zip("%s_%s" % (self.book.slug, self.type))
extra_info = self.extra_info
- if isinstance(extra_info, basestring):
+ if isinstance(extra_info, str):
# Walkaround for weird jsonfield 'no-decode' optimization.
extra_info = json.loads(extra_info)
extra_info.update(self.read_meta())
verbose_name_plural = _('collections')
app_label = 'catalogue'
- def __unicode__(self):
+ def __str__(self):
return self.title
def get_initial(self):
verbose_name_plural = _('sources')
app_label = 'catalogue'
- def __unicode__(self):
+ def __str__(self):
return self.netloc
def save(self, *args, **kwargs):
db_table = 'catalogue_tag_relation'
unique_together = (('tag', 'content_type', 'object_id'),)
- def __unicode__(self):
+ def __str__(self):
try:
return u'%s [%s]' % (self.content_type.get_object_for_this_type(pk=self.object_id), self.tag)
except ObjectDoesNotExist:
'polka': 'set',
'obiekt': 'thing',
}
- categories_dict = dict((item[::-1] for item in categories_rev.iteritems()))
+ categories_dict = dict((item[::-1] for item in categories_rev.items()))
class Meta:
ordering = ('sort_key',)
flush_ssi_includes([
'/katalog/%s.json' % lang for lang in languages])
- def __unicode__(self):
+ def __str__(self):
return self.name
def __repr__(self):
for field_name, category in categories:
try:
tag_names = getattr(info, field_name)
- except KeyError:
+ except (AttributeError, KeyError): # TODO: shouldn't be KeyError here at all.
try:
tag_names = [getattr(info, category)]
except KeyError:
# Allow creating new tag, if it's in default language.
tag, created = Tag.objects.get_or_create(slug=slugify(tag_name), category=category)
if created:
- tag_name = unicode(tag_name)
+ tag_name = str(tag_name)
tag.name = tag_name
setattr(tag, "name_%s" % lang, tag_name)
tag.sort_key = sortify(tag_sort_key.lower())
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from catalogue.models import Book
try:
return Book.objects.get(id=book_id).search_index(book_info, **kwargs)
- except Exception, e:
- print "Exception during index: %s" % e
+ except Exception as e:
+ print("Exception during index: %s" % e)
print_exc()
raise e
morefloats=settings.LIBRARIAN_PDF_MOREFLOATS,
ilustr_path=gallery_path(wldoc.book_info.url.slug),
**kwargs)
- DefaultStorage().save(file_name, File(open(pdf.get_filename())))
+ DefaultStorage().save(file_name, File(open(pdf.get_filename(), 'rb')))
finally:
if waiter_id is not None:
WaitedFile.objects.filter(pk=waiter_id).delete()
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from random import randint, random
-from urlparse import urlparse
+from urllib.parse import urlparse
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
# Specjalny przypadek "Twórczość w pozytywizmie", wtedy gdy tylko epoka
# jest wybrana przez użytkownika
if 'epoch' in self and len(self) == 1:
- text = u'Twórczość w %s' % flection.get_case(unicode(self['epoch']), u'miejscownik')
+ text = u'Twórczość w %s' % flection.get_case(str(self['epoch']), u'miejscownik')
return capfirst(text)
# Specjalny przypadek "Dramat w twórczości Sofoklesa", wtedy gdy podane
# są tylko rodzaj literacki i autor
if 'kind' in self and 'author' in self and len(self) == 2:
text = u'%s w twórczości %s' % (
- unicode(self['kind']), flection.get_case(unicode(self['author']), u'dopełniacz'))
+ str(self['kind']), flection.get_case(str(self['author']), u'dopełniacz'))
return capfirst(text)
# Przypadki ogólniejsze
if 'theme' in self:
- title += u'Motyw %s' % unicode(self['theme'])
+ title += u'Motyw %s' % str(self['theme'])
if 'genre' in self:
if 'theme' in self:
- title += u' w %s' % flection.get_case(unicode(self['genre']), u'miejscownik')
+ title += u' w %s' % flection.get_case(str(self['genre']), u'miejscownik')
else:
- title += unicode(self['genre'])
+ title += str(self['genre'])
if 'kind' in self or 'author' in self or 'epoch' in self:
if 'genre' in self or 'theme' in self:
if 'kind' in self:
- title += u' w %s ' % flection.get_case(unicode(self['kind']), u'miejscownik')
+ title += u' w %s ' % flection.get_case(str(self['kind']), u'miejscownik')
else:
title += u' w twórczości '
else:
- title += u'%s ' % unicode(self.get('kind', u'twórczość'))
+ title += u'%s ' % str(self.get('kind', u'twórczość'))
if 'author' in self:
- title += flection.get_case(unicode(self['author']), u'dopełniacz')
+ title += flection.get_case(str(self['author']), u'dopełniacz')
elif 'epoch' in self:
- title += flection.get_case(unicode(self['epoch']), u'dopełniacz')
+ title += flection.get_case(str(self['epoch']), u'dopełniacz')
return capfirst(title)
def __getattr__(self, key):
try:
return self.__dict[key]
- except KeyError:
+ except KeyError as e:
if key in self._empty_fields:
return None
elif key in self._salias:
return [getattr(self, self._salias[key])]
else:
- raise
+ raise AttributeError(e)
def to_dict(self):
- return dict((key, unicode(value)) for key, value in self.__dict.items())
+ return dict((key, str(value)) for key, value in self.__dict.items())
def info_args(title, language=None):
""" generate some keywords for comfortable BookInfoCreation """
- slug = unicode(slugify(title))
+ slug = str(slugify(title))
if language is None:
language = u'pol'
return {
- 'title': unicode(title),
+ 'title': str(title),
'url': WLURI.from_slug(slug),
'about': u"http://wolnelektury.pl/example/URI/%s" % slug,
'language': language,
def setUp(self):
WLTestCase.setUp(self)
- self.file = ContentFile('X')
- self.file2 = ContentFile('Y')
+ self.file = ContentFile(b'X')
+ self.file2 = ContentFile(b'Y')
self.book = models.Book.objects.create(slug='test-book', title='Test')
def set_title(self, title):
bm.file.save(None, self.file)
bm.file.save(None, self.file2)
- self.assertEqual(bm.file.read(), 'Y')
+ self.assertEqual(bm.file.read(), b'Y')
self.assertEqual(basename(bm.file.name), 'some-media.ogg')
@skip('broken, but is it needed?')
bm2.file.save(None, self.file2)
self.assertEqual(basename(bm.file.name), 'tytul.ogg')
self.assertNotEqual(basename(bm2.file.name), 'tytul.ogg')
- self.assertEqual(bm.file.read(), 'X')
- self.assertEqual(bm2.file.read(), 'Y')
+ self.assertEqual(bm.file.read(), b'X')
+ self.assertEqual(bm2.file.read(), b'Y')
def test_change_name(self):
"""
self.set_title("Other Title")
bm.save()
self.assertEqual(basename(bm.file.name), 'other-title.ogg')
- self.assertEqual(bm.file.read(), 'X')
+ self.assertEqual(bm.file.read(), b'X')
@skip('broken, but is it needed?')
def test_change_name_no_clobber(self):
self.set_title("Title")
bm2.save()
self.assertNotEqual(basename(bm2.file.name), 'title.ogg')
- self.assertEqual(bm.file.read(), 'X')
- self.assertEqual(bm2.file.read(), 'Y')
+ self.assertEqual(bm.file.read(), b'X')
+ self.assertEqual(bm2.file.read(), b'Y')
def test_zip_audiobooks(self):
paths = [
from django.core.files.base import ContentFile
from catalogue.test_utils import BookInfoStub, PersonStub, info_args, WLTestCase
from catalogue.models import Book
-from mock import patch
+from unittest.mock import patch
class CoverTests(WLTestCase):
parts=[self.child_info.url],
**info_args("Parent"))
- self.book_file = ContentFile('<utwor />')
+ self.book_file = ContentFile(b'<utwor />')
def test_nonexistent_tag(self):
""" Looking for a non-existent tag should yield 404 """
Ala ma kota
<end id="m01" />
</akap></opowiadanie></utwor>
- """ % info.title.encode('utf-8')
- book = models.Book.from_text_and_meta(ContentFile(book_text), info)
+ """ % info.title
+ book = models.Book.from_text_and_meta(
+ ContentFile(book_text.encode('utf-8')),
+ info)
book.save()
tag_empty = models.Tag(name='Empty tag', slug='empty', category='author')
self.assertTrue(
('ChildKind', 2) in [(tag.name, tag.count) for tag in cats['kind']],
'wrong related kind tags on tag page, got: ' +
- unicode([(tag.name, tag.count) for tag in cats['kind']]))
+ str([(tag.name, tag.count) for tag in cats['kind']]))
# all occurencies of theme should be counted
self.assertTrue(('Theme', 4) in [(tag.name, tag.count) for tag in cats['theme']],
cats = self.client.get('/katalog/gatunek/childgenre/').context['categories']
self.assertTrue(('Epoch', 2) in [(tag.name, tag.count) for tag in cats['epoch']],
'wrong related kind tags on tag page, got: ' +
- unicode([(tag.name, tag.count) for tag in cats['epoch']]))
+ str([(tag.name, tag.count) for tag in cats['epoch']]))
class CleanTagRelationTests(WLTestCase):
<end id="m01" />
</akap></opowiadanie></utwor>
"""
- self.book = models.Book.from_text_and_meta(ContentFile(book_text), book_info)
+ self.book = models.Book.from_text_and_meta(
+ ContentFile(book_text.encode('utf-8')),
+ book_info)
@skip('Not implemented and not priority')
def test_delete_objects(self):
def test_book_tags(self):
""" there should be all related tags in relevant categories """
- book = models.Book.from_text_and_meta(ContentFile(self.book_text), self.book_info)
+ book = models.Book.from_text_and_meta(
+ ContentFile(self.book_text.encode('utf-8')),
+ self.book_info)
related_themes = book.related_themes()
for category in 'author', 'kind', 'genre', 'epoch':
self.assertTrue('tag' in [tag.slug for tag in related_themes])
def test_qualified_url(self):
- models.Book.from_text_and_meta(ContentFile(self.book_text), self.book_info)
+ models.Book.from_text_and_meta(
+ ContentFile(self.book_text.encode('utf-8')),
+ self.book_info)
categories = {'author': 'autor', 'theme': 'motyw', 'epoch': 'epoka', 'kind': 'rodzaj', 'genre': 'gatunek'}
- for cat, localcat in categories.iteritems():
+ for cat, localcat in categories.items():
context = self.client.get('/katalog/%s/tag/' % localcat).context
self.assertEqual(1, len(context['object_list']))
self.assertNotEqual({}, context['categories'])
Ala ma kota
<end id="m01" />
</akap></opowiadanie></utwor>
- """ % info.title.encode('utf-8')
- models.Book.from_text_and_meta(ContentFile(book_text), info)
+ """ % info.title
+ models.Book.from_text_and_meta(
+ ContentFile(book_text.encode('utf-8')),
+ info)
def test_book_tags(self):
""" book should have own tags and whole tree's themes """
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.core.files.storage import DefaultStorage
from django.core.files.uploadedfile import UploadedFile
from django.http import HttpResponse
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from reporting.utils import read_chunks
randrange = random.SystemRandom().randrange
else:
randrange = random.randrange
-MAX_SESSION_KEY = 18446744073709551616L # 2 << 63
+MAX_SESSION_KEY = 18446744073709551616 # 2 << 63
def get_random_hash(seed):
- sha_digest = hashlib.sha1('%s%s%s%s' % (
- randrange(0, MAX_SESSION_KEY), time.time(), unicode(seed).encode('utf-8', 'replace'), settings.SECRET_KEY)
- ).digest()
- return urlsafe_b64encode(sha_digest).replace('=', '').replace('_', '-').lower()
+ sha_digest = hashlib.sha1((
+ '%s%s%s%s' % (
+ randrange(0, MAX_SESSION_KEY),
+ time.time(),
+ str(seed).encode('utf-8', 'replace'),
+ settings.SECRET_KEY
+ )
+ ).encode('utf-8')).digest()
+ return urlsafe_b64encode(sha_digest).decode('latin1').replace('=', '').replace('_', '-').lower()
def split_tags(*tag_lists):
This is just a version of django.utils.text.truncate_html_words with no space before the end_text.
"""
- s = force_unicode(s)
+ s = force_text(s)
length = int(num)
if length <= 0:
return u''
raise ResponseInstead(pdcounter_views.author_detail(request, chunks[1]))
else:
raise Http404
- except Tag.MultipleObjectsReturned, e:
+ except Tag.MultipleObjectsReturned as e:
# Ask the user to disambiguate
raise ResponseInstead(differentiate_tags(request, e.tags, e.ambiguous_slugs))
- except Tag.UrlDeprecationWarning, e:
+ except Tag.UrlDeprecationWarning as e:
raise ResponseInstead(HttpResponsePermanentRedirect(
reverse('tagged_object_list', args=['/'.join(tag.url_chunk for tag in e.tags)])))
verbose_name = _('chunk')
verbose_name_plural = _('chunks')
- def __unicode__(self):
+ def __str__(self):
return self.key
def save(self, *args, **kwargs):
ordering = ('key',)
verbose_name, verbose_name_plural = _('attachment'), _('attachments')
- def __unicode__(self):
+ def __str__(self):
return self.key
list_search = ['email']
list_filter = ['is_active', 'is_cancelled']
date_hierarchy = 'started_at'
+ raw_id_fields = ['membership']
inlines = [PaymentInline]
admin.site.register(models.Schedule, ScheduleAdmin)
class MembershipAdmin(admin.ModelAdmin):
- pass
+ list_display = ['user']
+ raw_id_fields = ['user']
+ search_fields = ['user__username', 'user__email']
admin.site.register(models.Membership, MembershipAdmin)
# -*- coding: utf-8
from django import forms
from . import models
-from . import widgets
from .payment_methods import method_by_slug
verbose_name = _('plan')
verbose_name_plural = _('plans')
- def __unicode__(self):
+ def __str__(self):
return "%s %s" % (self.min_amount, self.get_interval_display())
class Meta:
verbose_name = _('schedule')
verbose_name_plural = _('schedules')
- def __unicode__(self):
+ def __str__(self):
return self.key
def save(self, *args, **kwargs):
verbose_name = _('payment')
verbose_name_plural = _('payments')
- def __unicode__(self):
+ def __str__(self):
return "%s %s" % (self.schedule, self.payed_at)
verbose_name = _('membership')
verbose_name_plural = _('memberships')
- def __unicode__(self):
- return u'tow. ' + unicode(self.user)
+ def __str__(self):
+ return u'tow. ' + str(self.user)
class ReminderEmail(models.Model):
verbose_name_plural = _('reminder emails')
ordering = ['days_before']
- def __unicode__(self):
+ def __str__(self):
if self.days_before >= 0:
return ungettext('a day before expiration', '%d days before expiration', n=self.days_before)
else:
for key in keys:
if key not in record:
record[key] = ''
- if isinstance(record[key], basestring):
+ if isinstance(record[key], str):
pass
elif isinstance(record[key], bool):
record[key] = 'tak' if record[key] else 'nie'
- elif isinstance(record[key], (list, tuple)) and all(isinstance(v, basestring) for v in record[key]):
+ elif isinstance(record[key], (list, tuple)) and all(isinstance(v, str) for v in record[key]):
record[key] = ', '.join(record[key])
else:
record[key] = json.dumps(record[key])
import yaml
from hashlib import sha1
from django.db import models
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField
from . import app_settings
if type(value) in (tuple, list, dict):
value = yaml.safe_dump(value, allow_unicode=True, default_flow_style=False)
if for_html:
- value = smart_unicode(value).replace(u" ", unichr(160))
+ value = smart_text(value).replace(u" ", unichr(160))
return value
class Meta:
verbose_name = _('submitted form')
verbose_name_plural = _('submitted forms')
- def __unicode__(self):
- return unicode(self.created_at)
+ def __str__(self):
+ return str(self.created_at)
def digest(self):
- serialized_body = ';'.join(sorted('%s:%s' % item for item in self.body.iteritems()))
+ serialized_body = ';'.join(sorted('%s:%s' % item for item in self.body.items()))
data = '%s%s%s%s%s' % (self.id, self.contact, serialized_body, self.ip, self.form_tag)
return sha1(data).hexdigest()
-# -*- coding: utf-8 -*-
-from urllib import unquote
+from urllib.parse import unquote
from datetime import datetime
from django.contrib.auth.decorators import permission_required
if request.method == 'POST':
formsets = {
prefix: formset_class(request.POST, request.FILES, prefix=prefix)
- for prefix, formset_class in formset_classes.iteritems()}
+ for prefix, formset_class in formset_classes.items()}
if form.is_valid() and all(formset.is_valid() for formset in formsets.itervalues()):
contact = form.save(request, formsets.values())
if form.result_page:
else:
return redirect('contact_thanks', form_tag)
else:
- formsets = {prefix: formset_class(prefix=prefix) for prefix, formset_class in formset_classes.iteritems()}
+ formsets = {prefix: formset_class(prefix=prefix) for prefix, formset_class in formset_classes.items()}
return render(
request, ['contact/%s/form.html' % form_tag, 'contact/form.html'],
class Meta:
ordering = ['qualifier']
- def __unicode__(self):
+ def __str__(self):
return self.name or self.qualifier
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from optparse import make_option
from django.core.management.base import BaseCommand
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, help='Suppress output'),
- )
help = 'Sends relevant funding notifications.'
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-q', '--quiet', action='store_false', dest='verbose',
+ default=True, help='Suppress output')
+
def handle(self, **options):
from datetime import date, timedelta
for offer in Offer.past().filter(notified_end=None):
if verbose:
- print 'Notify end:', offer
+ print('Notify end:', offer)
# The 'WL fund' list needs to be updated.
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
offer.flush_includes()
current.end <= date.today() + timedelta(app_settings.DAYS_NEAR - 1) and
not current.notified_near):
if verbose:
- print 'Notify near:', current
+ print('Notify near:', current)
current.notify_near()
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from datetime import date, datetime
-from urllib import urlencode
+from urllib.parse import urlencode
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
verbose_name_plural = _('offers')
ordering = ['-end']
- def __unicode__(self):
+ def __str__(self):
return u"%s - %s" % (self.author, self.title)
def get_absolute_url(self):
verbose_name_plural = _('perks')
ordering = ['-price']
- def __unicode__(self):
+ def __str__(self):
return "%s (%s%s)" % (self.name, self.price, u" for %s" % self.offer if self.offer else "")
""" QuerySet for all completed payments. """
return cls.objects.exclude(payed_at=None)
- def __unicode__(self):
- return unicode(self.offer)
+ def __str__(self):
+ return str(self.offer)
def get_absolute_url(self):
return reverse('funding_funding', args=[self.pk])
verbose_name_plural = _('money spent on books')
ordering = ['-timestamp']
- def __unicode__(self):
- return u"Spent: %s" % unicode(self.book)
+ def __str__(self):
+ return u"Spent: %s" % str(self.book)
@receiver(getpaid.signals.new_payment_query)
# Punctuation is handled correctly and escaped as needed,
# with the notable exception of backslash.
sane_in_payu_title = re.escape(
- string.uppercase +
- string.lowercase +
+ string.ascii_uppercase +
+ string.ascii_lowercase +
u'ąćęłńóśźżĄĆĘŁŃÓŚŹŻ' +
string.digits +
' ' +
def sanitize_payment_title(value):
- return re.sub('[^%s]' % sane_in_payu_title, replace_char, unicode(value))
+ return re.sub('[^%s]' % sane_in_payu_title, replace_char, str(value))
verbose_name = _('info page')
verbose_name_plural = _('info pages')
- def __unicode__(self):
+ def __str__(self):
return self.title
@models.permalink
# -*- coding: utf-8 -*-
from datetime import date
-from urllib2 import urlopen
+from urllib.request import urlopen
from django import forms
from django.utils.translation import ugettext_lazy as _
for record in ONIXRecord.objects.all():
xml += self.render_product(record)
xml += FOOTER
- print xml.encode('utf-8')
+ print(xml.encode('utf-8'))
def render_product(self, record):
if record.product_form_detail:
def get_descendants(element, tags):
- if isinstance(tags, basestring):
+ if isinstance(tags, str):
tags = [tags]
return element.findall('.//' + '/'.join(ONIXNS(tag) for tag in tags))
class Command(BaseCommand):
help = "Import data from ONIX."
- args = 'filename'
- def handle(self, filename, *args, **options):
+ def add_arguments(self, parser):
+ parser.add_argument('filename')
+
+ def handle(self, **options):
+ filename = options['filename']
tree = etree.parse(open(filename))
for product in get_descendants(tree, 'Product'):
isbn = get_field(product, ['ProductIdentifier', 'IDValue'])
assert len(isbn) == 13
- pool = ISBNPool.objects.get(prefix__in=[isbn[:i] for i in xrange(8, 11)])
+ pool = ISBNPool.objects.get(prefix__in=[isbn[:i] for i in range(8, 11)])
contributors = [
self.parse_contributor(contributor)
for contributor in get_descendants(product, 'Contributor')]
get_field(product, ['PublishingDate', 'Date'], allow_multiple=True)),
'contributors': contributors,
}
- for field, tag in DIRECT_FIELDS.iteritems():
+ for field, tag in DIRECT_FIELDS.items():
record_data[field] = get_field(product, tag) or ''
record = ONIXRecord.objects.create(**record_data)
ONIXRecord.objects.filter(pk=record.pk).update(datestamp=parse_date(product.attrib['datestamp']))
contributor_data = {
'role': get_field(contributor, 'ContributorRole'),
}
- for key, value in data.iteritems():
+ for key, value in data.items():
if value:
contributor_data[key] = value
if contributor_data.get('name') == UNKNOWN:
next_suffix = models.IntegerField()
purpose = models.CharField(max_length=4, choices=PURPOSE_CHOICES)
- def __unicode__(self):
+ def __str__(self):
return self.prefix
@classmethod
if record.product_form_detail:
return PRODUCT_FORMATS[record.product_form_detail][0]
else:
- return [key for key, value in PRODUCT_FORMS.iteritems() if value == record.product_form][0]
+ return [key for key, value in PRODUCT_FORMS.items() if value == record.product_form][0]
@permission_required('add_onixrecord')
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import re
-from cPickle import dump
-from optparse import make_option
+from pickle import dump
from django.core.management.base import BaseCommand
from django.core.management.color import color_style
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-t', '--tags', dest='tags', metavar='SLUG,...',
- help='Use only books tagged with this tags'),
- make_option('-i', '--include', dest='include', metavar='SLUG,...',
- help='Include specific books by slug'),
- make_option('-e', '--exclude', dest='exclude', metavar='SLUG,...',
- help='Exclude specific books by slug')
- )
- help = 'Prepare data for Lesmianator.'
+ help = 'Prepare data for Leśmianator.'
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-t', '--tags', dest='tags', metavar='SLUG,...',
+ help='Use only books tagged with this tags')
+ parser.add_argument(
+ '-i', '--include', dest='include', metavar='SLUG,...',
+ help='Include specific books by slug')
+ parser.add_argument(
+ '-e', '--exclude', dest='exclude', metavar='SLUG,...',
+ help='Exclude specific books by slug')
def handle(self, *args, **options):
self.style = color_style()
try:
path = settings.LESMIANATOR_PICKLE
except AttributeError:
- print self.style.ERROR('LESMIANATOR_PICKLE not set in the settings.')
+ print(self.style.ERROR('LESMIANATOR_PICKLE not set in the settings.'))
return
books = []
processed = skipped = 0
for book in books:
if verbose >= 2:
- print 'Parsing', book.slug
+ print('Parsing', book.slug)
if not book.txt_file:
if verbose >= 1:
- print self.style.NOTICE('%s has no TXT file' % book.slug)
+ print(self.style.NOTICE('%s has no TXT file' % book.slug))
skipped += 1
continue
f = open(book.txt_file.path)
m = re_text(f.read())
if not m:
- print self.style.ERROR("Unknown text format: %s" % book.slug)
+ print(self.style.ERROR("Unknown text format: %s" % book.slug))
skipped += 1
continue
processed += 1
last_word = ''
- text = unicode(m.group(1), 'utf-8').lower()
+ text = str(m.group(1), 'utf-8').lower()
for letter in text:
mydict = lesmianator.setdefault(last_word, {})
mydict.setdefault(letter, 0)
if not processed:
if skipped:
- print self.style.ERROR("No books with TXT files found")
+ print(self.style.ERROR("No books with TXT files found"))
else:
- print self.style.ERROR("No books found")
+ print(self.style.ERROR("No books found"))
return
try:
dump(lesmianator, open(path, 'w'))
except IOError:
- print self.style.ERROR("Couldn't write to $s" % path)
+ print(self.style.ERROR("Couldn't write to $s" % path))
return
dump(lesmianator, open(path, 'w'))
if verbose >= 1:
- print "%d processed, %d skipped" % (processed, skipped)
- print "Results dumped to %s" % path
+ print("%d processed, %d skipped" % (processed, skipped))
+ print("Results dumped to %s" % path)
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-import cPickle
-from cPickle import PickleError
+import pickle
+from pickle import PickleError
from datetime import datetime
from random import randint
-from StringIO import StringIO
from django.core.files.base import ContentFile
from django.db import models
try:
f = open(settings.LESMIANATOR_PICKLE)
- global_dictionary = cPickle.load(f)
+ global_dictionary = pickle.load(f)
f.close()
except (IOError, AttributeError, PickleError):
global_dictionary = {}
self.seen_at = datetime.utcnow().replace(tzinfo=utc)
self.save()
- def __unicode__(self):
+ def __str__(self):
return "%s (%s...)" % (self.slug, self.text[:20])
@staticmethod
class Meta:
unique_together = (('content_type', 'object_id'), )
- def __unicode__(self):
- return "Continuations for: %s" % unicode(self.content_object)
+ def __str__(self):
+ return "Continuations for: %s" % str(self.content_object)
@staticmethod
def join_conts(a, b):
@classmethod
def for_book(cls, book, length=3):
# count from this book only
- output = StringIO()
wldoc = book.wldocument(parse_dublincore=False)
output = wldoc.as_text(('raw-text',)).get_bytes()
del wldoc
if not obj.pickle:
raise cls.DoesNotExist
f = open(obj.pickle.path)
- keys, conts = cPickle.load(f)
+ keys, conts = pickle.load(f)
f.close()
if set(keys) != should_keys:
raise cls.DoesNotExist
raise NotImplementedError('Lesmianator continuations: only Book and Tag supported')
c, created = cls.objects.get_or_create(content_type=object_type, object_id=sth.id)
- c.pickle.save(sth.slug+'.p', ContentFile(cPickle.dumps((should_keys, conts))))
+ c.pickle.save(sth.slug+'.p', ContentFile(pickle.dumps((should_keys, conts))))
c.save()
return conts
verbose_name = _('catalog')\r
verbose_name_plural = _('catalogs')\r
\r
- def __unicode__(self):\r
+ def __str__(self):\r
return self.name\r
\r
@models.permalink\r
verbose_name = _('library')\r
verbose_name_plural = _('libraries')\r
\r
- def __unicode__(self):\r
+ def __str__(self):\r
return self.name\r
\r
@models.permalink\r
verbose_name = _('subscription')
verbose_name_plural = _('subscriptions')
- def __unicode__(self):
+ def __str__(self):
return self.email
def hashcode(self):
def identify(self, **kw):
ident = common.Identify(
'Wolne Lektury', # generate
- '%s/oaipmh' % unicode(WL_BASE), # generate
+ '%s/oaipmh' % str(WL_BASE), # generate
'2.0', # version
[m[1] for m in settings.MANAGERS], # adminEmails
make_time_naive(self.earliest_datestamp), # earliest datestamp of any change
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import os.path
-from urlparse import urljoin
+from urllib.parse import urljoin
from django.contrib.syndication.views import Feed
from django.core.urlresolvers import reverse
_book_parent_img = lazy(lambda: full_url(os.path.join(settings.STATIC_URL, "img/book-parent.png")), str)()
try:
- _book_parent_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book-parent.png")))
+ _book_parent_img_size = str(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book-parent.png")))
except OSError:
_book_parent_img_size = ''
_book_img = lazy(lambda: full_url(os.path.join(settings.STATIC_URL, "img/book.png")), str)()
try:
- _book_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book.png")))
+ _book_img_size = str(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book.png")))
except OSError:
_book_img_size = ''
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.contrib.auth.models import User
-from mock import MagicMock, Mock, patch, DEFAULT
+from unittest.mock import MagicMock, Mock, patch, DEFAULT
from catalogue.test_utils import WLTestCase
from .models import BillingAgreement, BillingPlan
from .rest import user_is_subscribed
try:
approval_url = agreement_approval_url(amount, app=app)
except PaypalError as e:
- return render(request, 'paypal/error_page.html', {'error': e.message})
+ return render(request, 'paypal/error_page.html', {'error': str(e)})
return HttpResponseRedirect(approval_url)
else:
form = PaypalSubscriptionForm()
def category(self):
return "author"
- def __unicode__(self):
+ def __str__(self):
return self.name
def __repr__(self):
verbose_name = _('book stub')
verbose_name_plural = _('book stubs')
- def __unicode__(self):
+ def __str__(self):
return self.title
@permalink
for field in areas_json[u'things'].values():
field[u'object'] = field[u'object'].capitalize()
pic.areas_json = areas_json
- html_text = unicode(render_to_string('picture/picture_info.html', {
+ html_text = render_to_string('picture/picture_info.html', {
'things': pic.areas_json['things'],
'themes': pic.areas_json['themes'],
- }))
+ })
pic.html_file.save("%s.html" % pic.slug, ContentFile(html_text))
pic.save()
from catalogue.models.tag import prefetched_relations
from catalogue.utils import split_tags
from picture import tasks
-from StringIO import StringIO
+from io import BytesIO
import jsonfield
import itertools
import logging
return ret
- def __unicode__(self):
+ def __str__(self):
return self.title
def authors(self):
close_image_file = False
if image_file is not None and not isinstance(image_file, File):
- image_file = File(open(image_file))
+ image_file = File(open(image_file, 'rb'))
close_image_file = True
if not isinstance(xml_file, File):
raise Picture.AlreadyExists('Picture %s already exists' % picture_xml.slug)
picture.areas.all().delete()
- picture.title = unicode(picture_xml.picture_info.title)
+ picture.title = str(picture_xml.picture_info.title)
picture.extra_info = picture_xml.picture_info.to_dict()
picture_tags = set(catalogue.models.Tag.tags_from_info(picture_xml.picture_info))
picture.width, picture.height = modified.size
- modified_file = StringIO()
+ modified_file = BytesIO()
modified.save(modified_file, format='JPEG', quality=95)
# FIXME: hardcoded extension - detect from DC format or orginal filename
picture.image_file.save(path.basename(picture_xml.image_path), File(modified_file))
index.index_tags()
if commit:
index.index.commit()
- except Exception, e:
+ except Exception as e:
index.index.rollback()
raise e
import picture.models
pic = picture.models.Picture.objects.get(pk=picture_id)
- html_text = unicode(render_to_string('picture/picture_info.html', {
+ html_text = render_to_string('picture/picture_info.html', {
'things': pic.areas_json['things'],
'themes': pic.areas_json['themes'],
- }))
+ })
pic.html_file.save("%s.html" % pic.slug, ContentFile(html_text))
from picture.models import Picture
try:
return Picture.objects.get(id=picture_id).search_index(picture_info, **kwargs)
- except Exception, e:
- print "Exception during index: %s" % e
+ except Exception as e:
+ print("Exception during index: %s" % e)
print_exc()
raise e
crop="%dpx %dpx %dpx %dpx" % tuple(map(lambda d: max(0, d), tuple(coords[0] + coords[1]))))
except ZeroDivisionError:
return ''
- except Exception, e:
+ except Exception as e:
logging.exception("Error creating a thumbnail for PictureArea")
return ''
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
raise ValidationError(_('Slug of an open poll needs to be unique'))
return super(Poll, self).clean()
- def __unicode__(self):
+ def __str__(self):
return self.question[:100] + ' (' + self.slug + ')'
def get_absolute_url(self):
verbose_name = _('vote item')
verbose_name_plural = _('vote items')
- def __unicode__(self):
- return self.content + ' @ ' + unicode(self.poll)
+ def __str__(self):
+ return self.content + ' @ ' + str(self.poll)
@property
def vote_ratio(self):
class Meta:
ordering = ['-timestamp']
- def __unicode__(self):
+ def __str__(self):
return '%s: %s' % (self.timestamp, self.title)
:param dict add_files: a dictionary of additional files XeTeX will need
"""
- from StringIO import StringIO
+ from io import BytesIO
import shutil
from tempfile import mkdtemp
import subprocess
from django.template.loader import render_to_string
rendered = render_to_string(template, context)
- texml = StringIO(rendered.encode('utf-8'))
+ texml = BytesIO(rendered.encode('utf-8'))
tempdir = mkdtemp(prefix="render_to_pdf-")
tex_path = os.path.join(tempdir, "doc.tex")
with open(tex_path, 'w') as tex_file:
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from sunburnt import sunburnt
+from scorched import connection
from lxml import etree
-import urllib
+from urllib.parse import urlencode
import warnings
-from sunburnt import search
+from scorched import search
import copy
from httplib2 import socket
import re
def update(self, positions=False, fields=None):
if fields is None:
fields = []
- if isinstance(fields, basestring):
+ if isinstance(fields, (str, bytes)):
fields = [fields]
self.schema.check_fields(fields, {"stored": True})
self.fields.update(fields)
return opts
-class CustomSolrConnection(sunburnt.SolrConnection):
+class CustomSolrConnection(connection.SolrConnection):
def __init__(self, *args, **kw):
super(CustomSolrConnection, self).__init__(*args, **kw)
self.analysis_url = self.url + "analysis/field/"
def analyze(self, params):
- qs = urllib.urlencode(params)
+ qs = urlencode(params)
url = "%s?%s" % (self.analysis_url, qs)
if len(url) > self.max_length_get_url:
warnings.warn("Long query URL encountered - POSTing instead of GETting. "
kwargs = dict(method="GET")
r, c = self.request(url, **kwargs)
if r.status != 200:
- raise sunburnt.SolrError(r, c)
+ raise connection.SolrError(r, c)
return c
-# monkey patching sunburnt SolrSearch
+# monkey patching scorched SolrSearch
search.SolrSearch.option_modules += ('term_vectorer',)
setattr(search.SolrSearch, '_init_common_modules', __patched__init_common_modules)
-class CustomSolrInterface(sunburnt.SolrInterface):
+class CustomSolrInterface(connection.SolrInterface):
# just copied from parent and SolrConnection -> CustomSolrConnection
def __init__(self, url, schemadoc=None, http_connection=None, mode='', retry_timeout=-1,
- max_length_get_url=sunburnt.MAX_LENGTH_GET_URL):
+ max_length_get_url=connection.MAX_LENGTH_GET_URL):
self.conn = CustomSolrConnection(url, http_connection, retry_timeout, max_length_get_url)
self.schemadoc = schemadoc
if 'w' not in mode:
self.readable = False
try:
self.init_schema()
- except socket.error, e:
- raise socket.error, "Cannot connect to Solr server, and search indexing is enabled (%s)" % str(e)
+ except socket.error as e:
+ raise socket.error("Cannot connect to Solr server, and search indexing is enabled (%s)" % str(e))
def _analyze(self, **kwargs):
if not self.readable:
if 'query' in kwargs:
args['q'] = kwargs['q']
- params = map(lambda (k, v): (k.replace('_', '.'), v), sunburnt.params_from_dict(**args))
+ params = map(lambda k, v: (k.replace('_', '.'), v), connection.params_from_dict(**args))
content = self.conn.analyze(params)
doc = etree.fromstring(content)
def analyze(self, **kwargs):
doc = self._analyze(**kwargs)
terms = doc.xpath("//lst[@name='index']/arr[last()]/lst/str[1]")
- terms = map(lambda n: unicode(n.text), terms)
+ terms = map(lambda n: str(n.text), terms)
return terms
def expand_margins(self, text, start, end):
#
from django import forms
from django.forms.utils import flatatt
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
from django.utils.safestring import mark_safe
from json import dumps
final_attrs = self.build_attrs(self.attrs, attrs)
final_attrs["name"] = name
if value:
- final_attrs['value'] = smart_unicode(value)
+ final_attrs['value'] = smart_text(value)
if 'id' not in self.attrs:
final_attrs['id'] = 'id_%s' % name
import picture.models
from pdcounter.models import Author as PDCounterAuthor, BookStub as PDCounterBook
from itertools import chain
-import sunburnt
-import custom
+import scorched
+from . import custom
import operator
import logging
from wolnelektury.utils import makedirs
"""
uids = set()
for q in queries:
- if isinstance(q, sunburnt.search.LuceneQuery):
+ if isinstance(q, scorched.search.LuceneQuery):
q = self.index.query(q)
q.field_limiter.update(['uid'])
st = 0
elif type_indicator == dcparser.as_person:
p = getattr(book_info, field.name)
if isinstance(p, dcparser.Person):
- persons = unicode(p)
+ persons = str(p)
else:
- persons = ', '.join(map(unicode, p))
+ persons = ', '.join(map(str, p))
fields[field.name] = persons
elif type_indicator == dcparser.as_date:
dt = getattr(book_info, field.name)
fid = start.attrib['id'][1:]
handle_text.append(lambda text: None)
if start.text is not None:
- fragments[fid]['themes'] += map(unicode.strip, map(unicode, (start.text.split(','))))
+ fragments[fid]['themes'] += map(str.strip, map(str, (start.text.split(','))))
elif end is not None and end.tag == 'motyw':
handle_text.pop()
result._book = book
return result
- def __unicode__(self):
+ def __str__(self):
return u"<SR id=%d %d(%d) hits score=%f %d snippets>" % \
(self.book_id, len(self._hits),
len(self._processed_hits) if self._processed_hits else -1,
self._score, len(self.snippets))
- def __str__(self):
- return unicode(self).encode('utf-8')
+ def __bytes__(self):
+ return str(self).encode('utf-8')
@property
def score(self):
if self.query_terms is not None:
for i in range(0, len(f[self.OTHER]['themes'])):
tms = f[self.OTHER]['themes'][i].split(r' +') + f[self.OTHER]['themes_pl'][i].split(' ')
- tms = map(unicode.lower, tms)
+ tms = map(str.lower, tms)
for qt in self.query_terms:
if qt in tms:
themes_hit.add(f[self.OTHER]['themes'][i])
self._hits.append(hit)
- def __unicode__(self):
+ def __str__(self):
return u"<PR id=%d score=%f >" % (self.picture_id, self._score)
def __repr__(self):
- return unicode(self)
+ return str(self)
@property
def score(self):
if self.query_terms is not None:
for i in range(0, len(hit[self.OTHER]['themes'])):
tms = hit[self.OTHER]['themes'][i].split(r' +') + hit[self.OTHER]['themes_pl'][i].split(' ')
- tms = map(unicode.lower, tms)
+ tms = map(str.lower, tms)
for qt in self.query_terms:
if qt in tms:
themes_hit.add(hit[self.OTHER]['themes'][i])
num -= 1
idx += 1
- except IOError, e:
+ except IOError as e:
book = catalogue.models.Book.objects.filter(id=book_id)
if not book:
log.error("Book does not exist for book id = %d" % book_id)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.core.management.base import BaseCommand
-from optparse import make_option
-
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
class Command(BaseCommand):
help = 'Reindex everything.'
- args = ''
-
- option_list = BaseCommand.option_list + (
- make_option('-n', '--book-id', action='store_true', dest='book_id', default=False,
- help='book id instead of slugs'),
- make_option('-t', '--just-tags', action='store_true', dest='just_tags', default=False,
- help='just reindex tags'),
- make_option('--start', dest='start_from', default=None, help='start from this slug'),
- make_option('--stop', dest='stop_after', default=None, help='stop after this slug'),
- )
- def handle(self, *args, **opts):
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-n', '--book-id', action='store_true', dest='book_id',
+ default=False, help='book id instead of slugs')
+ parser.add_argument(
+ '-t', '--just-tags', action='store_true', dest='just_tags',
+ default=False, help='just reindex tags')
+ parser.add_argument(
+ '--start', dest='start_from', default=None,
+ help='start from this slug')
+ parser.add_argument(
+ '--stop', dest='stop_after', default=None,
+ help='stop after this slug')
+ parser.add_argument('args', nargs='*', metavar='slug/id')
+
+ def handle(self, **opts):
from catalogue.models import Book
from search.index import Index
idx = Index()
if not opts['just_tags']:
- if args:
+ if opts['args']:
books = []
- for a in args:
+ for a in opts['args']:
if opts['book_id']:
books += Book.objects.filter(id=int(a)).all()
else:
if stop_after and slug > stop_after:
break
if not start_from or slug >= start_from:
- print b.slug
+ print(b.slug)
idx.index_book(b)
idx.index.commit()
books.pop(0)
if not retry:
break
- print 'Reindexing tags.'
+ print('Reindexing tags.')
idx.index_tags()
idx.index.commit()
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.core.management.base import BaseCommand
-from optparse import make_option
-
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
class Command(BaseCommand):
help = 'Reindex pictures.'
- args = ''
- option_list = BaseCommand.option_list + (
- make_option('-n', '--picture-id', action='store_true', dest='picture_id', default=False,
- help='picture id instead of slugs'),
- )
+ def add_arguments(self, parser):
+ self.add_argument(
+ '-n', '--picture-id', action='store_true', dest='picture_id',
+ default=False, help='picture id instead of slugs')
+ self.add_argument('slug/id', nargs='*', metavar='slug/id')
- def handle(self, *args, **opts):
+ def handle(self, **opts):
from picture.models import Picture
from search.index import Index
idx = Index()
- if args:
+ if opts['args']:
pictures = []
- for a in args:
+ for a in opts['args']:
if opts['picture_id']:
pictures += Picture.objects.filter(id=int(a)).all()
else:
while pictures:
try:
p = pictures[0]
- print p.slug
+ print(p.slug)
idx.index_picture(p)
idx.index.commit()
pictures.pop(0)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from django.core.management.base import BaseCommand
-
from glob import glob
from os import path
from django.conf import settings
+from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Check snippets.'
- args = ''
def handle(self, *args, **opts):
sfn = glob(settings.SEARCH_INDEX+'snippets/*')
for fn in sfn:
- print fn
+ print(fn)
bkid = path.basename(fn)
with open(fn) as f:
cont = f.read()
try:
cont.decode('utf-8')
except UnicodeDecodeError:
- print "error in snippets %s" % bkid
+ print("error in snippets %s" % bkid)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from mock import Mock
+from unittest.mock import Mock
from catalogue.models import Book, Tag
from random import randint, choice
def book_searched(context, result):
# We don't need hits which lead to sections but do not have
# snippets.
- hits = filter(lambda (idx, h):
+ hits = filter(lambda idx, h:
result.snippets[idx] is not None or ('fragment' in h and h['themes_hit']),
enumerate(result.hits))
# print "[tmpl: from %d hits selected %d]" % (len(result.hits), len(hits))
verbose_name = _('cite')
verbose_name_plural = _('cites')
- def __unicode__(self):
+ def __str__(self):
return u"%s: %s…" % (self.vip, self.text[:60])
def get_absolute_url(self):
return ''
ctx = {'tags': tags}
return template.loader.render_to_string('social/shelf_tags.html', ctx)
- return lazy(get_value, unicode)()
+ return lazy(get_value, str)()
"""
- if not isinstance(value, unicode):
- value = unicode(value, 'utf-8')
+ if not isinstance(value, str):
+ value = str(value, 'utf-8')
# try to replace chars
value = re.sub('[^a-zA-Z0-9\\s\\-]', replace_char, value)
#
import json
import time
-from StringIO import StringIO
+from io import BytesIO
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.template.loader import render_to_string
logo = models.ImageField(_('logo'), upload_to='sponsorzy/sponsor/logo')
url = models.URLField(_('url'), blank=True)
- def __unicode__(self):
+ def __str__(self):
return self.name
def description(self):
(THUMB_WIDTH - simg.size[0]) / 2,
i * THUMB_HEIGHT + (THUMB_HEIGHT - simg.size[1]) / 2,
))
- imgstr = StringIO()
+ imgstr = BytesIO()
sprite.save(imgstr, 'png')
if self.sprite:
html = property(fget=html)
def save(self, *args, **kwargs):
- if isinstance(self.sponsors, basestring):
+ if isinstance(self.sponsors, str):
# Walkaround for weird jsonfield 'no-decode' optimization.
self.sponsors = json.loads(self.sponsors)
self.render_sprite()
def flush_includes(self):
flush_ssi_includes(['/sponsors/page/%s.html' % self.name])
- def __unicode__(self):
+ def __str__(self):
return self.name
def render(self, name, value, attrs=None):
output = [super(SponsorPageWidget, self).render(name, value, attrs)]
- sponsors = [(unicode(obj), obj.pk, obj.logo.url) for obj in models.Sponsor.objects.all().iterator()]
+ sponsors = [(str(obj), obj.pk, obj.logo.url) for obj in models.Sponsor.objects.all().iterator()]
sponsors_js = ', '.join('{name: "%s", id: %d, image: "%s"}' % sponsor for sponsor in sponsors)
output.append(u'<script type="text/javascript">addEvent(window, "load", function(e) {')
# TODO: "id_" is hard-coded here. This should instead use the correct
#
from celery.task import task
from django.conf import settings
-import httplib
+from http.client import HTTPConnection
import logging
-import urlparse
+from urllib.parse import urlsplit
logger = logging.getLogger(__name__)
# Retrieve piwik information
try:
- _host = urlparse.urlsplit(settings.PIWIK_URL).netloc
+ _host = urlsplit(settings.PIWIK_URL).netloc
except AttributeError:
logger.debug("PIWIK_URL not configured.")
_host = None
@task(ignore_result=True)
def track_request(piwik_args):
piwik_url = "%s%s%s" % (settings.PIWIK_URL, u"/piwik.php?", piwik_args)
- conn = httplib.HTTPConnection(_host)
+ conn = HTTPConnection(_host)
conn.request('GET', piwik_url)
conn.close()
from random import random
from inspect import isclass
-from django.utils.encoding import force_str
+from django.utils.encoding import force_bytes
from .tasks import track_request
return urllib.urlencode(dict(
idsite=getattr(settings, 'PIWIK_SITE_ID', '0'),
rec=1,
- url=force_str('http://%s%s' % (request.META['HTTP_HOST'], request.path)),
+ url=force_bytes('http://%s%s' % (request.META['HTTP_HOST'], request.path)),
rand=int(random() * 0x10000),
apiv=PIWIK_API_VERSION,
- urlref=force_str(request.META.get('HTTP_REFERER', '')),
+ urlref=force_bytes(request.META.get('HTTP_REFERER', '')),
ua=request.META.get('HTTP_USER_AGENT', ''),
lang=request.META.get('HTTP_ACCEPT_LANGUAGE', ''),
token_auth=getattr(settings, 'PIWIK_TOKEN', ''),
verbose_name = _('suggestion')
verbose_name_plural = _('suggestions')
- def __unicode__(self):
- return unicode(self.created_at)
+ def __str__(self):
+ return str(self.created_at)
class PublishingSuggestion(models.Model):
spam = True
return spam
- def __unicode__(self):
- return unicode(self.created_at)
+ def __str__(self):
+ return str(self.created_at)
from contact.fields import HeaderField
from django import forms
-mark_safe_lazy = lazy(mark_safe, unicode)
+mark_safe_lazy = lazy(mark_safe, str)
class KonkursForm(ContactForm):
class Command(BaseCommand):
def handle(self, *args, **options):
- for provider, kept_fields in KEPT_FIELDS.iteritems():
+ for provider, kept_fields in KEPT_FIELDS.items():
for sa in SocialAccount.objects.filter(provider=provider):
- trimmed_data = {k: v for k, v in sa.extra_data.iteritems() if k in kept_fields}
+ trimmed_data = {k: v for k, v in sa.extra_data.items() if k in kept_fields}
sa.extra_data = trimmed_data
sa.save()
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from optparse import make_option
+import os
+import shutil
+import sys
+import tempfile
+import allauth
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.management import call_command
-from .translation2po import get_languages
from wolnelektury.utils import makedirs
+from .translation2po import get_languages
-import os
-import shutil
-import tempfile
-import sys
-
-import allauth
ROOT = settings.ROOT_DIR
if is_our_app(app):
try:
SOURCES.append(AppLocale(app))
- except LookupError, e:
- print "no locales in %s" % app.__name__
+ except LookupError as e:
+ print("no locales in %s" % app.__name__)
SOURCES.append(ModelTranslation('infopages', 'infopages_db'))
SOURCES.append(CustomLocale(os.path.dirname(allauth.__file__), name='contrib'))
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load',
- default=False),
- make_option('-c', '--compile', help='compile messages', action='store_true', dest='compile',
- default=False),
- make_option('-g', '--generate', help='generate messages', action='store_true', dest='generate',
- default=False),
- make_option('-L', '--lang', help='load just one language', dest='lang', default=None),
- make_option('-d', '--directory', help='load from this directory', dest='directory', default=None),
- make_option('-o', '--outfile', help='Resulting zip file', dest='outfile', default='./wl-locale.zip'),
- make_option('-m', '--merge', help='Use git to merge. Please use with clean working directory.',
- action='store_true', dest='merge', default=False),
- make_option('-M', '--message', help='commit message', dest='message', default='New locale'),
- )
help = 'Make a locale pack'
- args = ''
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-l', '--load', help='load locales back to source',
+ action='store_true', dest='load', default=False)
+ parser.add_argument(
+ '-c', '--compile', help='compile messages',
+ action='store_true', dest='compile', default=False)
+ parser.add_argument(
+ '-g', '--generate', help='generate messages',
+ action='store_true', dest='generate', default=False)
+ parser.add_argument(
+ '-L', '--lang', help='load just one language',
+ dest='lang', default=None)
+ parser.add_argument(
+ '-d', '--directory', help='load from this directory',
+ dest='directory', default=None)
+ parser.add_argument(
+ '-o', '--outfile', help='Resulting zip file',
+ dest='outfile', default='./wl-locale.zip')
+ parser.add_argument(
+ '-m', '--merge', action='store_true',
+ dest='merge', default=False,
+ help='Use git to merge. Please use with clean working directory.')
+ parser.add_argument(
+ '-M', '--message', help='commit message',
+ dest='message', default='New locale')
def current_rev(self):
return os.popen('git rev-parse HEAD').read()
for src in SOURCES:
src.compile()
- def handle(self, *a, **options):
+ def handle(self, **options):
if options['load']:
if not options['directory'] or not os.path.exists(options['directory']):
- print "Directory not provided or does not exist, please use -d"
+ print("Directory not provided or does not exist, please use -d")
sys.exit(1)
if options['merge']:
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import os
import time
-from optparse import make_option
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import models
-
import polib
from modeltranslation.translator import translator, NotRegistered
-
from wolnelektury.utils import makedirs
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('-d', '--directory', help='Specify which directory should hold generated PO files',
- dest='directory', default=''),
- make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load',
- default=False),
- make_option('-L', '--language', help='locales to load', dest='lang', default=None),
- make_option('-n', '--poname', help='name of the po file [no extension]', dest='poname', default=None),
- make_option('-k', '--keep-running', help='keep running even when missing an input file', dest='keep_running',
- default=False, action='store_true'),
- )
help = 'Export models from app to po files'
- args = 'app'
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-d', '--directory', dest='directory', default='',
+ help='Specify which directory should hold generated PO files')
+ parser.add_argument(
+ '-l', '--load', help='load locales back to source',
+ action='store_true', dest='load', default=False)
+ parser.add_argument(
+ '-L', '--language', help='locales to load',
+ dest='lang', default=None)
+ parser.add_argument(
+ '-n', '--poname', help='name of the po file [no extension]',
+ dest='poname', default=None)
+ parser.add_argument(
+ '-k', '--keep-running', dest='keep_running',
+ help='keep running even when missing an input file',
+ default=False, action='store_true')
+ parser.add_argument('app')
def get_models(self, app):
for mdname in dir(app.models):
else:
yield (md, opts)
- def handle(self, appname, **options):
+ def handle(self, **options):
+ appname = options['app']
if not options['poname']:
options['poname'] = appname
app = __import__(appname)
-# -*- coding: utf-8 -*-
# Original version taken from http://www.djangosnippets.org/snippets/186/
# Original author: udfalkso
# Modified by: Shwagroo Team
import hotshot
import hotshot.stats
import tempfile
-import StringIO
+import io
import pprint
from django.conf import settings
if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET:
self.prof.close()
- out = StringIO.StringIO()
+ out = io.BytesIO()
old_stdout = sys.stdout
sys.stdout = out
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
'ssify',
'django_extensions',
'raven.contrib.django.raven_compat',
-
'club.apps.ClubConfig',
- 'django_comments',
- 'django_comments_xtd',
- 'django_gravatar',
# allauth stuff
'allauth',
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import codecs
import csv
-import cStringIO
+from functools import wraps
+from inspect import getargspec
+from io import BytesIO
import json
import os
-from functools import wraps
-
import pytz
-from inspect import getargspec
-
import re
+
from django.core.mail import send_mail
from django.http import HttpResponse
from django.template.loader import render_to_string
from django.conf import settings
from django.utils.translation import ugettext
+
tz = pytz.timezone(settings.TIME_ZONE)
def stringify_keys(dictionary):
return dict((keyword.encode('ascii'), value)
- for keyword, value in dictionary.iteritems())
+ for keyword, value in dictionary.items())
def json_encode(obj, sort_keys=True, ensure_ascii=False):
if request_params:
request_params = dict(
(key, json_decode_fallback(value))
- for key, value in request_params.iteritems()
+ for key, value in request_params.items()
if fun_kwargs or key in fun_params)
kwargs.update(stringify_keys(request_params))
res = None
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
# Redirect output to a queue
- self.queue = cStringIO.StringIO()
+ self.queue = BytesIO()
self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
self.stream = f
self.encoder = codecs.getincrementalencoder(encoding)()