# -*- coding: utf-8 -*-
import time, calendar
from datetime import datetime, date, timedelta
from cStringIO import StringIO
from trac.wiki.api import WikiSystem
from trac.wiki.macros import WikiMacroBase
from trac.util import *
from trac.web.chrome import add_stylesheet
from trac.web import Href
from trac.util.datefmt import utc, to_timestamp
from trac.resource import get_resource_url
from tracrendezvous.event.model import Event
from ctdotools.utils import get_tz
__all__ = ['RendezVousesCalendarMacro',]
class EventHeaderMacro(WikiMacroBase):
def expand_macro(self, formatter, name, content):
try:
e_id = int(content)
except ValueError:
return ""
event = Event.fetch_one(self.env, e_id, show_all=True, days=60)
if not event or not event.periodic():
return ""
rows = []
rows.append("""""")
session_tzname, selected_tz = get_tz(formatter.req.session.get('tz', self.env.config.get("trac", "default_timezone") or None))
rows.append("
%s |
" % event.rrules_explained)
if hasattr(event, "followups"):
l = []
for ev in event.followups:
local_time_begin = ev.time_begin.astimezone(selected_tz)
local_time_end = ev.time_end.astimezone(selected_tz)
link_label = "%s %s - %s %s" % (local_time_begin.strftime("%d.%m.%Y %H:%M"), local_time_begin.tzinfo.tzname(None), local_time_end.strftime("%d.%m.%Y %H:%M"), local_time_end.tzinfo.tzname(None))
link = "events/%s/%s" % (event.e_id, ev.time_begin.strftime("%Y-%m-%d"))
if WikiSystem(self.env).has_page(link):
row = '%s' % (formatter.href.wiki(link) or formatter.href.event("createpage", event.e_id, ev.time_begin.strftime("%Y-%m-%d")), link_label)
else:
row = '%s' % (formatter.href.event("createpage", event.e_id, ev.time_begin.strftime("%Y-%m-%d")), link_label)
l.append(row)
rows.append(" |
" % "".join(l))
return """""" % (formatter.href.event(event.e_id), event.name, "".join(rows))
class RendezVousesCalendarMacro(WikiMacroBase):
"""Inserts a small calendar with scheduled RendezVouses with optional locations
constraint
Examples:
{{{
[[WikiCalendar]]
[[WikiCalendar(location1,location2,foo_location)]]
}}}
"""
def expand_macro(self, formatter, name, content):
today = time.localtime()
http_param_year = formatter.req.args.get('year', '')
http_param_month = formatter.req.args.get('month', '')
if content:
args = content.split(',')
else:
args = []
if http_param_year == "":
# not clicked on a prev or next button
if len(args) >= 1 and args[0] <> "*":
# year given in macro parameters
year = int(args[0])
else:
# use current year
year = today.tm_year
else:
# year in http params (clicked by user) overrides everything
year = int(http_param_year)
if http_param_month == "":
# not clicked on a prev or next button
if len(args) >= 2 and args[1] <> "*":
# month given in macro parameters
month = int(args[1])
else:
# use current month
month = today.tm_mon
else:
# month in http params (clicked by user) overrides everything
month = int(http_param_month)
wiki_page_format = "%Y-%m-%d"
if len(args) >= 4:
wiki_page_format = args[3]
curr_day = None
if year == today.tm_year and month == today.tm_mon:
curr_day = today.tm_mday
thispageURL = Href(get_resource_url(self.env, formatter.resource, formatter.href))
# for the prev/next navigation links
prevMonth = month-1
prevYear = year
nextMonth = month+1
nextYear = year
# check for year change (KISS version)
if prevMonth == 0:
prevMonth = 12
prevYear -= 1
if nextMonth == 13:
nextMonth = 1
nextYear += 1
# 9-tuple for use with time.* functions requiring a struct_time
mydate = [0] * 8 + [-1] # AS: breaks Python 2.4
# building the output
buff = []
buff.append(u'''\
''')
import locale
encoding = locale.getlocale()[1]
# prev year link
mydate[0:2] = [year-1, month]
mydate_label = time.strftime('%B %Y', tuple(mydate))
if encoding:
mydate_label = mydate_label.decode(encoding)
buff.append(u'<<' % (
thispageURL(month=month, year=year-1),
mydate_label
))
# prev month link
mydate[0:2] = [prevYear, prevMonth]
mydate_label = time.strftime('%B %Y', tuple(mydate))
if encoding:
mydate_label = mydate_label.decode(encoding)
buff.append(u'<' % (
thispageURL(month=prevMonth, year=prevYear),
mydate_label
))
# the caption
mydate[0:2] = [year, month]
mydate_label = time.strftime('%B %Y', tuple(mydate))
if encoding:
mydate_label = mydate_label.decode(encoding)
buff.append(mydate_label)
# next month link
mydate[0:2] = [nextYear, nextMonth]
mydate_label = time.strftime('%B %Y', tuple(mydate))
if encoding:
mydate_label = mydate_label.decode(encoding)
buff.append(u'>' % (
thispageURL(month=nextMonth, year=nextYear),
mydate_label))
# next year link
mydate[0:2] = [year+1, month]
mydate_label = time.strftime('%B %Y', tuple(mydate))
if encoding:
mydate_label = mydate_label.decode(encoding)
buff.append(u'>>' % (
thispageURL(month=month, year=year+1),
mydate))
buff.append(u'\n\n')
for day in calendar.weekheader(2).split():
buff.append(u'%s | ' % day)
buff.append(u'
\n\n')
last_week_prev_month = calendar.monthcalendar(prevYear, prevMonth)[-1];
first_week_next_month = calendar.monthcalendar(nextYear, nextMonth)[0];
w = -1
db = self.env.get_db_cnx()
cursor = db.cursor()
day_list = []
foo,last_day = calendar.monthrange(year, month)
start_dt = datetime(year, month, 1, tzinfo=utc)
end_dt = datetime(year, month, last_day, 23, 59, tzinfo=utc)
rts = Event.fetch_by_period_dict(self.env, start_dt, end_dt)
session_tzname, selected_tz = get_tz(formatter.req.session.get('tz', self.env.config.get("trac", "default_timezone") or None))
def _f(t):
assert type(t) == Event
real_begin = t.time_begin.astimezone(selected_tz)
real_end = t.time_end.astimezone(selected_tz)
return u'%s:
%s' % (formatter.href.event(t.e_id), real_begin.strftime("%d.%m.%Y %H:%M"), real_end.strftime("%d.%m.%Y %H:%M"), real_begin.tzinfo.tzname(None), unicode(t.location.name), unicode(t.name))
for week in calendar.monthcalendar(year, month):
buff.append(u'\n')
w = w+1
d = -1
for day in week:
d = d+1
# calc date and update CSS classes
mydate[0:3] = [year, month, day]
classes = u'day'
title = u''
if not day:
classes += u' adjacent_month'
if w == 0:
day = last_week_prev_month[d]
mydate[0:3] = [prevYear, prevMonth, day]
else:
day = first_week_next_month[d]
mydate[0:3] = [nextYear, nextMonth, day]
else:
if day == curr_day:
classes += u' today'
title += u"Heute:"
wiki = time.strftime(wiki_page_format, tuple(mydate))
actual_date = date(mydate[0], mydate[1], mydate[2])
if rts and rts.has_key(actual_date):
rt = rts[actual_date]
for t in rt:
if actual_date.day != t.time_end.day:
tomorrow = actual_date + timedelta(1)
rts[tomorrow].append(t)
text = u"".join([_f(t) for t in rt])
classes += u" active"
title += u" %d Termin(e)" % len(rt)
daylink = unicode(formatter.href.event("by-day", "%d-%d-%d" % tuple(mydate[:3])))
#text = text.encode("utf8")
buff.append(u'\n%s
| ' % (classes.strip(), daylink, title, day, text))
else:
title += u"Noch keine Termine"
daylink = formatter.href.event("new", "%d-%d-%d" % tuple(mydate[:3]))
buff.append(u'\n%s | ' % (classes, daylink, title, day))
buff.append(u'\n
')
buff.append(u'\n\n
\n')
table = u"".join(buff)
return table