source: weekplanplugin/trunk/weekplan/macro.py

Last change on this file was 17664, checked in by lucid, 4 years ago

WeekPlanPlugin: Python3 compatibility.
(fix #13736)

File size: 5.5 KB
RevLine 
[13632]1# -*- coding: utf-8 -*-
2
[17664]3from __future__ import division
4
[13632]5import datetime
[16113]6import math
[17664]7from functools import reduce
[13632]8
9from trac.core import *
[14089]10from trac.util.datefmt import parse_date, utc
[17477]11from trac.util.html import tag
[13632]12from trac.web.chrome import (Chrome, add_script, add_script_data,
13                             add_stylesheet, ITemplateProvider)
14from trac.wiki.api import parse_args
15from trac.wiki.macros import WikiMacroBase
16
[14175]17from weekplan.core import WeekPlanModule
[13632]18
[14175]19
[13632]20class WeekPlanMacro(WikiMacroBase):
21    """Show a week-by-week calendar and allow planning events.
22   
23    The arguments are:
24    * `plan`: Id of the shown collection of events. (required)
25      * Can be a `|`-separated list of multiple plans.
26    * `start`: A date  in the first week shown. (Defaults to today.)
27    * `weeks`: Number of weeks shown. (Defaults to one.)
[16113]28    * `weeksperrow`: Number of weeks per row. (Defaults to one.)
[13768]29    * `width`: Width of the calendar. (Defaults to 400.)
30    * `rowheight`: Height of one row of the calendar. (Defaults to 100.)
31    * `showweekends`: Show Saturdays and Sundays (Defaults to hidden.)
32    * `color`: Color of the events. (Defaults to `#3A87AD|#39AC60|#D7A388|#88BDD7|#9939AC|#AC9939`.)
[13632]33      * Can be a `|`-separated list of multiple colors. Each plan uses a different colors if multiple plans are specified.
[13770]34    * `label`: Labels shown instead of the plan ids. (Defaults to the plan ids.)
35      * Can be a `|`-separated list of multiple labels. Each plan uses a different label if multiple plans are specified.
[13769]36    * `hidelegend`: Show a legend below the calendar. (Defaults to shown.)
[13632]37    Example:
38    {{{
39        [[WeekPlan(plan=example, start=1.1.2014,weeks=10)]]
40    }}}
41    """
42
43    def expand_macro(self, formatter, name, content):
44        args, kw = parse_args(content)
45        args = [arg.strip() for arg in args]
46
47        plan_ids = kw.get('plan', '').split('|')
48        if not plan_ids:
49            raise TracError('Missing plan id')
50
[14175]51        colors = kw.get('color', '#38A|#4B6|#DA8|#9CD|#CAD|#CC7').split('|')
[17664]52        colors = dict(zip(plan_ids, colors*((len(plan_ids)-1)//len(colors)+1)))
[13632]53
[13770]54        labels = [label for label in kw.get('label', '').split('|') if label]
55        labels = dict(zip(plan_ids, labels + plan_ids[len(labels):]))
56
[13632]57        start = kw.get('start')
58        if start is None:
[14089]59            start = datetime.date.today()
[13632]60        else:
[14089]61            start = parse_date(start, utc).date()
[13632]62        weeks = int(kw.get('weeks', 1))
[16113]63        weeksperrow = int(kw.get('weeksperrow', 1))
[13632]64
65        width = int(kw.get('width', 400))
66        rowheight = int(kw.get('rowheight', 100))
67
68        req = formatter.req
69        context = formatter.context
[14175]70        core = WeekPlanModule(self.env)
[13632]71
72        plan_data = {
73            'form_token': req.form_token,
74            'api_url': formatter.href('weekplan'),
75            'plans': plan_ids,
[14175]76            'plans_with_add_event': [plan_id for plan_id in plan_ids if core.can_plan_add_event(plan_id)],
77            'plans_with_update_event': [plan_id for plan_id in plan_ids if core.can_plan_update_event(plan_id)],
78            'plans_with_delete_event': [plan_id for plan_id in plan_ids if core.can_plan_delete_event(plan_id)],
[13632]79            'colors': colors,
[13770]80            'labels': labels,
[13632]81            'calendar_data': {
82                'firstDay': 1, # Start weeks on Monday
83                'weekends': 'showweekends' in args, # Hide Saturdays and Sundays by default
84                'columnFormat': 'ddd', # Show column headers "Mon Tue Wed Thu Fri"
85                'defaultView': 'multiWeek', # Custom extension of "basicWeek" view!
[14089]86                'defaultDate': start.isoformat(),
[13632]87                'weeks': weeks, # New option for custom "multiWeek" view
[16113]88                'weeksperrow': weeksperrow, # New option for custom "multiWeek" view
89                'contentHeight': math.ceil(weeks / weeksperrow) * rowheight,
[13632]90                'header': { # Title and navigation buttons
91                    'left': '',
92                    'center': 'title',
93                    'right': 'prev,next'
94                },
[14089]95                'eventSources': [
96                    {
97                        'url': formatter.href('weekplan'),
98                        'data': {
99                            'format': 'json',
100                            'plan': '|'.join(plan_ids),
101                        },
102                    },
103                ],
[13632]104            },
105        }
106        plan_data_id = '%012x' % id(plan_data)
107       
[14089]108        add_stylesheet(req, 'weekplan/css/fullcalendar.css')
109        add_script(req, 'weekplan/js/moment.min.js')
[13632]110        add_script(req, 'weekplan/js/fullcalendar.js')
111        add_script(req, 'weekplan/js/weekplan.js')
112        add_script_data(req, {'weekplan_%s' % plan_data_id: plan_data})
113        Chrome(self.env).add_jquery_ui(req)
114       
[13769]115        calendar_element = tag.div("Enable JavaScript to display the week plan.",
116            class_='trac-weekplan system-message',
117            id='trac-weekplan-%s' % plan_data_id,
118            style='width:%spx' % width)
119        if 'hidelegend' in args:
120            return calendar_element
121        else:
122            return tag.div(
123                calendar_element,
[13770]124                self._render_legend(plan_ids, labels, colors))
[13769]125
[13770]126    def _render_legend(self, names, labels, colors):
[13769]127        def merge(a, b):
128            return a + u' | ' + b
[13770]129        items = [tag.span(u'■', style='color:%s' % colors[name]) + ' ' + labels[name] for name in names]
[13769]130        return tag.p(
131            reduce(merge, items),
132            class_='trac-weekplan-legend')
Note: See TracBrowser for help on using the repository browser.