Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

類似度出すとこリファクタリング #53

Merged
merged 6 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 53 additions & 53 deletions app/src/app/api/image/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,74 @@ import type { NextRequest } from "next/server";
import { OpenAI } from "openai";

type ResponseData = {
message: string;
message: string;
};

const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
apiKey: process.env.OPENAI_API_KEY,
});

const BUCKET_NAME = "kz2404";

export async function GET(
req: NextRequest,
res: NextApiResponse<ResponseData>
req: NextRequest,
res: NextApiResponse<ResponseData>,
) {
// クエリパラメータを取得
// クエリパラメータを取得
const { searchParams } = new URL(req.url || "");
const imageName = searchParams.get("imageName") || "default-image-name";
const imageURL = `${process.env.NEXT_PUBLIC_MINIO_ENDPOINT}${BUCKET_NAME}/${imageName}`;
const imageURL = `${process.env.NEXT_PUBLIC_MINIO_ENDPOINT}${BUCKET_NAME}/${imageName}`;

return await generateCaption(imageURL)
.then((caption) => {
console.log(caption);
return new Response(JSON.stringify({ caption }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
})
.catch((error) => {
console.error("Error generating caption:", error);
return new Response(JSON.stringify({ message: "エラーが発生しました" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
});
return await generateCaption(imageURL)
.then((caption) => {
console.log(caption);
return new Response(JSON.stringify({ caption }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
})
.catch((error) => {
console.error("Error generating caption:", error);
return new Response(JSON.stringify({ message: "エラーが発生しました" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
});
}

// 画像URLからキャプションを生成する関数
const generateCaption = async (imageUrl: string) => {
try {
const completion = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{
role: "system",
content: [
{
type: "text",
text: "A robot that can generate very short captions for images.",
},
],
},
{
role: "user",
content: [
{
type: "image_url",
image_url: {
url: imageUrl,
detail: "low",
},
},
],
},
],
});
try {
const completion = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{
role: "system",
content: [
{
type: "text",
text: "A robot that can generate very short captions for images.",
},
],
},
{
role: "user",
content: [
{
type: "image_url",
image_url: {
url: imageUrl,
detail: "low",
},
},
],
},
],
});

const caption = await completion.choices[0].message.content;
return caption;
} catch (error) {
console.error("Error generating caption:", error);
}
const caption = await completion.choices[0].message.content;
return caption;
} catch (error) {
console.error("Error generating caption:", error);
}
};
179 changes: 115 additions & 64 deletions app/src/app/api/minio/route.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,127 @@
import fs from 'fs';
import { formidable, IncomingForm } from 'formidable';
import * as fs from "node:fs";
import type { IncomingMessage } from "node:http";
import { Readable } from "node:stream";
import { generateCaption } from "@/functions/gpt";
import { scoreRegister } from "@/functions/scoreRegister";
import { shapeCaption } from "@/functions/shapeCaption";
import { postSimilarity } from "@/functions/simirality";
import { prisma } from "@/lib/prisma";
import type { ScoreData, ScoreResponse } from "@/types";
import { formidable } from "formidable";
import { Client } from "minio";
import type { NextRequest } from "next/server";
import type { IncomingMessage } from 'http';
import { Readable } from 'stream';
import { Client } from 'minio';

const minioClient = new Client({
endPoint: process.env.NEXT_PUBLIC_ENDPOINT || '',
port: Number(process.env.NEXT_PUBLIC_PORT),
accessKey: process.env.NEXT_PUBLIC_ACCESS_KEY || '',
secretKey: process.env.NEXT_PUBLIC_SECRET_KEY || '',
useSSL: false,
endPoint: process.env.NEXT_PUBLIC_ENDPOINT || "",
port: Number(process.env.NEXT_PUBLIC_PORT),
accessKey: process.env.NEXT_PUBLIC_ACCESS_KEY || "",
secretKey: process.env.NEXT_PUBLIC_SECRET_KEY || "",
useSSL: false,
});

const BUCKET_NAME = 'kz2404';
const BUCKET_NAME = "kz2404";

// NextRequestをIncomingMessageのようにラップする関数
function toIncomingMessage(request: NextRequest): IncomingMessage {
const readable = new Readable({
read() {
request.body?.getReader().read().then(({ done, value }) => {
if (done) {
this.push(null);
} else {
this.push(Buffer.from(value));
}
});
},
});

const msg = Object.assign(readable, {
headers: Object.fromEntries(request.headers),
method: request.method,
url: request.nextUrl.pathname,
});

return msg as IncomingMessage;
}
const readable = new Readable({
read() {
request.body
?.getReader()
.read()
.then(({ done, value }) => {
if (done) {
this.push(null);
} else {
this.push(Buffer.from(value));
}
});
},
});

const msg = Object.assign(readable, {
headers: Object.fromEntries(request.headers),
method: request.method,
url: request.nextUrl.pathname,
});

return msg as IncomingMessage;
}

export async function POST(req: NextRequest) {
const form = formidable();
const incomingMessage = toIncomingMessage(req);

form.parse(incomingMessage, async (err: any, fields: any, files: any) => {
if (err) {
throw new Error('Error parsing form');
}
const image = files.image[0];
const mimetype = image.type;
const metaData = {
'Content-Type': mimetype
};

try {
await minioClient.putObject(
BUCKET_NAME,
image.originalFilename,
fs.createReadStream(image.filepath),
image.size,
metaData,
);
} catch (err) {
return new Response(JSON.stringify({ message: '失敗' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
});

return new Response(JSON.stringify({ message: "成功" }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
const form = formidable();
const incomingMessage = toIncomingMessage(req);

const { searchParams } = new URL(req.url || "");
const fileName = searchParams.get("file") || "";
const assignment = searchParams.get("assignment") || "";
const uid = searchParams.get("uid") || "";
const assignmentId = Number(searchParams.get("assignmentId") || 0);

form.parse(incomingMessage, async (err: Error | null, _, files: any) => {
if (err || !files.image) {
throw new Error("Error parsing form");
}
const image = files.image[0];
const mimetype = image.type;
const metaData = {
"Content-Type": mimetype,
};

try {
await minioClient.putObject(
BUCKET_NAME,
image.originalFilename,
fs.createReadStream(image.filepath),
image.size,
metaData,
);
} catch (err) {
return new Response(JSON.stringify({ message: "失敗" }), {
status: 400,
headers: { "Content-Type": "application/json" },
});
}
});

const imageURL = `${process.env.NEXT_PUBLIC_MINIO_ENDPOINT}${BUCKET_NAME}/${fileName}`;

// キャプション生成
const caption = await generateCaption(imageURL);

// 類似度分割
const words: string[] = shapeCaption(caption || "");

// 類似度計算
const resSimilarity: { similarity: number } = await postSimilarity(
assignment,
words,
);

const user = await prisma.user.findUnique({
where: {
uid: uid,
},
});

const scoreData: ScoreData = {
similarity: resSimilarity.similarity,
answerTime: new Date(),
imageUrl: imageURL,
assignmentId: assignmentId,
userId: user?.id || 0,
};

const score = await scoreRegister(scoreData);

const response: ScoreResponse = {
text: caption || "",
score: score?.point || 0,
similarity: resSimilarity.similarity,
assignmentId: assignmentId,
};

return new Response(JSON.stringify(response), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
Loading
Loading