From 13b941dfde3c09aa69a00bf64c810137ab4969ce Mon Sep 17 00:00:00 2001 From: Bibhas Date: Thu, 5 Dec 2019 17:06:18 +0530 Subject: [PATCH] 2to3 changes --- eventframe/__init__.py | 2 +- eventframe/assets.py | 4 +- eventframe/forms/website.py | 46 ++++++++++----------- eventframe/models/website.py | 32 +++++++------- eventframe/nodes/content/forms.py | 16 +++---- eventframe/nodes/content/models.py | 8 ++-- eventframe/nodes/content/views.py | 10 ++--- eventframe/nodes/data/forms.py | 12 +++--- eventframe/nodes/data/models.py | 2 +- eventframe/nodes/data/views.py | 4 +- eventframe/nodes/event/forms.py | 24 +++++------ eventframe/nodes/event/models.py | 22 +++++----- eventframe/nodes/event/views.py | 12 +++--- eventframe/nodes/fragment/forms.py | 12 +++--- eventframe/nodes/fragment/views.py | 4 +- eventframe/nodes/funnel_link/forms.py | 6 +-- eventframe/nodes/funnel_link/models.py | 2 +- eventframe/nodes/funnel_link/views.py | 4 +- eventframe/nodes/helpers.py | 8 ++-- eventframe/nodes/list/forms.py | 10 ++--- eventframe/nodes/list/views.py | 4 +- eventframe/nodes/map/forms.py | 12 +++--- eventframe/nodes/map/views.py | 4 +- eventframe/nodes/page/views.py | 4 +- eventframe/nodes/participant_list/forms.py | 16 +++---- eventframe/nodes/participant_list/models.py | 12 +++--- eventframe/nodes/participant_list/views.py | 28 ++++++------- eventframe/nodes/post/views.py | 6 +-- eventframe/nodes/redirect/forms.py | 12 +++--- eventframe/nodes/redirect/views.py | 6 +-- eventframe/views/content.py | 46 ++++++++++----------- eventframe/views/context.py | 2 +- eventframe/views/eventlogin.py | 2 +- eventframe/views/folder.py | 34 +++++++-------- eventframe/views/login.py | 14 +++---- eventframe/views/website.py | 26 ++++++------ migrations/env.py | 2 +- rqinit.py | 2 +- 38 files changed, 236 insertions(+), 236 deletions(-) diff --git a/eventframe/__init__.py b/eventframe/__init__.py index bea9ec8..3a8f0a6 100644 --- a/eventframe/__init__.py +++ b/eventframe/__init__.py @@ -2,7 +2,7 @@ # The imports in this file are order-sensitive -from __future__ import absolute_import + from threading import Lock from pytz import timezone from flask import Flask diff --git a/eventframe/assets.py b/eventframe/assets.py index 22c3697..696341a 100644 --- a/eventframe/assets.py +++ b/eventframe/assets.py @@ -133,7 +133,7 @@ def absurl(self, fragment): def load_theme_assets(env, theme): css_list = theme.options.get('assets_css', []) - if isinstance(css_list, basestring): + if isinstance(css_list, str): css_list = [css_list] css = Bundle(*[Bundle('_themes/%s/%s' % (theme.identifier, item), filters='cssmin', output='_themes/%s/%s.packed.css' % (theme.identifier, item)) for item in css_list]) # , @@ -141,7 +141,7 @@ def load_theme_assets(env, theme): env.register('css_%s' % theme.identifier, css) js_list = theme.options.get('assets_js', []) - if isinstance(js_list, basestring): + if isinstance(js_list, str): js_list = [js_list] js = Bundle(*[Bundle('_themes/%s/%s' % (theme.identifier, item), filters='uglipyjs', output='_themes/%s/%s.packed.js' % (theme.identifier, item)) for item in js_list]) diff --git a/eventframe/forms/website.py b/eventframe/forms/website.py index 5a0b477..59f63b2 100644 --- a/eventframe/forms/website.py +++ b/eventframe/forms/website.py @@ -51,9 +51,9 @@ def __init__(self, label='', validators=None, **kwargs): def _value(self): if self.data: - return u', '.join(self.data) + return ', '.join(self.data) else: - return u'' + return '' def process_formdata(self, valuelist): if valuelist: @@ -74,7 +74,7 @@ def _remove_duplicates(seq): class DictField(wtforms.fields.Field): widget = wtforms.widgets.TextArea() - description = u'One per line, as {"key": "value"}' + description = 'One per line, as {"key": "value"}' def __init__(self, *args, **kwargs): if not 'description' in kwargs: @@ -83,7 +83,7 @@ def __init__(self, *args, **kwargs): def _value(self): if isinstance(self.data, dict): - return '\r\n'.join([json.dumps({key: value}) for key, value in self.data.items()]) + return '\r\n'.join([json.dumps({key: value}) for key, value in list(self.data.items())]) return '' def process_formdata(self, valuelist): @@ -97,14 +97,14 @@ def process_formdata(self, valuelist): class WebsiteForm(Form): - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Required(), valid_name]) - url = wtforms.fields.html5.URLField(u"Website URL", validators=[wtforms.validators.Required()]) - hostnames = HostnamesField(u"Hostnames", validators=[wtforms.validators.Required()], - description=u"Hostnames at which this website will be accessed, comma separated") - theme = wtforms.SelectField(u"Website theme", validators=[wtforms.validators.Required()]) - typekit_code = wtforms.TextField(u"Typekit code") - googleanalytics_code = wtforms.TextField(u"Google Analytics code") + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) + name = wtforms.TextField("URL name", validators=[wtforms.validators.Required(), valid_name]) + url = wtforms.fields.html5.URLField("Website URL", validators=[wtforms.validators.Required()]) + hostnames = HostnamesField("Hostnames", validators=[wtforms.validators.Required()], + description="Hostnames at which this website will be accessed, comma separated") + theme = wtforms.SelectField("Website theme", validators=[wtforms.validators.Required()]) + typekit_code = wtforms.TextField("Typekit code") + googleanalytics_code = wtforms.TextField("Google Analytics code") def validate_name(self, field): # TODO: Ensure name is unique @@ -116,11 +116,11 @@ def validate_hostnames(self, field): class FolderForm(Form): - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Optional(), valid_name], - description=u"Folder name as it appears in the URL (without slashes)") - title = wtforms.TextField(u"Title", - description=u"Folder title, used in the per-folder blog feed") - theme = wtforms.SelectField(u"Theme") + name = wtforms.TextField("URL name", validators=[wtforms.validators.Optional(), valid_name], + description="Folder name as it appears in the URL (without slashes)") + title = wtforms.TextField("Title", + description="Folder title, used in the per-folder blog feed") + theme = wtforms.SelectField("Theme") def validate_name(self, field): # TODO @@ -128,9 +128,9 @@ def validate_name(self, field): class ImportForm(Form): - import_file = wtforms.FileField(u"Upload file", validators=[wtforms.validators.Required()]) - import_updated = wtforms.BooleanField(u"Only import newer nodes", default=True, - description=u"Nodes that are newer locally will not be imported") + import_file = wtforms.FileField("Upload file", validators=[wtforms.validators.Required()]) + import_updated = wtforms.BooleanField("Only import newer nodes", default=True, + description="Nodes that are newer locally will not be imported") class ConfirmForm(Form): @@ -138,6 +138,6 @@ class ConfirmForm(Form): class FileFolderForm(Form): - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Required(), valid_name]) - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) - properties = DictField(u"Properties") + name = wtforms.TextField("URL name", validators=[wtforms.validators.Required(), valid_name]) + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) + properties = DictField("Properties") diff --git a/eventframe/models/website.py b/eventframe/models/website.py index 343ae19..021a751 100644 --- a/eventframe/models/website.py +++ b/eventframe/models/website.py @@ -4,7 +4,7 @@ from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm.collections import attribute_mapped_collection -from urlparse import urljoin +from urllib.parse import urljoin from flask import url_for from coaster.auth import current_auth from coaster.utils import buid, parse_isoformat @@ -21,13 +21,13 @@ def default_user_id(): class Website(BaseNameMixin, db.Model): __tablename__ = 'website' #: URL to the website - url = db.Column(db.Unicode(80), nullable=False, default=u'') + url = db.Column(db.Unicode(80), nullable=False, default='') #: Theme that this website uses as the default (folders can override) - theme = db.Column(db.Unicode(80), nullable=False, default=u'default') + theme = db.Column(db.Unicode(80), nullable=False, default='default') #: Typekit code, if used - typekit_code = db.Column(db.Unicode(20), nullable=False, default=u'') + typekit_code = db.Column(db.Unicode(20), nullable=False, default='') #: Google Analytics code, if used - googleanalytics_code = db.Column(db.Unicode(20), nullable=False, default=u'') + googleanalytics_code = db.Column(db.Unicode(20), nullable=False, default='') _hostnames = db.relationship("Hostname", cascade='all, delete-orphan', backref='website') hostnames = association_proxy('_hostnames', 'name', @@ -35,12 +35,12 @@ class Website(BaseNameMixin, db.Model): def __init__(self, **kwargs): super(Website, self).__init__(**kwargs) - root = Folder(name=u'', title=u'', website=self) + root = Folder(name='', title='', website=self) self.folders.append(root) # root.pages[0].template = u'index.html' def __repr__(self): - return u'' % (self.name, self.title) + return '' % (self.name, self.title) def folder_ids(self): return [i[0] for i in db.session.query(Folder.id).filter_by(website=self).all()] @@ -62,7 +62,7 @@ class Hostname(BaseMixin, db.Model): website_id = db.Column(db.Integer, db.ForeignKey('website.id'), nullable=False) def __repr__(self): - return u'' % self.name + return '' % self.name @classmethod def get(cls, name, website=None): @@ -75,7 +75,7 @@ class LoginCode(BaseMixin, db.Model): #: Tracking code to enable users to login to an event website code = db.Column(db.Unicode(22), nullable=False, unique=True) #: Access scope requested - scope = db.Column(db.Unicode(250), nullable=False, default=u'') + scope = db.Column(db.Unicode(250), nullable=False, default='') #: User who logged in user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True, default=None) user = db.relationship(User) @@ -95,7 +95,7 @@ class Folder(BaseScopedNameMixin, db.Model): #: Website this folder is under website_id = db.Column(db.Integer, db.ForeignKey('website.id'), nullable=False) - _theme = db.Column("theme", db.Unicode(80), nullable=False, default=u'') + _theme = db.Column("theme", db.Unicode(80), nullable=False, default='') website = db.relationship(Website, backref=db.backref('folders', order_by='Folder.name', cascade='all, delete-orphan')) @@ -120,7 +120,7 @@ def __init__(self, **kwargs): # self.pages.append(index) def __repr__(self): - return u'' % (self.name or '(root)', self.website.name) + return '' % (self.name or '(root)', self.website.name) def url_for(self, action='view'): """ @@ -129,12 +129,12 @@ def url_for(self, action='view'): if action == 'view': return urljoin(self.website.url, self.name) elif action == 'list': - if self.name == u'': + if self.name == '': return url_for('website', website=self.website.name) else: return url_for('folder', website=self.website.name, folder=self.name) elif action == 'edit': - if self.name != u'': + if self.name != '': return url_for('folder_edit', website=self.website.name, folder=self.name) @@ -159,7 +159,7 @@ def __init__(self, *args, **kwargs): self.update(*args, **kwargs) def update(self, *args, **kwargs): - for k, v in dict(*args, **kwargs).iteritems(): + for k, v in dict(*args, **kwargs).items(): self[k] = v def __delitem__(self, key): @@ -178,7 +178,7 @@ def __setitem__(self, key, value): if isinstance(value, Property): dict.__setitem__(self, key, value.value) else: - value = unicode(value) # Since Property.value = db.Unicode + value = str(value) # Since Property.value = db.Unicode dict.__setitem__(self, key, value) if key in self.node.node_properties: self.node.node_properties[key].value = value @@ -260,7 +260,7 @@ def url_for(self, action='view', _external=False): Return a URL to this node. """ if action == 'view': - if self.folder.name == u'': + if self.folder.name == '': return url_for('folder', folder=self.name, _external=_external) else: return url_for('node', folder=self.folder.name, node=self.name, _external=_external) diff --git a/eventframe/nodes/content/forms.py b/eventframe/nodes/content/forms.py index 40d677d..ba0ccd0 100644 --- a/eventframe/nodes/content/forms.py +++ b/eventframe/nodes/content/forms.py @@ -8,19 +8,19 @@ class ContentForm(Form): - previous_id = wtforms.HiddenField(u"Previous revision") - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Optional(), valid_name]) - author = wtforms.TextField(u"Author (optional)", validators=[wtforms.validators.Length(max=40)], + previous_id = wtforms.HiddenField("Previous revision") + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) + name = wtforms.TextField("URL name", validators=[wtforms.validators.Optional(), valid_name]) + author = wtforms.TextField("Author (optional)", validators=[wtforms.validators.Length(max=40)], description="Name of the author. Will default to your name if blank") - description = wtforms.TextAreaField(u"Summary", description=u"Summary of this page") - content = RichTextField(u"Page content", linkify=False, + description = wtforms.TextAreaField("Summary", description="Summary of this page") + content = RichTextField("Page content", linkify=False, tinymce_options=tinymce_options, sanitize_tags=richtext_sanitize_tags, sanitize_attributes=richtext_sanitize_attributes) template = wtforms.TextField("Template", validators=[wtforms.validators.Required()], default='page.html.jinja2', - description=u"Template with which this page will be rendered.") - properties = DictField(u"Properties") + description="Template with which this page will be rendered.") + properties = DictField("Properties") def validate_previous_id(self, field): if not field.data: diff --git a/eventframe/nodes/content/models.py b/eventframe/nodes/content/models.py index de167ed..6025f54 100644 --- a/eventframe/nodes/content/models.py +++ b/eventframe/nodes/content/models.py @@ -25,11 +25,11 @@ class ContentRevision(BaseMixin, db.Model): #: Title of the current revision title = db.Column(db.Unicode(250), nullable=False) #: Abstract that is shown in summaries. Plain text. - description = db.Column(db.UnicodeText, nullable=False, default=u'') + description = db.Column(db.UnicodeText, nullable=False, default='') #: Page content. Rich text. - _content = db.Column('content', db.UnicodeText, nullable=False, default=u'') + _content = db.Column('content', db.UnicodeText, nullable=False, default='') #: Template with which this page will be rendered - template = db.Column(db.Unicode(80), nullable=False, default=u'') + template = db.Column(db.Unicode(80), nullable=False, default='') def __init__(self, **kwargs): super(ContentRevision, self).__init__(**kwargs) @@ -166,7 +166,7 @@ def content(self): return self.revisions.draft.content def __repr__(self): - return u'<%s %s/%s "%s" at %s>' % (self.__tablename__.title(), self.folder.name, self.name or '(index)', + return '<%s %s/%s "%s" at %s>' % (self.__tablename__.title(), self.folder.name, self.name or '(index)', self.title, self.folder.website.name) def as_json(self): diff --git a/eventframe/nodes/content/views.py b/eventframe/nodes/content/views.py index be4f04f..af18fe6 100644 --- a/eventframe/nodes/content/views.py +++ b/eventframe/nodes/content/views.py @@ -15,9 +15,9 @@ class ContentHandler(AutoFormHandler): def edit_tabs(self): if self.node: return [ - {'title': u"Edit", 'url': self.node.url_for('edit'), 'active': self.action == 'edit'}, - {'title': u"Publish", 'url': self.node.url_for('publish'), 'active': self.action == 'publish'}, - {'title': u"Unpublish", 'url': self.node.url_for('unpublish'), 'active': self.action == 'unpublish'}, + {'title': "Edit", 'url': self.node.url_for('edit'), 'active': self.action == 'edit'}, + {'title': "Publish", 'url': self.node.url_for('publish'), 'active': self.action == 'publish'}, + {'title': "Unpublish", 'url': self.node.url_for('unpublish'), 'active': self.action == 'unpublish'}, ] else: return [] @@ -64,10 +64,10 @@ def process_form(self): self.node.title = revision.title if not self.node.id and not self.node.name: # Is there already an index node in this folder? - index = db.session.query(Node.id).filter_by(folder=self.folder, name=u'').first() + index = db.session.query(Node.id).filter_by(folder=self.folder, name='').first() if index is not None: self.node.make_name() db.session.commit() # FIXME: Say created when created - flash(u"Edited node '%s'." % self.node.title, 'success') + flash("Edited node '%s'." % self.node.title, 'success') return render_redirect(url_for('folder', website=self.website.name, folder=self.folder.name), code=303) diff --git a/eventframe/nodes/data/forms.py b/eventframe/nodes/data/forms.py index 24459ce..db6380b 100644 --- a/eventframe/nodes/data/forms.py +++ b/eventframe/nodes/data/forms.py @@ -8,14 +8,14 @@ class DataForm(Form): - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Required(), valid_name]) - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) - data = wtforms.TextAreaField(u"Data", validators=[wtforms.validators.Required()], - description=u"Enter JSON data") - properties = DictField(u"Properties") + name = wtforms.TextField("URL name", validators=[wtforms.validators.Required(), valid_name]) + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) + data = wtforms.TextAreaField("Data", validators=[wtforms.validators.Required()], + description="Enter JSON data") + properties = DictField("Properties") def validate_data(self, field): # Check for exceptions when loading data parsed = simplejson.loads(field.data, use_decimal=True) if not isinstance(parsed, dict): - raise wtforms.ValidationError(u'This is not a valid JSON object. Use {"key": value, ...}') + raise wtforms.ValidationError('This is not a valid JSON object. Use {"key": value, ...}') diff --git a/eventframe/nodes/data/models.py b/eventframe/nodes/data/models.py index 43b91a4..9e0e7d4 100644 --- a/eventframe/nodes/data/models.py +++ b/eventframe/nodes/data/models.py @@ -23,7 +23,7 @@ def __len__(self): return len(self.data) def __iter__(self): - return self.data.iterkeys() + return iter(self.data.keys()) def __contains__(self, item): return item in self.data diff --git a/eventframe/nodes/data/views.py b/eventframe/nodes/data/views.py index 1bd9f00..de93ab9 100644 --- a/eventframe/nodes/data/views.py +++ b/eventframe/nodes/data/views.py @@ -22,11 +22,11 @@ def process_form(self): if self.node is None: self.node = Data(folder=self.folder, name=self.form.name.data, title=self.form.title.data) db.session.add(self.node) - flash(u"Created new data node '%s'" % self.node.title, 'success') + flash("Created new data node '%s'" % self.node.title, 'success') else: self.node.name = self.form.name.data self.node.title = self.form.title.data - flash(u"Edited data node '%s'" % self.node.title, 'success') + flash("Edited data node '%s'" % self.node.title, 'success') self.node.data = json.loads(self.form.data.data, use_decimal=True) db.session.commit() return render_redirect(url_for('folder', website=self.website.name, folder=self.folder.name), code=303) diff --git a/eventframe/nodes/event/forms.py b/eventframe/nodes/event/forms.py index 82e60c5..8d52035 100644 --- a/eventframe/nodes/event/forms.py +++ b/eventframe/nodes/event/forms.py @@ -9,15 +9,15 @@ class EventForm(ContentForm): - start_datetime = DateTimeField(u"Start date/time", validators=[wtforms.validators.Required()]) - end_datetime = DateTimeField(u"End date/time", validators=[wtforms.validators.Required()]) - timezone = wtforms.SelectField(u"Timezone", choices=timezone_list, validators=[wtforms.validators.Required()]) - location_name = wtforms.TextField(u"Location name", validators=[wtforms.validators.Required()]) - location_address = wtforms.TextField(u"Address", validators=[wtforms.validators.Required()]) - map = QuerySelectField(u"Map", get_label='title', allow_blank=True) - mapmarker = wtforms.TextField(u"Map marker") - capacity = wtforms.IntegerField(u"Capacity", validators=[wtforms.validators.Required()]) - allow_waitlisting = wtforms.BooleanField(u"Allow wait-listing if over capacity", default=False) - allow_maybe = wtforms.BooleanField(u"Allow “Maybe” responses", default=True) - participant_list = QuerySelectField(u"Participant list", get_label='title', allow_blank=True) - properties = DictField(u"Properties") + start_datetime = DateTimeField("Start date/time", validators=[wtforms.validators.Required()]) + end_datetime = DateTimeField("End date/time", validators=[wtforms.validators.Required()]) + timezone = wtforms.SelectField("Timezone", choices=timezone_list, validators=[wtforms.validators.Required()]) + location_name = wtforms.TextField("Location name", validators=[wtforms.validators.Required()]) + location_address = wtforms.TextField("Address", validators=[wtforms.validators.Required()]) + map = QuerySelectField("Map", get_label='title', allow_blank=True) + mapmarker = wtforms.TextField("Map marker") + capacity = wtforms.IntegerField("Capacity", validators=[wtforms.validators.Required()]) + allow_waitlisting = wtforms.BooleanField("Allow wait-listing if over capacity", default=False) + allow_maybe = wtforms.BooleanField("Allow “Maybe” responses", default=True) + participant_list = QuerySelectField("Participant list", get_label='title', allow_blank=True) + properties = DictField("Properties") diff --git a/eventframe/nodes/event/models.py b/eventframe/nodes/event/models.py index 929da19..f9b2d38 100644 --- a/eventframe/nodes/event/models.py +++ b/eventframe/nodes/event/models.py @@ -23,14 +23,14 @@ class Event(ContentMixin, Node): #: Timezone as a string timezone = db.Column(db.Unicode(32), nullable=False) #: Location name - location_name = db.Column(db.Unicode(80), nullable=False, default=u'') + location_name = db.Column(db.Unicode(80), nullable=False, default='') #: Location address - location_address = db.Column(db.Unicode(250), nullable=False, default=u'') + location_address = db.Column(db.Unicode(250), nullable=False, default='') #: Location on map map_id = db.Column(None, db.ForeignKey('map.id'), nullable=True) map = db.relationship(Map, primaryjoin=map_id == Map.id) #: Map marker - mapmarker = db.Column(db.Unicode(80), nullable=False, default=u'') + mapmarker = db.Column(db.Unicode(80), nullable=False, default='') #: Venue capacity, if attendance is capped capacity = db.Column(db.Integer, nullable=False, default=0) #: Allow wait-listing? @@ -54,7 +54,7 @@ def ends_at(self): def count(self): """Return count of confirmed attendees.""" - return len([a for a in self.attendees if a.status == u'Y']) + return len([a for a in self.attendees if a.status == 'Y']) def has_capacity(self): """Does the event have spare capacity for more attendees?""" @@ -72,18 +72,18 @@ def can_rsvp(self, user): def set_status(self, user, status): """Set RSVP status for user.""" - if status not in [u'Y', u'N', u'M']: + if status not in ['Y', 'N', 'M']: raise ValueError("Invalid status") - if status == u'M' and not self.allow_maybe: - raise ValueError(u"A “Maybe” response is not allowed") + if status == 'M' and not self.allow_maybe: + raise ValueError("A “Maybe” response is not allowed") if not self.can_rsvp(user): raise ValueError("This user cannot participate") attendee = EventAttendee.query.filter_by(event=self, user=user).first() if not attendee: attendee = EventAttendee(event=self, user=user) - if status == u'Y' and not self.has_capacity(): + if status == 'Y' and not self.has_capacity(): if self.allow_waitlisting: - status = u'W' + status = 'W' else: raise ValueError("This event is over capacity") db.session.add(attendee) @@ -93,7 +93,7 @@ def get_status(self, user): """Get RSVP status for this user.""" attendee = EventAttendee.query.filter_by(event=self, user=user).first() if not attendee: - return u'U' + return 'U' else: return attendee.status @@ -157,5 +157,5 @@ class EventAttendee(BaseMixin, db.Model): event_id = db.Column(None, db.ForeignKey('event.id'), nullable=False) event = db.relationship(Event, backref=db.backref('attendees', cascade='all, delete-orphan')) # Status codes: U/known, Y/es, N/o, M/aybe, W/ait-listed - status = db.Column(db.Unicode(1), nullable=False, default=u'U') + status = db.Column(db.Unicode(1), nullable=False, default='U') __table_args__ = (db.UniqueConstraint('user_id', 'event_id'),) diff --git a/eventframe/nodes/event/views.py b/eventframe/nodes/event/views.py index 6a29629..bcbc71f 100644 --- a/eventframe/nodes/event/views.py +++ b/eventframe/nodes/event/views.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from StringIO import StringIO +from io import StringIO import unicodecsv from werkzeug.routing import Map as UrlMap, Rule as UrlRule from flask import request, render_template, abort, Markup, flash, redirect, escape, jsonify @@ -21,8 +21,8 @@ class EventHandler(ContentHandler): form_class = EventForm model = Event - title_new = u"New event" - title_edit = u"Edit event" + title_new = "New event" + title_edit = "Edit event" actions = ['list', 'csv', 'update', 'json'] @@ -30,7 +30,7 @@ def edit_tabs(self): tabs = super(EventHandler, self).edit_tabs() if self.node: tabs = tabs + [ - {'title': u"Attendees", 'url': self.node.url_for('list'), 'active': self.action == 'list'}, + {'title': "Attendees", 'url': self.node.url_for('list'), 'active': self.action == 'list'}, ] return tabs @@ -152,9 +152,9 @@ def rsvp(self): # All good. Set status for this user. try: self.node.set_status(current_auth.user, status) - except ValueError, e: + except ValueError as e: if request.is_xhr: - return Markup('
%s
' % escape(unicode(e))) + return Markup('
%s
' % escape(str(e))) else: abort(403) db.session.commit() diff --git a/eventframe/nodes/fragment/forms.py b/eventframe/nodes/fragment/forms.py index 6cd459a..c9c6548 100644 --- a/eventframe/nodes/fragment/forms.py +++ b/eventframe/nodes/fragment/forms.py @@ -11,14 +11,14 @@ class FragmentForm(Form): """ A fragment form is like a content form but without a summary or template. """ - previous_id = wtforms.HiddenField(u"Previous revision") - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Required(), valid_name]) - content = RichTextField(u"Page content", linkify=False, + previous_id = wtforms.HiddenField("Previous revision") + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) + name = wtforms.TextField("URL name", validators=[wtforms.validators.Required(), valid_name]) + content = RichTextField("Page content", linkify=False, tinymce_options=tinymce_options, sanitize_tags=richtext_sanitize_tags, sanitize_attributes=richtext_sanitize_attributes) - properties = DictField(u"Properties") + properties = DictField("Properties") def validate_previous_id(self, field): if not field.data: @@ -27,7 +27,7 @@ def validate_previous_id(self, field): try: field.data = int(field.data) except ValueError: - raise wtforms.ValidationError(u"Unknown previous revision") + raise wtforms.ValidationError("Unknown previous revision") def validate_name(self, field): # TODO diff --git a/eventframe/nodes/fragment/views.py b/eventframe/nodes/fragment/views.py index 0264c23..5e4819f 100644 --- a/eventframe/nodes/fragment/views.py +++ b/eventframe/nodes/fragment/views.py @@ -10,8 +10,8 @@ class FragmentHandler(ContentHandler): model = Fragment form_class = FragmentForm - title_new = u"New page fragment" - title_edit = u"Edit page fragment" + title_new = "New page fragment" + title_edit = "Edit page fragment" def register(registry): diff --git a/eventframe/nodes/funnel_link/forms.py b/eventframe/nodes/funnel_link/forms.py index 11f2751..26059dd 100644 --- a/eventframe/nodes/funnel_link/forms.py +++ b/eventframe/nodes/funnel_link/forms.py @@ -8,6 +8,6 @@ class FunnelLinkForm(ContentForm): - funnel_name = wtforms.TextField(u"Funnel name", validators=[wtforms.validators.Required()], - description=u"URL name of the event in the HasGeek funnel") - properties = DictField(u"Properties") + funnel_name = wtforms.TextField("Funnel name", validators=[wtforms.validators.Required()], + description="URL name of the event in the HasGeek funnel") + properties = DictField("Properties") diff --git a/eventframe/nodes/funnel_link/models.py b/eventframe/nodes/funnel_link/models.py index 646ae8e..0c09044 100644 --- a/eventframe/nodes/funnel_link/models.py +++ b/eventframe/nodes/funnel_link/models.py @@ -49,7 +49,7 @@ def proposals_mapping(self): def sections(self): # There are no sections anymore. Keeping this method because it's used in all the themes. # Can be removed when `node.sections()` is removed from all the themes. - return u"" + return "" def proposals(self): return self._data()['proposals'] diff --git a/eventframe/nodes/funnel_link/views.py b/eventframe/nodes/funnel_link/views.py index a6c569f..d51968b 100644 --- a/eventframe/nodes/funnel_link/views.py +++ b/eventframe/nodes/funnel_link/views.py @@ -12,8 +12,8 @@ class FunnelLinkHandler(ContentHandler): model = FunnelLink form_class = FunnelLinkForm - title_new = u"New funnel link" - title_edit = u"Edit funnel link" + title_new = "New funnel link" + title_edit = "Edit funnel link" def make_form(self): form = super(FunnelLinkHandler, self).make_form() diff --git a/eventframe/nodes/helpers.py b/eventframe/nodes/helpers.py index 0e89230..4d3cfa7 100644 --- a/eventframe/nodes/helpers.py +++ b/eventframe/nodes/helpers.py @@ -37,8 +37,8 @@ def POST(self, *args, **kwargs): class AutoFormHandler(NodeHandler): - title_new = u"New node" - title_edit = u"Edit node" + title_new = "New node" + title_edit = "Edit node" def __init__(self, app, website, folder, node): super(AutoFormHandler, self).__init__(app, website, folder, node) @@ -63,7 +63,7 @@ def process_form(self): raise NotImplementedError def render_form(self): - return render_form(form=self.form, title=self.title_edit if self.node else self.title_new, submit=u"Save", + return render_form(form=self.form, title=self.title_edit if self.node else self.title_new, submit="Save", cancel_url=url_for('folder', website=self.website.name, folder=self.folder.name), tabs=self.edit_tabs(), node=self.node, ajax=False) @@ -104,7 +104,7 @@ def decorated_function(**kwargs): return decorated_function -def render_form(form, title, message='', formid='form', submit=u"Submit", cancel_url=None, tabs=[], node=None, ajax=False): +def render_form(form, title, message='', formid='form', submit="Submit", cancel_url=None, tabs=[], node=None, ajax=False): multipart = False for field in form: if isinstance(field.widget, wtforms.widgets.FileInput): diff --git a/eventframe/nodes/list/forms.py b/eventframe/nodes/list/forms.py index ef8b9f1..048160c 100644 --- a/eventframe/nodes/list/forms.py +++ b/eventframe/nodes/list/forms.py @@ -7,9 +7,9 @@ class ListForm(Form): - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Required(), valid_name]) - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) + name = wtforms.TextField("URL name", validators=[wtforms.validators.Required(), valid_name]) + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) list = wtforms.TextAreaField('Items', validators=[wtforms.validators.Required()], - description=u'Enter each row as a JSON array with ["name", title", "url", "folder/node"]. ' - u'For nodes in the root folder, use "/node". To not include a node, use "".') - properties = DictField(u"Properties") + description='Enter each row as a JSON array with ["name", title", "url", "folder/node"]. ' + 'For nodes in the root folder, use "/node". To not include a node, use "".') + properties = DictField("Properties") diff --git a/eventframe/nodes/list/views.py b/eventframe/nodes/list/views.py index 477149b..0ca5306 100644 --- a/eventframe/nodes/list/views.py +++ b/eventframe/nodes/list/views.py @@ -22,11 +22,11 @@ def process_form(self): if self.node is None: self.node = List(folder=self.folder, name=self.form.name.data, title=self.form.title.data) db.session.add(self.node) - flash(u"Created new list '%s'" % self.node.title, 'success') + flash("Created new list '%s'" % self.node.title, 'success') else: self.node.name = self.form.name.data self.node.title = self.form.title.data - flash(u"Edited list '%s'" % self.node.title, 'success') + flash("Edited list '%s'" % self.node.title, 'success') self.node.populate_list([json.loads(row, use_decimal=True) for row in self.form.list.data.split('\n') if row.strip()]) db.session.commit() return render_redirect(url_for('folder', website=self.website.name, folder=self.folder.name), code=303) diff --git a/eventframe/nodes/map/forms.py b/eventframe/nodes/map/forms.py index 576c4ba..61ed97b 100644 --- a/eventframe/nodes/map/forms.py +++ b/eventframe/nodes/map/forms.py @@ -7,10 +7,10 @@ class MapForm(Form): - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Required(), valid_name]) - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) + name = wtforms.TextField("URL name", validators=[wtforms.validators.Required(), valid_name]) + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) list = wtforms.TextAreaField('Map markers', validators=[wtforms.validators.Required()], - description=u'Enter each row as a JSON object with name, title, url, ' - u'latitude, longitude, zoomlevel and marker. ' - u'The URL, zoomlevel and marker can be null, others cannot.') - properties = DictField(u"Properties") + description='Enter each row as a JSON object with name, title, url, ' + 'latitude, longitude, zoomlevel and marker. ' + 'The URL, zoomlevel and marker can be null, others cannot.') + properties = DictField("Properties") diff --git a/eventframe/nodes/map/views.py b/eventframe/nodes/map/views.py index 5264b97..a2b5cf0 100644 --- a/eventframe/nodes/map/views.py +++ b/eventframe/nodes/map/views.py @@ -22,11 +22,11 @@ def process_form(self): if self.node is None: self.node = Map(folder=self.folder, name=self.form.name.data, title=self.form.title.data) db.session.add(self.node) - flash(u"Created new list '%s'" % self.node.title, 'success') + flash("Created new list '%s'" % self.node.title, 'success') else: self.node.name = self.form.name.data self.node.title = self.form.title.data - flash(u"Edited list '%s'" % self.node.title, 'success') + flash("Edited list '%s'" % self.node.title, 'success') self.node.populate_map([json.loads(row, use_decimal=True) for row in self.form.list.data.split('\n') if row.strip()]) db.session.commit() return render_redirect(url_for('folder', website=self.website.name, folder=self.folder.name), code=303) diff --git a/eventframe/nodes/page/views.py b/eventframe/nodes/page/views.py index 442f9a6..dffb9ec 100644 --- a/eventframe/nodes/page/views.py +++ b/eventframe/nodes/page/views.py @@ -8,8 +8,8 @@ class PageHandler(ContentHandler): model = Page - title_new = u"New page" - title_edit = u"Edit page" + title_new = "New page" + title_edit = "Edit page" def register(registry): diff --git a/eventframe/nodes/participant_list/forms.py b/eventframe/nodes/participant_list/forms.py index 85ca7e7..8bc2809 100644 --- a/eventframe/nodes/participant_list/forms.py +++ b/eventframe/nodes/participant_list/forms.py @@ -8,14 +8,14 @@ class ParticipantListForm(ContentForm): - source = wtforms.SelectField(u"Data Source", choices=[ + source = wtforms.SelectField("Data Source", choices=[ ('', ''), ('doattend', 'DoAttend')], - description=u"Source from which the participant list will be retrieved.") - sourceid = wtforms.TextField(u"Event id", - description=u"Id of this event at the selected data source.") - api_key = wtforms.TextField(u"API Key", - description=u"API key to retrieve data from the selected data source.") + description="Source from which the participant list will be retrieved.") + sourceid = wtforms.TextField("Event id", + description="Id of this event at the selected data source.") + api_key = wtforms.TextField("API Key", + description="API key to retrieve data from the selected data source.") participant_template = wtforms.TextField("Participant template", validators=[wtforms.validators.Required()], default='participant.html.jinja2', - description=u"Template with which a participant’s directory entry will be rendered.") - properties = DictField(u"Properties") + description="Template with which a participant’s directory entry will be rendered.") + properties = DictField("Properties") diff --git a/eventframe/nodes/participant_list/models.py b/eventframe/nodes/participant_list/models.py index 415cbd5..3b7fa2b 100644 --- a/eventframe/nodes/participant_list/models.py +++ b/eventframe/nodes/participant_list/models.py @@ -13,10 +13,10 @@ class ParticipantList(ContentMixin, Node): __tablename__ = 'participant_list' - source = db.Column(db.Unicode(80), nullable=False, default=u'') - sourceid = db.Column(db.Unicode(80), nullable=False, default=u'') - api_key = db.Column(db.Unicode(80), nullable=False, default=u'') - participant_template = db.Column(db.Unicode(80), nullable=False, default=u'') + source = db.Column(db.Unicode(80), nullable=False, default='') + sourceid = db.Column(db.Unicode(80), nullable=False, default='') + api_key = db.Column(db.Unicode(80), nullable=False, default='') + participant_template = db.Column(db.Unicode(80), nullable=False, default='') def purge(self): """ @@ -77,10 +77,10 @@ class Participant(BaseMixin, db.Model): is_listed = db.Column(db.Boolean, default=False, nullable=False) #: Data fields the participant has chosen to reveal in public fields_directory = db.Column(db.Unicode(250), nullable=False, - default=u'fullname company') + default='fullname company') #: Data fields the participant has chosen to reveal via ContactPoint fields_contactpoint = db.Column(db.Unicode(250), nullable=False, - default=u'fullname email phone twitter jobtitle company city') + default='fullname email phone twitter jobtitle company city') participant_list = db.relationship(ParticipantList, backref=db.backref( diff --git a/eventframe/nodes/participant_list/views.py b/eventframe/nodes/participant_list/views.py index 408cb4e..e619418 100644 --- a/eventframe/nodes/participant_list/views.py +++ b/eventframe/nodes/participant_list/views.py @@ -18,8 +18,8 @@ class ParticipantListHandler(ContentHandler): form_class = ParticipantListForm model = ParticipantList - title_new = u"New participant list" - title_edit = u"Edit participant list" + title_new = "New participant list" + title_edit = "Edit participant list" actions = ['sync', 'list'] @@ -27,8 +27,8 @@ def edit_tabs(self): tabs = super(ParticipantListHandler, self).edit_tabs() if self.node: tabs = tabs + [ - {'title': u"List", 'url': self.node.url_for('list'), 'active': self.action == 'list'}, - {'title': u"Sync", 'url': self.node.url_for('sync'), 'active': self.action == 'sync'}, + {'title': "List", 'url': self.node.url_for('list'), 'active': self.action == 'list'}, + {'title': "Sync", 'url': self.node.url_for('sync'), 'active': self.action == 'sync'}, ] return tabs @@ -68,7 +68,7 @@ def sync(self): node=self.node, title="Syncing participants...")) - return render_form(form=self.form, title="Sync participant list", submit=u"Sync", tabs=self.edit_tabs(), + return render_form(form=self.form, title="Sync participant list", submit="Sync", tabs=self.edit_tabs(), cancel_url=url_for('folder', website=self.node.folder.website.name, folder=self.node.folder.name), node=self.node) @@ -112,9 +112,9 @@ def _sync(self): local_tickets.add(participant.ticket) syncinfo = { 'datetime': parse_isoformat(p['Date']), - 'fullname': p['Name'].strip() if isinstance(p['Name'], basestring) else p['Name'], - 'email': p['Email'].strip() if isinstance(p['Email'], basestring) else p['Email'], - 'ticket_type': p['Ticket_Name'].strip() if isinstance(p['Ticket_Name'], basestring) else p['Ticket_Name'], + 'fullname': p['Name'].strip() if isinstance(p['Name'], str) else p['Name'], + 'email': p['Email'].strip() if isinstance(p['Email'], str) else p['Email'], + 'ticket_type': p['Ticket_Name'].strip() if isinstance(p['Ticket_Name'], str) else p['Ticket_Name'], } pinfo = p.get('participant_information', []) if isinstance(pinfo, dict): @@ -123,17 +123,17 @@ def _sync(self): key = keyval['desc'] value = keyval.get('info') if key == 'Job Title': - syncinfo['jobtitle'] = value.strip() if isinstance(value, basestring) else value + syncinfo['jobtitle'] = value.strip() if isinstance(value, str) else value elif key == 'Company': - syncinfo['company'] = value.strip() if isinstance(value, basestring) else value + syncinfo['company'] = value.strip() if isinstance(value, str) else value elif key == 'Twitter Handle': - syncinfo['twitter'] = value.strip() if isinstance(value, basestring) else value + syncinfo['twitter'] = value.strip() if isinstance(value, str) else value elif key == 'City': - syncinfo['city'] = value.strip() if isinstance(value, basestring) else value + syncinfo['city'] = value.strip() if isinstance(value, str) else value elif key == 'T-shirt size': - syncinfo['tshirt_size'] = value.split('-', 1)[0].strip() if isinstance(value, basestring) else value + syncinfo['tshirt_size'] = value.split('-', 1)[0].strip() if isinstance(value, str) else value edited = False - for key, value in syncinfo.items(): + for key, value in list(syncinfo.items()): if getattr(participant, key) != value: setattr(participant, key, value) if 'key' == 'email': diff --git a/eventframe/nodes/post/views.py b/eventframe/nodes/post/views.py index 4be5b9d..ed1009e 100644 --- a/eventframe/nodes/post/views.py +++ b/eventframe/nodes/post/views.py @@ -15,8 +15,8 @@ class PostHandler(ContentHandler): model = Post - title_new = u"New blog post" - title_edit = u"Edit blog post" + title_new = "New blog post" + title_edit = "Edit blog post" def make_form(self): form = super(PostHandler, self).make_form() @@ -84,7 +84,7 @@ def folder_feed(folder): theme, 'feed.xml', feedid=url_for('folder', folder=folder.name), website=folder.website, - title=u"%s — %s" % (folder.title or folder.name, folder.website.title), + title="%s — %s" % (folder.title or folder.name, folder.website.title), posts=posts, updated=updated), content_type='application/atom+xml; charset=utf-8') diff --git a/eventframe/nodes/redirect/forms.py b/eventframe/nodes/redirect/forms.py index c5a2d73..166edb7 100644 --- a/eventframe/nodes/redirect/forms.py +++ b/eventframe/nodes/redirect/forms.py @@ -7,13 +7,13 @@ class RedirectForm(Form): - name = wtforms.TextField(u"URL name", validators=[wtforms.validators.Optional(), valid_name]) - title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()]) - redirect_url = wtforms.TextField(u"Redirect URL", validators=[wtforms.validators.Required()]) - properties = DictField(u"Properties") + name = wtforms.TextField("URL name", validators=[wtforms.validators.Optional(), valid_name]) + title = wtforms.TextField("Title", validators=[wtforms.validators.Required()]) + redirect_url = wtforms.TextField("Redirect URL", validators=[wtforms.validators.Required()]) + properties = DictField("Properties") def validate_name(self, field): - if field.data == u'/': - field.data = u'' + if field.data == '/': + field.data = '' # TODO pass diff --git a/eventframe/nodes/redirect/views.py b/eventframe/nodes/redirect/views.py index 0969fd6..ab7e609 100644 --- a/eventframe/nodes/redirect/views.py +++ b/eventframe/nodes/redirect/views.py @@ -13,8 +13,8 @@ class RedirectHandler(AutoFormHandler): model = Redirect - title_new = u"New redirect" - title_edit = u"Edit redirect" + title_new = "New redirect" + title_edit = "Edit redirect" def make_form(self): return RedirectForm(obj=self.node) @@ -25,7 +25,7 @@ def process_form(self): db.session.add(self.node) self.form.populate_obj(self.node) db.session.commit() - flash(u"Edited redirect '%s'." % self.node.title, 'success') + flash("Edited redirect '%s'." % self.node.title, 'success') return render_redirect(url_for('folder', website=self.website.name, folder=self.folder.name), code=303) diff --git a/eventframe/views/content.py b/eventframe/views/content.py index 892f0c0..acd7002 100644 --- a/eventframe/views/content.py +++ b/eventframe/views/content.py @@ -13,7 +13,7 @@ # --- Routes ------------------------------------------------------------------ @app.route('///_new/', methods=['GET', 'POST']) -@app.route('//_root/_new/', defaults={'folder': u''}, methods=['GET', 'POST']) +@app.route('//_root/_new/', defaults={'folder': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -41,9 +41,9 @@ def node_new(website, folder, kwargs): @app.route('////_edit', methods=['GET', 'POST']) -@app.route('//_root//_edit', defaults={'folder': u''}, methods=['GET', 'POST']) -@app.route('///_index/_edit', defaults={'node': u''}, methods=['GET', 'POST']) -@app.route('//_root/_index/_edit', defaults={'folder': u'', 'node': u''}, methods=['GET', 'POST']) +@app.route('//_root//_edit', defaults={'folder': ''}, methods=['GET', 'POST']) +@app.route('///_index/_edit', defaults={'node': ''}, methods=['GET', 'POST']) +@app.route('//_root/_index/_edit', defaults={'folder': '', 'node': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -68,9 +68,9 @@ def node_edit(website, folder, node): @app.route('////do/', methods=['GET', 'POST']) -@app.route('//_root//do/', defaults={'folder': u''}, methods=['GET', 'POST']) -@app.route('///_index/do/', defaults={'node': u''}, methods=['GET', 'POST']) -@app.route('//_root/_index/do/', defaults={'folder': u'', 'node': u''}, methods=['GET', 'POST']) +@app.route('//_root//do/', defaults={'folder': ''}, methods=['GET', 'POST']) +@app.route('///_index/do/', defaults={'node': ''}, methods=['GET', 'POST']) +@app.route('//_root/_index/do/', defaults={'folder': '', 'node': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -98,9 +98,9 @@ def node_action(website, folder, node, kwargs): @app.route('////_delete', methods=['GET', 'POST']) -@app.route('//_root//_delete', defaults={'folder': u''}, methods=['GET', 'POST']) -@app.route('///_index/_delete', defaults={'node': u''}, methods=['GET', 'POST']) -@app.route('//_root/_index/_delete', defaults={'folder': u'', 'node': u''}, methods=['GET', 'POST']) +@app.route('//_root//_delete', defaults={'folder': ''}, methods=['GET', 'POST']) +@app.route('///_index/_delete', defaults={'node': ''}, methods=['GET', 'POST']) +@app.route('//_root/_index/_delete', defaults={'folder': '', 'node': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -110,17 +110,17 @@ def node_action(website, folder, node, kwargs): def node_delete(website, folder, node): g.website = website g.folder = folder - return render_delete_sqla(node, db, title=u"Confirm delete", - message=u"Delete '%s'? This is permanent. There is no undo." % node.title, - success=u"You have deleted '%s'." % node.title, + return render_delete_sqla(node, db, title="Confirm delete", + message="Delete '%s'? This is permanent. There is no undo." % node.title, + success="You have deleted '%s'." % node.title, next=url_for('folder', website=website.name, folder=folder.name)) # Temporary publish handler that needs to be rolled into the edit handler @app.route('////_publish', methods=['GET', 'POST']) -@app.route('//_root//_publish', defaults={'folder': u''}, methods=['GET', 'POST']) -@app.route('///_index/_publish', defaults={'node': u''}, methods=['GET', 'POST']) -@app.route('//_root/_index/_publish', defaults={'folder': u'', 'node': u''}, methods=['GET', 'POST']) +@app.route('//_root//_publish', defaults={'folder': ''}, methods=['GET', 'POST']) +@app.route('///_index/_publish', defaults={'node': ''}, methods=['GET', 'POST']) +@app.route('//_root/_index/_publish', defaults={'folder': '', 'node': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -136,18 +136,18 @@ def node_publish(website, folder, node): if form.validate_on_submit(): node.publish() db.session.commit() - flash(u"Published '%s'" % node.title, 'success') + flash("Published '%s'" % node.title, 'success') return render_redirect(url_for('folder', website=folder.website.name, folder=folder.name), code=303) - return render_form(form=form, title="Publish node", submit=u"Publish", + return render_form(form=form, title="Publish node", submit="Publish", cancel_url=url_for('folder', website=folder.website.name, folder=folder.name), node=node) # Temporary publish handler that needs to be rolled into the edit handler @app.route('////_unpublish', methods=['GET', 'POST']) -@app.route('//_root//_unpublish', defaults={'folder': u''}, methods=['GET', 'POST']) -@app.route('///_index/_unpublish', defaults={'node': u''}, methods=['GET', 'POST']) -@app.route('//_root/_index/_unpublish', defaults={'folder': u'', 'node': u''}, methods=['GET', 'POST']) +@app.route('//_root//_unpublish', defaults={'folder': ''}, methods=['GET', 'POST']) +@app.route('///_index/_unpublish', defaults={'node': ''}, methods=['GET', 'POST']) +@app.route('//_root/_index/_unpublish', defaults={'folder': '', 'node': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -163,8 +163,8 @@ def node_unpublish(website, folder, node): if form.validate_on_submit(): node.unpublish() db.session.commit() - flash(u"Unpublished '%s'" % node.title, 'success') + flash("Unpublished '%s'" % node.title, 'success') return render_redirect(url_for('folder', website=folder.website.name, folder=folder.name), code=303) - return render_form(form=form, title="Unpublish node", submit=u"Unpublish", + return render_form(form=form, title="Unpublish node", submit="Unpublish", cancel_url=url_for('folder', website=folder.website.name, folder=folder.name), node=node) diff --git a/eventframe/views/context.py b/eventframe/views/context.py index d1ccc1b..360ce73 100644 --- a/eventframe/views/context.py +++ b/eventframe/views/context.py @@ -28,7 +28,7 @@ def datetime_filter(date): def feedhelper(folder=None, limit=20): if folder is None: - folder = Folder.query.filter_by(name=u'', website=g.website).first() + folder = Folder.query.filter_by(name='', website=g.website).first() if folder.name == '': return rootfeed(folder.website, limit) else: diff --git a/eventframe/views/eventlogin.py b/eventframe/views/eventlogin.py index d1577cc..97fc757 100644 --- a/eventframe/views/eventlogin.py +++ b/eventframe/views/eventlogin.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from urlparse import urljoin +from urllib.parse import urljoin from functools import wraps from flask import g, request, url_for, redirect, session, abort from flask_lastuser import UserInfo as LastuserInfo diff --git a/eventframe/views/folder.py b/eventframe/views/folder.py index 65a33a5..6765add 100644 --- a/eventframe/views/folder.py +++ b/eventframe/views/folder.py @@ -31,7 +31,7 @@ def website_new(): db.session.add(website) db.session.commit() return render_redirect(url_for('website', website=website.name), code=303) - return render_form(form=form, title=u"New website", submit=u"Create", + return render_form(form=form, title="New website", submit="Create", cancel_url=url_for('index'), ajax=True) @@ -47,7 +47,7 @@ def website_edit(website): form.populate_obj(website) db.session.commit() return render_redirect(url_for('website', website=website.name), code=303) - return render_form(form=form, title=u"Edit website", submit=u"Save", + return render_form(form=form, title="Edit website", submit="Save", cancel_url=url_for('website', website=website.name), ajax=True) @@ -56,10 +56,10 @@ def website_edit(website): @load_model(Website, {'name': 'website'}, 'website') def website_delete(website): g.website = website - return render_delete_sqla(website, db, title=u"Confirm delete", - message=u"Delete website '%s'? This will also permanently remove all " + return render_delete_sqla(website, db, title="Confirm delete", + message="Delete website '%s'? This will also permanently remove all " "pages associated with the website. There is no undo." % website.title, - success=u"You have deleted website '%s'." % website.title, + success="You have deleted website '%s'." % website.title, next=url_for('index')) @@ -77,7 +77,7 @@ def folder_new(website): db.session.add(folder) db.session.commit() return render_redirect(url_for('folder', website=website.name, folder=folder.name), code=303) - return render_form(form=form, title=u"New folder", submit=u"Create", + return render_form(form=form, title="New folder", submit="Create", cancel_url=url_for('website', website=website.name), ajax=True) @@ -99,7 +99,7 @@ def folder_edit(website, folder): form.populate_obj(folder) db.session.commit() return render_redirect(url_for('folder', website=website.name, folder=folder.name), code=303) - return render_form(form=form, title=u"Edit folder", submit=u"Save", + return render_form(form=form, title="Edit folder", submit="Save", cancel_url=url_for('folder', website=website.name, folder=folder.name), ajax=True) @@ -157,9 +157,9 @@ def folder(website, folder): highlight.update(clipboard_paste(folder, session['clipboard'], clip_action)) db.session.commit() else: - flash(u"Unknown clipboard action requested", "error") + flash("Unknown clipboard action requested", "error") else: - flash(u"Nothing to paste", "error") + flash("Nothing to paste", "error") session.pop('clipboard', None) session.pop('clipboard_type', None) elif action == 'delete': @@ -168,9 +168,9 @@ def folder(website, folder): for node in nodes: db.session.delete(node) if len(nodes) == 1: - flash(u"“%s” has been deleted" % nodes[0].title, "success") + flash("“%s” has been deleted" % nodes[0].title, "success") else: - flash(u"%d items have been deleted" % len(nodes), "success") + flash("%d items have been deleted" % len(nodes), "success") db.session.commit() elif action == 'rename': flash("Rename hasn't been implemented yet", "info") @@ -196,15 +196,15 @@ def website(website): def folder_delete(website, folder): g.website = website g.folder = folder - return render_delete_sqla(folder, db, title=u"Confirm delete", - message=u"Delete folder '%s'? This will also permanently remove all " + return render_delete_sqla(folder, db, title="Confirm delete", + message="Delete folder '%s'? This will also permanently remove all " "pages in this folder. There is no undo." % folder.name, - success=u"You have deleted folder '%s'." % folder.name, + success="You have deleted folder '%s'." % folder.name, next=url_for('website', website=website.name)) @app.route('///_export') -@app.route('//_root/_export', defaults={'folder': u''}) +@app.route('//_root/_export', defaults={'folder': ''}) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -224,7 +224,7 @@ def folder_export(website, folder): @app.route('///_import', methods=['GET', 'POST']) -@app.route('//_root/_import', defaults={'folder': u''}, methods=['GET', 'POST']) +@app.route('//_root/_import', defaults={'folder': ''}, methods=['GET', 'POST']) @lastuser.requires_permission('siteadmin') @load_models( (Website, {'name': 'website'}, 'website'), @@ -267,5 +267,5 @@ def folder_import(website, folder): db.session.commit() flash("%d nodes were imported and %d new nodes were created" % (import_count, create_count), "success") return render_redirect(url_for('folder', website=website.name, folder=folder.name), code=303) - return render_form(form=form, title=u"Import to folder", submit=u"Upload", + return render_form(form=form, title="Import to folder", submit="Upload", cancel_url=url_for('folder', website=website.name, folder=folder.name)) diff --git a/eventframe/views/login.py b/eventframe/views/login.py index 297033b..8aaa7ca 100644 --- a/eventframe/views/login.py +++ b/eventframe/views/login.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -import urlparse +import urllib.parse from flask import request, Response, redirect, flash, abort, url_for from coaster.auth import current_auth @@ -29,7 +29,7 @@ def login_event(): code.user = current_auth.user db.session.commit() # Redirect to event website - if urlparse.urlsplit(code.return_url).query: + if urllib.parse.urlsplit(code.return_url).query: return redirect(code.return_url + '&code=' + code.code, code=302) else: return redirect(code.return_url + '?code=' + code.code, code=302) @@ -55,7 +55,7 @@ def logout_event(): code = LoginCode.query.filter_by(code=request.args['code']).first() if code: # Redirect to event website - if urlparse.urlsplit(code.return_url).query: + if urllib.parse.urlsplit(code.return_url).query: return redirect(code.return_url + '&code=' + code.code, code=302) else: return redirect(code.return_url + '?code=' + code.code, code=302) @@ -73,7 +73,7 @@ def logout(): next = url_for('logout_event', code=code.code) else: next = get_next_url() - flash(u"You are now logged out", category='success') + flash("You are now logged out", category='success') signal_logout.send(app, user=current_auth.user) return next @@ -99,7 +99,7 @@ def lastuser_error(error, error_description=None, error_uri=None): if error == 'access_denied': flash("You denied the request to login", category='error') return redirect(get_next_url()) - return Response(u"Error: %s\n" - u"Description: %s\n" - u"URI: %s" % (error, error_description, error_uri), + return Response("Error: %s\n" + "Description: %s\n" + "URI: %s" % (error, error_description, error_uri), mimetype="text/plain") diff --git a/eventframe/views/website.py b/eventframe/views/website.py index e8be8e4..bd3ee94 100644 --- a/eventframe/views/website.py +++ b/eventframe/views/website.py @@ -12,7 +12,7 @@ @eventapp.route('/') def index(): - return node(folder=u'', node=u'') + return node(folder='', node='') @eventapp.route('/favicon.ico') @@ -33,10 +33,10 @@ def node(website, folder, node): folderob = Folder.query.filter_by(name=folder, website=website).first() if folderob is None: # Are we handling a /node/custom_url case? - folderob = Folder.query.filter_by(name=u'', website=website).first_or_404() + folderob = Folder.query.filter_by(name='', website=website).first_or_404() nodeob = Node.query.filter_by(name=folder, folder=folderob).first_or_404() # The node exists. Let the path handler figure out what to do with it - return path_handler(path=u'/' + nodeob.name + u'/' + node) + return path_handler(path='/' + nodeob.name + '/' + node) else: nodeob = Node.query.filter_by(name=node, folder=folderob).first_or_404() @@ -59,9 +59,9 @@ def node(website, folder, node): @get_website def folder(website, folder): try: - return node(folder=folder, node=u'') + return node(folder=folder, node='') except NotFound: - return node(folder=u'', node=folder) + return node(folder='', node=folder) @eventapp.route('/', methods=['GET', 'POST']) @@ -70,13 +70,13 @@ def path_handler(website, path): """Handles paths for nodes with internal items.""" components = path.split('/') pathcomponents = [] - if components[0] == u'': + if components[0] == '': # We had a / prefix. Discard it. components.pop(0) - if len(components) > 2 and components[-1] == u'': + if len(components) > 2 and components[-1] == '': # We got a trailing slash and it's not a folder. Pop it. components.pop(-1) - return redirect(request.script_root + u'/' + u'/'.join(components)) + return redirect(request.script_root + '/' + '/'.join(components)) # Now what do we have? # A: / # B: /folder/ or /node/ @@ -85,15 +85,15 @@ def path_handler(website, path): # E: /folder/node/custom where custom can have many segments if len(components) == 0: # A: Render (root)/(index) [both named ''] - folder = Folder.query.filter_by(website=website, name=u'').first_or_404() - node = Node.query.filter_by(folder=folder, name=u'').first_or_404() + folder = Folder.query.filter_by(website=website, name='').first_or_404() + node = Node.query.filter_by(folder=folder, name='').first_or_404() elif len(components) == 1: # B: Could be a folder or node: folder = Folder.query.filter_by(website=website, name=components[0]).first() if folder is not None: - node = Node.query.filter_by(folder=folder, name=u'').first_or_404() + node = Node.query.filter_by(folder=folder, name='').first_or_404() else: - folder = Folder.query.filter_by(website=website, name=u'').first_or_404() + folder = Folder.query.filter_by(website=website, name='').first_or_404() node = Node.query.filter_by(folder=folder, name=components[0]).first_or_404() else: folder = Folder.query.filter_by(website=website, name=components[0]).first() @@ -103,7 +103,7 @@ def path_handler(website, path): pathcomponents = components[2:] else: # D: node/custom - folder = Folder.query.filter_by(website=website, name=u'').first_or_404() + folder = Folder.query.filter_by(website=website, name='').first_or_404() node = Node.query.filter_by(folder=folder, name=components[0]).first_or_404() pathcomponents = components[1:] diff --git a/migrations/env.py b/migrations/env.py index 4593816..db4cfdf 100755 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,4 +1,4 @@ -from __future__ import with_statement + from alembic import context from sqlalchemy import engine_from_config, pool from logging.config import fileConfig diff --git a/rqinit.py b/rqinit.py index a91b4b1..d0e4730 100644 --- a/rqinit.py +++ b/rqinit.py @@ -1,4 +1,4 @@ -from urlparse import urlparse +from urllib.parse import urlparse from eventframe import app