# -*- coding: utf-8 -*-
-from StringIO import StringIO
+from io import BytesIO
from catalogue.models import Book
from librarian import DocProvider
from django.http import HttpResponse
self.publishable = publishable
def by_slug(self, slug):
- return StringIO(Book.objects.get(dc_slug=slug
+ return BytesIO(Book.objects.get(dc_slug=slug
).materialize(publishable=self.publishable
).encode('utf-8'))
def fix_chunk(self, chunk, user, verbose=0, dry_run=False):
"""Runs the update for a single chunk."""
if verbose >= 2:
- print chunk.get_absolute_url()
+ print(chunk.get_absolute_url())
old_head = chunk.head
src = old_head.materialize()
try:
tree = etree.fromstring(src)
except:
if verbose:
- print "%s: invalid XML" % chunk.get_absolute_url()
+ print("%s: invalid XML" % chunk.get_absolute_url())
self.counters['Bad XML'] += 1
return
if not dry_run:
new_head = chunk.commit(
- etree.tostring(tree, encoding=unicode),
+ etree.tostring(tree, encoding='unicode'),
author=user,
description=self.commit_desc
)
if old_head.publishable:
new_head.set_publishable(True)
if verbose >= 2:
- print "done"
+ print("done")
self.counters['Updated chunks'] += 1
def run(self, user, verbose=0, dry_run=False, books=None):
def print_results(self):
"""Prints the counters."""
for item in sorted(self.counters.items()):
- print "%s: %d" % item
+ print("%s: %d" % item)
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import sys
-from optparse import make_option
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from catalogue.models import Book
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',
- default=True, help='Less output'),
- 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',
- help='Assign commits to this user (required, preferably yourself).'),
- )
args = "[slug]..."
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-q', '--quiet', action='store_false', dest='verbose',
+ default=True, help='Less output')
+ parser.add_argument(
+ '-d', '--dry-run', action='store_true', dest='dry_run',
+ default=False, help="Don't actually touch anything")
+ parser.add_argument(
+ '-u', '--username', dest='username', metavar='USER',
+ help='Assign commits to this user (required, preferably yourself).')
+
def handle(self, *args, **options):
verbose = options.get('verbose')
dry_run = options.get('dry_run')
if username:
user = User.objects.get(username=username)
else:
- print 'Please provide a username.'
+ print('Please provide a username.')
sys.exit(1)
books = Book.objects.filter(slug__in=args) if args else None
try:
WLURI.strict(elem.text)
except ValidationError:
- correct_field = unicode(WLURI.from_slug(
+ correct_field = str(WLURI.from_slug(
WLURI(elem.text.strip()).slug))
try:
WLURI.strict(correct_field)
# Can't make a valid WLURI out of it, leave as is.
return False
if verbose:
- print "Changing %s from %s to %s" % (
+ print("Changing %s from %s to %s" % (
elem.tag, elem.text, correct_field
- )
+ ))
elem.text = correct_field
return True
for field in BookInfo.FIELDS:
current_about = elem.get(attr_name)
if current_about != correct_about:
if verbose:
- print "Changing rdf:about from %s to %s" % (
+ print("Changing rdf:about from %s to %s" % (
current_about, correct_about
- )
+ ))
elem.set(attr_name, correct_about)
return True
from collections import defaultdict
import json
-from optparse import make_option
-import urllib2
+from urllib.request import urlopen
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('-q', '--quiet', action='store_false', dest='verbose', default=True,
- help='Less output'),
- )
help = 'Imports XML files from WL.'
+ def add_arguments(self, parser):
+ parser.add_argument('-q', '--quiet', action='store_false', dest='verbose', default=True,
+ help='Less output')
+
def handle(self, *args, **options):
self.style = color_style()
transaction.enter_transaction_management()
if verbose:
- print 'Reading currently managed files (skipping hidden ones).'
+ print('Reading currently managed files (skipping hidden ones).')
slugs = defaultdict(list)
for b in Book.objects.exclude(slug__startswith='.').all():
if verbose:
- print b.slug
+ print(b.slug)
text = b.materialize().encode('utf-8')
try:
info = BookInfo.from_bytes(text)
}
if verbose:
- print 'Opening books list'
- for book in json.load(urllib2.urlopen(WL_API)):
- book_detail = json.load(urllib2.urlopen(book['href']))
- xml_text = urllib2.urlopen(book_detail['xml']).read()
+ print('Opening books list')
+ for book in json.load(urlopen(WL_API)):
+ book_detail = json.load(urlopen(book['href']))
+ xml_text = urlopen(book_detail['xml']).read()
info = BookInfo.from_bytes(xml_text)
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:") % info.slug)
previous_book = previous_books[0]
comm = previous_book.slug
else:
previous_book = None
comm = '*'
- print book_count, info.slug , '-->', comm
+ 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
# Print results
- print
- print "Results:"
- print "Imported %d books from WL:" % (
- book_count, )
- print
+ print()
+ print("Results:")
+ print("Imported %d books from WL:" % (
+ book_count, ))
+ print()
transaction.commit()
import sys
from django.contrib.auth.models import User
from lxml import etree
-from optparse import make_option
-
from collections import defaultdict
from django.core.management import BaseCommand
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- # 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',
- # default=False, help="Don't actually touch anything"),
- make_option(
- '-u', '--username', dest='username', metavar='USER',
- help='Assign commits to this user (required, preferably yourself).'),
- )
args = 'csv_file'
+ def add_arguments(self, parser):
+ self.add_argument(
+ '-u', '--username', dest='username', metavar='USER',
+ help='Assign commits to this user (required, preferably yourself).')
+
def handle(self, csv_file, **options):
username = options.get('username')
if username:
user = User.objects.get(username=username)
else:
- print 'Please provide a username.'
+ print('Please provide a username.')
sys.exit(1)
csvfile = open(csv_file, 'rb')
csvfile.close()
for slug, isbn_list in isbn_lists.iteritems():
- print 'processing %s' % slug
+ print('processing %s' % slug)
book = Book.objects.get(dc_slug=slug)
chunk = book.chunk_set.first()
old_head = chunk.head
tree = etree.fromstring(src)
isbn_node = tree.find('.//' + DCNS("relation.hasFormat"))
if isbn_node is not None:
- print '%s already contains ISBN metadata, skipping' % slug
+ print('%s already contains ISBN metadata, skipping' % slug)
continue
desc = tree.find(".//" + RDFNS("Description"))
for format, isbn in isbn_list:
element.tail = '\n'
desc.append(element)
new_head = chunk.commit(
- etree.tostring(tree, encoding=unicode),
+ etree.tostring(tree, encoding='unicode'),
author=user,
description='automatyczne dodanie isbn'
)
- print 'committed %s' % slug
+ print('committed %s' % slug)
if old_head.publishable:
new_head.set_publishable(True)
else:
- print 'Warning: %s not publishable' % slug
+ print('Warning: %s not publishable' % slug)
-# -*- coding: utf-8 -*-
-#
# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import sys
from django.contrib.auth.models import User
-from optparse import make_option
-
from django.core.management import BaseCommand
from catalogue.models import Book, Chunk
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- # 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',
- # default=False, help="Don't actually touch anything"),
- make_option(
- '-u', '--username', dest='username', metavar='USER',
- help='Assign commits to this user (required).'),
- )
args = 'slug_file'
+ def add_arguments(self, parser):
+ self.add_argument(
+ '-u', '--username', dest='username', metavar='USER',
+ help='Assign commits to this user (required).')
+
def handle(self, slug_file, **options):
username = options.get('username')
if username:
user = User.objects.get(username=username)
else:
- print 'Please provide a username.'
+ print('Please provide a username.')
sys.exit(1)
slugs = [line.strip() for line in open(slug_file)]
books = Book.objects.filter(slug__in=slugs)
for book in books:
- print 'processing %s' % book.slug
+ print('processing %s' % book.slug)
for chunk in book.chunk_set.all():
src = chunk.head.materialize()
chunk.commit(
tags=[Chunk.tag_model.objects.get(slug='editor-proofreading')],
publishable=True
)
- print 'committed %s' % book.slug
+ print('committed %s' % book.slug)
-# -*- coding: utf-8 -*-
-
-from optparse import make_option
import sys
from django.contrib.auth.models import User
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- 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',
- 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,
- help='Less output'),
- 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,
- help='Dry run: do not actually change anything.'),
- 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 add_arguments(self, parser):
+ self.add_argument(
+ '-s', '--slug', dest='new_slug', metavar='SLUG',
+ help='New slug of the merged book (defaults to common part of all slugs).')
+ self.add_argument(
+ '-t', '--title', dest='new_title', metavar='TITLE',
+ help='New title of the merged book (defaults to common part of all titles).')
+ self.add_argument(
+ '-q', '--quiet', action='store_false', dest='verbose', default=True,
+ help='Less output')
+ self.add_argument(
+ '-g', '--guess', action='store_true', dest='guess', default=False,
+ help='Try to guess what merges are needed (but do not apply them).')
+ self.add_argument(
+ '-d', '--dry-run', action='store_true', dest='dry_run', default=False,
+ help='Dry run: do not actually change anything.')
+ self.add_argument(
+ '-f', '--force', action='store_true', dest='force', default=False,
+ help='On slug conflict, hide the original book to archive.')
def print_guess(self, dry_run=True, force=False):
from collections import defaultdict
def read_slug(slug):
res = []
- res.append((re.compile(ur'__?(przedmowa)$'), -1))
- res.append((re.compile(ur'__?(cz(esc)?|ksiega|rozdzial)__?(?P<n>\d*)$'), None))
- res.append((re.compile(ur'__?(rozdzialy__?)?(?P<n>\d*)-'), None))
+ res.append((re.compile(r'__?(przedmowa)$'), -1))
+ res.append((re.compile(r'__?(cz(esc)?|ksiega|rozdzial)__?(?P<n>\d*)$'), None))
+ res.append((re.compile(r'__?(rozdzialy__?)?(?P<n>\d*)-'), None))
for r, default in res:
m = r.search(slug)
conflicting_slugs.append(slug)
title = file_to_title(slug)
- print "./manage.py merge_books %s%s--title=%s --slug=%s \\\n %s\n" % (
+ print("./manage.py merge_books %s%s--title=%s --slug=%s \\\n %s\n" % (
'--dry-run ' if dry_run else '',
'--force ' if force else '',
quote(title), slug,
" \\\n ".join(merge_slugs)
- )
+ ))
if conflicting_slugs:
if force:
- print self.style.NOTICE('# These books will be archived:')
+ print(self.style.NOTICE('# These books will be archived:'))
else:
- print self.style.ERROR('# ERROR: Conflicting slugs:')
+ print(self.style.ERROR('# ERROR: Conflicting slugs:'))
for slug in conflicting_slugs:
- print '#', slug
+ print('#', slug)
def handle(self, *slugs, **options):
if guess:
if slugs:
- print "Please specify either slugs, or --guess."
+ print("Please specify either slugs, or --guess.")
return
else:
self.print_guess(dry_run, force)
return
if not slugs:
- print "Please specify some book slugs"
+ print("Please specify some book slugs")
return
# Start transaction management.
if dry_run and verbose:
- print self.style.NOTICE('DRY RUN: nothing will be changed.')
- print
+ print(self.style.NOTICE('DRY RUN: nothing will be changed.'))
+ print()
if verbose:
- print "New title:", self.style.NOTICE(new_title)
- print "New slug:", self.style.NOTICE(new_slug)
- print
+ print("New title:", self.style.NOTICE(new_title))
+ print("New slug:", self.style.NOTICE(new_slug))
+ print()
for i, book in enumerate(books):
chunk_titles = []
chunk_slugs.append(new_chunk_slug)
if verbose:
- print "title: %s // %s -->\n %s // %s\nslug: %s / %s -->\n %s / %s" % (
+ print("title: %s // %s -->\n %s // %s\nslug: %s / %s -->\n %s / %s" % (
book.title, chunk.title,
new_title, new_chunk_title,
book.slug, chunk.slug,
- new_slug, new_chunk_slug)
- print
+ new_slug, new_chunk_slug))
+ print()
if not dry_run:
try:
# FIXME: there still may be a conflict
conflict.slug = '.' + conflict.slug
conflict.save()
- print self.style.NOTICE('Book with slug "%s" moved to "%s".' % (new_slug, conflict.slug))
+ print(self.style.NOTICE('Book with slug "%s" moved to "%s".' % (new_slug, conflict.slug)))
else:
- print self.style.ERROR('ERROR: Book with slug "%s" exists.' % new_slug)
+ print(self.style.ERROR('ERROR: Book with slug "%s" exists.' % new_slug))
return
if i:
import sys
from django.contrib.auth.models import User
from lxml import etree
-from optparse import make_option
from django.core.management import BaseCommand
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- # 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',
- # default=False, help="Don't actually touch anything"),
- make_option(
- '-u', '--username', dest='username', metavar='USER',
- help='Assign commits to this user (required, preferably yourself).'),
- )
args = 'exclude_file'
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '-u', '--username', dest='username', metavar='USER',
+ help='Assign commits to this user (required, preferably yourself).')
+
def handle(self, exclude_file, **options):
username = options.get('username')
if username:
user = User.objects.get(username=username)
else:
- print 'Please provide a username.'
+ print('Please provide a username.')
sys.exit(1)
excluded_slugs = [line.strip() for line in open(exclude_file, 'rb') if line.strip()]
for book in books:
if not book.is_published():
continue
- print 'processing %s' % book.slug
+ print('processing %s' % book.slug)
chunk = book.chunk_set.first()
old_head = chunk.head
src = old_head.materialize()
tree = etree.fromstring(src)
audience_nodes = tree.findall('.//' + DCNS("audience"))
if not audience_nodes:
- print '%s has no audience, skipping' % book.slug
+ print('%s has no audience, skipping' % book.slug)
continue
for node in audience_nodes:
node.getparent().remove(node)
chunk.commit(
- etree.tostring(tree, encoding=unicode),
+ etree.tostring(tree, encoding='unicode'),
author=user,
description='automatyczne skasowanie audience',
publishable=old_head.publishable
)
- print 'committed %s' % book.slug
+ print('committed %s' % book.slug)
if not old_head.publishable:
- print 'Warning: %s not publishable, last head: %s, %s' % (
- book.slug, old_head.author.username, old_head.description[:40].replace('\n', ' '))
+ print('Warning: %s not publishable, last head: %s, %s' % (
+ book.slug, old_head.author.username, old_head.description[:40].replace('\n', ' ')))
class Meta:
proxy = True
- def __unicode__(self):
+ def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
def __len__(self):
return self.chunk_set.count()
- def __nonzero__(self):
+ def __bool__(self):
"""
Necessary so that __len__ isn't used for bool evaluation.
"""
return True
- def __unicode__(self):
+ def __str__(self):
return self.title
@models.permalink
try:
bi = self.wldocument(changes=changes, strict=True).book_info
- except ParseError, e:
- raise AssertionError(_('Invalid XML') + ': ' + unicode(e))
+ except ParseError as e:
+ raise AssertionError(_('Invalid XML') + ': ' + str(e))
except NoDublinCore:
raise AssertionError(_('No Dublin Core found.'))
- except ValidationError, e:
- raise AssertionError(_('Invalid Dublin Core') + ': ' + unicode(e))
+ except ValidationError as e:
+ raise AssertionError(_('Invalid Dublin Core') + ': ' + str(e))
valid_about = self.correct_about()
assert bi.about == valid_about, _("rdf:about is not") + " " + valid_about
def publishable_error(self):
try:
return self.assert_publishable()
- except AssertionError, e:
+ except AssertionError as e:
return e
else:
return None
# Representing
# ============
- def __unicode__(self):
+ def __str__(self):
return "%d:%d: %s" % (self.book_id, self.number, self.title)
@models.permalink
title = self.book.title
if self.title:
title += ", %s" % self.title
- if book_length > 1:
+ if book_length and book_length > 1:
title += " (%d/%d)" % (self.number, book_length)
return title
# Representing
# ============
- def __unicode__(self):
+ def __str__(self):
return self.title
@models.permalink
picture = WLPicture.from_bytes(
picture_xml.encode('utf-8'),
image_store=SelfImageStore)
- except ParseError, e:
+ except ParseError as e:
raise AssertionError(_('Invalid XML') + ': ' + str(e))
except NoDublinCore:
raise AssertionError(_('No Dublin Core found.'))
- except ValidationError, e:
+ except ValidationError as e:
raise AssertionError(_('Invalid Dublin Core') + ': ' + str(e))
valid_about = self.correct_about()
def publishable_error(self):
try:
return self.assert_publishable()
- except AssertionError, e:
+ except AssertionError as e:
return e
else:
return None
verbose_name = _('project')
verbose_name_plural = _('projects')
- def __unicode__(self):
+ def __str__(self):
return self.name
def get_fixture(path):
f_path = join(dirname(abspath(__file__)), 'tests/files', path)
with open(f_path) as f:
- return unicode(f.read(), 'utf-8')
+ return f.read()
from datetime import datetime, date, timedelta
import logging
import os
-from StringIO import StringIO
-from urllib import unquote
-from urlparse import urlsplit, urlunsplit
+from urllib.parse import unquote, urlsplit, urlunsplit
from django.conf import settings
from django.contrib import auth
if stage:
try:
stage = Chunk.tag_model.objects.get(slug=stage)
- except Chunk.DoesNotExist, e:
+ except Chunk.DoesNotExist as e:
stage = None
for c in chunks: c.stage = stage
if username:
try:
user = User.objects.get(username=username)
- except User.DoesNotExist, e:
+ except User.DoesNotExist as e:
user = None
for c in chunks: c.user = user
if project_id:
try:
project = Project.objects.get(pk=int(project_id))
- except (Project.DoesNotExist, ValueError), e:
+ except (Project.DoesNotExist, ValueError) as e:
project = None
for c in chunks:
book = c.book
if stage:
try:
stage = Image.tag_model.objects.get(slug=stage)
- except Image.DoesNotExist, e:
+ except Image.DoesNotExist as e:
stage = None
for c in images: c.stage = stage
if username:
try:
user = User.objects.get(username=username)
- except User.DoesNotExist, e:
+ except User.DoesNotExist as e:
user = None
for c in images: c.user = user
if project_id:
try:
project = Project.objects.get(pk=int(project_id))
- except (Project.DoesNotExist, ValueError), e:
+ except (Project.DoesNotExist, ValueError) as e:
project = None
for c in images:
c.project = project
book.publish(request.user, host=protocol + request.get_host(), days=days, beta=beta)
except NotAuthorizedError:
return http.HttpResponseRedirect(reverse('apiclient_oauth' if not beta else 'apiclient_beta_oauth'))
- except BaseException, e:
+ except BaseException as e:
return http.HttpResponse(repr(e))
else:
return http.HttpResponseRedirect(book.get_absolute_url())
image.publish(request.user)
except NotAuthorizedError:
return http.HttpResponseRedirect(reverse('apiclient_oauth'))
- except BaseException, e:
+ except BaseException as e:
return http.HttpResponse(e)
else:
return http.HttpResponseRedirect(image.get_absolute_url())
master.insert(0, trim_tag)
trim_tag.tail = '\n\n\n' + (master.text or '')
master.text = '\n'
- return unicode(etree.tostring(e, encoding="utf-8"), 'utf-8')
+ return str(etree.tostring(e, encoding="utf-8"), 'utf-8')
def add_trim_end(text):
prev.tail = (prev.tail or '') + '\n\n\n'
else:
master.text = (master.text or '') + '\n\n\n'
- return unicode(etree.tostring(e, encoding="utf-8"), 'utf-8')
+ return str(etree.tostring(e, encoding="utf-8"), 'utf-8')
def split_xml(text):
del parent[0]
element, parent = parent, parent.getparent()
chunks[:0] = [[name,
- unicode(etree.tostring(copied, encoding='utf-8'), 'utf-8')
+ str(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')
+ str(etree.tostring(src, encoding='utf-8'), 'utf-8')
]]
for ch in chunks[1:]:
# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from StringIO import StringIO
+from io import BytesIO
from django import forms
from django.conf import settings
raise forms.ValidationError(ugettext('No image specified'))
if download_url:
image_data = URLOpener().open(download_url).read()
- width, height = PILImage.open(StringIO(image_data)).size
+ width, height = PILImage.open(BytesIO(image_data)).size
else:
width, height = PILImage.open(uploaded_file.file).size
min_width, min_height = settings.MIN_COVER_SIZE
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import urllib2 as urllib
-from optparse import make_option
-
from django.core.files.base import ContentFile
from django.core.management import BaseCommand
class Command(BaseCommand):
- option_list = BaseCommand.option_list + (
- make_option('--from', dest='from_id', type=int, default=1),
- )
+ def add_arguments(self, parser):
+ parser.add_argument('--from', dest='from_id', type=int, default=1)
def handle(self, *args, **options):
from_id = options.get('from_id', 1)
images = Image.objects.filter(id__gte=from_id).exclude(book=None).order_by('id')
images = images.filter(source_url__contains='flickr.com').exclude(download_url__endswith='_o.jpg')
for image in images:
- print image.id
+ print(image.id)
try:
flickr_data = get_flickr_data(image.source_url)
- print flickr_data
+ print(flickr_data)
except FlickrError as e:
- print 'Flickr analysis failed: %s' % e
+ print('Flickr analysis failed: %s' % e)
else:
flickr_url = flickr_data['download_url']
if flickr_url != image.download_url:
same_url = Image.objects.filter(download_url=flickr_url)
if same_url:
- print 'Download url already present in image %s' % same_url.get().id
+ print('Download url already present in image %s' % same_url.get().id)
continue
try:
t = URLOpener().open(flickr_url).read()
except urllib.URLError:
- print 'Broken download url'
+ print('Broken download url')
except IOError:
- print 'Connection failed'
+ print('Connection failed')
else:
image.download_url = flickr_url
image.file.save(image.file.name, ContentFile(t))
verbose_name = _('cover image')
verbose_name_plural = _('cover images')
- def __unicode__(self):
+ def __str__(self):
return u"%s - %s" % (self.author, self.title)
@models.permalink
#
import json
import re
-from urllib import FancyURLopener
+from urllib.request import FancyURLopener
from django.contrib.sites.models import Site
abstract = True
ordering = ['ordering']
- def __unicode__(self):
+ def __str__(self):
return self.name
@classmethod
ordering = ('created_at',)
unique_together = ['tree', 'revision']
- def __unicode__(self):
+ def __str__(self):
return u"Id: %r, Tree %r, Parent %r, Data: %s" % (self.id, self.tree_id, self.parent_id, self.data)
def author_str(self):
f = self.data.storage.open(self.data)
text = f.read()
f.close()
- return unicode(text, 'utf-8')
+ return str(text, 'utf-8')
def merge_with(self, other, author=None,
author_name=None, author_email=None,
return model
-class Document(models.Model):
+class Document(models.Model, metaclass=DocumentMeta):
"""File in repository. Subclass it to use version control in your app."""
- __metaclass__ = DocumentMeta
-
# default repository path
REPO_PATH = os.path.join(settings.MEDIA_ROOT, 'dvcs')
class Meta:
abstract = True
- def __unicode__(self):
+ def __str__(self):
return u"{0}, HEAD: {1}".format(self.id, self.head_id)
def materialize(self, change=None):
This will automatically merge the commit into the main branch,
if parent is not document's head.
- :param unicode text: new version of the document
+ :param str text: new version of the document
:param parent: parent revision (head, if not specified)
:type parent: Change or None
:param User author: the commiter
- :param unicode author_name: commiter name (if ``author`` not specified)
- :param unicode author_email: commiter e-mail (if ``author`` not specified)
+ :param str author_name: commiter name (if ``author`` not specified)
+ :param str author_email: commiter e-mail (if ``author`` not specified)
:param Tag[] tags: list of tags to apply to the new commit
:param bool publishable: set new commit as ready to publish
:returns: new head
from django.core.files.base import ContentFile, File
from django.core.files.storage import FileSystemStorage
from django.utils.deconstruct import deconstructible
+from django.utils.encoding import force_bytes
@deconstructible
return ContentFile(decompress(text))
def _save(self, name, content):
- content = ContentFile(compress(content.read()))
+ data = force_bytes(content.read())
+ content = ContentFile(compress(data))
return super(GzipFileSystemStorage, self)._save(name, content)
+import codecs
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
mangled = "%s %s %s" % (name, at, (' %s ' % dot).join(domain.split('.')))
return mark_safe("<a class='mangled' data-addr1='%(name)s' "
"data-addr2='%(domain)s'>%(mangled)s</a>" % {
- 'name': name.encode('rot13'),
- 'domain': domain.encode('rot13'),
+ 'name': codecs.encode(name, 'rot13'),
+ 'domain': codecs.encode(domain, 'rot13'),
'mangled': mangled,
})
import json
import os
-from urllib import quote
+from urllib.parse import quote
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
from django.utils.decorators import method_decorator
value = self.cleaned_data['params']
try:
return json.dumps(json.loads(value))
- except ValueError, e:
+ except ValueError as e:
raise forms.ValidationError(e)
def handle_noargs(self, **options):
buttons = Button.objects.all()
- print "Validating parameters... "
+ print("Validating parameters... ")
for b in buttons:
params = b.params
try:
v = json.loads(b.params)
- except ValueError, e:
- print 'Trying to fix button "%s" ...' % b.slug
+ except ValueError as e:
+ print('Trying to fix button "%s" ...' % b.slug)
if params[0] == u'(':
params = params[1:]
if params[-1] == u')':
params = params[:-1]
try:
v = son.loads(re.sub(u'([\\w-]+)\\s*:', u'"\\1": ', params).encode('utf-8'))
- except ValueError, e:
- print "Unable to fix '%s' " % b.params
- print "Try to fix this button manually and rerun the script."
+ except ValueError as e:
+ print("Unable to fix '%s' " % b.params)
+ print("Try to fix this button manually and rerun the script.")
return False
# resave
b.params = json.dumps(v)
b.save()
- print "Merge duplicate buttons (if any)..."
+ print("Merge duplicate buttons (if any)...")
hash = {}
for b in buttons:
if b.slug not in hash:
continue
# duplicate button
- print "Found duplicate of '%s'" % b.slug
+ print("Found duplicate of '%s'" % b.slug)
a = hash[b.slug]
remove_duplicate = True
if a.params != b.params:
- print "Conflicting params for duplicate of '%s'." % b.slug
- print "Groups will be joined, but won't remove duplicates."
+ print("Conflicting params for duplicate of '%s'." % b.slug)
+ print("Groups will be joined, but won't remove duplicates.")
remove_duplicate = False
for g in b.group.all():
if remove_duplicate:
b.delete()
- print "Searching for empty groups and orphaned buttons:"
+ print("Searching for empty groups and orphaned buttons:")
for g in ButtonGroup.objects.all():
if len(g.button_set.all()) == 0:
- print "Empty group: '%s'" % g.slug
+ print("Empty group: '%s'" % g.slug)
for b in Button.objects.all():
if len(b.group.all()) == 0:
- print "orphan: '%s'" % b.slug
+ print("orphan: '%s'" % b.slug)
ordering = ('position', 'name',)
verbose_name, verbose_name_plural = _('button group'), _('button groups')
- def __unicode__(self):
+ def __str__(self):
return self.name
def to_dict(self, with_buttons=False):
'scriptlet_id': self.scriptlet_id,
}
- def __unicode__(self):
+ def __str__(self):
return self.label
name = models.CharField(max_length=64, primary_key=True)
code = models.TextField()
- def __unicode__(self):
+ def __str__(self):
return _(u'javascript') + u':' + self.name
def default(self, obj):
if isinstance(obj, Promise):
- return unicode(obj)
+ return str(obj)
if isinstance(obj, datetime):
return datetime.ctime(obj) + " " + (datetime.tzname(obj) or 'GMT')
verbose_name = _('theme')
verbose_name_plural = _('themes')
- def __unicode__(self):
+ def __str__(self):
return self.name
def __repr__(self):
import os
import logging
from time import mktime
-import urllib
+from urllib.parse import quote
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponseForbidden
from django.middleware.gzip import GZipMiddleware
from django.utils.decorators import decorator_from_middleware
-from django.utils.encoding import smart_unicode
from django.utils.formats import localize
from django.utils.translation import ugettext as _
from django.views.decorators.http import require_POST, require_GET
from django.shortcuts import get_object_or_404, render
from catalogue.models import Book, Chunk
-import nice_diff
+from . import nice_diff
from wiki import forms
from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
ajax_require_permission)
def gallery(request, directory):
try:
base_url = ''.join((
- smart_unicode(settings.MEDIA_URL),
- smart_unicode(settings.IMAGE_DIR),
- smart_unicode(directory)))
+ settings.MEDIA_URL,
+ settings.IMAGE_DIR,
+ directory))
- base_dir = os.path.join(
- smart_unicode(settings.MEDIA_ROOT),
- smart_unicode(settings.IMAGE_DIR),
- smart_unicode(directory))
+ base_dir = os.path.join((
+ settings.MEDIA_ROOT,
+ settings.IMAGE_DIR,
+ directory))
def map_to_url(filename):
- return urllib.quote(("%s/%s" % (base_url, smart_unicode(filename))).encode('utf-8'))
+ return quote(("%s/%s" % (base_url, filename)))
def is_image(filename):
return os.path.splitext(filename)[1].lower() in (u'.jpg', u'.jpeg', u'.png')
- images = [map_to_url(f) for f in map(smart_unicode, os.listdir(base_dir)) if is_image(f)]
+ images = [map_to_url(f) for f in os.listdir(base_dir) if is_image(f)]
images.sort()
books = Book.objects.filter(gallery=directory)
"author": change.author_str(),
"date": localize(change.created_at),
"publishable": _("Publishable") + "\n" if change.publishable else "",
- "tag": ',\n'.join(unicode(tag) for tag in change.tags.all()),
+ "tag": ',\n'.join(str(tag) for tag in change.tags.all()),
"published": _("Published") + ": " + \
localize(change.publish_log.order_by('-book_record__timestamp')[0].book_record.timestamp) \
if change.publish_log.exists() else "",
"author": change.author_str(),
"date": localize(change.created_at),
"publishable": _("Publishable") + "\n" if change.publishable else "",
- "tag": ',\n'.join(unicode(tag) for tag in change.tags.all()),
+ "tag": ',\n'.join(str(tag) for tag in change.tags.all()),
})
return JSONResponse(changes)