import os import subprocess import urllib.request import json import base64 import tempfile GITLAB_TOKEN = "glpat-KrN8svq4D9QeQD6-_p_r7GM6MQpvOjEKdTozN3R4cg8.01.171o6kz82" FORGEJO_AUTH = "mrhavens:Aok4y2k!" def get_gitlab_repos(): req = urllib.request.Request("https://gitlab.com/api/v4/users/mrhavens/projects?per_page=100") req.add_header("PRIVATE-TOKEN", GITLAB_TOKEN) with urllib.request.urlopen(req) as f: return [r for r in json.loads(f.read().decode('utf-8'))] def get_forgejo_repos(): req = urllib.request.Request("https://remember.thefoldwithin.earth/api/v1/user/repos?limit=100") req.add_header("User-Agent", "Mozilla/5.0") auth = base64.b64encode(FORGEJO_AUTH.encode("ascii")).decode("ascii") req.add_header("Authorization", f"Basic {auth}") with urllib.request.urlopen(req) as f: return [r["name"] for r in json.loads(f.read().decode('utf-8'))] def create_forgejo_repo(name, description): req = urllib.request.Request("https://remember.thefoldwithin.earth/api/v1/user/repos", method="POST") req.add_header("User-Agent", "Mozilla/5.0") auth = base64.b64encode(FORGEJO_AUTH.encode("ascii")).decode("ascii") req.add_header("Authorization", f"Basic {auth}") req.add_header("Content-Type", "application/json") data = json.dumps({"name": name, "description": description or ""}).encode("utf-8") try: with urllib.request.urlopen(req, data=data) as f: pass except urllib.error.HTTPError as e: if e.code == 409: print(f"{name} already exists on Forgejo") else: print(f"Failed to create {name} on Forgejo: {e}") gl_repos = get_gitlab_repos() fj_repos_names = set(get_forgejo_repos()) missing = [r for r in gl_repos if r["name"] not in fj_repos_names] print(f"Found {len(missing)} missing repositories.") for repo in missing: name = repo["name"] desc = repo.get("description", "") print(f"Processing {name}...") create_forgejo_repo(name, desc) # Clone and push gl_url = f"https://oauth2:{GITLAB_TOKEN}@gitlab.com/mrhavens/{name}.git" fj_url = f"https://mrhavens:Aok4y2k!@remember.thefoldwithin.earth/mrhavens/{name}.git" try: with tempfile.TemporaryDirectory() as tmpdir: subprocess.run(["git", "clone", "--bare", gl_url, tmpdir], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(["git", "push", "--mirror", fj_url], cwd=tmpdir, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) print(f"Successfully mirrored {name}") except subprocess.CalledProcessError as e: print(f"Git operation failed for {name}: {e}")