forked from jan/debianmemberportfolio
Add initial Flask implementation
This commit is contained in:
parent
7c60ac59a6
commit
f63939cb03
8 changed files with 312 additions and 1 deletions
12
config.py
Normal file
12
config.py
Normal file
|
@ -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)'
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
#
|
#
|
||||||
# Debian Member Portfolio Service package
|
# Debian Member Portfolio Service package
|
||||||
#
|
#
|
||||||
# Copyright © 2009-2014 Jan Dittberner <jan@dittberner.info>
|
# Copyright © 2009-2015 Jan Dittberner <jan@dittberner.info>
|
||||||
#
|
#
|
||||||
# This file is part of the Debian Member Portfolio Service.
|
# 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
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
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
|
||||||
|
|
35
debianmemberportfolio/forms.py
Normal file
35
debianmemberportfolio/forms.py
Normal file
|
@ -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()])
|
48
debianmemberportfolio/templates/base.html
Normal file
48
debianmemberportfolio/templates/base.html
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
{# vim: ft=jinja
|
||||||
|
Base template for XHTML templates.
|
||||||
|
Copyright © 2009-2015 Jan Dittberner <jan@dittberner.info>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
#}
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{% block title %}{{ _('Debian Member Portfolio Service') }}{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='stylesheets/style.css') }}" />
|
||||||
|
{% block extrahead %}{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<img alt="{{ _('Debian Logo') }}" id="debianlogo" src="{{ url_for('static', filename='images/openlogo-100.jpg') }}" height="100" width="100" />
|
||||||
|
<h1>{{ _('Debian Member Portfolio Service') }}</h1>
|
||||||
|
<p>{% trans %}This service has been inspired by Stefano Zacchiroli's <a href="https://wiki.debian.org/DDPortfolio">DDPortfolio page in the Debian Wiki</a>. You can create a set of customized links leading to a Debian Member's or package maintainer's information regarding Debian.{% endtrans %}</p>
|
||||||
|
<p><a class="FlattrButton" style="display:none" title="Debian Member Portfolio Service" href="{{ request.scheme }}://portfolio.debian.net/">Debian Member Portfolio Service</a></p>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div id="footer">
|
||||||
|
<img alt="{{ _('AGPL - Free Software') }}" id="agpllogo" src="{{ url_for('static', filename='images/agplv3-88x31.png') }}" width="88" height="31" />
|
||||||
|
<p>{% trans browseurl='http://debianstuff.dittberner.info/gitweb/?p=debianmemberportfolio.git;a=summary', cloneurl='http://debianstuff.dittberner.info/git/debianmemberportfolio.git', transifexurl='https://www.transifex.com/projects/p/debportfolioservice/' %}The service is available under the terms of the <a href="https://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. You can <a href="{{ browseurl }}" title="Gitweb repository browser URL">browse the source code</a> or clone it from <a href="{{ cloneurl }}" title="git clone URL">{{ cloneurl }}</a> using <a href="http://git-scm.com/">git</a>. If you want to translate this service to your language you can contribute at <a href="{{ transifexurl }}" title="Debian Member Portfolio Service at Transifex">Transifex</a>.{% endtrans %}</p>
|
||||||
|
<p>{{ _('Copyright © 2009-2015 Jan Dittberner') }}</p>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var flattr_url = '{{ request.scheme }}://portfolio.debian.net/';
|
||||||
|
</script>
|
||||||
|
<script src="{{ request.scheme }}://api.flattr.com/js/0.6/load.js?mode=auto&button=compact" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
40
debianmemberportfolio/templates/showform.html
Normal file
40
debianmemberportfolio/templates/showform.html
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{#
|
||||||
|
Template for the data input form.
|
||||||
|
|
||||||
|
Copyright © 2009-2015 Jan Dittberner <jan@dittberner.info>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
#}
|
||||||
|
{% block title %}{{ super()}} - {{ _('Enter your personal information') }}{% endblock %}
|
||||||
|
{% block extrahead %}{{ super() }}<script type="text/javascript" src="{{ url_for('static', filename='javascript/jquery/jquery.js') }}"></script>
|
||||||
|
<script type="text/javascript" src="{{ url_for('formhelper_js') }}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
{% block body %}{{ super() }}
|
||||||
|
<form action="{{ url_for('urllist') }}" method="get">
|
||||||
|
<fieldset id="portfolio">
|
||||||
|
<legend>{{ _('Debian Member Portfolio') }}</legend>
|
||||||
|
<div id="emailfield"{% if form.email.errors %} class="witherrors"{% endif %}>
|
||||||
|
<label for="email">{{ _('Email address:') }}
|
||||||
|
{% if form.email.errors %}<br />
|
||||||
|
<span class="errormsg">{{ form.email.errors|join(', ') }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</label><br />
|
||||||
|
{{ form.email }}<br />
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
119
debianmemberportfolio/templates/showformscript.js
Normal file
119
debianmemberportfolio/templates/showformscript.js
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
{# vim: ft=jinja
|
||||||
|
Helper JavaScript for the data input form.
|
||||||
|
Copyright © 2009, 2010, 2015 Jan Dittberner <jan@dittberner.info>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
#}
|
||||||
|
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();
|
||||||
|
});
|
42
debianmemberportfolio/views.py
Normal file
42
debianmemberportfolio/views.py
Normal file
|
@ -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'
|
6
run.py
Executable file
6
run.py
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
from debianmemberportfolio import app
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.debug = True
|
||||||
|
app.run()
|
Loading…
Reference in a new issue