Attachment 'schedule-1.0.py'
Download 1 #-*- coding: utf-8 -*-
2 '''
3 MoinMoin - schedule parser, Version 1.0, 13.02.2019
4
5 A simple parser that only displays its contents if the current datetime is
6 between two datetimes (`after` and `before`) provided as options in the form
7 YYYY-MM-DD or YYYY-MM-DD@HH:MM (where HH is 00 to 23, i.e. for 24-hour clock).
8
9 If only one datetime is provided, it is considered to be the `after` datetime,
10 and `before` is considered to be an unspecified time in the future.
11
12 There are no default values for the `after` and `before` datetimes. If neither
13 are specified, the content is displayed.
14
15 If the datetimes are not valid or redundant arguments are provided, then a
16 warning is displayed but not the contents.
17
18 Rather than have the dates spread across individual pages, it is possible to
19 specify aggregate these in a Schedule page in the form `SomethingSchedule`,
20 in similar way to Group pages. This page must contain a unnumbered first-order
21 list giving the name of the page to be scheduled followed by one or two dates,
22 and any keywords needed for that page. All other content of this page is
23 ignored, just as in Group pages. To avoid recursion, a Schedule page cannot
24 schedule itself. Likewise, the schedules in the list cannot call another
25 Schedule page.
26
27 Keywords
28
29 silent : suppress message indicating content is outside the scheduled range.
30 This could be useful for scheduled parser sections.
31
32 == Usage ==
33
34 As a processing instruction (four options)
35
36 #format schedule [YYYY-DD-MM[@HH:MM][ YYYY-MM-DD[@HH:MM]]][ silent]
37
38 #format schedule `SomethingSchedule`
39
40 #schedule [YYYY-DD-MM[@HH:MM][ YYYY-MM-DD[@HH:MM]]][ silent]
41
42 #schedule `SomethingSchedule`
43
44 where, `SomethingSchedule` is the name of an existing Schedule page.
45
46 As parser section
47
48 {{{#!schedule [YYYY-DD-MM[@HH:MM][ YYYY-MM-DD[@HH:MM]]][ silent]
49 ...
50 }}}
51
52 == Prerequiste ==
53
54 A customer formatter `schedules.py` needs to be installed as a plugin
55
56 History
57
58 Version 1.0 - 13.02.2019: initial version
59
60 Copyright
61
62 @copyright: 2019 Ian Riley <ian.@riley.asia>
63
64 License
65
66 GNU GPL, see COPYING for details.
67 '''
68
69 import re, time
70 from MoinMoin import wikiutil
71 from MoinMoin.parser import text_moin_wiki as wiki
72 from MoinMoin.Page import Page
73 #from MoinMoin.formatter.schedules import Formatter
74
75 Dependencies = []
76
77 def _timestamp(datestr):
78 try:
79 value = time.mktime(time.strptime(datestr, "%Y-%m-%d"))
80 return wikiutil.timestamp2version(value)
81 except:
82 try:
83 value = time.mktime(time.strptime(datestr, "%Y-%m-%d@%H:%M"))
84 return wikiutil.timestamp2version(value)
85 except:
86 pass
87 return False
88
89 def get_members(request, pagename):
90 Formatter = wikiutil.importPlugin(request.cfg, 'formatter', 'schedules', 'Formatter')
91 formatter = Formatter(request)
92 page = Page(request, pagename, formatter=formatter)
93 page.send_page(content_only=True)
94 return formatter.members
95
96 class Parser:
97 parsername = 'schedule'
98 _msg = u"{{{#!wiki caution\n'''Scheduling message'''\n\n%s\n}}}"
99
100 def __init__(self, raw, request, **kw):
101 self.raw = raw
102 self.request = request
103 self.pagename = request.page.page_name
104 self.form = request.form
105 self._ = request.getText
106 self.args = kw.get('format_args', '')
107
108 def process_schedule_args(self, pagename, argstr):
109 now = int(time.time()) * 1000000
110 after = before = None
111 show = silent = False
112 schedulePageList = []
113 hasSchedulePage = False
114 missingSchedulePage = False
115 pageScheduleExists = False
116 foundargs = ''
117 info_msg = err_msg = None
118 _msg_bad_arg = u"The date (%s) does not match the required format (YYYY-MM-DD or YYYY-MM-DD@HH:MM)."
119 _msg_extra_arg = u"Too many scheduling arguments given."
120 _msg_too_soon = u"Content will be available from %s."
121 _msg_too_late = u"Content was only available from %s to %s."
122 _msg_missing_schedule_page = u"Schedule page (%s) not found."
123 _msg_missing_schedule = u"No schedule for %s found in %s."
124 _msg_recursive_schedule = u"A avoid recursion, schedule page cannot schedule itself."
125
126 options = argstr.split(' ')
127 if '' in options:
128 options.remove('')
129
130 silent = 'silent' in options
131 if silent:
132 options.remove('silent')
133
134 options2 = list(options)
135 for option in options2:
136 if option.endswith('Schedule'):
137 if option == pagename: # avoid recursion
138 err_msg = _msg_recursive_schedule
139 break
140 if Page(self.request, option).exists():
141 hasSchedulePage = True
142 schedulePageList.append(option)
143 else:
144 missingSchedulePage = True
145 err_msg = _msg_missing_schedule_page % (option)
146 break
147 options.remove(option)
148
149 if hasSchedulePage and not missingSchedulePage:
150 schedulePageName = schedulePageList[0] # just 1 for now
151 pageScheduleExists = False # allow for future looping
152 members = get_members(self.request, schedulePageName)
153 for member in members:
154 options = member.split(' ')
155 if options[0] == pagename:
156 pageScheduleExists = True
157 options.remove(options[0])
158 if '' in options:
159 options.remove('')
160 silent = 'silent' in options
161 if silent:
162 options.remove('silent')
163 argstr = member.replace(pagename, "").strip()
164 argstr = "%s [[%s]]" % (argstr, schedulePageName)
165 break # only take the first one
166 if not pageScheduleExists:
167 err_msg = _msg_missing_schedule % (pagename, schedulePageName)
168
169 if err_msg:
170 return (False, silent, info_msg, err_msg, argstr)
171
172 if len(options) == 0:
173 show = True
174
175 if len(options) > 0:
176 after = _timestamp(options[0])
177 if after:
178 show = now > after
179 if not show:
180 info_msg = _msg_too_soon % options[0]
181 if not after:
182 show = False
183 err_msg = _msg_bad_arg % options[0]
184
185 if after and len(options) > 1:
186 before = _timestamp(options[1])
187 if before and show:
188 show = now < before
189 if not show:
190 info_msg = _msg_too_late % (options[0], options[1])
191 if not before:
192 show = False
193 err_msg = _msg_bad_arg % options[1]
194
195 if len(options) > 2:
196 err_msg = _msg_extra_arg
197
198 if err_msg:
199 show = False # not needed but fail safe
200
201 return (show, silent, info_msg, err_msg, argstr)
202
203 def format(self, formatter, inhibit_p=False):
204
205 show, silent, info_msg, err_msg, argstr = self.process_schedule_args(self.pagename, self.args)
206
207 result = self.raw
208 if not show:
209 if silent:
210 result = ''
211 elif info_msg:
212 result = self._msg % info_msg
213
214 if err_msg:
215 result = self._msg % err_msg
216
217 wikiizer = wiki.Parser(result, self.request)
218 wikiizer.format(formatter, inhibit_p=inhibit_p)
You are not allowed to attach a file to this page.