Files
ha-kiosk-dashboard/GITEA-UPLOAD-GUIDE.md
2025-12-31 04:29:52 -08:00

13 KiB

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

This method works without requiring git to be installed on the client machine.

Step 1: Create Repository

Endpoint: POST /api/v1/user/repos

Request:

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:

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

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

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

# 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:

#!/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": "<base64>", "branch": "main"}

Update File: Same as upload, but include "sha": "<file-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