source: indico/indico/web/http_api/export.py @ f3a845

hello-world-walkthroughipv6v0.98-seriesv0.98.2v0.98.3v0.98b2v0.99v1.0v1.1
Last change on this file since f3a845 was f3a845, checked in by Jose Benito <jose.benito.gonzalez@…>, 21 months ago

[FTR] HTTP API - First sketch

  • Just returns ids instead of events;
  • Property mode set to 100644
File size: 5.3 KB
Line 
1# -*- coding: utf-8 -*-
2##
3##
4## This file is part of CDS Indico.
5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 CERN.
6##
7## CDS Indico is free software; you can redistribute it and/or
8## modify it under the terms of the GNU General Public License as
9## published by the Free Software Foundation; either version 2 of the
10## License, or (at your option) any later version.
11##
12## CDS Indico is distributed in the hope that it will be useful, but
13## WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15## General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20
21"""
22Main export interface
23"""
24
25# python stdlib imports
26import re
27from zope.interface import Interface, implements
28from datetime import datetime, timedelta, date, time
29
30# external lib imports
31import pytz
32from simplejson import dumps
33
34# indico imports
35from indico.util.date_time import nowutc
36
37# indico legacy imports
38from MaKaC.common.indexes import IndexesHolder
39from MaKaC.common.info import HelperMaKaCInfo
40
41
42class ArgumentParseError(Exception):
43    pass
44
45class ArgumentValueError(Exception):
46    pass
47
48class IExport(Interface):
49
50    def category(cls, idlist, dformat, fromDT, toDT, location=None, limit=None,
51               orderBy=None, descending=False, detail="events"):
52        """
53        TODO: Document this
54        """
55
56    def event(cls, idlist, dformat, orderBy=None, descending=False, detail="events"):
57        """
58        TODO: Document this
59        """
60
61
62class ExportInterface(object):
63    implements(IExport)
64
65    _deltas =  {'yesterday': timedelta(-1),
66                'tomorrow': timedelta(1)}
67
68    def __init__(self, dbi):
69        self._dbi = dbi
70
71    @classmethod
72    def _parseDateTime(cls, dateTime):
73        """
74        Accepted formats:
75         * ISO 8601 subset - YYYY-MM-DD[THH:MM]
76         * 'today', 'yesterday', 'tomorrow' and 'now'
77         * days in the future/past: '[+/-]DdHHhMMm'
78
79         'ctx' means that the date will change according to its function
80         ('from' or 'to')
81        """
82
83        # if it's a an "alias", return immediately
84        now = nowutc()
85        if dateTime in cls._deltas:
86            return ('ctx', now + cls._deltas[dateTime])
87        elif dateTime == 'now':
88            return ('abs', now)
89        elif dateTime == 'today':
90            return ('ctx', now)
91
92        m = re.match(r'^(?:(\d{1,3})d)?(?:(\d{1,2})h)?(?:(\d{1,2})m)?$', dateTime)
93        if m:
94            atoms = list(0 if a == None else int(a) for a in m.groups())
95
96
97
98            if atoms[1] > 23  or atoms[2] > 59:
99                raise ArgumentParseError("Invalid time!")
100            return ('ctx', timedelta(days=atoms[0], hours=atoms[1], minutes=atoms[2]))
101        else:
102            # iso 8601 subset
103            try:
104                return ('abs', datetime.strptime(dateTime, "%Y-%m-%dT%H:%M"))
105            except ValueError:
106                pass
107            try:
108                return ('ctx', datetime.strptime(dateTime, "%Y-%m-%d"))
109            except ValueError:
110                raise ArgumentParseError("Impossible to parse '%s'" % dateTime)
111
112    @classmethod
113    def _getDateTime(cls, ctx, dateTime, tz, aux=None):
114
115        rel, value = cls._parseDateTime(dateTime)
116
117        if rel == 'abs':
118            return tz.localize(value)
119        elif rel == 'ctx' and type(value) == timedelta:
120            if ctx == 'from':
121                raise ArgumentValueError("Only 'to' accepts relative times")
122            else:
123                value = aux + value
124
125        # from here on, 'value' has to be a datetime
126        if ctx == 'from':
127            return tz.localize(value.combine(value.date(), time(0, 0, 0)))
128        else:
129            return tz.localize(value.combine(value.date(), time(23, 59, 59)))
130
131    def category(self, idlist, dformat, fromDT, toDT, location=None, limit=None,
132                 orderBy=None, descending=False, detail="events", tz=None):
133
134        self._dbi.startRequest()
135
136        if tz == None:
137            info = HelperMaKaCInfo.getMaKaCInfoInstance()
138            tz = pytz.timezone(info.getTimezone())
139
140        fromDT = ExportInterface._getDateTime('from', fromDT, tz) if fromDT != None else None
141        toDT = ExportInterface._getDateTime('to', toDT, tz, aux=fromDT) if toDT != None else None
142
143        idx = IndexesHolder().getById('categoryDate')
144
145        results = []
146        counter = 0
147        terminate = False
148        # this set acts as a checklist to know if a record has already been sent
149        exclude = set()
150
151        for catId in idlist:
152            for obj in idx.iterateObjectsIn(catId, fromDT, toDT):
153                # TODO: hard limit
154                if limit and counter >= limit:
155                    terminate = True
156                    break
157                if obj not in exclude:
158                    results.append(obj.id)
159                    exclude.add(obj)
160                    counter += 1
161            if terminate:
162                break
163
164        self._dbi.endRequest(False)
165
166        return dumps(results)
167
168    def event(self, idlist, dformat, orderBy=None, descending=False, detail="events"):
169        """
170        TODO: Document this
171        """
Note: See TracBrowser for help on using the repository browser.