From 48f1eec30b33883356f3bea4e078842d841790ba Mon Sep 17 00:00:00 2001 From: yoninachmany Date: Sun, 5 Feb 2017 19:49:45 -0500 Subject: [PATCH 1/2] isort --- app/account/forms.py | 11 +++----- app/account/views.py | 21 ++++---------- app/admin/forms.py | 9 +++--- app/admin/views.py | 11 +++----- app/bulk_resource/forms.py | 17 +++--------- app/bulk_resource/views.py | 54 ++++++++++++------------------------ app/contact/forms.py | 17 +++--------- app/contact/views.py | 14 ++++++---- app/decorators.py | 1 + app/descriptor/forms.py | 10 ++----- app/descriptor/views.py | 30 +++++++------------- app/email.py | 5 +++- app/main/errors.py | 1 + app/main/views.py | 19 ++++++++----- app/models/csv.py | 4 +-- app/models/geocoder_cache.py | 2 +- app/models/rating.py | 1 + app/models/resource.py | 2 +- app/models/suggestion.py | 3 +- app/models/user.py | 3 +- app/single_resource/views.py | 12 ++++---- app/suggestion/forms.py | 4 +-- app/suggestion/views.py | 21 ++++++++------ config.py | 3 +- manage.py | 23 ++++++--------- 25 files changed, 121 insertions(+), 177 deletions(-) diff --git a/app/account/forms.py b/app/account/forms.py index fcc9f13..00f61c2 100644 --- a/app/account/forms.py +++ b/app/account/forms.py @@ -1,13 +1,10 @@ from flask.ext.wtf import Form -from wtforms.fields import ( - BooleanField, - PasswordField, - StringField, - SubmitField -) +from wtforms import ValidationError +from wtforms.fields import (BooleanField, PasswordField, StringField, + SubmitField) from wtforms.fields.html5 import EmailField from wtforms.validators import Email, EqualTo, InputRequired, Length -from wtforms import ValidationError + from ..models import User diff --git a/app/account/views.py b/app/account/views.py index 2848bcd..9803b8a 100644 --- a/app/account/views.py +++ b/app/account/views.py @@ -1,24 +1,15 @@ from flask import flash, redirect, render_template, request, url_for -from flask.ext.login import ( - current_user, - login_required, - login_user, - logout_user -) +from flask.ext.login import (current_user, login_required, login_user, + logout_user) from flask.ext.rq import get_queue + from . import account from .. import db from ..email import send_email from ..models import User -from .forms import ( - ChangeAccountInfoForm, - ChangeEmailForm, - ChangePasswordForm, - CreatePasswordForm, - LoginForm, - RequestResetPasswordForm, - ResetPasswordForm -) +from .forms import (ChangeAccountInfoForm, ChangeEmailForm, ChangePasswordForm, + CreatePasswordForm, LoginForm, RequestResetPasswordForm, + ResetPasswordForm) @account.route('/login', methods=['GET', 'POST']) diff --git a/app/admin/forms.py b/app/admin/forms.py index e34b462..2705cf6 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -1,11 +1,12 @@ from flask.ext.wtf import Form +from wtforms import ValidationError +from wtforms.ext.sqlalchemy.fields import QuerySelectField from wtforms.fields import PasswordField, StringField, SubmitField from wtforms.fields.html5 import EmailField -from wtforms.ext.sqlalchemy.fields import QuerySelectField -from wtforms.validators import InputRequired, Length, Email, EqualTo -from wtforms import ValidationError -from ..models import User, Role +from wtforms.validators import Email, EqualTo, InputRequired, Length + from .. import db +from ..models import Role, User class ChangeUserEmailForm(Form): diff --git a/app/admin/views.py b/app/admin/views.py index 920f716..3108403 100644 --- a/app/admin/views.py +++ b/app/admin/views.py @@ -2,16 +2,13 @@ from flask.ext.login import current_user, login_required from flask.ext.rq import get_queue +from forms import (ChangeAccountTypeForm, ChangeUserEmailForm, InviteUserForm, + NewUserForm) + from . import admin from .. import db -from ..models import Role, User, Rating, Resource -from forms import ( - ChangeAccountTypeForm, - ChangeUserEmailForm, - InviteUserForm, - NewUserForm -) from ..email import send_email +from ..models import Rating, Resource, Role, User @admin.route('/') diff --git a/app/bulk_resource/forms.py b/app/bulk_resource/forms.py index a95d441..1332121 100644 --- a/app/bulk_resource/forms.py +++ b/app/bulk_resource/forms.py @@ -1,17 +1,8 @@ from flask.ext.wtf import Form -from flask_wtf.file import ( - InputRequired -) -from wtforms.fields import ( - FieldList, - FormField, - RadioField, - SubmitField, - TextAreaField, - StringField, - SelectField, - SelectMultipleField -) +from flask_wtf.file import InputRequired +from wtforms.fields import (FieldList, FormField, RadioField, SelectField, + SelectMultipleField, StringField, SubmitField, + TextAreaField) class NavigationForm(Form): diff --git a/app/bulk_resource/views.py b/app/bulk_resource/views.py index ba1c0dd..9f30f66 100644 --- a/app/bulk_resource/views.py +++ b/app/bulk_resource/views.py @@ -1,49 +1,29 @@ -from datetime import datetime import json -import geocoder -import time import os +import time +from datetime import datetime -from flask import abort, jsonify, redirect, render_template, request, url_for, flash +import geocoder +from flask import (abort, flash, jsonify, redirect, render_template, request, + url_for) from flask.ext.login import current_user, login_required - -from flask_wtf.file import ( - InputRequired -) -from wtforms.fields import ( - FieldList, - RadioField, - FormField, - SelectMultipleField -) from flask.ext.wtf import Form +from flask_wtf.file import InputRequired +from wtforms.fields import (FieldList, FormField, RadioField, + SelectMultipleField) from app import csrf +from forms import (DetermineDescriptorTypesForm, DetermineOptionsForm, + DetermineRequiredOptionDescriptorForm, NavigationForm, + RequiredOptionDescriptorMissingForm, SaveCsvDataForm) + from . import bulk_resource from .. import db -from ..models import ( - CsvStorage, - CsvRow, - CsvDescriptor, - CsvDescriptorRemove, - GeocoderCache, - Descriptor, - OptionAssociation, - Rating, - Resource, - RequiredOptionDescriptor, - RequiredOptionDescriptorConstructor, - Suggestion, - TextAssociation -) -from forms import ( - DetermineRequiredOptionDescriptorForm, - RequiredOptionDescriptorMissingForm, - DetermineDescriptorTypesForm, - DetermineOptionsForm, - NavigationForm, - SaveCsvDataForm -) +from ..models import (CsvDescriptor, CsvDescriptorRemove, CsvRow, CsvStorage, + Descriptor, GeocoderCache, OptionAssociation, Rating, + RequiredOptionDescriptor, + RequiredOptionDescriptorConstructor, Resource, + Suggestion, TextAssociation) @csrf.exempt diff --git a/app/contact/forms.py b/app/contact/forms.py index 477558b..b6025ea 100644 --- a/app/contact/forms.py +++ b/app/contact/forms.py @@ -1,17 +1,9 @@ from flask.ext.wtf import Form -from wtforms.fields import ( - StringField, - SelectField, - TextField, - TextAreaField, - SubmitField, -) +from wtforms.fields import (SelectField, StringField, SubmitField, + TextAreaField, TextField) from wtforms.fields.html5 import EmailField -from wtforms.validators import ( - InputRequired, - Email, - Length, -) +from wtforms.validators import Email, InputRequired, Length + class ContactForm(Form): name = StringField('Name', validators=[ @@ -41,4 +33,3 @@ class EditCategoryNameForm(Form): Length(1, 250), ]) submit = SubmitField('Update name') - diff --git a/app/contact/views.py b/app/contact/views.py index 92ad66b..29cc5c4 100644 --- a/app/contact/views.py +++ b/app/contact/views.py @@ -1,16 +1,18 @@ import os -from flask import render_template, redirect, url_for, abort, flash + +from flask import abort, flash, redirect, render_template, url_for from flask.ext.login import login_required from flask.ext.rq import get_queue - from wtforms.fields import SelectField -from .. import db -from ..models import EditableHTML, Resource, ContactCategory -from . import contact -from forms import ContactForm, ContactCategoryForm, EditCategoryNameForm from app import create_app +from forms import ContactCategoryForm, ContactForm, EditCategoryNameForm + +from . import contact +from .. import db from ..email import send_email +from ..models import ContactCategory, EditableHTML, Resource + @contact.route('/', methods=['GET', 'POST']) def index(): diff --git a/app/decorators.py b/app/decorators.py index 4697369..90286ac 100644 --- a/app/decorators.py +++ b/app/decorators.py @@ -2,6 +2,7 @@ from flask import abort from flask.ext.login import current_user + from .models import Permission diff --git a/app/descriptor/forms.py b/app/descriptor/forms.py index c0dffa0..40fbf41 100644 --- a/app/descriptor/forms.py +++ b/app/descriptor/forms.py @@ -1,12 +1,6 @@ from flask.ext.wtf import Form -from wtforms.fields import ( - BooleanField, - FieldList, - SelectField, - SelectMultipleField, - SubmitField, - TextField -) +from wtforms.fields import (BooleanField, FieldList, SelectField, + SelectMultipleField, SubmitField, TextField) from wtforms.validators import InputRequired, Length diff --git a/app/descriptor/views.py b/app/descriptor/views.py index 2b17f85..f65914d 100644 --- a/app/descriptor/views.py +++ b/app/descriptor/views.py @@ -1,28 +1,19 @@ -from flask import abort, flash, render_template, redirect, url_for, request +from flask import abort, flash, redirect, render_template, request, url_for from flask.ext.login import login_required +from flask_wtf.file import InputRequired from sqlalchemy.exc import IntegrityError from wtforms.fields import SelectField -from flask_wtf.file import InputRequired -from forms import ( - AddDescriptorOptionValueForm, - EditDescriptorNameForm, - EditDescriptorOptionValueForm, - EditDescriptorSearchableForm, - FixAllResourceOptionValueForm, - NewDescriptorForm, - ChangeRequiredOptionDescriptorForm, - RequiredOptionDescriptorMissingForm -) +from forms import (AddDescriptorOptionValueForm, + ChangeRequiredOptionDescriptorForm, EditDescriptorNameForm, + EditDescriptorOptionValueForm, EditDescriptorSearchableForm, + FixAllResourceOptionValueForm, NewDescriptorForm, + RequiredOptionDescriptorMissingForm) + from . import descriptor from .. import db -from ..models import ( - Descriptor, - OptionAssociation, - Resource, - RequiredOptionDescriptor, - RequiredOptionDescriptorConstructor -) +from ..models import (Descriptor, OptionAssociation, RequiredOptionDescriptor, + RequiredOptionDescriptorConstructor, Resource) @descriptor.route('/') @@ -420,4 +411,3 @@ def review_required_option_descriptor(): form.resources[j].label = r_name form.resources[j].choices = [(v, v) for v in req_opt_desc_const.values] return render_template('descriptor/review_required_option_descriptor.html', form=form) - diff --git a/app/email.py b/app/email.py index 17520dd..80f68ee 100644 --- a/app/email.py +++ b/app/email.py @@ -1,9 +1,12 @@ import os + from flask import render_template from flask.ext.mail import Message -from . import mail + from app import create_app +from . import mail + def send_email(recipient, subject, template, **kwargs): app = create_app(os.getenv('FLASK_CONFIG') or 'default') diff --git a/app/main/errors.py b/app/main/errors.py index 1d8cb59..52e7a5f 100644 --- a/app/main/errors.py +++ b/app/main/errors.py @@ -1,4 +1,5 @@ from flask import render_template + from . import main diff --git a/app/main/views.py b/app/main/views.py index a312702..08d67bd 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -1,17 +1,22 @@ import json import os -from twilio.rest.lookups import TwilioLookupsClient -from twilio.rest import TwilioRestClient -from flask import render_template, url_for, request, jsonify +from datetime import datetime + +from flask import jsonify, render_template, request, url_for from flask.ext.login import login_required from twilio import twiml +from twilio.rest import TwilioRestClient +from twilio.rest.lookups import TwilioLookupsClient +from wtforms.fields import SelectMultipleField, TextAreaField + from app import csrf -from .. import db -from ..models import EditableHTML, Resource, Rating, Descriptor, OptionAssociation, RequiredOptionDescriptor + from . import main -from wtforms.fields import SelectMultipleField, TextAreaField +from .. import db +from ..models import (Descriptor, EditableHTML, OptionAssociation, Rating, + RequiredOptionDescriptor, Resource) from ..single_resource.forms import SingleResourceForm -from datetime import datetime + @main.route('/') def index(): diff --git a/app/models/csv.py b/app/models/csv.py index 0a638c8..87c4fbc 100644 --- a/app/models/csv.py +++ b/app/models/csv.py @@ -1,7 +1,7 @@ -from .. import db - from sqlalchemy import desc +from .. import db + class CsvStorage(db.Model): """ General CSV Storage container encompassing one CSV """ diff --git a/app/models/geocoder_cache.py b/app/models/geocoder_cache.py index 30e1744..53514bc 100644 --- a/app/models/geocoder_cache.py +++ b/app/models/geocoder_cache.py @@ -7,4 +7,4 @@ class GeocoderCache(db.Model): id = db.Column(db.Integer, primary_key=True) address = db.Column(db.String(500), index=True) latitude = db.Column(db.Float) - longitude = db.Column(db.Float) \ No newline at end of file + longitude = db.Column(db.Float) diff --git a/app/models/rating.py b/app/models/rating.py index 61580d1..3fbb779 100644 --- a/app/models/rating.py +++ b/app/models/rating.py @@ -1,4 +1,5 @@ from datetime import datetime + from .. import db diff --git a/app/models/resource.py b/app/models/resource.py index b4f7a42..276232e 100644 --- a/app/models/resource.py +++ b/app/models/resource.py @@ -1,5 +1,5 @@ from .. import db -from .. models import Rating +from ..models import Rating class OptionAssociation(db.Model): diff --git a/app/models/suggestion.py b/app/models/suggestion.py index 78edf57..e27d72a 100644 --- a/app/models/suggestion.py +++ b/app/models/suggestion.py @@ -1,5 +1,7 @@ from datetime import datetime + import pytz + from .. import db @@ -85,4 +87,3 @@ def generate_fake_edits(count=20): db.session.commit() except IntegrityError: db.session.rollback() - diff --git a/app/models/user.py b/app/models/user.py index 413e8f0..2a0ecbf 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -1,8 +1,9 @@ from flask import current_app from flask.ext.login import AnonymousUserMixin, UserMixin -from werkzeug.security import check_password_hash, generate_password_hash from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from itsdangerous import BadSignature, SignatureExpired +from werkzeug.security import check_password_hash, generate_password_hash + from .. import db, login_manager diff --git a/app/single_resource/views.py b/app/single_resource/views.py index 9e3b21b..b89fb4d 100644 --- a/app/single_resource/views.py +++ b/app/single_resource/views.py @@ -1,13 +1,13 @@ -from flask import abort, flash, redirect, render_template, url_for, request +from flask import abort, flash, redirect, render_template, request, url_for from flask.ext.login import login_required -from sqlalchemy.exc import IntegrityError -from wtforms.fields import SelectMultipleField, TextAreaField -from wtforms.fields import SelectMultipleField, SelectField, TextAreaField from flask_wtf.file import InputRequired +from sqlalchemy.exc import IntegrityError +from wtforms.fields import SelectField, SelectMultipleField, TextAreaField -from .. import db -from ..models import Descriptor, OptionAssociation, Resource, TextAssociation, RequiredOptionDescriptor from . import single_resource +from .. import db +from ..models import (Descriptor, OptionAssociation, RequiredOptionDescriptor, + Resource, TextAssociation) from .forms import SingleResourceForm diff --git a/app/suggestion/forms.py b/app/suggestion/forms.py index 43a994e..74699a8 100644 --- a/app/suggestion/forms.py +++ b/app/suggestion/forms.py @@ -1,5 +1,5 @@ from flask.ext.wtf import Form -from wtforms.fields import SubmitField, TextField, StringField +from wtforms.fields import StringField, SubmitField, TextField from wtforms.validators import Email, InputRequired, Length @@ -57,4 +57,4 @@ class SuggestionAdvancedForm(Form): suggestion_text = TextField('Suggestion', validators=[ InputRequired() ]) - submit = SubmitField('Submit') \ No newline at end of file + submit = SubmitField('Submit') diff --git a/app/suggestion/views.py b/app/suggestion/views.py index eeddd0d..fd96386 100644 --- a/app/suggestion/views.py +++ b/app/suggestion/views.py @@ -1,21 +1,24 @@ -import pytz import os - from datetime import datetime + +import pytz from flask import abort, flash, redirect, render_template, url_for from flask.ext.login import login_required from flask.ext.rq import get_queue from sqlalchemy.exc import IntegrityError +from wtforms.fields import SelectField, TextAreaField + +from app import create_app +from forms import SuggestionAdvancedForm, SuggestionBasicForm from . import suggestion from .. import db -from ..models import Resource, Suggestion, Descriptor, TextAssociation, OptionAssociation -from forms import SuggestionBasicForm, SuggestionAdvancedForm -from wtforms.fields import TextAreaField, SelectField -from ..single_resource.views import save_associations -from ..single_resource.forms import SingleResourceForm -from app import create_app from ..email import send_email +from ..models import (Descriptor, OptionAssociation, Resource, Suggestion, + TextAssociation) +from ..single_resource.forms import SingleResourceForm +from ..single_resource.views import save_associations + @suggestion.route('/') @login_required @@ -227,4 +230,4 @@ def edit(sugg_id): for field_name in resource_field_names[1:]: form[field_name].data = resource.__dict__[field_name] - return render_template('suggestion/edit.html', form=form, suggestion=suggestion, resource_id=resource_id) \ No newline at end of file + return render_template('suggestion/edit.html', form=form, suggestion=suggestion, resource_id=resource_id) diff --git a/config.py b/config.py index fc00c88..1775121 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,7 @@ +import logging import os +import sys import urlparse -import logging, sys from logging.handlers import SMTPHandler basedir = os.path.abspath(os.path.dirname(__file__)) diff --git a/manage.py b/manage.py index cfbcb47..719289d 100755 --- a/manage.py +++ b/manage.py @@ -1,23 +1,16 @@ #!/usr/bin/env python import os -from app import create_app, db -from app.models import ( - CsvBodyCell, - CsvBodyRow, - CsvContainer, - CsvHeaderCell, - CsvHeaderRow, - Resource, - Role, - User, - RequiredOptionDescriptor, -) -from redis import Redis -from rq import Worker, Queue, Connection from config import Config -from flask.ext.script import Manager, Shell + from flask.ext.migrate import Migrate, MigrateCommand +from flask.ext.script import Manager, Shell +from redis import Redis +from rq import Connection, Queue, Worker +from app import create_app, db +from app.models import (CsvBodyCell, CsvBodyRow, CsvContainer, CsvHeaderCell, + CsvHeaderRow, RequiredOptionDescriptor, Resource, Role, + User) # Import settings from .env file. Must define FLASK_CONFIG if os.path.exists('.env'): From 97e5724cbf589f5132d8b9a520e2cb3f1b3f6b8c Mon Sep 17 00:00:00 2001 From: yoninachmany Date: Sun, 5 Feb 2017 19:50:00 -0500 Subject: [PATCH 2/2] yapf --- app/__init__.py | 8 +- app/account/forms.py | 76 ++++---- app/account/views.py | 59 +++---- app/admin/forms.py | 48 +++--- app/admin/views.py | 44 ++--- app/assets.py | 20 +-- app/bulk_resource/forms.py | 16 +- app/bulk_resource/views.py | 324 ++++++++++++++++++----------------- app/contact/forms.py | 44 ++--- app/contact/views.py | 65 +++---- app/decorators.py | 3 + app/descriptor/forms.py | 12 +- app/descriptor/views.py | 220 +++++++++++++----------- app/email.py | 7 +- app/main/views.py | 110 ++++++------ app/models/__init__.py | 12 +- app/models/bulk.py | 27 +-- app/models/csv.py | 60 ++++--- app/models/editable.py | 3 +- app/models/rating.py | 19 +- app/models/resource.py | 78 ++++----- app/models/suggestion.py | 27 ++- app/models/user.py | 26 +-- app/single_resource/forms.py | 19 +- app/single_resource/views.py | 123 +++++++------ app/suggestion/forms.py | 57 ++---- app/suggestion/views.py | 93 +++++----- config.py | 7 +- manage.py | 34 ++-- 29 files changed, 845 insertions(+), 796 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index e474869..68f7b6f 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -70,15 +70,15 @@ def create_app(config_name): app.register_blueprint(admin_blueprint, url_prefix='/admin') from bulk_resource import bulk_resource as bulk_resource_blueprint - app.register_blueprint(bulk_resource_blueprint, - url_prefix='/bulk-resource') + app.register_blueprint( + bulk_resource_blueprint, url_prefix='/bulk-resource') from descriptor import descriptor as descriptor_blueprint app.register_blueprint(descriptor_blueprint, url_prefix='/descriptor') from single_resource import single_resource as single_resource_blueprint - app.register_blueprint(single_resource_blueprint, - url_prefix='/single-resource') + app.register_blueprint( + single_resource_blueprint, url_prefix='/single-resource') from suggestion import suggestion as suggestion_blueprint app.register_blueprint(suggestion_blueprint, url_prefix='/suggestion') diff --git a/app/account/forms.py b/app/account/forms.py index 00f61c2..fd80f9a 100644 --- a/app/account/forms.py +++ b/app/account/forms.py @@ -9,21 +9,16 @@ class LoginForm(Form): - email = EmailField('Email', validators=[ - InputRequired(), - Length(1, 500), - Email() - ]) + email = EmailField( + 'Email', validators=[InputRequired(), Length(1, 500), Email()]) password = PasswordField('Password', validators=[InputRequired()]) remember_me = BooleanField('Keep me logged in') submit = SubmitField('Log in') class RequestResetPasswordForm(Form): - email = EmailField('Email', validators=[ - InputRequired(), - Length(1, 500), - Email()]) + email = EmailField( + 'Email', validators=[InputRequired(), Length(1, 500), Email()]) submit = SubmitField('Reset password') # We don't validate the email address so we don't confirm to attackers @@ -31,16 +26,15 @@ class RequestResetPasswordForm(Form): class ResetPasswordForm(Form): - email = EmailField('Email', validators=[ - InputRequired(), - Length(1, 500), - Email()]) - new_password = PasswordField('New password', validators=[ - InputRequired(), - EqualTo('new_password2', 'Passwords must match.') - ]) - new_password2 = PasswordField('Confirm new password', - validators=[InputRequired()]) + email = EmailField( + 'Email', validators=[InputRequired(), Length(1, 500), Email()]) + new_password = PasswordField( + 'New password', + validators=[ + InputRequired(), EqualTo('new_password2', 'Passwords must match.') + ]) + new_password2 = PasswordField( + 'Confirm new password', validators=[InputRequired()]) submit = SubmitField('Reset password') def validate_email(self, field): @@ -49,31 +43,31 @@ def validate_email(self, field): class CreatePasswordForm(Form): - password = PasswordField('Password', validators=[ - InputRequired(), - EqualTo('password2', 'Passwords must match.') - ]) - password2 = PasswordField('Confirm new password', - validators=[InputRequired()]) + password = PasswordField( + 'Password', + validators=[ + InputRequired(), EqualTo('password2', 'Passwords must match.') + ]) + password2 = PasswordField( + 'Confirm new password', validators=[InputRequired()]) submit = SubmitField('Set password') class ChangePasswordForm(Form): old_password = PasswordField('Old password', validators=[InputRequired()]) - new_password = PasswordField('New password', validators=[ - InputRequired(), - EqualTo('new_password2', 'Passwords must match.') - ]) - new_password2 = PasswordField('Confirm new password', - validators=[InputRequired()]) + new_password = PasswordField( + 'New password', + validators=[ + InputRequired(), EqualTo('new_password2', 'Passwords must match.') + ]) + new_password2 = PasswordField( + 'Confirm new password', validators=[InputRequired()]) submit = SubmitField('Update password') class ChangeEmailForm(Form): - email = EmailField('New email', validators=[ - InputRequired(), - Length(1, 500), - Email()]) + email = EmailField( + 'New email', validators=[InputRequired(), Length(1, 500), Email()]) password = PasswordField('Password', validators=[InputRequired()]) submit = SubmitField('Update email') @@ -83,12 +77,8 @@ def validate_email(self, field): class ChangeAccountInfoForm(Form): - first_name = StringField('First name', validators=[ - InputRequired(), - Length(1, 500) - ]) - last_name = StringField('Last name', validators=[ - InputRequired(), - Length(1, 500) - ]) + first_name = StringField( + 'First name', validators=[InputRequired(), Length(1, 500)]) + last_name = StringField( + 'Last name', validators=[InputRequired(), Length(1, 500)]) submit = SubmitField('Update account information') diff --git a/app/account/views.py b/app/account/views.py index 9803b8a..6b453b6 100644 --- a/app/account/views.py +++ b/app/account/views.py @@ -54,8 +54,8 @@ def reset_password_request(): user = User.query.filter_by(email=form.email.data).first() if user: token = user.generate_password_reset_token() - reset_link = url_for('account.reset_password', token=token, - _external=True) + reset_link = url_for( + 'account.reset_password', token=token, _external=True) get_queue().enqueue( send_email, recipient=user.email, @@ -63,11 +63,9 @@ def reset_password_request(): template='account/email/reset_password', user=user, reset_link=reset_link, - next=request.args.get('next') - ) + next=request.args.get('next')) flash('A password reset link has been sent to {}.' - .format(form.email.data), - 'warning') + .format(form.email.data), 'warning') return redirect(url_for('account.login')) return render_template('account/reset_password.html', form=form) @@ -140,8 +138,8 @@ def change_email_request(): if current_user.verify_password(form.password.data): new_email = form.email.data token = current_user.generate_email_change_token(new_email) - change_email_link = url_for('account.change_email', token=token, - _external=True) + change_email_link = url_for( + 'account.change_email', token=token, _external=True) get_queue().enqueue( send_email, recipient=new_email, @@ -150,8 +148,7 @@ def change_email_request(): # current_user is a LocalProxy, we want the underlying user # object user=current_user._get_current_object(), - change_email_link=change_email_link - ) + change_email_link=change_email_link) flash('A confirmation link has been sent to {}.'.format(new_email), 'warning') return redirect(url_for('main.index')) @@ -184,11 +181,9 @@ def confirm_request(): template='account/email/confirm', # current_user is a LocalProxy, we want the underlying user object user=current_user._get_current_object(), - confirm_link=confirm_link - ) - flash('A new confirmation link has been sent to {}.'. - format(current_user.email), - 'warning') + confirm_link=confirm_link) + flash('A new confirmation link has been sent to {}.'.format( + current_user.email), 'warning') return redirect(url_for('main.index')) @@ -205,8 +200,8 @@ def confirm(token): return redirect(url_for('main.index')) -@account.route('/join-from-invite//', - methods=['GET', 'POST']) +@account.route( + '/join-from-invite//', methods=['GET', 'POST']) def join_from_invite(user_id, token): """ Confirm new user's account with provided token and prompt them to set @@ -225,30 +220,32 @@ def join_from_invite(user_id, token): return redirect(url_for('main.index')) if new_user.confirm_account(token): - form = CreatePasswordForm() - if form.validate_on_submit(): - new_user.password = form.password.data - db.session.add(new_user) - db.session.commit() - flash('Your password has been set. After you log in, you can ' - 'go to the "Your Account" page to review your account ' - 'information and settings.', 'success') - return redirect(url_for('account.login')) - return render_template('account/join_invite.html', form=form) + form = CreatePasswordForm() + if form.validate_on_submit(): + new_user.password = form.password.data + db.session.add(new_user) + db.session.commit() + flash('Your password has been set. After you log in, you can ' + 'go to the "Your Account" page to review your account ' + 'information and settings.', 'success') + return redirect(url_for('account.login')) + return render_template('account/join_invite.html', form=form) else: flash('The confirmation link is invalid or has expired. Another ' 'invite email with a new link has been sent to you.', 'error') token = new_user.generate_confirmation_token() - invite_link = url_for('account.join_from_invite', user_id=user_id, - token=token, _external=True) + invite_link = url_for( + 'account.join_from_invite', + user_id=user_id, + token=token, + _external=True) get_queue().enqueue( send_email, recipient=new_user.email, subject='You Are Invited To Join', template='account/email/invite', user=new_user, - invite_link=invite_link - ) + invite_link=invite_link) return redirect(url_for('main.index')) diff --git a/app/admin/forms.py b/app/admin/forms.py index 2705cf6..6e6e385 100644 --- a/app/admin/forms.py +++ b/app/admin/forms.py @@ -10,11 +10,8 @@ class ChangeUserEmailForm(Form): - email = EmailField('New email', validators=[ - InputRequired(), - Length(1, 500), - Email() - ]) + email = EmailField( + 'New email', validators=[InputRequired(), Length(1, 500), Email()]) submit = SubmitField('Update email') def validate_email(self, field): @@ -23,26 +20,26 @@ def validate_email(self, field): class ChangeAccountTypeForm(Form): - role = QuerySelectField('New account type', - validators=[InputRequired()], - get_label='name', - query_factory=lambda: db.session.query(Role). - order_by('permissions')) + role = QuerySelectField( + 'New account type', + validators=[InputRequired()], + get_label='name', + query_factory=lambda: db.session.query(Role).order_by('permissions')) submit = SubmitField('Update role') class InviteUserForm(Form): - role = QuerySelectField('Account type', - validators=[InputRequired()], - get_label='name', - query_factory=lambda: db.session.query(Role). - order_by('permissions')) - first_name = StringField('First name', validators=[InputRequired(), - Length(1, 500)]) - last_name = StringField('Last name', validators=[InputRequired(), - Length(1, 500)]) - email = EmailField('Email', validators=[InputRequired(), Length(1, 500), - Email()]) + role = QuerySelectField( + 'Account type', + validators=[InputRequired()], + get_label='name', + query_factory=lambda: db.session.query(Role).order_by('permissions')) + first_name = StringField( + 'First name', validators=[InputRequired(), Length(1, 500)]) + last_name = StringField( + 'Last name', validators=[InputRequired(), Length(1, 500)]) + email = EmailField( + 'Email', validators=[InputRequired(), Length(1, 500), Email()]) submit = SubmitField('Invite') def validate_email(self, field): @@ -51,10 +48,11 @@ def validate_email(self, field): class NewUserForm(InviteUserForm): - password = PasswordField('Password', validators=[ - InputRequired(), EqualTo('password2', - 'Passwords must match.') - ]) + password = PasswordField( + 'Password', + validators=[ + InputRequired(), EqualTo('password2', 'Passwords must match.') + ]) password2 = PasswordField('Confirm password', validators=[InputRequired()]) submit = SubmitField('Create') diff --git a/app/admin/views.py b/app/admin/views.py index 3108403..7203137 100644 --- a/app/admin/views.py +++ b/app/admin/views.py @@ -24,11 +24,12 @@ def new_user(): """Create a new user.""" form = NewUserForm() if form.validate_on_submit(): - user = User(role=form.role.data, - first_name=form.first_name.data, - last_name=form.last_name.data, - email=form.email.data, - password=form.password.data) + user = User( + role=form.role.data, + first_name=form.first_name.data, + last_name=form.last_name.data, + email=form.email.data, + password=form.password.data) db.session.add(user) db.session.commit() flash('User {} successfully created'.format(user.full_name()), @@ -42,23 +43,26 @@ def invite_user(): """Invites a new user to create an account and set their own password.""" form = InviteUserForm() if form.validate_on_submit(): - user = User(role=form.role.data, - first_name=form.first_name.data, - last_name=form.last_name.data, - email=form.email.data) + user = User( + role=form.role.data, + first_name=form.first_name.data, + last_name=form.last_name.data, + email=form.email.data) db.session.add(user) db.session.commit() token = user.generate_confirmation_token() - invite_link = url_for('account.join_from_invite', user_id=user.id, - token=token, _external=True) + invite_link = url_for( + 'account.join_from_invite', + user_id=user.id, + token=token, + _external=True) get_queue().enqueue( send_email, recipient=user.email, subject='You Are Invited To Join', template='account/email/invite', user=user, - invite_link=invite_link, - ) + invite_link=invite_link, ) flash('User {} successfully invited'.format(user.full_name()), 'form-success') return render_template('admin/new_user.html', form=form) @@ -70,8 +74,8 @@ def registered_users(): """View all registered users.""" users = User.query.all() roles = Role.query.all() - return render_template('admin/registered_users.html', users=users, - roles=roles) + return render_template( + 'admin/registered_users.html', users=users, roles=roles) @admin.route('/user/') @@ -98,13 +102,12 @@ def change_user_email(user_id): db.session.add(user) db.session.commit() flash('Email for user {} successfully changed to {}.' - .format(user.full_name(), user.email), - 'form-success') + .format(user.full_name(), user.email), 'form-success') return render_template('admin/manage_user.html', user=user, form=form) -@admin.route('/user//change-account-type', - methods=['GET', 'POST']) +@admin.route( + '/user//change-account-type', methods=['GET', 'POST']) @login_required def change_account_type(user_id): """Change a user's account type.""" @@ -122,8 +125,7 @@ def change_account_type(user_id): db.session.add(user) db.session.commit() flash('Role for user {} successfully changed to {}.' - .format(user.full_name(), user.role.name), - 'form-success') + .format(user.full_name(), user.role.name), 'form-success') return render_template('admin/manage_user.html', user=user, form=form) diff --git a/app/assets.py b/app/assets.py index 910ab08..4d424b7 100644 --- a/app/assets.py +++ b/app/assets.py @@ -1,21 +1,10 @@ from flask.ext.assets import Bundle -app_css = Bundle( - '*.scss', - filters='scss', - output='styles/app.css' -) +app_css = Bundle('*.scss', filters='scss', output='styles/app.css') -app_js = Bundle( - '*.js', - filters='jsmin', - output='scripts/app.js' -) +app_js = Bundle('*.js', filters='jsmin', output='scripts/app.js') -vendor_css = Bundle( - 'vendor/*.css', - output='styles/vendor.css' -) +vendor_css = Bundle('vendor/*.css', output='styles/vendor.css') # Need to specify vendor order or JS errors on heroku vendor_js = Bundle( @@ -29,5 +18,4 @@ 'vendor/papaparse.min.js', 'vendor/zxcvbn.js', filters='jsmin', - output='scripts/vendor.js' -) + output='scripts/vendor.js') diff --git a/app/bulk_resource/forms.py b/app/bulk_resource/forms.py index 1332121..548f163 100644 --- a/app/bulk_resource/forms.py +++ b/app/bulk_resource/forms.py @@ -10,24 +10,30 @@ class NavigationForm(Form): submit_cancel = SubmitField('Cancel') submit_back = SubmitField('Back') + class DetermineRequiredOptionDescriptorForm(Form): - required_option_descriptor = SelectField('Required Option Descriptor', validators=[InputRequired()]) + required_option_descriptor = SelectField( + 'Required Option Descriptor', validators=[InputRequired()]) navigation = FormField(NavigationForm) + class DetermineDescriptorTypesForm(Form): - descriptor_types = FieldList(RadioField(choices=[ - ('text', 'Text'), - ('option', 'Option') - ], validators=[InputRequired()])) + descriptor_types = FieldList( + RadioField( + choices=[('text', 'Text'), ('option', 'Option')], + validators=[InputRequired()])) navigation = FormField(NavigationForm) + class RequiredOptionDescriptorMissingForm(Form): resources = FieldList(SelectMultipleField(validators=[InputRequired()])) navigation = FormField(NavigationForm) + class DetermineOptionsForm(Form): navigation = FormField(NavigationForm) + class SaveCsvDataForm(Form): submit = SubmitField('Save') submit_cancel = SubmitField('Cancel') diff --git a/app/bulk_resource/views.py b/app/bulk_resource/views.py index 9f30f66..6de8931 100644 --- a/app/bulk_resource/views.py +++ b/app/bulk_resource/views.py @@ -19,11 +19,10 @@ from . import bulk_resource from .. import db -from ..models import (CsvDescriptor, CsvDescriptorRemove, CsvRow, CsvStorage, - Descriptor, GeocoderCache, OptionAssociation, Rating, - RequiredOptionDescriptor, - RequiredOptionDescriptorConstructor, Resource, - Suggestion, TextAssociation) +from ..models import ( + CsvDescriptor, CsvDescriptorRemove, CsvRow, CsvStorage, Descriptor, + GeocoderCache, OptionAssociation, Rating, RequiredOptionDescriptor, + RequiredOptionDescriptorConstructor, Resource, Suggestion, TextAssociation) @csrf.exempt @@ -35,13 +34,15 @@ def upload(): ''' Processes each Deferred Ajax request ''' + + @csrf.exempt @bulk_resource.route('/_upload', methods=['POST']) def upload_row(): data = json.loads(request.form['json']) # Store CSV fields as descriptors - if data['action'] == 'fields-reset': # Reset operation + if data['action'] == 'fields-reset': # Reset operation try: fields = data['fields'] @@ -49,36 +50,35 @@ def upload_row(): csv_storage = CsvStorage( date_uploaded=datetime.now(), user=current_user, - action='reset', - ) + action='reset', ) # Store new descriptors - fields = [f.strip() for f in fields if - f.strip() and f.strip() != 'Name' and f.strip() != 'Address'] + fields = [ + f.strip() for f in fields + if f.strip() and f.strip() != 'Name' and f.strip() != 'Address' + ] for f in fields: desc = CsvDescriptor( csv_storage=csv_storage, name=f, - values=set(), - ) + values=set(), ) db.session.add(desc) db.session.add(csv_storage) db.session.commit() return jsonify({ "status": "Success", "message": "Successfully added fields", - }) + }) except: db.session.rollback() abort(404) - if data['action'] == 'fields-update': # Update operation + if data['action'] == 'fields-update': # Update operation try: fields = data['fields'] csv_storage = CsvStorage( date_uploaded=datetime.now(), user=current_user, - action='update', - ) + action='update', ) # get old fields descriptors = Descriptor.query.all() @@ -86,20 +86,19 @@ def upload_row(): old_d = descriptors.keys() # compare with new fields - new_d = [f.strip() for f in fields if - f.strip() and f.strip() != 'Name' and f.strip() != 'Address'] + new_d = [ + f.strip() for f in fields + if f.strip() and f.strip() != 'Name' and f.strip() != 'Address' + ] # store descriptors to remove removed = set(old_d) - set(new_d) for f in removed: - old_desc = Descriptor.query.filter_by( - name=f - ).first() + old_desc = Descriptor.query.filter_by(name=f).first() desc = CsvDescriptorRemove( csv_storage=csv_storage, descriptor_id=old_desc.id, - name=old_desc.name, - ) + name=old_desc.name, ) db.session.add(desc) # store old descriptors not removed @@ -113,8 +112,7 @@ def upload_row(): name=f, values=set(), descriptor_id=existing_desc.id, - descriptor_type=existing_type, - ) + descriptor_type=existing_type, ) db.session.add(desc) # store new descriptors @@ -123,8 +121,7 @@ def upload_row(): desc = CsvDescriptor( csv_storage=csv_storage, name=f, - values=set(), - ) + values=set(), ) db.session.add(desc) db.session.add(csv_storage) @@ -132,43 +129,41 @@ def upload_row(): return jsonify({ "status": "Success", "message": "Successfully added fields" - }) + }) except: db.session.rollback() abort(404) # Store CSV rows - if data['action'] == 'reset-update': # Reset operation + if data['action'] == 'reset-update': # Reset operation try: row = data['row'] - clean_row = {k.strip():v.strip() for k, v in row.iteritems()} + clean_row = {k.strip(): v.strip() for k, v in row.iteritems()} # Validate addresses address = clean_row['Address'] # See if address exists in cache - cached = GeocoderCache.query.filter_by( - address=address - ).first() + cached = GeocoderCache.query.filter_by(address=address).first() if cached is None: # Toggle API to avoid Google geocoder API limit - temp solution if data['count'] % 45 == 0: - if os.environ.get('GOOGLE_API_KEY') == os.environ.get('GOOGLE_API_1'): - os.environ['GOOGLE_API_KEY'] = os.environ.get('GOOGLE_API_2') + if os.environ.get('GOOGLE_API_KEY') == os.environ.get( + 'GOOGLE_API_1'): + os.environ['GOOGLE_API_KEY'] = os.environ.get( + 'GOOGLE_API_2') else: - os.environ['GOOGLE_API_KEY'] = os.environ.get('GOOGLE_API_1') - g = geocoder.google(address, key=os.environ.get('GOOGLE_API_KEY')) + os.environ['GOOGLE_API_KEY'] = os.environ.get( + 'GOOGLE_API_1') + g = geocoder.google( + address, key=os.environ.get('GOOGLE_API_KEY')) if g.status != 'OK': msg = 'Address cannot be geocoded due to ' + g.status + ": " + address - return jsonify({ - "status": "Error", - "message": msg - }) + return jsonify({"status": "Error", "message": msg}) else: geo = GeocoderCache( address=address, latitude=g.latlng[0], - longitude=g.latlng[1] - ) + longitude=g.latlng[1]) db.session.add(geo) csv_storage = CsvStorage.most_recent(user=current_user) @@ -177,62 +172,55 @@ def upload_row(): csv_row = CsvRow( csv_storage=csv_storage, - data=clean_row, - ) + data=clean_row, ) db.session.add(csv_row) db.session.commit() return jsonify({ "status": "Success", "message": "Successfully added row" - }) + }) except: db.session.rollback() abort(404) - if data['action'] == 'update': # Update operation + if data['action'] == 'update': # Update operation try: row = data['row'] - clean_row = {k.strip():v.strip() for k, v in row.iteritems()} + clean_row = {k.strip(): v.strip() for k, v in row.iteritems()} # Validate addresses address = clean_row['Address'] # See if address exists in cache - cached = GeocoderCache.query.filter_by( - address=address - ).first() + cached = GeocoderCache.query.filter_by(address=address).first() if cached is None: # Toggle API to avoid Google geocoder API limit - temp solution if data['count'] % 45 == 0: - if os.environ.get('GOOGLE_API_KEY') == os.environ.get('GOOGLE_API_1'): - os.environ['GOOGLE_API_KEY'] = os.environ.get('GOOGLE_API_2') + if os.environ.get('GOOGLE_API_KEY') == os.environ.get( + 'GOOGLE_API_1'): + os.environ['GOOGLE_API_KEY'] = os.environ.get( + 'GOOGLE_API_2') else: - os.environ['GOOGLE_API_KEY'] = os.environ.get('GOOGLE_API_1') - g = geocoder.google(address, key=os.environ.get('GOOGLE_API_KEY')) + os.environ['GOOGLE_API_KEY'] = os.environ.get( + 'GOOGLE_API_1') + g = geocoder.google( + address, key=os.environ.get('GOOGLE_API_KEY')) if g.status != 'OK': msg = 'Address cannot be geocoded due to ' + g.status + ": " + address - return jsonify({ - "status": "Error", - "message": msg - }) + return jsonify({"status": "Error", "message": msg}) else: geo = GeocoderCache( address=address, latitude=g.latlng[0], - longitude=g.latlng[1] - ) + longitude=g.latlng[1]) db.session.add(geo) csv_storage = CsvStorage.most_recent(user=current_user) if csv_storage is None: abort(404) - csv_row = CsvRow( - csv_storage=csv_storage, - data=clean_row - ) + csv_row = CsvRow(csv_storage=csv_storage, data=clean_row) # See if resource already exists existing_resource = Resource.query.filter_by( - name=row['Name'] - ).first() + name=row['Name']).first() if existing_resource is not None: csv_row.resource_id = existing_resource.id @@ -241,7 +229,7 @@ def upload_row(): return jsonify({ "status": "Success", "message": "Successfully added row" - }) + }) except: db.session.rollback() abort(404) @@ -256,14 +244,14 @@ def upload_row(): return jsonify({ "status": "Error", "message": 'No resources to update from CSV' - }) + }) - return jsonify( - redirect=url_for('bulk_resource.set_descriptor_types') - ) + return jsonify(redirect=url_for('bulk_resource.set_descriptor_types')) ''' Sets each descriptor in the CSV to be an option or a text descriptor ''' + + @bulk_resource.route('/set-descriptor-types', methods=['GET', 'POST']) @login_required def set_descriptor_types(): @@ -291,7 +279,8 @@ def set_descriptor_types(): if contains_options: csv_storage.set_desc_values() return redirect(url_for('bulk_resource.review_desc_options')) - return redirect(url_for('bulk_resource.set_required_option_descriptor')) + return redirect( + url_for('bulk_resource.set_required_option_descriptor')) elif form.navigation.data['submit_back']: db.session.delete(csv_storage) @@ -324,15 +313,22 @@ def set_descriptor_types(): remove_descs = [] if csv_storage.action == 'update': remove_descs = [d.name for d in csv_storage.csv_descriptors_remove] - existing_descs = [d for d in Descriptor.query.all() if d.name not in remove_descs] + existing_descs = [ + d for d in Descriptor.query.all() if d.name not in remove_descs + ] - return render_template('bulk_resource/set_descriptor_types.html', - form=form, existing_descs=existing_descs, - num=num, remove_descs=remove_descs) + return render_template( + 'bulk_resource/set_descriptor_types.html', + form=form, + existing_descs=existing_descs, + num=num, + remove_descs=remove_descs) ''' If there are option descriptors in the CSV, display the option values parsed from the CSV for verification ''' + + @bulk_resource.route('/review-desc-options', methods=['GET', 'POST']) @login_required def review_desc_options(): @@ -344,7 +340,8 @@ def review_desc_options(): if form.validate_on_submit(): if form.navigation.data['submit_next']: - return redirect(url_for('bulk_resource.set_required_option_descriptor')) + return redirect( + url_for('bulk_resource.set_required_option_descriptor')) elif form.navigation.data['submit_back']: return redirect(url_for('bulk_resource.set_descriptor_types')) elif form.navigation.data['submit_cancel']: @@ -353,30 +350,36 @@ def review_desc_options(): return redirect(url_for('bulk_resource.upload')) # New option descriptors found in the CSV - new_opt_descs = [desc for desc in csv_storage.csv_descriptors - if desc.descriptor_type == 'option' and not desc.descriptor_id] + new_opt_descs = [ + desc for desc in csv_storage.csv_descriptors + if desc.descriptor_type == 'option' and not desc.descriptor_id + ] # Old option descriptors found in the app old_opt_descs = [] if csv_storage.action == 'update': - old_opt_descs_csv = [desc for desc in csv_storage.csv_descriptors - if desc.descriptor_type == 'option' and desc.descriptor_id] + old_opt_descs_csv = [ + desc for desc in csv_storage.csv_descriptors + if desc.descriptor_type == 'option' and desc.descriptor_id + ] for d in old_opt_descs_csv: - old_d = Descriptor.query.filter_by( - id=d.descriptor_id - ).first() + old_d = Descriptor.query.filter_by(id=d.descriptor_id).first() old_opt_descs.append((d, old_d)) old_opt_descs = dict(old_opt_descs) - return render_template('bulk_resource/review_desc_options.html', - new_opt_descs=new_opt_descs, - old_opt_descs=old_opt_descs, - form=form) + return render_template( + 'bulk_resource/review_desc_options.html', + new_opt_descs=new_opt_descs, + old_opt_descs=old_opt_descs, + form=form) ''' Choose one option descriptor to be the required option descriptor. Can only select from option descriptors in the CSV or the existing required option descriptor if any.''' -@bulk_resource.route('/set-required-option-descriptor', methods=['GET', 'POST']) + + +@bulk_resource.route( + '/set-required-option-descriptor', methods=['GET', 'POST']) @login_required def set_required_option_descriptor(): csv_storage = CsvStorage.most_recent(user=current_user) @@ -394,7 +397,9 @@ def set_required_option_descriptor(): db.session.commit() return redirect(url_for('bulk_resource.upload')) elif form.required_option_descriptor.data == "": - flash('Error: You must select a required option descriptor. Please try again.', 'form-error') + flash( + 'Error: You must select a required option descriptor. Please try again.', + 'form-error') else: # Store the selected required option descriptor RequiredOptionDescriptorConstructor.query.delete() @@ -408,17 +413,17 @@ def set_required_option_descriptor(): if csv_storage.action == 'update': if desc.descriptor_id: descriptor = Descriptor.query.filter_by( - id=desc.descriptor_id - ).first() + id=desc.descriptor_id).first() for v in descriptor.values: values.add(v) req_opt_desc_const = RequiredOptionDescriptorConstructor( - name=desc.name, - values=desc.values - ) + name=desc.name, values=desc.values) db.session.add(req_opt_desc_const) db.session.commit() - return redirect(url_for('bulk_resource.validate_required_option_descriptor')) + return redirect( + url_for( + 'bulk_resource.validate_required_option_descriptor' + )) # If not in CSV, see if it is existing required option descriptor req_opt_desc = RequiredOptionDescriptor.query.all() @@ -426,18 +431,19 @@ def set_required_option_descriptor(): req_opt_desc = req_opt_desc[0] if req_opt_desc.descriptor_id != -1: descriptor = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() if descriptor is not None and descriptor.name == form.required_option_descriptor.data: req_opt_desc_const = RequiredOptionDescriptorConstructor( - name=descriptor.name, - values=descriptor.values - ) + name=descriptor.name, values=descriptor.values) db.session.add(req_opt_desc_const) db.session.commit() - return redirect(url_for('bulk_resource.validate_required_option_descriptor')) + return redirect( + url_for( + 'bulk_resource.validate_required_option_descriptor' + )) # If no descriptor found - flash('Error: No required option descriptor. Please try again.', 'form-error') + flash('Error: No required option descriptor. Please try again.', + 'form-error') descriptors = [] # If there is an existing required option descriptor, then make it @@ -450,8 +456,7 @@ def set_required_option_descriptor(): req_opt_desc = req_opt_desc[0] if req_opt_desc.descriptor_id != -1: descriptor = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() if descriptor is not None and descriptor.name not in remove_descs: req_name = descriptor.name descriptors.append(req_name) @@ -469,15 +474,17 @@ def set_required_option_descriptor(): form.required_option_descriptor.choices = [(d, d) for d in descriptors] return render_template( - 'bulk_resource/get_required_option_descriptor.html', - current=req_name, - form=form - ) + 'bulk_resource/get_required_option_descriptor.html', + current=req_name, + form=form) ''' If there are resources that don't have the selected required option descriptor value set, enforce that they are updated to have the required option descriptor''' -@bulk_resource.route('/validate-required-option-descriptor', methods=['GET', 'POST']) + + +@bulk_resource.route( + '/validate-required-option-descriptor', methods=['GET', 'POST']) @login_required def validate_required_option_descriptor(): csv_storage = CsvStorage.most_recent(user=current_user) @@ -494,7 +501,8 @@ def validate_required_option_descriptor(): csv_resources = set() for row in csv_storage.csv_rows: csv_resources.add(row.data['Name']) - if req_opt_desc not in row.data or row.data[req_opt_desc].strip() == '': + if req_opt_desc not in row.data or row.data[ + req_opt_desc].strip() == '': missing_resources.add(row.data['Name']) # Find all existing resources that lack an @@ -507,8 +515,7 @@ def validate_required_option_descriptor(): curr_req_opt_desc = curr_req_opt_desc[0] if curr_req_opt_desc.descriptor_id != -1: req_descriptor = Descriptor.query.filter_by( - id=curr_req_opt_desc.descriptor_id - ).first() + id=curr_req_opt_desc.descriptor_id).first() if req_descriptor is not None: curr_req = req_descriptor.name @@ -527,7 +534,8 @@ def validate_required_option_descriptor(): # For form submission if request.method == 'POST': if form.navigation.data['submit_back']: - return redirect(url_for('bulk_resource.set_required_option_descriptor')) + return redirect( + url_for('bulk_resource.set_required_option_descriptor')) elif form.navigation.data['submit_cancel']: db.session.delete(csv_storage) db.session.commit() @@ -536,10 +544,13 @@ def validate_required_option_descriptor(): # resource that previously lacked an association with the descriptor. req_opt_desc_const.missing_dict = {} if len(form.resources.data) < len(missing_resources): - flash('Error: You must choose an option for each resource. Please try again.', 'form-error') + flash( + 'Error: You must choose an option for each resource. Please try again.', + 'form-error') else: for num, name in enumerate(missing_resources): - req_opt_desc_const.missing_dict[name] = form.resources.data[num] + req_opt_desc_const.missing_dict[name] = form.resources.data[ + num] db.session.commit() return redirect(url_for('bulk_resource.save_csv')) @@ -554,19 +565,21 @@ def validate_required_option_descriptor(): for num, name in enumerate(missing_resources): form.resources.append_entry() form.resources[num].label = name - form.resources[num].choices = [(v, v) for v in req_opt_desc_const.values] + form.resources[num].choices = [(v, v) + for v in req_opt_desc_const.values] # Remove auto form label form.resources.label = '' return render_template( - 'bulk_resource/review_required_option_descriptor.html', - form=form, - required=req_opt_desc, - ) + 'bulk_resource/review_required_option_descriptor.html', + form=form, + required=req_opt_desc, ) ''' Last step in CSV workflow to update the resource and descriptor data models''' + + @bulk_resource.route('/save-csv', methods=['GET', 'POST']) @login_required def save_csv(): @@ -582,9 +595,12 @@ def save_csv(): if not req_opt_desc_const: return redirect(url_for('bulk_resource.set_descriptor_types')) elif req_opt_desc_const[0].missing_dict: - return redirect(url_for('bulk_resource.validate_required_option_descriptor')) + return redirect( + url_for( + 'bulk_resource.validate_required_option_descriptor')) else: - return redirect(url_for('bulk_resource.set_required_option_descriptor')) + return redirect( + url_for('bulk_resource.set_required_option_descriptor')) elif form.data['submit_cancel']: db.session.delete(csv_storage) db.session.commit() @@ -606,8 +622,7 @@ def save_csv(): if csv_storage.action == 'update' and desc.descriptor_id: if desc.descriptor_type == 'option': existing_descriptor = Descriptor.query.filter_by( - id=desc.descriptor_id - ).first() + id=desc.descriptor_id).first() values = existing_descriptor.values values.extend(desc.values) existing_descriptor.values = list(set(values)) @@ -616,8 +631,7 @@ def save_csv(): descriptor = Descriptor( name=desc.name, values=list(desc.values), - is_searchable=True, - ) + is_searchable=True, ) db.session.add(descriptor) # Remove descriptors not in the CSV @@ -631,15 +645,12 @@ def save_csv(): # Create/update rows and descriptor associations for row in csv_storage.csv_rows: if csv_storage.action == 'update' and row.resource_id: - resource = Resource.query.filter_by( - id=row.resource_id - ).first() + resource = Resource.query.filter_by(id=row.resource_id).first() address = row.data['Address'] if resource.address != address: resource.address = address cached = GeocoderCache.query.filter_by( - address=address - ).first() + address=address).first() if cached is None: db.session.rollback() abort(404) @@ -649,9 +660,7 @@ def save_csv(): else: name = row.data['Name'] address = row.data['Address'] - cached = GeocoderCache.query.filter_by( - address=address - ).first() + cached = GeocoderCache.query.filter_by(address=address).first() if cached is None: db.session.rollback() abort(404) @@ -659,16 +668,13 @@ def save_csv(): name=name, address=address, latitude=cached.latitude, - longitude=cached.longitude - ) + longitude=cached.longitude) db.session.add(resource) # Loop through descriptors on the resource rows for key in row.data: if key and key != 'Name' and key != 'Address': - descriptor = Descriptor.query.filter_by( - name=key - ).first() + descriptor = Descriptor.query.filter_by(name=key).first() values = list(descriptor.values) assocValues = [] if len(descriptor.values) == 0: # text descriptor @@ -678,8 +684,7 @@ def save_csv(): if csv_storage.action == 'update': text_association = TextAssociation.query.filter_by( resource_id=resource.id, - descriptor_id=descriptor.id, - ).first() + descriptor_id=descriptor.id, ).first() if text_association is None: assocValues.append(row.data[key]) # Just update text value if only text changed @@ -700,13 +705,14 @@ def save_csv(): if csv_storage.action == 'update': option_associations = OptionAssociation.query.filter_by( resource_id=resource.id, - descriptor_id=descriptor.id - ) + descriptor_id=descriptor.id) if option_associations is None: assocValues.extend(curr_opts) else: # Check if existing options same as new ones in CSV - old_opts = [opt.option for opt in option_associations] + old_opts = [ + opt.option for opt in option_associations + ] if set(curr_opts) != set(old_opts): # If options different, delete existing and add new ones after for o in option_associations: @@ -732,29 +738,29 @@ def save_csv(): if req_opt_desc_const: req_opt_desc_const = req_opt_desc_const[0] required_option_descriptor = Descriptor.query.filter_by( - name=req_opt_desc_const.name - ).first() + name=req_opt_desc_const.name).first() if required_option_descriptor is None: required_option_descriptor = Descriptor( - name=req_opt_desc_const.name, - values=req_opt_desc_const.values, - is_searchable=True) + name=req_opt_desc_const.name, + values=req_opt_desc_const.values, + is_searchable=True) db.session.add(required_option_descriptor) - req_opt_desc = RequiredOptionDescriptor(descriptor_id=required_option_descriptor.id) + req_opt_desc = RequiredOptionDescriptor( + descriptor_id=required_option_descriptor.id) # Add associations for the resources missing values for the required option descriptor if req_opt_desc_const.missing_dict: for name in req_opt_desc_const.missing_dict.keys(): - resource = Resource.query.filter_by( - name=name - ).first() + resource = Resource.query.filter_by(name=name).first() if resource is not None: for val in req_opt_desc_const.missing_dict[name]: new_association = OptionAssociation( - resource_id=resource.id, - descriptor_id=required_option_descriptor.id, - option=required_option_descriptor.values.index(val), - resource=resource, descriptor=required_option_descriptor) + resource_id=resource.id, + descriptor_id=required_option_descriptor.id, + option=required_option_descriptor.values.index( + val), + resource=resource, + descriptor=required_option_descriptor) db.session.add(new_association) db.session.delete(req_opt_desc_const) db.session.add(req_opt_desc) diff --git a/app/contact/forms.py b/app/contact/forms.py index b6025ea..33f4b06 100644 --- a/app/contact/forms.py +++ b/app/contact/forms.py @@ -6,30 +6,34 @@ class ContactForm(Form): - name = StringField('Name', validators=[ - InputRequired(), - Length(1, 500), - ]) - email = EmailField('Email', validators=[ - InputRequired(), - Length(1, 500), - Email(), - ]) - message = TextField('Message', validators=[ - InputRequired() - ]) + name = StringField( + 'Name', validators=[ + InputRequired(), + Length(1, 500), + ]) + email = EmailField( + 'Email', validators=[ + InputRequired(), + Length(1, 500), + Email(), + ]) + message = TextField('Message', validators=[InputRequired()]) submit = SubmitField('Submit') + class ContactCategoryForm(Form): - name = StringField('Name', validators=[ - InputRequired(), - Length(1, 250), - ]) + name = StringField( + 'Name', validators=[ + InputRequired(), + Length(1, 250), + ]) submit = SubmitField('Add Category') + class EditCategoryNameForm(Form): - name = TextField('Name', validators=[ - InputRequired(), - Length(1, 250), - ]) + name = TextField( + 'Name', validators=[ + InputRequired(), + Length(1, 250), + ]) submit = SubmitField('Update name') diff --git a/app/contact/views.py b/app/contact/views.py index 29cc5c4..1eab46c 100644 --- a/app/contact/views.py +++ b/app/contact/views.py @@ -17,9 +17,11 @@ @contact.route('/', methods=['GET', 'POST']) def index(): editable_html_obj = EditableHTML.get_editable_html('contact') - setattr(ContactForm, - 'category', - SelectField('Category', choices=[(c.name, c.name) for c in ContactCategory.query.all()])) + setattr( + ContactForm, 'category', + SelectField( + 'Category', + choices=[(c.name, c.name) for c in ContactCategory.query.all()])) form = ContactForm() app = create_app(os.getenv('FLASK_CONFIG') or 'default') contact_email = app.config['ADMIN_EMAIL'] @@ -31,23 +33,26 @@ def index(): template='contact/email/contact', name=form.name.data, email=form.email.data, - message=form.message.data - ) + message=form.message.data) return redirect(url_for('main.index')) category_form = ContactCategoryForm() if category_form.validate_on_submit(): - if ContactCategory.query.filter_by(name = category_form.name.data).first() is not None: - flash('Category \"{}\" already exists.'.format(category_form.name.data), 'form-error') + if ContactCategory.query.filter_by( + name=category_form.name.data).first() is not None: + flash('Category \"{}\" already exists.'.format( + category_form.name.data), 'form-error') else: new_category = ContactCategory(name=category_form.name.data) db.session.add(new_category) db.session.commit() categories = ContactCategory.query.all() - return render_template('contact/index.html', - editable_html_obj=editable_html_obj, - form=form, - category_form=category_form, - categories=categories) + return render_template( + 'contact/index.html', + editable_html_obj=editable_html_obj, + form=form, + category_form=category_form, + categories=categories) + @contact.route('/', methods=['GET', 'POST']) @login_required @@ -59,28 +64,27 @@ def edit_category_name(category_id): old_name = category.name form = EditCategoryNameForm() if form.validate_on_submit(): - if ContactCategory.query.filter(ContactCategory.name == form.name.data).first() is not None: - flash('Category \"{}\" already exists.'.format(form.name.data), 'form-error') - return render_template('contact/manage_category.html', - category=category, - form=form) + if ContactCategory.query.filter( + ContactCategory.name == form.name.data).first() is not None: + flash('Category \"{}\" already exists.'.format(form.name.data), + 'form-error') + return render_template( + 'contact/manage_category.html', category=category, form=form) category.name = form.name.data db.session.add(category) try: db.session.commit() flash('Name for category \"{}\" successfully changed to \"{}\".' - .format(old_name, category.name), - 'form-success') + .format(old_name, category.name), 'form-success') except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'form-error') - return render_template('contact/manage_category.html', - category=category, - form=form) + return render_template( + 'contact/manage_category.html', category=category, form=form) form.name.data = category.name - return render_template('contact/manage_category.html', - category=category, - form=form) + return render_template( + 'contact/manage_category.html', category=category, form=form) + @contact.route('//delete_request') @login_required @@ -89,8 +93,8 @@ def delete_category_request(category_id): category = ContactCategory.query.get(category_id) if category is None: abort(404) - return render_template('contact/manage_category.html', - category=category) + return render_template('contact/manage_category.html', category=category) + @contact.route('//delete') @login_required @@ -102,10 +106,11 @@ def delete_category(category_id): db.session.delete(category) try: db.session.commit() - flash('Successfully deleted category \"%s\".' % category.name, 'success') + flash('Successfully deleted category \"%s\".' % category.name, + 'success') except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'form-error') - return render_template('contact/manage_category.html', - category=category) + return render_template( + 'contact/manage_category.html', category=category) return redirect(url_for('contact.index')) diff --git a/app/decorators.py b/app/decorators.py index 90286ac..f1bfb16 100644 --- a/app/decorators.py +++ b/app/decorators.py @@ -8,13 +8,16 @@ def permission_required(permission): """Restrict a view to users with the given permission.""" + def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): if not current_user.can(permission): abort(403) return f(*args, **kwargs) + return decorated_function + return decorator diff --git a/app/descriptor/forms.py b/app/descriptor/forms.py index 40fbf41..1953e60 100644 --- a/app/descriptor/forms.py +++ b/app/descriptor/forms.py @@ -5,10 +5,10 @@ class NewDescriptorForm(Form): - desc_type = SelectField('Descriptor type', - choices=[('Text', 'Text'), ('Option', 'Option')], - validators=[InputRequired()] - ) + desc_type = SelectField( + 'Descriptor type', + choices=[('Text', 'Text'), ('Option', 'Option')], + validators=[InputRequired()]) name = TextField('Name', validators=[InputRequired(), Length(1, 500)]) option_values = FieldList(TextField('Option', [Length(0, 500)])) is_searchable = BooleanField('Searchable') @@ -26,8 +26,8 @@ class EditDescriptorSearchableForm(Form): class EditDescriptorOptionValueForm(Form): - value = TextField('Option Value', - validators=[InputRequired(), Length(1, 500)]) + value = TextField( + 'Option Value', validators=[InputRequired(), Length(1, 500)]) submit = SubmitField('Update option value') diff --git a/app/descriptor/views.py b/app/descriptor/views.py index f65914d..c09530d 100644 --- a/app/descriptor/views.py +++ b/app/descriptor/views.py @@ -21,8 +21,7 @@ def index(): """View all resource descriptors.""" descriptors = Descriptor.query.all() - return render_template('descriptor/index.html', - descriptors=descriptors) + return render_template('descriptor/index.html', descriptors=descriptors) @descriptor.route('/new-descriptor', methods=['GET', 'POST']) @@ -40,8 +39,7 @@ def new_descriptor(): descriptor = Descriptor( name=form.name.data, values=values, - is_searchable=form.is_searchable.data - ) + is_searchable=form.is_searchable.data) if Descriptor.query.filter(Descriptor.name == form.name.data).first() \ is not None: flash('Descriptor {} already exists.'.format(descriptor.name), @@ -51,8 +49,7 @@ def new_descriptor(): try: db.session.commit() flash('Descriptor {} successfully created' - .format(descriptor.name), - 'form-success') + .format(descriptor.name), 'form-success') return redirect(url_for('descriptor.new_descriptor')) except IntegrityError: db.session.rollback() @@ -69,8 +66,10 @@ def descriptor_info(desc_id): if descriptor is None: abort(404) is_option = len(descriptor.values) != 0 - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option) @descriptor.route('//name', methods=['GET', 'POST']) @@ -90,24 +89,31 @@ def edit_name(desc_id): flash('No change was made', 'form-error') else: flash('Descriptor {} already exists.'.format(form.name.data), - 'form-error') - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, form=form, - is_option=is_option) + 'form-error') + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + form=form, + is_option=is_option) descriptor.name = form.name.data db.session.add(descriptor) try: db.session.commit() - flash('Name for descriptor {} successfully changed to {}.'.format(old_name, descriptor.name), - 'form-success') + flash('Name for descriptor {} successfully changed to {}.'.format( + old_name, descriptor.name), 'form-success') except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'form-error') - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option) form.name.data = descriptor.name - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, form=form, is_option=is_option) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + form=form, + is_option=is_option) @descriptor.route('//searchable', methods=['GET', 'POST']) @@ -126,16 +132,20 @@ def edit_searchable(desc_id): try: db.session.commit() flash('Searchability successfully changed from {} to {}.' - .format(old_value, descriptor.is_searchable), - 'form-success') - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option) + .format(old_value, descriptor.is_searchable), 'form-success') + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option) except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'form-error') form.is_searchable.data = old_value - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, form=form, is_option=is_option) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + form=form, + is_option=is_option) @descriptor.route('//option-values', methods=['GET', 'POST']) @@ -154,9 +164,12 @@ def change_option_values_index(desc_id): if form.value.data in values: flash('Value {} already exists'.format(form.value.data), 'form-error') - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option, - desc_id=desc_id, form=form) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option, + desc_id=desc_id, + form=form) values.append(form.value.data) descriptor.values = values @@ -169,13 +182,17 @@ def change_option_values_index(desc_id): except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'form-error') - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option, - desc_id=desc_id, form=form) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option, + desc_id=desc_id, + form=form) -@descriptor.route('//option-values/edit/', - methods=['GET', 'POST']) +@descriptor.route( + '//option-values/edit/', + methods=['GET', 'POST']) @login_required def edit_option_value(desc_id, option_index): """Edit a descriptor's selected option value.""" @@ -196,22 +213,25 @@ def edit_option_value(desc_id, option_index): db.session.commit() flash('Value {} for descriptor {} successfully changed to {}.' .format(old_value, descriptor.name, - descriptor.values[option_index]), - 'form-success') - return redirect(url_for('descriptor.descriptor_info', - desc_id=desc_id)) + descriptor.values[option_index]), 'form-success') + return redirect( + url_for('descriptor.descriptor_info', desc_id=desc_id)) except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'form-error') else: form.value.data = descriptor.values[option_index] - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option, - desc_id=desc_id, form=form) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option, + desc_id=desc_id, + form=form) -@descriptor.route('//option-values/remove/', - methods=['GET', 'POST']) +@descriptor.route( + '//option-values/remove/', + methods=['GET', 'POST']) @login_required def remove_option_value(desc_id, option_index): """Remove a descriptor's selected option value.""" @@ -223,13 +243,12 @@ def remove_option_value(desc_id, option_index): if len(descriptor.values) == 1: flash('Descriptor {} only has one value.'.format(descriptor.name), 'form-error') - return redirect(url_for('descriptor.change_option_values_index', - desc_id=desc_id)) + return redirect( + url_for('descriptor.change_option_values_index', desc_id=desc_id)) - option_assocs = OptionAssociation.query.filter(db.and_( - OptionAssociation.descriptor_id == desc_id, - OptionAssociation.option == option_index - )).all() + option_assocs = OptionAssociation.query.filter( + db.and_(OptionAssociation.descriptor_id == desc_id, + OptionAssociation.option == option_index)).all() choice_names, choices = generate_option_choices(descriptor, option_index) @@ -245,14 +264,18 @@ def remove_option_value(desc_id, option_index): db.session.delete(oa) if remove_value_from_db(descriptor, choice_names, old_value): - return redirect(url_for('descriptor.descriptor_info', - desc_id=desc_id)) + return redirect( + url_for('descriptor.descriptor_info', desc_id=desc_id)) else: flash('Database error occurred. Please try again', 'form-error') - return render_template('descriptor/confirm_resources.html', - option_assocs=option_assocs, desc_id=desc_id, - desc=descriptor, option_index=option_index, - form=form) + return render_template( + 'descriptor/confirm_resources.html', + option_assocs=option_assocs, + desc_id=desc_id, + desc=descriptor, + option_index=option_index, + form=form) + def generate_option_choices(descriptor, removed_index): """Helper function to generate the new options + indices""" @@ -271,8 +294,7 @@ def remove_value_from_db(descriptor, values, old_value): try: db.session.commit() flash('Value {} for descriptor {} successfully removed.' - .format(old_value, descriptor.name), - 'form-success') + .format(old_value, descriptor.name), 'form-success') return True except IntegrityError: db.session.rollback() @@ -293,9 +315,11 @@ def delete_descriptor_request(desc_id): if req_opt_desc: req_opt_desc = req_opt_desc[0] is_required = req_opt_desc.descriptor_id == descriptor.id - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option, - is_required=is_required) + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option, + is_required=is_required) @descriptor.route('//delete') @@ -313,13 +337,17 @@ def delete_descriptor(desc_id): flash('Successfully deleted descriptor %s.' % descriptor.name, 'success') except IntegrityError: - db.session.rollback() - flash('Database error occurred. Please try again.', 'form-error') - return render_template('descriptor/manage_descriptor.html', - desc=descriptor, is_option=is_option) + db.session.rollback() + flash('Database error occurred. Please try again.', 'form-error') + return render_template( + 'descriptor/manage_descriptor.html', + desc=descriptor, + is_option=is_option) return redirect(url_for('descriptor.index')) -@descriptor.route('/change-required-option-descriptor', methods=['GET', 'POST']) + +@descriptor.route( + '/change-required-option-descriptor', methods=['GET', 'POST']) @login_required def change_required_option_descriptor(): descriptors = Descriptor.query.all() @@ -331,40 +359,37 @@ def change_required_option_descriptor(): current_name = "" if req_opt_desc.descriptor_id != -1: descriptor = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() if descriptor is not None: current_name = descriptor.name if current_name != "": - setattr( - ChangeRequiredOptionDescriptorForm, - 'descriptor', - SelectField( - 'Option Descriptor', - choices=choices, - validators=[InputRequired()], - default=current_name) - ) + setattr(ChangeRequiredOptionDescriptorForm, 'descriptor', + SelectField( + 'Option Descriptor', + choices=choices, + validators=[InputRequired()], + default=current_name)) form = ChangeRequiredOptionDescriptorForm() if form.validate_on_submit(): RequiredOptionDescriptorConstructor.query.delete() db.session.commit() desc = Descriptor.query.filter_by( - name=form.descriptor.data - ).first() + name=form.descriptor.data).first() if desc is not None: - req_opt_desc_const = RequiredOptionDescriptorConstructor(name=desc.name, values=desc.values) + req_opt_desc_const = RequiredOptionDescriptorConstructor( + name=desc.name, values=desc.values) db.session.add(req_opt_desc_const) db.session.commit() - return redirect(url_for('descriptor.review_required_option_descriptor')) + return redirect( + url_for('descriptor.review_required_option_descriptor')) else: form = None return render_template( - 'descriptor/change_required_option_descriptor.html', - form=form - ) + 'descriptor/change_required_option_descriptor.html', form=form) -@descriptor.route('/review-required-option-descriptor', methods=['GET', 'POST']) + +@descriptor.route( + '/review-required-option-descriptor', methods=['GET', 'POST']) @login_required def review_required_option_descriptor(): req_opt_desc_const = RequiredOptionDescriptorConstructor.query.all()[0] @@ -372,37 +397,35 @@ def review_required_option_descriptor(): missing_resources = [] resources = Resource.query.all() descriptor = Descriptor.query.filter_by( - name=req_opt_desc_const.name - ).first() + name=req_opt_desc_const.name).first() for r in resources: if descriptor is None: missing_resources.append(r.name) else: option_association = OptionAssociation.query.filter_by( - resource_id = r.id, - descriptor_id=descriptor.id - ).first() + resource_id=r.id, descriptor_id=descriptor.id).first() if option_association is None: missing_resources.append(r.name) if request.method == 'POST': if len(form.resources.data) < len(missing_resources): - flash('Error: You must choose an option for each resource. Please try again.', 'form-error') + flash( + 'Error: You must choose an option for each resource. Please try again.', + 'form-error') else: for j, r_name in enumerate(missing_resources): - resource = Resource.query.filter_by( - name=r_name - ).first() + resource = Resource.query.filter_by(name=r_name).first() if resource is not None: for val in form.resources.data[j]: new_association = OptionAssociation( - resource_id=resource.id, - descriptor_id=descriptor.id, - option=descriptor.values.index(val), - resource=resource, - descriptor=descriptor) + resource_id=resource.id, + descriptor_id=descriptor.id, + option=descriptor.values.index(val), + resource=resource, + descriptor=descriptor) db.session.add(new_association) RequiredOptionDescriptor.query.delete() - req_opt_desc = RequiredOptionDescriptor(descriptor_id=descriptor.id) + req_opt_desc = RequiredOptionDescriptor( + descriptor_id=descriptor.id) db.session.add(req_opt_desc) db.session.commit() return redirect(url_for('descriptor.index')) @@ -410,4 +433,5 @@ def review_required_option_descriptor(): form.resources.append_entry() form.resources[j].label = r_name form.resources[j].choices = [(v, v) for v in req_opt_desc_const.values] - return render_template('descriptor/review_required_option_descriptor.html', form=form) + return render_template( + 'descriptor/review_required_option_descriptor.html', form=form) diff --git a/app/email.py b/app/email.py index 80f68ee..aa1e7ff 100644 --- a/app/email.py +++ b/app/email.py @@ -11,9 +11,10 @@ def send_email(recipient, subject, template, **kwargs): app = create_app(os.getenv('FLASK_CONFIG') or 'default') with app.app_context(): - msg = Message(app.config['EMAIL_SUBJECT_PREFIX'] + ' ' + subject, - sender=app.config['EMAIL_SENDER'], - recipients=[recipient]) + msg = Message( + app.config['EMAIL_SUBJECT_PREFIX'] + ' ' + subject, + sender=app.config['EMAIL_SENDER'], + recipients=[recipient]) msg.body = render_template(template + '.txt', **kwargs) msg.html = render_template(template + '.html', **kwargs) mail.send(msg) diff --git a/app/main/views.py b/app/main/views.py index 08d67bd..d7fd4c5 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -25,12 +25,13 @@ def index(): if req_opt_desc: req_opt_desc = req_opt_desc[0] req_opt_desc = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() if req_opt_desc is not None: req_opt_id = req_opt_desc.id options = Descriptor.query.all() - options = [o for o in options if len(o.text_resources) == 0 and o.id != req_opt_id] + options = [ + o for o in options if len(o.text_resources) == 0 and o.id != req_opt_id + ] options_dict = {} for o in options: options_dict[o.name] = o.values @@ -38,7 +39,12 @@ def index(): if req_opt_desc: for val in req_opt_desc.values: req_options[val] = False - return render_template('main/index.html', options=options_dict, req_options=req_options, req_desc=req_opt_desc) + return render_template( + 'main/index.html', + options=options_dict, + req_options=req_options, + req_desc=req_opt_desc) + @main.route('/get-resources') def get_resources(): @@ -46,6 +52,7 @@ def get_resources(): resources_as_dicts = Resource.get_resources_as_dicts(resources) return json.dumps(resources_as_dicts) + @main.route('/search-resources') def search_resources(): name = request.args.get('name') @@ -55,13 +62,13 @@ def search_resources(): if req_options is None: req_options = [] # case insensitive search - resource_pool = Resource.query.filter(Resource.name.ilike('%{}%'.format(name))).all() + resource_pool = Resource.query.filter( + Resource.name.ilike('%{}%'.format(name))).all() req_opt_desc = RequiredOptionDescriptor.query.all() if req_opt_desc: req_opt_desc = req_opt_desc[0] req_opt_desc = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() resources = [] if req_opt_desc and len(req_options) > 0: int_req_options = [] @@ -69,9 +76,7 @@ def search_resources(): int_req_options.append(req_opt_desc.values.index(str(o))) for resource in resource_pool: associations = OptionAssociation.query.filter_by( - resource_id=resource.id, - descriptor_id=req_opt_desc.id - ) + resource_id=resource.id, descriptor_id=req_opt_desc.id) for a in associations: if a.option in int_req_options: resources.append(resource) @@ -100,8 +105,7 @@ def search_resources(): number_of_options_found = 0 for opt in option_map.keys(): opt_descriptors = OptionAssociation.query.filter_by( - resource_id=resource.id - ) + resource_id=resource.id) for desc in opt_descriptors: if desc.descriptor.name == opt: if desc.descriptor.values[desc.option] in option_map[opt]: @@ -112,6 +116,7 @@ def search_resources(): resources_as_dicts = Resource.get_resources_as_dicts(resources) return json.dumps(resources_as_dicts) + @main.route('/get-associations/') def get_associations(resource_id): resource = Resource.query.get(resource_id) @@ -133,36 +138,42 @@ def get_associations(resource_id): associations[od.descriptor.name] = list(values) return json.dumps(associations) + @main.route('/about') def about(): editable_html_obj = EditableHTML.get_editable_html('about') - return render_template('main/about.html', - editable_html_obj=editable_html_obj) + return render_template( + 'main/about.html', editable_html_obj=editable_html_obj) + @main.route('/health') def health(): editable_html_obj = EditableHTML.get_editable_html('health') - return render_template('main/health.html', - editable_html_obj=editable_html_obj) + return render_template( + 'main/health.html', editable_html_obj=editable_html_obj) + @main.route('/rights') def rights(): editable_html_obj = EditableHTML.get_editable_html('rights') - return render_template('main/rights.html', - editable_html_obj=editable_html_obj) + return render_template( + 'main/rights.html', editable_html_obj=editable_html_obj) + @main.route('/hotlines') def hotlines(): - editable_html_obj = EditableHTML.get_editable_html('hotlines') - return render_template('main/hotlines.html', - editable_html_obj=editable_html_obj) + editable_html_obj = EditableHTML.get_editable_html('hotlines') + return render_template( + 'main/hotlines.html', editable_html_obj=editable_html_obj) + @main.route('/overview') @login_required def overview(): - editable_html_obj = EditableHTML.get_editable_html('overview') - return render_template('main/overview.html', - editable_html_obj=editable_html_obj) + editable_html_obj = EditableHTML.get_editable_html('overview') + return render_template( + 'main/overview.html', editable_html_obj=editable_html_obj) + @main.route('/update-editor-contents', methods=['POST']) @login_required @@ -179,6 +190,7 @@ def update_editor_contents(): db.session.commit() return 'OK', 200 + @csrf.exempt @main.route('/send-sms', methods=['POST']) def send_sms(): @@ -187,42 +199,44 @@ def send_sms(): client = TwilioLookupsClient(account=sid, token=auth) send_client = TwilioRestClient(account=sid, token=auth) if request is not None: - phone_num= request.json['number'] + phone_num = request.json['number'] resourceID = request.json['id'] curr_res = Resource.query.get(resourceID) name = "Name: " + curr_res.name address = "Address: " + curr_res.address - message = name +"\n" + address + message = name + "\n" + address try: - number = client.phone_numbers.get(phone_num, include_carrier_info=False) + number = client.phone_numbers.get( + phone_num, include_carrier_info=False) num = number.phone_number send_client.messages.create( - to=num, - from_="+17657692023", - body=message) + to=num, from_="+17657692023", body=message) return jsonify(status='success') except: return jsonify(status='error') + @csrf.exempt -@main.route('/rating-post', methods =['POST']) +@main.route('/rating-post', methods=['POST']) def post_rating(): if request is not None: - time = datetime.now() - star_rating = request.json['rating'] - comment = request.json['review'] - resourceID = request.json['id'] - if comment and star_rating: - rating = Rating(submission_time=time, - rating=star_rating, - review=comment, - resource_id=resourceID) - db.session.add(rating) - db.session.commit() - elif star_rating: - rating = Rating(submission_time=time, - rating=star_rating, - resource_id=resourceID) - db.session.add(rating) - db.session.commit() + time = datetime.now() + star_rating = request.json['rating'] + comment = request.json['review'] + resourceID = request.json['id'] + if comment and star_rating: + rating = Rating( + submission_time=time, + rating=star_rating, + review=comment, + resource_id=resourceID) + db.session.add(rating) + db.session.commit() + elif star_rating: + rating = Rating( + submission_time=time, + rating=star_rating, + resource_id=resourceID) + db.session.add(rating) + db.session.commit() return jsonify(status='success') diff --git a/app/models/__init__.py b/app/models/__init__.py index da2b72e..4529ce6 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -5,10 +5,10 @@ from bulk import * # flake8: noqa from editable import * # flake8: noqa -from rating import * # flake8: noqa -from resource import * # flake8: noqa -from suggestion import * # flake8: noqa +from rating import * # flake8: noqa +from resource import * # flake8: noqa +from suggestion import * # flake8: noqa from user import * # flake8: noqa -from contact_category import * # flake8: noqa -from csv import * # flake8: noqa -from geocoder_cache import * # flake8: noqa +from contact_category import * # flake8: noqa +from csv import * # flake8: noqa +from geocoder_cache import * # flake8: noqa diff --git a/app/models/bulk.py b/app/models/bulk.py index b529fdc..650c96f 100644 --- a/app/models/bulk.py +++ b/app/models/bulk.py @@ -16,11 +16,13 @@ class CsvContainer(db.Model): id = db.Column(db.Integer, primary_key=True) date_uploaded = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) - csv_rows = db.relationship('CsvBodyRow', backref='csv_container', - uselist=True, cascade='delete') - csv_header_row = db.relationship('CsvHeaderRow', - backref='csv_header_row_container', - uselist=False, cascade='delete') + csv_rows = db.relationship( + 'CsvBodyRow', backref='csv_container', uselist=True, cascade='delete') + csv_header_row = db.relationship( + 'CsvHeaderRow', + backref='csv_header_row_container', + uselist=False, + cascade='delete') name_column_index = db.Column(db.Integer) # Required column: 'Name' address_column_index = db.Column(db.Integer) # Required column: 'Address' @@ -56,8 +58,7 @@ def __repr__(self): @staticmethod def most_recent(user): return CsvContainer.query.filter_by(user=user).order_by( - desc(CsvContainer.date_uploaded) - ).limit(1).first() + desc(CsvContainer.date_uploaded)).limit(1).first() class CsvHeaderRow(db.Model): @@ -69,9 +70,11 @@ class CsvHeaderRow(db.Model): id = db.Column(db.Integer, primary_key=True) csv_container_id = db.Column(db.Integer, db.ForeignKey('csv_containers.id')) - csv_header_cells = db.relationship('CsvHeaderCell', - backref='csv_header_row', - uselist=True, cascade='delete') + csv_header_cells = db.relationship( + 'CsvHeaderCell', + backref='csv_header_row', + uselist=True, + cascade='delete') class CsvBodyRow(db.Model): @@ -83,8 +86,8 @@ class CsvBodyRow(db.Model): id = db.Column(db.Integer, primary_key=True) csv_container_id = db.Column(db.Integer, db.ForeignKey('csv_containers.id')) - csv_body_cells = db.relationship('CsvBodyCell', backref='csv_body_row', - uselist=True, cascade='delete') + csv_body_cells = db.relationship( + 'CsvBodyCell', backref='csv_body_row', uselist=True, cascade='delete') class CsvHeaderCell(db.Model): diff --git a/app/models/csv.py b/app/models/csv.py index 87c4fbc..8d8104b 100644 --- a/app/models/csv.py +++ b/app/models/csv.py @@ -9,18 +9,28 @@ class CsvStorage(db.Model): id = db.Column(db.Integer, primary_key=True) date_uploaded = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) - action = db.Column(db.String, default='reset') # or 'update' - csv_rows = db.relationship('CsvRow', backref='csv_storage', - uselist=True, cascade='delete, delete-orphan') - csv_descriptors = db.relationship('CsvDescriptor', backref='csv_storage', - uselist=True, cascade='delete, delete-orphan') - csv_descriptors_remove = db.relationship('CsvDescriptorRemove', backref='csv_storage', - uselist=True, cascade='delete, delete-orphan') - + action = db.Column(db.String, default='reset') # or 'update' + csv_rows = db.relationship( + 'CsvRow', + backref='csv_storage', + uselist=True, + cascade='delete, delete-orphan') + csv_descriptors = db.relationship( + 'CsvDescriptor', + backref='csv_storage', + uselist=True, + cascade='delete, delete-orphan') + csv_descriptors_remove = db.relationship( + 'CsvDescriptorRemove', + backref='csv_storage', + uselist=True, + cascade='delete, delete-orphan') """ Find option values of option descriptors in the CSV """ + def set_desc_values(self): all_descs = self.csv_descriptors - opt_descs = dict([(d.name, d) for d in all_descs if d.descriptor_type == 'option']) + opt_descs = dict( + [(d.name, d) for d in all_descs if d.descriptor_type == 'option']) for row in self.csv_rows: for key in row.data: if key and key != 'Name' and key != 'Address' and key in opt_descs: @@ -41,8 +51,7 @@ def set_desc_values(self): @staticmethod def most_recent(user): return CsvStorage.query.filter_by(user=user).order_by( - desc(CsvStorage.date_uploaded) - ).limit(1).first() + desc(CsvStorage.date_uploaded)).limit(1).first() class CsvRow(db.Model): @@ -50,11 +59,12 @@ class CsvRow(db.Model): - data field is a dictionary of header name to row value - can be linked to an existing resource in the app for updates """ - __tablename__= 'csv_rows' + __tablename__ = 'csv_rows' id = db.Column(db.Integer, primary_key=True) - csv_storage_id = db.Column(db.Integer, db.ForeignKey('csv_storages.id', ondelete='CASCADE')) - data = db.Column(db.PickleType) # json - resource_id = db.Column(db.Integer) # no foreign key because could be null + csv_storage_id = db.Column( + db.Integer, db.ForeignKey('csv_storages.id', ondelete='CASCADE')) + data = db.Column(db.PickleType) # json + resource_id = db.Column(db.Integer) # no foreign key because could be null class CsvDescriptor(db.Model): @@ -64,13 +74,15 @@ class CsvDescriptor(db.Model): an existing descriptor in the app, the existing values won't show up here unless also present in the CSV """ - __tablename__= 'csv_descriptors' + __tablename__ = 'csv_descriptors' id = db.Column(db.Integer, primary_key=True) - csv_storage_id = db.Column(db.Integer, db.ForeignKey('csv_storages.id', ondelete='CASCADE')) + csv_storage_id = db.Column( + db.Integer, db.ForeignKey('csv_storages.id', ondelete='CASCADE')) name = db.Column(db.String(500)) - descriptor_type = db.Column(db.String, default='text') # or 'option' - values = db.Column(db.PickleType) # list of string options from CSV ONLY - descriptor_id = db.Column(db.Integer) # no foreign key because could be null + descriptor_type = db.Column(db.String, default='text') # or 'option' + values = db.Column(db.PickleType) # list of string options from CSV ONLY + descriptor_id = db.Column( + db.Integer) # no foreign key because could be null def value_string(self): if not self.values: @@ -86,10 +98,12 @@ class CsvDescriptorRemove(db.Model): - In updates, if a descriptor is in the app but not in the new CSV then we assume deletion of this descriptor """ - __tablename__= 'csv_descriptors_remove' + __tablename__ = 'csv_descriptors_remove' id = db.Column(db.Integer, primary_key=True) - csv_storage_id = db.Column(db.Integer, db.ForeignKey('csv_storages.id', ondelete='CASCADE')) - descriptor_id = db.Column(db.Integer, db.ForeignKey('descriptors.id', ondelete='CASCADE')) + csv_storage_id = db.Column( + db.Integer, db.ForeignKey('csv_storages.id', ondelete='CASCADE')) + descriptor_id = db.Column( + db.Integer, db.ForeignKey('descriptors.id', ondelete='CASCADE')) name = db.Column(db.String(500)) diff --git a/app/models/editable.py b/app/models/editable.py index fe1ccbc..65cccfa 100644 --- a/app/models/editable.py +++ b/app/models/editable.py @@ -10,8 +10,7 @@ class EditableHTML(db.Model): @staticmethod def get_editable_html(editor_name): editable_html_obj = EditableHTML.query.filter_by( - editor_name=editor_name - ).first() + editor_name=editor_name).first() if editable_html_obj is None: editable_html_obj = EditableHTML(editor_name=editor_name, value='') diff --git a/app/models/rating.py b/app/models/rating.py index 3fbb779..c7cf2e1 100644 --- a/app/models/rating.py +++ b/app/models/rating.py @@ -4,13 +4,14 @@ class Rating(db.Model): - """ Star rating and review """ - __tablename__ = 'ratings' - id = db.Column(db.Integer, primary_key=True) - resource_id = db.Column(db.Integer, db.ForeignKey('resources.id', ondelete='CASCADE')) - rating = db.Column(db.Integer) - review = db.Column(db.Text) - submission_time = db.Column(db.DateTime) + """ Star rating and review """ + __tablename__ = 'ratings' + id = db.Column(db.Integer, primary_key=True) + resource_id = db.Column(db.Integer, + db.ForeignKey('resources.id', ondelete='CASCADE')) + rating = db.Column(db.Integer) + review = db.Column(db.Text) + submission_time = db.Column(db.DateTime) - def __repr__(self): - return '%s: %s' % (self.id, self.resource_id) + def __repr__(self): + return '%s: %s' % (self.id, self.resource_id) diff --git a/app/models/resource.py b/app/models/resource.py index 276232e..b28cc67 100644 --- a/app/models/resource.py +++ b/app/models/resource.py @@ -10,13 +10,14 @@ class OptionAssociation(db.Model): """ __tablename__ = 'option_associations' id = db.Column(db.Integer, primary_key=True) - resource_id = db.Column(db.Integer, db.ForeignKey('resources.id', ondelete='CASCADE')) - descriptor_id = db.Column(db.Integer, db.ForeignKey('descriptors.id', ondelete='CASCADE')) + resource_id = db.Column(db.Integer, + db.ForeignKey('resources.id', ondelete='CASCADE')) + descriptor_id = db.Column( + db.Integer, db.ForeignKey('descriptors.id', ondelete='CASCADE')) option = db.Column(db.Integer) - resource = db.relationship('Resource', - back_populates='option_descriptors') - descriptor = db.relationship('Descriptor', - back_populates='option_resources') + resource = db.relationship('Resource', back_populates='option_descriptors') + descriptor = db.relationship( + 'Descriptor', back_populates='option_resources') def __repr__(self): return '%s: %s' % (self.descriptor.name, @@ -31,8 +32,10 @@ class TextAssociation(db.Model): """ __tablename__ = 'text_associations' id = db.Column(db.Integer, primary_key=True) - resource_id = db.Column(db.Integer, db.ForeignKey('resources.id', ondelete='CASCADE')) - descriptor_id = db.Column(db.Integer, db.ForeignKey('descriptors.id', ondelete='CASCADE')) + resource_id = db.Column(db.Integer, + db.ForeignKey('resources.id', ondelete='CASCADE')) + descriptor_id = db.Column( + db.Integer, db.ForeignKey('descriptors.id', ondelete='CASCADE')) text = db.Column(db.Text) resource = db.relationship('Resource', back_populates='text_descriptors') descriptor = db.relationship('Descriptor', back_populates='text_resources') @@ -49,18 +52,17 @@ class Descriptor(db.Model): __tablename__ = 'descriptors' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(500), index=True) - values = db.Column(db.PickleType) # should only have value for option descriptor + values = db.Column( + db.PickleType) # should only have value for option descriptor is_searchable = db.Column(db.Boolean) text_resources = db.relationship( 'TextAssociation', back_populates='descriptor', - cascade='all, delete-orphan' - ) + cascade='all, delete-orphan') option_resources = db.relationship( 'OptionAssociation', back_populates='descriptor', - cascade='all, delete-orphan' - ) + cascade='all, delete-orphan') def __repr__(self): return '' % self.name @@ -80,7 +82,8 @@ class RequiredOptionDescriptor(db.Model): """ __tablename__ = 'required_option_descriptor' id = db.Column(db.Integer, primary_key=True) - descriptor_id = db.Column(db.Integer); # -1 if none + descriptor_id = db.Column(db.Integer) + # -1 if none @staticmethod def init_required_option_descriptor(): @@ -102,25 +105,21 @@ class Resource(db.Model): text_descriptors = db.relationship( 'TextAssociation', back_populates='resource', - cascade='all, delete-orphan' - ) + cascade='all, delete-orphan') option_descriptors = db.relationship( 'OptionAssociation', back_populates='resource', - cascade='all, delete-orphan' - ) + cascade='all, delete-orphan') suggestions = db.relationship( 'Suggestion', backref='resource', uselist=True, - cascade='all, delete-orphan' - ) + cascade='all, delete-orphan') ratings = db.relationship( 'Rating', backref='resource', uselist=True, - cascade='all, delete-orphan', - ) + cascade='all, delete-orphan', ) def __repr__(self): return '' % self.name @@ -140,23 +139,18 @@ def generate_fake(count=20, center_lat=39.951021, center_long=-75.197243): options = [] for i in range(num_options): - options.append(Descriptor( - name=fake.word(), - values=['True', 'False'], - is_searchable=fake.boolean() - )) + options.append( + Descriptor( + name=fake.word(), + values=['True', 'False'], + is_searchable=fake.boolean())) for i in range(count): # Generates random coordinates around Philadelphia. - latitude = str(fake.geo_coordinate( - center=center_lat, - radius=0.01 - )) - longitude = str(fake.geo_coordinate( - center=center_long, - radius=0.01 - )) + latitude = str(fake.geo_coordinate(center=center_lat, radius=0.01)) + longitude = str( + fake.geo_coordinate(center=center_long, radius=0.01)) location = geolocater.reverse(latitude + ', ' + longitude) @@ -166,8 +160,7 @@ def generate_fake(count=20, center_lat=39.951021, center_long=-75.197243): name=fake.name(), address=location.address, latitude=latitude, - longitude=longitude - ) + longitude=longitude) oa = OptionAssociation(option=randint(0, 1)) oa.descriptor = options[randint(0, num_options - 1)] @@ -175,10 +168,7 @@ def generate_fake(count=20, center_lat=39.951021, center_long=-75.197243): ta = TextAssociation(text=fake.sentence(nb_words=10)) ta.descriptor = Descriptor( - name=fake.word(), - values=[], - is_searchable=fake.boolean() - ) + name=fake.word(), values=[], is_searchable=fake.boolean()) resource.text_descriptors.append(ta) db.session.add(resource) @@ -194,8 +184,7 @@ def get_resources_as_dicts(resources): if req_opt_desc: req_opt_desc = req_opt_desc[0] req_opt_desc = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() resources_as_dicts = [] for resource in resources: @@ -206,8 +195,7 @@ def get_resources_as_dicts(resources): if req_opt_desc: associations = OptionAssociation.query.filter_by( resource_id=resource.id, - descriptor_id=req_opt_desc.id - ).all() + descriptor_id=req_opt_desc.id).all() req = [a.descriptor.values[a.option] for a in associations] res['requiredOpts'] = req diff --git a/app/models/suggestion.py b/app/models/suggestion.py index e27d72a..2328271 100644 --- a/app/models/suggestion.py +++ b/app/models/suggestion.py @@ -11,7 +11,8 @@ class Suggestion(db.Model): """ __tablename__ = 'suggestions' id = db.Column(db.Integer, primary_key=True) - resource_id = db.Column(db.Integer, db.ForeignKey('resources.id', ondelete='CASCADE')) + resource_id = db.Column(db.Integer, + db.ForeignKey('resources.id', ondelete='CASCADE')) suggestion_text = db.Column(db.Text) # 0 stands for read, 1 stands for unread read = db.Column(db.Boolean, default=False) @@ -43,10 +44,15 @@ def generate_fake_inserts(count=20): s_contact_number = "123-456-7890" s_resource_name = fake.word() s_resource_address = fake.word() - s_insert = Suggestion(suggestion_text=s_text, - read=s_read, submission_time=s_timestamp, contact_name=s_contact_name, - contact_email=s_contact_email, contact_phone_number=s_contact_number, - resource_name=s_resource_name, resource_address=s_resource_address) + s_insert = Suggestion( + suggestion_text=s_text, + read=s_read, + submission_time=s_timestamp, + contact_name=s_contact_name, + contact_email=s_contact_email, + contact_phone_number=s_contact_number, + resource_name=s_resource_name, + resource_address=s_resource_address) db.session.add(s_insert) try: db.session.commit() @@ -79,9 +85,14 @@ def generate_fake_edits(count=20): s_contact_name = fake.word() s_contact_email = fake.word() + "@" + fake.word() + ".com" s_contact_number = "123-456-7890" - s_edit = Suggestion(resource_id=r_added.id, suggestion_text=s_text, - read=s_read, submission_time=s_timestamp, contact_name=s_contact_name, - contact_email=s_contact_email, contact_phone_number=s_contact_number) + s_edit = Suggestion( + resource_id=r_added.id, + suggestion_text=s_text, + read=s_read, + submission_time=s_timestamp, + contact_name=s_contact_name, + contact_email=s_contact_email, + contact_phone_number=s_contact_number) db.session.add(s_edit) try: db.session.commit() diff --git a/app/models/user.py b/app/models/user.py index 2a0ecbf..a3ca419 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -24,7 +24,9 @@ class Role(db.Model): def insert_roles(): roles = { 'Administrator': ( - Permission.ADMINISTER, 'admin', False # grants all permissions + Permission.ADMINISTER, + 'admin', + False # grants all permissions ) } for r in roles: @@ -50,12 +52,16 @@ class User(UserMixin, db.Model): email = db.Column(db.String(500), unique=True, index=True) password_hash = db.Column(db.String(128)) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) - csv_containers = db.relationship('CsvContainer', backref='user', - uselist=True, - order_by='CsvContainer.date_uploaded') - csv_storages = db.relationship('CsvStorage', backref='user', - uselist=True, - order_by='CsvStorage.date_uploaded') + csv_containers = db.relationship( + 'CsvContainer', + backref='user', + uselist=True, + order_by='CsvContainer.date_uploaded') + csv_storages = db.relationship( + 'CsvStorage', + backref='user', + uselist=True, + order_by='CsvStorage.date_uploaded') def __init__(self, **kwargs): super(User, self).__init__(**kwargs) @@ -171,8 +177,7 @@ def generate_fake(count=100, **kwargs): password=fake.password(), confirmed=True, role=choice(roles), - **kwargs - ) + **kwargs) db.session.add(u) try: db.session.commit() @@ -191,8 +196,7 @@ def create_confirmed_admin(first_name, last_name, email, password): password=password, confirmed=True, role=Role.query.filter_by( - permissions=Permission.ADMINISTER).first() - ) + permissions=Permission.ADMINISTER).first()) db.session.add(u) try: db.session.commit() diff --git a/app/single_resource/forms.py b/app/single_resource/forms.py index 10541e6..60c50c9 100644 --- a/app/single_resource/forms.py +++ b/app/single_resource/forms.py @@ -4,18 +4,9 @@ class SingleResourceForm(Form): - name = StringField('Name', validators=[ - InputRequired(), - Length(1, 500) - ]) - address = StringField('Address', validators=[ - InputRequired(), - Length(1, 500) - ]) - latitude = FloatField('Latitude', validators=[ - InputRequired() - ]) - longitude = FloatField('Longitude', validators=[ - InputRequired() - ]) + name = StringField('Name', validators=[InputRequired(), Length(1, 500)]) + address = StringField( + 'Address', validators=[InputRequired(), Length(1, 500)]) + latitude = FloatField('Latitude', validators=[InputRequired()]) + longitude = FloatField('Longitude', validators=[InputRequired()]) submit = SubmitField('Save Resource') diff --git a/app/single_resource/views.py b/app/single_resource/views.py index b89fb4d..6fcc9c5 100644 --- a/app/single_resource/views.py +++ b/app/single_resource/views.py @@ -20,13 +20,16 @@ def index(): if req_opt_desc: req_opt_desc = req_opt_desc[0] req_opt_desc = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() req_options = {} if req_opt_desc: for val in req_opt_desc.values: req_options[val] = False - return render_template('single_resource/index.html', resources=resources, req_options=req_options) + return render_template( + 'single_resource/index.html', + resources=resources, + req_options=req_options) + @single_resource.route('/search') @login_required @@ -37,13 +40,13 @@ def search_resources(): req_options = request.args.getlist('reqoption') if req_options is None: req_options = [] - resource_pool = Resource.query.filter(Resource.name.ilike('%{}%'.format(name))).all() + resource_pool = Resource.query.filter( + Resource.name.ilike('%{}%'.format(name))).all() req_opt_desc = RequiredOptionDescriptor.query.all() if req_opt_desc: req_opt_desc = req_opt_desc[0] req_opt_desc = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() resources = list(resource_pool) if req_opt_desc and len(req_options) > 0: resources = [] @@ -52,9 +55,7 @@ def search_resources(): int_req_options.append(req_opt_desc.values.index(str(o))) for resource in resource_pool: associations = OptionAssociation.query.filter_by( - resource_id=resource.id, - descriptor_id=req_opt_desc.id - ) + resource_id=resource.id, descriptor_id=req_opt_desc.id) for a in associations: if a.option in int_req_options: resources.append(resource) @@ -63,7 +64,12 @@ def search_resources(): if req_opt_desc is not None: for val in req_opt_desc.values: query_req_options[val] = val in req_options - return render_template('single_resource/index.html', resources=resources, query_name=name, req_options=query_req_options) + return render_template( + 'single_resource/index.html', + resources=resources, + query_name=name, + req_options=query_req_options) + @single_resource.route('/create', methods=['GET', 'POST']) @login_required @@ -73,9 +79,10 @@ def create(): for descriptor in descriptors: if descriptor.values: # Fields for option descriptors. choices = [(str(i), v) for i, v in enumerate(descriptor.values)] - setattr(SingleResourceForm, - descriptor.name, - SelectMultipleField(choices=choices)) + setattr( + SingleResourceForm, + descriptor.name, + SelectMultipleField(choices=choices)) else: # Fields for text descriptors setattr(SingleResourceForm, descriptor.name, TextAreaField()) form = SingleResourceForm() @@ -84,21 +91,24 @@ def create(): if req_opt_desc: req_opt_desc = req_opt_desc[0] descriptor = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() if descriptor is not None: if not form[descriptor.name].data: - flash('Error: Must set required descriptor: {}'.format(descriptor.name), 'form-error') - return render_template('single_resource/create.html', form=form) - new_resource = Resource(name=form.name.data, - address=form.address.data, - latitude=form.latitude.data, - longitude=form.longitude.data) + flash('Error: Must set required descriptor: {}'.format( + descriptor.name), 'form-error') + return render_template( + 'single_resource/create.html', form=form) + new_resource = Resource( + name=form.name.data, + address=form.address.data, + latitude=form.latitude.data, + longitude=form.longitude.data) db.session.add(new_resource) - save_associations(resource=new_resource, - form=form, - descriptors=descriptors, - resource_existed=False) + save_associations( + resource=new_resource, + form=form, + descriptors=descriptors, + resource_existed=False) try: db.session.commit() flash('Resource added', 'form-success') @@ -124,46 +134,44 @@ def edit(resource_id): choices = [(str(i), v) for i, v in enumerate(descriptor.values)] default = None option_associations = OptionAssociation.query.filter_by( - resource_id=resource_id, - descriptor_id=descriptor.id - ) + resource_id=resource_id, descriptor_id=descriptor.id) if option_associations is not None: default = [assoc.option for assoc in option_associations] - setattr(SingleResourceForm, - descriptor.name, + setattr(SingleResourceForm, descriptor.name, SelectMultipleField(choices=choices, default=default)) else: # Fields for text descriptors. default = None text_association = TextAssociation.query.filter_by( - resource_id=resource_id, - descriptor_id=descriptor.id - ).first() + resource_id=resource_id, descriptor_id=descriptor.id).first() if text_association is not None: default = text_association.text - setattr(SingleResourceForm, - descriptor.name, - TextAreaField(default=default)) + setattr( + SingleResourceForm, + descriptor.name, + TextAreaField(default=default)) form = SingleResourceForm() if form.validate_on_submit(): req_opt_desc = RequiredOptionDescriptor.query.all() if req_opt_desc: req_opt_desc = req_opt_desc[0] descriptor = Descriptor.query.filter_by( - id=req_opt_desc.descriptor_id - ).first() + id=req_opt_desc.descriptor_id).first() if descriptor is not None: if not form[descriptor.name].data: - flash('Error: Must set required descriptor: {}'.format(descriptor.name), 'form-error') - return render_template('single_resource/edit.html', - form=form, - resource_id=resource_id) + flash('Error: Must set required descriptor: {}'.format( + descriptor.name), 'form-error') + return render_template( + 'single_resource/edit.html', + form=form, + resource_id=resource_id) # Field id is not needed for the form, hence omitted with [1:]. for field_name in resource_field_names[1:]: setattr(resource, field_name, form[field_name].data) - save_associations(resource=resource, - form=form, - descriptors=descriptors, - resource_existed=True) + save_associations( + resource=resource, + form=form, + descriptors=descriptors, + resource_existed=True) try: db.session.commit() flash('Resource updated', 'form-success') @@ -176,9 +184,8 @@ def edit(resource_id): for field_name in resource_field_names[1:]: if form[field_name]: form[field_name].data = resource.__dict__[field_name] - return render_template('single_resource/edit.html', - form=form, - resource_id=resource_id) + return render_template( + 'single_resource/edit.html', form=form, resource_id=resource_id) def save_associations(resource, form, descriptors, resource_existed): @@ -186,11 +193,12 @@ def save_associations(resource, form, descriptors, resource_existed): handlers to the database.""" #first delete all the associations for this resource if it already existed (to handle the "empty" case) if resource_existed: - options = OptionAssociation.query.filter_by(resource_id=resource.id).all() + options = OptionAssociation.query.filter_by( + resource_id=resource.id).all() texts = TextAssociation.query.filter_by(resource_id=resource.id).all() associations = options + texts for a in associations: - db.session.delete(a) + db.session.delete(a) try: db.session.commit() except IntegrityError: @@ -208,14 +216,17 @@ def save_associations(resource, form, descriptors, resource_existed): values = [form[descriptor.name].data] keyword = 'text' for value in values: - arguments = {'resource_id': resource.id, - 'descriptor_id': descriptor.id, - keyword: value, - 'resource': resource, - 'descriptor': descriptor} + arguments = { + 'resource_id': resource.id, + 'descriptor_id': descriptor.id, + keyword: value, + 'resource': resource, + 'descriptor': descriptor + } new_association = AssociationClass(**arguments) db.session.add(new_association) + @single_resource.route('//delete', methods=['POST']) @login_required def delete(resource_id): diff --git a/app/suggestion/forms.py b/app/suggestion/forms.py index 74699a8..a2d6c2c 100644 --- a/app/suggestion/forms.py +++ b/app/suggestion/forms.py @@ -5,56 +5,33 @@ class SuggestionBasicForm(Form): contact_name = TextField( - 'Contact Name', - validators=[InputRequired(), Length(1, 500)] - ) + 'Contact Name', validators=[InputRequired(), Length(1, 500)]) contact_email = TextField( - 'Email', - validators=[InputRequired(), Length(1, 500), Email()] - ) + 'Email', validators=[InputRequired(), Length(1, 500), Email()]) contact_phone_number = TextField( - 'Phone Number', - validators=[InputRequired(), Length(1, 64)] - ) - name = StringField('Resource Name', validators=[ - InputRequired(), - Length(1, 500) - ]) - address = StringField('Resource Address', validators=[ - InputRequired(), - Length(1, 500) - ]) - suggestion_text = TextField('Suggestion', validators=[ - InputRequired() - ]) + 'Phone Number', validators=[InputRequired(), Length(1, 64)]) + name = StringField( + 'Resource Name', validators=[InputRequired(), Length(1, 500)]) + address = StringField( + 'Resource Address', validators=[InputRequired(), Length(1, 500)]) + suggestion_text = TextField('Suggestion', validators=[InputRequired()]) submit = SubmitField('Submit') + class SuggestionAdvancedForm(Form): """ CURRENTLY NOT IN USE Intention is to use this as an advanced suggestion form allowing users to also fill out descriptor values """ contact_name = TextField( - 'Contact Name', - validators=[InputRequired(), Length(1, 500)] - ) + 'Contact Name', validators=[InputRequired(), Length(1, 500)]) contact_email = TextField( - 'Email', - validators=[InputRequired(), Length(1, 500), Email()] - ) + 'Email', validators=[InputRequired(), Length(1, 500), Email()]) contact_phone_number = TextField( - 'Phone Number', - validators=[InputRequired(), Length(1, 64)] - ) - name = StringField('Resource Name', validators=[ - InputRequired(), - Length(1, 500) - ]) - address = StringField('Resource Address', validators=[ - InputRequired(), - Length(1, 500) - ]) - suggestion_text = TextField('Suggestion', validators=[ - InputRequired() - ]) + 'Phone Number', validators=[InputRequired(), Length(1, 64)]) + name = StringField( + 'Resource Name', validators=[InputRequired(), Length(1, 500)]) + address = StringField( + 'Resource Address', validators=[InputRequired(), Length(1, 500)]) + suggestion_text = TextField('Suggestion', validators=[InputRequired()]) submit = SubmitField('Submit') diff --git a/app/suggestion/views.py b/app/suggestion/views.py index fd96386..d0dd103 100644 --- a/app/suggestion/views.py +++ b/app/suggestion/views.py @@ -32,9 +32,8 @@ def index(): @login_required def unread(): """Returns the number of unread suggestions.""" - num_unread = Suggestion.query.filter( - Suggestion.read == False # noqa - ).count() + num_unread = Suggestion.query.filter(Suggestion.read == False # noqa + ).count() return "%d" % num_unread @@ -72,9 +71,9 @@ def delete(sugg_id): return redirect(url_for('suggestion.index')) -@suggestion.route('/new', defaults={'resource_id': None}, - methods=['GET', 'POST']) -@suggestion.route('/', methods=['GET', 'POST']) +@suggestion.route( + '/new', defaults={'resource_id': None}, methods=['GET', 'POST']) +@suggestion.route('/', methods=['GET', 'POST']) def suggest(resource_id): """Create a suggestion for a resource.""" basic_form = SuggestionBasicForm() @@ -93,9 +92,10 @@ def suggest(resource_id): for descriptor in descriptors: if descriptor.values: # Fields for option descriptors. choices = [(str(i), v) for i, v in enumerate(descriptor.values)] - setattr(SuggestionAdvancedForm, - descriptor.name, - SelectField(choices=choices)) + setattr( + SuggestionAdvancedForm, + descriptor.name, + SelectField(choices=choices)) else: # Fields for text descriptors setattr(SuggestionAdvancedForm, descriptor.name, TextAreaField()) if basic_form.validate_on_submit(): @@ -107,8 +107,7 @@ def suggest(resource_id): contact_phone_number=basic_form.contact_phone_number.data, resource_name=basic_form.name.data, resource_address=basic_form.address.data, - submission_time=datetime.now(pytz.timezone('US/Eastern')) - ) + submission_time=datetime.now(pytz.timezone('US/Eastern'))) db.session.add(suggestion) try: db.session.commit() @@ -124,15 +123,17 @@ def suggest(resource_id): phone=basic_form.contact_phone_number.data, message=basic_form.suggestion_text.data, resource_name=basic_form.name.data, - resource_address=basic_form.address.data, - ) + resource_address=basic_form.address.data, ) flash('Thanks for the suggestion!', 'success') return redirect(url_for('main.index')) except IntegrityError: db.session.rollback() flash('Database error occurred. Please try again.', 'error') - return render_template('suggestion/suggest.html', name=name, basic_form=basic_form, - advanced_form=advanced_form) + return render_template( + 'suggestion/suggest.html', + name=name, + basic_form=basic_form, + advanced_form=advanced_form) @suggestion.route('/create/', methods=['GET', 'POST']) @@ -145,24 +146,27 @@ def create(sugg_id): for descriptor in descriptors: if descriptor.values: # Fields for option descriptors. choices = [(str(i), v) for i, v in enumerate(descriptor.values)] - setattr(SingleResourceForm, - descriptor.name, - SelectField(choices=choices)) + setattr( + SingleResourceForm, + descriptor.name, + SelectField(choices=choices)) else: # Fields for text descriptors setattr(SingleResourceForm, descriptor.name, TextAreaField()) form = SingleResourceForm() form.name.data = suggestion.resource_name form.address.data = suggestion.resource_address if form.validate_on_submit(): - new_resource = Resource(name=form.name.data, - address=form.address.data, - latitude=form.latitude.data, - longitude=form.longitude.data) + new_resource = Resource( + name=form.name.data, + address=form.address.data, + latitude=form.latitude.data, + longitude=form.longitude.data) db.session.add(new_resource) - save_associations(resource=new_resource, - form=form, - descriptors=descriptors, - resource_existed=False) + save_associations( + resource=new_resource, + form=form, + descriptors=descriptors, + resource_existed=False) try: db.session.commit() flash('Resource added', 'form-success') @@ -171,7 +175,9 @@ def create(sugg_id): db.session.rollback() flash('Error: failed to save resource. Please try again.', 'form-error') - return render_template('suggestion/create.html', form=form, suggestion=suggestion) + return render_template( + 'suggestion/create.html', form=form, suggestion=suggestion) + @suggestion.route('/edit/', methods=['GET', 'POST']) @login_required @@ -190,34 +196,31 @@ def edit(sugg_id): choices = [(str(i), v) for i, v in enumerate(descriptor.values)] default = None option_association = OptionAssociation.query.filter_by( - resource_id=resource_id, - descriptor_id=descriptor.id - ).first() + resource_id=resource_id, descriptor_id=descriptor.id).first() if option_association is not None: default = option_association.option - setattr(SingleResourceForm, - descriptor.name, + setattr(SingleResourceForm, descriptor.name, SelectField(choices=choices, default=default)) else: # Fields for text descriptors. default = None text_association = TextAssociation.query.filter_by( - resource_id=resource_id, - descriptor_id=descriptor.id - ).first() + resource_id=resource_id, descriptor_id=descriptor.id).first() if text_association is not None: default = text_association.text - setattr(SingleResourceForm, - descriptor.name, - TextAreaField(default=default)) + setattr( + SingleResourceForm, + descriptor.name, + TextAreaField(default=default)) form = SingleResourceForm() if form.validate_on_submit(): # Field id is not needed for the form, hence omitted with [1:]. for field_name in resource_field_names[1:]: setattr(resource, field_name, form[field_name].data) - save_associations(resource=resource, - form=form, - descriptors=descriptors, - resource_existed=True) + save_associations( + resource=resource, + form=form, + descriptors=descriptors, + resource_existed=True) try: db.session.commit() flash('Resource updated', 'form-success') @@ -230,4 +233,8 @@ def edit(sugg_id): for field_name in resource_field_names[1:]: form[field_name].data = resource.__dict__[field_name] - return render_template('suggestion/edit.html', form=form, suggestion=suggestion, resource_id=resource_id) + return render_template( + 'suggestion/edit.html', + form=form, + suggestion=suggestion, + resource_id=resource_id) diff --git a/config.py b/config.py index 1775121..87628e0 100644 --- a/config.py +++ b/config.py @@ -21,8 +21,8 @@ class Config: ADMIN_EMAIL = os.environ.get('ADMIN_EMAIL') EMAIL_SUBJECT_PREFIX = '[{}]'.format(APP_NAME) - EMAIL_SENDER = '{app_name} Admin <{email}>'.format(app_name=APP_NAME, - email=MAIL_USERNAME) + EMAIL_SENDER = '{app_name} Admin <{email}>'.format( + app_name=APP_NAME, email=MAIL_USERNAME) REDIS_URL = os.getenv('REDISTOGO_URL') or 'http://localhost:6379' @@ -78,8 +78,7 @@ def init_app(cls, app): toaddrs=[cls.ADMIN_EMAIL], subject=cls.EMAIL_SUBJECT_PREFIX + ' Application Error', credentials=credentials, - secure=secure - ) + secure=secure) mail_handler.setLevel(logging.ERROR) app.logger.addHandler(mail_handler) diff --git a/manage.py b/manage.py index 719289d..1f6d717 100755 --- a/manage.py +++ b/manage.py @@ -26,9 +26,16 @@ def make_shell_context(): - return dict(app=app, db=db, User=User, Role=Role, CsvBodyCell=CsvBodyCell, - CsvBodyRow=CsvBodyRow, CsvContainer=CsvContainer, - CsvHeaderCell=CsvHeaderCell, CsvHeaderRow=CsvHeaderRow) + return dict( + app=app, + db=db, + User=User, + Role=Role, + CsvBodyCell=CsvBodyCell, + CsvBodyRow=CsvBodyRow, + CsvContainer=CsvContainer, + CsvHeaderCell=CsvHeaderCell, + CsvHeaderRow=CsvHeaderRow) manager.add_command('shell', Shell(make_context=make_shell_context)) @@ -55,12 +62,13 @@ def recreate_db(): db.session.commit() -@manager.option('-n', - '--number-users', - default=10, - type=int, - help='Number of each model type to create', - dest='number_users') +@manager.option( + '-n', + '--number-users', + default=10, + type=int, + help='Number of each model type to create', + dest='number_users') def add_fake_data(number_users): """ Adds fake data to the database. @@ -76,9 +84,7 @@ def setup_dev(): admin_email = os.environ.get('ADMIN_EMAIL') if User.query.filter_by(email=admin_email).first() is None: - User.create_confirmed_admin('Default', - 'Admin', - admin_email, + User.create_confirmed_admin('Default', 'Admin', admin_email, 'password') @@ -102,12 +108,12 @@ def run_worker(): host=app.config['RQ_DEFAULT_HOST'], port=app.config['RQ_DEFAULT_PORT'], db=0, - password=app.config['RQ_DEFAULT_PASSWORD'] - ) + password=app.config['RQ_DEFAULT_PASSWORD']) with Connection(conn): worker = Worker(map(Queue, listen)) worker.work() + if __name__ == '__main__': manager.run()