Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ test_router.php
*.mov
*.avi
*.mkv

# Benchmark / workspace d'analyse (corpus privé de torrents + artefacts) — local only
bench/
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf
COPY docker/entrypoint.sh /entrypoint.sh
COPY docker/demo-data.sh /docker/demo-data.sh
COPY docker/seed-tmdb.php /docker/seed-tmdb.php
COPY docker/demo-bootstrap.php /docker/demo-bootstrap.php
RUN chmod +x /docker/demo-data.sh

COPY . /app
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.nvidia
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/entrypoint-nvidia.sh /entrypoint.sh
COPY docker/demo-data.sh /docker/demo-data.sh
COPY docker/seed-tmdb.php /docker/seed-tmdb.php
COPY docker/demo-bootstrap.php /docker/demo-bootstrap.php
RUN chmod +x /entrypoint.sh /docker/demo-data.sh

COPY . /app
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ So I built ShareBox -- a single PHP app with zero external dependencies. No fram

## Live Demo

**[Try the demo](https://dn40904.seedhost.eu:8282/dl/browse?p=Films&view=grid)** -- no install needed. Netflix-style grid with TMDB posters, series, movies, and anime.
**[Try the demo](http://199.231.187.166:8282/dl/browse?p=Films&view=grid)** -- no install needed. Netflix-style grid with TMDB posters, series, movies, and anime.

[Admin panel](https://dn40904.seedhost.eu:8282/share/) -- `admin` / `demo2026`
[Admin panel](http://199.231.187.166:8282/share/) -- `admin` / `demo2026`

## How it compares

Expand Down
58 changes: 58 additions & 0 deletions docker/demo-bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Bootstrap de la démo Docker.
*
* Objectif : peupler les affiches via EXACTEMENT le même chemin de code qu'une
* install réelle — pas de mapping en dur, pas de seed naïf. On reproduit ce que
* font un admin (marquer un dossier "movies") puis un premier visiteur (browse →
* enqueue), puis on lance le VRAI worker qui matche tout via tmdb_match
* (retry/backoff + cache + scoring identiques à la prod).
*
* Appelé par docker/entrypoint.sh en tâche de fond après le démarrage des services,
* uniquement si SHAREBOX_DEMO_DATA=true et SHAREBOX_TMDB_API_KEY défini.
*
* Usage: php demo-bootstrap.php <mediaDir>
*/

require '/app/db.php';
require_once '/app/functions.php';

$mediaDir = rtrim(($argv[1] ?? '') ?: '/media', '/'); // défaut robuste si l'argument est vide

if (!defined('TMDB_API_KEY') || !TMDB_API_KEY) {
fwrite(STDERR, "demo-bootstrap: TMDB_API_KEY absent, rien à faire.\n");
exit(0);
}

$db = get_db();

// Dossiers de la démo affichés en mode "films" (fichiers vidéo à plat).
// Tout le reste (Series, Anime, saisons) est en "series" par défaut et découvert
// récursivement par le worker via discover_folders().
$movieDirs = ['Films'];
$videoExts = ['mp4','mkv','avi','m4v','mov','wmv','flv','webm','ts','m2ts','mpg','mpeg'];

// 1. Config admin + enqueue des fichiers vidéo (= ce que fait POST ?folder_type_set
// puis le browse ?posters). Sans folder_type='movies', les fichiers vidéo ne sont
// jamais enqueués (cf. handlers/tmdb.php, branche $isMovies).
$setType = $db->prepare("INSERT INTO folder_posters (path, folder_type) VALUES (:p, 'movies')
ON CONFLICT(path) DO UPDATE SET folder_type = 'movies'");
$enqueue = $db->prepare("INSERT OR IGNORE INTO folder_posters (path) VALUES (:p)");

foreach ($movieDirs as $d) {
$dirPath = realpath("$mediaDir/$d");
if (!$dirPath || !is_dir($dirPath)) continue;
$setType->execute([':p' => $dirPath]);
foreach (scandir($dirPath) as $f) {
if ($f[0] === '.' || is_dir("$dirPath/$f")) continue;
if (in_array(strtolower(pathinfo($f, PATHINFO_EXTENSION)), $videoExts, true)) {
$enqueue->execute([':p' => "$dirPath/$f"]);
}
}
}

echo "demo-bootstrap: dossiers films marqués + fichiers enqueués, lancement du worker…\n";

// 2. Le vrai worker : discover (Series/Anime/saisons) + match (tmdb_match) +
// auto-verify + propagation parent→enfant + posters de saison.
passthru(escapeshellarg(find_php_cli()) . ' /app/tools/tmdb-worker.php');
17 changes: 16 additions & 1 deletion docker/demo-data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,15 @@ make_episodes "$MEDIA_DIR/Series/Stranger Things/Season 1" "Stranger.Things.S01E
make_episodes "$MEDIA_DIR/Series/Stranger Things/Season 2" "Stranger.Things.S02E" 1 3
make_episodes "$MEDIA_DIR/Series/The Mandalorian/Season 1" "The.Mandalorian.S01E" 1 3
make_episodes "$MEDIA_DIR/Series/The Mandalorian/Season 2" "The.Mandalorian.S02E" 1 3
make_episodes "$MEDIA_DIR/Series/The Witcher/Season 1" "The.Witcher.S01E" 1 3
# Série AVEC année dans le nom de release (réel) → teste l'extraction année + preferTv
make_episodes "$MEDIA_DIR/Series/The Flash/Season 5" "The.Flash.2014.S05E" 1 4

# ── Films ──
# Le bloc bas teste volontairement les cas tordus du matching : homonyme à
# départager par l'année (Dune 1984 vs 2021), titre qui EST un nombre (1917),
# tag de site + crochets, titre long à raccourcir (LOTR), titre original japonais
# (Your Name / Kimi no Na wa), et séquelle numérotée (John Wick Chapter 4).
mkdir -p "$MEDIA_DIR/Films"
for f in \
"Inception.2010.1080p.BluRay.x264.mkv" \
Expand All @@ -121,7 +128,13 @@ for f in \
"The.Shawshank.Redemption.1994.1080p.mkv" \
"Spirited.Away.2001.JAPANESE.BluRay.mkv" \
"Blade.Runner.2049.2017.MULTI.2160p.HDR.mkv" \
"Dune.2021.IMAX.1080p.WEB-DL.mkv"
"Dune.2021.IMAX.1080p.WEB-DL.mkv" \
"Dune.1984.MULTI.1080p.BluRay.x264.mkv" \
"1917.2019.MULTI.1080p.BluRay.mkv" \
"[Torrent911.com].Avatar.2009.TRUEFRENCH.1080p.mkv" \
"The.Lord.of.the.Rings.The.Fellowship.of.the.Ring.2001.EXTENDED.2160p.mkv" \
"Your.Name.2016.JAPANESE.VOSTFR.1080p.mkv" \
"John.Wick.Chapter.4.2023.MULTI.2160p.mkv"
do
cp "$CLIP" "$MEDIA_DIR/Films/$f"
done
Expand All @@ -131,6 +144,8 @@ make_episodes "$MEDIA_DIR/Anime/Attack on Titan/Season 1" "Attack.on.Titan.S01E"
make_episodes "$MEDIA_DIR/Anime/Attack on Titan/Season 2" "Attack.on.Titan.S02E" 1 3
make_episodes "$MEDIA_DIR/Anime/Death Note/Season 1" "Death.Note.S01E" 1 4
make_episodes "$MEDIA_DIR/Anime/One Piece/Season 1" "One.Piece.S01E" 1 5
make_episodes "$MEDIA_DIR/Anime/Demon Slayer Kimetsu no Yaiba/Season 1" "Demon.Slayer.Kimetsu.no.Yaiba.S01E" 1 4
make_episodes "$MEDIA_DIR/Anime/Jujutsu Kaisen/Season 1" "Jujutsu.Kaisen.S01E" 1 3

# Clean up temp files
rm -f "$CLIP" /tmp/sub_en.srt /tmp/sub_fr.srt
Expand Down
15 changes: 12 additions & 3 deletions docker/entrypoint-nvidia.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,18 @@ if [ "${SHAREBOX_AUTO_SHARE:-}" = "yes" ]; then
fi

# ── Demo data (optional) ────────────────────────────────────────────────────
# Crée uniquement les médias d'exemple ; les affiches sont matchées par le vrai worker
# (lancé en tâche de fond après le démarrage) — même chemin de code qu'une install réelle.
if [ "${SHAREBOX_DEMO_DATA:-}" = "true" ]; then
/bin/bash /docker/demo-data.sh "$MEDIA_DIR"
if [ -n "${SHAREBOX_TMDB_API_KEY:-}" ]; then
php /docker/seed-tmdb.php "$MEDIA_DIR" "${SHAREBOX_TMDB_API_KEY}" || true
fi
fi

# ── Cron (bandwidth history + hourly DB backup) ──────────────────────────────
{
echo "* * * * * www-data php /app/cron/record_netspeed.php"
echo "0 * * * * www-data php /app/cron/backup_db.php"
# Worker affiches TMDB : découvre les nouveaux dossiers et matche via TMDB.
[ -n "${SHAREBOX_TMDB_API_KEY:-}" ] && echo "*/10 * * * * www-data php /app/tools/tmdb-worker.php >> /data/tmdb-worker.log 2>&1"
} > /etc/cron.d/sharebox
chmod 644 /etc/cron.d/sharebox
cron
Expand All @@ -135,4 +136,12 @@ fi

# ── Start services ───────────────────────────────────────────────────────────
php-fpm8.3 --daemonize

# Bootstrap démo : peuple les affiches via le vrai worker, en tâche de fond (www-data).
if [ "${SHAREBOX_DEMO_DATA:-}" = "true" ] && [ -n "${SHAREBOX_TMDB_API_KEY:-}" ]; then
# $MEDIA_DIR via variable exportée (pas d'interpolation dans -c) → pas d'injection shell.
export _DEMO_MEDIA_DIR="$MEDIA_DIR"
su -s /bin/sh www-data -c 'php /docker/demo-bootstrap.php "$_DEMO_MEDIA_DIR" >> /data/tmdb-worker.log 2>&1' &
fi

exec nginx -g 'daemon off;'
23 changes: 19 additions & 4 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,11 @@ if [ "${SHAREBOX_AUTO_SHARE:-}" = "yes" ]; then
fi

# ── Demo data (optional) ────────────────────────────────────────────────────
# Crée uniquement les médias d'exemple. Le matching des affiches est délégué au VRAI
# worker (lancé en tâche de fond après le démarrage des services) : la démo emprunte
# ainsi le même chemin de code qu'une install réelle, au lieu d'un seed en dur.
if [ "${SHAREBOX_DEMO_DATA:-}" = "true" ]; then
/bin/sh /docker/demo-data.sh "$MEDIA_DIR"
# Seed TMDB posters/overviews/ratings if API key is set
if [ -n "${SHAREBOX_TMDB_API_KEY:-}" ]; then
php /docker/seed-tmdb.php "$MEDIA_DIR" "${SHAREBOX_TMDB_API_KEY}" || true
fi
fi

# ── PHP limits (streaming + large uploads) ──────────────────────────────────
Expand All @@ -107,6 +106,10 @@ PHPINI
{
echo "* * * * * php /app/cron/record_netspeed.php"
echo "0 * * * * php /app/cron/backup_db.php"
# Worker affiches TMDB : découvre les nouveaux dossiers et matche via TMDB.
# Absent par défaut de l'image jusqu'ici → un install Docker n'avait jamais de
# cron poster (seul le ?posters au browse alimentait la grille).
[ -n "${SHAREBOX_TMDB_API_KEY:-}" ] && echo "*/10 * * * * php /app/tools/tmdb-worker.php >> /data/tmdb-worker.log 2>&1"
} > /etc/crontabs/www-data
crond -b -l 8

Expand All @@ -120,5 +123,17 @@ chown www-data:www-data /data/share.db /data/share.db-wal /data/share.db-shm /da

# ── Start services ───────────────────────────────────────────────────────────
php-fpm -D

# ── Bootstrap démo : peuple les affiches via le vrai worker ──────────────────
# En tâche de fond (www-data, propriétaire de la DB) pour ne pas bloquer le démarrage —
# les affiches apparaissent en ~1 min, exactement comme le premier passage de cron
# sur une install fraîche. Pas de seed en dur : même chemin de code que la prod.
if [ "${SHAREBOX_DEMO_DATA:-}" = "true" ] && [ -n "${SHAREBOX_TMDB_API_KEY:-}" ]; then
# $MEDIA_DIR passé via une variable exportée (pas d'interpolation dans la chaîne -c) →
# aucune injection shell possible même si l'env contient des guillemets/backticks.
export _DEMO_MEDIA_DIR="$MEDIA_DIR"
su -s /bin/sh www-data -c 'php /docker/demo-bootstrap.php "$_DEMO_MEDIA_DIR" >> /data/tmdb-worker.log 2>&1' &
fi

echo "ShareBox ready — admin: http://localhost/share"
exec nginx -g 'daemon off;'
Loading
Loading