]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/wiki.py
9 from .decorators
import *
11 # Used to automatically link some things
14 (re
.compile(r
"(?:#(\d+))", re
.I
), r
"https://bugzilla.ipfire.org/show_bug.cgi?id=\1"),
17 (re
.compile(r
"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)"), r
"mailto:\1"),
20 (re
.compile(r
"(?:CVE)[\s\-](\d{4}\-\d+)"), r
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=\1"),
23 class Wiki(misc
.Object
):
24 def _get_pages(self
, query
, *args
):
25 res
= self
.db
.query(query
, *args
)
28 yield Page(self
.backend
, row
.id, data
=row
)
30 def get_page_title(self
, page
, default
=None):
31 doc
= self
.get_page(page
)
37 def get_page(self
, page
, revision
=None):
38 page
= Page
.sanitise_page_name(page
)
42 res
= self
.db
.get("SELECT * FROM wiki WHERE page = %s \
43 AND timestamp = %s", page
, revision
)
45 res
= self
.db
.get("SELECT * FROM wiki WHERE page = %s \
46 ORDER BY timestamp DESC LIMIT 1", page
)
49 return Page(self
.backend
, res
.id, data
=res
)
51 def get_recent_changes(self
):
52 return self
._get
_pages
("SELECT * FROM wiki \
53 WHERE timestamp >= NOW() - INTERVAL '4 weeks' ORDER BY timestamp DESC")
55 def create_page(self
, page
, author
, markdown
):
56 page
= Page
.sanitise_page_name(page
)
58 res
= self
.db
.get("INSERT INTO wiki(page, author_id, markdown) \
59 VALUES(%s, %s, %s) RETURNING id", page
, author
.id, markdown
)
62 return self
.get_page_by_id(res
.id)
64 def delete_page(self
, page
, author
):
65 # Do nothing if the page does not exist
66 if not self
.get_page(page
):
69 # Just creates a blank last version of the page
70 self
.create_page(page
, author
, None)
74 parts
= list(e
for e
in url
.split("/") if e
)
76 num_parts
= len(parts
)
77 for i
in range(num_parts
):
78 yield "/".join(parts
[:i
])
80 def make_breadcrumbs(self
, url
):
81 for part
in self
._split
_url
(url
):
82 title
= self
.get_page_title(part
, os
.path
.basename(part
))
84 yield ("/%s" % part
, title
)
87 class Page(misc
.Object
):
88 def init(self
, id, data
=None):
92 def __lt__(self
, other
):
93 if isinstance(other
, self
.__class
__):
94 if self
.page
== other
.page
:
95 return self
.timestamp
< other
.timestamp
97 return self
.page
< other
.page
100 def sanitise_page_name(page
):
104 # Make sure that the page name does NOT end with a /
105 if page
.endswith("/"):
108 # Make sure the page name starts with a /
109 if not page
.startswith("/"):
112 # Remove any double slashes
113 page
= page
.replace("//", "/")
119 return "/%s" % self
.page
123 return self
.data
.page
127 return self
._title
or self
.page
[1:]
131 if not self
.markdown
:
134 # Find first H1 headline in markdown
135 markdown
= self
.markdown
.splitlines()
137 m
= re
.match(r
"^# (.*)( #)?$", markdown
[0])
143 if self
.data
.author_uid
:
144 return self
.backend
.accounts
.get_by_uid(self
.data
.author_uid
)
146 def _render(self
, text
):
147 logging
.debug("Rendering %s" % self
)
149 return markdown2
.markdown(text
, link_patterns
=link_patterns
,
150 extras
=["footnotes", "link-patterns", "wiki-tables"])
154 return self
.data
.markdown
158 return self
.data
.html
or self
._render
(self
.markdown
)
162 return self
.data
.timestamp
164 def was_deleted(self
):
165 return self
.markdown
is None
168 def breadcrumbs(self
):
169 return self
.backend
.wiki
.make_breadcrumbs(self
.page
)
171 def get_latest_revision(self
):
172 return self
.backend
.wiki
.get_page(self
.page
)
178 parts
= self
.page
.split("/")
181 sidebar
= self
.backend
.wiki
.get_page(os
.path
.join(*parts
, "sidebar"))