Attachment 'eventcal-090.py'

Download

   1 """
   2     eventcal.py  Version 0.90  2005. 11. 15.
   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     For more information, please visit http://moinmoin.wikiwikiweb.de/MacroMarket/EventCalendar
  10     
  11     Usage: 
  12         To insert events, enclose the information about the event records with 'eventcal' parser.
  13         E.g., 
  14             {{{#!eventcal
  15                 = [Title] =
  16                 [Start Date] ... [End Date]
  17                 [Start Time] ... [End Time]
  18             }}}
  19         
  20             [Title] should be enclosed with heading marker ('='), double quatation mark ("), wiki italic or bold ('', ''')
  21                 Title can be omitted and it will be titled as 'No Title'
  22                 e.g., == Title ==, === Title ===, "Title", ''Title'', '''Title'''
  23             
  24             [Start|End Date] should be in YYYY/MM/DD or YYYY-MM-DD. End date can be omitted.
  25                 e.g, 2005/10/20, 2005-10-20
  26             
  27             [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.
  28                 e.g., 08:00, 12:00, 18:00
  29             
  30             In the parsing block of eventcal, it pops out first two date formatted text (startdate and enddate), 
  31             two time formatted text (starttime, endtime), and quoted or heading titie. 
  32             
  33             It ignores further occurrence of the targeted string. 
  34             The order of each fields (date, time, title) does not matter .
  35             The start date|time should precede the end date|time in the occurrence respectively.
  36 
  37         You can separate the events starting a '##eventcal' line without any trailing characters.
  38         E.g., 
  39             {{{#!eventcal
  40             = 1st Event =
  41             StartDate1 ~ EndDate1
  42             ##eventcal
  43             = 2nd Event =
  44             StartDate2 ~ EndDate2
  45             ...
  46             }}}
  47             
  48     Features:
  49         Shows the event information in a parsed format.
  50         Validates the date, time format.
  51 
  52 
  53     Notes:
  54         Much buggy.. :please report bugs and suggest your ideas.
  55         
  56 
  57 
  58 """
  59 
  60 import datetime, re
  61 from MoinMoin.parser import wiki
  62 import urllib
  63 from MoinMoin import config
  64 
  65 class Parser:
  66 
  67     def __init__(self, raw, request, **kw):
  68         self.lines = raw
  69         self.request = request
  70         option_args = {}
  71         
  72         for arg in kw.get('format_args', '').split():
  73             try:
  74                 key, value = arg.split('=')
  75                 option_args[key.strip()] = value.strip()
  76             except ValueError:
  77                 pass
  78                 
  79         self.bgcolor = option_args.get('bgcolor', '')
  80         self.icon = option_args.get('icon', '')
  81         self.view = option_args.get('view', '')
  82         
  83 
  84     def format(self, formatter):
  85         """ Send the "parsed" text.
  86         """
  87         
  88         self.formatter = formatter
  89         
  90         # need help on regular expressions for more efficient/flexible form
  91         regex_date = r'(\d{4}[/-]\d{2}[/-]\d{2})'
  92         regex_time = r'(\d{2}[:]\d{2})'
  93         regex_title = r'["]+(\s*.*?)["]+|[\']{2,5}(\s*.*?)[\']{2,5}|^[=]+(\s*.*?)[=]+$'
  94         regex_bgcolor = r'^##bgcolor (\s*.*?)$'
  95         regex_icon = r'^##icon (\s*.*?)$'
  96         regex_view= r'^##view (\s*.*?)$'
  97         regex_eventcal = r'[\{]{3}#!eventcal[^\n]*(\s*.*?[^\}]+)[\}]{3}'
  98         
  99         msg = ''
 100         
 101         # compile regular expression objects
 102         pattern_date = re.compile(regex_date, re.UNICODE)
 103         pattern_time = re.compile(regex_time, re.UNICODE)
 104         pattern_title = re.compile(regex_title, re.UNICODE + re.DOTALL + re.MULTILINE)
 105         pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE)
 106         pattern_icon = re.compile(regex_icon, re.UNICODE + re.MULTILINE + re.IGNORECASE)
 107         pattern_view = re.compile(regex_view, re.UNICODE + re.MULTILINE + re.IGNORECASE)
 108         pattern_eventcal = re.compile(regex_eventcal, re.UNICODE + re.MULTILINE + re.IGNORECASE)
 109         
 110         # ignores #!eventcal blocks
 111         lines = pattern_eventcal.sub(r'\n##eventcal\n\1\n##eventcal\n', self.lines)
 112         
 113         # split events
 114         linesall = lines.split(u'##eventcal\n')
 115         
 116         for lines in linesall:
 117         
 118             linetemp = lines.strip()
 119             if not linetemp: 
 120                 continue
 121             
 122             title = ''
 123             startdate = ''
 124             enddate = ''
 125             starttime = ''
 126             endtime = ''
 127             icon = self.icon
 128             bgcolor = self.bgcolor
 129             view = self.view
 130             
 131             # retrieve view
 132             match = pattern_view.search(lines)
 133             if match:
 134                 view = match.group(0)[7:]
 135             
 136             if view == 'none':
 137                 # no need to check valididy
 138                 self.printoutput(lines, '', '', '', '', 1, '', '', view)
 139                 continue
 140             
 141             # retrieve date
 142             match = pattern_date.findall(lines)
 143             
 144             if not len(match):
 145                 msg = 'at least one date field should be specified'
 146                 self.printoutput(lines, 'Parse Error', msg, '', '', 0, bgcolor, icon, view)
 147                 continue
 148             
 149             # (month, day)-only date should be handled later
 150             
 151             startdate = match[0]
 152             if len(match) > 1:
 153                 enddate = match[1]
 154             
 155             # retrieve time
 156             match = pattern_time.findall(lines)
 157             
 158             if len(match) >= 2:
 159                 starttime = match[0]
 160                 endtime = match[1]
 161             elif len(match) == 0:
 162                 starttime = ''
 163                 endtime = ''
 164             else:
 165                 msg = 'no or 2 time field should be specified'
 166                 self.printoutput(lines, 'Parse Error', msg, '', '', 0, bgcolor, icon, view)
 167                 continue
 168                 
 169             # retrieve title
 170             match = pattern_title.search(lines)
 171             
 172             if not match:
 173                 title = 'No title'
 174             else:
 175                 for item in match.groups():
 176                     if item:
 177                         title = item
 178                         break
 179             
 180             # retrieve bgcolor
 181             match = pattern_bgcolor.search(lines)
 182             if match:
 183                 bgcolor = match.group(0)[10:]
 184             
 185             # retrieve icon
 186             match = pattern_icon.search(lines)
 187             if match:
 188                 icon = match.group(0)[7:]
 189                 
 190             # if no enddate, it's 1-day event
 191             if (not enddate) and (starttime and endtime):
 192                 enddate = startdate
 193            
 194             # check the validity of date/time
 195             try:
 196                 syear, smonth, sday = getdatefield(startdate
 197 )
 198                 if enddate:
 199                     eyear, emonth, eday = getdatefield(enddate
 200 )
 201             except:
 202                 msg = 'invalid date format'
 203                 self.printoutput(lines, 'Parse Error', msg, '', '', 0, bgcolor, icon, view)
 204                 continue
 205             
 206             if startdate and enddate:
 207                 if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
 208                     msg = 'startdate should precede enddate'
 209                     self.printoutput(lines, 'Parse Error', msg, '', '', 0, bgcolor, icon, view)
 210                     continue
 211     
 212             if starttime and endtime:
 213                 try:
 214                     shour, smin = gettimefield(starttime
 215 )
 216                     ehour, emin = gettimefield(endtime
 217 )
 218                 except:
 219                     msg = 'invalid time format'
 220                     self.printoutput(lines, 'Parse Error', msg, '', '', 0, bgcolor, icon, view)
 221                     continue
 222             
 223                 if startdate == enddate:
 224                     if datetime.time(shour, smin) > datetime.time(ehour, emin):
 225                         msg = 'starttime should precede endtime'
 226                         self.printoutput(lines, 'Parse Error', msg, '', '', 0, bgcolor, icon, view)
 227                         continue
 228             
 229             # format output
 230             fromstring = '%s %s' % (startdate, starttime)
 231             if enddate:
 232                 tostring = '%s %s' % (enddate, endtime)
 233             else:
 234                 tostring = ''
 235             
 236             startdateforbookmark = u'%d%02d%02d' % (syear, smonth, sday)
 237             
 238             self.printoutput(lines, title, fromstring, tostring, startdateforbookmark, 1, bgcolor, icon, view)
 239     
 240     def printoutput(self, lines, title='', fromstring='', tostring='', startdateforbookmark='', successflag=1, bgcolor='', icon='', view='table'):
 241         
 242         if view == u'footnote':
 243             self.outputfootnote(lines, title, fromstring, tostring, startdateforbookmark, successflag)
 244         elif view == u'erroronly':
 245             self.outputerroronly(lines, title, fromstring, tostring, startdateforbookmark, successflag)
 246         elif view == u'none':
 247             self.outputnone(lines, title, startdateforbookmark)
 248         else:
 249             self.outputtable(lines, title, fromstring, tostring, startdateforbookmark, successflag, bgcolor, icon)
 250             
 251 
 252     def outputtable(self, lines, title, fromstring, tostring, startdateforbookmark, successflag, bgcolor='', icon=''):
 253     
 254         formatter = self.formatter
 255         # title += u'[%s]' % self.args
 256         
 257         if startdateforbookmark:
 258             bookmark = u'%s%s' % (title.replace(' ', ''), startdateforbookmark)
 259             # bookmark = urllib.quote_plus(bookmark.encode(config.charset))
 260             html = u'<a name="%s"></a>' % bookmark
 261             self.request.write(formatter.rawHTML(html))
 262         
 263         html = [
 264             u'<table width="100%%" style="border-width:0px;"><tr><td width="100%%" style="border-width:0px; text-align: left; vertical-align: top;">',
 265             u'',
 266             ]
 267 
 268         html = u'\n'.join(html)
 269         self.request.write(formatter.rawHTML(html))
 270             
 271         wikiparser = wiki.Parser( lines, self.request )
 272         wikiparser.format( formatter )
 273         
 274         if tostring:
 275             fromto = '%s<br>~ %s' % (fromstring.strip(), tostring.strip())
 276         else:
 277             fromto = '%s' % fromstring.strip()
 278         
 279         if successflag:
 280             if icon:
 281                 flag = icon
 282             else:
 283                 flag = '(!)'
 284         else:
 285             flag = '{X}'
 286         
 287         if successflag:
 288             if bgcolor:
 289                 bgcolor = u'background-color: %s;' % bgcolor
 290             else:
 291                 bgcolor = u'background-color: #ddffdd;'
 292         else:
 293             bgcolor = u'background-color: #ff9933;'
 294         
 295         html = [
 296             u'</td>',
 297             u'<td style="border-width: 0px; padding: 0px; margin: 0px; border-top-width: 1px; width: 4px;">&nbsp;</td>',
 298             u'<td style="border-width:0px; border-left-width: 1px; vertical-align: bottom; padding: 0px; margin: 0px;"><table style="width: 140px; border-width:0px; padding: 0px; margin: 0px;">',
 299             u'<tr><td rowspan="2" style="width: 16px; border-width:1px; border-left-width: 0px; border-right-width: 0px; padding: 0px; margin: 0px; vertical-align: top;">',
 300             ]
 301 
 302         html = u'\n'.join(html)
 303         self.request.write(formatter.rawHTML(html))
 304         
 305         # flag        
 306         wikiparser = wiki.Parser( '%s' % flag, self.request )
 307         wikiparser.format( formatter )
 308         
 309         # title, fromto string
 310         html = [
 311             u'</td>',
 312             u'<td style="border-width:1px; border-left-width: 0px; border-bottom-width: 0px; line-height: 8px; padding: 0px; margin: 0px; %s"' % bgcolor,
 313             u'><font style="font-size: 8pt; font-weight: bold;">%s</font></td></tr>' % title.strip(),
 314             u'<tr><td style="border-width:1px; border-left-width: 0px; border-top-width: 0px; line-height: 8px; padding: 0px; margin: 0px; text-align: right;"',
 315             u'><font style="font-size: 7pt;">%s</font></td></tr></td></tr></table></td></tr></table>' % fromto,
 316             ]
 317 
 318         html = u'\n'.join(html)
 319         self.request.write(formatter.rawHTML(html))
 320    
 321     def outputerroronly(self, lines, title, fromstring, tostring, startdateforbookmark, successflag):
 322         
 323         formatter = self.formatter
 324         
 325         if tostring:
 326             fromto = '%s ~ %s' % (fromstring.strip(), tostring.strip())
 327         else:
 328             fromto = '%s' % fromstring.strip()
 329         
 330         if startdateforbookmark:
 331             bookmark = u'%s%s' % (title.replace(' ', ''), startdateforbookmark)
 332             # bookmark = urllib.quote_plus(bookmark.encode(config.charset))
 333             html = u'<a name="%s"></a>' % bookmark
 334             self.request.write(formatter.rawHTML(html))
 335             
 336         if successflag:
 337             wikiparser = wiki.Parser( lines, self.request )
 338             wikiparser.format( formatter )
 339         else:
 340                         
 341             html = [
 342                 u'<table width="100%%" style="border-width:0px;"><tr><td width="100%%" style="border-width:0px; text-align: left; vertical-align: top;">',
 343                 u'',
 344                 ]
 345     
 346             html = u'\n'.join(html)
 347             self.request.write(formatter.rawHTML(html))
 348                 
 349             wikiparser = wiki.Parser( lines, self.request )
 350             wikiparser.format( formatter )
 351             
 352             flag = '{X}'
 353 
 354             html = [
 355                 u'</td>',
 356                 u'<td style="border-width: 0px; padding: 0px; margin: 0px; border-top-width: 1px; width: 4px;">&nbsp;</td>',
 357                 u'<td style="border-width:0px; border-left-width: 1px; vertical-align: bottom; padding: 0px; margin: 0px;"><table style="width: 140px; border-width:0px; padding: 0px; margin: 0px;">',
 358                 u'<tr><td rowspan="2" style="width: 16px; border-width:1px; border-left-width: 0px; border-right-width: 0px; padding: 0px; margin: 0px; vertical-align: top;">',
 359                 ]
 360     
 361             html = u'\n'.join(html)
 362             self.request.write(formatter.rawHTML(html))
 363             
 364             # flag        
 365             wikiparser = wiki.Parser( '%s' % flag, self.request )
 366             wikiparser.format( formatter )
 367             
 368             # title, fromto string
 369             html = [
 370                 u'</td>',
 371                 u'<td style="border-width:1px; border-left-width: 0px; border-bottom-width: 0px; line-height: 8px; padding: 0px; margin: 0px;"',
 372                 u'><font style="font-size: 8pt; font-weight: bold;">%s</font></td></tr>' % title.strip(),
 373                 u'<tr><td style="border-width:1px; border-left-width: 0px; border-top-width: 0px; line-height: 8px; padding: 0px; margin: 0px; text-align: right;"',
 374                 u'><font style="font-size: 7pt;">%s</font></td></tr></td></tr></table></td></tr></table>' % fromto,
 375                 ]
 376     
 377             html = u'\n'.join(html)
 378             self.request.write(formatter.rawHTML(html))
 379 
 380     def outputnone(self, lines, title, startdateforbookmark):
 381         
 382         formatter = self.formatter
 383         
 384         if startdateforbookmark:
 385             bookmark = u'%s%s' % (title.replace(' ', ''), startdateforbookmark)
 386             # bookmark = urllib.quote_plus(bookmark.encode(config.charset))
 387             html = u'<a name="%s"></a>' % bookmark
 388             self.request.write(formatter.rawHTML(html))
 389             
 390         wikiparser = wiki.Parser( lines, self.request )
 391         wikiparser.format( formatter )
 392 
 393     def outputfootnote(self, lines, title, fromstring, tostring, startdateforbookmark, successflag):
 394     
 395         formatter = self.formatter
 396         
 397         if tostring:
 398             fromto = '%s ~ %s' % (fromstring.strip(), tostring.strip())
 399         else:
 400             fromto = '%s' % fromstring.strip()
 401 
 402         footnote = u'(Event) %s: %s' % (title, fromto)
 403         lines = u'%s [[FootNote(%s)]]' % (lines.rstrip(), footnote)
 404         
 405         if startdateforbookmark:
 406             bookmark = u'%s%s' % (title.replace(' ', ''), startdateforbookmark)
 407             # bookmark = urllib.quote_plus(bookmark.encode(config.charset))
 408             html = u'<a name="%s"></a>' % bookmark
 409             self.request.write(formatter.rawHTML(html))
 410         
 411         wikiparser = wiki.Parser( lines, self.request )
 412         wikiparser.format( formatter )
 413         
 414 
 415 
 416 def getdatefield(str_date):
 417     str_year = ''
 418     str_month = ''
 419     str_day = ''
 420     
 421     if len(str_date) == 6:
 422         # year+month
 423         str_year = str_date[:4]
 424         str_month = str_date[4:]
 425         str_day = '1'
 426 
 427     elif len(str_date) == 8:
 428         # year+month+day
 429         str_year = str_date[:4]
 430         str_month = str_date[4:6]
 431         str_day = str_date[6:]
 432     
 433     elif len(str_date) == 10:
 434         # year+?+month+?+day
 435         str_year = str_date[:4]
 436         str_month = str_date[5:7]
 437         str_day = str_date[8:]
 438     
 439     else:
 440         raise ValueError
 441     
 442     # It raises exception if the input date is incorrect
 443     temp = datetime.date(int(str_year), int(str_month), int(str_day))
 444 
 445     return temp.year, temp.month, temp.day
 446 
 447 
 448 def gettimefield(str_time):
 449     str_hour = ''
 450     str_min = ''
 451     
 452     if len(str_time) == 4:
 453         # hour+minute
 454         str_hour = str_time[:2]
 455         str_min = str_time[2:]
 456     
 457     elif len(str_time) == 5:
 458         # hour+?+minute
 459         str_hour = str_time[:2]
 460         str_min = str_time[3:]
 461         
 462     else:
 463         raise ValueError
 464     
 465     # It raises exception if the input date is incorrect
 466     temp = datetime.time(int(str_hour), int(str_min))
 467 
 468     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.