]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/wiki.py
8 from .decorators
import *
10 class Wiki(misc
.Object
):
11 def _get_pages(self
, query
, *args
):
12 res
= self
.db
.query(query
, *args
)
15 yield Page(self
.backend
, row
.id, data
=row
)
17 def _get_page(self
, query
, *args
):
18 res
= self
.db
.get(query
, *args
)
21 return Page(self
.backend
, res
.id, data
=res
)
23 def get_page_title(self
, page
, default
=None):
24 doc
= self
.get_page(page
)
30 def get_page(self
, page
, revision
=None):
31 page
= Page
.sanitise_page_name(page
)
35 return self
._get
_page
("SELECT * FROM wiki WHERE page = %s \
36 AND timestamp = %s", page
, revision
)
38 return self
._get
_page
("SELECT * FROM wiki WHERE page = %s \
39 ORDER BY timestamp DESC LIMIT 1", page
)
41 def get_recent_changes(self
, limit
=None):
42 return self
._get
_pages
("SELECT * FROM wiki \
43 WHERE timestamp >= NOW() - INTERVAL '4 weeks' \
44 ORDER BY timestamp DESC LIMIT %s", limit
)
46 def create_page(self
, page
, author
, content
, changes
=None, address
=None):
47 page
= Page
.sanitise_page_name(page
)
49 return self
._get
_page
("INSERT INTO wiki(page, author_uid, markdown, changes, address) \
50 VALUES(%s, %s, %s, %s, %s) RETURNING *", page
, author
.uid
, content
or None, changes
, address
)
52 def delete_page(self
, page
, author
, **kwargs
):
53 # Do nothing if the page does not exist
54 if not self
.get_page(page
):
57 # Just creates a blank last version of the page
58 self
.create_page(page
, author
=author
, content
=None, **kwargs
)
60 def make_breadcrumbs(self
, url
):
61 # Split and strip all empty elements (double slashes)
62 parts
= list(e
for e
in url
.split("/") if e
)
65 for part
in ("/".join(parts
[:i
]) for i
in range(1, len(parts
))):
66 ret
.append(("/%s" % part
, self
.get_page_title(part
, os
.path
.basename(part
))))
71 class Page(misc
.Object
):
72 def init(self
, id, data
=None):
76 def __lt__(self
, other
):
77 if isinstance(other
, self
.__class
__):
78 if self
.page
== other
.page
:
79 return self
.timestamp
< other
.timestamp
81 return self
.page
< other
.page
84 def sanitise_page_name(page
):
88 # Make sure that the page name does NOT end with a /
89 if page
.endswith("/"):
92 # Make sure the page name starts with a /
93 if not page
.startswith("/"):
96 # Remove any double slashes
97 page
= page
.replace("//", "/")
107 return self
.data
.page
111 return self
._title
or self
.page
[1:]
115 if not self
.markdown
:
118 # Find first H1 headline in markdown
119 markdown
= self
.markdown
.splitlines()
121 m
= re
.match(r
"^# (.*)( #)?$", markdown
[0])
127 if self
.data
.author_uid
:
128 return self
.backend
.accounts
.get_by_uid(self
.data
.author_uid
)
130 def _render(self
, text
):
131 logging
.debug("Rendering %s" % self
)
134 (r
"\[\[([\w\d\/]+)(?:\|([\w\d\s]+))\]\]", r
"/\1", r
"\2", None, None),
135 (r
"\[\[([\w\d\/\-]+)\]\]", r
"/\1", r
"\1", self
.backend
.wiki
.get_page_title
, r
"\1"),
138 for pattern
, link
, title
, repl
, args
in patterns
:
141 for match
in re
.finditer(pattern
, text
):
142 l
= match
.expand(link
)
143 t
= match
.expand(title
)
146 t
= repl(match
.expand(args
)) or t
148 replacements
.append((match
.span(), t
or l
, l
))
150 # Apply all replacements
151 for (start
, end
), t
, l
in reversed(replacements
):
152 text
= text
[:start
] + "[%s](%s)" % (t
, l
) + text
[end
:]
154 # Borrow this from the blog
155 return self
.backend
.blog
._render
_text
(text
, lang
="markdown")
159 return self
.data
.markdown
163 return self
.data
.html
or self
._render
(self
.markdown
)
167 return self
.data
.timestamp
169 def was_deleted(self
):
170 return self
.markdown
is None
173 def breadcrumbs(self
):
174 return self
.backend
.wiki
.make_breadcrumbs(self
.page
)
176 def get_latest_revision(self
):
177 revisions
= self
.get_revisions()
179 # Return first object
180 for rev
in revisions
:
183 def get_revisions(self
):
184 return self
.backend
.wiki
._get
_pages
("SELECT * FROM wiki \
185 WHERE page = %s ORDER BY timestamp DESC", self
.page
)
189 return self
.data
.changes
195 parts
= self
.page
.split("/")
198 sidebar
= self
.backend
.wiki
.get_page(os
.path
.join(*parts
, "sidebar"))