# Gitea Upload Guide This guide explains how to upload files to the Gitea server at `192.168.68.53:3000`. ## Authentication **Gitea Server:** `http://192.168.68.53:3000` **API Base URL:** `http://192.168.68.53:3000/api/v1` **Authentication Token:** `77d13be9a7dbae402cb21c08d9231047a645e050` **Important:** Always include the token in the `Authorization` header: ``` Authorization: token 77d13be9a7dbae402cb21c08d9231047a645e050 ``` ## Method 1: Create Repository and Upload Files via API (Recommended) This method works without requiring `git` to be installed on the client machine. ### Step 1: Create Repository **Endpoint:** `POST /api/v1/user/repos` **Request:** ```bash curl -X POST \ -H "Authorization: token 77d13be9a7dbae402cb21c08d9231047a645e050" \ -H "Content-Type: application/json" \ -d '{ "name": "repository-name", "description": "Repository description", "private": false, "auto_init": false }' \ http://192.168.68.53:3000/api/v1/user/repos ``` **Python Example:** ```python import urllib.request import json TOKEN = "77d13be9a7dbae402cb21c08d9231047a645e050" GITEA_API = "http://192.168.68.53:3000/api/v1" REPO_NAME = "repository-name" USERNAME = "kyle" # Replace with actual username url = f"{GITEA_API}/user/repos" data = json.dumps({ "name": REPO_NAME, "description": "Repository description", "private": False, "auto_init": False }).encode('utf-8') req = urllib.request.Request(url, data=data) req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") with urllib.request.urlopen(req) as response: result = json.loads(response.read().decode()) print(f"Repository created: {result.get('full_name')}") ``` **Response Codes:** - `201`: Repository created successfully - `409`: Repository already exists (this is OK, you can proceed) - `401`: Authentication failed (check token) - `422`: Invalid repository name or data ### Step 2: Upload Files **Endpoint:** `PUT /api/v1/repos/{owner}/{repo}/contents/{filepath}` **Important:** Files must be base64-encoded in the request body. **Python Example (Upload Single File):** ```python import urllib.request import json import base64 import os TOKEN = "77d13be9a7dbae402cb21c08d9231047a645e050" GITEA_API = "http://192.168.68.53:3000/api/v1" REPO = "kyle/repository-name" # Format: username/repo-name FILENAME = "example.txt" BRANCH = "main" # Read and encode file with open(FILENAME, 'rb') as f: content = f.read() content_b64 = base64.b64encode(content).decode('utf-8') # Create/Update file url = f"{GITEA_API}/repos/{REPO}/contents/{FILENAME}" data = json.dumps({ "message": f"Add {FILENAME}", "content": content_b64, "branch": BRANCH }).encode('utf-8') req = urllib.request.Request(url, data=data) req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") try: with urllib.request.urlopen(req) as response: result = json.loads(response.read().decode()) print(f"✓ {FILENAME} uploaded") except urllib.error.HTTPError as e: if e.code == 409: # File exists, need to update it # First get file SHA get_url = f"{GITEA_API}/repos/{REPO}/contents/{FILENAME}?ref={BRANCH}" get_req = urllib.request.Request(get_url) get_req.add_header("Authorization", f"token {TOKEN}") with urllib.request.urlopen(get_req) as get_resp: file_info = json.loads(get_resp.read().decode()) sha = file_info.get('sha') # Update with SHA update_data = json.dumps({ "message": f"Update {FILENAME}", "content": content_b64, "sha": sha, "branch": BRANCH }).encode('utf-8') req = urllib.request.Request(url, data=update_data, method='PUT') req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") with urllib.request.urlopen(req) as update_resp: print(f"✓ {FILENAME} updated") else: print(f"✗ Error {e.code}: {e.read().decode()}") ``` **Python Example (Upload Multiple Files):** ```python import urllib.request import urllib.parse import json import base64 import os TOKEN = "77d13be9a7dbae402cb21c08d9231047a645e050" GITEA_API = "http://192.168.68.53:3000/api/v1" REPO = "kyle/repository-name" BRANCH = "main" def upload_file(filename, repo, branch="main"): """Upload a single file to Gitea""" try: # Read and encode file with open(filename, 'rb') as f: content = f.read() content_b64 = base64.b64encode(content).decode('utf-8') # Try to create file url = f"{GITEA_API}/repos/{repo}/contents/{filename}" data = json.dumps({ "message": f"Add {filename}", "content": content_b64, "branch": branch }).encode('utf-8') req = urllib.request.Request(url, data=data) req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") try: with urllib.request.urlopen(req) as response: print(f"✓ {filename}") return True except urllib.error.HTTPError as e: if e.code == 409: # File exists, update it get_url = f"{GITEA_API}/repos/{repo}/contents/{filename}?ref={branch}" get_req = urllib.request.Request(get_url) get_req.add_header("Authorization", f"token {TOKEN}") with urllib.request.urlopen(get_req) as get_resp: file_info = json.loads(get_resp.read().decode()) sha = file_info.get('sha') update_data = json.dumps({ "message": f"Update {filename}", "content": content_b64, "sha": sha, "branch": branch }).encode('utf-8') req = urllib.request.Request(url, data=update_data, method='PUT') req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") with urllib.request.urlopen(req) as update_resp: print(f"✓ {filename} (updated)") return True else: print(f"✗ {filename} (HTTP {e.code})") return False except Exception as e: print(f"✗ {filename} ({str(e)})") return False # Upload all files in current directory files_to_upload = [f for f in os.listdir('.') if os.path.isfile(f) and not f.startswith('.')] for filename in files_to_upload: upload_file(filename, REPO, BRANCH) ``` ## Method 2: Using Git (If Available) If `git` is installed on the client machine, you can use traditional git commands: ### Step 1: Create Repository (via API or Web UI) Same as Method 1, Step 1. ### Step 2: Clone and Push ```bash # Clone the repository TOKEN="77d13be9a7dbae402cb21c08d9231047a645e050" git clone http://${TOKEN}@192.168.68.53:3000/kyle/repository-name.git # Or add remote cd /path/to/your/files git init git remote add origin http://${TOKEN}@192.168.68.53:3000/kyle/repository-name.git # Add, commit, and push git add -A git commit -m "Initial commit" git branch -M main git push -u origin main ``` ## Complete Example Script Here's a complete Python script that creates a repo and uploads all files: ```python #!/usr/bin/env python3 """Complete Gitea upload script""" import urllib.request import urllib.parse import json import base64 import os import sys # Configuration TOKEN = "77d13be9a7dbae402cb21c08d9231047a645e050" GITEA_API = "http://192.168.68.53:3000/api/v1" USERNAME = "kyle" # Change if different REPO_NAME = "repository-name" # Change to desired repo name BRANCH = "main" def create_repo(name, description="", private=False): """Create a new repository""" url = f"{GITEA_API}/user/repos" data = json.dumps({ "name": name, "description": description, "private": private, "auto_init": False }).encode('utf-8') req = urllib.request.Request(url, data=data) req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") try: with urllib.request.urlopen(req) as response: result = json.loads(response.read().decode()) print(f"✓ Repository created: {result.get('full_name')}") return True except urllib.error.HTTPError as e: if e.code == 409: print(f"✓ Repository already exists: {USERNAME}/{name}") return True else: print(f"✗ Failed to create repository: {e.code}") print(e.read().decode()) return False def upload_file(filename, repo, branch="main"): """Upload or update a file""" try: with open(filename, 'rb') as f: content = f.read() content_b64 = base64.b64encode(content).decode('utf-8') url = f"{GITEA_API}/repos/{repo}/contents/{filename}" # Try to create data = json.dumps({ "message": f"Add {filename}", "content": content_b64, "branch": branch }).encode('utf-8') req = urllib.request.Request(url, data=data) req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") try: with urllib.request.urlopen(req) as response: return True except urllib.error.HTTPError as e: if e.code == 409: # Update existing file get_url = f"{GITEA_API}/repos/{repo}/contents/{filename}?ref={branch}" get_req = urllib.request.Request(get_url) get_req.add_header("Authorization", f"token {TOKEN}") with urllib.request.urlopen(get_req) as get_resp: file_info = json.loads(get_resp.read().decode()) sha = file_info.get('sha') update_data = json.dumps({ "message": f"Update {filename}", "content": content_b64, "sha": sha, "branch": branch }).encode('utf-8') req = urllib.request.Request(url, data=update_data, method='PUT') req.add_header("Authorization", f"token {TOKEN}") req.add_header("Content-Type", "application/json") with urllib.request.urlopen(req) as update_resp: return True else: return False except Exception: return False # Main execution if __name__ == '__main__': # Create repository if not create_repo(REPO_NAME, "Repository description"): sys.exit(1) # Upload files repo = f"{USERNAME}/{REPO_NAME}" files = [f for f in os.listdir('.') if os.path.isfile(f) and not f.startswith('.')] uploaded = 0 failed = 0 for filename in files: if upload_file(filename, repo, BRANCH): print(f"✓ {filename}") uploaded += 1 else: print(f"✗ {filename}") failed += 1 print(f"\nComplete: {uploaded} uploaded, {failed} failed") print(f"Repository: http://192.168.68.53:3000/{repo}") ``` ## Important Notes 1. **Token Security:** The token has full access. Keep it secure and don't commit it to public repositories. 2. **File Size Limits:** Gitea may have file size limits. Very large files (>100MB) may need to use Git LFS. 3. **Branch Name:** Default branch is usually `main`. Check the repository settings if you need a different branch. 4. **File Encoding:** Always base64-encode file contents when using the API. 5. **Error Handling:** - `409 Conflict`: File already exists (handle by updating with SHA) - `401 Unauthorized`: Invalid or expired token - `404 Not Found`: Repository doesn't exist (create it first) 6. **Rate Limiting:** Gitea may rate-limit API requests. Add delays between uploads if uploading many files. ## Quick Reference **Create Repository:** ``` POST /api/v1/user/repos Authorization: token 77d13be9a7dbae402cb21c08d9231047a645e050 ``` **Upload File:** ``` PUT /api/v1/repos/{owner}/{repo}/contents/{filepath} Authorization: token 77d13be9a7dbae402cb21c08d9231047a645e050 Content-Type: application/json Body: {"message": "...", "content": "", "branch": "main"} ``` **Update File:** Same as upload, but include `"sha": ""` in the body. ## Repository URL Format - **Clone URL:** `http://77d13be9a7dbae402cb21c08d9231047a645e050@192.168.68.53:3000/username/repo-name.git` - **Web URL:** `http://192.168.68.53:3000/username/repo-name` - **API URL:** `http://192.168.68.53:3000/api/v1/repos/username/repo-name`