@@ -2,6 +2,7 @@ const Art = require("../../models/art");
2
2
const Theme = require ( "../../models/theme" ) ;
3
3
const User = require ( "../../models/user" ) ;
4
4
const fs = require ( "fs" ) ;
5
+ const path = require ( 'path' ) ; // Add this line
5
6
const slugify = require ( "../utils/slugify" ) ;
6
7
const stylizeImages = require ( "../utils/style-transfer" ) ;
7
8
@@ -18,6 +19,7 @@ const index = async (req, res) => {
18
19
. skip ( ( page - 1 ) * limit )
19
20
. limit ( limit ) ;
20
21
22
+ res . set ( 'Content-Type' , 'application/json' ) ;
21
23
return res . status ( 200 ) . json ( {
22
24
status : "success" ,
23
25
message : "Arts fetched successfully." ,
@@ -47,6 +49,7 @@ const gallery = async (req, res) => {
47
49
. skip ( ( page - 1 ) * limit )
48
50
. limit ( limit ) ;
49
51
52
+ res . set ( 'Content-Type' , 'application/json' ) ;
50
53
return res . status ( 200 ) . json ( {
51
54
status : "success" ,
52
55
message : "Arts fetched successfully." ,
@@ -90,6 +93,8 @@ const userArts = async (req, res) => {
90
93
. populate ( "theme" )
91
94
. skip ( ( page - 1 ) * limit )
92
95
. limit ( limit ) ;
96
+
97
+ res . set ( 'Content-Type' , 'application/json' ) ;
93
98
return res . status ( 200 ) . json ( {
94
99
status : "success" ,
95
100
message : "Arts fetched successfully." ,
@@ -127,6 +132,8 @@ const themeArts = async (req, res) => {
127
132
const arts = await Art . find ( { theme : theme . _id } )
128
133
. skip ( ( page - 1 ) * limit )
129
134
. limit ( limit ) ;
135
+
136
+ res . set ( 'Content-Type' , 'application/json' ) ;
130
137
return res . status ( 200 ) . json ( {
131
138
status : "success" ,
132
139
message : "Arts fetched successfully." ,
@@ -160,6 +167,8 @@ const show = async (req, res) => {
160
167
message : "Art not found." ,
161
168
} ) ;
162
169
}
170
+
171
+ res . set ( 'Content-Type' , 'application/json' ) ;
163
172
return res . status ( 200 ) . json ( {
164
173
status : "success" ,
165
174
message : "Art fetched successfully." ,
@@ -197,6 +206,7 @@ const like = async (req, res) => {
197
206
art . likedBy = art . likedBy . filter ( id => id . toString ( ) !== userId ) ;
198
207
art . likes = art . likedBy . length ;
199
208
await art . save ( ) ;
209
+ res . set ( 'Content-Type' , 'application/json' ) ;
200
210
res . status ( 200 ) . send ( {
201
211
message : 'Art unliked successfully' ,
202
212
likes : art . likes ,
@@ -205,6 +215,7 @@ const like = async (req, res) => {
205
215
art . likedBy . push ( userId ) ;
206
216
art . likes = art . likedBy . length ;
207
217
await art . save ( ) ;
218
+ res . set ( 'Content-Type' , 'application/json' ) ;
208
219
res . status ( 200 ) . send ( {
209
220
message : 'Art liked successfully' ,
210
221
likes : art . likes ,
@@ -219,19 +230,39 @@ const like = async (req, res) => {
219
230
}
220
231
} ;
221
232
233
+ const convertBase64ToBuffer = ( base64String ) => {
234
+ // Remove data:image/jpeg;base64, if present
235
+ const base64Data = base64String . replace ( / ^ d a t a : i m a g e \/ \w + ; b a s e 6 4 , / , '' ) ;
236
+ return Buffer . from ( base64Data , 'base64' ) ;
237
+ } ;
238
+
222
239
const model = async ( req , res ) => {
223
240
try {
224
- if ( ! req . files || ! Object . hasOwn ( req . files , "content_image" ) || ! Object . hasOwn ( req . files , "style_image" ) ) {
241
+ const contentImage = req . files ?. content_image ?. [ 0 ] || req . body . content_image ;
242
+ const styleImage = req . files ?. style_image ?. [ 0 ] || req . body . style_image ;
243
+
244
+ if ( ! contentImage || ! styleImage ) {
225
245
return res . status ( 400 ) . json ( {
226
246
status : "error" ,
227
- message : "Image is required." ,
247
+ message : "Both content and style images are required." ,
228
248
} ) ;
229
249
}
230
250
231
- const styled_image = await stylizeImages ( req . files [ "content_image" ] [ 0 ] , req . files [ "style_image" ] [ 0 ] ) ;
251
+ const contentBuffer = contentImage . buffer || convertBase64ToBuffer ( contentImage ) ;
252
+ const styleBuffer = styleImage . buffer || convertBase64ToBuffer ( styleImage ) ;
253
+
254
+ const contentImageObj = { buffer : contentBuffer } ;
255
+ const styleImageObj = { buffer : styleBuffer } ;
232
256
233
- res . set ( 'Content-Type' , 'image/jpeg' ) ;
234
- res . status ( 201 ) . send ( styled_image ) ;
257
+ const styled_image = await stylizeImages ( contentImageObj , styleImageObj ) ;
258
+ const base64Image = `data:image/jpeg;base64,${ styled_image . toString ( 'base64' ) } ` ;
259
+
260
+ res . set ( 'Content-Type' , 'application/json' ) ;
261
+ return res . status ( 201 ) . json ( {
262
+ status : "success" ,
263
+ message : "Image styled successfully" ,
264
+ image : base64Image
265
+ } ) ;
235
266
236
267
} catch ( e ) {
237
268
console . log ( e ) ;
@@ -245,73 +276,77 @@ const model = async (req, res) => {
245
276
246
277
const create = async ( req , res ) => {
247
278
try {
248
- let { title, description, theme } = await req . body ;
279
+ let { title, description, theme, image } = req . body ;
280
+
249
281
if ( ! theme ) {
250
282
return res . status ( 400 ) . json ( {
251
283
status : "error" ,
252
284
message : "Theme is required." ,
253
285
} ) ;
254
286
}
255
- if ( ! req . file ) {
287
+
288
+ if ( ! image ) {
256
289
return res . status ( 400 ) . json ( {
257
290
status : "error" ,
258
- message : "Image is required." ,
291
+ message : "Image (base64) is required." ,
259
292
} ) ;
260
293
}
294
+
261
295
if ( ! title || ! description ) {
262
296
return res . status ( 400 ) . json ( {
263
297
status : "error" ,
264
298
message : "Title and Description are required." ,
265
299
} ) ;
266
300
}
267
- theme = await Theme . findOne ( { slug : theme } ) ;
268
- if ( ! theme ) {
269
- return res . status ( 404 ) . json ( {
270
- status : "error" ,
271
- message : "Theme not found." ,
301
+
302
+ // Find or create theme
303
+ let themeDoc = await Theme . findOne ( { slug : slugify ( theme ) } ) ;
304
+ if ( ! themeDoc ) {
305
+ themeDoc = await Theme . create ( {
306
+ name : theme ,
307
+ slug : slugify ( theme ) ,
308
+ description : `User defined theme: ${ theme } ` ,
309
+ createdBy : req . user . id
272
310
} ) ;
273
311
}
312
+
274
313
let slug = slugify ( title ) ;
275
314
let i = 0 ;
276
315
while ( await Art . findOne ( { slug : slug } ) ) {
277
316
slug = slugify ( title , ++ i ) ;
278
317
}
279
318
280
- let image = "" ;
281
- if ( req . file ) {
282
- let oldFilename = req . file . filename ;
283
- let extension = oldFilename . split ( "." ) [ oldFilename . split ( "." ) . length - 1 ] ;
284
- image = slug + "." + extension ;
285
- fs . rename (
286
- req . file . path ,
287
- req . file . destination + "/" + image ,
288
- function ( err ) {
289
- if ( err ) {
290
- throw new Error ( "Error renaming file. Error: " + err ) ;
291
- }
292
- }
293
- ) ;
294
- image = "/images/arts/" + theme . slug + "/" + image ;
319
+ // Ensure directory exists
320
+ const uploadDir = path . join ( 'public/images/arts' , themeDoc . slug ) ;
321
+ if ( ! fs . existsSync ( uploadDir ) ) {
322
+ fs . mkdirSync ( uploadDir , { recursive : true } ) ;
295
323
}
296
324
297
- theme = theme . id ;
298
- const artist = req . user . id ;
325
+ // Save base64 image
326
+ const filename = `${ slug } .jpg` ;
327
+ const filePath = path . join ( uploadDir , filename ) ;
328
+
329
+ // Convert base64 to buffer and save
330
+ const base64Data = image . replace ( / ^ d a t a : i m a g e \/ \w + ; b a s e 6 4 , / , '' ) ;
331
+ fs . writeFileSync ( filePath , Buffer . from ( base64Data , 'base64' ) ) ;
332
+
333
+ // Create database entry
299
334
const art = await Art . create ( {
300
335
title,
301
336
description,
302
- theme,
303
- image,
304
- artist,
337
+ theme : themeDoc . id ,
338
+ image : `/images/arts/ ${ themeDoc . slug } / ${ filename } ` ,
339
+ artist : req . user . id ,
305
340
slug,
306
341
} ) ;
342
+
307
343
return res . status ( 201 ) . json ( {
308
344
status : "success" ,
309
345
message : "Art created successfully." ,
310
346
art : art ,
311
347
} ) ;
312
348
} catch ( e ) {
313
349
console . log ( e ) ;
314
-
315
350
return res . status ( 500 ) . json ( {
316
351
status : "error" ,
317
352
message : "Something went wrong." ,
@@ -351,6 +386,8 @@ const edit = async (req, res) => {
351
386
art . title = title ;
352
387
art . description = description ;
353
388
await art . save ( ) ;
389
+
390
+ res . set ( 'Content-Type' , 'application/json' ) ;
354
391
return res . status ( 200 ) . json ( {
355
392
status : "success" ,
356
393
message : "Art updated successfully." ,
@@ -388,6 +425,7 @@ const remove = async (req, res) => {
388
425
}
389
426
await Art . findOneAndDelete ( { slug } ) ;
390
427
428
+ res . set ( 'Content-Type' , 'application/json' ) ;
391
429
return res . status ( 200 ) . json ( {
392
430
status : "success" ,
393
431
message : "Art removed successfully." ,
@@ -426,6 +464,7 @@ const publish = async (req, res) => {
426
464
art . published = ! art . published ;
427
465
await art . save ( ) ;
428
466
467
+ res . set ( 'Content-Type' , 'application/json' ) ;
429
468
return res . status ( 200 ) . json ( {
430
469
status : "success" ,
431
470
message : "Art published/unpublished successfully." ,
0 commit comments