import os
import shutil
import subprocess
import sys
import importlib.util
import gradio as gr
# Configuration - USE DIFFERENT PATH
REPO_DIR = "/tmp/private_repo" # Changed to /tmp which is writable
GITHUB_REPO = os.getenv("GITHUB_REPO", "").strip()
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", "").strip()
def setup_github_clone():
"""Setup GitHub clone with token authentication if available"""
if GITHUB_TOKEN and GITHUB_REPO:
# Replace URL with token authentication
if "github.com" in GITHUB_REPO:
auth_url = GITHUB_REPO.replace(
"https://github.com/",
f"https://{GITHUB_TOKEN}@github.com/"
)
return auth_url
return GITHUB_REPO
def load_private_code():
"""Load private code from GitHub repository"""
try:
print("๐ Starting private code loading process...")
if not GITHUB_REPO:
print("โ GITHUB_REPO environment variable not set")
return False
# Clean up existing repo
if os.path.exists(REPO_DIR):
print("๐งน Cleaning up existing repository...")
shutil.rmtree(REPO_DIR)
# Clone repository
print(f"๐ฅ Cloning repository from: {GITHUB_REPO}")
clone_url = setup_github_clone()
clone_cmd = ["git", "clone", "--depth", "1", clone_url, REPO_DIR]
result = subprocess.run(
clone_cmd,
capture_output=True,
text=True,
timeout=300
)
if result.returncode != 0:
print(f"โ Git clone failed: {result.stderr}")
return False
print("โ
Repository cloned successfully!")
# Install requirements
requirements_path = os.path.join(REPO_DIR, "requirements.txt")
if os.path.exists(requirements_path):
print("๐ฆ Installing dependencies from requirements.txt...")
install_result = subprocess.run(
[sys.executable, "-m", "pip", "install", "-r", requirements_path],
capture_output=True,
text=True
)
if install_result.returncode == 0:
print("โ
Dependencies installed successfully!")
else:
print(f"โ ๏ธ Dependency installation had issues: {install_result.stderr}")
# Add to Python path
sys.path.insert(0, REPO_DIR)
print("๐ Private code loaded successfully!")
return True
except subprocess.TimeoutExpired:
print("โ Git clone timeout - repository might be too large or network issue")
return False
except Exception as e:
print(f"โ Error loading private code: {str(e)}")
return False
def create_fallback_ui():
"""Create a fallback UI when private repo fails to load"""
with gr.Blocks(
title="Tiko - Setup Required",
theme=gr.themes.Soft(primary_hue="purple")
) as demo:
gr.Markdown(
"""
๐ Tiko - TikTok Downloader
Premium TikTok Content Downloader
## โ ๏ธ Setup In Progress
We're currently setting up your Tiko instance. This might be because:
- ๐ First-time setup is running
- ๐ฅ Downloading latest updates
- โ๏ธ Installing dependencies
### ๐ฏ What's Happening?
Tiko is cloning your private repository from GitHub and setting up the environment.
**Repository:** `https://github.com/miftahganzz/Tiko`
### โณ Next Steps:
1. Wait a few moments
2. Refresh this page
3. The app should load automatically
If you continue to see this message, check:
- GitHub repository URL is correct
- Repository is accessible
- Enough storage space available
**Need help?** Contact support.
"""
)
# Add refresh button
refresh_btn = gr.Button("๐ Refresh Page", size="lg")
refresh_btn.click(
fn=lambda: None,
inputs=[],
outputs=[]
)
# Debug info
with gr.Accordion("๐ Technical Details", open=False):
gr.Markdown(f"""
**Environment Info:**
- GITHUB_REPO: `{GITHUB_REPO or 'Not set'}`
- GITHUB_TOKEN: `{'Set' if GITHUB_TOKEN else 'Not set'}`
- Repo Directory: `{REPO_DIR}`
- Python Path: `{sys.executable}`
""")
return demo
def load_private_app():
"""Load the main app from private repository"""
try:
private_app_path = os.path.join(REPO_DIR, "app.py")
if not os.path.exists(private_app_path):
raise FileNotFoundError(f"app.py not found in private repo at {private_app_path}")
print(f"๐ Loading app from: {private_app_path}")
# Dynamically import the private module
spec = importlib.util.spec_from_file_location("tiko_private", private_app_path)
private_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(private_module)
print("โ
Private module imported successfully!")
# Get the main app function
if hasattr(private_module, "main_app"):
print("๐ฏ Found main_app() function, launching...")
return private_module.main_app()
elif hasattr(private_module, "demo"):
print("๐ฏ Found demo variable, launching...")
return private_module.demo
elif hasattr(private_module, "create_tiko_ui"):
print("๐ฏ Found create_tiko_ui() function, launching...")
return private_module.create_tiko_ui()
else:
# Try to find any function that returns a Gradio interface
for attr_name in dir(private_module):
attr = getattr(private_module, attr_name)
if callable(attr) and not attr_name.startswith('_'):
try:
result = attr()
if isinstance(result, (gr.Blocks, gr.Interface)):
print(f"๐ฏ Found function {attr_name}, launching...")
return result
except:
continue
raise AttributeError("No valid Gradio app found")
except Exception as e:
print(f"โ Failed to load private app: {str(e)}")
raise
# Main execution flow
print("=" * 50)
print("๐ Tiko - TikTok Downloader Initializing...")
print("=" * 50)
print(f"๐ Repository: {GITHUB_REPO}")
print(f"๐ Target Directory: {REPO_DIR}")
# Try to load private code
if load_private_code():
try:
print("๐ Successfully loaded private code, launching Tiko...")
demo = load_private_app()
print("โ
Tiko is ready to go!")
except Exception as e:
print(f"โ Failed to launch private app: {e}")
print("๐ Falling back to setup UI...")
demo = create_fallback_ui()
else:
print("โ Could not load private repository")
print("๐ Launching setup UI...")
demo = create_fallback_ui()
# Launch the application
if __name__ == "__main__":
print("๐ Starting Gradio server...")
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=True
)