1 # Copyright (C) 2013 W. Trevor King <wking@tremily.us>
3 # This file is part of pycalender.
5 # pycalender is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free Software
7 # Foundation, either version 3 of the License, or (at your option) any later
10 # pycalender is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License along with
15 # pycalender. If not, see <http://www.gnu.org/licenses/>.
17 from . import text as _text
20 class Aggregator (list):
21 r"""An iCalendar feed aggregator
23 Figure out where the example feeds are located, relative to the
24 directory from which you run this doctest (i.e., the project's
28 >>> root_dir = os.curdir
29 >>> data_dir = os.path.abspath(os.path.join(root_dir, 'test', 'data'))
30 >>> base_url = 'file://{}'.format(data_dir.replace(os.sep, '/'))
32 >>> from .feed import Feed
34 You can set processing hooks to analyze and manipulate feeds as
37 >>> processors = [lambda feed: print("I'm processing {!r}".format(feed))]
40 ... prodid='-//pycalendar//NONSGML testing//EN',
42 ... Feed(url='{}/{}'.format(base_url, name))
43 ... for name in ['geohash.ics',]],
44 ... processors=processors,
46 >>> a # doctest: +ELLIPSIS
47 [<Feed url:file://.../test/data/geohash.ics>]
48 >>> a.fetch() # doctest: +ELLIPSIS
49 I'm processing <Feed url:file://.../test/data/geohash.ics>
51 Generate aggregate calendars with the ``.write`` method.
54 >>> stream = io.StringIO()
55 >>> a.write(stream=stream)
56 >>> value = stream.getvalue()
57 >>> value # doctest: +ELLIPSIS
58 'BEGIN:VCALENDAR\r\nVERSION:2.0\r\n...END:VCALENDAR\r\n'
59 >>> print(value.replace('\r\n', '\n'))
62 PRODID:-//pycalendar//NONSGML testing//EN
64 UID:2013-06-30@geohash.invalid
65 DTSTAMP:20130630T000000Z
66 DTSTART;VALUE=DATE:20130630
67 DTEND;VALUE=DATE:20130701
68 SUMMARY:XKCD geohashing\, Boston graticule
69 URL:http://xkcd.com/426/
70 LOCATION:Snow Hill\, Dover\, Massachusetts
71 GEO:42.226663;-71.28676
76 def __init__(self, prodid, version='2.0', feeds=None, processors=None):
77 super(Aggregator, self).__init__()
79 self.version = version
84 self.processors = processors
89 for processor in self.processors:
92 def write(self, stream):
93 stream.write('BEGIN:VCALENDAR\r\n')
94 stream.write('VERSION:{}\r\n'.format(_text.escape(self.version)))
95 stream.write('PRODID:{}\r\n'.format(_text.escape(self.prodid)))
103 for entry in feed.get(key, []):
104 entry.write(stream=stream)
105 stream.write('END:VCALENDAR\r\n')