最後活躍 1 week ago

KarelWintersky 已修改 1 week ago. 還原成這個修訂版本

1 file changed, 262 insertions

metube3.sh(檔案已創建)

@@ -0,0 +1,262 @@
1 + #!/usr/bin/env bash
2 +
3 + # MeTube installation script with offline Deno installation
4 + # Place this script and deno-x86_64-unknown-linux-gnu.zip in the same directory
5 +
6 + set -e
7 +
8 + APP="MeTube"
9 + APP_DIR="/opt/metube"
10 + DENO_INSTALL_DIR="/usr/local"
11 + DENO_ZIP="deno-x86_64-unknown-linux-gnu.zip"
12 + GITHUB_REPO="alexta69/metube"
13 + SERVICE_USER="root"
14 +
15 + # Colors for output
16 + RED='\033[0;31m'
17 + GREEN='\033[0;32m'
18 + YELLOW='\033[1;33m'
19 + BLUE='\033[0;34m'
20 + NC='\033[0m'
21 +
22 + info() { echo -e "${GREEN}[INFO]${NC} $1"; }
23 + warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
24 + error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
25 + step() { echo -e "${BLUE}[STEP]${NC} $1"; }
26 +
27 + # Check if running as root
28 + if [[ $EUID -ne 0 ]]; then
29 + error "This script must be run as root"
30 + fi
31 +
32 + # Check for local Deno archive
33 + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
34 + DENO_ARCHIVE_PATH="${SCRIPT_DIR}/${DENO_ZIP}"
35 +
36 + if [[ ! -f "$DENO_ARCHIVE_PATH" ]]; then
37 + error "Deno archive not found at $DENO_ARCHIVE_PATH"
38 + fi
39 +
40 + info "Found Deno archive: $DENO_ARCHIVE_PATH"
41 +
42 + # Install dependencies
43 + step "Installing system dependencies"
44 + apt-get update
45 + apt-get install -y curl wget unzip git build-essential python3 python3-pip python3-venv
46 +
47 + # Install FFmpeg
48 + step "Installing FFmpeg"
49 + apt-get install -y ffmpeg
50 + if command -v ffmpeg >/dev/null 2>&1; then
51 + info "FFmpeg installed successfully: $(ffmpeg -version | head -n1)"
52 + else
53 + error "FFmpeg installation failed"
54 + fi
55 +
56 + step "Installing NODEJS"
57 + curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
58 + apt install -y nodejs
59 + npm install -g pm2
60 +
61 + # Install Deno from local archive
62 + step "Installing Deno from local archive"
63 + if [[ -d "${DENO_INSTALL_DIR}/deno" ]]; then
64 + rm -rf "${DENO_INSTALL_DIR}/deno"
65 + fi
66 +
67 + unzip -o "$DENO_ARCHIVE_PATH" -d /tmp/deno_extract
68 + chmod +x /tmp/deno_extract/deno
69 + mv /tmp/deno_extract/deno "${DENO_INSTALL_DIR}/bin/deno"
70 + rm -rf /tmp/deno_extract
71 +
72 + if command -v deno >/dev/null 2>&1; then
73 + info "Deno installed successfully: $(deno --version)"
74 + else
75 + error "Deno installation failed"
76 + fi
77 +
78 + # Install pnpm
79 + step "Installing pnpm"
80 + curl -fsSL https://get.pnpm.io/install.sh | sh -
81 +
82 + # Download and setup MeTube
83 + step "Downloading MeTube from GitHub"
84 + LATEST_URL=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep "tarball_url" | cut -d '"' -f 4)
85 +
86 + if [[ -z "$LATEST_URL" ]]; then
87 + error "Failed to get latest release URL"
88 + fi
89 +
90 + if [[ -d "$APP_DIR" ]]; then
91 + warn "Existing installation found, backing up..."
92 + mv "$APP_DIR" "${APP_DIR}_bak_$(date +%Y%m%d_%H%M%S)"
93 + fi
94 +
95 + mkdir -p "$APP_DIR"
96 + cd "$APP_DIR"
97 +
98 + curl -L "$LATEST_URL" -o metube.tar.gz
99 + tar -xzf metube.tar.gz --strip-components=1
100 + rm metube.tar.gz
101 +
102 + # Build frontend
103 + step "Building frontend"
104 + if [[ -d "$APP_DIR/ui" ]]; then
105 + cd "$APP_DIR/ui"
106 + /root/.local/share/pnpm/pnpm install --frozen-lockfile
107 + /root/.local/share/pnpm/pnpm run build
108 + else
109 + error "UI directory not found"
110 + fi
111 +
112 + # Setup Python backend
113 + step "Setting up Python backend"
114 + cd "$APP_DIR"
115 + python3 -m venv .venv
116 + source .venv/bin/activate
117 + pip install --upgrade pip
118 +
119 + # Install required Python packages
120 + step "Installing Python packages"
121 + pip install yt-dlp aiohttp python-dotenv python-socketio watchfiles
122 +
123 + # Check for requirements.txt and install if exists
124 + if [[ -f "$APP_DIR/requirements.txt" ]]; then
125 + pip install -r requirements.txt
126 + fi
127 +
128 + # Configure yt-dlp to use Deno for JS challenges
129 + step "Configuring yt-dlp for JavaScript challenges"
130 + mkdir -p /root/.config/yt-dlp
131 +
132 + # Create yt-dlp config to enable remote components
133 + cat > /root/.config/yt-dlp/config <<EOF
134 + # Enable Deno for JS challenge solving
135 + --remote-components ejs:github
136 + EOF
137 +
138 + info "yt-dlp configured to use Deno for JavaScript challenges"
139 +
140 + # Create .env file with yt-dlp options in JSON format
141 + step "Creating configuration"
142 + if [[ ! -f "$APP_DIR/.env" ]]; then
143 + cat > "$APP_DIR/.env" <<'EOF'
144 + # MeTube Configuration
145 + DOWNLOAD_DIR=/downloads
146 + STATE_DIR=/opt/metube/state
147 + URL_PREFIX=
148 + HTTP_USERNAME=
149 + HTTP_PASSWORD=
150 + YTDL_OPTIONS={"extractor_args":{"youtube":{"skip":[["hls","dash","live"]],"player_client":["android","web"]}},"remote_components":"ejs:github"}
151 + EOF
152 + else
153 + # Check if YTDL_OPTIONS already exists in .env
154 + if ! grep -q "YTDL_OPTIONS" "$APP_DIR/.env"; then
155 + echo "" >> "$APP_DIR/.env"
156 + echo "# yt-dlp options for JS challenge solving" >> "$APP_DIR/.env"
157 + echo 'YTDL_OPTIONS={"extractor_args":{"youtube":{"skip":[["hls","dash","live"]],"player_client":["android","web"]}},"remote_components":"ejs:github"}' >> "$APP_DIR/.env"
158 + fi
159 + fi
160 +
161 + # Create download and state directories
162 + mkdir -p /downloads
163 + mkdir -p "$APP_DIR/state"
164 + chown -R root:root /downloads
165 + chown -R root:root "$APP_DIR"
166 +
167 + # Fix potential missing app/main.py structure
168 + step "Checking MeTube application structure"
169 + if [[ ! -f "$APP_DIR/app/main.py" ]]; then
170 + warn "app/main.py not found, checking alternative locations..."
171 + if [[ -f "$APP_DIR/main.py" ]]; then
172 + warn "Found main.py in root, creating app directory structure"
173 + mkdir -p "$APP_DIR/app"
174 + mv "$APP_DIR/main.py" "$APP_DIR/app/"
175 + else
176 + error "Cannot find main.py. MeTube structure may be different than expected"
177 + fi
178 + fi
179 +
180 + # Create systemd service
181 + step "Creating systemd service"
182 + cat > /etc/systemd/system/metube.service <<EOF
183 + [Unit]
184 + Description=MeTube - YouTube Downloader
185 + After=network.target
186 +
187 + [Service]
188 + Type=simple
189 + WorkingDirectory=${APP_DIR}
190 + EnvironmentFile=${APP_DIR}/.env
191 + Environment="PATH=/usr/local/bin:/usr/bin:/bin:${APP_DIR}/.venv/bin"
192 + ExecStartPre=/bin/bash -c 'echo "Starting MeTube with YTDL_OPTIONS=\${YTDL_OPTIONS}"'
193 + ExecStart=${APP_DIR}/.venv/bin/python3 ${APP_DIR}/app/main.py
194 + Restart=always
195 + User=root
196 + StandardOutput=journal
197 + StandardError=journal
198 +
199 + [Install]
200 + WantedBy=multi-user.target
201 + EOF
202 +
203 + # Test the Python application manually before starting service
204 + step "Testing Python application manually"
205 + cd "$APP_DIR"
206 + source .venv/bin/activate
207 + timeout 5 python3 -c "
208 + import os
209 + import json
210 + os.environ['DOWNLOAD_DIR'] = '/downloads'
211 + os.environ['STATE_DIR'] = '/opt/metube/state'
212 + ytdl_options_str = '{\"extractor_args\":{\"youtube\":{\"skip\":[[\"hls\",\"dash\",\"live\"]],\"player_client\":[\"android\",\"web\"]}},\"remote_components\":\"ejs:github\"}'
213 + try:
214 + ytdl_options = json.loads(ytdl_options_str)
215 + print(f'YTDL_OPTIONS parsed successfully: {ytdl_options}')
216 + except Exception as e:
217 + print(f'Error parsing YTDL_OPTIONS: {e}')
218 + exit(1)
219 + " || warn "Manual test failed, but continuing..."
220 +
221 + # Reload systemd and start service
222 + step "Starting MeTube service"
223 + systemctl daemon-reload
224 + systemctl enable metube
225 + systemctl start metube
226 +
227 + # Check if service is running
228 + sleep 5
229 + if systemctl is-active --quiet metube; then
230 + info "MeTube service started successfully"
231 + else
232 + warn "MeTube service failed to start. Checking logs..."
233 + journalctl -u metube --no-pager -n 30
234 + echo ""
235 + echo "Trying to run MeTube directly to see error:"
236 + cd "$APP_DIR"
237 + source .venv/bin/activate
238 + timeout 10 python3 app/main.py || true
239 + error "MeTube service failed to start. Check logs with: journalctl -u metube"
240 + fi
241 +
242 + # Get IP address
243 + IP_ADDRESS=$(hostname -I | awk '{print $1}')
244 +
245 + echo ""
246 + echo -e "${GREEN}========================================${NC}"
247 + echo -e "${GREEN}MeTube installation completed!${NC}"
248 + echo -e "${GREEN}========================================${NC}"
249 + echo -e "Access MeTube at: ${YELLOW}http://${IP_ADDRESS}:8081${NC}"
250 + echo ""
251 + echo -e "Commands:"
252 + echo -e " Start: ${BLUE}systemctl start metube${NC}"
253 + echo -e " Stop: ${BLUE}systemctl stop metube${NC}"
254 + echo -e " Status: ${BLUE}systemctl status metube${NC}"
255 + echo -e " Logs: ${BLUE}journalctl -u metube -f${NC}"
256 + echo ""
257 + echo -e "Download directory: ${YELLOW}/downloads${NC}"
258 + echo -e "Config file: ${YELLOW}${APP_DIR}/.env${NC}"
259 + echo -e "yt-dlp config: ${YELLOW}/root/.config/yt-dlp/config${NC}"
260 + echo ""
261 + echo -e "${GREEN}Note:${NC} yt-dlp has been configured to use Deno for JavaScript challenge solving"
262 + echo -e "This helps bypass YouTube's anti-bot protection for downloading videos"
上一頁 下一頁