Attachment 'eventcal-080.py'

Download

   1 """
   2     eventcal.py  Version 0.80  2005. 10. 31.
   3                                                                                                            
   4     This parser gives a parsed format of the event which will be shown at the EventCalendar macro.
   5                                                                                                            
   6     @copyright: 2005 by Seungik Lee <seungiklee<at>gmail.com>  http://cds.icu.ac.kr/~silee/
   7     @license: GPL
   8 
   9     Usage: 
  10         To insert an event, enclose the information about ONE event record with 'eventcal' parser.
  11         E.g., 
  12             {{{#!eventcal
  13                 = [Title] =
  14                 [Start Date] ... [End Date]
  15                 [Start Time] ... [End Time]
  16             }}}
  17         
  18             [Title] should be enclosed with heading marker ('='), double quatation mark ("), wiki italic or bold ('', ''')
  19                 Title can be omitted and it will be titled as 'No Title'
  20                 e.g., == Title ==, === Title ===, "Title", ''Title'', '''Title'''
  21             
  22             [Start|End Date] should be in YYYY/MM/DD or YYYY-MM-DD. End date can be omitted.
  23                 e.g, 2005/10/20, 2005-10-20
  24             
  25             [Start|End Time] should be in HH:MM in 24-hour format. Both of start|end Time can be omitted but not either of them.
  26                 e.g., 08:00, 12:00, 18:00
  27             
  28             In the parsing block of eventcal, it pops out first two date formatted text (startdate and enddate), 
  29             two time formatted text (starttime, endtime), and quoted or heading titie. 
  30             
  31             It ignores further occurrence of the targeted string. 
  32             The order of each fields (date, time, title) does not matter .
  33             The start date|time should precede the end date|time in the occurrence respectively.
  34 
  35         There is no input parameter yet.
  36 
  37     Features:
  38         Shows the event information in a parsed format.
  39         Validates the date, time format.
  40 
  41     Change Log:
  42         Oct. 31, 2005 - Version 0.80 
  43             - The initial version is released.
  44 
  45     To do list:
  46         Clean the ugly codes!!! (need help)
  47             raw html codes
  48         Date/time Format customization (e.g., 2005/10, Oct. 2005, 18:00, 06:00pm)
  49         Custom background color per event 
  50         Custom icon per event 
  51         More input parameters
  52         Parsing description field
  53 
  54     Notes:
  55         Much buggy.. :please report bugs and suggest your ideas.
  56         
  57     Usage Examples:
  58     
  59         {{{#!eventcal
  60         === Event Calendar Development === # title
  61          * Duration: 2005/10/20 ~ 2005/10/27 # startdate, enddate
  62          * It was very hard! # ignored
  63          * FYI, today's 2005/10/28 # ignored
  64         }}}
  65 
  66         {{{#!eventcal
  67         On 2005/10/10 20:00~22:00, we have "3rd Project meeting". Please don't miss it. # startdate, starttime, endtime, title
  68         }}}
  69         
  70         {{{#!eventcal
  71         '''My Business Trip'''  # title
  72          From 2005-10-02 to 2005/10/07. See you later~ # startdate, enddate
  73         }}}
  74         
  75         {{{#!eventcal
  76          Please come to my office on 2005-10-10. Thanks. # (title: 'No Title'), startdate
  77         }}}
  78 
  79 
  80 """
  81 
  82 import datetime, re, wiki
  83 import urllib
  84 from MoinMoin import config
  85 
  86 class Parser:
  87 
  88     def __init__(self, raw, request, **kw):
  89         self.lines = raw
  90         self.request = request
  91 
  92     def format(self, formatter):
  93         """ Send the "parsed" text.
  94         """
  95         
  96         self.formatter = formatter
  97         
  98         # need help on regular expressions for more efficient/flexible form
  99         regex_date = r'(\d{4}[/-]\d{2}[/-]\d{2})'
 100         regex_time = r'(\d{2}[:]\d{2})'
 101         # regex_title = r'["\'=-]+(\s*.*[^"\'=-]+)["\'=-]+'
 102         # regex_title = r'["]+ | [\']{2,5} | [=-]+ (\s*.*[^"\'=-]+) [=-]+ | ["]+ | [\']{2,5}'
 103         # regex_title = r'[=-]+|[\']{2,5}(\s*.*[^"\'=-]+)[=-]|[\']{2,5}'
 104         regex_title = r'["]+(\s*.*?)["]+|[\']{2,}(\s*.*?)[\']{2,}|[=]+(\s*.*?)[=]+'
 105         
 106         msg = ''
 107         title = ''
 108         startdate = ''
 109         enddate = ''
 110         starttime = ''
 111         endtime = ''
 112         
 113         lines = self.lines
 114         
 115         # retrieve date
 116         pattern = re.compile(regex_date, re.UNICODE + re.MULTILINE)
 117         
 118         match = pattern.findall(lines)
 119         
 120         if not len(match):
 121             msg = 'at least one date field should be specified'
 122             self.printoutput('Parse Error', msg, '', '', 0)
 123             return
 124         
 125         # (month, day)-only date should be handled later
 126         
 127         startdate = match[0]
 128         if len(match) > 1:
 129             enddate = match[1]
 130         
 131         # retrieve time
 132         pattern = re.compile(regex_time, re.UNICODE + re.MULTILINE)
 133         
 134         match = pattern.findall(lines)
 135         
 136         if len(match) >= 2:
 137             starttime = match[0]
 138             endtime = match[1]
 139         elif len(match) == 0:
 140             starttime = ''
 141             endtime = ''
 142         else:
 143             msg = 'no or 2 time field should be specified'
 144             self.printoutput('Parse Error', msg, '', '', 0)
 145             return
 146             
 147         # retrieve title
 148         pattern = re.compile(regex_title, re.UNICODE + re.MULTILINE + re.DOTALL)
 149         
 150         match = pattern.search(lines)
 151         
 152         if not match:
 153             title = 'No title'
 154         else:
 155             for item in match.groups():
 156                 if item:
 157                     title = item
 158                     break
 159         
 160         # if no enddate, it's 1-day event
 161         if (not enddate) and (starttime and endtime):
 162             enddate = startdate
 163         
 164        
 165         # check the validity of date/time
 166         try:
 167             syear, smonth, sday = getdatefield(startdate
 168 )
 169             if enddate:
 170                 eyear, emonth, eday = getdatefield(enddate
 171 )
 172         except:
 173             msg = 'invalid date format'
 174             self.printoutput('Parse Error', msg, '', '', 0)
 175             return
 176         
 177         if startdate and enddate:
 178             if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
 179                 msg = 'startdate should precede enddate'
 180                 self.printoutput('Parse Error', msg, '', '', 0)
 181                 return
 182 
 183         if starttime and endtime:
 184             try:
 185                 shour, smin = gettimefield(starttime
 186 )
 187                 ehour, emin = gettimefield(endtime
 188 )
 189             except:
 190                 msg = 'invalid time format'
 191                 self.printoutput('Parse Error', msg, '', '', 0)
 192                 return
 193         
 194             if startdate == enddate:
 195                 if datetime.time(shour, smin) > datetime.time(ehour, emin):
 196                     msg = 'starttime should precede endtime'
 197                     self.printoutput('Parse Error', msg, '', '', 0)
 198                     return
 199         
 200         # format output
 201         fromstring = '%s %s' % (startdate, starttime)
 202         if enddate:
 203             tostring = '%s %s' % (enddate, endtime)
 204         else:
 205             tostring = ''
 206         
 207         startdateforbookmark = u'%d%02d%02d' % (syear, smonth, sday)
 208         
 209         self.printoutput(title, fromstring, tostring, startdateforbookmark, 1)
 210     
 211     def printoutput(self, title, fromstring, tostring, startdateforbookmark, successflag):
 212         
 213         formatter = self.formatter
 214         lines = self.lines
 215         
 216         if startdateforbookmark:
 217             bookmark = u'%s%s' % (title.replace(' ', ''), startdateforbookmark)
 218             # bookmark = urllib.quote_plus(bookmark.encode(config.charset))
 219             html = u'<a name="%s"></a>' % bookmark
 220             self.request.write(formatter.rawHTML(html))
 221         
 222         html = [
 223             u'<table width="100%%" style="border-width:0px;"><tr><td width="100%%" style="border-width:0px; text-align: left; vertical-align: top;">',
 224             u'',
 225             ]
 226 
 227         html = u'\n'.join(html)
 228         self.request.write(formatter.rawHTML(html))
 229             
 230         wikiparser = wiki.Parser( lines, self.request )
 231         wikiparser.format( formatter )
 232         
 233         html = [
 234             u'</td>',
 235             u'<td style="border-width: 0px; padding: 0px; margin: 0px; border-top-width: 1px; width: 4px;">&nbsp;</td>',
 236             # u'<table width="100%%" height="100%%" style="padding: 0px; margin: 0px;">',
 237             # u'<tr><td colspan="2" width="2" style="border-width: 0px; background-color: #c0c0c0;">&nbsp;</td></tr>',
 238             # u'<tr><td width="1"></td><td width="1" style="line-height: 100%%; border-width: 0px; background-color: #c0c0c0;">&nbsp;</td></tr>',
 239             # u'<tr><td colspan="2" style="border-width: 0px; background-color: #c0c0c0;">&nbsp;</td></tr></table>',
 240             # u'<table width="100%%" style="border-width:0px;"><tr><td width="50%%" style="border-width:0px;">&nbsp;</td>',
 241             u'<td style="border-width:0px; border-left-width: 1px; text-align:right; vertical-align: bottom; padding: 0px; margin: 0px;"><table style="border-width:0px; align: right; padding: 0px; margin: 0px;">',
 242             u'<tr><td style="border-width:1px; border-left-width: 0px; line-height: 5px; padding: 0px; margin: 0px;" nowrap>',
 243             ]
 244 
 245         html = u'\n'.join(html)
 246         self.request.write(formatter.rawHTML(html))
 247         
 248         if tostring:
 249             fromto = '%s ~ %s' % (fromstring, tostring)
 250         else:
 251             fromto = '%s' % fromstring
 252         
 253         if successflag:
 254             flag = '(!)'
 255         else:
 256             flag = '{X}'
 257         
 258         wikiparser = wiki.Parser( '%s \'\'\'~-%s-~\'\'\' ~-%s-~' % (flag, title, fromto), self.request )
 259         wikiparser.format( formatter )
 260         
 261         html = [
 262             #u'  <font style="font-size: 8pt;">%s</font>' % msg,
 263             u'</td></tr></table></td></tr></table>',
 264             u'',
 265             ]
 266 
 267         html = u'\n'.join(html)
 268             
 269         self.request.write(formatter.rawHTML(html))
 270    
 271 
 272 def getdatefield(str_date):
 273     str_year = ''
 274     str_month = ''
 275     str_day = ''
 276     
 277     if len(str_date) == 6:
 278         # year+month
 279         str_year = str_date[:4]
 280         str_month = str_date[4:]
 281         str_day = '1'
 282 
 283     elif len(str_date) == 8:
 284         # year+month+day
 285         str_year = str_date[:4]
 286         str_month = str_date[4:6]
 287         str_day = str_date[6:]
 288     
 289     elif len(str_date) == 10:
 290         # year+?+month+?+day
 291         str_year = str_date[:4]
 292         str_month = str_date[5:7]
 293         str_day = str_date[8:]
 294     
 295     else:
 296         raise ValueError
 297     
 298     # It raises exception if the input date is incorrect
 299     temp = datetime.date(int(str_year), int(str_month), int(str_day))
 300 
 301     return temp.year, temp.month, temp.day
 302 
 303 
 304 def gettimefield(str_time):
 305     str_hour = ''
 306     str_min = ''
 307     
 308     if len(str_time) == 4:
 309         # hour+minute
 310         str_hour = str_time[:2]
 311         str_min = str_time[2:]
 312     
 313     elif len(str_time) == 5:
 314         # hour+?+minute
 315         str_hour = str_time[:2]
 316         str_min = str_time[3:]
 317         
 318     else:
 319         raise ValueError
 320     
 321     # It raises exception if the input date is incorrect
 322     temp = datetime.time(int(str_hour), int(str_min))
 323 
 324     return temp.hour, temp.minute

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-10-31 18:42:02, 65.4 KB) [[attachment:EventCalendar-080.py]]
  • [get | view] (2005-11-22 17:40:26, 55.4 KB) [[attachment:EventCalendar-090.py]]
  • [get | view] (2006-01-15 16:25:08, 57.2 KB) [[attachment:EventCalendar-091.py]]
  • [get | view] (2006-01-17 08:02:06, 75.4 KB) [[attachment:EventCalendar-092.py]]
  • [get | view] (2006-01-18 03:54:33, 75.6 KB) [[attachment:EventCalendar-093.py]]
  • [get | view] (2006-02-25 09:00:17, 74.8 KB) [[attachment:EventCalendar-094-easytime.py]]
  • [get | view] (2006-02-06 04:39:13, 76.2 KB) [[attachment:EventCalendar-094.py]]
  • [get | view] (2006-04-17 13:21:03, 122.7 KB) [[attachment:EventCalendar-096.py]]
  • [get | view] (2006-05-12 15:26:40, 150.6 KB) [[attachment:EventCalendar-098.py]]
  • [get | view] (2008-11-05 16:58:27, 3.2 KB) [[attachment:EventCalendar-099-01.py.patch]]
  • [get | view] (2006-05-23 09:50:33, 152.3 KB) [[attachment:EventCalendar-099.py]]
  • [get | view] (2008-02-14 05:18:57, 1.0 KB) [[attachment:EventCalendar-099.py.patch]]
  • [get | view] (2009-07-15 23:35:13, 151.1 KB) [[attachment:EventCalendar-099a.py]]
  • [get | view] (2013-01-21 02:05:25, 152.4 KB) [[attachment:EventCalendar-099b.py]]
  • [get | view] (2006-11-30 15:51:59, 1.8 KB) [[attachment:defaults-099-01.patch]]
  • [get | view] (2005-10-31 18:35:06, 5.0 KB) [[attachment:eventcal-080.css]]
  • [get | view] (2005-10-31 18:35:01, 11.3 KB) [[attachment:eventcal-080.py]]
  • [get | view] (2005-11-22 17:40:51, 6.8 KB) [[attachment:eventcal-090.css]]
  • [get | view] (2005-11-22 17:40:40, 18.1 KB) [[attachment:eventcal-090.py]]
  • [get | view] (2006-04-17 13:22:09, 8.9 KB) [[attachment:eventcal-096.css]]
  • [get | view] (2006-02-08 02:31:50, 1.4 KB) [[attachment:eventcalendar-094-01.patch]]
  • [get | view] (2006-11-30 15:52:26, 12.2 KB) [[attachment:label_priority-099-01.patch]]
  • [get | view] (2006-11-16 17:06:28, 1.1 KB) [[attachment:pagelinks-099-01.patch]]
  • [get | view] (2006-11-16 17:06:52, 2.9 KB) [[attachment:pagelist-099-01.patch]]
  • [get | view] (2006-03-29 07:37:02, 118.7 KB) [[attachment:snap-daily.jpg]]
  • [get | view] (2006-01-18 03:52:49, 23.2 KB) [[attachment:snap-list.jpg]]
  • [get | view] (2006-01-18 03:52:40, 37.4 KB) [[attachment:snap-monthly.jpg]]
  • [get | view] (2006-03-29 07:35:54, 43.8 KB) [[attachment:snap-simple.jpg]]
  • [get | view] (2006-01-18 03:53:04, 29.4 KB) [[attachment:snap-upcoming.jpg]]
  • [get | view] (2006-03-29 07:36:43, 161.0 KB) [[attachment:snap-weekly.jpg]]
  • [get | view] (2007-06-12 19:51:39, 55.0 KB) [[attachment:time_bug.PNG]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.