summaryrefslogtreecommitdiffstats
path: root/g2h
diff options
context:
space:
mode:
Diffstat (limited to 'g2h')
-rw-r--r--g2h/cli.py2
-rw-r--r--g2h/commit_page.py2
-rw-r--r--g2h/file.py16
-rw-r--r--g2h/file_page.py45
-rw-r--r--g2h/page_factory.py8
-rw-r--r--g2h/tree.py2
-rw-r--r--g2h/tree_page.py31
7 files changed, 97 insertions, 9 deletions
diff --git a/g2h/cli.py b/g2h/cli.py
index 52a2be7..fbc456e 100644
--- a/g2h/cli.py
+++ b/g2h/cli.py
@@ -34,6 +34,8 @@ def main():
tree = factory.new_tree(commit, '', git.get_repo())
for tree_page in tree.build_pages(factory):
tree_page.render()
+ for file in tree_page.get_files():
+ factory.new_file(commit, file).render()
if __name__ == '__main__':
main()
diff --git a/g2h/commit_page.py b/g2h/commit_page.py
index 6111013..a998417 100644
--- a/g2h/commit_page.py
+++ b/g2h/commit_page.py
@@ -17,7 +17,7 @@ def redact_email(email):
class CommitPage(Page):
def __init__(self, out_dir, name, commit, content_subdir):
- super(CommitPage, self).__init__('commit.md', out_dir, os.path.join(commit.hexsha, 'index.md'), name, content_subdir)
+ super(CommitPage, self).__init__('commit.md', out_dir, os.path.join(commit.hexsha, '_index.md'), name, content_subdir)
self.commit = commit
def context(self):
diff --git a/g2h/file.py b/g2h/file.py
new file mode 100644
index 0000000..8f683cd
--- /dev/null
+++ b/g2h/file.py
@@ -0,0 +1,16 @@
+import os
+
+def sanitize_file_name(file_name, files):
+ if not file_name.startswith('.'):
+ return file_name
+
+ file_names = [ f.name for f in files ]
+ for i in range(1, 10):
+ new_name = file_name.replace('.', '_' * i, 1)
+ if not new_name in file_names:
+ return new_name
+
+ raise RuntimeError('Couldn not find unused sanitized file name')
+
+def tree_join(commit, path):
+ return os.path.join(commit.hexsha, 't', path)
diff --git a/g2h/file_page.py b/g2h/file_page.py
new file mode 100644
index 0000000..b154ee5
--- /dev/null
+++ b/g2h/file_page.py
@@ -0,0 +1,45 @@
+import base64
+import filetype
+import os
+
+from .file import sanitize_file_name, tree_join
+from .page import Page
+from .tree import safe_join
+
+def bytes_to_content(file_bytes):
+ if not file_bytes:
+ return (None, 'empty')
+ try:
+ text = file_bytes.decode('utf-8')
+ return (text, 'text')
+ except UnicodeError:
+ if filetype.is_image(file_bytes):
+ # TODO: Refer to the static file once that's implemented.
+ img = base64.b64encode(file_bytes)
+ return (img.decode('utf-8'), 'image')
+
+ return (None, None)
+
+class FilePage(Page):
+ def __init__(self, out_dir, name, commit, file_name, file_path, content_subdir):
+ tree = safe_join(commit.tree, file_path)
+ super(FilePage, self).__init__('file.md', out_dir, os.path.join(tree_join(commit, file_path), sanitize_file_name(file_name, tree.blobs) + '.md'), name, content_subdir)
+ self.commit = commit
+ self.file_name = file_name
+ self.file_path = file_path
+ self.tree = tree
+
+ def read_file(self):
+ return self.tree.join(self.file_name).data_stream.read()
+
+ def context(self):
+ file_bytes = self.read_file()
+ content, file_type = bytes_to_content(file_bytes)
+
+ return {
+ 'content': content,
+ 'content_subdir': self.content_subdir,
+ 'file_extension': os.path.splitext(self.file_name)[1].lstrip('.'),
+ 'title': self.name + ': ' + self.file_name,
+ 'type': file_type
+ }
diff --git a/g2h/page_factory.py b/g2h/page_factory.py
index c4b89ed..da9c5d5 100644
--- a/g2h/page_factory.py
+++ b/g2h/page_factory.py
@@ -1,4 +1,7 @@
+import os
+
from .commit_page import CommitPage
+from .file_page import FilePage
from .overview_page import OverviewPage
from .log_page import LogPage
from .tree_page import TreePage
@@ -12,6 +15,11 @@ class PageFactory:
def new_commit(self, commit):
return CommitPage(self.out_dir, self.name, commit, self.content_subdir)
+ def new_file(self, commit, path):
+ filename = os.path.basename(path)
+ dir = os.path.dirname(path)
+ return FilePage(self.out_dir, self.name, commit, filename, dir, self.content_subdir)
+
def new_overview(self, branches, tags):
return OverviewPage(self.out_dir, self.name, branches, tags, self.content_subdir)
diff --git a/g2h/tree.py b/g2h/tree.py
new file mode 100644
index 0000000..bd8116c
--- /dev/null
+++ b/g2h/tree.py
@@ -0,0 +1,2 @@
+def safe_join(tree, path):
+ return tree.join(path) if path else tree
diff --git a/g2h/tree_page.py b/g2h/tree_page.py
index 977e981..9b7a0d5 100644
--- a/g2h/tree_page.py
+++ b/g2h/tree_page.py
@@ -1,14 +1,14 @@
import os
+from .file import sanitize_file_name, tree_join
from .page import Page
-
-def tree_prefix(sha, tree):
- return os.path.join(sha, 't', tree)
+from .tree import safe_join
class TreePage(Page):
def __init__(self, out_dir, name, commit, sub_tree, repo, content_subdir):
- super(TreePage, self).__init__('tree.md', out_dir, os.path.join(tree_prefix(commit.hexsha, sub_tree), 'index.md'), name, content_subdir)
- self.tree = commit.tree.join(sub_tree) if sub_tree else commit.tree
+ tree = safe_join(commit.tree, sub_tree)
+ super(TreePage, self).__init__('tree.md', out_dir, os.path.join(tree_join(commit, tree.path), '_index.md'), name, content_subdir)
+ self.tree = tree
self.repo = repo
self.commit = commit
self.sub_tree = sub_tree
@@ -17,8 +17,16 @@ class TreePage(Page):
entries = []
for node in nodes:
latest_commit = next(self.repo.iter_commits(self.commit, max_count=1, paths=node.path))
+ name = node.name
+ file_name = name
+ if node.type == 'tree':
+ name += '/'
+ file_name = name
+ else:
+ file_name = sanitize_file_name(name, self.tree.blobs)
entry = {
- 'name': node.name + str('/' if node.type == 'tree' else ''),
+ 'file_name': file_name,
+ 'name': name,
'modified': latest_commit.committed_datetime
}
entries.append(entry)
@@ -35,7 +43,8 @@ class TreePage(Page):
return {
'content_subdir': self.content_subdir,
'entries': self._get_entries(),
- 'subdir': '/'.join([self.content_subdir, tree_prefix(self.commit.hexsha, self.tree.path)]),
+ # TODO: Make this fit the rest of the system.
+ 'subdir': '/'.join([self.content_subdir, tree_join(self.commit, self.tree.path)]),
'title': self.name + ': Tree'
}
@@ -47,10 +56,16 @@ class TreePage(Page):
current = remaining.pop()
if not current in visited:
visited.add(current)
- tree = self.commit.tree.join(current) if current else self.commit.tree
+ tree = safe_join(self.commit.tree, current)
tree_pages.append(factory.new_tree(self.commit, tree.path, self.repo))
for sub_tree in tree.trees:
remaining.append(sub_tree.path)
return tree_pages
+ def get_files(self):
+ file_paths = []
+ for blob in self.tree.blobs:
+ file_paths.append(blob.path)
+
+ return file_paths