Example #1
0
def get_contents(repo_key, file_path=''):
    repo = get_repo(repo_key)
    refspec = request.args.get('ref', 'master')
    commit = get_commit_for_refspec(repo, refspec)
    tree = get_tree(repo, commit.tree.id)
    obj = get_object_from_path(repo, tree, file_path)
    return _get_contents(repo_key, repo, refspec, file_path, obj)
Example #2
0
def get_zip_file(repo_key, branch_or_tag_or_sha):
    """
    Serves a ZIP file of a working copy of the repo at the given commit.
    Note: This endpoint is relatively slow, and the ZIP file is generated from-scratch on each request (no caching is done).
    """
    repo = get_repo(repo_key)
    commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, commit.tree_id)

    wrapper_dir = _wrapper_dir_name_for(repo_key, commit)
    temp_file = _make_temp_file(suffix=ZIP_EXTENSION)
    with zipfile.ZipFile(temp_file,
                         mode='w',
                         compression=ZIP_COMPRESSION_METHOD,
                         allowZip64=True) as zip_file:
        for filepath, _, blob in _walk_tree_recursively(repo,
                                                        tree,
                                                        blobs_only=True):
            filepath = os.path.join(wrapper_dir, filepath)
            zip_file.writestr(filepath, blob.data)
    temp_file.seek(0)
    return _send_transient_file_as_attachment(
        temp_file,
        _archive_filename_for(repo_key,
                              refspec=branch_or_tag_or_sha,
                              ext=ZIP_EXTENSION), mime_types.ZIP)
Example #3
0
def get_contents(repo_key, file_path=''):
    repo = get_repo(repo_key)
    refspec = request.args.get('ref', 'master')
    commit = get_commit_for_refspec(repo, refspec)
    tree = get_tree(repo, commit.tree.id)
    obj = get_object_from_path(repo, tree, file_path)
    return _get_contents(repo_key, repo, refspec, file_path, obj)
Example #4
0
def get_raw(repo_key, branch_or_tag_or_sha, file_path):
    repo = get_repo(repo_key)
    commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, commit.tree.id)
    data = get_raw_file_content(repo, tree, file_path)
    mime_type = guess_mime_type(os.path.basename(file_path), data)
    if mime_type is None:
        mime_type = mime_types.OCTET_STREAM
    return Response(data, mimetype=mime_type)
Example #5
0
def get_raw(repo_key, branch_or_tag_or_sha, file_path):
    repo = get_repo(repo_key)
    commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, commit.tree.id)
    data = get_raw_file_content(repo, tree, file_path)
    mime_type = guess_mime_type(os.path.basename(file_path), data)
    if mime_type is None:
        mime_type = mime_types.OCTET_STREAM
    return Response(data, mimetype=mime_type)
Example #6
0
def get_tarball(repo_key, branch_or_tag_or_sha):
    """
    Serves a TAR file of a working copy of the repo at the given commit.
    If Python's zlib bindings are available, the TAR file will be gzip-ed.
    The limited permissions information that git stores is honored in the TAR file.
    The commit SHA is included as a PAX header field named "comment".
    Note: This endpoint is relatively slow, and the TAR file is generated from-scratch on each request (no caching is done).
    """
    repo = get_repo(repo_key)
    commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, commit.tree_id)

    wrapper_dir = _wrapper_dir_name_for(repo_key, commit)
    extension = (TGZ_EXTENSION if ZLIB_SUPPORT else TAR_EXTENSION)
    timestamp = int(
        (datetime.utcnow() - EPOCH_START
         ).total_seconds())  # FIX ME: use committer/author timestamp?
    temp_file = _make_temp_file(suffix=extension)
    with tarfile.open(fileobj=temp_file,
                      mode=TARFILE_WRITE_MODE,
                      encoding='utf-8') as tar_file:
        tar_file.pax_headers = {u'comment': unicode(commit.id)}

        for path, filemode, obj in _walk_tree_recursively(repo, tree):
            tar_info = tarfile.TarInfo(os.path.join(wrapper_dir, path))
            tar_info.mtime = timestamp

            if obj.type == GIT_OBJ_BLOB:
                tar_info.size = obj.size

            if obj.type == GIT_OBJ_TREE:
                filemode = 0o755  # git doesn't store meaningful directory perms
            tar_info.mode = filemode

            if obj.type == GIT_OBJ_BLOB:
                tar_info.type = tarfile.REGTYPE
                content = StringIO(obj.data)
            elif obj.type == GIT_OBJ_TREE:
                tar_info.type = tarfile.DIRTYPE
                content = None
            # FIX ME: handle submodules & symlinks

            tar_file.addfile(tar_info, content)
    temp_file.seek(0)
    return _send_transient_file_as_attachment(
        temp_file,
        _archive_filename_for(repo_key,
                              refspec=branch_or_tag_or_sha,
                              ext=extension),
        (mime_types.GZIP if ZLIB_SUPPORT else mime_types.TAR))
