From 0e95ca8d0c9ff849107fea9b249a3cc0bb281944 Mon Sep 17 00:00:00 2001 From: Antoine Durand-Gasselin Date: Mon, 24 Nov 2008 08:07:03 +0100 Subject: [PATCH] =?UTF-8?q?[/usr/scripts/wiki-lenny/=E2=80=A6/macros/Event?= =?UTF-8?q?Calendar]=20Passage=20=C3=A0=20la=20MoinMoin1.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prétendre que "ça marche" me paraît téméraire, mais en tout cas, ça en donne bien l'impression darcs-hash:20081124070703-bd074-e1fc02c830a2e7b0b1835d8c361b45551561f785.gz --- wiki-lenny/local/macro/EventCalendar.py | 4173 +++++++++++++++++++++++ 1 file changed, 4173 insertions(+) create mode 100644 wiki-lenny/local/macro/EventCalendar.py diff --git a/wiki-lenny/local/macro/EventCalendar.py b/wiki-lenny/local/macro/EventCalendar.py new file mode 100644 index 00000000..f53e5ce9 --- /dev/null +++ b/wiki-lenny/local/macro/EventCalendar.py @@ -0,0 +1,4173 @@ +# -*- coding: iso-8859-1 -*- +""" + EventCalendar.py Version 0.98 May 12, 2006 + + This macro gives a list of the events recorded at the sub-pages in the form of various views: + monthly, weekly, daily, simple-month, list, and upcoming. + + @copyright: 2006 by Seungik Lee gmail.com> http://www.silee.net/ + @license: GPL + + For more information, please visit http://moinmoin.wikiwikiweb.de/MacroMarket/EventCalendar + + + + * To list the events in a page, just insert [[EventCalendar]] + * To insert an event, insert the event information in any pages of specified category (CategoryEventCalendar by default). + + + + * category: the category of the event data to be used in the calendar. default: 'CategoryEventCalendar' + * menubar: shows menubar or not (1: show, 0: no menubar). default: 1 + * monthlywidth: calendar width in pixel or percent (monthly view). default: '600' (pixel) + * simplewidth: calendar width in pixel or percent (simpleview). default: '150' (pixel) + * firstview: initial calendar view: monthly, weekly, daily, list, simple, upcoming. default: 'monthly' + * curdate: initial calendar date (in YYYYMM format). default: current month + * upcomingrange: # of days for the range of upcoming event list. default: 7 (days) + * changeview: enables to change the calendar view or not (1: enalbed, 0: disabled). default: 1 + * numcal: # of calendar. default: 1 + * showlastweekday: shows the event at the last weekday if the recurred weekday is not available. (1: enalbed, 0: disabled). default: 0 + * showerror: shows error messages below the calendar if event data format is invalid. (1: enalbed, 0: disabled). default: 1 + * showweeknumber: shows the week number of the year (1: enalbed, 0: disabled). default: 0 + + + + + * Event data fields: +... + + [default_description:: [page_default_description_text]] + [default_bgcolor:: [page_default_background_color]] + [label_def:: [label_name], [label_background_color]] + +== == + start:: <startdate> [starttime] + [end:: [enddate] [endtime]] + [description:: [description_text]] + [bgcolor:: [custom_background_color]] + [recur:: <recur_freq> <recur_type> [until <recur_until>]] + [label:: <label_name>] + +... + +---- +CategoryEventCalendar + + * default_bgcolor, default_description: default values of bgcolor and description in the page if unavailable. optional + * label_def: label definition with name, bgcolor. optional + + * title: event title. required + * should be enclosed with heading marker ('='), Title cannot be omitted. + + * startdate: date of start. required + * should be in date format or date format + + * starttime: time of start. optional + * should be in time format + + * enddate: date of end. optional + * should be in date format or date format. If omitted, it will be assigned equal to <startdate>. + + * endtime: time of end. optional + * should be in time format. Both of start|end Time can be omitted but not either of them. + + * description: description of the event. optional + * any text with no markup. should be in a line. + + * bgcolor: custom background color of the event in monthly view. optional + * e.g., #abcdef + + * recur: recurrence information of the event. optional + * recur_freq: how many intervals, digit or 'last' for weekday, required + * recur_type: [day|week|weekday|month|year], required + * day: every [recur_freq] days + * week: every [recur_freq] weeks + * weekday: on the same weekday of [recur_freq]-th week of the month. or 'last weekday' + * month: on the same day of [recur_freq]-th month + * year: on the same day of [recur_freq]-th year + * recur_until: recurred until when, date format, optional + + * e.g., 10 day, 2 week until 2006-06-31, 3 weekday, 6 month until 2007-12-31, 1 year + + * label: custom label for specific name, bgcolor. optional + + * The order of the fields after an event title does not matter. + * Priority of bgcolor: bgcolor > default_bgcolor > label_bgcolor + + + * Datetime format: + + * Date format: + * YYYY/MM/DD, YYYY-MM-DD, YYYY.MM.DD: 2006/05/12; 2006-05-12; 2006.05.12; 2006-5-12; 06/5/12 + * B DD, YYYY: May 12, 2006; May 5th, 2006; January 1st, 2006; Jan 5, 06 + * YYYYMMDD, YYMMDD: 20060512; 060512 + + * Year: YY = 20YY. e.g., 06-2-2 = 2006-02-02, allowed 1900 ~ 2099 only. + + * Time format: + * H:M, HHMM: 12:00; 22:00; 2:00; 2 (= 2 o'clock); 2200; 12:0; 2:0 + * I:M PP, IIMM PP: 12:00 PM; 3:00p; 2a (= 2 o'clock AM); 3:0pm; 0200 am; 10pm + + + + <Event Data Examples> + +== Default values == + default_bgcolor:: #c0c0c0 + default_description:: testing... + +== Labels == + label_def:: Holiday, #ff0000 + label_def:: Meeting, #00ff00 + +=== Test event === + start:: 2006-01-10 02:00p + end:: 2006-01-12 17:00 + description:: test event + bgcolor:: #cfcfcf + +=== Jinah's Birthday === + start:: 1977-10-20 + recur:: 1 year + label:: Holiday + +=== Weekly meeting === + start:: Jan 17, 2006 7:00pm + end:: 21:00 + recur:: 1 week until 061231 + label:: Meeting + +---- +CategoryEventCalendar + + + <Notes> + + * It caches all the page list of the specified category and the event information. + * If you added/removed a page into/from a category, you need to do 'Delete cache' in the macro page. + + * 'MonthCalendar.py' developed by Thomas Waldmann <ThomasWaldmann@gmx.de> has inspired this macro. + * Much buggy.. : please report bugs and suggest your ideas. + * If you missed to add css for EventCalender, monthly view may not be readable. + * Insert the EventCalendar css classes into the screen.css of an appropriate theme. + + + +""" + +from MoinMoin import wikiutil, config, search, caching +from MoinMoin.Page import Page +from MoinMoin.parser import text_moin_wiki as wiki +import re, calendar, time, datetime +import codecs, os, urllib, sha + +try: + import cPickle as pickle +except ImportError: + import pickle + +# Set pickle protocol, see http://docs.python.org/lib/node64.html +PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL + + +# The following line sets the calendar to have either Sunday or Monday as +# the first day of the week. Only SUNDAY or MONDAY (case sensitive) are +# valid here. All other values will not make good calendars. +# XXX change here ----------------vvvvvv +calendar.setfirstweekday(calendar.SUNDAY) + + +class Globs: + month_style_us = 1 # 1: October 2005; 2: 2005 / 10 + defaultcategory = 'CategoryEventCalendar' + upcomingrange = 7 # days + dailystart = 9 + dailyend = 18 + pagename = '' + baseurl = '' + subname = '' + wkend = '' + months = '' + wkdays = '' + today = '' + now = '' + request = None + formatter = None + cal_action = '' + debugmsg = '' + errormsg = '' + page_action = '' + form_vals = {} + events = None + labels = None + + +class Params: + menubar = 0 + monthlywidth = '' + weeklywidth = '' + dailywidth = '' + simplewidth = '' + firstview = '' + curdate = '' + bgcolor = '' + category = '' + upcomingrange = 0 + changeview = 0 + numcal = 1 + showlastweekday = 0 + showerror = 1 + showweeknumber = 0 + debug = 0 + + +class EventcalError(Exception): + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + +def execute(macro, args): + + request = macro.request + formatter = macro.formatter + + # INITIALIZATION ---------------------------------------- + setglobalvalues(macro) + getparams(args) + + # allowed actions + allowed_action = ['monthly', 'list', 'simple', 'upcoming', 'daily', 'weekly'] + default_action = Params.firstview + + # Internal variables + cal_action = '' + form_vals = {} + + # PROCESSING ARGUEMENTS ---------------------------------------- + if args: + args=request.getText(args) + + for item in macro.form.items(): + if not form_vals.has_key(item[0]): + try: + form_vals[item[0]]=item[1][0] + except AttributeError: + pass + + # PROCESSING ACTIONS ---------------------------------------- + cal_action = form_vals.get('calaction', default_action) + page_action = form_vals.get('action', 'show') + + if not cal_action in allowed_action: + cal_action = default_action + + form_vals['calaction'] = cal_action + + Globs.form_vals = form_vals + + # CONTROL FUNCTIONS ---------------------------------------- + + html = [] + html_result = '' + + Globs.cal_action = cal_action + Globs.page_action = page_action + + + # redirect to the appropriate view + if cal_action == 'monthly': + html_result = showcalendar() + + if cal_action == 'list': + html_result = showeventlist() + + if cal_action == 'simple': + html_result = showsimplecalendar() + + if cal_action == 'upcoming': + html_result = showupcomingeventlist() + + if cal_action == 'daily': + html_result = showdailycalendar() + + if cal_action == 'weekly': + html_result = showweeklycalendar() + + + # format output + html.append( html_result ) + html.append( showmenubar() ) + + if Params.showerror and Globs.errormsg: + html.append(u'<p><i><font size="2" color="#aa0000"><ol>%s</ol></font></i>' % Globs.errormsg) + + if Params.debug and Globs.debugmsg: + html.append(u'<p><b>Debug messages:</b><font color="#000099"><ol>%s</ol></font>' % Globs.debugmsg) + + return formatter.rawHTML(u''.join(html)) + + + +def getparams(args): + # process arguments + + params = {} + if args: + # Arguments are comma delimited key=value pairs + sargs = args.split(',') + + for item in sargs: + sitem = item.split('=') + + if len(sitem) == 2: + key, value = sitem[0], sitem[1] + params[key.strip()] = value.strip() + + # category name: + # default: 'CategoryEventCalendar' + Params.category = params.get('category', Globs.defaultcategory) + # menu bar: shows menubar or not (1: show, 0: no menubar) + # default: 1 + try: + Params.menubar = int(params.get('menubar', 1)) + except (TypeError, ValueError): + Params.menubar = 1 + + # calendar width in pixel or percent (monthly) + # default: 600px + Params.monthlywidth = params.get('monthlywidth', '600') + if Params.monthlywidth: + Params.monthlywidth = ' width="%s" ' % Params.monthlywidth + + # calendar width in pixel or percent (weekly) + # default: 600px + Params.weeklywidth = params.get('weeklywidth', '600') + if Params.weeklywidth: + Params.weeklywidth = ' width="%s" ' % Params.weeklywidth + + # calendar width in pixel or percent (daily) + # default: 600px + Params.dailywidth = params.get('dailywidth', '600') + if Params.monthlywidth: + Params.dailywidth = ' width="%s" ' % Params.dailywidth + + # calendar width in pixel or percent (simply) + # default: 150px + Params.simplewidth = params.get('simplewidth', '150') + if Params.simplewidth: + # Params.simplewidth = Params.simplewidth.replace('%', '%%') + Params.simplewidth = ' width="%s" ' % Params.simplewidth + + # calendar view: monthly, list, simple + # default: 'monthly' + Params.firstview = params.get('firstview', 'monthly') + + # calendar date: in YYYYMM format (in monthly, simple view) + # default: current month + Params.curdate = params.get('curdate', '') + + # upcoming range: # of days for upcoming event list + # default: 7 + try: + Params.upcomingrange = int(params.get('upcomingrange', Globs.upcomingrange)) + except (TypeError, ValueError): + Params.upcomingrange = Globs.upcomingrange + + # number of calendar: # of calendar for monthly & simple view + # default: 1 + try: + Params.numcal = int(params.get('numcal', '1')) + except (TypeError, ValueError): + Params.numcal = 1 + + # change view enabled? + # default: 1 + try: + Params.changeview = int(params.get('changeview', '1')) + except (TypeError, ValueError): + Params.changeview = 1 + + # shows the event at the last weekday if the recurred weekday is not available. + # default: 0 + try: + Params.showlastweekday = int(params.get('showlastweekday', '0')) + except (TypeError, ValueError): + Params.showlastweekday = 0 + + # show error message? + # default: 1 + try: + Params.showerror = int(params.get('showerror', '1')) + except (TypeError, ValueError): + Params.showerror = 1 + + # show week number? + # default: 0 + try: + Params.showweeknumber = int(params.get('showweeknumber', '0')) + except (TypeError, ValueError): + Params.showweeknumber = 0 + + # default bgcolor + Params.bgcolor = '#ddffdd' + + +def setglobalvalues(macro): + + request = macro.request + formatter = macro.formatter + + # Useful variables + Globs.baseurl = request.getBaseURL() + '/' + Globs.pagename = formatter.page.page_name + Globs.request = request + Globs.formatter = formatter + Globs.pageurl = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(formatter.page.page_name)) + + # This fixes the subpages bug. subname is now used instead of pagename when creating certain urls + Globs.subname = Globs.pagename.split('/')[-1] + + pagepath = formatter.page.getPagePath() + Globs.pagepath = formatter.page.getPagePath() + + # european / US differences + months = (u'Janvier',u'Fevrier',u'Mars',u'Avril',u'Mai',u'Juin',u'Juillet',u'Aout',u'Septembre',u'Octobre',u'Novembre',u'Decembre') + + # Set things up for Monday or Sunday as the first day of the week + if calendar.firstweekday() == calendar.MONDAY: + wkend = 6 + wkdays = ('Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim') + elif calendar.firstweekday() == calendar.SUNDAY: + wkend = 0 + wkdays = ('Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam') + + Globs.months = months + Globs.wkdays = wkdays + Globs.wkend = wkend + + year, month, day, h, m, s, wd, yd, ds = request.user.getTime(time.time()) + Globs.today = datetime.date(year, month, day) + Globs.now = datetime.time(h, m, s) + + Globs.debugmsg = '' + Globs.errormsg = '' + + +def showReferPageParsed(event, targettext='title', showdesc=0): + request = Globs.request + pagename = Globs.pagename + + refer = event['refer'] + targettext = event[targettext] + startdate = event['startdate'] + enddate = event['enddate'] + description = event['description'] + starttime = event['starttime'] + endtime = event['endtime'] + hid = event['hid'] + + refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer)) + + if not Params.changeview: + refer_url = '' + hid = '' + + if showdesc: + if (startdate == enddate) and (starttime and endtime): + timedescription = '(%s:%s ~ %s:%s)' % (starttime[:2], starttime[2:], endtime[:2], endtime[2:]) + if description: + timedescription = '%s ' % timedescription + else: + timedescription = '' + + targetlink = '<a href="%s#%s" title="%s%s">%s</a>' % ( refer_url, hid, timedescription, wikiutil.escape(description), wikiutil.escape(targettext) ) + + else: + targetlink = '<a href="%s#%s">%s</a>' % ( refer_url, hid, wikiutil.escape(targettext)) + + return targetlink + + +def showReferPageParsedForLabel(thelabel, targettext='name', showdesc=1): + request = Globs.request + pagename = Globs.pagename + + labels = Globs.labels + + label_bgcolor = '' + refer = '' + + if labels and labels.has_key(thelabel): + targettext = labels[thelabel][targettext] + refer = labels[thelabel]['refer'] + if showdesc: + label_bgcolor = labels[thelabel]['bgcolor'] + + if not refer: + return '<i>%s</i>' % thelabel + + refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer)) + + if showdesc: + targetlink = '<a href="%s" title="%s">%s</a>' % ( refer_url, label_bgcolor, wikiutil.escape(targettext) ) + else: + targetlink = '<a href="%s">%s</a>' % ( refer_url, wikiutil.escape(targettext)) + + return targetlink + + +def getheadingid(request, referpage, title): + + pntt = (referpage + title).encode(config.charset) + hid = "head-" + sha.new(pntt).hexdigest() + + if not hasattr(request, '_eventcal_headings'): + request._eventcal_headings = {} + + request._eventcal_headings.setdefault(pntt, 0) + request._eventcal_headings[pntt] += 1 + if request._eventcal_headings[pntt] > 1: + hid += '-%d'%(request._eventcal_headings[pntt],) + + return hid + + +def getquerystring(req_fields): + + m_query = [] + tmp_form_vals = Globs.form_vals + + # format querystring + # action should be poped out + for field in req_fields: + if tmp_form_vals.has_key(field): + m_query.append(u'%s=%s' % (field, tmp_form_vals[field]) ) + + if 'prevcalaction' in req_fields: + if not tmp_form_vals.has_key('prevcalaction'): + m_query.append(u'%s=%s' % ('prevcalaction', tmp_form_vals['calaction']) ) + + m_query = u'&'.join(m_query) + + if m_query: + m_query = '&%s' % m_query + + return m_query + + +# bottom menu bar +def showmenubar(): + + request = Globs.request + cal_action = Globs.cal_action + page_name = Globs.pagename + + page_url = Globs.pageurl + + if not Params.menubar: return '' + + if cal_action == 'simple': + menuwidth = Params.simplewidth + elif cal_action == 'monthly': + menuwidth = Params.monthlywidth + else: + menuwidth = '' + + left_menu_selected = [] + right_menu_selected = [] + + # Go Today + year, month, day = gettodaydate() + mnu_curmonthcal = u'<a href="%s?calaction=%s&caldate=%d%02d%02d%s" title="Aujourd\'hui">[Aujourd\'hui]</a>' % (page_url, cal_action, year, month, day, getquerystring(['numcal'])) + + # List View + mnu_listview = u'<a href="%s?calaction=list%s" title="Liste de tous les évènements">[Liste]</a>' % (page_url, getquerystring(['caldate', 'numcal'])) + + # Monthly View + mnu_monthview = u'<a href="%s?calaction=monthly%s" title="Vue du mois">[Mois]</a>' % (page_url, getquerystring(['caldate', 'numcal']) ) + + # Simple Calendar View + mnu_simpleview = u'<a href="%s?calaction=simple%s" title="Simple calendrier">[Simple]</a>' % (page_url, getquerystring(['caldate', 'numcal']) ) + + # Upcoming Event List + mnu_upcomingview = u'<a href="%s?calaction=upcoming%s" title="Évènements à venir">[À venir]</a>' % (page_url, getquerystring(['caldate', 'numcal']) ) + + # Daily View + mnu_dayview = u'<a href="%s?calaction=daily%s" title="Vue du jour">[Jour]</a>' % (page_url, getquerystring(['caldate', 'numcal']) ) + + # Weekly View + mnu_weekview = u'<a href="%s?calaction=weekly%s" title="Vue de la semaine" >[Semaine]</a>' % (page_url, getquerystring(['caldate', 'numcal']) ) + + html = [ + u'\r\n', + u'<table class="eventcalendar_menubar" %s>', + u' <tr>', + u' <td class="eventcalendar_menubar" align="left">%s</td>', + u' <td class="eventcalendar_menubar" align="right">%s</td>', + u' </tr>', + u'</table>', + ] + + if cal_action == 'list': + left_menu_selected.append(mnu_monthview) + left_menu_selected.append(mnu_weekview) + left_menu_selected.append(mnu_dayview) + left_menu_selected.append(mnu_simpleview) + right_menu_selected.append(mnu_upcomingview) + + elif cal_action == 'simple': + left_menu_selected.append(mnu_monthview) + left_menu_selected.append(mnu_weekview) + left_menu_selected.append(mnu_dayview) + right_menu_selected.append(mnu_listview) + right_menu_selected.append(mnu_upcomingview) + right_menu_selected.append(mnu_curmonthcal) + + elif cal_action == 'upcoming': + left_menu_selected.append(mnu_monthview) + left_menu_selected.append(mnu_weekview) + left_menu_selected.append(mnu_dayview) + left_menu_selected.append(mnu_simpleview) + right_menu_selected.append(mnu_listview) + + elif cal_action == 'weekly': + left_menu_selected.append(mnu_monthview) + left_menu_selected.append(mnu_dayview) + left_menu_selected.append(mnu_simpleview) + right_menu_selected.append(mnu_upcomingview) + right_menu_selected.append(mnu_listview) + right_menu_selected.append(mnu_curmonthcal) + + elif cal_action == 'daily': + left_menu_selected.append(mnu_monthview) + left_menu_selected.append(mnu_weekview) + left_menu_selected.append(mnu_simpleview) + right_menu_selected.append(mnu_upcomingview) + right_menu_selected.append(mnu_listview) + right_menu_selected.append(mnu_curmonthcal) + + else: + left_menu_selected.append(mnu_weekview) + left_menu_selected.append(mnu_dayview) + left_menu_selected.append(mnu_simpleview) + right_menu_selected.append(mnu_upcomingview) + right_menu_selected.append(mnu_listview) + right_menu_selected.append(mnu_curmonthcal) + + left_menu_selected = u'\r\n'.join(left_menu_selected) + right_menu_selected = u'\r\n'.join(right_menu_selected) + + html = u'\r\n'.join(html) + html = html % (menuwidth, left_menu_selected, right_menu_selected) + + return html + + +def getdatefield(str_date): + str_year = '' + str_month = '' + str_day = '' + + if len(str_date) == 6: + # year+month + str_year = str_date[:4] + str_month = str_date[4:] + str_day = '1' + + elif len(str_date) == 8: + # year+month+day + str_year = str_date[:4] + str_month = str_date[4:6] + str_day = str_date[6:] + + elif len(str_date) == 10: + # year+?+month+?+day + str_year = str_date[:4] + str_month = str_date[5:7] + str_day = str_date[8:] + + else: + raise ValueError + + # It raises exception if the input date is incorrect + temp = datetime.date(int(str_year), int(str_month), int(str_day)) + + return temp.year, temp.month, temp.day + + +def gettimefield(str_time): + str_hour = '' + str_min = '' + + if len(str_time) == 4: + # hour+minute + str_hour = str_time[:2] + str_min = str_time[2:] + + elif len(str_time) == 5: + # hour+?+minute + str_hour = str_time[:2] + str_min = str_time[3:] + + else: + raise ValueError + + # It raises exception if the input date is incorrect + temp = datetime.time(int(str_hour), int(str_min)) + + return temp.hour, temp.minute + + +def gettodaydate(): + today = Globs.today + return today.year, today.month, today.day + + +def cal_listhead(): + + html = [ + u' <tr>', + u' <td class="list_head">Titre</td>', + u' <td class="list_head">Début</td>', + u' <td class="list_head">Fin</td>', + u' <td class="list_head">Fréquence</td>', + u' <td class="list_head">Label</td>', + u' <td class="list_head">Description</td>', + u' <td class="list_head">Page source</td>', + u' </tr>', + ] + + return u'\r\n'.join(html) + + +def showeventlist(): + + debug('Show Calendar: List view') + + request = Globs.request + formatter = Globs.formatter + + html_event_rows = [] + html_list_header = cal_listhead() + + # read all the events + events, cal_events, labels = loadEvents() + + # sort events + sorted_eventids = events.keys() + sorted_eventids.sort(comp_list_events) + + for eid in sorted_eventids: + if not events[eid]['clone']: + html_event_rows.append( listshow_event(events[eid]) ) + + html_event_rows = u'\r\n'.join(html_event_rows) + + html_list_table = [ + u'\r\n<div id="eventlist">', + u'<table class="eventlist">', + u'%s' % html_list_header, + u'%s' % html_event_rows, + u'</table>', + u'</div>', + ] + html_list_table = u'\r\n'.join(html_list_table) + + return html_list_table + + +def listshow_event(event): + + if event['recur_freq']: + if event['recur_freq'] == -1: + recur_desc = 'last %s' % event['recur_type'] + else: + recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type']) + + if event['recur_until']: + recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until'])) + else: + recur_desc = '' + + html = [ + u' <tr>', + u' <td class="list_entry">%s</td>' % converttext(event['title']), + u' <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']), + u' <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']), + u' <td class="list_entry">%s</td>' % recur_desc, + u' <td class="list_entry">%s</td>' % showReferPageParsedForLabel(event['label']), + u' <td class="list_entry">%s</td>' % converttext(event['description']), + u' <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'), + u' </tr>', + ] + + return u'\r\n'.join(html) + + +def showupcomingeventlist(): + + debug('Show Calendar: Upcoming Event View') + + request = Globs.request + formatter = Globs.formatter + + html_event_rows = [] + html_list_header = cal_listhead() + + year, month, day = gettodaydate() + day_delta = datetime.timedelta(days=Params.upcomingrange) + cur_date = datetime.date(year, month, day) + next_range = cur_date + day_delta + + # set ranges of events + datefrom = u'%04d%02d%02d' % (year, month, day) + dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day) + + # read all the events (no cache) + events, cal_events, labels = loadEvents(datefrom, dateto, 1) + + nowtime = formattimeobject(Globs.now) + + datefrom = formatcfgdatetime(cur_date, nowtime) + #u'%04d-%02d-%02d %s:%s' % (year, month, day, nowtime[:2], nowtime[2:]) + dateto = formatcfgdatetime(formatdateobject(next_range)) + #u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day) + + # sort events + sorted_eventids = events.keys() + sorted_eventids.sort(comp_list_events) + + for eid in sorted_eventids: + if events[eid]['enddate'] >= formatdateobject(Globs.today): + if (not events[eid]['endtime']) or events[eid]['endtime'] >= formattimeobject(Globs.now): + html_event_rows.append( listshow_event(events[eid]) ) + + html_event_rows = u'\r\n'.join(html_event_rows) + + html_list_table = [ + u'\r\n<div id="eventlist">', + u'<table class="eventlist">', + u'<tr><td colspan="7" class="list_entry" style="border-width: 0px;"><b>Évènement à venir: %s ~ %s</b><p><br><p></td></tr>' % (datefrom, dateto), + u'%s' % html_list_header, + u'%s' % html_event_rows, + u'</table>', + u'</div>', + ] + html_list_table = u'\r\n'.join(html_list_table) + + return html_list_table + + + + +def showcalendar(): + + request = Globs.request + formatter = Globs.formatter + form_vals = Globs.form_vals + + html = [] + + if form_vals.has_key('caldate'): + try: + year, month, str_temp = getdatefield(form_vals['caldate']) + except (TypeError, ValueError): + errormsgcode('invalid_caldate') + year, month, dy = gettodaydate() + + elif Params.curdate: + try: + year, month, str_temp = getdatefield(Params.curdate) + except (TypeError, ValueError): + errormsgcode('invalid_curdate') + year, month, dy = gettodaydate() + + else: + year, month, dy = gettodaydate() + + # check number of calendar + numcal = Params.numcal + + if form_vals.has_key('numcal'): + try: + numcal = int(form_vals['numcal']) + except (TypeError, ValueError): + errormsgcode('invalid_numcal') + + if numcal < 1: + numcal = 1 + elif numcal > 12: + numcal = 12 + + for index in range(numcal): + + cyear, cmonth = yearmonthplusoffset(year, month, index) + + cal_html = showeventcalendar(cyear, cmonth) + html.append(cal_html) + + return u''.join(html) + + +def showdailycalendar(): + + request = Globs.request + formatter = Globs.formatter + + form_vals = Globs.form_vals + + if form_vals.has_key('caldate'): + try: + year, month, dy = getdatefield(form_vals['caldate']) + + if len(form_vals['caldate']) <= 6: + tyear, tmonth, tdy = gettodaydate() + if tyear == year and month == tmonth: + dy = tdy + + except (TypeError, ValueError): + errormsgcode('invalid_caldate') + year, month, dy = gettodaydate() + + elif Params.curdate: + try: + year, month, dy = getdatefield(Params.curdate) + except (TypeError, ValueError): + errormsgcode('invalid_curdate') + year, month, dy = gettodaydate() + + else: + year, month, dy = gettodaydate() + + html = showdailyeventcalendar(year, month, dy) + + return u''.join(html) + + +def showweeklycalendar(): + + request = Globs.request + formatter = Globs.formatter + + form_vals = Globs.form_vals + + if form_vals.has_key('caldate'): + try: + year, month, dy = getdatefield(form_vals['caldate']) + + if len(form_vals['caldate']) <= 6: + tyear, tmonth, tdy = gettodaydate() + if tyear == year and month == tmonth: + dy = tdy + + except (TypeError, ValueError): + errormsgcode('invalid_caldate') + year, month, dy = gettodaydate() + + elif Params.curdate: + try: + year, month, dy = getdatefield(Params.curdate) + except (TypeError, ValueError): + errormsgcode('invalid_curdate') + year, month, dy = gettodaydate() + else: + year, month, dy = gettodaydate() + + html = showweeklyeventcalendar(year, month, dy) + + return u''.join(html) + + +def showsimplecalendar(): + + request = Globs.request + formatter = Globs.formatter + form_vals = Globs.form_vals + + html = [] + + if form_vals.has_key('caldate'): + try: + year, month, str_temp = getdatefield(form_vals['caldate']) + except (TypeError, ValueError): + errormsgcode('invalid_caldate') + year, month, dy = gettodaydate() + elif Params.curdate: + try: + year, month, str_temp = getdatefield(Params.curdate) + except (TypeError, ValueError): + errormsgcode('invalid_curdate') + year, month, dy = gettodaydate() + else: + year, month, dy = gettodaydate() + + # check number of calendar + numcal = Params.numcal + + if form_vals.has_key('numcal'): + try: + numcal = int(form_vals['numcal']) + except (TypeError, ValueError): + errormsgcode('invalid_numcal') + + + if numcal < 1: + numcal = 1 + elif numcal > 12: + numcal = 12 + + for index in range(numcal): + + cyear, cmonth = yearmonthplusoffset(year, month, index) + + cal_html = showsimpleeventcalendar(cyear, cmonth) + html.append(cal_html) + + return u''.join(html) + + + +# sort events in cal_events by length of days of the event +def comp_cal_events(xid, yid): + events = Globs.events + + if events[xid]['date_len'] > events[yid]['date_len']: + return -1 + elif events[xid]['date_len'] == events[yid]['date_len']: + if events[xid]['date_len'] == 1: + if events[xid]['starttime'] == events[yid]['starttime']: + return cmp(events[yid]['time_len'], events[xid]['time_len']) + else: + return cmp(events[xid]['starttime'], events[yid]['starttime']) + else: + return 0 + else: + return 1 + + +# sort events in the list by start date of the event +def comp_list_events(xid, yid): + events = Globs.events + + return cmp(events[xid]['startdate'], events[yid]['startdate']) + +# load events from wiki pages +def loadEvents(datefrom='', dateto='', nocache=0): + + request = Globs.request + + debug('Loading event information.') + + events = {} + labels = {} + cal_events = {} + raw_events = {} + + raw_events, labels = loadEventsFromWikiPages() + + # handling cal_events + if datefrom or dateto: + + # cache configurations + arena = Page(request, Globs.pagename) + eventkey = 'events' + filteredeventkey = 'events_%s-%s' % (datefrom, dateto) + caleventkey = 'calevents_%s-%s' % (datefrom, dateto) + + cache_events = caching.CacheEntry(request, arena, eventkey) + cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey) + cache_calevents = caching.CacheEntry(request, arena, caleventkey) + + dirty = 1 + + debug('Checking cal_events cache') + + if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())): + + try: + events = pickle.loads(cache_filteredevents.content()) + cal_events = pickle.loads(cache_calevents.content()) + debug('Cached event (filtered) information is used: total %d events' % len(events)) + dirty = 0 + except (pickle.UnpicklingError, IOError, EOFError, ValueError): + debug('Picke error at fetching cached events (filtered)') + events = {} + cal_events = {} + + + # if cache is dirty, update the cache + if dirty: + + debug('Checking event cache: it\'s dirty or requested to refresh') + debug('Building new cal_event information') + + try: + datefrom, dateto = int(datefrom), int(dateto) + except (TypeError, ValueError): + datefrom, dateto = 0, 0 + + clone_num = 0 + + for e_id in raw_events.keys(): + + cur_event = raw_events[e_id] + + # handling event recurrence + recur_freq = cur_event['recur_freq'] + + if recur_freq or recur_freq == -1: + + if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto: + + if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto): + # generating cal_events for iteself + events[e_id] = cur_event.copy() + insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate']) + + delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 ) + + if cur_event['recur_type'] == 'day': + + day_delta = int(recur_freq) + startdate = getdatetimefromstring(cur_event['startdate']) + datefrom_date = getdatetimefromstring(datefrom) + + if int(datefrom) > int(cur_event['startdate']): + diffs = datefrom_date - startdate + q_delta = diffs.days / day_delta + if diffs.days % day_delta > 0: + q_delta += 1 + else: + q_delta = 1 + + while 1: + + if q_delta == 0: + q_delta += 1 + continue + + recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta ) + recurred_enddate = recurred_startdate + delta_date_len + + new_startdate = formatdateobject(recurred_startdate) + new_enddate = formatdateobject(recurred_enddate) + + if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)): + break + + clone_num += 1 + clone_id = 'c%d' % clone_num + + events[clone_id] = cur_event.copy() + events[clone_id]['id'] = clone_id + events[clone_id]['startdate'] = new_startdate + events[clone_id]['enddate'] = new_enddate + events[clone_id]['clone'] = 1 + + insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate) + + q_delta += 1 + + elif cur_event['recur_type'] == 'week': + + day_delta = int(recur_freq) * 7 + + startdate = getdatetimefromstring(cur_event['startdate']) + datefrom_date = getdatetimefromstring(datefrom) + + if int(datefrom) > int(cur_event['startdate']): + diffs = datefrom_date - startdate + q_delta = diffs.days / day_delta + if diffs.days % day_delta > 0: + q_delta += 1 + else: + q_delta = 1 + + while 1: + + if q_delta == 0: + q_delta += 1 + continue + + recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta ) + recurred_enddate = recurred_startdate + delta_date_len + + new_startdate = formatdateobject(recurred_startdate) + new_enddate = formatdateobject(recurred_enddate) + + if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)): + break + + clone_num += 1 + clone_id = 'c%d' % clone_num + + events[clone_id] = cur_event.copy() + events[clone_id]['id'] = clone_id + events[clone_id]['startdate'] = new_startdate + events[clone_id]['enddate'] = new_enddate + events[clone_id]['clone'] = 1 + + insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate) + + q_delta += 1 + + + elif cur_event['recur_type'] == 'weekday': + + syear, smonth, sday = getdatefield(cur_event['startdate']) + cyear, cmonth, cday = getdatefield(str(datefrom)) + + recur_weekday = calendar.weekday(syear, smonth, sday) + + while 1: + + firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth) + firstmatch = (recur_weekday - firstweekday) % 7 + 1 + + if recur_freq == -1: + therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1] + else: + #XXX should handle error + try: + therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1] + except IndexError: + if Params.showlastweekday: + # if no matched weekday, the last weekday will be displayed + therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1] + else: + # if no matched weekday, no event will be displayed + cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1) + continue + + + recurred_startdate = datetime.date(cyear, cmonth, therecur_day) + recurred_enddate = recurred_startdate + delta_date_len + + new_startdate = formatdateobject(recurred_startdate) + new_enddate = formatdateobject(recurred_enddate) + + if int(new_startdate) < int(datefrom) or new_startdate == cur_event['startdate']: + cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1) + continue + + if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)): + break + + clone_num += 1 + clone_id = 'c%d' % clone_num + + events[clone_id] = cur_event.copy() + events[clone_id]['id'] = clone_id + events[clone_id]['startdate'] = new_startdate + events[clone_id]['enddate'] = new_enddate + events[clone_id]['clone'] = 1 + + insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate) + + cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1) + + + elif cur_event['recur_type'] == 'month': + + cyear, cmonth, therecurday = getdatefield(cur_event['startdate']) + + while 1: + + cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq) + firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth) + recur_day = therecurday + if daysinmonth < recur_day: + recur_day = daysinmonth + new_startdate = formatDate(cyear, cmonth, recur_day) + + if int(new_startdate) < int(datefrom): + continue + + recurred_startdate = datetime.date(cyear, cmonth, recur_day) + recurred_enddate = recurred_startdate + delta_date_len + + new_startdate = formatdateobject(recurred_startdate) + new_enddate = formatdateobject(recurred_enddate) + + if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)): + break + + clone_num += 1 + clone_id = 'c%d' % clone_num + + events[clone_id] = cur_event.copy() + events[clone_id]['id'] = clone_id + events[clone_id]['startdate'] = new_startdate + events[clone_id]['enddate'] = new_enddate + events[clone_id]['clone'] = 1 + + insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate) + + elif cur_event['recur_type'] == 'year': + + ryear, rmonth, rday = getdatefield(cur_event['startdate']) + cyear, cmonth, cday = getdatefield(str(datefrom)) + + while 1: + + ryear += recur_freq + new_startdate = formatDate(ryear, rmonth, rday) + + if int(new_startdate) < int(datefrom): + continue + + if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)): + break + + recurred_startdate = datetime.date(ryear, rmonth, rday) + recurred_enddate = recurred_startdate + delta_date_len + + new_startdate = formatdateobject(recurred_startdate) + new_enddate = formatdateobject(recurred_enddate) + + clone_num += 1 + clone_id = 'c%d' % clone_num + + events[clone_id] = cur_event.copy() + events[clone_id]['id'] = clone_id + events[clone_id]['startdate'] = new_startdate + events[clone_id]['enddate'] = new_enddate + events[clone_id]['clone'] = 1 + + insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate) + + else: + + if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto): + events[e_id] = cur_event.copy() + insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate']) + + + # sort cal_events + # store event list into global variables in order to sort them + Globs.events = events + + for eachdate in cal_events.keys(): + cal_events[eachdate].sort(comp_cal_events) + + # cache update + if not nocache: + cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL)) + cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL)) + + else: + events = raw_events + + # store event list into global variables in order to sort them + Globs.events = events + + Globs.labels = labels + + debug(u'Total %d events are loaded finally.' % len(events)) + debug(u'Total %d labels are loaded finally.' % len(labels)) + + return events, cal_events, labels + + + +def loadEventsFromWikiPages(): + + events = {} + labels = {} + cached_event_loaded = 0 + dirty = 0 + + eventrecord_list = [] + labelrecord_list = [] + eventpages = [] + stored_errmsg = '' + + request = Globs.request + category = Params.category + + # cache configurations + arena = Page(request, Globs.pagename) + + eventkey = 'events' + labelkey = 'labels' + pagelistkey = 'eventpages' + errmsglistkey = 'eventcalerrormsglist' + + cache_events = caching.CacheEntry(request, arena, eventkey) + cache_labels = caching.CacheEntry(request, arena, labelkey) + cache_pages = caching.CacheEntry(request, arena, pagelistkey) + cache_errmsglist = caching.CacheEntry(request, arena, errmsglistkey) + + # page list cache + + debug('Checking page list cache') + + # check the time at which page list cache has been created + + cp_mtime = cache_pages.mtime() + timedelta_days = 9999 + + if cp_mtime: + cp_date = datetime.datetime.fromtimestamp(cp_mtime) + today = datetime.datetime.fromtimestamp(time.time()) + datediff = today - cp_date + timedelta_days = datediff.days + debug('Time from page list cache built = %s' % datediff) + + + if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1: + categorypages = searchPages(request, 'category:'+category) + for page in categorypages: + eventpages.append(page.page_name) + cache_pages.update('\n'.join(eventpages)) + debug('New page list is built: %d pages<p>%s</p>' % (len(eventpages), "<br/>\n".join(eventpages))) + else: + eventpages = cache_pages.content().split('\n') + debug('Cached page list is used: %d pages<p>%s</p>' % (len(eventpages), "<br/>\n".join(eventpages))) + + if not Globs.page_action == 'refresh': + # check the cache validity + for page_name in eventpages: + + p = Page(request, page_name) + e_ref = page_name + + if cache_events.needsUpdate(p._text_filename()) or cache_labels.needsUpdate(p._text_filename()) or cache_errmsglist.needsUpdate(p._text_filename()): + dirty = 1 + break + else: + dirty = 1 + + if dirty: + # generating events + debug('dirty') + + dirty_local = 0 + debug_records = {} + + eventrecordkey = 'eventrecords' + labelrecordkey = 'labelrecords' + errmsgkey = 'eventcalerrormsg' + + # fetch event records from each page in the category + for page_name in eventpages: + + p = Page(request, page_name) + e_ref = page_name + + cache_errmsg = caching.CacheEntry(request, p, errmsgkey) + cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey) + cache_labelrecords = caching.CacheEntry(request, p, labelrecordkey) + + if cache_eventrecords.needsUpdate(p._text_filename()) or cache_labelrecords.needsUpdate(p._text_filename()) or Globs.page_action == 'refresh': + page_content = p.get_raw_body() + eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref) + + debug_records[e_ref] = '%d events are fetched from %s' % (len(eventrecords), e_ref) + + # XXXXX + #debug('events: %s' % eventrecords) + #debug('labels: %s' % labelrecords) + + cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL)) + cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL)) + cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL)) + + stored_errmsg += Globs.errormsg + Globs.errormsg = '' + + else: + try: + eventrecords = pickle.loads(cache_eventrecords.content()) + labelrecords = pickle.loads(cache_labelrecords.content()) + Globs.errormsg = pickle.loads(cache_errmsg.content()) + + debug_records[e_ref] = '%d cached eventrecords are used from %s' % (len(eventrecords), e_ref) + + except (pickle.UnpicklingError, IOError, EOFError, ValueError): + dirty = 1 + page_content = p.get_raw_body() + eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref) + debug_records[e_ref] = '%d eventrecords are fetched from %s due to pickle error' % (len(eventrecords), e_ref) + + cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL)) + cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL)) + cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL)) + + eventrecord_list.append(eventrecords) + labelrecord_list.append(labelrecords) + + stored_errmsg += Globs.errormsg + Globs.errormsg = '' + + debug('Checking event cache: it\'s dirty or requested to refresh') + + for eventrecords in eventrecord_list: + for evtrecord in eventrecords: + e_id = evtrecord['id'] + events[e_id] = evtrecord + + for labelrecords in labelrecord_list: + for label in labelrecords: + c_id = label['name'] + if not labels.has_key(c_id): + labels[c_id] = label + else: + stored_errmsg += u'<li>%s\n' % geterrormsg('redefined_label', label['refer'], label['name']) + + # after generating updated events, update the cache + cache_events.update(pickle.dumps(events, PICKLE_PROTOCOL)) + cache_labels.update(pickle.dumps(labels, PICKLE_PROTOCOL)) + cache_errmsglist.update(pickle.dumps(stored_errmsg, PICKLE_PROTOCOL)) + + debug('Event information is newly built: total %d events' % len(events)) + + + else: + + debug('Checking event cache: still valid') + + try: + events = pickle.loads(cache_events.content()) + labels = pickle.loads(cache_labels.content()) + stored_errmsg = pickle.loads(cache_errmsglist.content()) + + cached_event_loaded = 1 + + debug('Cached event information is used: total %d events' % len(events)) + + except (pickle.UnpicklingError, IOError, EOFError, ValueError): + " " +1 + events = {} + labels = {} + stored_errmsg = '' + + debug('Picke error at fetching cached events') + + Globs.errormsg = stored_errmsg + # end of updating events block + return events, labels + + + +def getEventRecordFromPage(pagecontent, referpage): + + request = Globs.request + + eventrecords = [] + labelrecords = [] + page_bgcolor = '' + page_description = '' + + e_num = 0 + + # fetch the page default bgcolor + regex_page_bgcolor = r""" +(?P<req_field>^[ ]+default_bgcolor::[ ]+) +( + (?P<pagebgcolor>\#[0-9a-fA-F]{6}) + \s*? + $ +)? +""" + + pattern = re.compile(regex_page_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + match = pattern.search(pagecontent) + + if match: + if match.group('pagebgcolor'): + page_bgcolor = match.group('pagebgcolor') + else: + errormsg( geterrormsg('invalid_default_bgcolor', referpage) ) + + + # fetch the page default description + regex_page_description = r""" +(?P<req_field>^[ ]+default_description::[ ]+) +( + (?P<pagedescription>.*?) + \s*? + $ +)? +""" + + pattern = re.compile(regex_page_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + match = pattern.search(pagecontent) + + if match: + if match.group('pagedescription'): + page_description = match.group('pagedescription') + else: + errormsg( geterrormsg('empty_default_description', referpage) ) + + # fetch the label definition + regex_label_definition = r""" +(?P<reqfield>^[ ]+label_def::[ ]+) +( + (?P<name>[^,^:^\s]+?) + [,: ]+ + (?P<bgcolor>\#[0-9a-fA-F]{6}) + \s*? + $ +)? +""" + + + pattern = re.compile(regex_label_definition, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + match = pattern.findall(pagecontent) + + if match: + + for matchitem in match: + + labelitem = {} + + label_name = matchitem[2] + label_bgcolor = matchitem[3] + + if label_name and label_bgcolor: + labelitem['name'] = label_name + labelitem['bgcolor'] = label_bgcolor + labelitem['refer'] = referpage + + labelrecords.append(labelitem) + else: + errormsg( geterrormsg('empty_label_definition', referpage) ) + continue + + + # fetch event item + regex_eventitem = r""" +(?P<eventitem> + (?P<heading>^\s*(?P<hmarker>=+)\s(?P<eventtitle>.*?)\s(?P=hmarker) $) + (?P<eventdetail> + .*? + (?= + ^\s*(?P<nexthmarker>=+)\s(?P<nexteventtitle>.*?)\s(?P=nexthmarker) $ + | \Z + ) + ) +) +""" + + pattern = re.compile(regex_eventitem, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + match = pattern.findall(pagecontent) + + if match: + + for matchitem in match: + + eventitem = {} + + eventtitle = matchitem[3] + eventdetail = matchitem[4] + + e_headid = getheadingid(request, referpage, eventtitle) + + if not eventdetail: + continue + + #debug('Examininng "%s" event from %s ..' % (eventtitle, referpage)) + + try: + e_start_date, e_start_time, e_end_date, e_end_time, e_bgcolor, e_label, e_description, e_recur_freq, e_recur_type, e_recur_until = geteventfield(eventdetail) + except EventcalError, errmsgcode: + + if not errmsgcode.value == 'pass': + errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) ) + + continue + + #except TypeError, ValueError: + # errormsg('undefined') + # continue + + # set default values + if not e_bgcolor: + e_bgcolor = page_bgcolor + + if not e_description: + e_description = page_description + + e_num += 1 + e_id = 'e_%s_%d' % (referpage, e_num) + + eventitem['id'] = e_id + eventitem['title'] = eventtitle + eventitem['startdate'] = e_start_date + eventitem['starttime'] = e_start_time + eventitem['enddate'] = e_end_date + eventitem['endtime'] = e_end_time + eventitem['title'] = eventtitle + eventitem['refer'] = referpage + eventitem['bgcolor'] = e_bgcolor + eventitem['label'] = e_label + eventitem['description'] = e_description + eventitem['recur_freq'] = e_recur_freq + eventitem['recur_type'] = e_recur_type + eventitem['recur_until'] = e_recur_until + + try: + eventitem['date_len'] = diffday(e_start_date, e_end_date) + 1 + eventitem['clone'] = 0 + eventitem['hid'] = e_headid + + if eventitem['date_len'] == 1 and e_start_time and e_end_time: + eventitem['time_len'] = difftime(e_start_time, e_end_time) + 1 + else: + eventitem['time_len'] = 0 + + except EventcalError, errmsgcode: + debug('Failed to add "%s" event from %s ..' % (eventtitle, referpage)) + errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) ) + continue + + eventrecords.append(eventitem) + + #debug('Added "%s" event from %s ..' % (eventtitle, referpage)) + + return eventrecords, labelrecords + + + +def geteventfield(detail): + + + # START DATE REGEX ---------------------------- + regex_startdate = r""" +(?P<reqfield>^[ ]+start::(?=[ ]+)) +( + (?P<startdate> + [ ]+ + ( + (?P<startdate1> + (?P<startyear1>19\d{2} | 20\d{2} | \d{2} ) + [./-] + (?P<startmonth1>1[012] | 0[1-9] | [1-9]) + [./-] + (?P<startday1>3[01] | 0[1-9] | [12]\d | [1-9]) + ) + | + (?P<startdate2> + (?P<startmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec) + [ ]+ + (?P<startday2>3[01] | 0[1-9] | [12]\d | [1-9]) + (?: st | nd | rd | th )? + [ ,]+ + (?P<startyear2>19\d{2} | 20\d{2} | \d{2}) + ) + | + (?P<startdate3> + (?P<startyear3>19\d{2} | 20\d{2} | \d{2} ) + (?P<startmonth3>1[012] | 0[1-9]) + (?P<startday3>3[01] | 0[1-9] | [12]\d) + ) + ) + ) + (?P<starttime> + [ ,]+ + ( + (?P<starttime1> + (?P<starthour1> 1[0-2] | [0]?[1-9] ) + ( + (?: [.:]) + (?P<startminute1>[0-5]\d{0,1} | [6-9]) + )? + [ ]* + (?P<am1> am | pm | p | a ) + ) + | + (?P<starttime2> + (?P<starthour2> | [01]\d{0,1} | 2[0-3] | [1-9]) + ( + (?: [.:]) + (?P<startminute2>[0-5]\d{0,1} | [6-9]) + )? + ) + | + (?P<starttime3> + (?P<starthour3> [01]\d | 2[0-3]) + (?P<startminute3> [0-5]\d)? + ) + | + (?P<starttime4> + (?P<starthour4> 0[1-9] | 1[0-2]) + (?P<startminute4> [0-5]\d)? + [ ]* + (?P<am4> am | pm | p | a ) + ) + ) + )? + \s*? + $ +)? +""" + + + + # END DATE REGEX ---------------------------- + regex_enddate = r""" +(?P<reqfield>^[ ]+end::(?=[ ]+)) +( + (?P<enddate> + [ ]+ + ( + (?P<enddate1> + (?P<endyear1>19\d{2} | 20\d{2} | \d{2} ) + [./-] + (?P<endmonth1>1[012] | 0[1-9] | [1-9]) + [./-] + (?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9]) + ) + | + (?P<enddate2> + (?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec) + [ ]+ + (?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9]) + (?: st | nd | rd | th )? + [ ,]+ + (?P<endyear2>19\d{2} | 20\d{2} | \d{2}) + ) + | + (?P<enddate3> + (?P<endyear3>19\d{2} | 20\d{2} | \d{2} ) + (?P<endmonth3>1[012] | 0[1-9]) + (?P<endday3>3[01] | 0[1-9] | [12]\d) + ) + ) + )? + (?P<endtime> + [ ,]+ + ( + (?P<endtime1> + (?P<endhour1> 1[0-2] | [0]?[1-9] ) + ( + (?: [.:]) + (?P<endminute1>[0-5]\d{0,1} | [6-9]) + )? + [ ]* + (?P<am1> am | pm | p | a ) + ) + | + (?P<endtime2> + (?P<endhour2> | [01]\d{0,1} | 2[0-3] | [1-9]) + ( + (?: [.:]) + (?P<endminute2>[0-5]\d{0,1} | [6-9]) + )? + ) + | + (?P<endtime3> + (?P<endhour3> [01]\d | 2[0-3]) + (?P<endminute3> [0-5]\d)? + ) + | + (?P<endtime4> + (?P<endhour4> 0[1-9] | 1[0-2]) + (?P<endminute4> [0-5]\d)? + [ ]* + (?P<am4> am | pm | p | a ) + ) + ) + )? + \s*? + $ +)? +""" + + regex_bgcolor = r""" +(?P<reqfield>^[ ]+bgcolor::[ ]+) +( + (?P<bgcolor>\#[0-9a-fA-F]{6})? + \s*? + $ +)? +""" + + regex_description = r""" +(?P<reqfield>^[ ]+description::[ ]+) +( + (?P<description>.*?) + \s*? + $ +)? +""" + + + regex_recur = r""" +(?P<reqfield>^[ ]+recur::[ ]+) +( + (?P<recur_freq>\d+|last) + \s+ + (?P<recur_type>weekday|day|week|month|year) + ( + \s+ + (?P<recur_until_req>until) + \s+ + (?P<recur_until> + (?P<enddate> + (?P<enddate1> + (?P<endyear1>19\d{2} | 20\d{2} | \d{2} ) + [./-] + (?P<endmonth1>1[012] | 0[1-9] | [1-9]) + [./-] + (?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9]) + ) + | + (?P<enddate2> + (?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec) + \s+ + (?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9]) + (?: st | nd | rd | th )? + [\s,]+ + (?P<endyear2>19\d{2} | 20\d{2} | \d{2}) + ) + | + (?P<enddate3> + (?P<endyear3>19\d{2} | 20\d{2} | \d{2} ) + (?P<endmonth3>1[012] | 0[1-9]) + (?P<endday3>3[01] | 0[1-9] | [12]\d) + ) + )? + )? + )? + \s*? + $ +)? +""" + + regex_label = r""" +(?P<reqfield>^[ ]+label::[ ]+) +( + (?P<name>[^,^:^\s]+?) + \s*? + $ +)? +""" + + + # need help on regular expressions for more efficient/flexible form + + # compile regular expression objects + + pattern_startdate = re.compile(regex_startdate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + pattern_enddate = re.compile(regex_enddate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + pattern_label = re.compile(regex_label, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + pattern_description = re.compile(regex_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + pattern_recur = re.compile(regex_recur, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE) + + ##################### retrieve startdate + match = pattern_startdate.search(detail) + + if match: + + if match.group('startdate'): + + # yyyy/mm/dd: 2006/05/10; 06/05/10, + if match.group('startdate1'): + if len(match.group('startyear1')) == 2: + startyear = '20%s' % match.group('startyear1') + else: + startyear = match.group('startyear1') + + startmonth = match.group('startmonth1') + startday = match.group('startday1') + + # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06 + elif match.group('startdate2'): + if len(match.group('startyear2')) == 2: + startyear = '20%s' % match.group('startyear2') + else: + startyear = match.group('startyear2') + + startmonth = getNumericalMonth(match.group('startmonth2')) + if not startmonth: + raise EventcalError('invalid_startdate') + + startday = match.group('startday2') + + # yyyymmdd: 20060510, 060510 + elif match.group('startdate3'): + if len(match.group('startyear3')) == 2: + startyear = '20%s' % match.group('startyear3') + else: + startyear = match.group('startyear3') + + startmonth = match.group('startmonth3') + startday = match.group('startday3') + + startdate = '%d/%02d/%02d' % (int(startyear), int(startmonth), int(startday)) + + else: + startdate = '' + + if match.group('starttime'): + + # 12h with ':': 12:00; 9:00pm + if match.group('starttime1'): + starthour = int(match.group('starthour1')) + if match.group('startminute1'): + startmin = int(match.group('startminute1')) + else: + startmin = 0 + + if starthour < 12 and match.group('am1').lower().startswith('p'): + starthour += 12 + + # 24h with ':': 12:00; 23:00 + elif match.group('starttime2'): + starthour = int(match.group('starthour2')) + if match.group('startminute2'): + startmin = int(match.group('startminute2')) + else: + startmin = 0 + + # 24h without ':': 1200; 2300 + elif match.group('starttime3'): + starthour = int(match.group('starthour3')) + if match.group('startminute3'): + startmin = int(match.group('startminute3')) + else: + startmin = 0 + + # 12h without ':': 1200; 0900pm + elif match.group('starttime4'): + + starthour = int(match.group('starthour4')) + if match.group('startminute4'): + startmin = int(match.group('startminute4')) + else: + startmin = 0 + + if starthour < 12 and match.group('am4').lower().startswith('p'): + starthour += 12 + + starttime = '%02d:%02d' % (int(starthour), int(startmin)) + + else: + starttime = '' + + if not startdate: + raise EventcalError('invalid_start') + + else: + raise EventcalError('pass') + + ##################### retrieve enddate + match = pattern_enddate.search(detail) + + if match: + + if match.group('enddate'): + # yyyy/mm/dd: 2006/05/10; 06/05/10, + if match.group('enddate1'): + if len(match.group('endyear1')) == 2: + endyear = '20%s' % match.group('endyear1') + else: + endyear = match.group('endyear1') + + endmonth = match.group('endmonth1') + endday = match.group('endday1') + + # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06 + elif match.group('enddate2'): + if len(match.group('endyear2')) == 2: + endyear = '20%s' % match.group('endyear2') + else: + endyear = match.group('endyear2') + + endmonth = getNumericalMonth(match.group('endmonth2')) + if not endmonth: + raise EventcalError('invalid_enddate') + + endday = match.group('endday2') + + # yyyymmdd: 20060510, 060510 + elif match.group('enddate3'): + if len(match.group('endyear3')) == 2: + endyear = '20%s' % match.group('endyear3') + else: + endyear = match.group('endyear3') + + endmonth = match.group('endmonth3') + endday = match.group('endday3') + + enddate = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday)) + else: + enddate = '' + + if match.group('endtime'): + + # 12h with ':': 12:00; 9:00pm + if match.group('endtime1'): + endhour = int(match.group('endhour1')) + if match.group('endminute1'): + endmin = int(match.group('endminute1')) + else: + endmin = 0 + + if endhour < 12 and match.group('am1').lower() == 'pm': + endhour += 12 + + # 24h with ':': 12:00; 23:00 + elif match.group('endtime2'): + endhour = int(match.group('endhour2')) + if match.group('endminute2'): + endmin = int(match.group('endminute2')) + else: + endmin = 0 + + # 24h without ':': 1200; 2300 + elif match.group('endtime3'): + endhour = int(match.group('endhour3')) + if match.group('endminute3'): + endmin = int(match.group('endminute3')) + else: + endmin = 0 + + # 12h without ':': 1200; 0900pm + elif match.group('endtime4'): + + endhour = int(match.group('endhour4')) + if match.group('endminute4'): + endmin = int(match.group('endminute4')) + else: + endmin = 0 + + if endhour < 12 and match.group('am4').lower() == 'pm': + endhour += 12 + + endtime = '%02d:%02d' % (int(endhour), int(endmin)) + + else: + endtime = '' + + if not (enddate or endtime): + raise EventcalError('invalid_end') + + else: + enddate = '' + endtime = '' + + + ##################### retrieve bgcolor + match = pattern_bgcolor.search(detail) + + if match: + if match.group('bgcolor'): + bgcolor = match.group('bgcolor') + else: + errormsgcode('invalid_bgcolor') + bgcolor = '' + + else: + bgcolor = '' + + ##################### retrieve label + match = pattern_label.search(detail) + + if match: + if match.group('name'): + label = match.group('name') + else: + errormsgcode('invalid_label') + label = '' + + else: + label = '' + + ##################### retrieve description + match = pattern_description.search(detail) + + if match: + if match.group('description'): + description = match.group('description') + else: + errormsgcode('empty_description') + description = '' + else: + description = '' + + ##################### retrieve recurrence + match = pattern_recur.search(detail) + + if match: + + if match.group('recur_freq') and match.group('recur_type'): + + if match.group('recur_freq') == 'last': + if match.group('recur_type') == 'weekday': + recur_freq = -1 + recur_type = match.group('recur_type') + recur_until = match.group('recur_until') + else: + recur_freq = 0 + recur_type = '' + recur_until = '' + + else: + recur_freq = int(match.group('recur_freq')) + recur_type = match.group('recur_type') + + if match.group('recur_until_req'): + if match.group('recur_until'): + # yyyy/mm/dd: 2006/05/10; 06/05/10, + if match.group('enddate1'): + if len(match.group('endyear1')) == 2: + endyear = '20%s' % match.group('endyear1') + else: + endyear = match.group('endyear1') + + endmonth = match.group('endmonth1') + endday = match.group('endday1') + + # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06 + elif match.group('enddate2'): + if len(match.group('endyear2')) == 2: + endyear = '20%s' % match.group('endyear2') + else: + endyear = match.group('endyear2') + + endmonth = getNumericalMonth(match.group('endmonth2')) + if not endmonth: + raise EventcalError('invalid_recur_until') + + endday = match.group('endday2') + + # yyyymmdd: 20060510, 060510 + elif match.group('enddate3'): + if len(match.group('endyear3')) == 2: + endyear = '20%s' % match.group('endyear3') + else: + endyear = match.group('endyear3') + + endmonth = match.group('endmonth3') + endday = match.group('endday3') + + recur_until = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday)) + else: + raise EventcalError('invalid_recur_until') + + else: + recur_until = '' + + else: + raise EventcalError('invalid_recur') + + else: + recur_freq = 0 + recur_type = '' + recur_until = '' + + # check validity of each fields + + if (starttime or endtime): + if not endtime: + endtime = starttime + elif not starttime: + raise EventcalError('invalid_starttime') + + + # if no time, it's 1-day event + if not enddate: + enddate = startdate + + try: + syear, smonth, sday = getdatefield(startdate) + except (TypeError, ValueError): + raise EventcalError('invalid_startdate') + + try: + eyear, emonth, eday = getdatefield(enddate) + except (TypeError, ValueError): + raise EventcalError('invalid_enddate') + + if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday): + raise EventcalError('enddate_precede') + + # format date + startdate = formatDate(syear, smonth, sday) + enddate = formatDate(eyear, emonth, eday) + + if (starttime and endtime): + try: + shour, smin = gettimefield(starttime) + except (TypeError, ValueError): + raise EventcalError('invalid_starttime') + + try: + ehour, emin = gettimefield(endtime) + except (TypeError, ValueError): + raise EventcalError('invalid_endtime') + + if startdate == enddate: + if datetime.time(shour, smin) > datetime.time(ehour, emin): + raise EventcalError('endtime_precede') + + # format time + starttime = u'%02d%02d' %(shour, smin) + endtime = u'%02d%02d' %(ehour, emin) + + # check recurrent data + event_len = diffday(startdate, enddate) + if recur_freq: + + if recur_type == 'day': + if event_len > int(recur_freq): + raise EventcalError('len_recur_int') + + elif recur_type == 'week': + if event_len > int(recur_freq) * 7: + raise EventcalError('len_recur_int') + + elif recur_type == 'weekday': + if event_len > 25: + raise EventcalError('len_recur_int') + + elif recur_type == 'month': + if event_len > int(recur_freq) * 25: + raise EventcalError('len_recur_int') + + elif recur_type == 'year': + if event_len > int(recur_freq) * 365: + raise EventcalError('len_recur_int') + + if recur_until: + try: + ryear, rmonth, rday = getdatefield(recur_until) + except (TypeError, ValueError): + raise EventcalError('invalid_date') + + recur_until = formatDate(ryear, rmonth, rday) + + if int(recur_until) < int(enddate): + raise EventcalError('invalid_date') + + return startdate, starttime, enddate, endtime, bgcolor, label, description, recur_freq, recur_type, recur_until + + + +def converttext(targettext): + # Converts some special characters of html to plain-text style + # What else to handle? + + targettext = targettext.replace(u'&', '&') + targettext = targettext.replace(u'>', '>') + targettext = targettext.replace(u'<', '<') + targettext = targettext.replace(u'\n', '<br>') + targettext = targettext.replace(u'"', '"') + targettext = targettext.replace(u'\t', '    ') + targettext = targettext.replace(u' ', '  ') + + return targettext + + +# monthly view +def showeventcalendar(year, month): + + debug('Show Calendar: Monthly View') + + request = Globs.request + formatter = Globs.formatter + _ = request.getText + + wkend = Globs.wkend + months= Globs.months + wkdays = Globs.wkdays + + # get the calendar + monthcal = calendar.monthcalendar(year, month) + + # shows current year & month + html_header_curyearmonth = calhead_yearmonth(year, month, 'head_yearmonth') + + r7 = range(7) + + # shows header of week days + html_header_weekdays = [] + + for wkday in r7: + wday = _(wkdays[wkday]) + html_header_weekdays.append( calhead_weekday(wday, 'head_weekday') ) + html_header_weekdays = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays) + + # pending events for next row + next_pending = [] + + # gets previous, next month + day_delta = datetime.timedelta(days=-1) + cur_month = datetime.date(year, month, 1) + prev_month = cur_month + day_delta + + day_delta = datetime.timedelta(days=15) + cur_month_end = datetime.date(year, month, 25) + next_month = cur_month_end + day_delta + + prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month) + next_monthcal = calendar.monthcalendar(next_month.year, next_month.month) + + # shows days + html_week_rows = [] + + # set ranges of events + datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month) + dateto = u'%04d%02d06' % (next_month.year, next_month.month) + + # read all the events + events, cal_events, labels = loadEvents(datefrom, dateto) + + #debug(u' events: %s' % events) + #debug(u' cal_events: %s' % cal_events) + + for week in monthcal: + + # day head rows + html_headday_cols = [] + html_events_rows = [] + + for wkday in r7: + + day = week[wkday] + + if not day: + if week == monthcal[0]: + nb_day = prev_monthcal[-1][wkday] + else: + nb_day = next_monthcal[0][wkday] + + html_headday_cols.append( calhead_day_nbmonth(nb_day) ) + else: + html_headday_cols.append( calhead_day(year, month, day, wkday) ) + + html_headday_row = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols) + html_week_rows.append(html_headday_row) + + # dummy rows + html_headdummy_cols = [] + + for wkday in r7: + day = week[wkday] + if not day: + html_headdummy_cols.append( calshow_blankbox('head_dummy_nbmonth') ) + else: + html_headdummy_cols.append( calshow_blankbox('head_dummy') ) + + html_headdummy_cols = u'\r\n'.join(html_headdummy_cols) + html_week_rows.append(' <tr>\r\n%s </tr>\r\n' % html_headdummy_cols) + + # pending events for next row + pending = next_pending + next_pending = [] + + # show events + while 1: + event_left = 7 + colspan = -1 + html_events_cols = [] + + for wkday in r7: + + day = week[wkday] + + if not day: + if week == monthcal[0]: + cur_date = formatDate(prev_month.year, prev_month.month, prev_monthcal[-1][wkday]) + else: + cur_date = formatDate(next_month.year, next_month.month, next_monthcal[0][wkday]) + else: + cur_date = formatDate(year, month, day) + + # if an event is already displayed with colspan + if colspan > 0: + colspan -= 1 + if cal_events.has_key(cur_date) and lastevent in cal_events[cur_date]: + cal_events[cur_date].remove(lastevent) + + continue + + # if there is any event for this date + if cal_events.has_key(cur_date): + if len(cal_events[cur_date]) > 0: + + # if there is any pending event in the previous week + if wkday == 0 and len(pending) > 0: + todo_event_id = pending.pop(0) + if todo_event_id in cal_events[cur_date]: + cur_event = events[todo_event_id] + temp_len = diffday(cur_date, cur_event['enddate']) + 1 + + # calculate colspan value + if (7-wkday) < temp_len: + colspan = 7 - wkday + next_pending.append(cur_event['id']) + html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) ) + + else: + colspan = temp_len + html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) ) + + + cal_events[cur_date].remove(todo_event_id) + + colspan -= 1 + lastevent = todo_event_id + else: + debug('Warning: no such event in cal_events') + + continue + + # if there is no pending event in the previous week, start a new event + event_found = 0 + for e_id in cal_events[cur_date]: + + # if the start date of the event is current date + if events[e_id]['startdate'] == cur_date: + + cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))] + + # calculate colspan value + if (7-wkday) < cur_event['date_len']: + colspan = 7 - wkday + next_pending.append(cur_event['id']) + html_events_cols.append( calshow_eventbox(cur_event, colspan, 'pending', cur_date) ) + + else: + colspan = cur_event['date_len'] + html_events_cols.append( calshow_eventbox(cur_event, colspan, '', cur_date) ) + + colspan -= 1 + lastevent = cur_event['id'] + event_found = 1 + break + + # if the start date of the event is NOT current date + else: + + # pending event from previous month + if wkday == 0 and week == monthcal[0]: + + cur_event = events[cal_events[cur_date].pop(0)] + temp_len = diffday(cur_date, cur_event['enddate']) + 1 + + # calculate colspan value + if (7-wkday) < temp_len: + colspan = 7 - wkday + next_pending.append(cur_event['id']) + html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) ) + else: + colspan = temp_len + html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) ) + + colspan -= 1 + lastevent = cur_event['id'] + event_found = 1 + break + + # if there is no event to start + if not event_found: + if not day: + html_events_cols.append( calshow_blankbox('cal_nbmonth') ) + else: + html_events_cols.append( calshow_blankbox('cal_noevent') ) + event_left -= 1 + + else: + if not day: + html_events_cols.append( calshow_blankbox('cal_nbmonth') ) + else: + html_events_cols.append( calshow_blankbox('cal_noevent') ) + + event_left -= 1 + + # if there is NO event for this date + else: + if not day: + html_events_cols.append( calshow_blankbox('cal_nbmonth') ) + else: + html_events_cols.append( calshow_blankbox('cal_noevent') ) + + event_left -= 1 + + # if no event for this entry + if not event_left: + # ignore the previous entry + break + else: + html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols)) + + # show dummy blank slots for week height + left_blank_rows = 2 - len(html_events_rows) + + # remove the followings + if left_blank_rows > 0 and 0: + for i in range(left_blank_rows): + html_events_cols = [] + for wkday in r7: + day = week[wkday] + if not day: + html_events_cols.append( calshow_blankbox('cal_nbmonth') ) + else: + html_events_cols.append( calshow_blankbox('cal_noevent') ) + + html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols)) + + + # close the week slots + html_events_cols = [] + for wkday in r7: + day = week[wkday] + if not day: + html_events_cols.append( calshow_blankbox('cal_last_nbmonth') ) + else: + html_events_cols.append( calshow_blankbox('cal_last_noevent') ) + + html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols)) + + html_events_rows = u'\r\n'.join(html_events_rows) + html_week_rows.append(html_events_rows) + + html_calendar_rows = u'\r\n'.join(html_week_rows) + + html_cal_table = [ + u'\r\n<div id="eventcalendar">', + u'<table class="eventcalendar" %s>' % Params.monthlywidth, + u'%s' % html_header_curyearmonth, + u'%s' % html_header_weekdays, + u'%s' % html_calendar_rows, + u'</table>', + u'</div>', + ] + html_cal_table = u'\r\n'.join(html_cal_table) + + return html_cal_table + + + +# daily view +def showdailyeventcalendar(year, month, day): + + debug('Show Calendar: Daily View') + + request = Globs.request + formatter = Globs.formatter + _ = request.getText + + wkend = Globs.wkend + months= Globs.months + wkdays = Globs.wkdays + + cur_date = formatDate(year, month, day) + + # gets previous, next month + day_delta = datetime.timedelta(days=-1) + cur_month = datetime.date(year, month, 1) + prev_month = cur_month + day_delta + + day_delta = datetime.timedelta(days=15) + cur_month_end = datetime.date(year, month, 25) + next_month = cur_month_end + day_delta + + # set ranges of events + datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month) + dateto = u'%04d%02d06' % (next_month.year, next_month.month) + + # read all the events + events, cal_events, labels = loadEvents(datefrom, dateto) + + #debug(u' events: %s' % events) + #debug(u' cal_events: %s' % cal_events) + + # calculates hour_events + hour_events = {} + + if cal_events.has_key(cur_date): + for e_id in cal_events[cur_date]: + cur_event = events[e_id] + + if cur_event['date_len'] == 1 and cur_event['time_len'] > 0: + start_hour, start_min = gettimefield(cur_event['starttime']) + + if not hour_events.has_key(start_hour): + hour_events[start_hour] = [] + + hour_events[start_hour].append(e_id) + + #debug(u'hour_events: %s' % hour_events) + + # in-day events + html_calendar_rows = [] + html_hour_cols = {} + + slot_pending = {} + max_num_slots = 0 + hour_max_slots = {} + block_slots = [] + + start_hour_index = 0 + + r24 = range(24) + + for hour_index in r24: + + html_hour_cols[hour_index] = [] + hour_max_slots[hour_index] = 1 + html_hour_cols[hour_index].append( calshow_daily_hourhead(hour_index) ) + + if len(slot_pending) > 0 or hour_events.has_key(hour_index): + + #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending)) + if len(slot_pending) == 0: + if max_num_slots < 1: + max_num_slots = 1 + + for hour_lines in range(start_hour_index, hour_index): + hour_max_slots[hour_lines] = max_num_slots + + #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots)) + + block_slots.append(max_num_slots) + + max_num_slots = 0 + start_hour_index = hour_index + + for slot_index in range(max_num_slots): + if slot_pending.has_key(slot_index) and slot_pending[slot_index] > 0: + if slot_pending[slot_index] == 1: + del slot_pending[slot_index] + else: + slot_pending[slot_index] -= 1 + html_hour_cols[hour_index].append ( '' ) + + else: + if hour_events.has_key(hour_index) and len(hour_events[hour_index]) > 0: + e_id = hour_events[hour_index][0] + cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))] + html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) ) + slot_pending[slot_index] = cur_event['time_len'] - 1 + else: + if not ((len(slot_pending) > 0 and slot_index > max(slot_pending.keys())) or len(slot_pending) == 0): + html_hour_cols[hour_index].append ( calshow_blankeventbox() ) + + if hour_events.has_key(hour_index): + for tmp_cnt in range(len(hour_events[hour_index])): + e_id = hour_events[hour_index][0] + cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))] + html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) ) + slot_pending[max_num_slots] = cur_event['time_len'] - 1 + if slot_pending[max_num_slots] == 0: + del slot_pending[max_num_slots] + max_num_slots += 1 + + else: + html_hour_cols[hour_index].append ( calshow_blankeventbox() ) + #hour_max_slots[hour_index] = 1 + + if max_num_slots < 1: + max_num_slots = 1 + + for hour_lines in range(start_hour_index, hour_index): + hour_max_slots[hour_lines] = max_num_slots + + #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots)) + + block_slots.append(max_num_slots) + + max_num_slots = 0 + start_hour_index = hour_index + + + #debug('end: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending)) + + if max_num_slots < 1: + max_num_slots = 1 + + for hour_lines in range(start_hour_index, 24): + hour_max_slots[hour_lines] = max_num_slots + + #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, 23, max_num_slots)) + + block_slots.append(max_num_slots) + + #debug('hour_max_slots: %s' % hour_max_slots) + + + # calculates global colspan + if len(block_slots): + global_colspan = LCM(block_slots) + else: + global_colspan = 1 + + for hour_index in r24: + + colspan = global_colspan / hour_max_slots[hour_index] + width = 96 / hour_max_slots[hour_index] + + left_slots = hour_max_slots[hour_index] - (len(html_hour_cols[hour_index]) - 1) + + if left_slots > 0: + #debug('appending left %d slots: %d' % (left_slots, hour_index)) + html_hour_cols[hour_index].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) ) + + html_cols = u'\r\n'.join(html_hour_cols[hour_index]) % {'colspan': colspan, 'width': u'%d' % width} + html_cols = u'<tr>%s</tr>\r\n' % html_cols + + html_calendar_rows.append (html_cols) + + html_calendar_rows = u'\r\n'.join(html_calendar_rows) + + # shows current year & month + html_header_curyearmonthday = calhead_yearmonthday(year, month, day, 'head_yearmonth', global_colspan) + + # one-day long events + html_oneday_rows = [] + + #debug('before cal_events[cur_date] = %s' % cal_events[cur_date]) + + if cal_events.has_key(cur_date): + if len(cal_events[cur_date]) > 0: + for e_id in cal_events[cur_date]: + #debug('before cal_events[cur_date] = %s' % cal_events[cur_date]) + #debug('test events[%s] = %s' % (e_id, events[e_id])) + if events[e_id]['time_len'] <= 0 or events[e_id]['date_len'] > 1: + #cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))] + cur_event = events[e_id] + + if cur_event['startdate'] == cur_date: + if cur_event['enddate'] == cur_date: + str_status = '' + else: + str_status = 'pending' + else: + if cur_event['enddate'] == cur_date: + str_status = 'append' + else: + str_status = 'append_pending' + + tmp_html = u'<tr><td width="4%%" style="border-width: 0px; "> </td>%s</tr>' % calshow_daily_eventbox2(cur_event, global_colspan, str_status, cur_date) + html_oneday_rows.append( tmp_html ) + + #debug('after cal_events[cur_date] = %s' % cal_events[cur_date]) + else: + tmp_html = u'<tr><td width="4%%" style="border-width: 0px; "> </td>%s</tr>' % calshow_blankbox2('cal_daily_noevent', global_colspan) + html_oneday_rows.append( tmp_html ) + + #debug('after cal_events[cur_date] = %s' % cal_events[cur_date]) + #debug('html_oneday_rows = %s' % html_oneday_rows) + + html_oneday_rows = u'\r\n'.join(html_oneday_rows) + + + html_cal_table = [ + u'\r\n<div id="eventcalendar">', + u'<table class="eventcalendar" %s>' % Params.dailywidth, + u'<table border="0">', + u'%s' % html_header_curyearmonthday, + u'%s' % html_oneday_rows, + u'%s' % html_calendar_rows, + u'</table>', + u'</td></tr>', + u'</div>', + ] + html_cal_table = u'\r\n'.join(html_cal_table) + + return html_cal_table + + + +# weekly view +def showweeklyeventcalendar(year, month, day): + + debug('Show Calendar: Weekly View') + + request = Globs.request + formatter = Globs.formatter + _ = request.getText + + wkend = Globs.wkend + months= Globs.months + wkdays = Globs.wkdays + + cur_date = formatDate(year, month, day) + + # gets previous, next month + day_delta = datetime.timedelta(days=-1) + cur_month = datetime.date(year, month, 1) + prev_month = cur_month + day_delta + + day_delta = datetime.timedelta(days=15) + cur_month_end = datetime.date(year, month, 25) + next_month = cur_month_end + day_delta + + # set ranges of events + datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month) + dateto = u'%04d%02d06' % (next_month.year, next_month.month) + + # read all the events + events, cal_events, labels = loadEvents(datefrom, dateto) + + #debug(u' events: %s' % events) + #debug(u' cal_events: %s' % cal_events) + + # calculates hour_events + hour_events = {} + + first_date_week = getFirstDateOfWeek(year, month, day) + + + for dayindex in range(7): + hour_events[dayindex] = {} + + cur_date = first_date_week + datetime.timedelta(dayindex) + cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day) + + if cal_events.has_key(cur_date): + for e_id in cal_events[cur_date]: + cur_event = events[e_id] + + if cur_event['date_len'] == 1 and cur_event['time_len'] > 0: + start_hour, start_min = gettimefield(cur_event['starttime']) + + if not hour_events[dayindex].has_key(start_hour): + hour_events[dayindex][start_hour] = [] + + hour_events[dayindex][start_hour].append(e_id) + + #debug(u'hour_events: %s' % hour_events) + + # in-day events + html_calendar_rows = [] + html_hour_cols = {} + + slot_pending = {} + max_num_slots = {} + hour_max_slots = {} + block_slots = {} + + start_hour_index = {} + + r24 = range(24) + + for hour_index in r24: + + html_hour_cols[hour_index] = {} + hour_max_slots[hour_index] = {} + + #html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) ) + + for dayindex in range(7): + + if not max_num_slots.has_key(dayindex): + max_num_slots[dayindex] = 0 + + if not slot_pending.has_key(dayindex): + slot_pending[dayindex] = {} + + if not start_hour_index.has_key(dayindex): + start_hour_index[dayindex] = 0 + + if not block_slots.has_key(dayindex): + block_slots[dayindex] = [] + + html_hour_cols[hour_index][dayindex] = [] + hour_max_slots[hour_index][dayindex] = 1 + + if len(slot_pending[dayindex]) > 0 or hour_events[dayindex].has_key(hour_index): + + #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending[dayindex])) + if len(slot_pending[dayindex]) == 0: + if max_num_slots[dayindex] < 1: + max_num_slots[dayindex] = 1 + + for hour_lines in range(start_hour_index[dayindex], hour_index): + hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex] + + #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex])) + + block_slots[dayindex].append(max_num_slots[dayindex]) + + max_num_slots[dayindex] = 0 + start_hour_index[dayindex] = hour_index + + for slot_index in range(max_num_slots[dayindex]): + if slot_pending[dayindex].has_key(slot_index) and slot_pending[dayindex][slot_index] > 0: + if slot_pending[dayindex][slot_index] == 1: + del slot_pending[dayindex][slot_index] + else: + slot_pending[dayindex][slot_index] -= 1 + html_hour_cols[hour_index][dayindex].append ( '' ) + + else: + if hour_events[dayindex].has_key(hour_index) and len(hour_events[dayindex][hour_index]) > 0: + e_id = hour_events[dayindex][hour_index][0] + cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))] + html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) ) + slot_pending[dayindex][slot_index] = cur_event['time_len'] - 1 + else: + if not ((len(slot_pending[dayindex]) > 0 and slot_index > max(slot_pending[dayindex].keys())) or len(slot_pending[dayindex]) == 0): + html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() ) + + if hour_events[dayindex].has_key(hour_index): + for tmp_cnt in range(len(hour_events[dayindex][hour_index])): + e_id = hour_events[dayindex][hour_index][0] + cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))] + html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) ) + slot_pending[dayindex][max_num_slots[dayindex]] = cur_event['time_len'] - 1 + if slot_pending[dayindex][max_num_slots[dayindex]] == 0: + del slot_pending[dayindex][max_num_slots[dayindex]] + max_num_slots[dayindex] += 1 + + else: + html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() ) + #hour_max_slots[hour_index][dayindex] = 1 + + if max_num_slots[dayindex] < 1: + max_num_slots[dayindex] = 1 + + for hour_lines in range(start_hour_index[dayindex], hour_index): + hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex] + + #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex])) + + block_slots[dayindex].append(max_num_slots[dayindex]) + + max_num_slots[dayindex] = 0 + start_hour_index[dayindex] = hour_index + + global_colspan = {} + header_colspan = 0 + + for dayindex in range(7): + if max_num_slots[dayindex] < 1: + max_num_slots[dayindex] = 1 + + for hour_lines in range(start_hour_index[dayindex], 24): + hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex] + + block_slots[dayindex].append(max_num_slots[dayindex]) + + # calculates global colspan + if len(block_slots[dayindex]): + global_colspan[dayindex] = LCM(block_slots[dayindex]) + else: + global_colspan[dayindex] = 1 + + header_colspan += global_colspan[dayindex] + + + for hour_index in r24: + + html_cols_days = [] + + for dayindex in range(7): + + colspan = global_colspan[dayindex] / hour_max_slots[hour_index][dayindex] + width = (100 - 2) / 7 / hour_max_slots[hour_index][dayindex] + + left_slots = hour_max_slots[hour_index][dayindex] - len(html_hour_cols[hour_index][dayindex]) + + if left_slots > 0: + #debug('appending left %d slots: %d' % (left_slots, hour_index)) + html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) ) + + html_cols = u'\r\n'.join(html_hour_cols[hour_index][dayindex]) % {'colspan': colspan, 'width': "%d%%" % width} + html_cols_days.append(html_cols) + + html_cols_collected = u'\r\n'.join(html_cols_days) + html_cols = u'<tr>%s\r\n%s</tr>\r\n' % (calshow_weekly_hourhead(hour_index), html_cols_collected) + + html_calendar_rows.append (html_cols) + + html_calendar_rows = u'\r\n'.join(html_calendar_rows) + + # shows current year & month + html_header_curyearmonthday = calhead_yearmonthday2(year, month, day, 'head_yearmonth', header_colspan) + + # one-day long events + html_oneday_rows = {} + + #debug('before cal_events[cur_date] = %s' % cal_events[cur_date]) + + #first_date_week = getFirstDateOfWeek(year, month, day) + + html_oneday_rows = [] + + while 1: + html_oneday_cols = [] + cnt_blank_cols = 0 + pending = -1 + + for dayindex in range(7): + + if pending > 0: + pending -= 1 + html_oneday_cols.append('') + continue + else: + pending = -1 + + cur_date = first_date_week + datetime.timedelta(dayindex) + cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day) + + if cal_events.has_key(cur_date) and len(cal_events[cur_date]) > 0: + + tmpcount = len(cal_events[cur_date]) + for tmp_index in range(tmpcount): + cur_event = events[cal_events[cur_date].pop(0)] + + #debug('event poped out at %s: %s' % (cur_date, cur_event)) + + if (cur_event['startdate'] <= cur_date and dayindex == 0) or cur_event['startdate'] == cur_date: + if cur_event['time_len'] <= 0 or cur_event['date_len'] > 1: + + temp_len = diffday(cur_date, cur_event['enddate']) + 1 + + if cur_event['startdate'] == cur_date: + if temp_len <= 7 - dayindex: + str_status = '' + else: + str_status = 'pending' + else: + if temp_len <= 7 - dayindex: + str_status = 'append' + else: + str_status = 'append_pending' + + if temp_len > 7 - dayindex: + temp_len = 7 - dayindex + + pending = temp_len - 1 + + tmp_global_colspan = 0 + for tmp_index in range(dayindex, dayindex+temp_len): + tmp_global_colspan += global_colspan[tmp_index] + + #debug('event appended at %s with pending=%d: %s' % (cur_date, pending, cur_event)) + + html_oneday_cols.append( calshow_weekly_eventbox2(cur_event, tmp_global_colspan, 14 * temp_len, str_status, cur_date) ) + break + + if pending < 0: + html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) ) + cnt_blank_cols += 1 + + else: + html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) ) + cnt_blank_cols += 1 + + if cnt_blank_cols >= 7: + if len(html_oneday_rows) == 0: + html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_oneday_cols) + html_oneday_rows.append (html_oneday_cols) + break + else: + html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_oneday_cols) + html_oneday_rows.append (html_oneday_cols) + + html_date_rows = [] + + for dayindex in range(7): + cur_date = first_date_week + datetime.timedelta(dayindex) + html_date_rows.append(calhead_weeklydate(cur_date.year, cur_date.month, cur_date.day, global_colspan[dayindex])) + + html_date_rows = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_date_rows) + + html_oneday_rows = u'\r\n'.join(html_oneday_rows) + + html_cal_table = [ + u'\r\n<div id="eventcalendar">', + u'<table class="eventcalendar" %s>' % Params.weeklywidth, + u'<table border="0">', + u'%s' % html_header_curyearmonthday, + u'%s' % html_date_rows, + u'%s' % html_oneday_rows, + u'%s' % html_calendar_rows, + u'</table>', + u'</td></tr>', + u'</div>', + ] + html_cal_table = u'\r\n'.join(html_cal_table) + + return html_cal_table + + + +# simple view +def showsimpleeventcalendar(year, month): + + debug('Show Calendar: Simple View') + + request = Globs.request + formatter = Globs.formatter + _ = request.getText + monthstyle_us = Globs.month_style_us + + wkend = Globs.wkend + months= Globs.months + wkdays = Globs.wkdays + + # get the calendar + monthcal = calendar.monthcalendar(year, month) + + # shows current year & month + html_header_curyearmonth = calhead_yearmonth(year, month, 'simple_yearmonth') + + r7 = range(7) + + # shows header of week days + html_header_weekdays = [] + + for wkday in r7: + wday = wkdays[wkday] + html_header_weekdays.append( calhead_weekday(wday, 'simple_weekday') ) + html_header_weekdays = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays) + + # gets previous, next month + day_delta = datetime.timedelta(days=-1) + cur_month = datetime.date(year, month, 1) + prev_month = cur_month + day_delta + + day_delta = datetime.timedelta(days=15) + cur_month_end = datetime.date(year, month, 25) + next_month = cur_month_end + day_delta + + prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month) + next_monthcal = calendar.monthcalendar(next_month.year, next_month.month) + + # shows days + html_week_rows = [] + + # set ranges of events + datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month) + dateto = u'%04d%02d06' % (next_month.year, next_month.month) + + # read all the events + events, cal_events, labels = loadEvents(datefrom, dateto) + + maketip_js = [] + + for week in monthcal: + + # day head rows + html_headday_cols = [] + html_events_rows = [] + + for wkday in r7: + + day = week[wkday] + + if not day: + if week == monthcal[0]: + nb_day = prev_monthcal[-1][wkday] + else: + nb_day = next_monthcal[0][wkday] + + html_headday_cols.append( simple_eventbox(year, month, day, nb_day, 'simple_nb') ) + else: + cur_date = formatDate(year, month, day) + + if cal_events.has_key(cur_date): + html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_event') ) + + if monthstyle_us: + tiptitle = u'%s %d, %d' % (months[month-1], day, year) + else: + tiptitle = u'%d / %02d / %02d' % (year, month, day) + + date_today = datetime.date( year, month, day ) + tiptitle = u'%s (%s)' % (tiptitle, _(wkdays[date_today.weekday() - calendar.firstweekday()])) + + tiptext = [] + + for e_id in cal_events[cur_date]: + cur_event = events[e_id] + if cur_event['starttime']: + time_string = u'(%s:%s)' % (cur_event['starttime'][:2], cur_event['starttime'][2:]) + else: + time_string = '' + + title = wikiutil.escape(cur_event['title']).replace("'","\\'") + description = wikiutil.escape(cur_event['description']).replace("'","\\'") + + tiptext.append( u'<b>%s</b>%s %s' % (title, time_string, description) ) + + tiptext = u'<br>'.join(tiptext) + + maketip_js.append("maketip('%s','%s','%s');" % (cur_date, tiptitle, tiptext)) + else: + html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_noevent') ) + + html_headday_row = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols) + html_week_rows.append(html_headday_row) + + html_calendar_rows = u'\r\n'.join(html_week_rows) + + html_tooltip_result = """\ +<script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script> +<div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div> +<script language="JavaScript" type="text/javascript"> +<!-- +%s +// --> +</script> + +""" % (request.cfg.url_prefix, "\n".join(maketip_js)) + + + html_cal_table = [ + u'\r\n<div id="eventcalendar">', + u'%s' % html_tooltip_result, + u'<table class="simplecalendar" %s>' % Params.simplewidth, + u'%s' % html_header_curyearmonth, + u'%s' % html_header_weekdays, + u'%s' % html_calendar_rows, + u'</table>', + u'</div>', + ] + html_cal_table = u'\r\n'.join(html_cal_table) + + return html_cal_table + + +# show calendar head (year & month) +def calhead_yearmonth(year, month, headclass): + + request = Globs.request + + months = Globs.months + monthstyle_us = Globs.month_style_us + cal_action = Globs.cal_action + page_name = Globs.pagename + + page_url = Globs.pageurl + + nextyear, nextmonth = yearmonthplusoffset(year, month, 1) + prevyear, prevmonth = yearmonthplusoffset(year, month, -1) + + prevlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, prevyear, prevmonth, getquerystring(['numcal']) ) + nextlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, nextyear, nextmonth, getquerystring(['numcal'])) + curlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, year, month, getquerystring(['numcal'])) + + if monthstyle_us: + stryearmonth = u'%s %d' % (months[month-1], year) + strnextmonth = u'%s %d' % (months[nextmonth-1], nextyear) + strprevmonth = u'%s %d' % (months[prevmonth-1], prevyear) + else: + stryearmonth = u'%d / %02d' % (year, month) + strnextmonth = u'%d / %02d' % (nextyear, nextmonth) + strprevmonth = u'%d / %02d' % (prevyear, prevmonth) + + html = [ + u' <tr>', + u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth), + u' <td colspan="5" class="%s"><a href="%s" title="Go/Refresh this month">%s</a></td>' % (headclass, curlink, stryearmonth), + u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth), + u' </tr>', + ] + + return u'\r\n'.join(html) + + +# show calendar head (year & month & day) +def calhead_yearmonthday(year, month, day, headclass, colspan): + + request = Globs.request + _ = request.getText + + months = Globs.months + monthstyle_us = Globs.month_style_us + cal_action = Globs.cal_action + page_name = Globs.pagename + wkdays = Globs.wkdays + + page_url = Globs.pageurl + + date_today = datetime.date( year, month, day ) + prevdate = date_today - datetime.timedelta(days=1) + nextdate = date_today + datetime.timedelta(days=1) + + prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) ) + nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal'])) + curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal'])) + + if monthstyle_us: + stryearmonth = u'%s %d, %d' % (months[month-1], day, year) + strnextmonth = u'%s %d, %d' % (months[nextdate.month-1], nextdate.day, nextdate.year) + strprevmonth = u'%s %d, %d' % (months[prevdate.month-1], prevdate.day, prevdate.year) + else: + stryearmonth = u'%d / %02d / %02d' % (year, month, day) + strnextmonth = u'%d / %02d / %02d' % (nextdate.year, nextdate.month, nextdate.day) + strprevmonth = u'%d / %02d / %02d' % (prevdate.year, prevdate.month, prevdate.day) + + #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday()])) + stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()])) + + html = [ + u'<tr><td width="4%" style="border: none;"> </td>', + u'<td colspan="%d" style="border: none;">' % colspan, + u'<table width="95%">', + u' <tr>', + u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth), + u' <td class="%s"><a href="%s" title="Go/Refresh this day">%s</a></td>' % (headclass, curlink, stryearmonth), + u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth), + u' </tr>', + u'</table>', + u'</td></tr>', + ] + + return u'\r\n'.join(html) + +# show calendar head for weekly view (year & month & day) +def calhead_yearmonthday2(year, month, day, headclass, colspan): + + request = Globs.request + _ = request.getText + + months = Globs.months + monthstyle_us = Globs.month_style_us + cal_action = Globs.cal_action + page_name = Globs.pagename + wkdays = Globs.wkdays + + page_url = Globs.pageurl + + date_today = datetime.date( year, month, day ) + prevdate = date_today - datetime.timedelta(days=7) + nextdate = date_today + datetime.timedelta(days=7) + + first_date_week = getFirstDateOfWeek(year, month, day) + prevdate_f = first_date_week - datetime.timedelta(days=7) + nextdate_f = first_date_week + datetime.timedelta(days=7) + + last_date_week = first_date_week + datetime.timedelta(days=6) + prevdate_l = last_date_week - datetime.timedelta(days=7) + nextdate_l = last_date_week + datetime.timedelta(days=7) + + prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) ) + nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal'])) + curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal'])) + + if monthstyle_us: + stryearmonth = u'%s %d, %d ~ %s %d, %d' % (months[first_date_week.month-1], first_date_week.day, first_date_week.year, months[last_date_week.month-1], last_date_week.day, last_date_week.year) + strnextmonth = u'%s %d, %d ~ %s %d, %d' % (months[nextdate_f.month-1], nextdate_f.day, nextdate_f.year, months[nextdate_l.month-1], nextdate_l.day, nextdate_l.year) + strprevmonth = u'%s %d, %d ~ %s %d, %d' % (months[prevdate_f.month-1], prevdate_f.day, prevdate_f.year, months[prevdate_l.month-1], prevdate_l.day, prevdate_l.year) + else: + stryearmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (first_date_week.year, first_date_week.month, first_date_week.day, last_date_week.year, last_date_week.month, last_date_week.day) + strnextmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (nextdate_f.year, nextdate_f.month, nextdate_f.day, nextdate_l.year, nextdate_l.month, nextdate_l.day) + strprevmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (prevdate_f.year, prevdate_f.month, prevdate_f.day, prevdate_l.year, prevdate_l.month, prevdate_l.day) + + #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()])) + + html = [ + u'<tr><td width="2%" style="border: none;"> </td>', + u'<td colspan="%d" style="border: none;">' % colspan, + u'<table width="95%">', + u' <tr>', + u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth), + u' <td class="%s"><a href="%s" title="Go/Refresh this week">%s</a></td>' % (headclass, curlink, stryearmonth), + u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth), + u' </tr>', + u'</table>', + u'</td></tr>', + ] + + return u'\r\n'.join(html) + + +# show calendar head for weekly view (the date) +def calhead_weeklydate(year, month, day, colspan): + + request = Globs.request + _ = request.getText + + months = Globs.months + monthstyle_us = Globs.month_style_us + cal_action = Globs.cal_action + page_name = Globs.pagename + wkdays = Globs.wkdays + + page_url = Globs.pageurl + + date_today = datetime.date( year, month, day ) + + if monthstyle_us: + stryearmonth = u'%s %d' % (months[month-1], day) + else: + stryearmonth = u'%02d / %02d' % (month, day) + + stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()])) + curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day) + + cyear, cmonth, cday = gettodaydate() + if cyear == year and cmonth == month and cday == day: + bgcolor = 'background-color: #FFFFAA;' + else: + bgcolor = '' + + if not Params.changeview: + curlink = '#' + + html = [ + u'<td colspan="%d" style="border-width: 2px; text-align: center; font-size: 9pt; %s">' % (colspan, bgcolor), + u'<a href="%s">%s</a>' % (curlink, stryearmonth), + u'</td>', + ] + + return u'\r\n'.join(html) + +# show days in simple +def simple_eventbox(year, month, day, wkday, boxclass): + wkend = Globs.wkend + if wkday == wkend: + html_text = u'<font color="#aa7744">%s</font>' % day + else: + html_text = u'%s' % day + + cyear, cmonth, cday = gettodaydate() + + page_url = Globs.pageurl + linkkey = u'%d%02d%02d' % (year, month, day) + + curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day) + + if not Params.changeview: + curlink = '#' + + curlink = u'<a href="%s" onMouseOver="tip(\'%s\')" onMouseOut="untip()" >%s</a>' % (curlink, linkkey, html_text) + + if boxclass == 'simple_nb': + html = u' <td class="%s"> </td>\r\n' % boxclass + else: + if cyear == year and cmonth == month and cday == day: + html = u' <td class="%s_today">%s</td>\r\n' % (boxclass, curlink) + else: + html = u' <td class="%s">%s</td>\r\n' % (boxclass, curlink) + + return html + + +# show weekday +def calhead_weekday(wday, headclass): + if headclass == 'simple_weekday': + html = u' <td class="%s">%s</td>\r\n' % (headclass, wday[0]) + else: + html = u' <td class="%s">%s</td>\r\n' % (headclass, wday) + + return html + + +# show days of current month +def calhead_day(year, month, day, wkday): + + request = Globs.request + page_name = Globs.pagename + wkend = Globs.wkend + + if wkday == wkend: + html_text = u'<font color="#FF3300">%s</font>' % day + else: + html_text = u'%s' % day + + page_url = Globs.pageurl + html_text = u'<a href="%s?calaction=daily&caldate=%d%02d%02d">%s</a>' % (page_url, year, month, day, html_text) + + cyear, cmonth, cday = gettodaydate() + + if (not wkday) and Params.showweeknumber: + html_text = u'%s <font size="1" color="#aaaaaa"><i>(%d)</i></font>' % (html_text, (int(datetime.date(year, month, day).strftime('%W')) + 1)) + + if cyear == year and cmonth == month and cday == day: + html = u' <td class="head_day_today"> %s</td>\r\n' % html_text + else: + html = u' <td class="head_day"> %s</td>\r\n' % html_text + + return html + + +# show days of previous or next month +def calhead_day_nbmonth(day): + + html = u' <td class="head_day_nbmonth"> %s</td>\r\n' % day + return html + + +# show blank calendar box +def calshow_blankbox(classname): + html = u' <td class="%s"> </td>' % classname + return html + + +def calshow_blankbox2(classname, colspan): + html = u' <td class="%s" colspan="%d"> </td>' % (classname, colspan) + return html + + +# show eventbox +def calshow_eventbox(event, colspan, status, cur_date): + + if status: + status = u'_%s' % status + + title = event['title'] + eid = event['id'] + startdate = event['startdate'] + enddate = event['enddate'] + starttime = event['starttime'] + endtime = event['endtime'] + description = event['description'] + bgcolor = event['bgcolor'] + + if not bgcolor: + if Globs.labels: + labels = Globs.labels + # for backward compatibility + if event.has_key('label'): + if labels.has_key(event['label']): + bgcolor = labels[event['label']]['bgcolor'] + + year, month, day = getdatefield(cur_date) + + if bgcolor: + bgcolor = 'background-color: %s;' % bgcolor + else: + bgcolor = 'background-color: %s;' % Params.bgcolor + + if (startdate == enddate) and starttime: + shour, smin = gettimefield(starttime) + + link = [ + u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n', + u'<td nowrap class="cal_eventbox_time">%02d:%02d </td>\r\n' % (shour, smin), + u'<td class="cal_eventbox_time_event">', + u'%s' % showReferPageParsed(event, 'title', 1), + u'</td>\r\n</tr></table>', + ] + link = u''.join(link) + else: + link = u'%s' % showReferPageParsed(event, 'title', 1) + + + html = [ + u' <td class="cal_eventbox" colspan="%d"><table class="cal_event">' % colspan, + u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link), + u' </table></td>', + ] + + return u'\r\n'.join(html) + + +# show eventbox +def calshow_daily_eventbox2(event, colspan, status, cur_date): + if status: + status = u'_%s' % status + + title = event['title'] + eid = event['id'] + startdate = event['startdate'] + enddate = event['enddate'] + starttime = event['starttime'] + endtime = event['endtime'] + description = event['description'] + bgcolor = event['bgcolor'] + + if not bgcolor: + labels = Globs.labels + # for backward compatibility + if event.has_key('label'): + if labels.has_key(event['label']): + bgcolor = labels[event['label']]['bgcolor'] + + year, month, day = getdatefield(cur_date) + + if bgcolor: + bgcolor = 'background-color: %s;' % bgcolor + else: + bgcolor = 'background-color: %s;' % Params.bgcolor + + if (startdate == enddate) and starttime: + shour, smin = gettimefield(starttime) + + link = [ + u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n', + u'<td width="10" nowrap style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top; font-size: 7pt; color: #000000;">%02d:%02d </td>\r\n' % (shour, smin), + u'<td style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top;font-size: 8pt;">', + u'%s' % showReferPageParsed(event, 'title', 1), + u'</td>\r\n</tr></table>', + ] + link = u''.join(link) + else: + link = u'%s' % showReferPageParsed(event, 'title', 1) + + + html = [ + u' <td colspan="%d" style="width: 96%%; border-width: 0px; line-height: 11px;"><table class="cal_event">' % colspan, + u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link), + u' </table></td>', + ] + + return u'\r\n'.join(html) + + +# show eventbox +def calshow_daily_eventbox(event): + + title = event['title'] + eid = event['id'] + startdate = event['startdate'] + enddate = event['enddate'] + starttime = event['starttime'] + endtime = event['endtime'] + description = event['description'] + bgcolor = event['bgcolor'] + time_len = event['time_len'] + + if not bgcolor: + labels = Globs.labels + # for backward compatibility + if event.has_key('label'): + if labels.has_key(event['label']): + bgcolor = labels[event['label']]['bgcolor'] + + if bgcolor: + bgcolor = 'background-color: %s;' % bgcolor + else: + bgcolor = 'background-color: %s;' % Params.bgcolor + + shour, smin = gettimefield(starttime) + ehour, emin = gettimefield(endtime) + + html = [ + u' <td colspan="%(colspan)d"', + u' style="%s border-width: 2px; border-color: #000000; vertical-align: top; font-size: 9pt; ' % bgcolor, + u' width: %(width)s;" ', + u' rowspan="%(rowspan)d">' % { 'rowspan': time_len }, + u' %02d:%02d ~ %02d:%02d<br>%s' % (shour, smin, ehour, emin, showReferPageParsed(event, 'title', 1)), + u' </td>', + ] + + return u'\r\n'.join(html) + + +# show eventbox +def calshow_weekly_eventbox(event): + + title = event['title'] + eid = event['id'] + startdate = event['startdate'] + enddate = event['enddate'] + starttime = event['starttime'] + endtime = event['endtime'] + description = event['description'] + bgcolor = event['bgcolor'] + time_len = event['time_len'] + + if not bgcolor: + labels = Globs.labels + # for backward compatibility + if event.has_key('label'): + if labels.has_key(event['label']): + bgcolor = labels[event['label']]['bgcolor'] + + if bgcolor: + bgcolor = 'background-color: %s;' % bgcolor + else: + bgcolor = 'background-color: %s;' % Params.bgcolor + + shour, smin = gettimefield(starttime) + ehour, emin = gettimefield(endtime) + + html = [ + u' <td colspan="%(colspan)d"', + u' style="%s;' % bgcolor, + u' width: %(width)s;" ', + u' rowspan="%(rowspan)d"' % { 'rowspan': time_len }, + u' class="cal_weekly_eventbox">', + u' %s' % (showReferPageParsed(event, 'title', 1).replace("%","%%")), + u' </td>', + ] + + return u'\r\n'.join(html) + +# show blank eventbox +def calshow_blankeventbox(): + + html = [ + u' <td colspan="%(colspan)d" style="width: %(width)s;" class="cal_blankeventbox"> </td>', + ] + + return u'\r\n'.join(html) + + +# show eventbox +def calshow_weekly_eventbox2(event, colspan, width, status, cur_date): + if status: + status = u'_%s' % status + + title = event['title'] + eid = event['id'] + startdate = event['startdate'] + enddate = event['enddate'] + starttime = event['starttime'] + endtime = event['endtime'] + description = event['description'] + bgcolor = event['bgcolor'] + + year, month, day = getdatefield(cur_date) + + if not bgcolor: + labels = Globs.labels + # for backward compatibility + if event.has_key('label'): + if labels.has_key(event['label']): + bgcolor = labels[event['label']]['bgcolor'] + + if bgcolor: + bgcolor = 'background-color: %s;' % bgcolor + else: + bgcolor = 'background-color: %s;' % Params.bgcolor + + link = u'%s' % showReferPageParsed(event, 'title', 1) + + html = [ + u' <td colspan="%d" style="width: %d%%;" class="cal_weekly_eventbox2"><table class="cal_event">' % (colspan, width), + u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link), + u' </table></td>', + ] + + return u'\r\n'.join(html) + + + +# show blank eventbox +def calshow_blankeventbox2(colspan, width): + html = [ + u' <td colspan="%(colspan)d"' % { 'colspan': colspan }, + u' style="width: %(width)s;" class="cal_blankeventbox"> </td>' % { 'width': '%d%%%%' % width }, + ] + + return u'\r\n'.join(html) + + + +def calshow_daily_hourhead(hour): + + if hour >= Globs.dailystart and hour <= Globs.dailyend: + bgcolor = "#ffffcc" + else: + bgcolor = "#ffeeee" + + html = [ + u' <td class="cal_hourhead" style="background-color: %s; width: 4%%%%;">%02d</td>' % (bgcolor, hour), + ] + + return u'\r\n'.join(html) + +def calshow_weekly_hourhead(hour): + + if hour >= Globs.dailystart and hour <= Globs.dailyend: + bgcolor = "#ffffcc" + else: + bgcolor = "#ffeeee" + + html = [ + u' <td class="cal_hourhead" style="width: 2%%%%; background-color: %s; ">%02d</td>' % (bgcolor, hour), + ] + + return u'\r\n'.join(html) + + + +def insertcalevents(cal_events, datefrom, dateto, e_id, e_start_date, e_end_date): + + if not (int(e_start_date) > dateto or int(e_end_date) < datefrom): + + e_start_date = str(max(int(e_start_date), datefrom)) + e_end_date = str(min(int(e_end_date), dateto)) + + day_delta = datetime.timedelta(days=1) + e_start_year, e_start_month, e_start_day = getdatefield(e_start_date) + cur_datetime = datetime.date(e_start_year, e_start_month, e_start_day) + + while 1: + tmp_record_date = formatdateobject(cur_datetime) + + if not cal_events.has_key(tmp_record_date): + cal_events[tmp_record_date] = [] + cal_events[tmp_record_date].append(e_id) + + if tmp_record_date == e_end_date: + break + + cur_datetime = cur_datetime + day_delta + +# date format should be like '20051004' for 2005, Oct., 04 +def diffday(date1, date2): + + try: + year1, month1, day1 = getdatefield(date1) + year2, month2, day2 = getdatefield(date2) + tmp_diff = datetime.date(year2, month2, day2) - datetime.date(year1, month1, day1) + except (TypeError, ValueError): + raise EventcalError('invalid_date') + + return tmp_diff.days + + +# time format should be like '1700' for 05:00pm +def difftime(time1, time2): + + try: + hour1, min1 = gettimefield(time1) + hour2, min2 = gettimefield(time2) + + except (TypeError, ValueError): + raise EventcalError('invalid_time') + + if min2 == 0 and hour2 != 0 and hour1 != hour2: + hour2 -= 1 + + tmp_diff = hour2 - hour1 + + return tmp_diff + + + +def formatDate(year, month, day): + # returns like: '20051004' + return u'%4d%02d%02d' % (year, month, day) + +def formatTime(hour, min): + # returns like: '1700' + return u'%2d%02d' % (hour, min) + + +def formatdateobject(obj_date): + + return formatDate(obj_date.year, obj_date.month, obj_date.day) + +def formattimeobject(obj_time): + + return formatTime(obj_time.hour, obj_time.minute) + + +def debug(astring): + Globs.debugmsg += u'<li>%s\n' % astring + + +def geterrormsg(errmsgcode, refer='', title='', hid=''): + + if errmsgcode == 'invalid_caldate': + msg = 'Warning: Invalid value for "caldate" parameter. Shows today.' + + elif errmsgcode == 'invalid_curdate': + msg = 'Warning: Invalid value for "curdate" parameter. Shows today.' + + elif errmsgcode == 'invalid_numcal': + msg = 'Warning: Invalid value of "numcal" parameter. Shows one.' + + elif errmsgcode == 'invalid_startdate': + msg = 'Error: Invalid startdate format. Not handled.' + + elif errmsgcode == 'invalid_enddate': + msg = 'Error: Invalid enddate format. Not handled.' + + elif errmsgcode == 'invalid_start': + msg = 'Error: Invalid start date or time format. Not handled.' + + elif errmsgcode == 'invalid_end': + msg = 'Error: Invalid end date or time format. Not handled.' + + elif errmsgcode == 'invalid_date': + msg = 'Error: Invalid date format. Not handled.' + + elif errmsgcode == 'enddate_precede': + msg = 'Error: Enddate precedes startdate. Not handled.' + + elif errmsgcode == 'invalid_starttime': + msg = 'Error: Invalid starttime format. Not handled.' + + elif errmsgcode == 'invalid_endtime': + msg = 'Error: Invalid endtime format. Not handled.' + + elif errmsgcode == 'invalid_time': + msg = 'Error: Invalid time format. Not handled.' + + elif errmsgcode == 'endtime_precede': + msg = 'Error: Enddate precedes startdate. Not handled.' + + elif errmsgcode == 'len_recur_int': + msg = 'Error: Event length should be smaller than recurrence interval. Not handled.' + + elif errmsgcode == 'invalid_bgcolor': + msg = 'Warning: Invalid bgcolor format. Ignored.' + + elif errmsgcode == 'invalid_label': + msg = 'Warning: Invalid label format. Ignored.' + + elif errmsgcode == 'invalid_recur': + msg = 'Error: Invalid recurrence format. Not handled.' + + elif errmsgcode == 'invalid_recur_until': + msg = 'Error: Invalid end date (until) format of the recurrence. Not handled.' + + elif errmsgcode == 'empty_description': + msg = 'Warning: Empty description. Ignored.' + + elif errmsgcode == 'invalid_default_bgcolor': + msg = 'Warning: Invalid default_bgcolor format. Ignored.' + + elif errmsgcode == 'empty_default_description': + msg = 'Warning: Empty default_description. Ignored.' + + elif errmsgcode == 'redefined_label': + msg = 'Warning: Redefined label. Ignored.' + + elif errmsgcode == 'empty_label_definition': + msg = 'Warning: Invalid label definition. Ignored.' + + else: + msg = 'undefined: %s' % errmsgcode + + if refer: + msg = '%s (%s)' % (msg, getReferLink(refer, title, hid)) + + return msg + + +def errormsgcode(errmsgcode): + + errormsg(geterrormsg(errmsgcode)) + + +def errormsg(astring): + Globs.errormsg += u'<li>%s\n' % astring + + +def yearmonthplusoffset(year, month, offset): + month = month+offset + # handle offset and under/overflows - quick and dirty, yes! + while month < 1: + month = month + 12 + year = year - 1 + while month > 12: + month = month - 12 + year = year + 1 + return year, month + + +def formatcfgdatetime(strdate, strtime=''): + + if not strdate: + return '' + + request = Globs.request + + if request.user.date_fmt: + date_fmt = request.user.date_fmt + else: + date_fmt = request.cfg.date_fmt + + if request.user.datetime_fmt: + datetime_fmt = request.user.datetime_fmt + else: + datetime_fmt = request.cfg.datetime_fmt + + ## XXX HACK + datetime_fmt = datetime_fmt.replace(':%S', '') + + date_fmt = str(date_fmt) + datetime_fmt = str(datetime_fmt) + + year, month, day = getdatefield(str(strdate)) + if strtime: + hour, min = gettimefield(str(strtime)) + objdatetime = datetime.datetime(year, month, day, hour, min) + return objdatetime.strftime(datetime_fmt) + else: + objdate = getdatetimefromstring(strdate) + return objdate.strftime(date_fmt) + + +def getdatetimefromstring(strdate): + year, month, day = getdatefield(str(strdate)) + return datetime.date( year, month, day ) + + +def searchPages(request, needle): + # Search the pages and return the results + query = search.QueryParser().parse_query(needle) + results = search.searchPages(request, query) + #results.sortByPagename() + + return results.hits + + html = [] + for page in results.hits: + html.append(page.page_name) + + html = u',<br>'.join(html) + return u'%s<p>%s' % (Params.category, html) + + +def getFirstDateOfWeek(year, month, day): + orgday = datetime.date(year, month, day) + yearBase, week, weekday = orgday.isocalendar() + baseDate = datetime.date(yearBase, 2, 1) + yearBase, weekBase, dayBase = baseDate.isocalendar() + days = datetime.timedelta(1-dayBase+(week-weekBase)*7) + theday = baseDate + days + + theday -= datetime.timedelta(7 - calendar.firstweekday()) + + if orgday - theday >= datetime.timedelta(7): + theday += datetime.timedelta(7) + + return theday + +def gcd(a,b): + """Return greatest common divisor using Euclid's Algorithm.""" + while b: + a, b = b, a % b + + return a + +def lcm(a,b): + """ + Return lowest common multiple.""" + return (a*b)/gcd(a,b) + +def LCM(terms): + "Return lcm of a list of numbers." + return reduce(lambda a,b: lcm(a,b), terms) + + +def getNumericalMonth(strMonth): + months = Globs.months + + strMonth = strMonth.lower() + + index = 0 + for monthitem in months: + index += 1 + if monthitem.lower().startswith(strMonth): + return index + + return 0 + + +def getReferLink(refer, title='', hid=''): + request = Globs.request + + refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer)) + + if hid: + refer_url += '#%s' % hid + + if title: + refer = '%s: "%s"' % (refer, title) + + return '<a href="%s">%s</a>' % (refer_url, refer) +