Download dari Cloudflare R2 lalu upload ke AWS S3, sambil hapus URL yang sukses dari list

Download dari Cloudflare R2 lalu upload ke AWS S3, sambil hapus URL yang sukses dari list

Script praktis buat mindahin file dari Cloudflare R2 ke AWS S3, langsung hapus URL yang sudah sukses dari listmp4.txt.

Masalahnya gini

Gue punya daftar file MP4 di listmp4.txt. Sumbernya ada di Cloudflare R2, terus gue mau pindahin ke AWS S3 ke folder dramabox/. Yang udah sukses harus langsung dihapus dari list, biar kalau script dijalankan ulang, sisa yang gagal aja yang diproses.

Kalau dikerjain manual, capek. Apalagi kalau file-nya banyak. Jadi yang paling enak ya bikin script yang:

  • ambil URL dari listmp4.txt
  • download file dari R2
  • upload langsung ke S3
  • kalau sukses, hapus URL itu dari list
  • kalau gagal, biarin tetap ada buat retry

Solusi paling praktis

Gue saranin pakai Python + boto3 + requests. Enaknya, file bisa di-stream langsung ke S3, jadi nggak perlu nyimpen full file ke disk dulu.

Install dulu dependensinya:

pip install boto3 requests

Terus simpan script ini misalnya dengan nama download_and_upload.py:

import os
import sys
import time
import boto3
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import urlparse

AWS_ACCESS_KEY = 'MASUKKAN_ACCESS_KEY_KAMU'
AWS_SECRET_KEY = 'MASUKKAN_SECRET_KEY_KAMU'

BUCKET_NAME = 'dramaku'
S3_FOLDER = 'dramabox/'
LIST_FILE = 'listmp4.txt'
MAX_WORKERS = 5
TIMEOUT = 300

s3_client = boto3.client(
    's3',
    aws_access_key_id=AWS_ACCESS_KEY,
    aws_secret_access_key=AWS_SECRET_KEY,
    endpoint_url='https://s3.dualstack.us-east-1.amazonaws.com'
)

def get_filename_from_url(url):
    return os.path.basename(urlparse(url).path)

def download_and_upload(url):
    filename = get_filename_from_url(url)
    try:
        s3_key = S3_FOLDER + filename
        print(f'[{filename}] mulai download dan upload...')

        with requests.get(url, stream=True, timeout=TIMEOUT) as r:
            r.raise_for_status()
            s3_client.upload_fileobj(
                r.raw,
                BUCKET_NAME,
                s3_key,
                ExtraArgs={'ContentType': 'video/mp4'}
            )

        print(f'OK: {filename}')
        return url, True

    except Exception as e:
        print(f'GAGAL: {filename} | {e}')
        return url, False

def main():
    if not os.path.exists(LIST_FILE):
        print(f'File {LIST_FILE} tidak ditemukan')
        sys.exit(1)

    with open(LIST_FILE, 'r') as f:
        urls = [line.strip() for line in f if line.strip() and not line.startswith('#')]

    if not urls:
        print('List kosong, tidak ada yang perlu diproses')
        return

    print(f'Mulai proses {len(urls)} file dengan {MAX_WORKERS} worker...')

    successful = []
    start_time = time.time()

    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        future_to_url = {executor.submit(download_and_upload, url): url for url in urls}

        for future in as_completed(future_to_url):
            url, success = future.result()
            if success:
                successful.append(url)

    remaining = [u for u in urls if u not in successful]

    with open(LIST_FILE, 'w') as f:
        for u in remaining:
            f.write(u + '\n')

    print('\nSelesai')
    print(f'Berhasil: {len(successful)}')
    print(f'Sisa di list: {len(remaining)}')
    print(f'Waktu total: {(time.time() - start_time) / 60:.1f} menit')

if __name__ == '__main__':
    main()

Cara jalaninnya

  1. Isi dulu AWS_ACCESS_KEY dan AWS_SECRET_KEY.
  2. Pastikan file listmp4.txt ada di folder yang sama.
  3. Jalankan script:
python3 download_and_upload.py

Catatan penting

  • Script ini pakai parallel worker, jadi lumayan ngebut buat banyak file.
  • Kalau koneksi lu nggak stabil, turunin MAX_WORKERS jadi 2 atau 3.
  • Kalau mau lebih aman, bisa tambahin retry per file.
  • Kalau file gagal, URL-nya tetap ada di list, jadi gampang dicoba lagi nanti.

Kalau mau yang lebih praktis lagi

Kalau jumlah file udah banyak banget, kadang rclone lebih enak buat workflow sinkronisasi. Tapi buat kasus lu yang pengin download dari URL lalu upload ke S3 sambil ngelola list sendiri, script Python ini udah paling fleksibel.

Kalau mau, gue juga bisa bikinin versi yang:

  • ada retry otomatis 2-3 kali
  • pakai log file biar gampang audit
  • cek file yang sudah ada di S3 dulu sebelum upload
  • jalan dari CSV atau TXT yang formatnya lebih rapi

Intinya, buat kebutuhan ini, script di atas udah cukup enak dipakai harian.

Tags: Catatan Teknis, AWS S3, Cloudflare R2, Python, Upload File