scanner/scan_disc.py: - Inventory disc into video files + photo folders (grouped by directory) - Photo extensions: jpg/jpeg/png/gif/tiff/bmp/heic/heif/webp + raw formats (cr2 cr3 nef arw dng orf rw2 raf) - Video disc → 1 record per disc with video file list - Photo disc → 1 record per gallery folder with photo list - Mixed disc → both: 1 video record + 1 record per photo folder - Unknown disc → 1 fallback record with total file count - Folder title format: "DISC_LABEL — Folder / Subfolder" videodb/api_ingest.php: - Add subtitle field (gallery folder path) - Add plot field (TEXT — full filename list, no 255-char limit) - Add custom3 field (content type: video | photo | mixed | data) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
91 lines
4.3 KiB
PHP
91 lines
4.3 KiB
PHP
<?php
|
|
/**
|
|
* Disc ingest API
|
|
*
|
|
* Called by the local macOS scanner (scanner/scan_disc.py).
|
|
* Accepts a JSON POST with disc metadata and inserts a record
|
|
* into the videoDB database.
|
|
*
|
|
* Auth: X-API-Token header must match INGEST_API_TOKEN in config.inc.php
|
|
*/
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
// ── Load config ───────────────────────────────────────────────────────────────
|
|
$config = [];
|
|
require_once './config.sample.php';
|
|
if (!@include_once './config.inc.php') {
|
|
http_response_code(503);
|
|
echo json_encode(['error' => 'config.inc.php not found']);
|
|
exit;
|
|
}
|
|
require_once './core/constants.php';
|
|
|
|
// ── Auth ─────────────────────────────────────────────────────────────────────
|
|
$expected_token = $config['ingest_api_token'] ?? '';
|
|
$provided_token = $_SERVER['HTTP_X_API_TOKEN'] ?? '';
|
|
|
|
if (!$expected_token || $provided_token !== $expected_token) {
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'Unauthorized']);
|
|
exit;
|
|
}
|
|
|
|
// ── Method guard ─────────────────────────────────────────────────────────────
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['error' => 'POST required']);
|
|
exit;
|
|
}
|
|
|
|
// ── Parse body ───────────────────────────────────────────────────────────────
|
|
$body = file_get_contents('php://input');
|
|
$data = json_decode($body, true);
|
|
|
|
if (!$data || empty($data['title'])) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Missing required field: title']);
|
|
exit;
|
|
}
|
|
|
|
// ── Connect ───────────────────────────────────────────────────────────────────
|
|
$dbh = @mysqli_connect(
|
|
$config['db_server'],
|
|
$config['db_user'],
|
|
$config['db_password'],
|
|
$config['db_database']
|
|
);
|
|
if (!$dbh) {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'DB connection failed: ' . mysqli_connect_error()]);
|
|
exit;
|
|
}
|
|
|
|
// ── Sanitize inputs ───────────────────────────────────────────────────────────
|
|
$title = mysqli_real_escape_string($dbh, substr($data['title'] ?? '', 0, 255));
|
|
$subtitle = mysqli_real_escape_string($dbh, substr($data['subtitle'] ?? '', 0, 255)); // gallery folder path
|
|
$mediatype = (int)($data['mediatype'] ?? 1);
|
|
$comment = mysqli_real_escape_string($dbh, substr($data['comment'] ?? '', 0, 255));
|
|
$plot = mysqli_real_escape_string($dbh, $data['plot'] ?? ''); // full file listing (TEXT, no limit)
|
|
$filesize = (int)($data['filesize'] ?? 0);
|
|
$custom1 = mysqli_real_escape_string($dbh, substr($data['custom1'] ?? '', 0, 255)); // disc type string
|
|
$custom2 = mysqli_real_escape_string($dbh, substr($data['custom2'] ?? '', 0, 255)); // file/photo count
|
|
$custom3 = mysqli_real_escape_string($dbh, substr($data['custom3'] ?? '', 0, 255)); // content type: video|photo|mixed
|
|
$disklabel = mysqli_real_escape_string($dbh, substr($data['disklabel'] ?? '', 0, 32));
|
|
|
|
// ── Insert ────────────────────────────────────────────────────────────────────
|
|
$sql = "INSERT INTO " . TBL_DATA . "
|
|
(title, subtitle, mediatype, comment, plot, filesize, disklabel, custom1, custom2, custom3, created, owner_id)
|
|
VALUES
|
|
('$title', '$subtitle', $mediatype, '$comment', '$plot', $filesize, '$disklabel', '$custom1', '$custom2', '$custom3', NOW(), 1)";
|
|
|
|
if (mysqli_query($dbh, $sql)) {
|
|
$id = (int)mysqli_insert_id($dbh);
|
|
echo json_encode(['ok' => true, 'id' => $id, 'title' => $data['title']]);
|
|
} else {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Insert failed: ' . mysqli_error($dbh)]);
|
|
}
|
|
|
|
mysqli_close($dbh);
|