4afb9cd95da2f5b6568733b5a21b150bf7a3fc81
[zzz-spline-users.git] / spline / plugins / users / controllers / users.py
1 import logging
2 import unicodedata
3
4 from wtforms import Form, ValidationError, fields, validators, widgets
5
6 from pylons import config, request, response, session, tmpl_context as c, url
7 from pylons.controllers.util import abort, redirect_to
8 from routes import request_config
9 from sqlalchemy.orm.exc import NoResultFound
10
11 from spline import model
12 from spline.model import meta
13 from spline.lib import helpers as h
14 from spline.lib.base import BaseController, render
15
16 log = logging.getLogger(__name__)
17
18
19 class ProfileEditForm(Form):
20 name = fields.TextField(u'Display name', [validators.Required()])
21
22 def validate_name(form, field):
23 if not 1 < len(field.data) <= 20:
24 raise ValidationError("Name can't be longer than 20 characters")
25
26 any_real_characters = False
27 for char in field.data:
28 cat = unicodedata.category(char)
29
30 # Non-spacing marks and spaces don't count as letters
31 if cat not in ('Mn', 'Zs'):
32 any_real_characters = True
33
34 # Disallow control characters, format characters, non-assigned,
35 # private use, surrogates, spacing-combining marks (for Arabic,
36 # etc), enclosing marks (millions sign), line-spacing,
37 # paragraph-spacing.
38 # This also, thankfully, includes the RTL characters.
39 if cat in ('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Mc', 'Me', 'Zl', 'Zp'):
40 raise ValidationError("Please don't play stupid Unicode tricks")
41
42 class UsersController(BaseController):
43
44 def list(self):
45 c.users = meta.Session.query(model.User).order_by(model.User.id.asc())
46 return render('/users/list.mako')
47
48 def profile(self, id, name=None):
49 """Main user profile.
50
51 URL is /users/id:name, where 'name' only exists for readability and is
52 entirely optional and ignored.
53 """
54
55 c.page_user = meta.Session.query(model.User).get(id)
56 if not c.page_user:
57 abort(404)
58
59 return render('/users/profile.mako')
60
61 def profile_edit(self, id, name=None):
62 """Main user profile editing."""
63 c.page_user = meta.Session.query(model.User).get(id)
64 if not c.page_user:
65 abort(404)
66
67 # XXX could use some real permissions
68 if c.page_user != c.user:
69 abort(403)
70
71 c.form = ProfileEditForm(request.params,
72 name=c.page_user.name,
73 )
74
75 if request.method != 'POST' or not c.form.validate():
76 return render('/users/profile_edit.mako')
77
78
79 c.page_user.name = c.form.name.data
80
81 meta.Session.add(c.page_user)
82 meta.Session.commit()
83
84 h.flash('Saved your profile.', icon='tick')
85
86 redirect_to(controller='users', action='profile',
87 id=c.page_user.id, name=c.page_user.name,
88 _code=303)