예제 #1
0
def get_commit_templatedata(repo, obj):
    """Gets the required data to feed into the templates which display a single commit, including the tree changes
    in the commit, author and committer info, time and commit messages, and list of changed files. Returns a dict
    with appropriate key names for the templates to use."""
    tree = list(get_tree_diff(repo, obj))
    td = tree_diff.TreeDiffer(repo)
    
    changed_files = []
    for entry in tree:
        if entry.kind != tree_diff.DiffEntry.UNMODIFIED:
            changed_files.extend(td.commitdiff(entry))
    
    message = ggutils.force_unicode(obj.message)
    short_message = ggutils.short_message(message)
    author = (ggutils.force_unicode(obj.author.name), ggutils.force_unicode(obj.author.email))
    committer = (ggutils.force_unicode(obj.committer.name), ggutils.force_unicode(obj.committer.email))
    author_time = ggutils.format_commit_time(obj.author.time)
    commit_time = ggutils.format_commit_time(obj.committer.time)
    return dict(
        commit=obj,
        message=message,
        title=short_message,
        author=author,
        committer=committer,
        author_time=author_time,
        commit_time=commit_time,
        initial_tree=tree,
        td_encoder=tree_diff.DiffEntryEncoder,
        changed_files=changed_files
    )
예제 #2
0
 def draw_commits(self, walker, existing_branches=[], currentY=0):
     """ This is the main function that draws the commits taken from a walk of the repository
     (the walker object). It can optionally start with a number of existing branches and at a
     given y-position. It returns a tuple with the first member being a dictionary of the nodes,
     edges, and labels to be drawn, and the second member being a list of branches at the bottom
     of the graph (used for continuing the graph later)"""
     column = 0
     self.graph = [] #stores a list of edges which aren't finished being drawn.
     # display_list is a structure holding what should actually be drawn on the screen.
     self.display_list = {'edges':[], 'nodes':[], 'labels':[], 'authors':[], 'dates':[]}
     # branches is an array of strings used to track where branches should go.
     # A SHA hash in some position indicates that commit should be the next one in that position.
     # An empty string indicates the position is blank and can be filled with a new branch if one appears.
     self.branches = []
     for existing_branch in existing_branches:
         if existing_branch:
             # start drawing these existing branches
             self.graph.append(self.new_edge(column, currentY, existing_branch))
         column = column + 1
         # Keep track of existing branches
         self.branches.append(existing_branch)
     for commit in walker:
         pos = self.place_commit(commit, currentY)
         
         # Do any edges need finishing off?
         self.finish_edges(commit.hex, pos, currentY)
         
         #The delete flag determines whether to mark this branch as deleted
         if commit.parents:
             delete = self.process_parents(commit.parents, pos, currentY)
         else:
             del self.branches[pos] #this branch has no parent, delete it
             delete = False
         
         #TODO: make this more elegant?
         textX = len(self.branches)
         for branch in reversed(self.branches):
             if branch == '':
                 textX -= 1
             else:
                 break
         textX = max(textX,1)
         
         if delete:
             #clear out this branch for future use
             self.branches[pos] = ''
         
         # Create a node representing this commit and the message, author and time labels
         self.display_list['nodes'].append(self.new_node(pos, currentY, commit.hex, [x.hex for x in commit.parents]))
         label_text = ggutils.force_unicode(ggutils.short_message(commit.message))
         self.display_list['labels'].append({'x': textX, 'y': currentY, 'content': label_text, 'sha': commit.hex})
         self.display_list['authors'].append({'x': 0, 'y': currentY, 'content': ggutils.force_unicode(commit.author.name), 'sha': commit.hex})
         self.display_list['dates'].append({'x': 0, 'y': currentY, 'content': ggutils.format_commit_time(commit.commit_time), 'sha': commit.hex})
         currentY += 1
     for incomplete in self.graph:
         incomplete['d'].append({'type': 'V', 'y': currentY})
         self.display_list['edges'].append(incomplete)
     self.display_list['edges'].sort(key=itemgetter('order'))
     return (self.display_list, self.branches)
