def tree_link(repo, ref, path, file): if isinstance(file, str): file = Fakefile(name=file, filemode=stat.S_IFREG) if path: tree_path = '/'.join([ref, path, decode(file.name)]) else: tree_path = '/'.join([ref, decode(file.name)]) if stat.S_ISDIR(file.filemode): return url_for('tree', repo=repo.name, path=tree_path) if stat.S_ISREG(file.filemode): return url_for('blob', repo=repo.name, path=tree_path)
def fakediff(tree): files = {} fstat = {} for file in tree: if stat.S_ISDIR(getattr(file, 'filemode', getattr(file, 'attributes'))): f2, s2 = fakediff(file.to_object()) for f in f2: files[os.path.join(file.name, f)] = f2[f] fstat[os.path.join(file.name, f)] = s2[f] continue data = file.to_object().data if '\0' in data: # Binary file, ignore continue data = decode(data) lines = data.strip().split('\n') fstat[file.name] = {'+': len(lines), '-': 0} files[file.name] = [{ 'header': '@@ -0,0 +1,%d' % len(lines), 'data': [(x, pygit2.GIT_DIFF_LINE_ADDITION) for x in lines], 'new_start': 1, 'old_start': 0, }] fstat[None] = {'-': sum([x['-'] for x in fstat.values()]), '+': sum([x['+'] for x in fstat.values()])} return files, fstat
def code(repo, ref, path, entry, lexer, data=None, blame=False): from goblet.views import blob_link data = decode(data or entry.to_object().data) formatter = pygments.formatters.html.HtmlFormatter(linenos='inline', linenospecial=10, encoding='utf-8', anchorlinenos=True, lineanchors='l') html = Markup(pygments.highlight(data, lexer, formatter).decode('utf-8')) if blame: blame = repo.blame(ref, path) blame.append(None) def replace(match): line = int(match.group(2)) - 1 _, orig_line, _, commit = blame[line] link = blob_link(repo, commit['hex'], path) if blame[-1] == commit['hex']: return Markup( ' %s<a href="%s#l-%s">%s</a>' % (match.group(1), link, orig_line, match.group(2))) link2 = url_for('commit', repo=repo.name, ref=commit['hex']) blame[-1] = commit['hex'] return Markup( '<a href="%s" title="%s (%s)">%s</a> %s<a href="%s#l-%s">%s</a>' % (link2, commit['summary'], time.strftime( '%Y-%m-%d', time.gmtime(int( commit['committer-time']))), commit['hex'][:7], match.group(1), link, orig_line, match.group(2))) html = re.sub(r'(<a name="l-(\d+)"></a><span class="[^"]+">\s*)(\d+)', replace, html) return html
def blame(self, commit, path): if hasattr(commit, 'hex'): commit = commit.hex contents = decode(self.git('blame', '-p', commit, '--', path).stdout).split('\n') contents.pop(-1) commits = {} last_commit = None lines = [] orig_line = line_now = 0 for line in contents: if not last_commit: last_commit, orig_line, line_now = line.split()[:3] if last_commit not in commits: commits[last_commit] = {'hex': last_commit} elif line.startswith('\t'): lines.append( (line[1:], orig_line, line_now, commits[last_commit])) last_commit = None elif line == 'boundary': commits[last_commit]['previous'] = None else: key, val = line.split(None, 1) commits[last_commit][key] = val if not lines: # Empty file, pretend to have a line lines.append(('', orig_line, line_now, commits[last_commit])) return lines
def blame(self, commit, path): if hasattr(commit, 'hex'): commit = commit.hex contents = decode(self.git('blame', '-p', commit, '--', path).stdout).split('\n') contents.pop(-1) commits = {} last_commit = None lines = [] orig_line = line_now = 0 for line in contents: if not last_commit: last_commit, orig_line, line_now = line.split()[:3] if last_commit not in commits: commits[last_commit] = {'hex': last_commit} elif line.startswith('\t'): lines.append((line[1:], orig_line, line_now, commits[last_commit])) last_commit = None elif line == 'boundary': commits[last_commit]['previous'] = None else: key, val = line.split(None, 1) commits[last_commit][key] = val if not lines: # Empty file, pretend to have a line lines.append(('', orig_line, line_now, commits[last_commit])) return lines
def fakediff(tree): files = {} fstat = {} for file in tree: if stat.S_ISDIR(file.filemode): f2, s2 = fakediff(file.to_object()) for f in f2: files[os.path.join(file.name, f)] = f2[f] fstat[os.path.join(file.name, f)] = s2[f] continue data = file.to_object().data if '\0' in data: # Binary file, ignore continue data = decode(data) lines = data.strip().split('\n') fstat[file.name] = {'+': len(lines), '-': 0} files[file.name] = [{ 'header': '@@ -0,0 +1,%d' % len(lines), 'data': [(x, pygit2.GIT_DIFF_LINE_ADDITION) for x in lines], 'new_start': 1, 'old_start': 0, }] fstat[None] = { '-': sum([x['-'] for x in fstat.values()]), '+': sum([x['+'] for x in fstat.values()]) } return files, fstat
def code(repo, ref, path, entry, lexer, data=None, blame=False): from goblet.views import blob_link try: data = decode(data or repo[entry.oid].data) except: data = '(Binary data)' formatter = pygments.formatters.html.HtmlFormatter(linenos='inline', linenospecial=10, encoding='utf-8', anchorlinenos=True, lineanchors='l') html = Markup(pygments.highlight(data, lexer, formatter).decode('utf-8')) if blame: blame = repo.blame(ref, path) if not blame: return blame.append(None) def replace(match): line = int(match.group(2)) - 1 _, orig_line, _, commit = blame[line] link = blob_link(repo, commit['hex'], path) if blame[-1] == commit['hex']: return Markup(' %s<a href="%s#l-%s">%s</a>' % (match.group(1), link, orig_line, match.group(2))) link2 = url_for('commit', repo=repo.name, ref=commit['hex']) blame[-1] = commit['hex'] return Markup('<a href="%s" title="%s (%s)">%s</a> %s<a href="%s#l-%s">%s</a>' % (link2, commit['summary'], time.strftime('%Y-%m-%d', time.gmtime(int(commit['committer-time']))), commit['hex'][:7], match.group(1), link, orig_line, match.group(2))) html = re.sub(r'(<a name="l-(\d+)"></a><span class="[^"]+">\s*)(\d+)', replace, html) return html
def rest(repo, ref, path, entry): data = decode(repo[entry.oid].data) settings = { 'file_insertion_enabled': False, 'raw_enabled': False, 'output_encoding': 'utf-8', 'report_level': 5, } data = docutils.core.publish_parts(data,settings_overrides=settings,writer_name='html') return Markup(data['body']) + add_plain_link
def man(repo, ref, path, entry): res = shell.groff('-Thtml', '-P', '-l', '-mandoc', input=repo[entry.oid].data) if res.returncode != 0: raise RuntimeError(res.stderr) data = decode(res.stdout) return Markup( data[data.find('<body>') + 6:data.find('</body>')]) + add_plain_link
def rest(repo, ref, path, entry): data = decode(repo[entry.oid].data) settings = { 'file_insertion_enabled': False, 'raw_enabled': False, 'output_encoding': 'utf-8', 'report_level': 5, } data = docutils.core.publish_parts(data, settings_overrides=settings, writer_name='html') return Markup(data['body']) + add_plain_link
def blame(self, commit, path): if hasattr(commit, "hex"): commit = commit.hex contents = decode(self.git("blame", "-p", commit, "--", path).stdout).split("\n") contents.pop(-1) commits = {} last_commit = None lines = [] orig_line = line_now = 0 for line in contents: if not last_commit: last_commit, orig_line, line_now = line.split()[:3] if last_commit not in commits: commits[last_commit] = {"hex": last_commit} elif line.startswith("\t"): lines.append((line[1:], orig_line, line_now, commits[last_commit])) last_commit = None elif line == "boundary": commits[last_commit]["previous"] = None else: key, val = line.split(None, 1) commits[last_commit][key] = val return lines
def plain(repo, ref, path, entry): data = escape(decode(repo[entry.oid].data)) data = re.sub(r'(https?://(?:[-a-zA-Z0-9\._~:/?#\[\]@!\'()*+,;=]+|&)+)', Markup(r'<a href="\1">\1</a>'), data) return Markup(u"<pre>%s</pre>" % data)
def man(repo, ref, path, entry): res = shell.groff('-Thtml', '-P', '-l', '-mandoc', input=repo[entry.oid].data) if res.returncode != 0: raise RuntimeError(res.stderr) data = decode(res.stdout) return Markup(data[data.find('<body>')+6:data.find('</body>')]) + add_plain_link
def markdown(repo, ref, path, entry): data = decode(repo[entry.oid].data) return Markup(markdown_.Markdown(safe_mode="escape").convert(data)) + add_plain_link
def markdown(repo, ref, path, entry): data = decode(repo[entry.oid].data) return Markup( markdown_.Markdown(safe_mode="escape").convert(data)) + add_plain_link
def plain(repo, ref, path, entry): data = escape(decode(repo[entry.oid].data)) data = re.sub( r'(https?://(?:[-a-zA-Z0-9\._~:/?#\[\]@!\'()*+,;=]+|&)+)', Markup(r'<a href="\1">\1</a>'), data) return Markup(u"<pre>%s</pre>" % data)
def get_description(self): desc = os.path.join(self.path, 'description') if not os.path.exists(desc): return "" with open(desc) as fd: return decode(fd.read())
def markdown(repo, ref, path, entry): data = decode(entry.to_object().data) return Markup(markdown_.Markdown(safe_mode="escape").convert(data))
def code(repo, ref, path, entry, lexer, data=None): data = decode(data or entry.to_object().data) formatter = pygments.formatters.html.HtmlFormatter(linenos='inline', linenospecial=10, encoding='utf-8') return Markup(pygments.highlight(data, lexer, formatter).decode('utf-8'))