Attachment 'schedule-1.1.py'

Download

   1 #-*- coding: utf-8 -*-
   2 '''
   3 MoinMoin - schedule parser, Version 1.1, 03.03.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 Version 1.1 - 03.03.2019: using send_special to bypass acl requirement
  60 
  61 Copyright
  62 
  63 @copyright: 2019 Ian Riley <ian.@riley.asia>
  64 
  65 License
  66 
  67 GNU GPL, see COPYING for details.
  68 '''
  69 
  70 import re, time
  71 from MoinMoin import wikiutil
  72 from MoinMoin.parser import text_moin_wiki as wiki
  73 from MoinMoin.Page import Page
  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(self, pagename):
  90     # done here (not with wiki_groups) because we need a different formatter
  91     Formatter = wikiutil.importPlugin(self.request.cfg, 'formatter', 'schedules', 'Formatter')
  92     formatter = Formatter(self.request)
  93     page = Page(self.request, pagename, formatter=formatter)
  94     request_page = getattr(self.request, "page", None)
  95     self.request.page = page
  96     self.request.redirectedOutput(page.send_page, content_only=True, send_special=True)
  97     if request_page:
  98         self.request.page = request_page
  99     else:
 100         del self.request.page
 101     return formatter.members
 102 
 103 class Parser:
 104     parsername = 'schedule'
 105     _msg = u"{{{#!wiki caution\n'''Scheduling message'''\n\n%s\n}}}"
 106 
 107     def __init__(self, raw, request, **kw):
 108         self.raw = raw
 109         self.request = request
 110         self.pagename = request.page.page_name
 111         self.form = request.form
 112         self._ = request.getText
 113         self.args = kw.get('format_args', '')
 114 
 115     def process_schedule_args(self, pagename, argstr):
 116         now = int(time.time()) * 1000000
 117         after = before = None
 118         show = silent = False
 119         schedulePageList = []
 120         hasSchedulePage = False
 121         missingSchedulePage = False
 122         pageScheduleExists = False
 123         foundargs = ''
 124         info_msg = err_msg = None
 125         _msg_bad_arg = u"The date (%s) does not match the required format (YYYY-MM-DD or YYYY-MM-DD@HH:MM)."
 126         _msg_extra_arg = u"Too many scheduling arguments given."
 127         _msg_too_soon = u"Content will be available from %s."
 128         _msg_too_late = u"Content was only available from %s to %s."
 129         _msg_missing_schedule_page = u"Schedule page (%s) not found."
 130         _msg_missing_schedule = u"No schedule for %s found in %s."
 131         _msg_recursive_schedule = u"A avoid recursion, schedule page cannot schedule itself."
 132 
 133         options = argstr.split(' ')
 134         if '' in options:
 135            options.remove('')
 136 
 137         silent = 'silent' in options
 138         if silent:
 139             options.remove('silent')
 140 
 141         options2 = list(options)
 142         for option in options2:
 143             if option.endswith('Schedule'):
 144                 if option == pagename: # avoid recursion
 145                      err_msg = _msg_recursive_schedule
 146                      break
 147                 if Page(self.request, option).exists():
 148                      hasSchedulePage = True
 149                      schedulePageList.append(option)
 150                 else:
 151                      missingSchedulePage = True
 152                      err_msg = _msg_missing_schedule_page % (option)
 153                      break
 154                 options.remove(option)
 155 
 156         if hasSchedulePage and not missingSchedulePage:
 157             schedulePageName = schedulePageList[0] # just 1 for now
 158             pageScheduleExists = False # allow for future looping
 159             members = get_members(self, schedulePageName)
 160             for member in members:
 161                 options = member.split(' ')
 162                 if options[0] == pagename:
 163                     pageScheduleExists = True
 164                     options.remove(options[0])
 165                     if '' in options:
 166                         options.remove('')
 167                     silent = 'silent' in options
 168                     if silent:
 169                         options.remove('silent')
 170                     argstr = member.replace(pagename, "").strip()
 171                     argstr = "%s [[%s]]" % (argstr, schedulePageName)
 172                     break # only take the first one
 173             if not pageScheduleExists:
 174                  err_msg = _msg_missing_schedule % (pagename, schedulePageName)
 175 
 176         if err_msg:
 177             return (False, silent, info_msg, err_msg, argstr)
 178 
 179         if len(options) == 0:
 180             show = True
 181 
 182         if len(options) > 0:
 183             after = _timestamp(options[0])
 184             if after:
 185                 show = now > after
 186                 if not show:
 187                     info_msg = _msg_too_soon % options[0]
 188             if not after:
 189                 show = False
 190                 err_msg = _msg_bad_arg % options[0]
 191 
 192         if after and len(options) > 1:
 193             before = _timestamp(options[1])
 194             if before and show:
 195                 show = now < before
 196                 if not show:
 197                     info_msg = _msg_too_late % (options[0], options[1])
 198             if not before:
 199                 show = False
 200                 err_msg = _msg_bad_arg % options[1]
 201 
 202         if len(options) > 2:
 203             err_msg = _msg_extra_arg
 204 
 205         if err_msg:
 206             show = False # not needed but fail safe
 207 
 208         return (show, silent, info_msg, err_msg, argstr)
 209 
 210     def format(self, formatter, inhibit_p=False):
 211 
 212         show, silent, info_msg, err_msg, argstr = self.process_schedule_args(self.pagename, self.args)
 213 
 214         result = self.raw
 215         if not show:
 216             if silent:
 217                 result = ''
 218             elif info_msg:
 219                 result = self._msg % info_msg
 220 
 221         if err_msg:
 222             result = self._msg % err_msg
 223 
 224         wikiizer = wiki.Parser(result, self.request)
 225         wikiizer.format(formatter, inhibit_p=inhibit_p)

You are not allowed to attach a file to this page.