예제 #3
0
 def commitdiff(self, entry):
     if entry.children:
         for child in entry.children:
             for result in self.commitdiff(child):
                 yield result
     elif entry.type == pygit2.GIT_OBJ_BLOB:
         if entry.kind == DiffEntry.CREATED:
             entry_content = self.repo[entry.sha].read_raw()
             unicode_content = ggutils.force_unicode(entry_content)
             if b'\0' in entry_content or unicode_content is None:
                 #Binary file
                 if entry.name.endswith(('.png','.jpg','.jpeg','.gif')):
                     yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': 'image', 'content': DiffEntry.CREATED}
                 else:
                     yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': True, 'content': [(DiffEntry.CREATED,0,0,'(Binary file, created)')]}
             else:
                 yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': False, 'content': _all_inserted(unicode_content.splitlines())}
         elif entry.kind == DiffEntry.DELETED:
             entry_content = self.repo[entry.sha].read_raw()
             unicode_content = ggutils.force_unicode(entry_content)
             if b'\0' in entry_content or unicode_content is None:
                 #Binary file
                 if entry.name.endswith(('.png','.jpg','.jpeg','.gif')):
                     yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': 'image', 'content': DiffEntry.CREATED}
                 else:
                     yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': True, 'content': [(DiffEntry.DELETED,0,0,'(Binary file, deleted)')]}
             else:
                 yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': False, 'content': _all_deleted(unicode_content.splitlines())}
         elif entry.kind == DiffEntry.MODIFIED:
             new_content = self.repo[entry.sha].read_raw()
             old_content = self.repo[entry.old_sha].read_raw()
             new_unicode = ggutils.force_unicode(new_content).splitlines()
             old_unicode = ggutils.force_unicode(old_content).splitlines()
             if b'\0' in new_content or b'\0' in old_content or old_unicode is None or new_unicode is None:
                 #Binary file
                 if entry.name.endswith(('.png','.jpg','.jpeg','.gif')):
                     yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': 'image', 'content': DiffEntry.MODIFIED, 'old_sha': entry.old_sha }
                 else:
                     yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': True, 'content': [(DiffEntry.MODIFIED,0,0,'(Binary file, modified)')]}
             else:
                 yield {'name': entry.name, 'kind':entry.kind, 'sha': entry.sha, 'binary': False, 'content': self._context_diff(old_unicode,new_unicode,entry.name)}
예제 #4
0
def get_blob(obj, filename_hint=None):
    """Displays the contents of a blob, either in an HTML table with numbered lines, or as binary/plaintext"""
    is_binary = b'\0' in obj.data
    if is_binary:
        # It may be an image file so we try to detect the file type.
        imgtype = imghdr.what(None, obj.data)

    if request.accept_mimetypes.best == 'text/html':
        #TODO: only return a snippet, as here, if this is an AJAX request. Otherwise return a full page?
        if is_binary:
            if imgtype:
                resp = app.make_response(render_template('simple_image.html', filename=filename_hint, sha=obj.hex))
            else:
                resp = app.make_response(Markup('<pre>(Binary file)</pre>'))
        else:
            try:
                if filename_hint:
                    lexer = guess_lexer_for_filename(filename_hint, obj.data, stripnl=False, encoding='chardet')
                else:
                    lexer = guess_lexer(obj.data, stripnl=False, encoding='chardet')
            except ClassNotFound:
                highlighted = escape(ggutils.force_unicode(obj.data))
            else:
                highlighted = highlight(obj.data, lexer, HtmlFormatter(nowrap=True))
            if highlighted:
                resp = app.make_response(render_template(
                    'simple_file.html', sha=obj.hex, filename=filename_hint,
                    content=highlighted.splitlines()))
            else:
                resp = app.make_response(Markup('<pre>(Binary file)</pre>'))
    else:
        resp = app.make_response(obj.data)
        # At this point, we have some data, but no idea what mimetype it should be.
        if is_binary:
            resp.mimetype = {'gif':'image/gif', 'jpeg':'image/jpeg', 'png':'image/png'}.get(imgtype, 'application/octet-stream')
        else:
            resp.mimetype = 'text/plain'
    return resp
예제 #5
0
 def compare_data(self, old_data, new_data, name=None):
     old_data = ggutils.force_unicode(old_data).splitlines()
     new_data = ggutils.force_unicode(new_data).splitlines()
     return self._full_diff(old_data, new_data, name)