diff --git a/lib/booki/editor/management/commands/brokenlinks.py b/lib/booki/editor/management/commands/brokenlinks.py index 94ea738a0..4801889eb 100644 --- a/lib/booki/editor/management/commands/brokenlinks.py +++ b/lib/booki/editor/management/commands/brokenlinks.py @@ -15,7 +15,7 @@ # along with Booktype. If not, see . import os -import urllib2 +from urllib import request as urllib2 from lxml import etree, html from django.test import Client @@ -40,14 +40,14 @@ def checkLink(options, chapter, urlLink): if urlLink.startswith(hostUrl): return - print ' >>> ', urlLink, + print(' >>> ', urlLink,) if cacheLinks.get(urlLink): returnCode = cacheLinks.get(urlLink) else: try: response = urllib2.urlopen(HeadRequest(urlLink)) - except IOError, e: + except IOError as e: if hasattr(e, 'reason'): returnCode = e.reason elif hasattr(e, 'code'): @@ -58,7 +58,7 @@ def checkLink(options, chapter, urlLink): if not options['no_cache']: cacheLinks[urlLink] = returnCode - print ' [%s]' % returnCode + print(' [%s]' % returnCode) else: if options['no_local']: return @@ -66,10 +66,10 @@ def checkLink(options, chapter, urlLink): newUrl = os.path.normpath('/%s/_v/%s/%s/%s' % ( chapter.version.book.url_title, chapter.version.getVersion(), chapter.url_title, urlLink)) - print ' >> ', newUrl, + print(' >> ', newUrl,) response = c.get(newUrl) - print ' [%s]' % response.status_code + print(' [%s]' % response.status_code) class Command(BaseCommand): @@ -115,17 +115,17 @@ def handle(self, *args, **options): booksList = models.Book.objects.all().order_by('url_title') for book in booksList: - print '[%s]' % book.url_title + print('[%s]' % book.url_title) try: for chapter in models.Chapter.objects.filter(version__book=book): - print ' [%s]' % chapter.url_title, + print(' [%s]' % chapter.url_title,) try: tree = html.document_fromstring(chapter.content) - print '' + print('') except: - print ' [ERROR PARSING HTML]' + print(' [ERROR PARSING HTML]') continue for elem in tree.iter(): diff --git a/lib/booki/editor/management/commands/confdel.py b/lib/booki/editor/management/commands/confdel.py index 8c4c43197..6d874ce38 100644 --- a/lib/booki/editor/management/commands/confdel.py +++ b/lib/booki/editor/management/commands/confdel.py @@ -34,7 +34,7 @@ def handle(self, *args, **options): if not options[''][0]: raise CommandError("You must specify variable name") - if not settings.BOOKTYPE_CONFIG.has_key(options[''][0]): + if options[''][0] not in settings.BOOKTYPE_CONFIG: raise CommandError("There is no such variable.") del settings.BOOKTYPE_CONFIG[options[''][0]] diff --git a/lib/booki/editor/management/commands/confget.py b/lib/booki/editor/management/commands/confget.py index ec34f8279..9c4f5f250 100644 --- a/lib/booki/editor/management/commands/confget.py +++ b/lib/booki/editor/management/commands/confget.py @@ -39,7 +39,7 @@ def handle(self, *args, **options): if not options[""][0]: raise CommandError("You must specify variable name") - if not settings.BOOKTYPE_CONFIG.has_key(options[""][0]): + if options[""][0] not in settings.BOOKTYPE_CONFIG: raise CommandError("There is no such variable.") value = settings.BOOKTYPE_CONFIG[options[""][0]] diff --git a/lib/booki/editor/management/commands/conflist.py b/lib/booki/editor/management/commands/conflist.py index fa1a99845..b36c1eb33 100644 --- a/lib/booki/editor/management/commands/conflist.py +++ b/lib/booki/editor/management/commands/conflist.py @@ -35,7 +35,7 @@ def handle(self, *args, **options): self.stderr.write('Does not have BOOKTYPE_CONFIG in settings.py file.') return False - for name in settings.BOOKTYPE_CONFIG.iterkeys(): + for name in settings.BOOKTYPE_CONFIG.keys(): s = name if options['values']: diff --git a/lib/booki/editor/migrations/0002_load_initial_data.py b/lib/booki/editor/migrations/0002_load_initial_data.py index 4eb852c4b..0975fb7dd 100644 --- a/lib/booki/editor/migrations/0002_load_initial_data.py +++ b/lib/booki/editor/migrations/0002_load_initial_data.py @@ -37,9 +37,9 @@ def load_data(apps, schema_editor): license = License.objects.get(pk=data['pk']) license.url = data['url'] license.save() - print "Updating url '%s' to license '%s'" % (data['url'], license.name) + print("Updating url '%s' to license '%s'" % (data['url'], license.name)) except License.DoesNotExist: - print "License with pk %s does not exist. Doing nothing" % data['pk'] + print("License with pk %s does not exist. Doing nothing" % data['pk']) class Migration(migrations.Migration): diff --git a/lib/booki/editor/migrations/0004_convert_endnotes.py b/lib/booki/editor/migrations/0004_convert_endnotes.py index fe0b84c36..a8bc3e8b0 100644 --- a/lib/booki/editor/migrations/0004_convert_endnotes.py +++ b/lib/booki/editor/migrations/0004_convert_endnotes.py @@ -19,7 +19,7 @@ def convert_endnotes(apps, schema_editor): # converting tree, _ = EpubImporter.convert_endnotes(tree) - content = unicode(etree.tostring(tree, pretty_print=True, encoding='utf-8', + content = str(etree.tostring(tree, pretty_print=True, encoding='utf-8', xml_declaration=False), 'utf-8') # remove redundant div wrapper diff --git a/lib/booki/editor/models.py b/lib/booki/editor/models.py index ccc893564..1cc9cf5c4 100644 --- a/lib/booki/editor/models.py +++ b/lib/booki/editor/models.py @@ -39,7 +39,7 @@ class License(models.Model): abbrevation = models.CharField(_('abbreviation'), max_length=30) url = models.URLField(_('url'), blank=True, null=True) - def __unicode__(self): + def __str__(self): return self.name class Meta: @@ -53,7 +53,7 @@ class Language(models.Model): abbrevation = models.CharField(_('abbreviation'), max_length=10, blank=False) - def __unicode__(self): + def __str__(self): return self.name class Meta: @@ -70,12 +70,12 @@ class Meta: class BookStatus(models.Model): - book = models.ForeignKey('Book', verbose_name=_("book")) + book = models.ForeignKey('Book', on_delete=models.CASCADE, verbose_name=_("book")) name = models.CharField(_('name'), max_length=30, blank=False) weight = models.SmallIntegerField(_('weight')) color = models.CharField(_('color'), max_length=30, default='', blank=True) - def __unicode__(self): + def __str__(self): return self.name class Meta: @@ -86,10 +86,10 @@ class Meta: # free form shared notes for writers of the book class BookNotes(models.Model): - book = models.ForeignKey('Book', verbose_name=_("book")) + book = models.ForeignKey('Book', on_delete=models.CASCADE, verbose_name=_("book")) notes = models.TextField(_('notes')) - def __unicode__(self): + def __str__(self): return u"Notes for " + self.book.title class Meta: @@ -102,7 +102,7 @@ class BookiGroup(models.Model): url_name = models.CharField(_('url name'), max_length=300, blank=False) description = models.TextField(_('description')) - owner = models.ForeignKey(auth_models.User, verbose_name=_('owner')) + owner = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_('owner')) members = models.ManyToManyField(auth_models.User, related_name="members", blank=True, verbose_name=_("members")) @@ -144,7 +144,7 @@ def remove_group_images(self): except Exception as e: logger.exception(e) - def __unicode__(self): + def __str__(self): return self.name class Meta: @@ -185,16 +185,16 @@ class Meta: class Book(models.Model): url_title = models.CharField(_('url title'), max_length=2500, blank=False, unique=True) # can it be blank? title = models.CharField(_('title'), max_length=2500, blank=False) - status = models.ForeignKey('BookStatus', null=True, related_name="status", verbose_name=_("status")) - language = models.ForeignKey(Language, null=True, verbose_name=_("language")) # can it be blank? + status = models.ForeignKey('BookStatus', on_delete=models.CASCADE, null=True, related_name="status", verbose_name=_("status")) + language = models.ForeignKey(Language, on_delete=models.CASCADE, null=True, verbose_name=_("language")) # can it be blank? - version = models.ForeignKey('BookVersion', null=True, related_name="version", verbose_name=_("version")) + version = models.ForeignKey('BookVersion', on_delete=models.CASCADE, null=True, related_name="version", verbose_name=_("version")) - group = models.ForeignKey(BookiGroup, null=True, verbose_name=_("group")) + group = models.ForeignKey(BookiGroup, on_delete=models.CASCADE, null=True, verbose_name=_("group")) - owner = models.ForeignKey(auth_models.User, verbose_name=_("owner")) + owner = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("owner")) - license = models.ForeignKey(License, null=True, blank=True, verbose_name=_("license")) + license = models.ForeignKey(License, on_delete=models.CASCADE, null=True, blank=True, verbose_name=_("license")) created = models.DateTimeField(_('created'), auto_now=False, default=datetime.datetime.now) published = models.DateTimeField(_('published'), null=True) @@ -209,7 +209,7 @@ class Meta: verbose_name = _('Book') verbose_name_plural = _('Books') - def __unicode__(self): + def __str__(self): return self.title def get_absolute_url(self): @@ -330,17 +330,17 @@ def author(self, name): class BookHistory(models.Model): - book = models.ForeignKey(Book, null=False, verbose_name=_("book")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False, verbose_name=_("book")) # this should probably be null=False - version = models.ForeignKey('BookVersion', null=True, verbose_name=_("version")) - chapter = models.ForeignKey('Chapter', null=True, verbose_name=_("chapter")) - chapter_history = models.ForeignKey('ChapterHistory', null=True, verbose_name=_("chapter history")) + version = models.ForeignKey('BookVersion', on_delete=models.CASCADE, null=True, verbose_name=_("version")) + chapter = models.ForeignKey('Chapter', on_delete=models.CASCADE, null=True, verbose_name=_("chapter")) + chapter_history = models.ForeignKey('ChapterHistory', on_delete=models.CASCADE, null=True, verbose_name=_("chapter history")) modified = models.DateTimeField(_('modified'), auto_now=True) args = models.CharField(_('args'), max_length=2500, blank=False) - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) kind = models.SmallIntegerField(_('kind'), default=0) - def __unicode__(self): + def __str__(self): return self.args @@ -363,7 +363,7 @@ class BaseInfo(models.Model): value_text = models.TextField(_('value text'), null=True) value_date = models.DateTimeField(_('value date'), auto_now=False, null=True) - def __unicode__(self): + def __str__(self): return self.name class Meta: @@ -418,7 +418,7 @@ class Meta: # Book Version class BookVersion(models.Model): - book = models.ForeignKey(Book, null=False, verbose_name=_("book")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False, verbose_name=_("book")) major = models.IntegerField(_('major')) minor = models.IntegerField(_('minor')) name = models.CharField(_('name'), max_length=50, blank=True) @@ -454,7 +454,7 @@ def get_version(self): def get_absolute_url(self): return '%s/%s/_v/%s/' % (settings.BOOKI_URL, self.book.url_title, self.get_version()) - def __unicode__(self): + def __str__(self): return u'%d.%d (%s)' % (self.major, self.minor, self.name) # DEPRECATED API NAMES @@ -468,11 +468,11 @@ def __unicode__(self): class Chapter(models.Model): EDIT_PING_SECONDS_MAX_DELTA = 15 - version = models.ForeignKey(BookVersion, null=False, verbose_name=_('version')) - book = models.ForeignKey(Book, null=False, verbose_name=_('book')) + version = models.ForeignKey(BookVersion, on_delete=models.CASCADE, null=False, verbose_name=_('version')) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False, verbose_name=_('book')) url_title = models.CharField(_('url title'), max_length=2500) title = models.CharField(_('title'), max_length=2500) - status = models.ForeignKey(BookStatus, null=False, verbose_name=_('status')) + status = models.ForeignKey(BookStatus, on_delete=models.CASCADE, null=False, verbose_name=_('status')) # used to save statuses as checked checked_statuses = models.ManyToManyField( @@ -493,7 +493,7 @@ class Meta: def get_absolute_url(self): return '%s/%s/%s/' % (settings.BOOKI_URL, self.book.url_title, self.url_title) - def __unicode__(self): + def __str__(self): return self.title @property @@ -596,14 +596,14 @@ def has_marker(self): class ChapterHistory(models.Model): - chapter = models.ForeignKey(Chapter, null=False, verbose_name=_("chapter")) + chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE, null=False, verbose_name=_("chapter")) content = models.TextField() modified = models.DateTimeField(_('modified'), null=False, auto_now=True) - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) revision = models.IntegerField(_('revision'), default=1) comment = models.CharField(_('comment'), max_length=2500, blank=True) - def __unicode__(self): + def __str__(self): return u'{0} | {1} - {2}. Comment: {3}'.format( self.chapter.book, self.chapter, self.modified, self.comment) @@ -639,7 +639,7 @@ class ChapterLock(models.Model): ) chapter = models.OneToOneField(Chapter, related_name='lock') - user = models.ForeignKey(auth_models.User, verbose_name=_('user')) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_('user')) type = models.IntegerField(choices=LOCK_CHOICES, default=LOCK_SIMPLE) created = models.DateTimeField(_('created'), auto_now_add=True) @@ -648,7 +648,7 @@ class Meta: verbose_name_plural = _('Chapters Locks') ordering = ('created',) - def __unicode__(self): + def __str__(self): return u"{0} - {1}".format(self.chapter.title, self.get_type_display()) @@ -675,10 +675,10 @@ def get_directory_name(self): class Attachment(models.Model): - version = models.ForeignKey(BookVersion, null=False, verbose_name=_("version")) - book = models.ForeignKey(Book, null=False, verbose_name=_("book")) + version = models.ForeignKey(BookVersion, on_delete=models.CASCADE, null=False, verbose_name=_("version")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False, verbose_name=_("book")) attachment = models.FileField(_('filename'), upload_to=upload_attachment_to, max_length=2500) - status = models.ForeignKey(BookStatus, null=False, verbose_name=_("status")) + status = models.ForeignKey(BookStatus, on_delete=models.CASCADE, null=False, verbose_name=_("status")) created = models.DateTimeField(_('created'), null=False, auto_now=False, default=datetime.datetime.now) def delete(self): @@ -687,7 +687,7 @@ def delete(self): super(Attachment, self).delete() - def __unicode__(self): + def __str__(self): return self.attachment.name class Meta: @@ -756,12 +756,12 @@ class BookToc(models.Model): (LINE_TYPE, _('line')) ) - version = models.ForeignKey(BookVersion, null=False, verbose_name=_("version")) + version = models.ForeignKey(BookVersion, on_delete=models.CASCADE, null=False, verbose_name=_("version")) # book should be removed - book = models.ForeignKey(Book, null=False, verbose_name=_("book")) - parent = models.ForeignKey('self', null=True, blank=True, verbose_name=_("parent")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False, verbose_name=_("book")) + parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, verbose_name=_("parent")) name = models.CharField(_('name'), max_length=2500, blank=True) - chapter = models.ForeignKey(Chapter, null=True, blank=True, verbose_name=_("chapter")) + chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE, null=True, blank=True, verbose_name=_("chapter")) weight = models.IntegerField(_('weight')) typeof = models.SmallIntegerField(_('typeof'), choices=TYPEOF_CHOICES) @@ -784,8 +784,8 @@ def url_title(self): return self.chapter.url_title return None - def __unicode__(self): - return unicode(self.weight) + def __str__(self): + return str(self.weight) class Meta: verbose_name = _('Book TOC') @@ -803,20 +803,20 @@ class BookiPermission(models.Model): 1 - admin """ - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) - book = models.ForeignKey(Book, null=True, verbose_name=_("book")) - group = models.ForeignKey(BookiGroup, null=True, verbose_name=_("group")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True, verbose_name=_("book")) + group = models.ForeignKey(BookiGroup, on_delete=models.CASCADE, null=True, verbose_name=_("group")) permission = models.SmallIntegerField(_('permission')) - def __unicode__(self): + def __str__(self): return u'%s %s ' % (self.user.username, self.permission) class AttributionExclude(models.Model): - book = models.ForeignKey(Book, null=True, verbose_name=_("book")) - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True, verbose_name=_("book")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) - def __unicode__(self): + def __str__(self): return u'%s' % (self.user.username, ) class Meta: @@ -825,12 +825,12 @@ class Meta: class PublishWizzard(models.Model): - book = models.ForeignKey(Book, null=True, verbose_name=_("book")) - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True, verbose_name=_("book")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) wizz_type = models.CharField(_('wizard type'), max_length=20, blank=False) wizz_options = models.TextField(_('wizard options'), default='', null=False) - def __unicode__(self): + def __str__(self): return u'%s' % (self.book.url_title, ) class Meta: @@ -845,8 +845,8 @@ def upload_cover_to(att, filename): class BookCover(models.Model): - book = models.ForeignKey(Book, null=True, verbose_name=_("book")) - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True, verbose_name=_("book")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) cid = models.CharField('cid', max_length=40, null=False, default='', unique=True) @@ -866,7 +866,7 @@ class BookCover(models.Model): cover_type = models.CharField(_('Cover type'), max_length=20, blank=True) creator = models.CharField(_('Cover'), max_length=40, blank=True) - license = models.ForeignKey(License, null=True, verbose_name=_("license")) + license = models.ForeignKey(License, on_delete=models.CASCADE, null=True, verbose_name=_("license")) notes = models.TextField(_('notes')) @@ -879,7 +879,7 @@ def delete(self): super(BookCover, self).delete() - def __unicode__(self): + def __str__(self): return u'%s' % (self.id, ) diff --git a/lib/booki/editor/south_migrations/0018_add_licenses_url.py b/lib/booki/editor/south_migrations/0018_add_licenses_url.py index b4a022ba0..d96337eac 100644 --- a/lib/booki/editor/south_migrations/0018_add_licenses_url.py +++ b/lib/booki/editor/south_migrations/0018_add_licenses_url.py @@ -35,9 +35,9 @@ def forwards(self, orm): license = orm.License.objects.get(pk=data['pk']) license.url = data['url'] license.save() - print "Updating url '%s' to license '%s'" % (data['url'], license.name) + print("Updating url '%s' to license '%s'" % (data['url'], license.name)) except orm.License.DoesNotExist: - print "License with pk %s does not exist. Doing nothing" % data['pk'] + print("License with pk %s does not exist. Doing nothing" % data['pk']) def backwards(self, orm): "Write your backwards methods here." diff --git a/lib/booki/messaging/models.py b/lib/booki/messaging/models.py index e4dbcd3c5..c29de7326 100644 --- a/lib/booki/messaging/models.py +++ b/lib/booki/messaging/models.py @@ -29,7 +29,7 @@ def uploadAttachmentTo(message, filename): # XXX class "Message" with field "sender" would cause Django Admin to crash... class Post(models.Model): - sender = models.ForeignKey("Endpoint", verbose_name=_("sender")) + sender = models.ForeignKey("Endpoint", on_delete=models.CASCADE, verbose_name=_("sender")) timestamp = models.DateTimeField(_('timestamp'), null=False, auto_now=True) content = models.TextField(_('content')) attachment = models.FileField(_('attachment'), upload_to=uploadAttachmentTo, max_length=2500) @@ -54,7 +54,7 @@ def content_as_html(self): res.append(part) return " ".join(res) - def __unicode__(self): + def __str__(self): return u"%s-%s" % (self.sender, self.timestamp) class Meta: @@ -63,11 +63,11 @@ class Meta: class PostAppearance(models.Model): - post = models.ForeignKey('Post', verbose_name=_("post")) + post = models.ForeignKey('Post', on_delete=models.CASCADE, verbose_name=_("post")) timestamp = models.DateTimeField(_('timestamp'), null=False) - endpoint = models.ForeignKey('Endpoint', verbose_name=_('endpoint')) + endpoint = models.ForeignKey('Endpoint', on_delete=models.CASCADE, verbose_name=_('endpoint')) - def __unicode__(self): + def __str__(self): return u"%s-%s-%s" % (self.post.sender, self.endpoint, self.timestamp) class Meta: @@ -83,7 +83,7 @@ def match_wildcard(pattern, word): class Endpoint(models.Model): syntax = models.CharField(_('syntax'), max_length=2500, unique=True) - config = models.ForeignKey('EndpointConfig', unique=True, null=True, blank=True) + config = models.ForeignKey('EndpointConfig', on_delete=models.CASCADE, unique=True, null=True, blank=True) def as_user(self): if not self.syntax.startswith("@"): @@ -139,7 +139,7 @@ def wants_notification(self, message, word): return True # no filters matched - def __unicode__(self): + def __str__(self): return self.syntax class Meta: @@ -149,7 +149,7 @@ class Meta: class EndpointConfig(models.Model): notification_filter = models.CharField(_('notification filter'), max_length=2500, blank=True) - def __unicode__(self): + def __str__(self): return u"config-"+"-".join(str(x) for x in self.endpoint_set.all()) class Meta: @@ -157,10 +157,10 @@ class Meta: verbose_name_plural = _('Endpoint configs') class Following(models.Model): - follower = models.ForeignKey('Endpoint', verbose_name=_("follower"), related_name='follower') - target = models.ForeignKey('Endpoint', verbose_name=_("target"), related_name='target') + follower = models.ForeignKey('Endpoint', on_delete=models.CASCADE, verbose_name=_("follower"), related_name='follower') + target = models.ForeignKey('Endpoint', on_delete=models.CASCADE, verbose_name=_("target"), related_name='target') - def __unicode__(self): + def __str__(self): return u"%s-%s" % (self.follower, self.target) class Meta: diff --git a/lib/booki/messaging/views.py b/lib/booki/messaging/views.py index c7f0c1605..1f162e70b 100644 --- a/lib/booki/messaging/views.py +++ b/lib/booki/messaging/views.py @@ -169,7 +169,7 @@ def add_appearance_for_tag(message, word, sent, direct=False, orig_word=None): @login_required def view_post(request): if request.method != 'POST': - return HttpResponse(unicode(_("Error")), content_type="text/plain") + return HttpResponse(str(_("Error")), content_type="text/plain") # XXX validate: content = request.POST.get('content', '') @@ -215,7 +215,7 @@ def view_post(request): if not ajax: return redirect('view_profile', request.user.username) else: - return HttpResponse(unicode(_("Sent.")), content_type="text/plain") + return HttpResponse(str(_("Sent.")), content_type="text/plain") @login_required def view_follow(request): diff --git a/lib/booki/utils/json_wrapper.py b/lib/booki/utils/json_wrapper.py index 2f93e1366..ec1e4e547 100644 --- a/lib/booki/utils/json_wrapper.py +++ b/lib/booki/utils/json_wrapper.py @@ -14,15 +14,9 @@ # You should have received a copy of the GNU Affero General Public License # along with Booktype. If not, see . -"""In Python 2.5, the json module we use is an external module called -'simplejson'. From Python 2.6, it is a standard module called 'json'. -Just to complicate things, in Debian's Python 2.5, there is an -entirely different module called 'json', so 'import json' might apeear -to work there but do the worng thing. - -This module includes the logic for ensuring that the right module gets -imported. For simplcity of backwards compatibility, the module it -finds is called both 'simplejson' and 'json'. +"""In Python 3, the json module is always available as a standard module. +This module maintains backward compatibility with code that might still +import from booki.utils.json_wrapper. >>> from booki.utils.json_wrapper import json >>> from booki.utils.json_wrapper import simplejson @@ -30,14 +24,6 @@ True """ -try: - import json - if not hasattr(json, 'loads'): - raise ImportError('accidentally imported the wrong json module.') -except ImportError, e: - from warnings import warn - warn('json not found: "%s", trying simplejson' % e) - del warn - import simplejson as json +import json simplejson = json diff --git a/lib/booktype/api/editor/views.py b/lib/booktype/api/editor/views.py index 402e8adb0..804708513 100644 --- a/lib/booktype/api/editor/views.py +++ b/lib/booktype/api/editor/views.py @@ -611,7 +611,7 @@ def get(self, request, book_id, pk, format=None): Role.objects.get(name='registered_users') ).data) - print Role.objects.get(name='registered_users').permissions + print(Role.objects.get(name='registered_users').permissions) # get book roles for role in user.roles.filter(book=book): diff --git a/lib/booktype/api/management/commands/generate_filters.py b/lib/booktype/api/management/commands/generate_filters.py index a5b9fe931..08615e94a 100644 --- a/lib/booktype/api/management/commands/generate_filters.py +++ b/lib/booktype/api/management/commands/generate_filters.py @@ -215,4 +215,4 @@ def handle(self, *args, **options): "\n model = {0}" \ "\n fields = {1}\n".format(model.__name__, tuple(filters)) - print result + print(result) diff --git a/lib/booktype/apps/account/models.py b/lib/booktype/apps/account/models.py index 30f3f55b3..4cfb5a56f 100644 --- a/lib/booktype/apps/account/models.py +++ b/lib/booktype/apps/account/models.py @@ -45,7 +45,7 @@ def remove_image(self): try: os.remove('%s/%s%s.jpg' % (settings.MEDIA_ROOT, settings.PROFILE_IMAGE_UPLOAD_DIR, self.user.username)) except Exception as err: - print err + print(err) class UserPassword(models.Model): @@ -61,7 +61,7 @@ class UserPassword(models.Model): @ivar host: Client host. """ - user = models.ForeignKey(User, unique=False, verbose_name=_("user")) + user = models.ForeignKey(User, on_delete=models.CASCADE, unique=False, verbose_name=_("user")) secretcode = models.CharField(_('secretcode'), max_length=30, blank=False, null=False) created = models.DateTimeField(_('created'), auto_now=True) diff --git a/lib/booktype/apps/account/utils.py b/lib/booktype/apps/account/utils.py index 0ca0caa46..a4b0ba57a 100644 --- a/lib/booktype/apps/account/utils.py +++ b/lib/booktype/apps/account/utils.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -import urllib -import urlparse +from urllib import parse as urllib_parse, request as urllib_request +from urllib import parse as urlparse import hashlib from django.conf import settings @@ -35,7 +35,7 @@ def get_profile_image(user, size=100): hashlib.md5( profile.user.email.encode('utf-8').lower() ).hexdigest(), - urllib.urlencode({'d': default, 's': str(size)}) + urlparse.urlencode({'d': default, 's': str(size)}) ) filename = profile.image.name diff --git a/lib/booktype/apps/convert/tasks.py b/lib/booktype/apps/convert/tasks.py index bc5d6fd2b..c922d5215 100644 --- a/lib/booktype/apps/convert/tasks.py +++ b/lib/booktype/apps/convert/tasks.py @@ -102,7 +102,7 @@ def convert(request_data, base_path): assets.add_files(request_data.files) subtasks = [] - for (name, output) in request_data.outputs.iteritems(): + for (name, output) in request_data.outputs.items(): sandbox_path = os.path.join(base_path, name) output_path = os.path.join(sandbox_path, output.output) @@ -129,7 +129,7 @@ def convert(request_data, base_path): with allow_join_result(): result.join(propagate=False) - subtasks_info = {async.task_id: async for async in result.children} + subtasks_info = {task.task_id: task for task in result.children} celery.current_task.update_state(state="PROGRESS", meta=subtasks_info) return subtasks_info diff --git a/lib/booktype/apps/convert/templatetags/convert_tags.py b/lib/booktype/apps/convert/templatetags/convert_tags.py index 212d48f1c..c6a955a51 100644 --- a/lib/booktype/apps/convert/templatetags/convert_tags.py +++ b/lib/booktype/apps/convert/templatetags/convert_tags.py @@ -16,8 +16,8 @@ def find_with_key(data, key, value): Returns metadata entries """ - for k, v in data.iteritems(): - for a, b in v.iteritems(): + for k, v in data.items(): + for a, b in v.items(): for c in b: if c[1].get(key, '') == value: yield c @@ -79,8 +79,8 @@ def get_metadata(data, name): Returns metadata entry. """ - for k, v in data.iteritems(): - for a, b in v.iteritems(): + for k, v in data.items(): + for a, b in v.items(): if a == name: if len(b) > 0 and len(b[0]) > 0: return b[0][0] diff --git a/lib/booktype/apps/convert/views.py b/lib/booktype/apps/convert/views.py index 4f09697ad..5b1f9dfd8 100644 --- a/lib/booktype/apps/convert/views.py +++ b/lib/booktype/apps/convert/views.py @@ -50,7 +50,7 @@ def __init__(self, data): self.assets = data.get("assets", {}) # TODO: check type is dict self.input = data["input"] self.outputs = { - k: OutputData(v) for (k, v) in data["outputs"].iteritems() + k: OutputData(v) for (k, v) in data["outputs"].items() } @@ -72,7 +72,7 @@ def post(self, request): # name:path for all uploaded files request_data.files = { field_name: _file.file_path() - for (field_name, _file) in request.FILES.iteritems() + for (field_name, _file) in request.FILES.items() } # start the task in the background @@ -101,7 +101,7 @@ def get_task_name(async_result): if task_result: task_info["result"] = { get_task_name(subtask): get_task_info(subtask) - for (_n, subtask) in task_result.iteritems() + for (_n, subtask) in task_result.items() } response_data = task_info diff --git a/lib/booktype/apps/core/management/commands/update_default_roles.py b/lib/booktype/apps/core/management/commands/update_default_roles.py index d6a546cfd..ce190d10c 100644 --- a/lib/booktype/apps/core/management/commands/update_default_roles.py +++ b/lib/booktype/apps/core/management/commands/update_default_roles.py @@ -31,4 +31,4 @@ def handle(self, *args, **options): raise CommandError(err_msg) statuses = ['updated', 'created'] - print 'Role %s has been %s.' % (role_name, statuses[created]) + print('Role %s has been %s.' % (role_name, statuses[created])) diff --git a/lib/booktype/apps/core/management/commands/update_permissions.py b/lib/booktype/apps/core/management/commands/update_permissions.py index ee978c4f6..228fbdefc 100644 --- a/lib/booktype/apps/core/management/commands/update_permissions.py +++ b/lib/booktype/apps/core/management/commands/update_permissions.py @@ -33,7 +33,7 @@ def handle(self, *args, **options): if options['delete_orphans']: orphan_perms.delete() - print BOLD_ON + "All undeclared permissions has been deleted." + BOLD_OFF + print(BOLD_ON + "All undeclared permissions has been deleted." + BOLD_OFF) else: if orphan_perms.count() > 0: suggestion = ( @@ -41,4 +41,4 @@ def handle(self, *args, **options): "To delete them use: \n" "./manage.py update_permissions --delete-orphans" ) - print BOLD_ON + suggestion % orphan_perms.count() + BOLD_OFF + print(BOLD_ON + suggestion % orphan_perms.count() + BOLD_OFF) diff --git a/lib/booktype/apps/core/models.py b/lib/booktype/apps/core/models.py index eaa0cd653..749d0cf4d 100644 --- a/lib/booktype/apps/core/models.py +++ b/lib/booktype/apps/core/models.py @@ -20,7 +20,7 @@ class Permission(models.Model): max_length=255 ) - def __unicode__(self): + def __str__(self): return self.label class Meta: @@ -62,7 +62,7 @@ class Role(models.Model): blank=True, null=True ) - def __unicode__(self): + def __str__(self): return u'%s' % self.name class Meta: @@ -81,15 +81,15 @@ class BookRole(models.Model): Roles scoped by the desired Book """ - role = models.ForeignKey(Role, verbose_name=_('role')) - book = models.ForeignKey(Book, verbose_name=_('book')) + role = models.ForeignKey(Role, on_delete=models.CASCADE, verbose_name=_('role')) + book = models.ForeignKey(Book, on_delete=models.CASCADE, verbose_name=_('book')) members = models.ManyToManyField( User, verbose_name=_('users'), blank=True, null=True, related_name='roles' ) - def __unicode__(self): + def __str__(self): return u'%s %s' % (self.book.title, self.role.name) class Meta: @@ -130,7 +130,7 @@ class BookSkeleton(models.Model): upload_to=SKELETON_UPLOAD_DIR, verbose_name=_('File')) - def __unicode__(self): + def __str__(self): return u'{0} - {1}'.format(self.name, self.language) class Meta: diff --git a/lib/booktype/apps/edit/channel.py b/lib/booktype/apps/edit/channel.py index 8eea0b17c..c96f6a3b4 100644 --- a/lib/booktype/apps/edit/channel.py +++ b/lib/booktype/apps/edit/channel.py @@ -1355,13 +1355,13 @@ def remote_chapters_changed(request, message, bookid, version): id__exact=int(chap[1]), version=book_version ) - except Exception, e: + except Exception as e: pass toc_item.parent = parent toc_item.save() - except Exception, e: - print e + except Exception as e: + print(e) weight -= 1 diff --git a/lib/booktype/apps/edit/models.py b/lib/booktype/apps/edit/models.py index 8ff119e40..aa78476de 100644 --- a/lib/booktype/apps/edit/models.py +++ b/lib/booktype/apps/edit/models.py @@ -12,7 +12,7 @@ class Comment(models.Model): """Model for storing Word comments""" # Every comment is connected with certain chapter document - chapter = models.ForeignKey(Chapter, null=False, verbose_name="chapter") + chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE, null=False, verbose_name="chapter") # Comments can have parents. This is when one user participates in the discussion parent = models.ForeignKey('self', null=True, on_delete=models.SET_NULL) @@ -24,7 +24,7 @@ class Comment(models.Model): author = models.CharField("author", max_length=50, default='', null=False) # user who created the comment if any - user = models.ForeignKey(User, null=True) + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) # Date when comments was written date = models.DateTimeField("date", null=False) @@ -82,7 +82,7 @@ class InviteCode(models.Model): """ code = models.CharField(max_length=20, unique=True, db_index=True) - book = models.ForeignKey(Book, related_name='invite_codes') + book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='invite_codes') roles = models.ManyToManyField(Role, verbose_name='Roles to assign') created = models.DateTimeField(auto_now_add=True) expire_on = models.DateField() @@ -103,7 +103,7 @@ class ChatThread(models.Model): In future book can have more than 1 thread, that is why we have this proxy model. """ - book = models.ForeignKey(Book) + book = models.ForeignKey(Book, on_delete=models.CASCADE) def __str__(self): return '"{}" thread.'.format(self.book.title) @@ -113,8 +113,8 @@ class ChatMessage(models.Model): """ Chat message. """ - thread = models.ForeignKey(ChatThread, related_name='messages') - sender = models.ForeignKey(User) + thread = models.ForeignKey(ChatThread, on_delete=models.CASCADE, related_name='messages') + sender = models.ForeignKey(User, on_delete=models.CASCADE) text = models.TextField() datetime = models.DateTimeField(auto_now_add=True, db_index=True) diff --git a/lib/booktype/apps/edit/tasks.py b/lib/booktype/apps/edit/tasks.py index 54eb275b8..9d66e6a70 100644 --- a/lib/booktype/apps/edit/tasks.py +++ b/lib/booktype/apps/edit/tasks.py @@ -110,7 +110,7 @@ def publish_book(*args, **kwargs): logger.debug(data) output_results = {} - # _format: False for _format in data["outputs"].iterkeys()} + # _format: False for _format in data["outputs"].keys()} convert_url = '{}/_convert/'.format(settings.CONVERT_URL) result = download.fetch_url(convert_url, data, method='POST') @@ -157,7 +157,7 @@ def publish_book(*args, **kwargs): 'Could not communicate with a server to fetch polling data.') if dta['state'] == 'SUCCESS': - for _key in data["outputs"].iterkeys(): + for _key in data["outputs"].keys(): if 'state' in dta['result'][_key]: if dta['result'][_key]['state'] == 'SUCCESS': output_results[_key] = True @@ -187,7 +187,7 @@ def publish_book(*args, **kwargs): _files = {} - for output_type, result in dta['result'].iteritems(): + for output_type, result in dta['result'].items(): if 'state' in result: if result['state'] == 'SUCCESS': status = 0 diff --git a/lib/booktype/apps/edit/views.py b/lib/booktype/apps/edit/views.py index da08a7933..55a9f34ac 100644 --- a/lib/booktype/apps/edit/views.py +++ b/lib/booktype/apps/edit/views.py @@ -801,10 +801,10 @@ def form_valid(self, form): else: error, message = True, _('You have no permissions to execute this action.') except Exception as err: - print err + print(err) error, message = True, _('Unknown error while saving changes.') - return self.render_json_response({'message': unicode(message), 'error': error, + return self.render_json_response({'message': str(message), 'error': error, 'updated_settings': updated_settings}) def form_invalid(self, form): diff --git a/lib/booktype/apps/export/models.py b/lib/booktype/apps/export/models.py index ca36ec617..70313c544 100644 --- a/lib/booktype/apps/export/models.py +++ b/lib/booktype/apps/export/models.py @@ -33,8 +33,8 @@ class BookExport(models.Model): - version = models.ForeignKey(BookVersion, null=False, verbose_name=_("export")) - user = models.ForeignKey(auth_models.User, verbose_name=_("user"), null=True) + version = models.ForeignKey(BookVersion, on_delete=models.CASCADE, null=False, verbose_name=_("export")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user"), null=True) name = models.CharField(_('Name'), max_length=100, blank=False) task_id = models.CharField(_('Task ID'), max_length=64, null=False, unique=True, db_index=True) created = models.DateTimeField(_('Created'), auto_now=False, default=datetime.datetime.now) @@ -51,7 +51,7 @@ def book_title(self): class ExportFile(models.Model): - export = models.ForeignKey(BookExport, null=False, verbose_name=_("export")) + export = models.ForeignKey(BookExport, on_delete=models.CASCADE, null=False, verbose_name=_("export")) typeof = models.CharField(_('Export type'), max_length=20, blank=False, null=False) filesize = models.IntegerField(_('File size'), default=0, null=True) pages = models.IntegerField(_('Number of pages'), default=0, null=True) @@ -85,8 +85,8 @@ def _exportfile_delete(sender, instance, **kwargs): class ExportComment(models.Model): - export = models.ForeignKey(BookExport, null=False, verbose_name=_("version")) - user = models.ForeignKey(auth_models.User, verbose_name=_("user")) + export = models.ForeignKey(BookExport, on_delete=models.CASCADE, null=False, verbose_name=_("version")) + user = models.ForeignKey(auth_models.User, on_delete=models.CASCADE, verbose_name=_("user")) created = models.DateTimeField(_('Created'), auto_now=False, default=datetime.datetime.now) content = models.TextField(_('Content'), default='') @@ -96,7 +96,7 @@ class Meta: class ExportSettings(models.Model): - book = models.ForeignKey(Book, null=False, verbose_name=_("book")) + book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False, verbose_name=_("book")) typeof = models.CharField(_('Export type'), max_length=20, blank=False, null=False) data = models.TextField(_('Data'), default='{}', null=False) created = models.DateTimeField(_('Created'), auto_now=False, default=datetime.datetime.now) diff --git a/lib/booktype/apps/export/utils.py b/lib/booktype/apps/export/utils.py index fe842e459..4b8303e73 100644 --- a/lib/booktype/apps/export/utils.py +++ b/lib/booktype/apps/export/utils.py @@ -18,7 +18,7 @@ import os import json import logging -import urlparse +from urllib import parse as urlparse from lxml import etree from collections import OrderedDict diff --git a/lib/booktype/apps/loadsave/management/commands/bookload.py b/lib/booktype/apps/loadsave/management/commands/bookload.py index 3b53554dc..9931b5d43 100644 --- a/lib/booktype/apps/loadsave/management/commands/bookload.py +++ b/lib/booktype/apps/loadsave/management/commands/bookload.py @@ -63,4 +63,4 @@ def handle(self, *args, **options): raise CommandError('File "%s" does not exist. Can not finish import.' % fileName) else: if options['verbosity'] in ['1', '2']: - print 'Booki-zip "%s" file successfully imported.' % fileName + print('Booki-zip "%s" file successfully imported.' % fileName) diff --git a/lib/booktype/apps/loadsave/management/commands/booksave.py b/lib/booktype/apps/loadsave/management/commands/booksave.py index 72ceb4a12..2dc74bff9 100644 --- a/lib/booktype/apps/loadsave/management/commands/booksave.py +++ b/lib/booktype/apps/loadsave/management/commands/booksave.py @@ -58,4 +58,4 @@ def handle(self, *args, **options): get_exporter_class()(filename, book_version).run() if options['verbosity'] in ['1', '2']: - print 'Book successfully exported into "%s" file.' % filename + print('Book successfully exported into "%s" file.' % filename) diff --git a/lib/booktype/apps/portal/forms.py b/lib/booktype/apps/portal/forms.py index 7853a5722..b5623d164 100644 --- a/lib/booktype/apps/portal/forms.py +++ b/lib/booktype/apps/portal/forms.py @@ -14,8 +14,8 @@ class SpanErrorList(ErrorList): - def __unicode__(self): - return unicode(self.as_spans()) + def __str__(self): + return str(self.as_spans()) def as_spans(self): return "%s" % ( @@ -72,7 +72,7 @@ def set_group_image(self, group_id, group_image): misc.set_group_image("{}_small".format(group_id), group_image, 18, 18) except Exception as err: # TODO: we should do something here - print err + print(err) class GroupCreateForm(BaseGroupForm): diff --git a/lib/booktype/apps/portal/views.py b/lib/booktype/apps/portal/views.py index 2da30c40d..db5f3cbc3 100644 --- a/lib/booktype/apps/portal/views.py +++ b/lib/booktype/apps/portal/views.py @@ -341,7 +341,7 @@ def delete(self, request, *args, **kwargs): try: group.remove_group_images() except Exception as e: - print e + print(e) messages.success(self.request, _('Group successfully deleted.')) return super(GroupDeleteView, self).delete(request, *args, **kwargs) diff --git a/lib/booktype/apps/reader/templatetags/reader_tags.py b/lib/booktype/apps/reader/templatetags/reader_tags.py index 72f0a8e44..5fcd0fbf6 100644 --- a/lib/booktype/apps/reader/templatetags/reader_tags.py +++ b/lib/booktype/apps/reader/templatetags/reader_tags.py @@ -53,7 +53,7 @@ def verbose_activity(activity): fields to it. """ - verbose = unicode(ACTIVITY_KIND_VERBOSE.get(activity.kind, None)) + verbose = str(ACTIVITY_KIND_VERBOSE.get(activity.kind, None)) default_image = static('core/img/chapter-default.png') link_url = None book = activity.book diff --git a/lib/booktype/apps/reader/views.py b/lib/booktype/apps/reader/views.py index ce010befb..99a12137f 100644 --- a/lib/booktype/apps/reader/views.py +++ b/lib/booktype/apps/reader/views.py @@ -187,7 +187,7 @@ def form_valid(self, form): self.object.set_cover(fname) os.unlink(fname) self.object.save() - except Exception, e: + except Exception as e: logger.exception(e) all_ok = False diff --git a/lib/booktype/apps/themes/templatetags/themes.py b/lib/booktype/apps/themes/templatetags/themes.py index 107c95bfd..8a716f826 100644 --- a/lib/booktype/apps/themes/templatetags/themes.py +++ b/lib/booktype/apps/themes/templatetags/themes.py @@ -31,11 +31,10 @@ def list_theme_options(context): for theme in os.listdir('{}/themes/'.format(settings.BOOKTYPE_ROOT)): if os.path.isdir('{}/themes/{}/'.format(settings.BOOKTYPE_ROOT, theme)): if os.path.exists('{}/themes/{}/panel.html'.format(settings.BOOKTYPE_ROOT, theme)): - f = open('{}/themes/{}/panel.html'.format(settings.BOOKTYPE_ROOT, theme), 'rt') - s = f.read() - f.close() + with open('{}/themes/{}/panel.html'.format(settings.BOOKTYPE_ROOT, theme), 'rt', encoding='utf-8') as f: + s = f.read() - t = Template(unicode(s, 'utf8')) + t = Template(s) content = t.render(context) options.append({'name': theme, 'content': content}) diff --git a/lib/booktype/contrib/legacy/bookizip.py b/lib/booktype/contrib/legacy/bookizip.py index 0f9a99af0..622625f51 100644 --- a/lib/booktype/contrib/legacy/bookizip.py +++ b/lib/booktype/contrib/legacy/bookizip.py @@ -41,7 +41,7 @@ def get_chapters(self): chapters = [] - for key, value in info['manifest'].iteritems(): + for key, value in info['manifest'].items(): if value['mimetype'] in ['text/html', 'application/xhtml+xml']: chapters.append(value['url']) @@ -52,7 +52,7 @@ def get_attachments(self): chapters = [] - for key, value in info['manifest'].iteritems(): + for key, value in info['manifest'].items(): if value['mimetype'] in ['image/png', 'image/jpeg', 'image/gif', 'image/tiff']: chapters.append(value['url']) diff --git a/lib/booktype/contrib/legacy/views.py b/lib/booktype/contrib/legacy/views.py index 1905f4ec6..cd3a99182 100644 --- a/lib/booktype/contrib/legacy/views.py +++ b/lib/booktype/contrib/legacy/views.py @@ -24,9 +24,9 @@ import time import requests import logging -import urlparse +from urllib import parse as urlparse -from StringIO import StringIO +from io import StringIO from collections import OrderedDict from django.views.generic.base import View @@ -91,7 +91,7 @@ def export_book(input_file, filename): title=title, file_name='{}.xhtml'.format(file_name[6:-5]) ) - cont = unicode(bookizip.read(file_name), 'utf-8') + cont = str(bookizip.read(file_name), 'utf-8') _section.append(c1) try: @@ -274,7 +274,7 @@ def send_request(book_url, conf, request): logger.exception('Could not read response data.') if dta['state'] == 'SUCCESS': - for _key in data["outputs"].iterkeys(): + for _key in data["outputs"].keys(): if 'state' in dta['result'][_key]: if dta['result'][_key]['state'] == 'SUCCESS': output_results[_key] = True @@ -289,13 +289,13 @@ def _x(_key): d['status'] = output_results[_key] return d - urls = {_key: _x(_key) for _key in output_results.iterkeys()} + urls = {_key: _x(_key) for _key in output_results.keys()} _now = datetime.datetime.now() _files = {} - for output_type, result in dta['result'].iteritems(): + for output_type, result in dta['result'].items(): if 'state' in result: if result['state'] == 'SUCCESS': return result diff --git a/lib/booktype/convert/assets.py b/lib/booktype/convert/assets.py index 1122f99d1..515984c2a 100644 --- a/lib/booktype/convert/assets.py +++ b/lib/booktype/convert/assets.py @@ -29,11 +29,11 @@ def __init__(self, base_path): self.files = {} def add_files(self, files): - for (asset_id, file_path) in files.iteritems(): + for (asset_id, file_path) in files.items(): self.files[asset_id] = AssetFile(asset_id, file_path) def add_urls(self, urls): - for (asset_id, url) in urls.iteritems(): + for (asset_id, url) in urls.items(): file_path = os.path.join(self.base_path, slugify(asset_id)) download(url, file_path) self.files[asset_id] = AssetFile(asset_id, file_path, original_url=url) diff --git a/lib/booktype/convert/epub/converter.py b/lib/booktype/convert/epub/converter.py index b3c7bed3e..64347fdb0 100644 --- a/lib/booktype/convert/epub/converter.py +++ b/lib/booktype/convert/epub/converter.py @@ -18,7 +18,7 @@ import uuid import json import logging -import urlparse +from urllib import parse as urlparse import ebooklib import datetime from copy import deepcopy @@ -236,10 +236,10 @@ def _edit_metadata(self, epub_book): # delete existing 'modified' tag m = epub_book.metadata[ebooklib.epub.NAMESPACES["OPF"]] - m[None] = filter(lambda (_, x): not (isinstance(x, dict) and x.get("property") == "dcterms:modified"), m[None]) # noqa + m[None] = list(filter(lambda item: not (isinstance(item[1], dict) and item[1].get("property") == "dcterms:modified"), m[None])) # noqa # we also need to remove the `additional metadata` which here is just garbage - m[None] = filter(lambda (_, x): not (isinstance(x, dict) and x.get("property").startswith("add_meta_terms:")), m[None]) # noqa + m[None] = list(filter(lambda item: not (isinstance(item[1], dict) and item[1].get("property") and item[1].get("property").startswith("add_meta_terms:")), m[None])) # noqa # NOTE: probably going to extend this function in future @@ -439,7 +439,7 @@ def _get_theme_assets(self): def _add_theme_assets(self, epub_book): assets = self._get_theme_assets() - for asset_type, asset_list in assets.iteritems(): + for asset_type, asset_list in assets.items(): if asset_type == 'images': for image_name in asset_list: name = os.path.basename(image_name) diff --git a/lib/booktype/convert/epub/writerplugins/base_writerplugin.py b/lib/booktype/convert/epub/writerplugins/base_writerplugin.py index ebaf4e1a6..983e28c09 100644 --- a/lib/booktype/convert/epub/writerplugins/base_writerplugin.py +++ b/lib/booktype/convert/epub/writerplugins/base_writerplugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import os -import urllib -import urlparse +from urllib import parse as urllib_parse, request as urllib_request +from urllib import parse as urlparse import ebooklib import logging @@ -85,7 +85,7 @@ def _fix_images(self, root): if not src: continue - path = urllib.unquote(src) + path = urlparse.unquote(src) # if hostname, then it is an image with absolute url if urlparse.urlparse(path).hostname: diff --git a/lib/booktype/convert/loader.py b/lib/booktype/convert/loader.py index 293bba310..fea9b04a6 100644 --- a/lib/booktype/convert/loader.py +++ b/lib/booktype/convert/loader.py @@ -67,7 +67,7 @@ def allowed_module(klass, module_name): for module_name in module_names: try: module = importlib.import_module(module_name) - except Exception, e: + except Exception as e: print("could not load module %s: %s" % (module_name, e)) continue diff --git a/lib/booktype/convert/mpdf/converter.py b/lib/booktype/convert/mpdf/converter.py index acf577654..573f4f464 100644 --- a/lib/booktype/convert/mpdf/converter.py +++ b/lib/booktype/convert/mpdf/converter.py @@ -18,7 +18,7 @@ import json import uuid import codecs -import urllib2 +from urllib import request as urllib2 import logging import datetime from lxml import etree @@ -266,7 +266,7 @@ def get_metadata(self, book): dc_metadata = { key: value[0][0] for key, value in - book.metadata.get("http://purl.org/dc/elements/1.1/").iteritems() + book.metadata.get("http://purl.org/dc/elements/1.1/").items() } m = book.metadata[ebooklib.epub.NAMESPACES["OPF"]] @@ -539,9 +539,8 @@ def _write_configuration(self, book): data = {'metadata': dc_metadata, 'config': self.config} data.update(self.get_extra_configuration()) - f = codecs.open('{}/config.json'.format(self.sandbox_path), 'wt', 'utf8') - f.write(unicode(json.dumps(data), 'utf8')) - f.close() + with codecs.open('{}/config.json'.format(self.sandbox_path), 'wt', 'utf8') as f: + f.write(json.dumps(data)) def _save_images(self, book): """Saves all the images from EPUB file to the temporary directory. @@ -809,7 +808,7 @@ def _write(name, content): except IOError: pass - for asset_type, asset_list in assets.iteritems(): + for asset_type, asset_list in assets.items(): if asset_type == 'images': for image_name in asset_list: name = os.path.basename(image_name) diff --git a/lib/booktype/convert/pdf/bookjs.py b/lib/booktype/convert/pdf/bookjs.py index d0a3a0333..2f6839c79 100644 --- a/lib/booktype/convert/pdf/bookjs.py +++ b/lib/booktype/convert/pdf/bookjs.py @@ -34,7 +34,7 @@ def render(html_path, pdf_path, **kwargs): "-output", pdf_path, ] - if kwargs.has_key("page_config"): + if "page_config" in kwargs: params += ["-page-config", kwargs.get("page_config")] custom_css_file = None @@ -93,8 +93,8 @@ def unit(x): def _get_page_settings(args): settings = {} - for key, (min_val, max_val, multiplier) in constants.PAGE_EXTREMA.iteritems(): - if not args.has_key(key): + for key, (min_val, max_val, multiplier) in constants.PAGE_EXTREMA.items(): + if key not in args: continue val = float(args.get(key)) @@ -104,10 +104,10 @@ def _get_page_settings(args): else: settings[key] = val * multiplier - if args.has_key("page_size"): + if "page_size" in args: page_size = args.get("page_size") - if constants.PAGE_SIZE_DATA.has_key(page_size): + if page_size in constants.PAGE_SIZE_DATA: settings.update(constants.PAGE_SIZE_DATA.get(page_size)) else: raise ValueError("invalid page size specifier") diff --git a/lib/booktype/convert/pdf/converter.py b/lib/booktype/convert/pdf/converter.py index 0320be2fb..3e0daad3c 100644 --- a/lib/booktype/convert/pdf/converter.py +++ b/lib/booktype/convert/pdf/converter.py @@ -22,7 +22,7 @@ import lxml.html from lxml import etree -import urllib2 +from urllib import request as urllib2 import logging @@ -71,7 +71,7 @@ def __init__(self, *args, **kwargs): def convert(self, book, output_path): self._save_images(book) - dc_metadata = {key : value[0][0] for (key, value) in book.metadata.get("http://purl.org/dc/elements/1.1/").iteritems()} + dc_metadata = {key : value[0][0] for (key, value) in book.metadata.get("http://purl.org/dc/elements/1.1/").items()} head_params = { "title" : dc_metadata.get("title", ""), diff --git a/lib/booktype/convert/runner.py b/lib/booktype/convert/runner.py index 509b23e26..9d40d8419 100644 --- a/lib/booktype/convert/runner.py +++ b/lib/booktype/convert/runner.py @@ -39,7 +39,7 @@ def run_conversion(profile, input, output, config=None, sandbox_path=None, asset if converters is None: converters = loader.find_all() - if not converters.has_key(profile): + if profile not in converters: raise ConversionError("no converter registered for " + profile) book_asset = assets.get(input) diff --git a/lib/booktype/convert/xhtml/converter.py b/lib/booktype/convert/xhtml/converter.py index dd3acd398..f651d5f05 100644 --- a/lib/booktype/convert/xhtml/converter.py +++ b/lib/booktype/convert/xhtml/converter.py @@ -16,8 +16,8 @@ import os import logging -import urlparse -import urllib +from urllib import parse as urlparse +from urllib import parse as urllib_parse, request as urllib_request import zipfile import ebooklib @@ -162,7 +162,7 @@ def _fix_images(self, root): for element in root.iter('img'): - path = urllib.unquote(element.get('src')) + path = urlparse.unquote(element.get('src')) # if hostname, then it is an image with absolute url if urlparse.urlparse(path).hostname: diff --git a/lib/booktype/importer/docx/docximporter.py b/lib/booktype/importer/docx/docximporter.py index e7e81705f..75f92a689 100644 --- a/lib/booktype/importer/docx/docximporter.py +++ b/lib/booktype/importer/docx/docximporter.py @@ -180,7 +180,7 @@ def _import_attachments(self, book, doc): unimportable_image = False not_supported = False - for rel_id, rel_value in doc.relationships['document'].iteritems(): + for rel_id, rel_value in doc.relationships['document'].items(): if rel_value.get('type', '') == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image': att = models.Attachment(book=book, version=book.version, status=stat) diff --git a/lib/booktype/importer/epub/epubimporter.py b/lib/booktype/importer/epub/epubimporter.py index 65dc01ab9..f88dcef30 100644 --- a/lib/booktype/importer/epub/epubimporter.py +++ b/lib/booktype/importer/epub/epubimporter.py @@ -17,11 +17,11 @@ import os import uuid import pprint -import urllib +from urllib import parse as urllib_parse, request as urllib_request import difflib import logging import hashlib -import urlparse +from urllib import parse as urlparse import datetime import lxml.html @@ -103,7 +103,7 @@ def _parse_toc(elements, parent=None): _parse_toc(_elem[1], unique_id) elif isinstance(_elem, ebooklib.epub.Link): _urlp = urlparse.urlparse(_elem.href) - _name = os.path.normpath(urllib.unquote(_urlp.path)) + _name = os.path.normpath(urlparse.unquote(_urlp.path)) # check in case _name is an empty string if not _name: @@ -228,15 +228,15 @@ def _make_url_title(title, i=0): "Imported chapter: {} -> {}".format(document, chapter)) # fix links to chapters - for file_name, chapter in self._chapters.iteritems(): + for file_name, chapter in self._chapters.items(): self._fix_links(chapter, base_path=os.path.dirname(file_name)) # create TOC objects self._make_toc(book, toc) def _create_content(self, document, title): - if not isinstance(title, unicode): - title = unicode(title, 'utf-8') + if isinstance(title, bytes): + title = title.decode('utf-8') content = document.get_body_content() @@ -288,7 +288,7 @@ def _find_heading(self, tree, title): return None def matches(heading): - heading_text = unicode( + heading_text = str( etree.tostring(heading, method='text', encoding='utf-8'), 'utf-8' ) @@ -468,7 +468,7 @@ def _fix_links(self, chapter, base_path): urlp = urlparse.urlparse(href) name = os.path.normpath( - os.path.join(base_path, urllib.unquote(urlp.path))) + os.path.join(base_path, urlparse.unquote(urlp.path))) if name in self._chapters: title = self._chapters[name].url_title @@ -488,7 +488,7 @@ def _fix_links(self, chapter, base_path): urlp = urlparse.urlparse(src) name = os.path.normpath( - os.path.join(base_path, urllib.unquote(urlp.path))) + os.path.join(base_path, urlparse.unquote(urlp.path))) if urlp.netloc: continue @@ -498,7 +498,7 @@ def _fix_links(self, chapter, base_path): self._attachments[name].attachment.name) attName, attExt = os.path.splitext(file_name) - fixed_src = urllib.quote( + fixed_src = urlparse.quote( 'static/{}{}'.format(booktype_slugify(attName), attExt)) image.set('src', fixed_src) to_save = True diff --git a/lib/booktype/utils/book.py b/lib/booktype/utils/book.py index e3c7a3c68..dd0849001 100644 --- a/lib/booktype/utils/book.py +++ b/lib/booktype/utils/book.py @@ -226,7 +226,7 @@ def set_book_cover(book, file_name): # If we have used book.cover.save we would end up with obsolete files on disk book.cover = '%s%s.jpg' % (settings.COVER_IMAGE_UPLOAD_DIR, book.id) - except Exception, e: + except Exception as e: logger.exception(e) diff --git a/lib/booktype/utils/misc.py b/lib/booktype/utils/misc.py index 670342557..a57409f2c 100644 --- a/lib/booktype/utils/misc.py +++ b/lib/booktype/utils/misc.py @@ -15,14 +15,14 @@ # along with Booktype. If not, see . import os -import urllib +from urllib import parse as urllib_parse, request as urllib_request import config import logging -import urlparse +from urllib import parse as urlparse import tempfile import ebooklib import datetime -import StringIO +from io import StringIO, BytesIO import importlib from django.conf import settings @@ -206,7 +206,7 @@ def _convert_file_name(file_name): _ext = name[name.rfind('.'):] name = booktype_slugify(_np) + _ext - name = urllib.unquote(name) + name = urlparse.unquote(name) name = name.replace(' ', '_') return name @@ -261,7 +261,7 @@ def _parse_toc(elements, parent=None): pass elif isinstance(_elem, epub.Link): _u = urlparse.urlparse(_elem.href) - _name = urllib.unquote(os.path.basename(_u.path)) + _name = urlparse.unquote(os.path.basename(_u.path)) if not _name: _name = _elem.title @@ -288,7 +288,11 @@ def _parse_toc(elements, parent=None): ) s = attach.get_content() - f = StringIO.StringIO(s) + # Use BytesIO for binary data + if isinstance(s, bytes): + f = BytesIO(s) + else: + f = StringIO(s) f2 = File(f) f2.size = len(s) att.attachment.save(attach.file_name, f2, save=False) @@ -304,7 +308,7 @@ def _parse_toc(elements, parent=None): continue # check if this chapter name already exists - name = urllib.unquote(os.path.basename(chap.file_name)) + name = urlparse.unquote(os.path.basename(chap.file_name)) content = chap.get_body_content() # maybe this part has to go to the plugin @@ -320,7 +324,7 @@ def _parse_toc(elements, parent=None): chapter = models.Chapter( book=book, version=book.version, - url_title=booktype_slugify(unicode(name)), + url_title=booktype_slugify(str(name)), title=name, status=stat, content=content, @@ -328,7 +332,7 @@ def _parse_toc(elements, parent=None): modified=now ) chapter.save() - _imported[urllib.unquote(os.path.basename(chap.file_name))] = chapter + _imported[urlparse.unquote(os.path.basename(chap.file_name))] = chapter # fix links for chap in epub_book.get_items_of_type(ebooklib.ITEM_DOCUMENT): @@ -354,7 +358,7 @@ def _parse_toc(elements, parent=None): if _href: _u = urlparse.urlparse(_href) - pth = urllib.unquote(os.path.basename(_u.path)) + pth = urlparse.unquote(os.path.basename(_u.path)) if pth in _imported: _name = _imported[pth].url_title @@ -365,8 +369,8 @@ def _parse_toc(elements, parent=None): if to_save: chap.content = etree.tostring(tree, pretty_print=True, encoding='utf-8', xml_declaration=True) - _imported[urllib.unquote(os.path.basename(chap.file_name))].content = chap.content - _imported[urllib.unquote(os.path.basename(chap.file_name))].save() + _imported[urlparse.unquote(os.path.basename(chap.file_name))].content = chap.content + _imported[urlparse.unquote(os.path.basename(chap.file_name))].save() n = len(toc) + 1 parents = {} diff --git a/lib/booktype/utils/permissions.py b/lib/booktype/utils/permissions.py index 8c0a0daa4..aef859fbd 100644 --- a/lib/booktype/utils/permissions.py +++ b/lib/booktype/utils/permissions.py @@ -24,19 +24,19 @@ def create_permissions(app_name, app_perms, stdout=True): if len(permissions) > 0: if stdout: - print "Updating permissions for %s" % app_name + print("Updating permissions for %s" % app_name) for codename, description in permissions: perm, _ = Permission.objects.get_or_create( app_name=perms_app_name, name=codename ) - perm.description = unicode(description) + perm.description = str(description) perm.save() created_perms.append(perm) if stdout: - print "\t- saving %s.%s permission".expandtabs(4) \ - % (perms_app_name, codename) + print("\t- saving %s.%s permission".expandtabs(4) + % (perms_app_name, codename)) return created_perms diff --git a/lib/booktype/utils/tidy.py b/lib/booktype/utils/tidy.py index 0a8693c91..709e1d297 100644 --- a/lib/booktype/utils/tidy.py +++ b/lib/booktype/utils/tidy.py @@ -41,7 +41,7 @@ def tidy_cleanup(content, **extra): content = misc.remove_unknown_tags(content) - for k, v in extra.iteritems(): + for k, v in extra.items(): cmd.append('--%s' % k) if v: diff --git a/lib/booktype/utils/wordcount.py b/lib/booktype/utils/wordcount.py index 64623eedd..202ebd853 100644 --- a/lib/booktype/utils/wordcount.py +++ b/lib/booktype/utils/wordcount.py @@ -50,14 +50,14 @@ def _wordcount(i): def wordcount(text): - if isinstance(text, str): - text = unicode(text, "utf-8") + if isinstance(text, bytes): + text = text.decode('utf-8') return _wordcount(iter(text)) def charcount(text): - if isinstance(text, str): - text = unicode(text, "utf-8") + if isinstance(text, bytes): + text = text.decode('utf-8') count = 0 try: i = iter(text) @@ -70,8 +70,8 @@ def charcount(text): def charspacecount(text): - if isinstance(text, str): - text = unicode(text, "utf-8") + if isinstance(text, bytes): + text = text.decode('utf-8') count = 0 try: i = iter(text) @@ -83,11 +83,11 @@ def charspacecount(text): if __name__ == "__main__": - print wordcount("") - print wordcount(" ") - print wordcount(" a") - print wordcount(" ,., ....") - print wordcount(" a b ,., ....") - print wordcount(" a b ,., .... c ") - print wordcount(",,, 1 2 3 4 5 6 7 8 9 deset ,,,.. jedanaest") - print charspacecount("ab cd") + print(wordcount("")) + print(wordcount(" ")) + print(wordcount(" a")) + print(wordcount(" ,., ....")) + print(wordcount(" a b ,., ....")) + print(wordcount(" a b ,., .... c ")) + print(wordcount(",,, 1 2 3 4 5 6 7 8 9 deset ,,,.. jedanaest")) + print(charspacecount("ab cd")) diff --git a/lib/booktypecontrol/forms.py b/lib/booktypecontrol/forms.py index e54c422e5..f0273616a 100644 --- a/lib/booktypecontrol/forms.py +++ b/lib/booktypecontrol/forms.py @@ -132,9 +132,8 @@ class AppearanceForm(BaseControlForm, forms.Form): @classmethod def initial_data(cls): try: - f = open('%s/css/_user.css' % settings.STATIC_ROOT, 'r') - css_content = unicode(f.read(), 'utf8') - f.close() + with open('%s/css/_user.css' % settings.STATIC_ROOT, 'r', encoding='utf-8') as f: + css_content = f.read() except IOError: css_content = '' @@ -190,9 +189,10 @@ def initial_data(cls): f = open( '%s/templates/portal/welcome_message.html' % settings.BOOKTYPE_ROOT, - 'r' + 'r', + encoding='utf-8' ) - _dict['description'] = unicode(f.read(), 'utf8') + _dict['description'] = f.read() f.close() except IOError: _dict['description'] = '' diff --git a/lib/booktypecontrol/migrations/0002_static_user_css.py b/lib/booktypecontrol/migrations/0002_static_user_css.py index 2e2e2daac..94f412906 100644 --- a/lib/booktypecontrol/migrations/0002_static_user_css.py +++ b/lib/booktypecontrol/migrations/0002_static_user_css.py @@ -13,14 +13,14 @@ def create_user_css(apps, schema_editor): try: os.mkdir('%s/css/' % settings.STATIC_ROOT) except OSError as err: - print err + print(err) raise RuntimeError('Can not create css directory.') f = open('%s/css/_user.css' % settings.STATIC_ROOT, 'w') f.write(' ') f.close() except IOError as err: - print err + print(err) raise RuntimeError('Can not create the file.') diff --git a/lib/booktypecontrol/views.py b/lib/booktypecontrol/views.py index a6f2bcc1f..e3f7952cc 100644 --- a/lib/booktypecontrol/views.py +++ b/lib/booktypecontrol/views.py @@ -222,7 +222,7 @@ def form_valid(self, form): form.success_message or _('Successfully saved settings.') ) except Exception as err: - print err + print(err) messages.warning(self.request, _('Unknown error while saving changes.')) return super(ControlCenterSettings, self).form_valid(form) @@ -473,7 +473,7 @@ def delete(self, request, *args, **kwargs): try: group.remove_group_images() except Exception as e: - print e + print(e) return super(DeleteGroupView, self).delete(request, *args, **kwargs) diff --git a/lib/sputnik/redis-backuo.py b/lib/sputnik/redis-backuo.py index fee9f985e..212e3d44e 100755 --- a/lib/sputnik/redis-backuo.py +++ b/lib/sputnik/redis-backuo.py @@ -92,7 +92,7 @@ def _encode(self, s): if isinstance(s, unicode): try: return s.encode(self.charset, self.errors) - except UnicodeEncodeError, e: + except UnicodeEncodeError as e: raise InvalidData("Error encoding unicode value '%s': %s" % (value.encode(self.charset, 'replace'), e)) return str(s) @@ -103,7 +103,7 @@ def _send_command(self, s): >>> r._sock.close() >>> try: ... r._send_command('pippo') - ... except ConnectionError, e: + ... except ConnectionError as e: ... print e Error 9 while writing to socket. Bad file descriptor. >>> @@ -114,7 +114,7 @@ def _send_command(self, s): try: self._sock.sendall(s) - except socket.error, e: + except socket.error as e: self.lck.release() if e.args[0] == 32: # broken pipe @@ -137,7 +137,7 @@ def _send_command_retry(self, s): def _read(self): try: return self._fp.readline() - except socket.error, e: + except socket.error as e: if e.args and e.args[0] == errno.EAGAIN: return self.disconnect() @@ -363,14 +363,14 @@ def rename(self, src, dst, preserve=False): >>> r = Redis(db=9) >>> try: ... r.rename('a', 'a') - ... except ResponseError, e: + ... except ResponseError as e: ... print e source and destination objects are the same >>> r.rename('a', 'b') 'OK' >>> try: ... r.rename('a', 'b') - ... except ResponseError, e: + ... except ResponseError as e: ... print e no such key >>> r.set('a', 1) @@ -432,7 +432,7 @@ def push(self, name, value, head=False): 'OK' >>> try: ... r.push('a', 'a') - ... except ResponseError, e: + ... except ResponseError as e: ... print e Operation against a key holding the wrong kind of value >>> @@ -492,7 +492,7 @@ def ltrim(self, name, start, end): 1 >>> try: ... r.ltrim('l', 0, 1) - ... except ResponseError, e: + ... except ResponseError as e: ... print e no such key >>> r.push('l', 'aaa') @@ -600,14 +600,14 @@ def lset(self, name, index, value): 1 >>> try: ... r.lset('l', 0, 'a') - ... except ResponseError, e: + ... except ResponseError as e: ... print e no such key >>> r.push('l', 'aaa') 'OK' >>> try: ... r.lset('l', 1, 'a') - ... except ResponseError, e: + ... except ResponseError as e: ... print e index out of range >>> r.lset('l', 0, 'bbb') @@ -699,7 +699,7 @@ def sort(self, name, by=None, get=None, start=None, num=None, desc=False, alpha= stmt.append("LIMIT %s %s" % (start, num)) if get is None: pass - elif isinstance(get, basestring): + elif isinstance(get, str): stmt.append("GET %s" % get) elif isinstance(get, list) or isinstance(get, tuple): for g in get: @@ -827,12 +827,12 @@ def sinter(self, *args): 1 >>> try: ... r.sinter() - ... except ResponseError, e: + ... except ResponseError as e: ... print e wrong number of arguments for 'sinter' command >>> try: ... r.sinter('l') - ... except ResponseError, e: + ... except ResponseError as e: ... print e Operation against a key holding the wrong kind of value >>> r.sinter('s1', 's2', 's3') @@ -876,7 +876,7 @@ def smembers(self, name): 1 >>> try: ... r.smembers('l') - ... except ResponseError, e: + ... except ResponseError as e: ... print e Operation against a key holding the wrong kind of value >>> r.smembers('s') @@ -1328,7 +1328,7 @@ def connect(self): sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, self.nodelay) setattr(connections, self.connection_key, sock) sock = getattr(connections, self.connection_key) - except socket.error, e: + except socket.error as e: raise ConnectionError("Error %s connecting to %s:%s. %s." % (e.args[0], self.host, self.port, e.args[1])) else: # no exceptions diff --git a/lib/sputnik/views.py b/lib/sputnik/views.py index 3c6b7ec4a..4cd55c008 100644 --- a/lib/sputnik/views.py +++ b/lib/sputnik/views.py @@ -164,19 +164,19 @@ def dispatcher(request, **sputnik_dict): # For now they all do the same thing but this might change in the future try: ret = fnc(request, message, **a) - except ObjectDoesNotExist, e: + except ObjectDoesNotExist as e: execute_status = False logger.error("[{}] Object you are trying to find does not exist.".format("remote_{}".format(message.get('command', '')))) logger.exception(e) - except SuspiciousOperation, e: + except SuspiciousOperation as e: execute_status = False logger.error("[{}] Suspicious operation.".format("remote_{}".format(message.get('command', '')))) logger.exception(e) - except PermissionDenied, e: + except PermissionDenied as e: execute_status = False logger.error("[{}] Permission denied.".format("remote_{}".format(message.get('command', '')))) logger.exception(e) - except Exception, e: + except Exception as e: execute_status = False logger.error("[{}] Unknown exception.".format("remote_{}".format(message.get('command', '')))) logger.exception(e) diff --git a/requirements/_base.txt b/requirements/_base.txt index c42c79a48..5351ca4ce 100644 --- a/requirements/_base.txt +++ b/requirements/_base.txt @@ -1,18 +1,18 @@ -Django>1.11.18,<2.0 -django-compressor==2.2 -celery==4.1.1 -django-celery-results==1.0.1 +Django>=2.2,<3.0 +django-compressor>=2.4 +celery>=4.4.0 +django-celery-results>=1.2.0 Unidecode lxml -Pillow==2.9.0 -redis==2.9.1 +Pillow>=6.0.0 +redis>=3.0.0 pika unipath django-braces python-ooxml -django-rest-swagger==2.1.0 -djangorestframework==3.5.3 -Markdown==2.6.7 -django-filter==1.1.0 -Ebooklib==0.16 -GitPython==2.1.8 +drf-yasg>=1.20.0 +djangorestframework>=3.11.0 +Markdown>=3.0.0 +django-filter>=2.2.0 +Ebooklib>=0.17 +GitPython>=3.0.0 diff --git a/requirements/dev.txt b/requirements/dev.txt index 5e84b7df3..4c20fbcd6 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,16 +1,14 @@ -r _base.txt -requests==2.9.2 -sqlparse==0.2.2 -django-debug-toolbar==1.6 -django-discover-runner +requests>=2.20.0 +sqlparse>=0.3.0 +django-debug-toolbar>=2.0 mock -selenium +selenium>=3.141.0 factory_boy sphinx -pep8 -pytest==3.0.7 -pytest-cov==2.4.0 -pytest-django==3.1.2 -pytest-pythonpath==0.7.1 -Faker==0.7.10 +pytest>=5.0.0 +pytest-cov>=2.8.0 +pytest-django>=3.8.0 +pytest-pythonpath>=0.7.3 +Faker>=4.0.0 diff --git a/requirements/prod.txt b/requirements/prod.txt index f88ba0f94..046040b94 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -1,6 +1,6 @@ -r _base.txt urllib3[secure] -requests[security]==2.9.2 +requests[security]>=2.20.0 psycopg2-binary -BeautifulSoup +beautifulsoup4 diff --git a/setup.py b/setup.py index 0bb5f17c4..9036e540a 100644 --- a/setup.py +++ b/setup.py @@ -44,15 +44,20 @@ def read(*rnames): }, scripts=['scripts/createbooktype'], - install_requires=['setuptools', 'simplejson', 'django'], + install_requires=['setuptools', 'django'], classifiers=[ "License :: OSI Approved :: GNU General Public License (GPL)", "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Framework :: Django", ], + python_requires='>=3.6', keywords='collaborative book writing sprint', license='AGPL',