mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-05-05 20:51:49 +02:00
Merge 45d2e33499
into 67331dcf2a
This commit is contained in:
commit
01b0b62775
8 changed files with 36 additions and 34 deletions
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from flask import Blueprint, request
|
from flask import Blueprint, request
|
||||||
from flask.ext.rest import RESTResource, need_auth
|
from flask_rest import RESTResource, need_auth
|
||||||
|
|
||||||
from models import db, Project, Person, Bill
|
from models import db, Project, Person, Bill
|
||||||
from forms import (ProjectForm, EditProjectForm, MemberForm,
|
from forms import (ProjectForm, EditProjectForm, MemberForm,
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
from flask.ext.wtf import DateField, DecimalField, Email, Form, PasswordField, \
|
from flask_wtf.form import FlaskForm
|
||||||
Required, SelectField, SelectMultipleField, SubmitField, TextAreaField, \
|
from wtforms.fields.core import SelectField, SelectMultipleField
|
||||||
TextField, ValidationError
|
from wtforms.fields.html5 import DateField, DecimalField
|
||||||
from flask.ext.babel import lazy_gettext as _
|
from wtforms.fields.simple import PasswordField, SubmitField, TextAreaField, TextField
|
||||||
|
from wtforms.validators import Email, Required, ValidationError
|
||||||
|
from flask_babel import lazy_gettext as _
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from wtforms.widgets import html_params
|
from wtforms.widgets import html_params
|
||||||
|
@ -57,7 +59,7 @@ class CommaDecimalField(DecimalField):
|
||||||
return super(CommaDecimalField, self).process_formdata(value)
|
return super(CommaDecimalField, self).process_formdata(value)
|
||||||
|
|
||||||
|
|
||||||
class EditProjectForm(Form):
|
class EditProjectForm(FlaskForm):
|
||||||
name = TextField(_("Project name"), validators=[Required()])
|
name = TextField(_("Project name"), validators=[Required()])
|
||||||
password = TextField(_("Private code"), validators=[Required()])
|
password = TextField(_("Private code"), validators=[Required()])
|
||||||
contact_email = TextField(_("Email"), validators=[Required(), Email()])
|
contact_email = TextField(_("Email"), validators=[Required(), Email()])
|
||||||
|
@ -97,13 +99,13 @@ class ProjectForm(EditProjectForm):
|
||||||
"that you will be able to remember.")))
|
"that you will be able to remember.")))
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationForm(Form):
|
class AuthenticationForm(FlaskForm):
|
||||||
id = TextField(_("Project identifier"), validators=[Required()])
|
id = TextField(_("Project identifier"), validators=[Required()])
|
||||||
password = PasswordField(_("Private code"), validators=[Required()])
|
password = PasswordField(_("Private code"), validators=[Required()])
|
||||||
submit = SubmitField(_("Get in"))
|
submit = SubmitField(_("Get in"))
|
||||||
|
|
||||||
|
|
||||||
class PasswordReminder(Form):
|
class PasswordReminder(FlaskForm):
|
||||||
id = TextField(_("Project identifier"), validators=[Required()])
|
id = TextField(_("Project identifier"), validators=[Required()])
|
||||||
submit = SubmitField(_("Send me the code by email"))
|
submit = SubmitField(_("Send me the code by email"))
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ class PasswordReminder(Form):
|
||||||
raise ValidationError(_("This project does not exists"))
|
raise ValidationError(_("This project does not exists"))
|
||||||
|
|
||||||
|
|
||||||
class BillForm(Form):
|
class BillForm(FlaskForm):
|
||||||
date = DateField(_("Date"), validators=[Required()], default=datetime.now)
|
date = DateField(_("Date"), validators=[Required()], default=datetime.now)
|
||||||
what = TextField(_("What?"), validators=[Required()])
|
what = TextField(_("What?"), validators=[Required()])
|
||||||
payer = SelectField(_("Payer"), validators=[Required()], coerce=int)
|
payer = SelectField(_("Payer"), validators=[Required()], coerce=int)
|
||||||
|
@ -147,7 +149,7 @@ class BillForm(Form):
|
||||||
raise ValidationError(_("Bills can't be null"))
|
raise ValidationError(_("Bills can't be null"))
|
||||||
|
|
||||||
|
|
||||||
class MemberForm(Form):
|
class MemberForm(FlaskForm):
|
||||||
|
|
||||||
name = TextField(_("Name"), validators=[Required()])
|
name = TextField(_("Name"), validators=[Required()])
|
||||||
weight = CommaDecimalField(_("Weight"), default=1)
|
weight = CommaDecimalField(_("Weight"), default=1)
|
||||||
|
@ -180,7 +182,7 @@ class MemberForm(Form):
|
||||||
self.weight.data = member.weight
|
self.weight.data = member.weight
|
||||||
|
|
||||||
|
|
||||||
class InviteForm(Form):
|
class InviteForm(FlaskForm):
|
||||||
emails = TextAreaField(_("People to notify"))
|
emails = TextAreaField(_("People to notify"))
|
||||||
submit = SubmitField(_("Send invites"))
|
submit = SubmitField(_("Send invites"))
|
||||||
|
|
||||||
|
@ -192,7 +194,7 @@ class InviteForm(Form):
|
||||||
email=email))
|
email=email))
|
||||||
|
|
||||||
|
|
||||||
class CreateArchiveForm(Form):
|
class CreateArchiveForm(FlaskForm):
|
||||||
name = TextField(_("Name for this archive (optional)"), validators=[])
|
name = TextField(_("Name for this archive (optional)"), validators=[])
|
||||||
start_date = DateField(_("Start date"), validators=[Required()])
|
start_date = DateField(_("Start date"), validators=[Required()])
|
||||||
end_date = DateField(_("End date"), validators=[Required()], default=datetime.now)
|
end_date = DateField(_("End date"), validators=[Required()], default=datetime.now)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask.ext.sqlalchemy import SQLAlchemy, BaseQuery
|
from flask_sqlalchemy import SQLAlchemy, BaseQuery
|
||||||
from flask import g
|
from flask import g
|
||||||
|
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
@ -225,11 +225,11 @@ class Bill(db.Model):
|
||||||
|
|
||||||
def pay_each(self):
|
def pay_each(self):
|
||||||
"""Compute what each share has to pay"""
|
"""Compute what each share has to pay"""
|
||||||
if self.owers:
|
if self.owers:
|
||||||
# FIXME: SQL might dot that more efficiently
|
# FIXME: SQL might dot that more efficiently
|
||||||
return self.amount / sum(i.weight for i in self.owers)
|
return self.amount / sum(i.weight for i in self.owers)
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Bill of %s from %s for %s>" % (self.amount,
|
return "<Bill of %s from %s for %s>" % (self.amount,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
flask>=0.9
|
flask>=0.11
|
||||||
flask-wtf==0.8
|
flask-wtf>=0.13
|
||||||
flask-sqlalchemy
|
flask-sqlalchemy
|
||||||
flask-mail>=0.8
|
flask-mail>=0.8
|
||||||
Flask-Migrate==1.8.0
|
Flask-Migrate>=1.8.0
|
||||||
flask-babel
|
flask-babel
|
||||||
flask-rest
|
flask-rest
|
||||||
jinja2==2.6
|
jinja2>=2.6
|
||||||
raven
|
raven
|
||||||
blinker
|
blinker
|
||||||
|
|
|
@ -2,8 +2,8 @@ import os
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from flask import Flask, g, request, session
|
from flask import Flask, g, request, session
|
||||||
from flask.ext.babel import Babel
|
from flask_babel import Babel
|
||||||
from flask.ext.migrate import Migrate, upgrade, stamp
|
from flask_migrate import Migrate, upgrade, stamp
|
||||||
from raven.contrib.flask import Sentry
|
from raven.contrib.flask import Sentry
|
||||||
|
|
||||||
from web import main, db, mail
|
from web import main, db, mail
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
try:
|
try:
|
||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -56,7 +56,7 @@ class TestCase(unittest.TestCase):
|
||||||
})
|
})
|
||||||
|
|
||||||
def create_project(self, name):
|
def create_project(self, name):
|
||||||
models.db.session.add(models.Project(id=name, name=unicode(name),
|
models.db.session.add(models.Project(id=name, name=name,
|
||||||
password=name, contact_email="%s@notmyidea.org" % name))
|
password=name, contact_email="%s@notmyidea.org" % name))
|
||||||
models.db.session.commit()
|
models.db.session.commit()
|
||||||
|
|
||||||
|
@ -292,10 +292,10 @@ class BudgetTestCase(TestCase):
|
||||||
self.assertTrue(models.Project.query.get("demo") is not None)
|
self.assertTrue(models.Project.query.get("demo") is not None)
|
||||||
|
|
||||||
def test_authentication(self):
|
def test_authentication(self):
|
||||||
# try to authenticate without credentials should redirect
|
# try to authenticate without credentials should redirect
|
||||||
# to the authentication page
|
# to the authentication page
|
||||||
resp = self.app.post("/authenticate")
|
resp = self.app.post("/authenticate")
|
||||||
self.assertIn("Authentication", resp.data)
|
self.assertIn("Authentication", resp.data)
|
||||||
|
|
||||||
# raclette that the login / logout process works
|
# raclette that the login / logout process works
|
||||||
self.create_project("raclette")
|
self.create_project("raclette")
|
||||||
|
|
|
@ -12,10 +12,10 @@ def slugify(value):
|
||||||
|
|
||||||
Copy/Pasted from ametaireau/pelican/utils itself took from django sources.
|
Copy/Pasted from ametaireau/pelican/utils itself took from django sources.
|
||||||
"""
|
"""
|
||||||
if type(value) == unicode:
|
if type(value) == str:
|
||||||
import unicodedata
|
import unicodedata
|
||||||
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
|
value = unicodedata.normalize('NFKD', value)
|
||||||
value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
|
value = re.sub('[^\w\s-]', '', value).strip().lower()
|
||||||
return re.sub('[-\s]+', '-', value)
|
return re.sub('[-\s]+', '-', value)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ and `add_project_id` for a quick overview)
|
||||||
|
|
||||||
from flask import Blueprint, current_app, flash, g, redirect, \
|
from flask import Blueprint, current_app, flash, g, redirect, \
|
||||||
render_template, request, session, url_for
|
render_template, request, session, url_for
|
||||||
from flask.ext.mail import Mail, Message
|
from flask_mail import Mail, Message
|
||||||
from flask.ext.babel import get_locale, gettext as _
|
from flask_babel import get_locale, gettext as _
|
||||||
from smtplib import SMTPRecipientsRefused
|
from smtplib import SMTPRecipientsRefused
|
||||||
import werkzeug
|
import werkzeug
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
|
Loading…
Reference in a new issue