imip-agent

imipweb/resource.py

763:3ee9193569d8
2015-09-24 Paul Boddie Removed separate viewing of counter-proposals (which will be shown as part of the event view). imipweb-client-simplification
     1 #!/usr/bin/env python     2      3 """     4 Common resource functionality for Web calendar clients.     5      6 Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20 """    21     22 from datetime import datetime    23 from imiptools.client import Client, ClientForObject    24 from imiptools.data import get_uri, uri_values    25 from imiptools.dates import get_recurrence_start_point    26 from imiptools.period import remove_period, remove_affected_period    27 from imipweb.env import CGIEnvironment    28 import babel.dates    29 import imip_store    30 import markup    31     32 class Resource:    33     34     "A Web application resource."    35     36     def __init__(self, resource=None):    37     38         """    39         Initialise a resource, allowing it to share the environment of any given    40         existing 'resource'.    41         """    42     43         self.encoding = "utf-8"    44         self.env = CGIEnvironment(self.encoding)    45     46         self.objects = {}    47         self.locale = None    48         self.requests = None    49     50         self.out = resource and resource.out or self.env.get_output()    51         self.page = resource and resource.page or markup.page()    52         self.html_ids = None    53     54     # Presentation methods.    55     56     def new_page(self, title):    57         self.page.init(title=title, charset=self.encoding, css=self.env.new_url("styles.css"))    58         self.html_ids = set()    59     60     def status(self, code, message):    61         self.header("Status", "%s %s" % (code, message))    62     63     def header(self, header, value):    64         print >>self.out, "%s: %s" % (header, value)    65     66     def no_user(self):    67         self.status(403, "Forbidden")    68         self.new_page(title="Forbidden")    69         self.page.p("You are not logged in and thus cannot access scheduling requests.")    70     71     def no_page(self):    72         self.status(404, "Not Found")    73         self.new_page(title="Not Found")    74         self.page.p("No page is provided at the given address.")    75     76     def redirect(self, url):    77         self.status(302, "Redirect")    78         self.header("Location", url)    79         self.new_page(title="Redirect")    80         self.page.p("Redirecting to: %s" % url)    81     82     def link_to(self, uid, recurrenceid=None):    83     84         """    85         Return a link to an object with the given 'uid' and 'recurrenceid'.    86         See get_identifiers for the decoding of such links.    87         """    88     89         path = [uid]    90         if recurrenceid:    91             path.append(recurrenceid)    92         return self.env.new_url("/".join(path))    93     94     # Control naming helpers.    95     96     def element_identifier(self, name, index=None):    97         return index is not None and "%s-%d" % (name, index) or name    98     99     def element_name(self, name, suffix, index=None):   100         return index is not None and "%s-%s" % (name, suffix) or name   101    102     def element_enable(self, index=None):   103         return index is not None and str(index) or "enable"   104    105     # Access to objects.   106    107     def get_identifiers(self, path_info):   108    109         """   110         Return identifiers provided by 'path_info', potentially encoded by   111         'link_to'.   112         """   113    114         parts = path_info.lstrip("/").split("/")   115    116         # UID only.   117    118         if len(parts) == 1:   119             return parts[0], None   120    121         # UID and RECURRENCE-ID.   122    123         else:   124             return parts[:2]   125    126     def _get_object(self, uid, recurrenceid=None, section=None):   127         if self.objects.has_key((uid, recurrenceid, section)):   128             return self.objects[(uid, recurrenceid, section)]   129    130         obj = self.objects[(uid, recurrenceid, section)] = self.get_stored_object(uid, recurrenceid, section)   131         return obj   132    133     def _get_recurrences(self, uid):   134         return self.store.get_recurrences(self.user, uid)   135    136     def _get_active_recurrences(self, uid):   137         return self.store.get_active_recurrences(self.user, uid)   138    139     def _get_requests(self):   140         if self.requests is None:   141             self.requests = self.store.get_requests(self.user)   142         return self.requests   143    144     def _have_request(self, uid, recurrenceid=None, type=None, strict=False):   145         return self.store.have_request(self._get_requests(), uid, recurrenceid, type, strict)   146    147     def _get_request_summary(self):   148    149         "Return a list of periods comprising the request summary."   150    151         summary = []   152    153         for uid, recurrenceid, request_type in self._get_requests():   154             obj = self.get_stored_object(uid, recurrenceid)   155             if obj:   156                 recurrenceids = self._get_active_recurrences(uid)   157    158                 # Obtain only active periods, not those replaced by redefined   159                 # recurrences, converting to free/busy periods.   160    161                 for p in obj.get_active_periods(recurrenceids, self.get_tzid(), self.get_window_end()):   162                     summary.append(obj.get_freebusy_period(p))   163    164         return summary   165    166     # Preference methods.   167    168     def get_user_locale(self):   169         if not self.locale:   170             self.locale = self.get_preferences().get("LANG", "en")   171         return self.locale   172    173     # Prettyprinting of dates and times.   174    175     def format_date(self, dt, format):   176         return self._format_datetime(babel.dates.format_date, dt, format)   177    178     def format_time(self, dt, format):   179         return self._format_datetime(babel.dates.format_time, dt, format)   180    181     def format_datetime(self, dt, format):   182         return self._format_datetime(   183             isinstance(dt, datetime) and babel.dates.format_datetime or babel.dates.format_date,   184             dt, format)   185    186     def _format_datetime(self, fn, dt, format):   187         return fn(dt, format=format, locale=self.get_user_locale())   188    189     # Data management methods.   190    191     def remove_request(self, uid, recurrenceid=None):   192         return self.store.dequeue_request(self.user, uid, recurrenceid)   193    194     def remove_event(self, uid, recurrenceid=None):   195         return self.store.remove_event(self.user, uid, recurrenceid)   196    197 class ResourceClient(Resource, Client):   198    199     "A Web application resource and calendar client."   200    201     def __init__(self, resource=None):   202         Resource.__init__(self, resource)   203         user = self.env.get_user()   204         Client.__init__(self, user and get_uri(user) or None)   205    206 class ResourceClientForObject(Resource, ClientForObject):   207    208     "A Web application resource and calendar client for a specific object."   209    210     def __init__(self, resource=None):   211         Resource.__init__(self, resource)   212         user = self.env.get_user()   213         ClientForObject.__init__(self, None, user and get_uri(user) or None)   214    215 # vim: tabstop=4 expandtab shiftwidth=4