Skip to content

Commit 9a16736

Browse files
committed
fix: minor fixes and changes for image
1 parent fdee538 commit 9a16736

File tree

6 files changed

+135
-36
lines changed

6 files changed

+135
-36
lines changed

art-gallery/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Use platform-specific base image
2-
FROM --platform=linux/arm64 node:18
2+
FROM node:18
33

44
# Set working directory
55
WORKDIR /usr/src/app

art-gallery/app.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,38 @@ if (process.env.NODE_ENV !== "production") {
44
const express = require("express");
55
const routes = require("./routes/routes");
66
const mongoose = require("mongoose");
7+
const cors = require('cors');
8+
const multer = require('multer');
79

810
const port = 8000;
911
const app = express();
10-
app.use(express.urlencoded({ extended: false }));
12+
app.use(cors({
13+
origin: "*",
14+
credentials: true
15+
}));
16+
17+
app.use(express.json({limit: '150mb'}));
18+
app.use(express.urlencoded({limit: '150mb'}));
19+
app.use(express.urlencoded({ extended: true }));
1120
app.use(express.json());
21+
22+
// Increase the request size limit for multer
23+
const upload = multer({ limits: { fileSize: 150 * 1024 * 1024 } });
1224
//static serves
1325
app.use("/images", express.static(process.cwd() + "/public/uploads"));
1426
app.use("/default", express.static(process.cwd() + "/public/placeholders"));
1527

28+
const testCORS = async () => {
29+
try {
30+
const response = await fetch('http://localhost:8000/test-cors', {
31+
credentials: 'include'
32+
});
33+
const data = await response.json();
34+
console.log(data);
35+
} catch (error) {
36+
console.error('CORS Error:', error);
37+
}
38+
}
1639
// Database connection
1740
mongoose
1841
.connect(process.env.DATABASE)

art-gallery/app/controllers/art.controller.js

+73-34
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const Art = require("../../models/art");
22
const Theme = require("../../models/theme");
33
const User = require("../../models/user");
44
const fs = require("fs");
5+
const path = require('path'); // Add this line
56
const slugify = require("../utils/slugify");
67
const stylizeImages = require("../utils/style-transfer");
78

@@ -18,6 +19,7 @@ const index = async (req, res) => {
1819
.skip((page - 1) * limit)
1920
.limit(limit);
2021

22+
res.set('Content-Type', 'application/json');
2123
return res.status(200).json({
2224
status: "success",
2325
message: "Arts fetched successfully.",
@@ -47,6 +49,7 @@ const gallery = async (req, res) => {
4749
.skip((page - 1) * limit)
4850
.limit(limit);
4951

52+
res.set('Content-Type', 'application/json');
5053
return res.status(200).json({
5154
status: "success",
5255
message: "Arts fetched successfully.",
@@ -90,6 +93,8 @@ const userArts = async (req, res) => {
9093
.populate("theme")
9194
.skip((page - 1) * limit)
9295
.limit(limit);
96+
97+
res.set('Content-Type', 'application/json');
9398
return res.status(200).json({
9499
status: "success",
95100
message: "Arts fetched successfully.",
@@ -127,6 +132,8 @@ const themeArts = async (req, res) => {
127132
const arts = await Art.find({ theme: theme._id })
128133
.skip((page - 1) * limit)
129134
.limit(limit);
135+
136+
res.set('Content-Type', 'application/json');
130137
return res.status(200).json({
131138
status: "success",
132139
message: "Arts fetched successfully.",
@@ -160,6 +167,8 @@ const show = async (req, res) => {
160167
message: "Art not found.",
161168
});
162169
}
170+
171+
res.set('Content-Type', 'application/json');
163172
return res.status(200).json({
164173
status: "success",
165174
message: "Art fetched successfully.",
@@ -197,6 +206,7 @@ const like = async (req, res) => {
197206
art.likedBy = art.likedBy.filter(id => id.toString() !== userId);
198207
art.likes = art.likedBy.length;
199208
await art.save();
209+
res.set('Content-Type', 'application/json');
200210
res.status(200).send({
201211
message: 'Art unliked successfully',
202212
likes: art.likes,
@@ -205,6 +215,7 @@ const like = async (req, res) => {
205215
art.likedBy.push(userId);
206216
art.likes = art.likedBy.length;
207217
await art.save();
218+
res.set('Content-Type', 'application/json');
208219
res.status(200).send({
209220
message: 'Art liked successfully',
210221
likes: art.likes,
@@ -219,19 +230,39 @@ const like = async (req, res) => {
219230
}
220231
};
221232

233+
const convertBase64ToBuffer = (base64String) => {
234+
// Remove data:image/jpeg;base64, if present
235+
const base64Data = base64String.replace(/^data:image\/\w+;base64,/, '');
236+
return Buffer.from(base64Data, 'base64');
237+
};
238+
222239
const model = async (req, res) => {
223240
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) {
225245
return res.status(400).json({
226246
status: "error",
227-
message: "Image is required.",
247+
message: "Both content and style images are required.",
228248
});
229249
}
230250

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 };
232256

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+
});
235266

236267
} catch (e) {
237268
console.log(e);
@@ -245,73 +276,77 @@ const model = async (req, res) => {
245276

246277
const create = async (req, res) => {
247278
try {
248-
let { title, description, theme } = await req.body;
279+
let { title, description, theme, image } = req.body;
280+
249281
if (!theme) {
250282
return res.status(400).json({
251283
status: "error",
252284
message: "Theme is required.",
253285
});
254286
}
255-
if (!req.file) {
287+
288+
if (!image) {
256289
return res.status(400).json({
257290
status: "error",
258-
message: "Image is required.",
291+
message: "Image (base64) is required.",
259292
});
260293
}
294+
261295
if (!title || !description) {
262296
return res.status(400).json({
263297
status: "error",
264298
message: "Title and Description are required.",
265299
});
266300
}
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
272310
});
273311
}
312+
274313
let slug = slugify(title);
275314
let i = 0;
276315
while (await Art.findOne({ slug: slug })) {
277316
slug = slugify(title, ++i);
278317
}
279318

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 });
295323
}
296324

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(/^data:image\/\w+;base64,/, '');
331+
fs.writeFileSync(filePath, Buffer.from(base64Data, 'base64'));
332+
333+
// Create database entry
299334
const art = await Art.create({
300335
title,
301336
description,
302-
theme,
303-
image,
304-
artist,
337+
theme: themeDoc.id,
338+
image: `/images/arts/${themeDoc.slug}/${filename}`,
339+
artist: req.user.id,
305340
slug,
306341
});
342+
307343
return res.status(201).json({
308344
status: "success",
309345
message: "Art created successfully.",
310346
art: art,
311347
});
312348
} catch (e) {
313349
console.log(e);
314-
315350
return res.status(500).json({
316351
status: "error",
317352
message: "Something went wrong.",
@@ -351,6 +386,8 @@ const edit = async (req, res) => {
351386
art.title = title;
352387
art.description = description;
353388
await art.save();
389+
390+
res.set('Content-Type', 'application/json');
354391
return res.status(200).json({
355392
status: "success",
356393
message: "Art updated successfully.",
@@ -388,6 +425,7 @@ const remove = async (req, res) => {
388425
}
389426
await Art.findOneAndDelete({ slug });
390427

428+
res.set('Content-Type', 'application/json');
391429
return res.status(200).json({
392430
status: "success",
393431
message: "Art removed successfully.",
@@ -426,6 +464,7 @@ const publish = async (req, res) => {
426464
art.published = !art.published;
427465
await art.save();
428466

467+
res.set('Content-Type', 'application/json');
429468
return res.status(200).json({
430469
status: "success",
431470
message: "Art published/unpublished successfully.",

art-gallery/app/middlewares/upload.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const multer = require('multer');
2+
const path = require('path');
3+
4+
const storage = multer.diskStorage({
5+
// ...existing storage configuration...
6+
});
7+
8+
const fileFilter = (req, file, cb) => {
9+
// ...existing filter configuration...
10+
};
11+
12+
// Updated multer configuration with limits
13+
const upload = multer({
14+
storage: storage,
15+
fileFilter: fileFilter,
16+
limits: {
17+
fileSize: 50 * 1024 * 1024, // 50MB in bytes
18+
files: 2 // Maximum number of files
19+
}
20+
});
21+
22+
module.exports = upload;

art-gallery/package-lock.json

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

art-gallery/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"@tensorflow/tfjs": "^4.22.0",
1313
"@tensorflow/tfjs-node": "^4.22.0",
1414
"bcrypt": "^5.1.1",
15+
"cors": "^2.8.5",
1516
"dotenv": "^16.4.5",
1617
"express": "^4.19.2",
1718
"jsonwebtoken": "^9.0.2",

0 commit comments

Comments
 (0)