Implement creator studio and upload updates

This commit is contained in:
2026-04-04 10:12:02 +02:00
parent 1da7d3bf88
commit 0b216b7ecd
15107 changed files with 31206 additions and 626514 deletions

View File

@@ -83,6 +83,11 @@ final class UploadController extends Controller
$sessionId = (string) $request->validated('session_id');
$artworkId = (int) $request->validated('artwork_id');
$originalFileName = $request->validated('file_name');
$archiveSessionId = $request->validated('archive_session_id');
$archiveOriginalFileName = $request->validated('archive_file_name');
$additionalScreenshotSessions = collect($request->validated('additional_screenshot_sessions', []))
->filter(fn ($payload) => is_array($payload) && is_string($payload['session_id'] ?? null))
->values();
$session = $sessions->getOrFail($sessionId);
@@ -112,14 +117,81 @@ final class UploadController extends Controller
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$validatedArchive = null;
if (is_string($archiveSessionId) && trim($archiveSessionId) !== '') {
$validatedArchive = $pipeline->validateAndHashArchive($archiveSessionId);
if (! $validatedArchive->validation->ok || ! $validatedArchive->hash) {
return response()->json([
'message' => 'Archive validation failed.',
'reason' => $validatedArchive->validation->reason,
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$archiveScan = $pipeline->scan($archiveSessionId);
if (! $archiveScan->ok) {
return response()->json([
'message' => 'Archive scan failed.',
'reason' => $archiveScan->reason,
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
}
$validatedAdditionalScreenshots = [];
foreach ($additionalScreenshotSessions as $payload) {
$screenshotSessionId = (string) ($payload['session_id'] ?? '');
if ($screenshotSessionId === '') {
continue;
}
$validatedScreenshot = $pipeline->validateAndHash($screenshotSessionId);
if (! $validatedScreenshot->validation->ok || ! $validatedScreenshot->hash) {
return response()->json([
'message' => 'Screenshot validation failed.',
'reason' => $validatedScreenshot->validation->reason,
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$screenshotScan = $pipeline->scan($screenshotSessionId);
if (! $screenshotScan->ok) {
return response()->json([
'message' => 'Screenshot scan failed.',
'reason' => $screenshotScan->reason,
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$validatedAdditionalScreenshots[] = [
'session_id' => $screenshotSessionId,
'hash' => $validatedScreenshot->hash,
'file_name' => is_string($payload['file_name'] ?? null) ? $payload['file_name'] : null,
];
}
try {
$status = DB::transaction(function () use ($pipeline, $sessionId, $validated, $artworkId, $originalFileName) {
$status = DB::transaction(function () use ($pipeline, $sessionId, $validated, $artworkId, $originalFileName, $archiveSessionId, $validatedArchive, $archiveOriginalFileName, $validatedAdditionalScreenshots) {
if ((bool) config('uploads.queue_derivatives', false)) {
GenerateDerivativesJob::dispatch($sessionId, $validated->hash, $artworkId, is_string($originalFileName) ? $originalFileName : null)->afterCommit();
GenerateDerivativesJob::dispatch(
$sessionId,
$validated->hash,
$artworkId,
is_string($originalFileName) ? $originalFileName : null,
is_string($archiveSessionId) ? $archiveSessionId : null,
$validatedArchive?->hash,
is_string($archiveOriginalFileName) ? $archiveOriginalFileName : null,
$validatedAdditionalScreenshots
)->afterCommit();
return 'queued';
}
$pipeline->processAndPublish($sessionId, $validated->hash, $artworkId, is_string($originalFileName) ? $originalFileName : null);
$pipeline->processAndPublish(
$sessionId,
$validated->hash,
$artworkId,
is_string($originalFileName) ? $originalFileName : null,
is_string($archiveSessionId) ? $archiveSessionId : null,
$validatedArchive?->hash,
is_string($archiveOriginalFileName) ? $archiveOriginalFileName : null,
$validatedAdditionalScreenshots
);
// Derivatives are available now; dispatch AI auto-tagging.
AutoTagArtworkJob::dispatch($artworkId, $validated->hash)->afterCommit();
@@ -132,6 +204,8 @@ final class UploadController extends Controller
'hash' => $validated->hash,
'artwork_id' => $artworkId,
'status' => $status,
'archive_session_id' => is_string($archiveSessionId) ? $archiveSessionId : null,
'additional_screenshot_session_ids' => array_values(array_map(static fn (array $payload): string => (string) $payload['session_id'], $validatedAdditionalScreenshots)),
]);
return response()->json([
@@ -540,13 +614,6 @@ final class UploadController extends Controller
$slugBase = 'artwork';
}
$slug = $slugBase;
$suffix = 2;
while (Artwork::query()->where('slug', $slug)->where('id', '!=', $artwork->id)->exists()) {
$slug = $slugBase . '-' . $suffix;
$suffix++;
}
$artwork->title = $title;
if (array_key_exists('description', $validated)) {
$artwork->description = $validated['description'];
@@ -554,7 +621,7 @@ final class UploadController extends Controller
if (array_key_exists('is_mature', $validated) || array_key_exists('nsfw', $validated)) {
$artwork->is_mature = (bool) ($validated['is_mature'] ?? $validated['nsfw'] ?? false);
}
$artwork->slug = $slug;
$artwork->slug = Str::limit($slugBase, 160, '');
$artwork->artwork_timezone = $validated['timezone'] ?? null;
// Sync category if provided