From 7380b6f9f71c1ab3da905d8795a50f0aeb418950 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 11:33:42 +0200 Subject: [PATCH 1/8] Explicitly disables SQLALCHEMY_TRACK_MODIFICATIONS That noisy warning was everywhere in our test/CI logs before that commit: > ./home/travis/build/spiral-project/ihatemoney/.tox/py27/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py:839: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning. > > 'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhe --- budget/default_settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/budget/default_settings.py b/budget/default_settings.py index d5a9a9b3..5ee6de80 100644 --- a/budget/default_settings.py +++ b/budget/default_settings.py @@ -1,6 +1,10 @@ DEBUG = False SQLALCHEMY_DATABASE_URI = 'sqlite:///budget.db' SQLACHEMY_ECHO = DEBUG +# Will likely become the default value in flask-sqlalchemy >=3 ; could be removed +# then: +SQLALCHEMY_TRACK_MODIFICATIONS = False + SECRET_KEY = "tralala" MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") From c7f4547d5d99c3ba5aed594304d050c81d33ab97 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 14:32:43 +0200 Subject: [PATCH 2/8] Use non-deprecated way to disable CSRF for API See also https://github.com/lepture/flask-wtf/pull/287 --- budget/api.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/budget/api.py b/budget/api.py index ec664b6b..4b991bdf 100644 --- a/budget/api.py +++ b/budget/api.py @@ -29,7 +29,7 @@ def check_project(*args, **kwargs): class ProjectHandler(object): def add(self): - form = ProjectForm(csrf_enabled=False) + form = ProjectForm(meta={'csrf': False}) if form.validate(): project = form.save() db.session.add(project) @@ -49,7 +49,7 @@ class ProjectHandler(object): @need_auth(check_project, "project") def update(self, project): - form = EditProjectForm(csrf_enabled=False) + form = EditProjectForm(meta={'csrf': False}) if form.validate(): form.update(project) db.session.commit() @@ -69,7 +69,7 @@ class MemberHandler(object): return 200, project.members def add(self, project): - form = MemberForm(project, csrf_enabled=False) + form = MemberForm(project, meta={'csrf': False}) if form.validate(): member = Person() form.save(project, member) @@ -78,7 +78,7 @@ class MemberHandler(object): return 400, form.errors def update(self, project, member_id): - form = MemberForm(project, csrf_enabled=False) + form = MemberForm(project, meta={'csrf': False}) if form.validate(): member = Person.query.get(member_id, project) form.save(project, member) @@ -104,7 +104,7 @@ class BillHandler(object): return project.get_bills().all() def add(self, project): - form = get_billform_for(project, True, csrf_enabled=False) + form = get_billform_for(project, True, meta={'csrf': False}) if form.validate(): bill = Bill() form.save(bill, project) @@ -114,7 +114,7 @@ class BillHandler(object): return 400, form.errors def update(self, project, bill_id): - form = get_billform_for(project, True, csrf_enabled=False) + form = get_billform_for(project, True, meta={'csrf': False}) if form.validate(): bill = Bill.query.get(project, bill_id) form.save(bill, project) From 5a7ae4f5d2b2de1e0ff171cdb03f79d7f7ec5d5b Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 14:38:16 +0200 Subject: [PATCH 3/8] Update flask-wtf to 0.14 Important changes include the new way to disable CSRF for a given form, 0.13 does not support it. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c4776f03..c89f9393 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ flask>=0.11 -flask-wtf>=0.13 +flask-wtf>=0.14 flask-sqlalchemy flask-mail>=0.8 Flask-Migrate>=1.8.0 From 2609c4aaa7605addcf322c9deaf6065ae61ac262 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 14:53:22 +0200 Subject: [PATCH 4/8] Update flask-sqlalchemy to >=2.2 Versions prior to 2.1 trigger a deprecation warning because of the import of `flask.ext.sqlalchemy._compat` instead of `flask_sqlalchemy`. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c89f9393..5820a548 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ flask>=0.11 flask-wtf>=0.14 -flask-sqlalchemy +flask-sqlalchemy>=2.2,<3.0 flask-mail>=0.8 Flask-Migrate>=1.8.0 flask-babel From ec75e554160232a32df9ed1e6ed286a85c4fcb00 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 15:09:28 +0200 Subject: [PATCH 5/8] Remove deprecated wtforms TextField It is a bare alias of StringField (thus, no alembic migration is required), deprecated since wtforms v2.0 (2013). Removes the following warning: > DeprecationWarning: The TextField alias for StringField has been deprecated and will be removed in WTForms 3.0 Ref https://github.com/wtforms/wtforms/commit/f07729dd45c0f5191f131d37adb0456104dc7c44 --- budget/forms.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/budget/forms.py b/budget/forms.py index 69679837..f4464751 100644 --- a/budget/forms.py +++ b/budget/forms.py @@ -1,7 +1,7 @@ from flask_wtf.form import FlaskForm from wtforms.fields.core import SelectField, SelectMultipleField from wtforms.fields.html5 import DateField, DecimalField -from wtforms.fields.simple import PasswordField, SubmitField, TextAreaField, TextField +from wtforms.fields.simple import PasswordField, SubmitField, TextAreaField, StringField from wtforms.validators import Email, Required, ValidationError from flask_babel import lazy_gettext as _ from flask import request @@ -38,9 +38,9 @@ class CommaDecimalField(DecimalField): class EditProjectForm(FlaskForm): - name = TextField(_("Project name"), validators=[Required()]) - password = TextField(_("Private code"), validators=[Required()]) - contact_email = TextField(_("Email"), validators=[Required(), Email()]) + name = StringField(_("Project name"), validators=[Required()]) + password = StringField(_("Private code"), validators=[Required()]) + contact_email = StringField(_("Email"), validators=[Required(), Email()]) def save(self): """Create a new project with the information given by this form. @@ -62,7 +62,7 @@ class EditProjectForm(FlaskForm): class ProjectForm(EditProjectForm): - id = TextField(_("Project identifier"), validators=[Required()]) + id = StringField(_("Project identifier"), validators=[Required()]) password = PasswordField(_("Private code"), validators=[Required()]) submit = SubmitField(_("Create the project")) @@ -78,13 +78,13 @@ class ProjectForm(EditProjectForm): class AuthenticationForm(FlaskForm): - id = TextField(_("Project identifier"), validators=[Required()]) + id = StringField(_("Project identifier"), validators=[Required()]) password = PasswordField(_("Private code"), validators=[Required()]) submit = SubmitField(_("Get in")) class PasswordReminder(FlaskForm): - id = TextField(_("Project identifier"), validators=[Required()]) + id = StringField(_("Project identifier"), validators=[Required()]) submit = SubmitField(_("Send me the code by email")) def validate_id(form, field): @@ -94,7 +94,7 @@ class PasswordReminder(FlaskForm): class BillForm(FlaskForm): date = DateField(_("Date"), validators=[Required()], default=datetime.now) - what = TextField(_("What?"), validators=[Required()]) + what = StringField(_("What?"), validators=[Required()]) payer = SelectField(_("Payer"), validators=[Required()], coerce=int) amount = CommaDecimalField(_("Amount paid"), validators=[Required()]) payed_for = SelectMultipleField(_("For whom?"), @@ -129,7 +129,7 @@ class BillForm(FlaskForm): class MemberForm(FlaskForm): - name = TextField(_("Name"), validators=[Required()]) + name = StringField(_("Name"), validators=[Required()]) weight = CommaDecimalField(_("Weight"), default=1) submit = SubmitField(_("Add")) From f6236b43ca5556c6df764e95428d5efced8ff4e1 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 15:14:50 +0200 Subject: [PATCH 6/8] Remove ExtDeprecationWarning from manage.py Using new-style flask extensions imports. grep tells me there were the only flask.ext.* occurences remaining in ihatemoney code. --- budget/manage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/budget/manage.py b/budget/manage.py index e0b25a76..94a21a27 100755 --- a/budget/manage.py +++ b/budget/manage.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -from flask.ext.script import Manager -from flask.ext.migrate import Migrate, MigrateCommand +from flask_script import Manager +from flask_migrate import Migrate, MigrateCommand from run import app from models import db From 95d0c71827502f6e5ab0f5280176d07725073858 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 15:31:28 +0200 Subject: [PATCH 7/8] Use propper base64 encoding version for py3 Removes py3-only warning (this alias might be removed in future py3 version): > DeprecationWarning: encodestring() is a deprecated alias, use encodebytes() > ('%s:%s' % (username, password)).encode('utf-8')).decode('utf-8').replace('\n', '') py2-compatible change. --- budget/tests.py | 4 ++-- budget/utils.py | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/budget/tests.py b/budget/tests.py index 50c01ae6..854c07b0 100644 --- a/budget/tests.py +++ b/budget/tests.py @@ -5,7 +5,6 @@ try: except ImportError: import unittest # NOQA -import base64 import os import json from collections import defaultdict @@ -17,6 +16,7 @@ from flask import session import run import models +import utils class TestCase(unittest.TestCase): @@ -759,7 +759,7 @@ class APITestCase(TestCase): def get_auth(self, username, password=None): password = password or username - base64string = base64.encodestring( + base64string = utils.base64_encode( ('%s:%s' % (username, password)).encode('utf-8')).decode('utf-8').replace('\n', '') return {"Authorization": "Basic %s" % base64string} diff --git a/budget/utils.py b/budget/utils.py index f518049c..0e6251b2 100644 --- a/budget/utils.py +++ b/budget/utils.py @@ -1,3 +1,4 @@ +import base64 import re import inspect @@ -120,3 +121,6 @@ def list_of_dicts2csv(dict_to_convert): if six.PY3: csv_file = BytesIO(csv_file.getvalue().encode('utf-8')) return csv_file + +# base64 encoding that works with both py2 and py3 and yield no warning +base64_encode = base64.encodestring if six.PY2 else base64.encodebytes From 4799fcb34f1319615666fb0663bbb6cb12e8a4d1 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Wed, 29 Mar 2017 15:36:04 +0200 Subject: [PATCH 8/8] Remove unused sphinx option It was triggering a warning : > copying static files... WARNING: html_static_path entry u'/home/jocelyn/dev/ihatemoney/docs/_static' does not exist To my knowledge it was not used, and the _static dir do not even exist. Let me know if I am wrong. --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 17f693a2..332c3dee 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,5 +16,4 @@ pygments_style = 'sphinx' sys.path.append(os.path.abspath('_themes')) html_theme_path = ['_themes'] html_theme = 'pelican' -html_static_path = ['_static'] html_theme_options = { 'nosidebar': True }