Example #7
0
def get_blame(repo_key, branch_or_tag_or_sha, file_path):
    min_line = request.args.get('firstLine')
    if min_line is None:
        min_line = 1
    try:
        min_line = int(min_line)
    except ValueError:
        raise BadRequest("firstLine was not a valid integer")
    if min_line < 1:
        raise BadRequest("firstLine must be positive")

    max_line = request.args.get('lastLine')
    if max_line is not None:
        try:
            max_line = int(max_line)
        except ValueError:
            raise BadRequest("lastLine was not a valid integer")
        if max_line < 1:
            raise BadRequest("lastLine must be positive")

        if min_line > max_line:
            raise BadRequest("firstLine cannot be greater than lastLine")

    repo = get_repo(repo_key)
    newest_commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, newest_commit.tree_id)

    raw_lines = get_raw_file_content(repo, tree, file_path).splitlines()
    if min_line > len(raw_lines):
        raise BadRequest("firstLine out of bounds")
    if max_line is not None and max_line > len(raw_lines):
        raise BadRequest("lastLine out of bounds")
    raw_lines = raw_lines[(min_line - 1):max_line]

    blame = _get_blame(
        repo,
        file_path,
        newest_commit,
        oldest_refspec=request.args.get('oldest'),
        min_line=min_line,
        max_line=max_line,
    )

    return convert_blame(repo_key, repo, blame, raw_lines, min_line)
Example #8
0
def get_blame(repo_key, branch_or_tag_or_sha, file_path):
    min_line = request.args.get('firstLine')
    if min_line is None:
        min_line = 1
    try:
        min_line = int(min_line)
    except ValueError:
        raise BadRequest("firstLine was not a valid integer")
    if min_line < 1:
        raise BadRequest("firstLine must be positive")

    max_line = request.args.get('lastLine')
    if max_line is not None:
        try:
            max_line = int(max_line)
        except ValueError:
            raise BadRequest("lastLine was not a valid integer")
        if max_line < 1:
            raise BadRequest("lastLine must be positive")

        if min_line > max_line:
            raise BadRequest("firstLine cannot be greater than lastLine")

    repo = get_repo(repo_key)
    newest_commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, newest_commit.tree_id)

    raw_lines = get_raw_file_content(repo, tree, file_path).splitlines()
    if min_line > len(raw_lines):
        raise BadRequest("firstLine out of bounds")
    if max_line is not None and max_line > len(raw_lines):
        raise BadRequest("lastLine out of bounds")
    raw_lines = raw_lines[(min_line - 1):max_line]

    blame = _get_blame(
        repo,
        file_path,
        newest_commit,
        oldest_refspec=request.args.get('oldest'),
        min_line=min_line,
        max_line=max_line,
    )

    return convert_blame(repo_key, repo, blame, raw_lines, min_line)
Example #9
0
def get_tarball(repo_key, branch_or_tag_or_sha):
    """
    Serves a TAR file of a working copy of the repo at the given commit.
    If Python's zlib bindings are available, the TAR file will be gzip-ed.
    The limited permissions information that git stores is honored in the TAR file.
    The commit SHA is included as a PAX header field named "comment".
    Note: This endpoint is relatively slow, and the TAR file is generated from-scratch on each request (no caching is done).
    """
    repo = get_repo(repo_key)
    commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, commit.tree.hex)

    wrapper_dir = _wrapper_dir_name_for(repo_key, commit)
    extension = (TGZ_EXTENSION if ZLIB_SUPPORT else TAR_EXTENSION)
    timestamp = int((datetime.utcnow() - EPOCH_START).total_seconds())  # FIX ME: use committer/author timestamp?
    temp_file = _make_temp_file(suffix=extension)
    with tarfile.open(fileobj=temp_file, mode=TARFILE_WRITE_MODE, encoding='utf-8') as tar_file:
        tar_file.pax_headers = {u'comment': commit.hex.decode('ascii')}

        for path, filemode, obj in _walk_tree_recursively(repo, tree):
            tar_info = tarfile.TarInfo(os.path.join(wrapper_dir, path))
            tar_info.mtime = timestamp

            if obj.type == GIT_OBJ_BLOB:
                tar_info.size = obj.size

            if obj.type == GIT_OBJ_TREE:
                filemode = 0o755  # git doesn't store meaningful directory perms
            tar_info.mode = filemode

            if obj.type == GIT_OBJ_BLOB:
                tar_info.type = tarfile.REGTYPE
                content = StringIO(obj.data)
            elif obj.type == GIT_OBJ_TREE:
                tar_info.type = tarfile.DIRTYPE
                content = None
            # FIX ME: handle submodules & symlinks

            tar_file.addfile(tar_info, content)
    temp_file.seek(0)
    return _send_transient_file_as_attachment(temp_file,
                                              _archive_filename_for(repo_key, refspec=branch_or_tag_or_sha, ext=extension),
                                              (mime_types.GZIP if ZLIB_SUPPORT else mime_types.TAR))
Example #10
0
def get_zip_file(repo_key, branch_or_tag_or_sha):
    """
    Serves a ZIP file of a working copy of the repo at the given commit.
    Note: This endpoint is relatively slow, and the ZIP file is generated from-scratch on each request (no caching is done).
    """
    repo = get_repo(repo_key)
    commit = get_commit_for_refspec(repo, branch_or_tag_or_sha)
    tree = get_tree(repo, commit.tree.hex)

    wrapper_dir = _wrapper_dir_name_for(repo_key, commit)
    temp_file = _make_temp_file(suffix=ZIP_EXTENSION)
    with zipfile.ZipFile(temp_file, mode='w', compression=ZIP_COMPRESSION_METHOD, allowZip64=True) as zip_file:
        for filepath, _, blob in _walk_tree_recursively(repo, tree, blobs_only=True):
            filepath = os.path.join(wrapper_dir, filepath)
            zip_file.writestr(filepath, blob.data)
    temp_file.seek(0)
    return _send_transient_file_as_attachment(temp_file,
                                              _archive_filename_for(repo_key, refspec=branch_or_tag_or_sha, ext=ZIP_EXTENSION),
                                              mime_types.ZIP)