"""
self.db.execute("REFRESH MATERIALIZED VIEW wiki_search_index")
+ def get_watchlist(self, account):
+ pages = self._get_pages(
+ "WITH pages AS (SELECT * FROM wiki_current \
+ LEFT JOIN wiki ON wiki_current.id = wiki.id) \
+ SELECT * FROM wiki_watchlist watchlist \
+ LEFT JOIN pages ON watchlist.page = pages.page \
+ WHERE watchlist.uid = %s",
+ account.uid,
+ )
+
+ return sorted(pages)
+
# ACL
def check_acl(self, page, account):
class Page(misc.Object):
+ # Wiki links
+ wiki_link = re.compile(r"\[\[([\w\d\/\-\.]+)(?:\|(.+?))?\]\]")
+
+ # External links
+ external_link = re.compile(r"\[\[((?:ftp|git|https?|rsync|sftp|ssh|webcal)\:\/\/.+?)(?:\|(.+?))?\]\]")
+
# Interwiki links e.g. [[wp>IPFire]]
interwiki_link = re.compile(r"\[\[(\w+)>(.+?)(?:\|(.+?))?\]\]")
+ # Mail link
+ email_link = re.compile(r"\[\[([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)(?:\|(.+?))?\]\]")
+
def init(self, id, data=None):
self.id = id
self.data = data
if self.data.author_uid:
return self.backend.accounts.get_by_uid(self.data.author_uid)
+ def _render_wiki_link(self, m):
+ path, alias = m.groups()
+
+ # Allow relative links
+ if not path.startswith("/"):
+ path = os.path.join(self.page, path)
+
+ # Normalise links
+ path = os.path.normpath(path)
+
+ return """<a href="%s">%s</a>""" % (
+ path,
+ alias or self.backend.wiki.get_page_title(path),
+ )
+
+ def _render_external_link(self, m):
+ url, alias = m.groups()
+
+ return """<a class="link-external" href="%s">%s</a>""" % (url, alias or url)
+
def _render_interwiki_link(self, m):
wiki = m.group(1)
if not wiki:
return " ".join(s)
+ def _render_email_link(self, m):
+ address, alias = m.groups()
+
+ return """<a class="link-external" href="mailto:%s">%s</a>""" \
+ % (address, alias or address)
+
def _render(self, text):
logging.debug("Rendering %s" % self)
for (start, end), file, alt_text, url in reversed(replacements):
text = text[:start] + "[![%s](%s)](%s?action=detail)" % (alt_text, url, file.url) + text[end:]
+ # Handle wiki links
+ text = self.wiki_link.sub(self._render_wiki_link, text)
+
# Handle interwiki links
text = self.interwiki_link.sub(self._render_interwiki_link, text)
- # Add wiki links
- patterns = (
- (r"\[\[([\w\d\/\-\.]+)(?:\|(.+?))\]\]", r"\1", r"\2", None, True),
- (r"\[\[([\w\d\/\-\.]+)\]\]", r"\1", r"\1", self.backend.wiki.get_page_title, True),
-
- # External links
- (r"\[\[((?:ftp|git|https?|rsync|sftp|ssh|webcal)\:\/\/.+?)(?:\|(.+?))\]\]",
- r"\1", r"\2", None, False),
-
- # Mail
- (r"\[\[([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)\]\]",
- r"\1", r"\1", None, False),
- )
-
- for pattern, link, title, repl, internal in patterns:
- replacements = []
-
- for match in re.finditer(pattern, text):
- l = match.expand(link)
- t = match.expand(title)
-
- if internal:
- # Allow relative links
- if not l.startswith("/"):
- l = os.path.join(self.page, l)
-
- # Normalise links
- l = os.path.normpath(l)
-
- if callable(repl):
- t = repl(l) or t
-
- replacements.append((match.span(), t or l, l))
+ # Handle external links
+ text = self.external_link.sub(self._render_external_link, text)
- # Apply all replacements
- for (start, end), t, l in reversed(replacements):
- text = text[:start] + "[%s](%s)" % (t, l) + text[end:]
+ # Handle email links
+ text = self.email_link.sub(self._render_email_link, text)
# Borrow this from the blog
return self.backend.blog._render_text(text, lang="markdown")