Stability improvements for pushing
Allow higher payload
Fix receiving multiple commits
Begin work on commit details/diff page
By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.
Allow higher payload
Fix receiving multiple commits
Begin work on commit details/diff page
roundabout,
created on Saturday, 23 March 2024, 12:03:24 (1711195404),
received on Wednesday, 31 July 2024, 06:54:42 (1722408882)
Author identity: vlad <vlad.muntoiu@gmail.com>
a17bef1eb7b9db27553507cb05f15af1799276fd
import flask import cairosvg import celery import shlexfrom functools import wraps from datetime import datetime from enum import Enum
app.config["SQLALCHEMY_DATABASE_URI"] = config.DB_URI app.config["SECRET_KEY"] = config.DB_PASSWORD app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.config['BABEL_TRANSLATION_DIRECTORIES'] = "i18n"app.config["BABEL_TRANSLATION_DIRECTORIES"] = "i18n" app.config["MAX_CONTENT_LENGTH"] = config.MAX_PAYLOAD_SIZEdb = SQLAlchemy(app) bcrypt = Bcrypt(app)
from celery import Celery, Task import celery_integration babel = Babel(app)
babel.init_app(app, locale_selector=get_locale) with app.app_context(): locale_names = {} for language in config.available_locales:
# NOTE: Translate this to the language's name in that language, for example in French you would use français locale_names[language] = gettext("English") worker = celery_integration.init_celery_app(app) repositories = flask.Blueprint("repository", __name__, template_folder="templates/repository/")
@app.route("/language", methods=["POST"]) def set_locale(): response = flask.redirect(flask.request.referrer if flask.request.referrer else "/", code=303)response = flask.redirect(flask.request.referrer if flask.request.referrer else "/", code=303)if not flask.request.form.get("language"): response.delete_cookie("language") else:
@app.route("/cookie-dismiss") def dismiss_banner(): response = flask.redirect(flask.request.referrer if flask.request.referrer else "/", code=303)response = flask.redirect(flask.request.referrer if flask.request.referrer else "/", code=303)response.set_cookie("cookie-banner", "1") return response
user.URL = flask.request.form["url"] user.company = flask.request.form["company"] user.company_URL = flask.request.form["companyurl"] user.email = flask.request.form.get("email") if flask.request.form.get("email") else Noneuser.email = flask.request.form.get("email") if flask.request.form.get( "email") else Noneuser.location = flask.request.form["location"] user.show_mail = True if flask.request.form.get("showmail") else False user.bio = flask.request.form.get("bio") db.session.commit() flask.flash(Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")), category="success")flask.flash( Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")), category="success")return flask.redirect(f"/{flask.session.get('username')}", code=303)
if not flask.session.get("username"): flask.abort(401) if flask.request.method == "GET": relationships = RepoFavourite.query.filter_by(user_username=flask.session.get("username"))relationships = RepoFavourite.query.filter_by( user_username=flask.session.get("username"))return flask.render_template("favourites.html", favourites=relationships)
if not flask.session.get("username"): flask.abort(401) if flask.request.method == "GET": return flask.render_template("notifications.html", notifications=UserNotification.query.filter_by(user_username=flask.session.get("username")))return flask.render_template("notifications.html", notifications=UserNotification.query.filter_by( user_username=flask.session.get("username")))@app.route("/accounts/", methods=["GET", "POST"])
if user and bcrypt.check_password_hash(user.password_hashed, password): flask.session["username"] = user.username flask.flash( Markup("<iconify-icon icon='mdi:account'></iconify-icon>" + _("Successfully logged in as {username}").format(username=username)),Markup("<iconify-icon icon='mdi:account'></iconify-icon>" + _( "Successfully logged in as {username}").format(username=username)),category="success") return flask.redirect("/", code=303) elif not user: flask.flash(Markup("<iconify-icon icon='mdi:account-question'></iconify-icon>" + _("User not found")),flask.flash(Markup( "<iconify-icon icon='mdi:account-question'></iconify-icon>" + _( "User not found")),category="alert") return flask.render_template("login.html") else: flask.flash(Markup("<iconify-icon icon='mdi:account-question'></iconify-icon>" + _("Invalid password")),flask.flash(Markup( "<iconify-icon icon='mdi:account-question'></iconify-icon>" + _( "Invalid password")),category="error") return flask.render_template("login.html") if "signup" in flask.request.form:
email2 = flask.request.form.get("email2") # repeat email is a honeypot name = flask.request.form.get("name") if not only_chars(username, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"):if not only_chars(username, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"):flask.flash(Markup( _("Usernames may only contain Latin alphabet, numbers, '-' and '_'")), category="error")
if username in config.RESERVED_NAMES: flask.flash( Markup( "<iconify-icon icon='mdi:account-error'></iconify-icon>" + _("Sorry, {username} is a system path").format(username=username)),"<iconify-icon icon='mdi:account-error'></iconify-icon>" + _( "Sorry, {username} is a system path").format( username=username)),category="error") return flask.render_template("login.html")
if user_check: flask.flash( Markup( "<iconify-icon icon='mdi:account-error'></iconify-icon>" + _("The username {username} is taken").format(username=username)),"<iconify-icon icon='mdi:account-error'></iconify-icon>" + _( "The username {username} is taken").format( username=username)),category="error") return flask.render_template("login.html") if password2 != password: flask.flash(Markup("<iconify-icon icon='mdi:key-alert'></iconify-icon>" + _("Make sure the passwords match")),flask.flash(Markup("<iconify-icon icon='mdi:key-alert'></iconify-icon>" + _( "Make sure the passwords match")),category="error") return flask.render_template("login.html")
db.session.commit() flask.session["username"] = user.username flask.flash(Markup( "<iconify-icon icon='mdi:account'></iconify-icon>" + _("Successfully created and logged in as {username}").format(username=username)),"<iconify-icon icon='mdi:account'></iconify-icon>" + _( "Successfully created and logged in as {username}").format( username=username)),category="success") notification = Notification({"type": "welcome"})
name = flask.request.form["name"] visibility = int(flask.request.form["visibility"]) if not only_chars(name, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"):if not only_chars(name, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"):flask.flash(Markup( "<iconify-icon icon='mdi:error'></iconify-icon>" + _("Repository names may only contain Latin alphabet, numbers, '-' and '_'")),"<iconify-icon icon='mdi:error'></iconify-icon>" + _( "Repository names may only contain Latin alphabet, numbers, '-' and '_'")),category="error") return flask.render_template("new-repo.html")
@app.route("/logout") def logout(): flask.session.clear() flask.flash(Markup("<iconify-icon icon='mdi:account'></iconify-icon>" + _("Successfully logged out")), category="info")flask.flash(Markup( "<iconify-icon icon='mdi:account'></iconify-icon>" + _("Successfully logged out")), category="info")return flask.redirect("/", code=303) @app.route("/<username>/", methods=["GET", "POST"]) def user_profile(username): old_relationship = UserFollow.query.filter_by(follower_username=flask.session.get("username"),followed_username=username).first()old_relationship = UserFollow.query.filter_by( follower_username=flask.session.get("username"), followed_username=username).first()if flask.request.method == "GET": user = User.query.filter_by(username=username).first() match flask.request.args.get("action"): case "repositories": repos = Repo.query.filter_by(owner_name=username, visibility=2) return flask.render_template("user-profile-repositories.html", user=user, repos=repos,return flask.render_template("user-profile-repositories.html", user=user, repos=repos,relationship=old_relationship) case "followers": return flask.render_template("user-profile-followers.html", user=user, relationship=old_relationship)return flask.render_template("user-profile-followers.html", user=user, relationship=old_relationship)case "follows": return flask.render_template("user-profile-follows.html", user=user, relationship=old_relationship)return flask.render_template("user-profile-follows.html", user=user, relationship=old_relationship)case _: return flask.render_template("user-profile-overview.html", user=user, relationship=old_relationship)return flask.render_template("user-profile-overview.html", user=user, relationship=old_relationship)elif flask.request.method == "POST": match flask.request.args.get("action"):
db.session.add(notification) db.session.commit() result = celery_tasks.send_notification.delay(notification.id, [username], 1)result = celery_tasks.send_notification.delay(notification.id, [username], 1)db.session.commit() return flask.redirect("?", code=303)
@app.route("/<username>/<repository>/raw/<branch>/<path:subpath>") def repository_raw(username, repository, branch, subpath): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository)
except git.exc.GitCommandError: return flask.render_template("not-found.html"), 404 return flask.send_from_directory(config.REPOS_PATH, os.path.join(username, repository, subpath))return flask.send_from_directory(config.REPOS_PATH, os.path.join(username, repository, subpath))@repositories.route("/<username>/<repository>/tree/", defaults={"branch": None, "subpath": ""}) @repositories.route("/<username>/<repository>/tree/<branch>/", defaults={"subpath": ""}) @repositories.route("/<username>/<repository>/tree/<branch>/<path:subpath>") def repository_tree(username, repository, branch, subpath): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
path = os.path.join(server_repo_location, file) mimetype = guess_mime(path) text = git_command(server_repo_location, None, "log", "--format='%H\n'", file).decode()text = git_command(server_repo_location, None, "log", "--format='%H\n'", shlex.quote(file)).decode()sha = text.split("\n")[0] identifier = f"/{username}/{repository}/{sha}" last_commit = Commit.query.filter_by(identifier=identifier).first()last_commit = db.session.get(Commit, identifier)info = { "name": os.path.basename(file),
) @repositories.route("/<username>/<repository>/commit/<sha>") def repository_commit(username, repository, sha): if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None): flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository) app.logger.info(f"Loading {server_repo_location}") if not os.path.exists(server_repo_location): app.logger.error(f"Cannot load {server_repo_location}") return flask.render_template("not-found.html"), 404 repo = git.Repo(server_repo_location) repo_data = Repo.query.filter_by(route=f"/{username}/{repository}").first() files = git_command(os.path.join(server_repo_location, ".git"), None, "diff-tree", "-r", "--name-only", "--no-commit-id", sha).decode().split("\n") return flask.render_template( "repo-commit.html", username=username, repository=repository, remote=f"http{'s' if config.suggest_https else ''}://{config.BASE_DOMAIN}/git/{username}/{repository}", is_favourite=get_favourite(flask.session.get("username"), username, repository), diff={file: git_command(os.path.join(server_repo_location, ".git"), None, "diff", str(sha), str(sha) + "^", file).decode().split("\n") for file in files} ) @repositories.route("/<username>/<repository>/forum/") def repository_forum(username, repository): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
@repositories.route("/<username>/<repository>/forum/topic/<int:id>") def repository_forum_topic(username, repository, id): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
@repositories.route("/<username>/<repository>/forum/new", methods=["POST", "GET"]) def repository_forum_new(username, repository): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) serverRepoLocation = os.path.join(config.REPOS_PATH, username, repository)
relationships = RepoAccess.query.filter_by(repo=repoData) userRelationship = RepoAccess.query.filter_by(repo=repoData, user=user).first() post = Post(user, repoData, None, flask.request.form["subject"], flask.request.form["message"])post = Post(user, repoData, None, flask.request.form["subject"], flask.request.form["message"])db.session.add(post) db.session.commit() return flask.redirect( flask.url_for(".repository_forum_thread", username=username, repository=repository, post_id=post.number),flask.url_for(".repository_forum_thread", username=username, repository=repository, post_id=post.number),code=303) @repositories.route("/<username>/<repository>/forum/<int:post_id>") def repository_forum_thread(username, repository, post_id): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
@repositories.route("/<username>/<repository>/forum/<int:post_id>/reply", methods=["POST"]) def repository_forum_reply(username, repository, post_id): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
flask.abort(401) parent = Post.query.filter_by(identifier=f"/{username}/{repository}/{post_id}").first() post = Post(user, repo_data, parent, flask.request.form["subject"], flask.request.form["message"])post = Post(user, repo_data, parent, flask.request.form["subject"], flask.request.form["message"])db.session.add(post) post.update_date() db.session.commit() return flask.redirect( flask.url_for(".repository_forum_thread", username=username, repository=repository, post_id=post_id),flask.url_for(".repository_forum_thread", username=username, repository=repository, post_id=post_id),code=303) @repositories.route("/<username>/<repository>/forum/<int:post_id>/voteup", defaults={"score": 1})@repositories.route("/<username>/<repository>/forum/<int:post_id>/votedown", defaults={"score": -1})@repositories.route("/<username>/<repository>/forum/<int:post_id>/voteup", defaults={"score": 1}) @repositories.route("/<username>/<repository>/forum/<int:post_id>/votedown", defaults={"score": -1})@repositories.route("/<username>/<repository>/forum/<int:post_id>/votes", defaults={"score": 0}) def repository_forum_vote(username, repository, post_id, score): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
db.session.commit() user_vote = PostVote.query.filter_by(user_username=user.username, post_identifier=post.identifier).first()response = flask.make_response(str(post.vote_sum) + " " + str(user_vote.vote_score if user_vote else 0))user_vote = PostVote.query.filter_by(user_username=user.username, post_identifier=post.identifier).first() response = flask.make_response( str(post.vote_sum) + " " + str(user_vote.vote_score if user_vote else 0))response.content_type = "text/plain" return response
@repositories.route("/<username>/<repository>/favourite") def repository_favourite(username, repository): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
if not user: flask.abort(401) old_relationship = RepoFavourite.query.filter_by(user_username=user.username, repo_route=repo_data.route).first()old_relationship = RepoFavourite.query.filter_by(user_username=user.username, repo_route=repo_data.route).first()if old_relationship: db.session.delete(old_relationship) else:
@repositories.route("/<username>/<repository>/users/", methods=["GET", "POST"]) def repository_users(username, repository): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
if flask.request.form.get("new-username"): # Create new relationship new_user = User.query.filter_by(username=flask.request.form.get("new-username")).first()new_user = User.query.filter_by( username=flask.request.form.get("new-username")).first()relationship = RepoAccess(new_user, repo_data, flask.request.form.get("new-level")) db.session.add(relationship) db.session.commit() if flask.request.form.get("update-username"): # Create new relationship updated_user = User.query.filter_by(username=flask.request.form.get("update-username")).first()updated_user = User.query.filter_by( username=flask.request.form.get("update-username")).first()relationship = RepoAccess.query.filter_by(repo=repo_data, user=updated_user).first() if flask.request.form.get("update-level") == -1: relationship.delete()
relationship.access_level = flask.request.form.get("update-level") db.session.commit() return flask.redirect(app.url_for(".repository_users", username=username, repository=repository))return flask.redirect( app.url_for(".repository_users", username=username, repository=repository))@repositories.route("/<username>/<repository>/branches/") def repository_branches(username, repository): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
@repositories.route("/<username>/<repository>/log/", defaults={"branch": None}) @repositories.route("/<username>/<repository>/log/<branch>/") def repository_log(username, repository, branch): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
all_refs.append((ref, "tag")) commit_list = [f"/{username}/{repository}/{sha}" for sha in git_command(server_repo_location, None, "log", "--format='%H'").decode().split("\n")]git_command(server_repo_location, None, "log", "--format='%H'").decode().split("\n")]commits = Commit.query.filter(Commit.identifier.in_(commit_list))
@repositories.route("/<username>/<repository>/prs/", methods=["GET", "POST"]) def repository_prs(username, repository): if not (get_visibility(username, repository) or get_permission_level(flask.session.get("username"), username,repository) is not None):if not (get_visibility(username, repository) or get_permission_level( flask.session.get("username"), username, repository) is not None):flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
head_data = db.session.get(Repo, head_route) if not head_data.visibility: flask.flash(Markup( "<iconify-icon icon='mdi:error'></iconify-icon>" + _("Head can't be restricted")),"<iconify-icon icon='mdi:error'></iconify-icon>" + _( "Head can't be restricted")),category="error") return flask.redirect(".", 303) pull_request = PullRequest(repo_data, head, head_data, base, db.session.get(User, flask.session["username"]))pull_request = PullRequest(repo_data, head, head_data, base, db.session.get(User, flask.session["username"]))db.session.add(pull_request) db.session.commit()
if __name__ == "__main__": app.run(debug=True, port=8080, host="0.0.0.0") app.register_blueprint(repositories)app.register_blueprint(repositories)
BASE_DOMAIN: str = "localhost" SERVER_IPS: set = {"127.0.0.1", "localhost", "0.0.0.0"} AUTH_REALM: str = "roundabout" MAX_PAYLOAD_SIZE: int = 4 * 1024**3AVATAR_SIZE: tuple = (192, 192)
auth = HTTPBasicAuth(realm=config.AUTH_REALM) auth_required = flask.Response("Unauthorized Access", 401, {"WWW-Authenticate": 'Basic realm="Login Required"'})auth_required = flask.Response("Unauthorized Access", 401, {"WWW-Authenticate": 'Basic realm="Login Required"'})@auth.verify_password
flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository, ".git") text = git_command(server_repo_location, flask.request.data, "upload-pack", "--stateless-rpc", ".")text = git_command(server_repo_location, flask.request.data, "upload-pack", "--stateless-rpc", ".")return flask.Response(text, content_type="application/x-git-upload-pack-result")
flask.abort(403) server_repo_location = os.path.join(config.REPOS_PATH, username, repository, ".git") text = git_command(server_repo_location, flask.request.data, "receive-pack", "--stateless-rpc", ".")text = git_command(server_repo_location, flask.request.data, "receive-pack", "--stateless-rpc", ".") if flask.request.data == b"0000": return flask.Response("", content_type="application/x-git-receive-pack-result") push_info = flask.request.data.split(b"\x00")[1].split(b" ")[0].decode() old_sha, new_sha, _ = push_info.split() commits_list = subprocess.check_output(["git", "rev-list", f"{old_sha}..{new_sha}"], cwd=server_repo_location).decode().strip().split("\n")sha = flask.request.data.split(b" ", 2)[1].decode() info = git_command(server_repo_location, None, "show", "-s", "--format='%H%n%at%n%cn <%ce>%n%B'", sha).decode()if re.match("^[0-9a-fA-F]{40}$", info[:40]):for sha in commits_list: info = git_command(server_repo_location, None, "show", "-s", "--format='%H%n%at%n%cn <%ce>%n%B'", sha).decode()print(info.split("\n", 3)) sha, time, identity, body = info.split("\n", 3) login = flask.g.user
repo.git.checkout("-f", repo_data.default_branch) if auth.current_user() is None and ( not get_visibility(username, repository) or flask.request.args.get("service") == "git-receive-pack"):not get_visibility(username, repository) or flask.request.args.get( "service") == "git-receive-pack"):return auth_required try: if not (get_visibility(username, repository) or get_permission_level(flask.g.user, username,if not (get_visibility(username, repository) or get_permission_level(flask.g.user, username,repository) is not None): flask.abort(403) except AttributeError:
service_line = (f"{len(service_line) + 4:04x}" + service_line).encode() if service == "upload-pack": text = service_line + b"0000" + git_command(server_repo_location, None, "upload-pack", "--stateless-rpc","--advertise-refs", "--http-backend-info-refs", ".")text = service_line + b"0000" + git_command(server_repo_location, None, "upload-pack", "--stateless-rpc", "--advertise-refs", "--http-backend-info-refs", ".")elif service == "receive-pack": refs = git_command(server_repo_location, None, "receive-pack", "--http-backend-info-refs", ".")refs = git_command(server_repo_location, None, "receive-pack", "--http-backend-info-refs", ".")text = service_line + b"0000" + refs else: flask.abort(403)
response = flask.Response(text, content_type=f"application/x-git-{service}-advertisement") response.headers["Cache-Control"] = "no-cache" return responsereturn response
msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2024-03-19 18:02+0200\n""POT-Creation-Date: 2024-03-21 16:33+0200\n""PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
msgid "Successfully logged out" msgstr "" #: app.py:1004#: app.py:1033msgid "Bad branch name" msgstr "" #: app.py:1011#: app.py:1040msgid "Head can't be restricted" msgstr ""
msgid "When you add favourite repositories, you can manage them from here." msgstr "" #: templates/file-view.html:5 msgid "View raw" msgstr "" #: templates/file-view.html:6 templates/no-home.html:39 msgid "Download" msgstr "" #: templates/file-view.html:58 templates/file-view.html:63 msgid "Your browser does not support HTML5 multimedia." msgstr "" #: templates/file-view.html:59 templates/file-view.html:64 msgid "Download file" msgstr "" #: templates/forbidden.html:3 msgid "403" msgstr ""
msgid "FAQs" msgstr "" #: templates/home.html:3 templates/repository/repo-file.html:25#: templates/home.html:3 templates/repository/repo-file.html:24#: templates/repository/repo-tree.html:24 msgid "Home" msgstr ""
msgstr "" #: templates/no-home.html:33 msgid "The roundabout to all your code"msgid "Welcome to the roundabout"msgstr "" #: templates/no-home.html:34 msgid "Git repository hosting, made simple. Powered by free software."msgstr ""#: templates/no-home.html:39msgid "Download"msgid "Easy git repository hosting, with free software"msgstr "" #: templates/no-home.html:40
msgid "Remove favourite" msgstr "" #: templates/task-monitor.html:3 #, python-format msgid "Task monitor for %(result_id)s" msgstr "" #: templates/task-monitor.html:6 #, python-format msgid "Task %(result_id)s" msgstr "" #: templates/task-monitor.html:11 msgid "Task results" msgstr "" #: templates/task-monitor.html:15 msgid "Done" msgstr "" #: templates/task-monitor.html:18 msgid "Running..." msgstr "" #: templates/task-monitor.html:24 msgid "Info" msgstr "" #: templates/task-monitor.html:28 msgid "Errors" msgstr "" #: templates/task-monitor.html:33 msgid "Cannot merge your branches" msgstr "" #: templates/task-monitor.html:35 msgid "" "Since we can't help you with this yet, you'll need to resolve the merge " "conflicts on your own computer." msgstr "" #: templates/task-monitor.html:38 msgid "In a shell inside your repository execute:" msgstr "" #: templates/task-monitor.html:47 msgid "Then fix your conflicts, merge, and finally, run:" msgstr "" #: templates/task-monitor.html:50 msgid "git remote rm UPSTREAM" msgstr "" #: templates/task-monitor.html:52 msgid "and push the changes." msgstr "" #: templates/task-monitor.html:59 msgid "Resolve your conflicts and merge, then push." msgstr "" #: templates/task-monitor.html:63 msgid "Merge simulation went well; continue?" msgstr "" #: templates/repository/repo-prs.html:58 templates/task-monitor.html:64 msgid "Merge" msgstr "" #: templates/teapot.html:3 msgid "418" msgstr ""
msgid "Tags" msgstr "" #: templates/repository/repo-commit.html:6 #: templates/repository/repo-file.html:5 #, python-format msgid "%(basename)s in %(username)s/%(repository)s" msgstr "" #: templates/repository/repo-file.html:16#: templates/repository/repo-file.html:15#: templates/repository/repo-tree.html:15 msgid "Back" msgstr "" #: templates/repository/repo-file.html:19#: templates/repository/repo-file.html:18#: templates/repository/repo-tree.html:18 msgid "Forwards" msgstr "" #: templates/repository/repo-file.html:22#: templates/repository/repo-file.html:21#: templates/repository/repo-tree.html:21 msgid "Up" msgstr "" #: templates/repository/repo-file.html:28#: templates/repository/repo-file.html:27#: templates/repository/repo-tree.html:27 msgid "Refresh" msgstr ""
msgid "Deny" msgstr "" #: templates/repository/repo-prs.html:58msgid "Merge"msgstr ""#: templates/repository/repo-tree.html:5 #, python-format msgid "Tree of %(username)s/%(repository)s"
msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2024-03-19 18:02+0200\n""PO-Revision-Date: 2024-03-19 18:05+0200\n""POT-Creation-Date: 2024-03-21 16:33+0200\n" "PO-Revision-Date: 2024-03-21 16:39+0200\n""Last-Translator: roundabout <root@roundabout-host.com>\n" "Language-Team: ro_RO <LL@li.org>\n" "Language: ro_RO\n"
msgid "Successfully logged out" msgstr "Ieșit din cont cu succes" #: app.py:1004#: app.py:1033msgid "Bad branch name" msgstr "Nume de ramificație greșit" #: app.py:1011#: app.py:1040msgid "Head can't be restricted" msgstr "Vârful nu poate fi restricționat"
msgid "When you add favourite repositories, you can manage them from here." msgstr "Când adaugi depozite preferate, le poți gestiona de aici." #: templates/file-view.html:5 msgid "View raw" msgstr "Vezi versiunea brută" #: templates/file-view.html:6 templates/no-home.html:39 msgid "Download" msgstr "Descarcă" #: templates/file-view.html:58 templates/file-view.html:63 msgid "Your browser does not support HTML5 multimedia." msgstr "Navigatorul tău nu acceptă formatele multimedia HTML5." #: templates/file-view.html:59 templates/file-view.html:64 msgid "Download file" msgstr "Descarcă fișierul" #: templates/forbidden.html:3 msgid "403" msgstr "403"
msgid "FAQs" msgstr "Întrebări frecvente" #: templates/home.html:3 templates/repository/repo-file.html:25#: templates/home.html:3 templates/repository/repo-file.html:24#: templates/repository/repo-tree.html:24 msgid "Home" msgstr "Acasă"
msgstr "Bine ai venit" #: templates/no-home.html:33 msgid "The roundabout to all your code"msgstr "Giratoriul către tot codul tău"msgid "Welcome to the roundabout" msgstr "Bine ai venit la giratoriu"#: templates/no-home.html:34 msgid "Git repository hosting, made simple. Powered by free software."msgstr "Găzduirea depozitelor de git, acum ușoară. Alimentat de programe libere."#: templates/no-home.html:39msgid "Download"msgstr "Descarcă"msgid "Easy git repository hosting, with free software" msgstr "Găzduirea depozitelor git ușoară, cu programe libere"#: templates/no-home.html:40 msgid "for setting up your own instance"
msgid "Remove favourite" msgstr "Elimină preferatul" #: templates/task-monitor.html:3 #, python-format msgid "Task monitor for %(result_id)s" msgstr "Monitorul sarcinii %(result_id)s" #: templates/task-monitor.html:6 #, python-format msgid "Task %(result_id)s" msgstr "Sarcina %(result_id)s" #: templates/task-monitor.html:11 msgid "Task results" msgstr "Rezultatele sarcinii" #: templates/task-monitor.html:15 msgid "Done" msgstr "Gata" #: templates/task-monitor.html:18 msgid "Running..." msgstr "Se execută..." #: templates/task-monitor.html:24 msgid "Info" msgstr "Informații" #: templates/task-monitor.html:28 msgid "Errors" msgstr "Erori" #: templates/task-monitor.html:33 msgid "Cannot merge your branches" msgstr "Nu-ți putem îmbina ramificațiile" #: templates/task-monitor.html:35 msgid "" "Since we can't help you with this yet, you'll need to resolve the merge " "conflicts on your own computer." msgstr "" "Pentru că nu te putem ajuta încă cu aceasta, va trebui să rezolvi conflictele " "pe propriul calculator." #: templates/task-monitor.html:38 msgid "In a shell inside your repository execute:" msgstr "Într-un terminal în depozitul tău execută:" #: templates/task-monitor.html:47 msgid "Then fix your conflicts, merge, and finally, run:" msgstr "Apoi rezolvă-ți conflictele, îmbină, și rulează:" #: templates/task-monitor.html:50 msgid "git remote rm UPSTREAM" msgstr "" #: templates/task-monitor.html:52 msgid "and push the changes." msgstr "și trimite schimbările." #: templates/task-monitor.html:59 msgid "Resolve your conflicts and merge, then push." msgstr "Rezolvă-ți conflictele și îmbină, apoi trimite." #: templates/task-monitor.html:63 msgid "Merge simulation went well; continue?" msgstr "Simularea îmbinării a funcționat; continui?" #: templates/repository/repo-prs.html:58 templates/task-monitor.html:64 msgid "Merge" msgstr "Îmbină" #: templates/teapot.html:3 msgid "418" msgstr "418"
msgid "Tags" msgstr "Etichete" #: templates/repository/repo-file.html:5#: templates/repository/repo-commit.html:6 templates/repository/repo-file.html:5#, python-format msgid "%(basename)s in %(username)s/%(repository)s" msgstr "%(basename)s în %(username)s/%(repository)s" #: templates/repository/repo-file.html:16 templates/repository/repo-tree.html:15#: templates/repository/repo-file.html:15 templates/repository/repo-tree.html:15msgid "Back" msgstr "Înapoi" #: templates/repository/repo-file.html:19 templates/repository/repo-tree.html:18#: templates/repository/repo-file.html:18 templates/repository/repo-tree.html:18msgid "Forwards" msgstr "Înainte" #: templates/repository/repo-file.html:22 templates/repository/repo-tree.html:21#: templates/repository/repo-file.html:21 templates/repository/repo-tree.html:21msgid "Up" msgstr "Sus" #: templates/repository/repo-file.html:28 templates/repository/repo-tree.html:27#: templates/repository/repo-file.html:27 templates/repository/repo-tree.html:27msgid "Refresh" msgstr "Reîncarcă"
msgid "Deny" msgstr "Respinge" #: templates/repository/repo-prs.html:58msgid "Merge"msgstr "Îmbină"#: templates/repository/repo-tree.html:5 #, python-format msgid "Tree of %(username)s/%(repository)s"
#: templates/repository/repo-users.html:81 msgid "Add" msgstr "Adaugă" #~ msgid "The roundabout to all your code" #~ msgstr "Giratoriul către tot codul tău"
{% extends "default.html" %} {% set active_page = "log" %} {% block title %} {% trans basename=basename, username=username, repository=repository %}{{ basename }} in {{ username }}/{{ repository }}{% endtrans %} {% endblock %} {% block content %} <x-vbox> <x-frame style="--width: 896px;" class="flexible-space"> {% for line in diff | decode | split("\n") %} {% if line[0] == "+" %} <ins>{{ line[1:] }}</ins> {% endif %} {% endfor %} </x-frame> </x-vbox> {% endblock %}
{% trans basename=basename, username=username, repository=repository %}{{ basename }} in {{ username }}/{{ repository }}{% endtrans %} {% endblock %} {% block content %} <x-vbox> <x-frame style="--width: 896px;" class="flexible-space"> <article class="card">
{% trans %}Then fix your conflicts, merge, and finally, run:{% endtrans %} </p> <pre> <span class="decorative-dollar">{% trans %}git remote rm UPSTREAM{% endtrans %}</span></pre><span class="decorative-dollar">git remote rm UPSTREAM</span></pre><p> {% trans %}and push the changes.{% endtrans %} </p>
<td>{{ file.mimetype }}</td> <td style="text-align: right;">{{ file.size[0] }} {{ file.size[1] }}</td> <td> <x-hbox style="align-items: baseline; gap: 0.5ch;"><code>{{ file.commit.sha[:file.shaSize] }}</code><span class="commit-message">{{ file.commit.message }}</span></x-hbox>{% if file.commit %} <a href="/{{ username }}/{{ repository }}/commit/{{ file.commit.sha }}" class="file-link"> <x-hbox style="align-items: baseline; gap: 0.5ch;"> <code>{{ file.commit.sha[:file.shaSize] }}</code> <span class="commit-message">{{ file.commit.message }}</span> </x-hbox> </a> {% else %} ??? {% endif %}</td> </tr> {% endfor %}