Modify ↓
Opened 17 years ago
#4308 new enhancement
modified to add minutes...
| Reported by: | Mogga | Owned by: | Alec Thomas |
|---|---|---|---|
| Priority: | normal | Component: | AddCommentMacro |
| Severity: | normal | Keywords: | |
| Cc: | Trac Release: | 0.10 |
Description
I like this macro for recording minutes in a meeting... I modified to remove the commenting and changed it to AddMinuteMacro...
# vim: expandtab
import re, time
from StringIO import StringIO
from genshi.builder import tag
from trac.core import *
from trac.wiki.formatter import format_to_html
from trac.util import TracError
from trac.util.text import to_unicode
from trac.web.api import IRequestFilter, RequestDone
from trac.web.chrome import add_script
from trac.wiki.api import parse_args, IWikiMacroProvider
from trac.wiki.macros import WikiMacroBase
from trac.wiki.model import WikiPage
from trac.wiki.web_ui import WikiModule
from macropost.api import IMacroPoster
class AddMinuteMacro(WikiMacroBase):
"""A macro to add meeting minutes to a page more interactively. Usage:
{{{
[[AddMinute]]
}}}
The macro accepts one optional argument that allows appending
to the wiki page even though user may not have modify permission:
{{{
[[AddMinute(appendonly)]]
}}}
"""
implements(IWikiMacroProvider, IRequestFilter, IMacroPoster)
def expand_macro(self, formatter, name, content):
args, kw = parse_args(content)
req = formatter.req
context = formatter.context
# Prevent multiple inclusions - store a temp in req
if hasattr(req, 'AddMinutemacro'):
raise TracError('\'AddMinute\' macro cannot be included twice.')
req.AddMinutemacro = True
# Prevent it being used outside of wiki page context
resource = context.resource
if not resource.realm == 'wiki':
raise TracError('\'AddMinute\' macro can only be used in Wiki pages.')
# Setup info and defaults
authname = req.authname
page = WikiPage(self.env, resource)
page_url = req.href.wiki(resource.id)
wikipreview = req.args.get("preview", "")
# Can this user add a minute to this page?
appendonly = ('appendonly' in args)
canminute = False
if page.readonly:
if 'WIKI_ADMIN' in req.perm(resource):
canminute = True
elif 'WIKI_MODIFY' in req.perm(resource):
canminute = True
elif appendonly and 'WIKI_VIEW' in req.perm(resource):
canminute = True
else:
raise TracError('Error: Insufficient privileges to AddMinute')
# Get the data from the POST
minute = req.args.get("AddMinute", "")
preview = req.args.get("previewAddMinute", "")
cancel = req.args.get("cancelAddMinute", "")
submit = req.args.get("submitAddMinute", "")
if not cancel and req.authname == 'anonymous':
authname = req.args.get("authorAddMinute", authname)
# Ensure [[AddMinute]] is not present in minute, so that infinite
# recursion does not occur.
minute = to_unicode(re.sub('(^|[^!])(\[\[AddMinute)', '\\1!\\2', minute))
the_preview = the_message = the_form = tag()
# If we are submitting or previewing, inject minute as it should look
if canminute and minute and (preview or submit):
heading = tag.h4("minute by ", authname, " on ",
to_unicode(time.strftime('%c', time.localtime())),
id="minutepreview")
if preview:
the_preview = tag.div(heading,
format_to_html(self.env, context, minute),
class_="wikipage", id="preview")
# Check the form_token
form_ok = True
if submit and req.args.get('__FORM_TOKEN','') != req.form_token:
form_ok = False
the_message = tag.div(tag.strong("ERROR: "),
"AddMinute received incorrect form token. "
"Do you have cookies enabled?",
class_="system-message")
# When submitting, inject minute before macro
if minute and submit and canminute and form_ok:
submitted = False
newtext = ""
for line in page.text.splitlines():
if line.find('[[AddMinute') == 0:
newtext += "%s\n" % (minute)
submitted = True
newtext += line+"\n"
if submitted:
page.text = newtext
# Let the wiki page manipulators have a look at the
# submission.
valid = True
req.args.setdefault('minute', 'Minute added.')
try:
for manipulator in WikiModule(self.env).page_manipulators:
for field, message in manipulator.validate_wiki_page(req, page):
valid = False
if field:
the_message += tag.div(tag.strong("invalid field '%s': " % field),
message,
class_="system-message")
else:
the_message += tag.div(tag.strong("invalid: "),
message,
class_="system-message")
# The TracSpamfilterPlugin does not generate messages,
# but throws RejectContent.
except TracError, s:
valid = False
the_message += tag.div(tag.strong("ERROR: "), s, class_="system-message")
if valid:
page.save(authname, req.args['minute'], req.environ['REMOTE_ADDR'])
# We can't redirect from macro as it will raise RequestDone
# which like other macro errors gets swallowed in the Formatter.
# We need to re-raise it in a post_process_request instead.
try:
self.env.log.debug(
"AddMinute saved - redirecting to: %s" % page_url)
req._outheaders = []
req.redirect(page_url)
except RequestDone:
req.AddMinute_raise = True
else:
the_message = tag.div(tag.strong("ERROR: "), "[[AddMinute]] "
"macro call must be the only content on its line. "
"Could not add minute.",
class_="system-message")
the_form = tag.form(
tag.fieldset(
tag.legend("Add Minute"),
tag.div(
(wikipreview and "Page preview..." or None),
tag.textarea((not cancel and minute or ""),
class_="wikitext",
id="AddMinute",
name="AddMinute",
cols=80, rows=5,
disabled=(not canminute and "disabled" or None)),
class_="field"
),
(req.authname == 'anonymous' and tag.div(
tag.label("Your email or username:",
for_="authorAddMinute"),
tag.input(id="authorAddMinute", type="text",
size=30, value=authname)
) or None),
tag.input(type="hidden", name="__FORM_TOKEN",
value=req.form_token),
tag.div(
tag.input(value="Add Minute", type="submit",
name="submitAddMinute", size=30,
disabled=(not canminute and "disabled" or None)),
tag.input(value="Preview Minute", type="submit",
name="previewAddMinute",
disabled=(not canminute and "disabled" or None)),
tag.input(value="Cancel", type="submit",
name="cancelAddMinute",
disabled=(not canminute and "disabled" or None)),
class_="buttons"
),
),
method="post",
action=page_url+"#minuteing",
)
if not wikipreview:
# Wiki edit preview already adds this javascript file
add_script(req, 'common/js/wikitoolbar.js')
return tag.div(the_preview, the_message, the_form, id="minuteing")
# IMacroPoster method
def process_macro_post(self, req):
self.log.debug('AddMinuteMacro: Got a POST')
# IRequestFilter methods
def pre_process_request(self, req, handler):
return handler
def post_process_request(self, req, template, data, content_type):
if hasattr(req, 'AddMinute_raise'):
self.env.log.debug("AddMinuteMacro: Re-raising RequestDone from redirect")
del(req.AddMinute_raise)
raise RequestDone
return template, data, content_type
Attachments (0)
Note: See
TracTickets for help on using
tickets.


