# HG changeset patch # User Paul Boddie # Date 1445729129 -7200 # Node ID a348efd651846b5ee99a0dea6615bfe81cd55489 # Parent 9e88e5e276aa38b0e656cc6a0301a0c37990b83b Added initial support for viewing and eventually editing user preferences. diff -r 9e88e5e276aa -r a348efd65184 htdocs/styles.css --- a/htdocs/styles.css Sun Oct 25 01:24:56 2015 +0200 +++ b/htdocs/styles.css Sun Oct 25 01:25:29 2015 +0200 @@ -28,6 +28,7 @@ table.conflicts, table.counters, +table.profile, table.recurrence, table.object { border: 2px solid #000; @@ -55,7 +56,12 @@ width: 100%; } +table.profile th.mainheading { + background-color: #7bf; +} + th.timeslot, +th.profileheading, th.objectheading { white-space: nowrap; } @@ -64,6 +70,11 @@ background-color: #fca; } +th.profileheading { + background-color: #bef; + text-align: right; +} + th.timeslot { padding-top: 0; vertical-align: top; @@ -120,6 +131,7 @@ color: #009; } +th.profileheading.error, th.objectheading.error { background-color: #f77; } diff -r 9e88e5e276aa -r a348efd65184 imip_manager.py --- a/imip_manager.py Sun Oct 25 01:24:56 2015 +0200 +++ b/imip_manager.py Sun Oct 25 01:25:29 2015 +0200 @@ -29,6 +29,7 @@ from imipweb.calendar import CalendarPage from imipweb.event import EventPage +from imipweb.profile import ProfilePage from imipweb.resource import ResourceClient class Manager(ResourceClient): @@ -43,6 +44,8 @@ if not path_info: CalendarPage(self).show() + elif path_info == "profile": + ProfilePage(self).show() elif EventPage(self).show(path_info): pass else: diff -r 9e88e5e276aa -r a348efd65184 imipweb/profile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imipweb/profile.py Sun Oct 25 01:25:29 2015 +0200 @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +""" +A Web interface to the user profile. + +Copyright (C) 2015 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from imiptools import config +from imipweb.resource import ResourceClient + +class ProfilePage(ResourceClient): + + "A request handler for the user profile page." + + # See: imiptools.profile + + pref_labels = { + "CN" : "Common name", + "LANG" : "Language", + "TZID" : "Time zone/regime", + "add_method_response" : "Respond to messages adding events with...", + "event_refreshing" : "Handle event refresh requests automatically", + "freebusy_bundling" : "Bundle free/busy details with messages", + "freebusy_messages" : "Notify about received free/busy messages", + "freebusy_offers" : "Reserve time periods when making counter-proposals", + "freebusy_publishing" : "Publish free/busy details via the Web", + "freebusy_sharing" : "Share free/busy information at all", + "incoming" : "Incoming calendar messages presented using...", + "organiser_replacement" : "Recognise which kinds of participants as replacement organisers...", + "participating" : "Participate in the calendar system at all?", + "permitted_times" : None, + } + + def handle_request(self): + args = self.env.get_args() + save = args.has_key("save") + cancel = args.has_key("cancel") + action = save or cancel + + if not action: + return ["action"] + + return None + + # Output fragment methods. + + def show_preferences(self, errors=None): + page = self.page + + # Show the range of preferences, getting all possible entries and using + # configuration defaults. + + prefs = self.get_preferences() + items = prefs.items(True, None, True) + items.sort() + + page.table(class_="profile", cellspacing=5, cellpadding=5) + page.thead() + page.tr() + page.th("Preferences", class_="mainheading", colspan=2) + page.tr.close() + page.thead.close() + page.tbody() + + for name, value in items: + label = self.pref_labels.get(name) + if not label: + continue + + page.tr() + page.th(class_="profileheading %s%s" % (name, errors and name in errors and " error" or "")) + page.label(label) + page.th.close() + page.td() + page.input(name=name, value=(value or ""), type="text", class_="preference") + page.td.close() + page.tr.close() + + page.tbody.close() + page.table.close() + + # Full page output methods. + + def show(self): + + "Show the preferences of a user." + + errors = self.handle_request() + + if not errors: + return True + + self.new_page(title="Profile") + self.show_preferences(errors) + + return True + +# vim: tabstop=4 expandtab shiftwidth=4