sub.connect('register', '/account/register', action='register')
sub.connect('register_finish', '/account/register_finish', action='register_finish', **require_POST)
- # with map.submapper()
- map.connect('/users', controller='users', action='list')
- map.connect('user_page', '/users/{name}', controller='users', action='view')
+ # Specific user stuff
+ with map.submapper(controller='users') as sub:
+ sub.connect( '/users', action='list')
+ sub.connect('user_page', '/users/{name}', action='view')
+ with map.submapper(controller='user_settings') as sub:
+ sub.connect( '/users/{name}/settings/relationships/toggle',
+ action='rel_toggle', **require_POST)
# Comments
with map.submapper(controller='comments') as sub:
--- /dev/null
+import logging
+
+import elixir
+from pylons import request, response, session, tmpl_context as c
+from pylons.controllers.util import abort, redirect_to
+from sqlalchemy import func
+from sqlalchemy.orm.exc import NoResultFound
+
+import floof.lib.helpers as h
+from floof.lib.base import BaseController, render
+from floof.model.users import User, UserRelationship
+from floof.model.forms import UserRelationshipToggleForm
+
+log = logging.getLogger(__name__)
+
+class UserSettingsController(BaseController):
+
+ def rel_toggle(self, name):
+ """Adds or removes a single relationship with a single user.
+
+ Expects to be called as a POST with `target_user_id`,
+ `type`, and `add_remove` as parameters.
+ """
+ try:
+ user = User.query.filter(func.lower(User.name) == name).one()
+ except NoResultFound:
+ abort(404)
+
+ schema = UserRelationshipToggleForm()
+ try:
+ form_result = schema.to_python(request.params)
+ except BaseException, e:
+ # The data for this form is generated entirely by the app. If
+ # there are errors, the user has been dicking around.
+ abort(400)
+
+ # Grab any existing relationship row
+ rel = None
+ try:
+ rel = UserRelationship.query.filter_by(
+ user_id=user.id,
+ target_user_id=form_result['target_user'].id,
+ type=form_result['type'],
+ ).one()
+ except:
+ pass
+
+ # XXX shouldn't include "watching"...
+ target_name = form_result['target_user'].name
+ if form_result['add_remove'] == u'add':
+ # Adding
+ if rel:
+ # Already exists! Nothing to do.
+ h.flash("You're already watching {name}..."
+ .format(name=target_name))
+ else:
+ # Add it
+ UserRelationship(
+ user_id=user.id,
+ target_user_id=form_result['target_user'].id,
+ type=form_result['type'],
+ )
+ h.flash("Now watching {name}."
+ .format(name=target_name))
+ else:
+ # Removing
+ if rel:
+ # Toss it
+ rel.delete()
+ h.flash("No longer watching {name}. How cruel!."
+ .format(name=target_name))
+ else:
+ # Already gone! Nothing to do.
+ h.flash("You're not watching {name}..."
+ .format(name=target_name))
+
+ elixir.session.commit()
+
+ self.redirect_to_referrer()
from sqlalchemy.orm.exc import NoResultFound
from floof.lib.base import BaseController, render
-from floof.model.users import User
+from floof.model.users import User, UserRelationship
log = logging.getLogger(__name__)
except NoResultFound:
abort(404)
+ rels = UserRelationship.query.filter_by(
+ user_id=c.user.id,
+ target_user_id=c.this_user.id,
+ ).all()
+
+ c.relationships = [_.type for _ in rels]
+
return render('/users/view.mako')
Provides the BaseController class for subclassing.
"""
from pylons.controllers import WSGIController
+from pylons.controllers.util import abort, redirect
from pylons.templating import render_mako as render
-from pylons import config, session, tmpl_context as c
+from pylons import config, request, session, tmpl_context as c
from routes import request_config
from floof import model
return WSGIController.__call__(self, environ, start_response)
finally:
model.Session.remove()
+
+
+ def redirect_to_referrer(self):
+ """Performs a redirect_to to wherever we came from. Used for stuff
+ like logging in.
+ """
+ referrer = request.headers.get('REFERER', '/')
+ redirect(referrer, code=302)
--- /dev/null
+"""FormEncode validators."""
+
+import formencode
+
+from floof.model.users import User, UserRelationshipTypes
+
+class UniqueExistingRow(formencode.FancyValidator):
+ """Given a column object, converts a unique value from that column into the
+ corresponding row object.
+ """
+ def __init__(self, table, column):
+ self.table = table
+ self.column = column
+ super(formencode.FancyValidator, self).__init__()
+
+ def _to_python(self, value, state):
+ try:
+ row = self.table.query.filter(self.column == value).one()
+ except BaseException, e:
+ raise formencode.Invalid(
+ 'No unique row.',
+ value, state
+ )
+ return row
+
+### user_settings
+
+class UserRelationshipToggleForm(formencode.Schema):
+ target_user = UniqueExistingRow(User, User.id)
+ type = formencode.compound.Pipe(
+ formencode.validators.Int(),
+ formencode.validators.OneOf(
+ [v for (k, v) in UserRelationshipTypes.__dict__.items()
+ if k[0] != '_']
+ ),
+ )
+ add_remove = formencode.validators.OneOf([u'add', u'remove'])
## | <a href="${h.url_for("/users/"+c.user}">Your Page</a>
% endif
-${h.form(h.url_for('search'), method='GET')}
+${h.form(url('search'), method='GET')}
${h.text('query', c.query)}
${h.submit('button', 'Search')}
<p>This is the userpage for ${c.this_user.name}.</p>
+<%! from floof.model.users import UserRelationshipTypes %>
+% if c.this_user == c.user:
+## Nothing
+<% pass %>\
+% else:
+${h.form(url(controller='user_settings', action='rel_toggle', name=c.user.name.lower()), method='POST')}
+<p>
+ <input type="hidden" name="target_user" value="${c.this_user.id}">
+ <input type="hidden" name="type" value="${UserRelationshipTypes.IS_WATCHING}">
+ % if UserRelationshipTypes.IS_WATCHING in c.relationships:
+ <input type="hidden" name="add_remove" value="remove">
+ <input type="submit" value="Unwatch">
+ % else:
+ <input type="hidden" name="add_remove" value="add">
+ <input type="submit" value="Watch">
+ % endif
+% endif
+
% for gallery in c.this_user.primary_page.galleries:
<h2>${gallery.string}</h2>
${macros.thumbs(gallery.search.results)}
-% endfor
\ No newline at end of file
+% endfor
--- /dev/null
+from floof.tests import *
+
+class TestUserSettingsController(TestController):
+
+ def test_index(self):
+ response = self.app.get(url(controller='user_settings', action='index'))
+ # Test response...