Oceń i ulepsz ten skrypt: 

# -*- coding: utf-8 -*-

import csv
import requests
import random
import string
import sys
import time
import json

from concurrent.futures import ThreadPoolExecutor, as_completed
import threading

# --- Konfiguracja ---
CLOUDFLARE_TOKEN = ""
ACCOUNT_ID = ""
NAMESPACE_ID = ""
INPUT_FILE = "shorts-2.csv"
OUTPUT_FILE = "shorts-2-url.csv"
DOMAIN = "https://d3e.pl"
PREFIX = "2-"
SHORT_ID_LEN = 9

MAX_RETRIES = 20           # Ile razy próbować GET/PUT w razie problemów
MAX_WORKERS = 5            # Ile równoległych wątków (na PRO max 5-10 stabilnie!)
SLEEP_EACH_ROW = 0.05      # Sekundy po każdym pełnym przetworzonym wierszu (dla bezpieczeństwa)
SLEEP_ON_429 = 3           # Sekundy po rate limit (429)
SLEEP_ON_API_FAIL = 1      # Sekundy po innych błędach API (np. timeout)
SLEEP_ON_COLLISION = 0.5   # Sekundy przy kolizji (losowy wygenerowany klucz już istnieje)
SLEEP_ON_KV_FAIL = 1       # Sekundy po błędzie zapis/odczyt do KV

# --- Funkcje pomocnicze ---
def random_id(length=9):
    chars = string.ascii_letters + string.digits
    return ''.join(random.choices(chars, k=length))

def cf_kv_exists(key):
    url = f"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/storage/kv/namespaces/{NAMESPACE_ID}/values/{key}"
    headers = {"Authorization": f"Bearer {CLOUDFLARE_TOKEN}"}
    for retry in range(MAX_RETRIES):
        resp = requests.get(url, headers=headers)
        if resp.status_code == 200:
            return True
        if resp.status_code == 404:
            return False
        if resp.status_code == 429:
            print("[X] API GET 429 - Rate limited, czekam", SLEEP_ON_429, "sekund...")
            time.sleep(SLEEP_ON_429)
            continue
        try:
            err = resp.json()
            if "errors" in err and len(err["errors"]) > 0:
                msg = err["errors"][0].get("message", "brak message")
            else:
                msg = resp.text.strip()
        except Exception:
            msg = resp.text.strip()
        print(f"[X] ERROR API GET: {resp.status_code} - {msg}")
        time.sleep(SLEEP_ON_API_FAIL)
    return None

def cf_kv_put(key, value):
    url = f"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/storage/kv/namespaces/{NAMESPACE_ID}/values/{key}"
    headers = {"Authorization": f"Bearer {CLOUDFLARE_TOKEN}"}
    for retry in range(MAX_RETRIES):
        resp = requests.put(url, data=value.encode('utf-8'), headers=headers)
        if resp.status_code == 200:
            return True
        if resp.status_code == 429:
            print("[X] API PUT 429 - Rate limited, czekam", SLEEP_ON_429, "sekund...")
            time.sleep(SLEEP_ON_429)
            continue
        try:
            err = resp.json()
            if "errors" in err and len(err["errors"]) > 0:
                msg = err["errors"][0].get("message", "brak message")
            else:
                msg = resp.text.strip()
        except Exception:
            msg = resp.text.strip()
        print(f"[X] ERROR API PUT: {resp.status_code} - {msg}")
        time.sleep(SLEEP_ON_API_FAIL)
    return False

# --- Główna logika ---
def process_row(i, row):
    try:
        long_url = row[24].strip()
        if not long_url or not long_url.startswith("http"):
            return f"[X] ERROR: {i} - Brak/dziwny link: {long_url}"

        # Generuj unikalny short id
        for attempt in range(MAX_RETRIES):
            short_id = PREFIX + random_id(SHORT_ID_LEN)
            exists = cf_kv_exists(short_id)
            if exists is None:
                time.sleep(SLEEP_ON_KV_FAIL)
                continue
            if exists:
                time.sleep(SLEEP_ON_COLLISION)
                continue
            break
        else:
            return f"[X] ERROR: {i} - Za dużo kolizji/prób"

        # Wstaw do KV
        for attempt in range(MAX_RETRIES):
            ok = cf_kv_put(short_id, long_url)
            if ok:
                break
            time.sleep(SLEEP_ON_KV_FAIL)
        else:
            return f"[X] ERROR: {i} - API: Nie udało się dodać po wielu próbach"

        # Zapisz do wyjściowego CSV (wątkowo: użyj locka)
        short_url = f"{DOMAIN}/{short_id}"
        with output_lock:
            writer.writerow([short_url] + row)
            output_fh.flush()
        time.sleep(SLEEP_EACH_ROW)  # opóźnienie po wierszu

        return f"[ ] OK: {i} - {short_url}"

    except Exception as e:
        return f"[X] ERROR: {i} - {e}"

def main(one_only=False):
    global writer, output_fh, output_lock

    # Policz ile linii już mamy w pliku wynikowym (jeśli istnieje)
    try:
        with open(OUTPUT_FILE, newline="", encoding="utf-8-sig") as f_out:
            out_lines = sum(1 for _ in f_out)
    except FileNotFoundError:
        out_lines = 0

    # Wczytaj wszystkie linie do przetworzenia (bez przetworzonych)
    with open(INPUT_FILE, newline="", encoding="utf-8") as f_in:
        reader = csv.reader(f_in, delimiter=";")
        all_rows = list(reader)
        rows_to_process = all_rows[out_lines:]

    # Otwórz wyjściowy plik CSV i przygotuj writer + lock
    output_fh = open(OUTPUT_FILE, "a", newline="", encoding="utf-8-sig")
    writer = csv.writer(output_fh, delimiter=";")
    output_lock = threading.Lock()

    try:
        with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
            futures = []
            for idx, row in enumerate(rows_to_process, start=out_lines+1):
                futures.append(executor.submit(process_row, idx, row))
                if one_only:
                    break
            for future in as_completed(futures):
                result = future.result()
                print(result)
    except KeyboardInterrupt:
        print("\nPrzerwano przez użytkownika (Ctrl+C).")
    finally:
        output_fh.close()

if __name__ == "__main__":
    one_only = False
    if len(sys.argv) > 1 and sys.argv[1] == "--one":
        one_only = True
    main(one_only)