<commit_before>"""Allows use of some high-level git operations at GitHub."""

import base64
import requests
from threading import Lock

from decorator import decorator
import github


class Githubx:
    def __init__(self, *args, **kwargs):
        """All parameters are passed to PyGithub."""
        self._gh = github.Github(*args, **kwargs)
        self._mutex = Lock()

    @decorator
    def _atomic(f, self, *args, **kwargs):
        """Ensure the decorated method is the only one in this instance
        modifying GitHub resorces."""

        with self._mutex:
            return f(self, *args, **kwargs)

    @_atomic
    def commit(self, repo, filepath, content,
               commit_message,
               branch='master',
               executable=False, force=False):
        """Make a commit on GitHub.

        If _filepath_ exists, it will be replaced; if not, it will be created.

        See http://developer.github.com/v3/git/"""

        gh_repo = self._gh.get_user().get_repo(repo)

        latest_commit = gh_repo.get_git_ref("heads/%s" % branch)

        base_tree = gh_repo.get_git_commit(latest_commit).tree

        new_tree = gh_repo.create_git_tree(
            [github.InputGitTreeElement(
                path=filepath,
                mode='100755' if executable else '100644',
                type='blob',
                content=content
            )],
            base_tree)

        new_commit = gh_repo.create_git_commit(
            message=commit_message,
            parents=[latest_commit],
            tree=new_tree)

        new_commit.edit(sha=new_commit.sha, force=force)

    @_atomic
    def get_file(self, user, repo,
                 filepath, branch='master'):
        """Returns a unicode string of the file contents."""



        sha_latest_commit = Github._verify(requests.get(
            self._API + "repos/{user}/{repo}/git/refs/heads/{branch}".format(
                user=user,
                repo=repo,
                branch=branch)
        )).json['object']['sha']

        sha_base_tree = Github._verify(requests.get(
            self._API + "repos/{user}/{repo}/git/commits/{sha}".format(
                user=user,
                repo=repo,
                sha=sha_latest_commit)
        )).json['tree']['sha']

        tree = Github._verify(
            requests.get(
                self._API +
                "repos/{user}/{repo}/git/trees/{sha}?recursive=1".format(
                    user=user,
                    repo=repo,
                    sha=sha_base_tree)
            )).json['tree']

        blob_found = [blob for blob in tree
                      if blob['type'] == 'blob' and
                      blob['path'] == filepath]

        if not blob_found:
            raise GithubException('File not found in repo.')

        blob = Github._verify(requests.get(blob_found[0]['url'])).json

        if blob['encoding'] == 'base64':
            return base64.b64decode(blob['content'])
        else:
            return blob['content']
<commit_msg>finish githubx draft<commit_after>"""Allows use of some high-level git operations at GitHub."""

import base64
from threading import Lock

from decorator import decorator
import github


class Githubx:
    def __init__(self, *args, **kwargs):
        """All parameters are passed to PyGithub."""
        self._gh = github.Github(*args, **kwargs)
        self._mutex = Lock()

    @decorator
    def _atomic(f, self, *args, **kwargs):
        """Ensure the decorated method is the only one in this instance
        modifying GitHub resorces."""

        with self._mutex:
            return f(self, *args, **kwargs)

    @_atomic
    def commit(self, repo, filepath, content,
               commit_message,
               branch='master',
               executable=False, force=False):
        """Make a commit on GitHub.

        If _filepath_ exists, it will be replaced; if not, it will be created.

        See http://developer.github.com/v3/git/"""

        gh_repo = self._gh.get_user().get_repo(repo)

        latest_commit = gh_repo.get_git_ref("heads/%s" % branch)

        base_tree = gh_repo.get_git_commit(latest_commit).tree

        new_tree = gh_repo.create_git_tree(
            [github.InputGitTreeElement(
                path=filepath,
                mode='100755' if executable else '100644',
                type='blob',
                content=content
            )],
            base_tree)

        new_commit = gh_repo.create_git_commit(
            message=commit_message,
            parents=[latest_commit],
            tree=new_tree)

        new_commit.edit(sha=new_commit.sha, force=force)

    @_atomic
    def get_file(self, repo, filepath, branch='master'):
        """Return a unicode string of the file contents.
        Raise a github.GithubException is the file is not found."""

        #Raising an exception isn't the best general api, but for my use
        #it makes the most sense; I always expect the file to be there.

        gh_repo = self._gh.get_user().get_repo(repo)

        latest_commit = gh_repo.get_git_ref("heads/%s" % branch)

        base_tree = gh_repo.get_git_commit(latest_commit).tree

        matching_blobs = [el for el in base_tree.tree
                          if el.type == 'blob' and
                          el.path == filepath]

        if not matching_blobs:
            raise github.GithubException('File not found in repo.')

        blob = matching_blobs[0]

        if blob.encoding == 'base64':
            return base64.b64decode(blob.content)
        else:
            return blob.content

{'fraction_non_alphanumeric': 0.10737895301054136, 'fraction_numerical': 0.008040021440057173, 'mean_word_length': 1.9603384452670545, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1482930', 'n_tokens_mistral': 1670, 'n_tokens_neox': 1535, 'n_words': 401}