diff --git a/ddportfolioservice/config/routing.py b/ddportfolioservice/config/routing.py index 6d6dfb6..3d116d4 100644 --- a/ddportfolioservice/config/routing.py +++ b/ddportfolioservice/config/routing.py @@ -41,6 +41,8 @@ def make_map(): # CUSTOM ROUTES HERE map.connect('', controller='ddportfolio', action='index') map.connect('result', controller='ddportfolio', action='urllist') + map.connect('htmlformhelper.js', controller='showformscripts', + action='index') map.connect(':controller/:action/:id') map.connect('*url', controller='template', action='view') diff --git a/ddportfolioservice/controllers/showformscripts.py b/ddportfolioservice/controllers/showformscripts.py index 7664345..72a0aeb 100644 --- a/ddportfolioservice/controllers/showformscripts.py +++ b/ddportfolioservice/controllers/showformscripts.py @@ -1,13 +1,69 @@ +# -*- python -*- +# -*- coding: utf-8 -*- +# +# DDPortfolio service ShowformscriptController. +# Copyright (c) 2009 Jan Dittberner <jan@dittberner.info> +# +# This file is part of DDPortfolio service. +# +# DDPortfolio 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. +# +# DDPortfolio 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 +# <http://www.gnu.org/licenses/>. +# import logging +import simplejson from ddportfolioservice.lib.base import * +from ddportfolioservice.model.form import * +from ddportfolioservice.model import keyfinder +from webob.exc import HTTPBadRequest log = logging.getLogger(__name__) class ShowformscriptsController(BaseController): + """This controller is used to support data entry in showform. + + It provides code for generating JavaScript as well as JSON + responses for autocompletion of fields.""" def index(self): - # Return a rendered template - # return render('/some/template.mako') - # or, Return a response - return 'Hello World' + """This action generates the helper script for the showform + page.""" + response.headers['Content-Type'] = 'text/javascript' + return render('/showformscript.mako') + + def fetchdddata(self): + schema = DDDataRequest() + try: + formencode.api.set_stdtranslation( + domain="FormEncode", + languages=[lang[0:2] for lang in request.languages]) + form_result = schema.to_python(request.params) + except formencode.validators.Invalid, error: + errors = error.unpack_errors() + abort(400, "\n".join( + ["%s: %s" % (key, errors[key]) for key in errors])) + + fields = dict([(field, func(str(form_result['email']))) \ + for (field, func) in \ + [('gpgfp', keyfinder.getFingerprintByEmail), + ('name', keyfinder.getRealnameByEmail), + ('username', keyfinder.getLoginByEmail)]]) + fields['email'] = form_result['email'] + if fields['username'] and fields['gpgfp'] and fields['name']: + fields['isdd'] = 1 + else: + fields['isdd'] = 0 + log.debug(fields) + response.headers['Content-Type'] = 'text/plain' + return simplejson.dumps(fields) diff --git a/ddportfolioservice/model/form.py b/ddportfolioservice/model/form.py index b8f39ed..b097c45 100644 --- a/ddportfolioservice/model/form.py +++ b/ddportfolioservice/model/form.py @@ -29,9 +29,14 @@ class DeveloperData(formencode.Schema): email = formencode.validators.Email(not_empty=True) name = formencode.validators.String(not_empty=True) gpgfp = formencode.All(formencode.validators.PlainText(), - formencode.validators.MinLength(32), - formencode.validators.MaxLength(32)) + formencode.validators.MinLength(40), + formencode.validators.MaxLength(40)) username = formencode.validators.PlainText() nonddemail = formencode.validators.Email() aliothusername = formencode.validators.PlainText() mode = formencode.validators.OneOf([u'json', u'html'], not_empty=True) + +class DDDataRequest(formencode.Schema): + """Validation schema for DDData request.""" + allow_extra_fields = False + email = formencode.validators.Email(not_empty=True) diff --git a/ddportfolioservice/templates/base.mako b/ddportfolioservice/templates/base.mako index d209ec6..c01b4a0 100644 --- a/ddportfolioservice/templates/base.mako +++ b/ddportfolioservice/templates/base.mako @@ -1,7 +1,7 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <%doc> -Template for the data input form. +Base template for XHTML templates. Copyright (c) 2009 Jan Dittberner <jan@dittberner.info> This file is part of DDPortfolio service. diff --git a/ddportfolioservice/templates/showform.mako b/ddportfolioservice/templates/showform.mako index fa37508..a520ae1 100644 --- a/ddportfolioservice/templates/showform.mako +++ b/ddportfolioservice/templates/showform.mako @@ -22,11 +22,17 @@ License along with this program. If not, see <%def name="titleaddon()"> - ${_('Enter your personal information')} </%def> -<%def name="extrahead()">${h.javascript_link('/javascript/jquery/jquery.js')}</%def> +<%def name="extrahead()">${h.javascript_link('/javascript/jquery/jquery.js', +h.url_for(controller='showformscripts', +action='index'))}</%def> ${h.form(h.url_for(action='urllist'), method='get')} <fieldset id="ddportfolio"> <legend>${_('Debian Developer Portfolio')}</legend> - <div id="emailfield"> + <div id="emailfield" \ + % if 'email' in c.messages['errors']: + class="witherrors" \ + % endif + > <label for="email">${_('Email address:')} % if 'email' in c.messages['errors']: <br /> @@ -35,7 +41,11 @@ ${h.form(h.url_for(action='urllist'), method='get')} </label><br /> ${h.text('email', request.params.get('email', None), id='email')}<br /> </div> - <div id="namefield"> + <div id="namefield" \ + % if 'name' in c.messages['errors']: + class="witherrors" \ + % endif + > <label for="name">${_('Name:')} % if 'name' in c.messages['errors']: <br /> @@ -54,7 +64,11 @@ ${h.form(h.url_for(action='urllist'), method='get')} ${h.text('gpgfp', request.params.get('gpgfp', None), id='gpgfp', readonly='readonly')}<br /> </div> - <div id="usernamefield"> + <div id="usernamefield" \ + % if 'username' in c.messages['errors']: + class="witherrors" \ + % endif + > <label for="username">${_('Debian user name:')} % if 'username' in c.messages['errors']: <br /> @@ -64,7 +78,11 @@ ${h.form(h.url_for(action='urllist'), method='get')} ${h.text('username', request.params.get('username', None), id='username')}<br /> </div> - <div id="nonddemailfield"> + <div id="nonddemailfield" \ + % if 'nonddemail' in c.messages['errors']: + class="witherrors" \ + % endif + > <label for="nonddemail">${_('Non DD email address:')} % if 'nonddemail' in c.messages['errors']: <br /> @@ -74,7 +92,11 @@ ${h.form(h.url_for(action='urllist'), method='get')} ${h.text('nonddemail', request.params.get('nonddemail', None), id='nonddemail')}<br /> </div> - <div id="aliothusernamefield"> + <div id="aliothusernamefield" \ + % if 'aliothusername' in c.messages['errors']: + class="witherrors" + % endif + > <label for="aliothusername">${_('Alioth user name:')} % if 'aliothusername' in c.messages['errors']: <br /> diff --git a/ddportfolioservice/templates/showformscript.mako b/ddportfolioservice/templates/showformscript.mako new file mode 100644 index 0000000..b951a78 --- /dev/null +++ b/ddportfolioservice/templates/showformscript.mako @@ -0,0 +1,78 @@ +## -*- coding: utf-8 -*- +<%doc> +Helper JavaScript for the data input form. +Copyright (c) 2009 Jan Dittberner <jan@dittberner.info> + +This file is part of DDPortfolio service. + +DDPortfolio 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. + +DDPortfolio 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 +<http://www.gnu.org/licenses/>. +</%doc> + +function updateFields(data, textStatus) { + if (data.isdd == 1) { + $('#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); + + $('#namefield').show(); + $('#gpgfpfield').show(); + $('#usernamefield').show(); + $('#nonddemailfield').show(); + $('#aliothusernamefield').show(); + + $('#nonddemail').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(); + + $('#name').focus().select(); + } +} + +function onBlurEmail() { + $.ajax({ + 'url' : '${h.url_for(action='fetchdddata')}', + 'data' : {'email' : $('#email').attr('value')}, + 'dataType' : 'json', + 'success' : updateFields, + 'error' : function(request, textStatus, errorThrown) { + $('#email').focus(); + } + }); +} + +$(document).ready(function() { + var fields = new Array( + '#namefield', '#usernamefield', + '#nonddemailfield', '#aliothusernamefield'); + for (var index in fields) { + if (!$(fields[index]).hasClass('witherrors')) { + $(fields[index]).hide(); + } + } + + $('#email').blur(onBlurEmail).focus(); +});