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)
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)
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)
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))
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)
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))
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)