2013-10-02 07:32:53 +03:00
|
|
|
import os
|
2013-10-08 06:06:54 +03:00
|
|
|
import re
|
2013-10-08 22:47:49 +03:00
|
|
|
import lxml.html
|
2013-12-03 22:09:57 +02:00
|
|
|
from lxml.html.clean import Cleaner
|
2013-10-03 17:58:07 +03:00
|
|
|
import ghdiff
|
2013-10-15 23:32:17 +03:00
|
|
|
import gittle.utils
|
2013-09-29 00:09:02 +03:00
|
|
|
from gittle import Gittle
|
2013-10-05 00:42:45 +03:00
|
|
|
from dulwich.repo import NotGitRepository
|
2013-11-08 20:20:40 +02:00
|
|
|
from werkzeug.utils import escape, unescape
|
|
|
|
from util import to_canonical
|
2013-09-29 00:09:02 +03:00
|
|
|
|
2013-09-29 00:33:00 +03:00
|
|
|
|
2013-10-02 04:50:48 +03:00
|
|
|
class MyGittle(Gittle):
|
2013-10-03 17:58:07 +03:00
|
|
|
|
2013-10-02 04:50:48 +03:00
|
|
|
def file_history(self, path):
|
|
|
|
"""Returns all commits where given file was modified
|
|
|
|
"""
|
|
|
|
versions = []
|
|
|
|
commits_info = self.commit_info()
|
|
|
|
seen_shas = set()
|
|
|
|
|
|
|
|
for commit in commits_info:
|
|
|
|
try:
|
|
|
|
files = self.get_commit_files(commit['sha'], paths=[path])
|
|
|
|
file_path, file_data = files.items()[0]
|
|
|
|
except IndexError:
|
|
|
|
continue
|
|
|
|
|
|
|
|
file_sha = file_data['sha']
|
|
|
|
|
|
|
|
if file_sha in seen_shas:
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
seen_shas.add(file_sha)
|
|
|
|
|
|
|
|
versions.append(dict(author=commit['author']['name'],
|
|
|
|
time=commit['time'],
|
|
|
|
file_sha=file_sha,
|
|
|
|
sha=commit['sha'],
|
|
|
|
message=commit['message']))
|
|
|
|
return versions
|
|
|
|
|
2013-10-02 07:32:53 +03:00
|
|
|
def mv_fs(self, file_pair):
|
|
|
|
old_name, new_name = file_pair
|
|
|
|
os.rename(self.path + "/" + old_name, self.path + "/" + new_name)
|
|
|
|
|
2013-10-02 04:50:48 +03:00
|
|
|
|
2013-09-29 00:09:02 +03:00
|
|
|
class Wiki():
|
|
|
|
path = None
|
|
|
|
base_path = '/'
|
|
|
|
default_ref = 'master'
|
|
|
|
default_committer_name = 'Anon'
|
|
|
|
default_committer_email = 'anon@anon.anon'
|
2013-10-02 04:50:48 +03:00
|
|
|
index_page = 'home'
|
2013-09-29 00:33:00 +03:00
|
|
|
repo = None
|
2013-09-29 00:09:02 +03:00
|
|
|
|
2013-10-01 07:10:10 +03:00
|
|
|
def __init__(self, path):
|
|
|
|
try:
|
2013-10-02 04:50:48 +03:00
|
|
|
self.repo = MyGittle(path)
|
2013-10-05 00:42:45 +03:00
|
|
|
except NotGitRepository:
|
|
|
|
self.repo = MyGittle.init(path)
|
2013-10-01 07:10:10 +03:00
|
|
|
|
2013-09-29 00:09:02 +03:00
|
|
|
self.path = path
|
|
|
|
|
2013-10-15 23:32:17 +03:00
|
|
|
def revert_page(self, name, commit_sha, message, username):
|
|
|
|
page = self.get_page(name, commit_sha)
|
|
|
|
if not page:
|
|
|
|
# Page not found
|
|
|
|
return None
|
|
|
|
commit_info = gittle.utils.git.commit_info(self.repo[commit_sha])
|
|
|
|
message = commit_info['message']
|
|
|
|
return self.write_page(name, page['data'], message=message, username=username)
|
|
|
|
|
2013-10-03 17:58:07 +03:00
|
|
|
def write_page(self, name, content, message=None, create=False, username=None, email=None):
|
2013-10-08 22:47:49 +03:00
|
|
|
|
2013-11-08 20:20:40 +02:00
|
|
|
def escape_repl(m):
|
|
|
|
if m.group(1):
|
|
|
|
return "```" + escape(m.group(1)) + "```"
|
|
|
|
|
|
|
|
def unescape_repl(m):
|
|
|
|
if m.group(1):
|
|
|
|
return "```" + unescape(m.group(1)) + "```"
|
|
|
|
|
2013-10-08 22:47:49 +03:00
|
|
|
# prevents p tag from being added, we remove this later
|
|
|
|
content = '<div>' + content + '</div>'
|
|
|
|
content = re.sub(r"```(.*?)```", escape_repl, content, flags=re.DOTALL)
|
|
|
|
|
|
|
|
tree = lxml.html.fromstring(content)
|
|
|
|
|
2013-12-03 22:09:57 +02:00
|
|
|
cleaner = Cleaner(remove_unknown_tags=False,
|
|
|
|
kill_tags=set(['style']),
|
|
|
|
safe_attrs_only=False)
|
2013-10-08 22:47:49 +03:00
|
|
|
tree = cleaner.clean_html(tree)
|
|
|
|
|
|
|
|
content = lxml.html.tostring(tree, encoding='utf-8', method='html')
|
|
|
|
|
|
|
|
# post processing to fix errors
|
2013-10-08 01:03:23 +03:00
|
|
|
content = content[5:-6]
|
2013-11-08 20:20:40 +02:00
|
|
|
|
2013-10-15 23:32:17 +03:00
|
|
|
# FIXME this is for block quotes, doesn't work for double ">"
|
2013-10-08 06:06:54 +03:00
|
|
|
content = re.sub(r"(\n>)", "\n>", content)
|
|
|
|
content = re.sub(r"(^>)", ">", content)
|
2013-11-08 20:20:40 +02:00
|
|
|
|
2013-10-08 22:47:49 +03:00
|
|
|
content = re.sub(r"```(.*?)```", unescape_repl, content, flags=re.DOTALL)
|
2013-10-08 06:06:54 +03:00
|
|
|
|
2013-10-02 07:32:53 +03:00
|
|
|
filename = self.cname_to_filename(to_canonical(name))
|
2013-10-01 07:10:10 +03:00
|
|
|
f = open(self.path + "/" + filename, 'w')
|
|
|
|
f.write(content)
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
if create:
|
|
|
|
self.repo.add(filename)
|
|
|
|
|
2013-10-03 17:58:07 +03:00
|
|
|
if not message:
|
|
|
|
message = "Updated %s" % name
|
|
|
|
|
|
|
|
if not username:
|
|
|
|
username = self.default_committer_name
|
|
|
|
|
2013-10-08 06:06:54 +03:00
|
|
|
if not email:
|
|
|
|
email = "%s@realms.io" % username
|
2013-10-03 17:58:07 +03:00
|
|
|
|
|
|
|
return self.repo.commit(name=username,
|
|
|
|
email=email,
|
2013-10-01 07:10:10 +03:00
|
|
|
message=message,
|
|
|
|
files=[filename])
|
2013-09-29 00:09:02 +03:00
|
|
|
|
2013-10-01 07:10:10 +03:00
|
|
|
def rename_page(self, old_name, new_name):
|
2013-10-02 07:32:53 +03:00
|
|
|
old_name, new_name = map(self.cname_to_filename, [old_name, new_name])
|
|
|
|
self.repo.mv([(old_name, new_name)])
|
|
|
|
self.repo.commit(name=self.default_committer_name,
|
|
|
|
email=self.default_committer_email,
|
|
|
|
message="Moving %s to %s" % (old_name, new_name),
|
|
|
|
files=[old_name])
|
2013-09-29 00:09:02 +03:00
|
|
|
|
2013-10-02 04:50:48 +03:00
|
|
|
def get_page(self, name, sha='HEAD'):
|
2013-11-08 20:20:40 +02:00
|
|
|
# commit = gittle.utils.git.commit_info(self.repo[sha])
|
2013-10-02 07:32:53 +03:00
|
|
|
name = self.cname_to_filename(name)
|
2013-10-01 07:10:10 +03:00
|
|
|
try:
|
2013-10-02 04:50:48 +03:00
|
|
|
return self.repo.get_commit_files(sha, paths=[name]).get(name)
|
2013-10-01 07:10:10 +03:00
|
|
|
except KeyError:
|
|
|
|
# HEAD doesn't exist yet
|
2013-10-02 04:50:48 +03:00
|
|
|
return None
|
|
|
|
|
2013-10-15 23:32:17 +03:00
|
|
|
def compare(self, name, old_sha, new_sha):
|
2013-10-03 17:58:07 +03:00
|
|
|
old = self.get_page(name, sha=old_sha)
|
|
|
|
new = self.get_page(name, sha=new_sha)
|
|
|
|
return ghdiff.diff(old['data'], new['data'])
|
|
|
|
|
2013-10-02 04:50:48 +03:00
|
|
|
def get_history(self, name):
|
2013-10-02 07:32:53 +03:00
|
|
|
return self.repo.file_history(self.cname_to_filename(name))
|
|
|
|
|
|
|
|
def cname_to_filename(self, cname):
|
|
|
|
return cname.lower() + ".md"
|