From f63939cb03603bd3ab89f120c650d3ccadf4c543 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Tue, 10 Nov 2015 22:31:14 +0100 Subject: [PATCH] Add initial Flask implementation --- config.py | 12 ++ debianmemberportfolio/__init__.py | 11 +- debianmemberportfolio/forms.py | 35 ++++++ debianmemberportfolio/templates/base.html | 48 +++++++ debianmemberportfolio/templates/showform.html | 40 ++++++ .../templates/showformscript.js | 119 ++++++++++++++++++ debianmemberportfolio/views.py | 42 +++++++ run.py | 6 + 8 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 config.py create mode 100644 debianmemberportfolio/forms.py create mode 100644 debianmemberportfolio/templates/base.html create mode 100644 debianmemberportfolio/templates/showform.html create mode 100644 debianmemberportfolio/templates/showformscript.js create mode 100644 debianmemberportfolio/views.py create mode 100755 run.py diff --git a/config.py b/config.py new file mode 100644 index 0000000..4345151 --- /dev/null +++ b/config.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +WTF_CSRF_ENABLED = False + +# available languages +LANGUAGES = { + 'en': 'English', + 'de': 'Deutsch', + 'fr': 'Français', + 'id': 'Bahasa Indonesia', + 'pt_BR': 'Portuguese (Brazil)' +} diff --git a/debianmemberportfolio/__init__.py b/debianmemberportfolio/__init__.py index d500ba2..56f6669 100644 --- a/debianmemberportfolio/__init__.py +++ b/debianmemberportfolio/__init__.py @@ -3,7 +3,7 @@ # # Debian Member Portfolio Service package # -# Copyright © 2009-2014 Jan Dittberner +# Copyright © 2009-2015 Jan Dittberner # # This file is part of the Debian Member Portfolio Service. # @@ -20,3 +20,12 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # + +from flask import Flask +from flask.ext.babel import Babel + +app = Flask(__name__) +babel = Babel(app) +app.config.from_object('config') + +from debianmemberportfolio import views diff --git a/debianmemberportfolio/forms.py b/debianmemberportfolio/forms.py new file mode 100644 index 0000000..9f988a5 --- /dev/null +++ b/debianmemberportfolio/forms.py @@ -0,0 +1,35 @@ +from __future__ import unicode_literals + +from flask.ext.wtf import Form +from wtforms import IntegerField, StringField +from wtforms.validators import ( + AnyOf, DataRequired, Email, Length, Optional, Regexp +) + + +class FingerPrint(Regexp): + def __init__(self, **kwargs): + super(FingerPrint, self).__init__(r'^[a-fA-F0-9]*$', **kwargs) + + +class PlainText(Regexp): + def __init__(self, **kwargs): + super(PlainText, self).__init__(r'^[a-zA-Z\-0-9]*$') + + +class DeveloperData(Form): + email = StringField('email', validators=[DataRequired(), Email()]) + name = StringField('name', validators=[DataRequired()]) + gpgfp = StringField('gpgfp', validators=[ + FingerPrint(), + Length(min=32, max=40) + ]) + username = StringField('username', validators=[PlainText()]) + nonddemail = StringField('nonddemail', validators=[Email()]) + aliothusername = StringField('aliothusername', validators=[PlainText()]) + mode = StringField( + 'mode', default='html',validators=[AnyOf(['json', 'html'])] + ) + forumsid = IntegerField('forumsid', default=None, validators=[Optional()]) + wikihomepage = StringField('wikihomepage', default=None, validators=[ + Optional()]) diff --git a/debianmemberportfolio/templates/base.html b/debianmemberportfolio/templates/base.html new file mode 100644 index 0000000..3d5b139 --- /dev/null +++ b/debianmemberportfolio/templates/base.html @@ -0,0 +1,48 @@ + +{# vim: ft=jinja +Base template for XHTML templates. +Copyright © 2009-2015 Jan Dittberner + +This file is part of the Debian Member Portfolio service. + +Debian Member Portfolio service is free software: you can redistribute it +and/or modify it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Debian Member Portfolio service is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +General Public License for more details. + +You should have received a copy of the GNU Affero General Public License along +with this program. If not, see . +#} + + + {% block title %}{{ _('Debian Member Portfolio Service') }}{% endblock %} + + {% block extrahead %}{% endblock %} + + + +
+ {% block body %}{% endblock %} +
+ + + + + diff --git a/debianmemberportfolio/templates/showform.html b/debianmemberportfolio/templates/showform.html new file mode 100644 index 0000000..fac47d8 --- /dev/null +++ b/debianmemberportfolio/templates/showform.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} +{# +Template for the data input form. + +Copyright © 2009-2015 Jan Dittberner + +This file is part of the Debian Member Portfolio service. + +Debian Member Portfolio service is free software: you can redistribute it +and/or modify it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Debian Member Portfolio service is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +General Public License for more details. + +You should have received a copy of the GNU Affero General Public License along +with this program. If not, see . +#} +{% block title %}{{ super()}} - {{ _('Enter your personal information') }}{% endblock %} +{% block extrahead %}{{ super() }} + +{% endblock %} +{% block body %}{{ super() }} +
+
+ {{ _('Debian Member Portfolio') }} +
+
+ {{ form.email }}
+
+
+
+{% endblock %} diff --git a/debianmemberportfolio/templates/showformscript.js b/debianmemberportfolio/templates/showformscript.js new file mode 100644 index 0000000..10d54cd --- /dev/null +++ b/debianmemberportfolio/templates/showformscript.js @@ -0,0 +1,119 @@ +{# vim: ft=jinja +Helper JavaScript for the data input form. +Copyright © 2009, 2010, 2015 Jan Dittberner + +This file is part of the Debian Member Portfolio service. + +Debian Member Portfolio service is free software: you can redistribute it +and/or modify it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Debian Member Portfolio service is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +General Public License for more details. + +You should have received a copy of the GNU Affero General Public License along +with this program. If not, see . +#} +var defaulthiddendivs = new Array( + '#namefield', '#gpgfpfield', '#usernamefield', '#nonddemailfield', + '#aliothusernamefield', '#wikihomepagefield', '#forumsidfield'); +var maskedfielddivs = new Array( + '#namefield', '#gpgfpfield', '#usernamefield', '#nonddemailfield', + '#aliothusernamefield', '#wikihomepagefield', '#forumsidfield'); +var allfielddivs = new Array( + '#namefield', '#gpgfpfield', '#usernamefield', '#nonddemailfield', + '#aliothusernamefield', '#wikihomepagefield', '#forumsidfield'); + +function updateFields(data, textStatus) { + if (data.type == 2) { // DD + $('#name').attr('value', data.name).attr('readonly', 'readonly'); + $('#gpgfp').attr('value', data.gpgfp); + $('#username').attr('value', data.username).attr( + 'readonly', 'readonly'); + $('#nonddemail').attr('value', data.email).focus(); + $('#aliothusername').attr('value', data.username); + $('#wikihomepage').attr('value', data.wikihomepage); + + $('#namefield').show(); + $('#gpgfpfield').show(); + $('#usernamefield').show(); + $('#nonddemailfield').show(); + $('#aliothusernamefield').show(); + $('#wikihomepagefield').show(); + $('#forumsidfield').show(); + + $('#nonddemail').focus().select(); + } else if (data.type == 1) { // DM + $('#name').attr('value', data.name).attr('readonly', 'readonly'); + $('#gpgfp').attr('value', data.gpgfp); + $('#username').attr('value', ''); + $('#nonddemail').attr('value', data.email).focus(); + $('#wikihomepage').attr('value', data.wikihomepage); + + $('#namefield').show(); + $('#gpgfpfield').show(); + $('#usernamefield').hide(); + $('#nonddemailfield').hide(); + $('#aliothusernamefield').show(); + $('#wikihomepagefield').show(); + $('#forumsidfield').show(); + + $('#aliothusername').focus().select(); + } else { + $('#nonddemail').attr('value', data.email); + $('#name').removeAttr('readonly'); + $('#username').removeAttr('readonly').attr('value', ''); + $('#gpgfp').attr('value', ''); + + $('#usernamefield').hide(); + $('#gpgfpfield').hide(); + $('#nonddemailfield').hide(); + $('#namefield').show(); + $('#aliothusernamefield').show(); + $('#wikihomepagefield').show(); + $('#forumsidfield').show(); + + $('#name').focus().select(); + } +} + +function onChangeShowAll(event) { + if ($('#showall').attr('checked')) { + for (var fielddiv in allfielddivs) { + $(allfielddivs[fielddiv]).show(); + } + } else { + for (var fielddiv in maskedfielddivs) { + $(maskedfielddivs[fielddiv]).hide(); + } + } +} + +function onBlurEmail() { + if ($.trim($('#email').attr('value')).length > 0) { + $.ajax({ + 'url' : '{{ url_for("fetchdddata") }}', + 'data' : {'email' : $('#email').attr('value')}, + 'dataType' : 'json', + 'success' : updateFields, + 'error' : function(request, textStatus, errorThrown) { + $('#email').focus(); + } + }); + } +} + +$(document).ready(function() { + for (var index in defaulthiddendivs) { + if (!$(defaulthiddendivs[index]).hasClass('witherrors')) { + $(defaulthiddendivs[index]).hide(); + } + } + + $('#showall').attr('checked', false).change(onChangeShowAll); + $('#showallfield').show(); + $('#email').blur(onBlurEmail).focus(); +}); diff --git a/debianmemberportfolio/views.py b/debianmemberportfolio/views.py new file mode 100644 index 0000000..233800d --- /dev/null +++ b/debianmemberportfolio/views.py @@ -0,0 +1,42 @@ +from debianmemberportfolio import app, babel +from flask import g, make_response, request, render_template +from config import LANGUAGES +from .forms import DeveloperData + + +@babel.localeselector +def get_locale(): + return request.accept_languages.best_match(LANGUAGES.keys()) + + +@app.before_request +def before_request(): + g.locale = get_locale() + + +@app.route('/') +def index(): + form = DeveloperData() + # TODO: replicate behavior of + # debianmemberportfolio.controllers.portfolio.PortfolioController.index + return render_template('showform.html', form=form) + + +@app.route('/result') +def urllist(): + form = DeveloperData(request.values) + if form.validate(): + return render_template('showurls.html') + return render_template('showform.html', form=form) + + +@app.route('/htmlformhelper.js') +def formhelper_js(): + response = make_response(render_template('showformscript.js')) + response.headers['Content-Type'] = 'text/javascript; charset=utf-8' + return response + + +@app.route('/showformscripts/fetchdddata/') +def fetchdddata(): + return 'dddata' diff --git a/run.py b/run.py new file mode 100755 index 0000000..715fe63 --- /dev/null +++ b/run.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python2 +from debianmemberportfolio import app + +if __name__ == '__main__': + app.debug = True + app.run()