annotate medi/main.c @ 217:7ef4c9d2a72d hg-web

[DO NOT PUSH] Random values.
author MrJuneJune <me@mrjunejune.com>
date Sun, 25 Jan 2026 10:44:04 -0800
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
217
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 #include "seobeo/seobeo.h"
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2 #include "media_processor/media_processor.h"
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 #include <stdio.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 #include <stdlib.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 #include <string.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7 #include <sys/stat.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 #include <dirent.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 #include <pthread.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 #include <unistd.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 #define UPLOAD_DIR "./uploads"
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 #define PROCESSED_DIR "./media"
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 #define MAX_UPLOAD_SIZE (100 * 1024 * 1024) // 100MB
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 // Background processing queue
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 typedef struct ProcessJob {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 char* input_path;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 char* id;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 MediaType type;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 struct ProcessJob* next;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 } ProcessJob;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 static ProcessJob* job_queue_head = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 static ProcessJob* job_queue_tail = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 static pthread_mutex_t job_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 static pthread_cond_t job_queue_cond = PTHREAD_COND_INITIALIZER;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 // Helper Functions
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 static void ensure_directories(void) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 mkdir(UPLOAD_DIR, 0755);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35 mkdir(PROCESSED_DIR, 0755);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 static char* extract_filename_from_content_disposition(const char* header, Dowa_Arena* arena) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 const char* filename_start = strstr(header, "filename=\"");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 if (!filename_start) return NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 filename_start += 10; // Skip 'filename="'
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43 const char* filename_end = strchr(filename_start, '"');
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 if (!filename_end) return NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 size_t len = filename_end - filename_start;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 char* filename = Dowa_Arena_Allocate(arena, len + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 memcpy(filename, filename_start, len);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 filename[len] = '\0';
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 return filename;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 static char* find_multipart_boundary(const char* content_type, Dowa_Arena* arena) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 const char* boundary_start = strstr(content_type, "boundary=");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 if (!boundary_start) return NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 boundary_start += 9; // Skip 'boundary='
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 // Handle quoted boundary
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 if (*boundary_start == '"') {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 boundary_start++;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 const char* boundary_end = strchr(boundary_start, '"');
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 if (!boundary_end) return NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 size_t len = boundary_end - boundary_start;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 char* boundary = Dowa_Arena_Allocate(arena, len + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 memcpy(boundary, boundary_start, len);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67 boundary[len] = '\0';
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 return boundary;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 // Unquoted boundary
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 size_t len = strlen(boundary_start);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 char* boundary = Dowa_Arena_Allocate(arena, len + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 strcpy(boundary, boundary_start);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 // Trim whitespace/newline
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 while (len > 0 && (boundary[len-1] == '\r' || boundary[len-1] == '\n' || boundary[len-1] == ' ')) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 boundary[--len] = '\0';
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79 return boundary;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 // Background Processing Worker
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 static void enqueue_job(const char* input_path, const char* id, MediaType type) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 ProcessJob* job = malloc(sizeof(ProcessJob));
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 job->input_path = strdup(input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89 job->id = strdup(id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 job->type = type;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 job->next = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 pthread_mutex_lock(&job_queue_mutex);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 if (job_queue_tail) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 job_queue_tail->next = job;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 job_queue_tail = job;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 job_queue_head = job_queue_tail = job;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 pthread_cond_signal(&job_queue_cond);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 pthread_mutex_unlock(&job_queue_mutex);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 static void* processing_worker(void* arg) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 (void)arg;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 while (1) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 pthread_mutex_lock(&job_queue_mutex);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 while (!job_queue_head) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 pthread_cond_wait(&job_queue_cond, &job_queue_mutex);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 ProcessJob* job = job_queue_head;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 job_queue_head = job->next;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 if (!job_queue_head) job_queue_tail = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 pthread_mutex_unlock(&job_queue_mutex);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 // Process the job
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 Seobeo_Log(SEOBEO_INFO, "Processing media: %s (id=%s)", job->input_path, job->id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 MediaProcessorOpts opts = media_processor_opts_default(PROCESSED_DIR);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 MediaResult* result = media_process_file(job->input_path, job->id, &opts);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 if (result->status == MEDIA_STATUS_COMPLETED) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 Seobeo_Log(SEOBEO_INFO, "Processing completed for %s", job->id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 Seobeo_Log(SEOBEO_ERROR, "Processing failed for %s: %s", job->id, result->error_message);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 media_result_free(result);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 // Clean up temp upload file
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 unlink(job->input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 free(job->input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 free(job->id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136 free(job);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 return NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142 void Seobeo_Render_Html(
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143 char *final_body,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144 char *template,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 Dowa_Arena *arena
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 )
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 size_t current_offset = 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 char *cursor = template;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 int32 token_len = 2;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 while (1)
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155 char *start_tag = strstr(cursor, "{{");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 if (!start_tag) break;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 char *end_tag = strstr(start_tag, "}}");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 if (!end_tag) break;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 size_t leading_len = start_tag - cursor;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 memcpy(final_body + current_offset, cursor, leading_len);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 current_offset += leading_len;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 size_t name_len = end_tag - (start_tag + token_len);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 char *include_name = Dowa_Arena_Allocate(arena, name_len + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 memcpy(include_name, start_tag + token_len, name_len);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 include_name[name_len] = '\0';
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170 size_t sub_file_size = 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 char *sub_content = Seobeo_Web_LoadFile(include_name, &sub_file_size);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 Seobeo_Log(SEOBEO_DEBUG, "[Curr] Sub content: %s\n", sub_content);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173 if (sub_content)
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 memcpy(final_body + current_offset, sub_content, sub_file_size);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 current_offset += sub_file_size;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 free(sub_content);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 cursor = end_tag + 2;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 strcpy(final_body + current_offset, cursor);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 void Seobeo_Render_Html_FilePath(
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187 char *final_body,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 char *path,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189 Dowa_Arena *arena
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 ) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 Seobeo_Log(SEOBEO_DEBUG, "[Curr] %s\n", path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 size_t html_size = 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193 char *template = Seobeo_Web_LoadFile(path, &html_size);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 if (!template) return;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
195 Seobeo_Render_Html(final_body, template, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
196 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
198 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 // API Route Handlers
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
201
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
202 // GET / - Serve the main HTML page
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
203 Seobeo_Request_Entry* handle_index(Seobeo_Request_Entry* req, Dowa_Arena* arena) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
204 Seobeo_Request_Entry *resp = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
205 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
206 Seobeo_Render_Html_FilePath(final_body, "/index.html", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
207 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
208 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
209 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
210
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211 // POST /api/upload - Handle file upload
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
212 Seobeo_Request_Entry* handle_upload(Seobeo_Request_Entry* req, Dowa_Arena* arena) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
213 const char* content_type = Dowa_HashMap_Get(req, "content-type");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
214 const char* body = Dowa_HashMap_Get(req, "Body");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
215 const char* content_length_str = Dowa_HashMap_Get(req, "content-length");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
217 Seobeo_Request_Entry* resp = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
218
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
219 if (!content_type || !body) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
220 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
221 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
222 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Missing content\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
223 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
224 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
225
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
226 size_t content_length = content_length_str ? atol(content_length_str) : strlen(body);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
227
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
228 if (content_length > MAX_UPLOAD_SIZE) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
229 Dowa_HashMap_Push_Arena(resp, "status", "413", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
230 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
231 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"File too large\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
232 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
233 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
234
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 // Parse multipart form data
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
236 char* boundary = find_multipart_boundary(content_type, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
237 if (!boundary) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
238 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
239 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
240 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Invalid multipart data\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
241 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
242 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
243
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
244 // Find file content in multipart data
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
245 char boundary_marker[256];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
246 snprintf(boundary_marker, sizeof(boundary_marker), "--%s", boundary);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
247
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
248 const char* part_start = strstr(body, boundary_marker);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
249 if (!part_start) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
250 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
251 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
252 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"No file found\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
253 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
254 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
255
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
256 // Skip to headers
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
257 part_start = strstr(part_start, "\r\n");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
258 if (!part_start) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
259 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
260 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
261 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Invalid format\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
262 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
263 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
264 part_start += 2;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
265
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
266 // Find filename from Content-Disposition
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
267 char* filename = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
268 const char* header_end = strstr(part_start, "\r\n\r\n");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
269 if (header_end) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
270 char headers[1024] = {0};
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
271 size_t headers_len = header_end - part_start;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
272 if (headers_len < sizeof(headers)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
273 memcpy(headers, part_start, headers_len);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
274 filename = extract_filename_from_content_disposition(headers, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
275 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
276 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
277
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
278 if (!filename) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
279 filename = "upload";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
280 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
281
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
282 // Find file content
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
283 const char* file_start = header_end + 4; // Skip \r\n\r\n
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
284
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
285 // Find end boundary
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
286 char end_boundary[256];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
287 snprintf(end_boundary, sizeof(end_boundary), "\r\n--%s", boundary);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
288 const char* file_end = strstr(file_start, end_boundary);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
289
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
290 if (!file_end) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
291 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
292 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
293 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Incomplete upload\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
294 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
295 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
296
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
297 size_t file_size = file_end - file_start;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
298
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
299 // Generate ID and determine type
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
300 char* id = media_generate_id();
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
301 MediaType type = media_detect_type(filename);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
302
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
303 if (type == MEDIA_TYPE_UNKNOWN) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
304 free(id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
305 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
306 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
307 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Unsupported file type\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
308 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
309 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
310
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
311 // Save to temp file
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
312 const char* ext = media_get_extension(filename);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
313 char temp_path[512];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
314 snprintf(temp_path, sizeof(temp_path), "%s/%s%s", UPLOAD_DIR, id, ext ? ext : "");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
315
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
316 FILE* f = fopen(temp_path, "wb");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
317 if (!f) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
318 free(id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
319 Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
320 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
321 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Failed to save file\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
322 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
323 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
324
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
325 fwrite(file_start, 1, file_size, f);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
326 fclose(f);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
327
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
328 // Enqueue for processing
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
329 enqueue_job(temp_path, id, type);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
330
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
331 // Return success with ID
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
332 char response_body[256];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
333 snprintf(response_body, sizeof(response_body),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
334 "{\"id\":\"%s\",\"type\":\"%s\",\"status\":\"processing\"}",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
335 id, type == MEDIA_TYPE_IMAGE ? "image" : "video");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
336
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
337 char* body_copy = Dowa_Arena_Allocate(arena, strlen(response_body) + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
338 strcpy(body_copy, response_body);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
339
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
340 Dowa_HashMap_Push_Arena(resp, "status", "202", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
341 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
342 Dowa_HashMap_Push_Arena(resp, "Body", body_copy, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
343
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
344 free(id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
345 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
346 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
347
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
348 // GET /api/media/:id - Get media info/status
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
349 Seobeo_Request_Entry* handle_media_info(Seobeo_Request_Entry* req, Dowa_Arena* arena) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
350 const char* path = Dowa_HashMap_Get(req, "path");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
351
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
352 Seobeo_Request_Entry* resp = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
353
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
354 // Extract ID from path (e.g., /api/media/123456)
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
355 const char* id = path + strlen("/api/media/");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
356 if (!id || strlen(id) == 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
357 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
358 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
359 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Missing media ID\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
360 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
361 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
362
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
363 // Check if processed directory exists
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
364 char media_dir[512];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
365 snprintf(media_dir, sizeof(media_dir), "%s/%s", PROCESSED_DIR, id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
366
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
367 struct stat st;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
368 if (stat(media_dir, &st) != 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
369 // Check if still processing
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
370 char upload_pattern[512];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
371 snprintf(upload_pattern, sizeof(upload_pattern), "%s/%s", UPLOAD_DIR, id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
372
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
373 DIR* dir = opendir(UPLOAD_DIR);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
374 boolean found = FALSE;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
375 if (dir) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
376 struct dirent* entry;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
377 while ((entry = readdir(dir)) != NULL) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
378 if (strncmp(entry->d_name, id, strlen(id)) == 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
379 found = TRUE;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
380 break;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
381 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
382 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
383 closedir(dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
384 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
385
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
386 if (found) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
387 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
388 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
389 Dowa_HashMap_Push_Arena(resp, "Body", "{\"status\":\"processing\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
390 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
391 Dowa_HashMap_Push_Arena(resp, "status", "404", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
392 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
393 Dowa_HashMap_Push_Arena(resp, "Body", "{\"error\":\"Media not found\"}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
394 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
395 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
396 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
397
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
398 // Check what files exist
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
399 char webp_path[512], hls_path[512], thumb_path[512];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
400 snprintf(webp_path, sizeof(webp_path), "%s/image.webp", media_dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
401 snprintf(hls_path, sizeof(hls_path), "%s/video.m3u8", media_dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
402 snprintf(thumb_path, sizeof(thumb_path), "%s/video_thumb.jpg", media_dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
403
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
404 boolean is_image = (stat(webp_path, &st) == 0);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
405 boolean is_video = (stat(hls_path, &st) == 0);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
406
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
407 char response[1024];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
408 if (is_image) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
409 snprintf(response, sizeof(response),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
410 "{\"id\":\"%s\",\"type\":\"image\",\"status\":\"completed\","
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
411 "\"webp\":\"/media/%s/image.webp\","
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
412 "\"original\":\"/media/%s/original\"}",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
413 id, id, id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
414 } else if (is_video) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
415 snprintf(response, sizeof(response),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
416 "{\"id\":\"%s\",\"type\":\"video\",\"status\":\"completed\","
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
417 "\"hls\":\"/media/%s/video.m3u8\","
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
418 "\"thumbnail\":\"/media/%s/video_thumb.jpg\","
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
419 "\"original\":\"/media/%s/original\"}",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
420 id, id, id, id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
421 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
422 snprintf(response, sizeof(response), "{\"id\":\"%s\",\"status\":\"processing\"}", id);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
423 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
424
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
425 char* body = Dowa_Arena_Allocate(arena, strlen(response) + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
426 strcpy(body, response);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
427
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
428 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
429 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
430 Dowa_HashMap_Push_Arena(resp, "Body", body, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
431
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
432 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
433 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
434
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
435 // GET /api/media - List all media
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
436 Seobeo_Request_Entry* handle_media_list(Seobeo_Request_Entry* req, Dowa_Arena* arena) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
437 (void)req;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
438
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
439 Seobeo_Request_Entry* resp = NULL;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
440
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
441 DIR* dir = opendir(PROCESSED_DIR);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
442 if (!dir) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
443 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
444 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
445 Dowa_HashMap_Push_Arena(resp, "Body", "{\"items\":[]}", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
446 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
447 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
448
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
449 // Build JSON array
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
450 char json[16384] = "{\"items\":[";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
451 size_t json_len = strlen(json);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
452 boolean first = TRUE;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
453
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
454 struct dirent* entry;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
455 while ((entry = readdir(dir)) != NULL) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
456 if (entry->d_name[0] == '.') continue;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
457
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
458 char media_dir[512];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
459 snprintf(media_dir, sizeof(media_dir), "%s/%s", PROCESSED_DIR, entry->d_name);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
460
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
461 struct stat st;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
462 if (stat(media_dir, &st) != 0 || !S_ISDIR(st.st_mode)) continue;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
463
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
464 // Check type
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
465 char webp_path[512], hls_path[512];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
466 snprintf(webp_path, sizeof(webp_path), "%s/image.webp", media_dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
467 snprintf(hls_path, sizeof(hls_path), "%s/video.m3u8", media_dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
468
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
469 const char* type = "unknown";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
470 if (stat(webp_path, &st) == 0) type = "image";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
471 else if (stat(hls_path, &st) == 0) type = "video";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
472
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
473 char item[256];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
474 snprintf(item, sizeof(item), "%s{\"id\":\"%s\",\"type\":\"%s\"}",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
475 first ? "" : ",", entry->d_name, type);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
476
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
477 size_t item_len = strlen(item);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
478 if (json_len + item_len + 10 < sizeof(json)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
479 strcpy(json + json_len, item);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
480 json_len += item_len;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
481 first = FALSE;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
482 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
483 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
484
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
485 closedir(dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
486
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
487 strcpy(json + json_len, "]}");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
488
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
489 char* body = Dowa_Arena_Allocate(arena, strlen(json) + 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
490 strcpy(body, json);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
491
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
492 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
493 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
494 Dowa_HashMap_Push_Arena(resp, "Body", body, arena);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
495
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
496 return resp;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
497 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
498
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
499 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
500 // Main
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
501 // ============================================================================
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
502
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
503 int main(int argc, char** argv) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
504 const char* port = "8080";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
505
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
506 printf("===========================================\n");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
507 printf(" Medi - Media Upload & Processing Server\n");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
508 printf("===========================================\n");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
509 printf("Starting on port %s...\n\n", port);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
510
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
511 // Create directories
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
512 ensure_directories();
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
513
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
514 // Start background processing worker
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
515 pthread_t worker_thread;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
516 pthread_create(&worker_thread, NULL, processing_worker, NULL);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
517
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
518 // Initialize router
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
519 Seobeo_Router_Init();
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
520
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
521 // Register routes
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
522 Seobeo_Router_Register("GET", "/", handle_index);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
523 Seobeo_Router_Register("POST", "/api/upload", handle_upload);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
524 Seobeo_Router_Register("GET", "/api/media", handle_media_list);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
525 Seobeo_Router_Register("GET", "/api/media/*", handle_media_info);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
526
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
527 // Start server (serves static files from ./media for /media/* paths)
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
528 Seobeo_Web_Server_Start("medi/src", port, SEOBEO_MODE_EDGE, 4);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
529
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
530 return 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
531 }