return False return True # # Renderers to display the results of all of this minimal effort. search_form = '<form method=get action="%s">Search: <input name=search size=15></form>' def searchbox(context): """Create the search form, if searching is enabled.""" if not can_search(context): return '' # We use the root instead of some synthetic paths because that # seems representative of what's actually going on. # This is a GET form, so we are not screwing ourselves on various # issues that way. return search_form % context.web.url_from_path("") htmlrends.register("search::enter", searchbox) def display_results(context): """Display the results of a search.""" if not can_search(context): return '' data = context.getviewvar("search") if not data: return '' data = data.strip() if not data: return '' hlist = search_pages(context, [data], find_in) if not hlist: return '' hlist.sort()
if not verify_ip_prefix(context): #context.set_error("mismatch in comment origin: previp %s: %s" % (repr(context.getviewvar('previp')), repr(comdata))) context.set_error( "info: mismatch in comment origin: previp %s (%s): %s" % (repr(context.getviewvar('previp')), context[error_var], repr(comdata))) elif 'comments-report-drafts' in context: # We can optionally log all draft comments, even ones that do # not fail any of the rules. Note that this is verbose and # possibly privacy intrusive. context.set_error("info: comment preview contents: %s" % repr(comdata)) return show_comment(comdata, context) htmlrends.register("comment::preview", commentpreview) def commentpre(context): """In a comment-writing context, generate a <pre> block of the comment being written.""" comdata = context.getviewvar("comment") #comdata = comtrim(comdata) if not comdata: return '' return "<pre>\n%s</pre>\n" % httputil.quotehtml(comdata) htmlrends.register("comment::pre", commentpre) #
def inject(context, pname): page = context.page.me().curdir() if page.type != "dir": return '' np = page.child(pname) # We don't have to check access when we render, because rendering # does it implicitly. if np.type != "file" or not np.displayable(): return '' return render_page(context, np) def readme(context): """Insert the wikitext file ((__readme)), in HTML form, if such a file exists in the current directory.""" return inject(context, "__readme") htmlrends.register("inject::readme", readme) def index(context): """Insert the wikitext file ((__index)) in HTML form, if such a file exists in the current directory.""" return inject(context, "__index") htmlrends.register("inject::index", index) # # Not just in the current directory. def upreadme(context): """Like _inject::readme_, except it searches for ((__readme)) all the way back to the DWiki root directory, not just in the current directory.""" page = context.page.me().curdir() if page.type != "dir":
return '' np = page.child(pname) # We don't have to check access when we render, because rendering # does it implicitly. if np.type != "file" or not np.displayable(): return '' return render_page(context, np) def readme(context): """Insert the wikitext file ((__readme)), in HTML form, if such a file exists in the current directory.""" return inject(context, "__readme") htmlrends.register("inject::readme", readme) def index(context): """Insert the wikitext file ((__index)) in HTML form, if such a file exists in the current directory.""" return inject(context, "__index") htmlrends.register("inject::index", index) # # Not just in the current directory. def upreadme(context): """Like _inject::readme_, except it searches for ((__readme)) all
# of thing into different functions, so that things don't become # even more messy than they already are. rangeOps = {'latest': latest_rel, 'range': range_rel, 'calendar': calendar_rel, 'oldest': oldest_rel} def rangebar(context): """Display a simple range navigation bar inside a VirtualDirectory.""" if not is_restriction(context): return '' r = rangeOps[context[rest_type]](context) if not r: return '' r = " | ".join([x for x in r if x]) if not r: return '' return '<div class="rangenav"> (%s) </div>' % r htmlrends.register("range::bar", rangebar) # # --------------- def entriesIn(context, ctuple): dl = context.cache_page_children(context.page.me()) if not dl: return False cstart, cend = crange_to_limits(ctuple) # We search for days a lot; this case is worth optimizing # specifically. # NOTE: this is lame. if cstart == cend: for e in dl: t = datetime.date.fromtimestamp(e[0])
def registerSimpleCached(name, func, perUser = False): htmlrends.register(name, simpleCacheWrap(func, name, perUser))
def registerSimpleCached(name, func, perUser=False): htmlrends.register(name, simpleCacheWrap(func, name, perUser))
# # Render a title for the error. def errortitle(context): """Generate the title for an error from a template in _errors/_, if the template exists; otherwise uses a default. Only usable during generation of an error page.""" if ":error:error" not in context: return '' (etype, to) = errorTemplate(context, "title") if to: return template.Template(to).render(context) elif etype in title_map: return title_map[etype] % context[":error:code"] else: return default_title % context[":error:code"] htmlrends.register("error::title", errortitle) # Render a body for the error. default_body = "<h1> %s - Error Processing Request </h1> <p> %s </p>" def errorbody(context): """Generates the body for an error page from a template in _errors/_, if the template exists; otherwise uses a default. Only usable during generation of an error page.""" if ":error:error" not in context: return '' (etype, to) = errorTemplate(context) if to: return template.Template(to).render(context) elif etype in body_map: return default_body % (context[":error:code"], body_map[etype]) else:
# Support a 'blog' style view of a directory. import time import derrors, htmlrends, template, views import pageranges import httputil def blogtime(context): """Generate a YYYY-MM-DD HH:MM:SS timestamp of the current page.""" ts = context.page.timestamp if ts: dstr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts)) return dstr else: return '' htmlrends.register("blog::time", blogtime) # Just year-month-day def blogdate(context): """Generates a YYYY-MM-DD timestamp of the current page.""" ts = context.page.timestamp if ts: dstr = time.strftime("%Y-%m-%d", time.localtime(ts)) return dstr else: return '' htmlrends.register("blog::date", blogdate) def blognamedate(context): """Generate a Month DD, YYYY timestamp of the current page.""" ts = context.page.timestamp
dp = np.parent() if dp not in dirs: dirs[dp] = True ustr = genurlent(context, dp, dir_pri) res.append(ustr) # Generate a reference to the show-comments page if # there are comments. Note that this skips comments # on undisplayable pages, because of how get_commentlist # behaves. # If comments-in-normal is set, comments are already # shown in the default page view. if "comments-in-normal" not in context and \ context.model.get_commentlist(np): res.append(genviewurlent(context, np, comment_pri, 'showcomments')) return "".join(res) htmlrends.register("sitemap::minurlset", minurlset) # Register the 'sitemap' view. # Google doesn't say what content-type their sitemap should be # returned in, so we pick application/xml since, well, it's an # XML file. The sitemap view is only valid on directories. class XMLView(views.AltType): content_type = "application/xml" views.register('sitemap', XMLView, onDir=True, onFile=False)
import derrors, htmlrends, template, views import pageranges import httputil def blogtime(context): """Generate a YYYY-MM-DD HH:MM:SS timestamp of the current page.""" ts = context.page.timestamp if ts: dstr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts)) return dstr else: return '' htmlrends.register("blog::time", blogtime) # Just year-month-day def blogdate(context): """Generates a YYYY-MM-DD timestamp of the current page.""" ts = context.page.timestamp if ts: dstr = time.strftime("%Y-%m-%d", time.localtime(ts)) return dstr else: return '' htmlrends.register("blog::date", blogdate)
def errortitle(context): """Generate the title for an error from a template in _errors/_, if the template exists; otherwise uses a default. Only usable during generation of an error page.""" if ":error:error" not in context: return '' (etype, to) = errorTemplate(context, "title") if to: return template.Template(to).render(context) elif etype in title_map: return title_map[etype] % context[":error:code"] else: return default_title % context[":error:code"] htmlrends.register("error::title", errortitle) # Render a body for the error. default_body = "<h1> %s - Error Processing Request </h1> <p> %s </p>" def errorbody(context): """Generates the body for an error page from a template in _errors/_, if the template exists; otherwise uses a default. Only usable during generation of an error page.""" if ":error:error" not in context: return '' (etype, to) = errorTemplate(context) if to: return template.Template(to).render(context) elif etype in body_map:
import pageranges def notblogroot(context): """Succeds (by generating a space) if we are a directory that is in a default blog view but is not the directory that made it the default view. Fails otherwise.""" if context.page.type != "dir" or context.view != "blog": return '' (pv, vdir) = context.pref_view_and_dir(context.page) if vdir == context.page: return '' return ' ' htmlrends.register("cond::notblogroot", notblogroot) def isblogyearmonth(context): """Suceeds (by generating a space) if we are a directory, in a blog view, and we are in a month or year VirtualDirectory. Fails otherwise.""" if context.view != "blog" or \ not pageranges.is_restriction(context) or \ pageranges.restriction(context) not in ('year', 'month'): return '' else: return ' ' htmlrends.register("cond::blogyearmonth", isblogyearmonth)
context.set_error("banned content in comment preview: " + repr(comdata)) set_comment_bad(context) return bad_char_msg # This only triggers if we have comment data to start with, so it # will never go off for people just starting to write comments. if not verify_ip_prefix(context): #context.set_error("mismatch in comment origin: previp %s: %s" % (repr(context.getviewvar('previp')), repr(comdata))) context.set_error("info: mismatch in comment origin: previp %s (%s): %s" % (repr(context.getviewvar('previp')), context[error_var], repr(comdata))) elif 'comments-report-drafts' in context: # We can optionally log all draft comments, even ones that do # not fail any of the rules. Note that this is verbose and # possibly privacy intrusive. context.set_error("info: comment preview contents: %s" % repr(comdata)) return show_comment(comdata, context) htmlrends.register("comment::preview", commentpreview) def commentpre(context): """In a comment-writing context, generate a <pre> block of the comment being written.""" comdata = context.getviewvar("comment") #comdata = comtrim(comdata) if not comdata: return '' return "<pre>\n%s</pre>\n" % httputil.quotehtml(comdata) htmlrends.register("comment::pre", commentpre) # # When we generate the form, we have to stamp the current comment # contents into it so that the user can re-edit them; this happens
# see it. if np.type == "file": dp = np.parent() if dp not in dirs: dirs[dp] = True ustr = genurlent(context, dp, dir_pri) res.append(ustr) # Generate a reference to the show-comments page if # there are comments. Note that this skips comments # on undisplayable pages, because of how get_commentlist # behaves. # If comments-in-normal is set, comments are already # shown in the default page view. if "comments-in-normal" not in context and \ context.model.get_commentlist(np): res.append(genviewurlent(context, np, comment_pri, 'showcomments')) return "".join(res) htmlrends.register("sitemap::minurlset", minurlset) # Register the 'sitemap' view. # Google doesn't say what content-type their sitemap should be # returned in, so we pick application/xml since, well, it's an # XML file. The sitemap view is only valid on directories. class XMLView(views.AltType): content_type = "application/xml" views.register('sitemap', XMLView, onDir = True, onFile = False)
return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts)) def rss2timestr(ts): return time.strftime("%a, %d %b %Y %T %z", time.gmtime(ts)) def feedtitle(context): """Generate an Atom feed title for the current page.""" title = context.getfirst("wikititle", "wikiname") if context.page.path != "": title = title + " :: " + context.page.path return httputil.quotehtml(title) htmlrends.register("atom::feedtitle", feedtitle) # # I think this is another case like that of redirection: you can't # supply an explicit port because everyone will fix it up for you # and thereby *double* the port. # How this works when people pass feeds around I have no <censored> # idea. Hopefully they rewrite the URL. # NOTE: this makes it dangerous for use in <id> ... </id> context. # Fix later. Head hurts. # Apparently feed readers that do this are buggy (it should be an # absolute URI). The question is 'how common are they?', because # liferea is at least one of them. def atomurl(context): """Generate the URL of this page in its normal view."""
else: return context['feed-start-time'] # Joy, yet another time string format. def atomtimestr(ts): return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts)) def rss2timestr(ts): return time.strftime("%a, %d %b %Y %T %z", time.gmtime(ts)) def feedtitle(context): """Generate an Atom feed title for the current page.""" title = context.getfirst("wikititle", "wikiname") if context.page.path != "": title = title + " :: " + context.page.path return httputil.quotehtml(title) htmlrends.register("atom::feedtitle", feedtitle) # # I think this is another case like that of redirection: you can't # supply an explicit port because everyone will fix it up for you # and thereby *double* the port. # How this works when people pass feeds around I have no <censored> # idea. Hopefully they rewrite the URL. # NOTE: this makes it dangerous for use in <id> ... </id> context. # Fix later. Head hurts. # Apparently feed readers that do this are buggy (it should be an # absolute URI). The question is 'how common are they?', because # liferea is at least one of them. def atomurl(context): """Generate the URL of this page in its normal view.""" url = context.nurl(context.page)
# HTML view renders for components of a file's history, provided that the # file actually has history. import time, calendar import htmlrends def showactive(context): """If the current page is under RCS and is locked, display who has locked it.""" if not context.page.hashistory(): return '' res = context.page.current_user() if not res: return '' return res htmlrends.register("hist::lockedby", showactive) # TODO: somehow, show diffs/etc. def cell(str): return "<td>%s</td>" % str def showrevs(context): """If the current page is under RCS, display a version history table.""" if not context.page.hashistory(): return '' hl = context.page.history() if not hl: return '' # We format this into a table for now, because I feel like it. result = []
# the same, because we need the latter. # Are we logged in? # (We have to use url_from_path instead of getting pages, because # we can't *get* these as valid pages. That's the point of the # synthetic names.) qppath = httputil.quotehtml(ppath) if context.current_user() and not context.is_login_default(): turl = context.web.url_from_path(".logout") return logoutBoxForm % (turl, qppath) else: turl = context.web.url_from_path(".login") return loginBoxForm % (turl, qppath) # Fortunately I don't have to figure out how to add values # in the URL right now, because this is (ta-dah) a POST form. htmlrends.register("auth::loginbox", loginbox) # Render in a link to the :post:page variable. def postlink(context): """Generate a link to the origin page for a POST request in a POST form context.""" if not ":post:page" in context: return '' pp = context.model.get_page(context[":post:page"]) return htmlrends.makelink(pp.path, context.nurl(pp)) htmlrends.register("post::oldpage", postlink) # ----- # View registration and other view things. login_msg = "Your login attempt was unsuccessful. Please try again. (We apologize for the terseness here, but our normal friendly login failure page is broken.)"