diff --git a/.github/workflows/fix-readme.yml b/.github/workflows/fix-readme.yml
new file mode 100644
index 0000000..93e23d6
--- /dev/null
+++ b/.github/workflows/fix-readme.yml
@@ -0,0 +1,77 @@
+name: Fix README
+
+on:
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ fix:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout (sparse - readme + json metadata only)
+ uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
+ README.md
+ assets/*.json
+ sparse-checkout-cone-mode: false
+ fetch-depth: 1
+
+ - name: Configure Git
+ run: |
+ git config user.name 'github-actions[bot]'
+ git config user.email 'github-actions[bot]@users.noreply.github.com'
+
+ - name: Rebuild README from JSON metadata
+ run: |
+ python3 << 'PYEOF'
+ import os, json, glob
+
+ CDN_BASE = "https://raw.githubusercontent.com/yapude/wallpapers/main/assets"
+
+ header = "# Wallpaper Archive\n\nAutomated archive of wallpapers to bypass Cloudflare and prevent dead links.\n\n## Gallery\n\n| Preview | Title | Tags |\n| --- | --- | --- |\n"
+
+ rows = []
+ count = 0
+ errors = 0
+
+ for json_file in sorted(glob.glob("assets/*.json")):
+ try:
+ with open(json_file, "r", encoding="utf-8") as f:
+ item = json.load(f)
+
+ ext = "png" if ".png" in item.get("download_url", "") else "jpg"
+ item_id = item.get("id", "")
+ filename = f"{item_id}.{ext}"
+ cdn_url = f"{CDN_BASE}/{filename}"
+
+ title = item.get("title", "Wallpaper")
+ tags = ", ".join(item.get("tags", []))
+
+ row = f'|
| **{title}**
[Download]({cdn_url}) | {tags} |\n'
+ rows.append((item_id, row))
+ count += 1
+ except Exception as e:
+ errors += 1
+
+ rows.sort(key=lambda x: x[0])
+
+ chunk_size = 100000
+
+ for i in range(0, len(rows), chunk_size):
+ chunk = rows[i:i + chunk_size]
+ filename = "README.md" if i == 0 else f"README{(i//chunk_size) + 1}.md"
+ with open(filename, "w", encoding="utf-8") as f:
+ f.write(header)
+ for _, row in chunk:
+ f.write(row)
+
+ print(f"Rebuilt README with {count} wallpapers ({errors} errors) across {len(rows)//chunk_size + 1} files")
+ PYEOF
+
+ - name: Commit and Push
+ run: |
+ git add --sparse README*.md
+ git diff --cached --quiet && echo "no changes" || (git commit -m "fix: rebuild readme from archive metadata [skip ci]" && git push)
\ No newline at end of file
diff --git a/.github/workflows/scrape.yml b/.github/workflows/scrape.yml
new file mode 100644
index 0000000..ff348fd
--- /dev/null
+++ b/.github/workflows/scrape.yml
@@ -0,0 +1,56 @@
+name: Daily Wallpaper Archive
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ scrape:
+ runs-on: ubuntu-latest
+ timeout-minutes: 760
+
+ steps:
+ - name: Checkout (sparse - code only, no images)
+ uses: actions/checkout@v4
+ with:
+ sparse-checkout: |
+ src
+ Cargo.toml
+ Cargo.lock
+ .github
+ .gitignore
+ LICENSE
+ README.md
+ sparse-checkout-cone-mode: false
+
+ - name: Setup Rust
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Cache Cargo registry and target
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.cargo/bin/
+ ~/.cargo/registry/index/
+ ~/.cargo/registry/cache/
+ ~/.cargo/git/db/
+ target/
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-cargo-
+
+ - name: Install dependencies for BoringSSL
+ run: sudo apt-get update && sudo apt-get install -y cmake nasm clang
+
+ - name: Configure Git
+ run: |
+ git config --global user.name 'github-actions[bot]'
+ git config --global user.email 'github-actions[bot]@users.noreply.github.com'
+
+ - name: Build and Run Scraper
+ run: |
+ cargo run --release --bin scrape