comparison mrjunejune/main.c @ 216:e82b80b24012 default tip

[MrJuneJune] Make webp translate background job.
author June Park <parkjune1995@gmail.com>
date Sat, 28 Feb 2026 21:04:43 -0800
parents 240337164a80
children
comparison
equal deleted inserted replaced
215:c3df85159b31 216:e82b80b24012
22 char content_type[128]; 22 char content_type[128];
23 char access_token[256]; 23 char access_token[256];
24 char db_path[256]; 24 char db_path[256];
25 S3_Config s3_config; 25 S3_Config s3_config;
26 } Media_Processing_Context; 26 } Media_Processing_Context;
27
28 typedef struct {
29 char *input_path;
30 char *output_path;
31 } File_Converter_Config;
27 32
28 // Server configuration (loaded from .config) 33 // Server configuration (loaded from .config)
29 static char g_upload_auth_token[256] = {0}; 34 static char g_upload_auth_token[256] = {0};
30 static char g_s3_region[64] = "us-west-2"; 35 static char g_s3_region[64] = "us-west-2";
31 static char g_s3_bucket[128] = "mrjunejune"; 36 static char g_s3_bucket[128] = "mrjunejune";
288 Seobeo_Render_Html_FilePath(final_body, "/tools/file_converter/index.html", arena); 293 Seobeo_Render_Html_FilePath(final_body, "/tools/file_converter/index.html", arena);
289 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); 294 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
290 return resp; 295 return resp;
291 } 296 }
292 297
298 // Background thread function for media processing
299 void *Simple_WebpConverter_Background(void *arg)
300 {
301 File_Converter_Config *configuration = (File_Converter_Config *)arg;
302
303 char cmd[1024];
304 snprintf(cmd, sizeof(cmd), "ffmpeg -y -i %s -quality 80 %s 2>/tmp/error_log",
305 configuration->input_path, configuration->output_path);
306 Seobeo_Log(SEOBEO_INFO, "[MEDIA] Running FFmpeg: %s\n", cmd);
307 int ffmpeg_result = system(cmd);
308
309 Seobeo_Log(SEOBEO_INFO, "[MEDIA] FFmpeg result: %d\n", ffmpeg_result);
310 if (ffmpeg_result != 0)
311 {
312 Seobeo_Log(SEOBEO_ERROR, "[MEDIA] ERROR: FFmpeg conversion failed\n");
313 return NULL;
314 }
315 Seobeo_Log(SEOBEO_INFO, "[MEDIA] Successfully converted to webp: %s\n");
316 return NULL;
317 }
318
293 Seobeo_Request_Entry *ConvertImageToWebP(Seobeo_Request_Entry *req, Dowa_Arena *arena) 319 Seobeo_Request_Entry *ConvertImageToWebP(Seobeo_Request_Entry *req, Dowa_Arena *arena)
294 { 320 {
295 Seobeo_Request_Entry *resp = NULL; 321 Seobeo_Request_Entry *resp = NULL;
296 322
297 if (!req) 323 if (!req)
336 362
337 const char *file_data = ((Seobeo_Request_Entry*)body_kv)->value; 363 const char *file_data = ((Seobeo_Request_Entry*)body_kv)->value;
338 const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value; 364 const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value;
339 size_t file_size = atoi(content_length_str); 365 size_t file_size = atoi(content_length_str);
340 366
341 printf("DEBUG: Converting image, file_size=%zu bytes\n", file_size); 367 Seobeo_Log(SEOBEO_DEBUG, "Converting image, file_size=%zu bytes\n", file_size);
342 368
343 int open_flags = O_RDWR | O_CREAT | O_EXCL; 369 int open_flags = O_RDWR | O_CREAT | O_EXCL;
344 370
345 char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN); 371 char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN);
346 uint32 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++; 372 uint32 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++;
363 uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN); 389 uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN);
364 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++; 390 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++;
365 Dowa_String_UUID(seed, uuid4); 391 Dowa_String_UUID(seed, uuid4);
366 char *output_path = (char *)Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);; 392 char *output_path = (char *)Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);;
367 snprintf(output_path, TMP_FILE_LENGTH, "/tmp/%s.webp", uuid4); 393 snprintf(output_path, TMP_FILE_LENGTH, "/tmp/%s.webp", uuid4);
368 printf("[DEBUG] output_path %s\n", output_path); 394 Seobeo_Log(SEOBEO_DEBUG, "output_path %s\n", output_path);
369 printf("[DEBUG] open_flags: 0x%x\n", open_flags); 395 Seobeo_Log(SEOBEO_DEBUG, "open_flags: 0x%x\n", open_flags);
370 printf("[DEBUG] input_path: %s\n", input_path); 396 Seobeo_Log(SEOBEO_DEBUG, "input_path: %s\n", input_path);
371 int output_fd = open(output_path, open_flags, 0600); 397 int output_fd = open(output_path, open_flags, 0600);
372 printf("[DEBUG] output_fd: %d\n", output_fd); 398 Seobeo_Log(SEOBEO_DEBUG, "output_fd: %d\n", output_fd);
373 if (output_fd == -1) 399 if (output_fd == -1)
374 { 400 {
375 unlink(input_path); 401 unlink(input_path);
376 printf("[DEBUG] errno: %d (%s)\n", errno, strerror(errno)); 402 Seobeo_Log(SEOBEO_DEBUG, "errno: %d (%s)\n", errno, strerror(errno));
377 char *error_msg = "Failed to create output file"; 403 char *error_msg = "Failed to create output file";
378 Dowa_HashMap_Push_Arena(resp, "status", "500", arena); 404 Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
379 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena); 405 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
380 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena); 406 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
381 return resp; 407 return resp;
382 } 408 }
383 close(output_fd); 409 close(output_fd);
384 410
385 char cmd[1024]; 411 File_Converter_Config *configuration = Dowa_Arena_Allocate(arena, sizeof(File_Converter_Config));
386 snprintf(cmd, sizeof(cmd), "ffmpeg -y -i %s -quality 80 %s 2>/tmp/error_log", 412 configuration->input_path = input_path;
387 input_path, output_path); 413 configuration->output_path = output_path;
388 int result = system(cmd); 414
389 if (result != 0) 415 pthread_t thread_id;
416 int thread_result = pthread_create(&thread_id, NULL, Simple_WebpConverter_Background, (void *)configuration);
417
418 if (thread_result != 0)
390 { 419 {
391 unlink(input_path); 420 unlink(input_path);
392 unlink(output_path); 421 unlink(output_path);
393 char *error_msg = "FFmpeg conversion failed"; 422 char *error_msg = "FFmpeg conversion failed";
394 Dowa_HashMap_Push_Arena(resp, "status", "500", arena); 423 Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
395 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena); 424 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
396 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena); 425 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
397 return resp; 426 return resp;
398 } 427 }
428 else
429 {
430 // Detach thread so it cleans up automatically when done
431 pthread_detach(thread_id);
432 Seobeo_Log(SEOBEO_INFO, "[MEDIA] Successfully spawned and detached thread\n");
433 }
399 434
400 size_t converted_size = 0; 435 size_t converted_size = 0;
401 FILE *out_file = fopen(output_path, "rb"); 436 FILE *out_file = fopen(output_path, "rb");
402 if (!out_file) 437 if (!out_file)
403 { 438 {
410 return resp; 445 return resp;
411 } 446 }
412 fclose(out_file); 447 fclose(out_file);
413 448
414 unlink(input_path); 449 unlink(input_path);
415
416 char *filename = strrchr(output_path, '/') + 1; 450 char *filename = strrchr(output_path, '/') + 1;
417 char *response_body = Dowa_Arena_Allocate(arena, 512); 451 char *response_body = Dowa_Arena_Allocate(arena, 512);
418 snprintf(response_body, 512, 452 snprintf(response_body, 512,
419 "{\"success\":true,\"download_url\":\"/api/download/%s\",\"expires\":\"10 minutes\"}", 453 "{\"success\":true,\"download_url\":\"/api/download/%s\",\"expires\":\"10 minutes\"}",
420 filename); 454 filename);
421 Dowa_HashMap_Push_Arena(resp, "status", "200", arena); 455 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
422 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena); 456 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
423 Dowa_HashMap_Push_Arena(resp, "body", response_body, arena); 457 Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);
424 458
425 printf("DEBUG: Image converted, available at /api/download/%s\n", filename); 459 Seobeo_Log(SEOBEO_DEBUG, "Image converted, available at /api/download/%s\n", filename);
426 460
427 return resp; 461 return resp;
428 } 462 }
429 463
430 Seobeo_Request_Entry *ConvertVideoToMP4(Seobeo_Request_Entry *req, Dowa_Arena *arena) 464 Seobeo_Request_Entry *ConvertVideoToMP4(Seobeo_Request_Entry *req, Dowa_Arena *arena)