Skip to content

Commit 59ec02e

Browse files
Merge pull request #83 from abhitrueprogrammer/staging
enhance: add fuzzy and regex finding to make ai results correspond to ones that we have in our dbs
2 parents 6baab2e + c7b38ab commit 59ec02e

File tree

4 files changed

+57
-49
lines changed

4 files changed

+57
-49
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"cmdk": "1.0.0",
3939
"debounce": "^2.1.1",
4040
"file-saver": "^2.0.5",
41+
"fuse.js": "^7.0.0",
4142
"geist": "^1.3.0",
4243
"gridfs-stream": "^1.1.1",
4344
"jose": "^5.4.1",

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/api/ai-upload/route.ts

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import { NextResponse } from "next/server";
22
import { PDFDocument } from "pdf-lib";
3-
import { campuses, exams, semesters, slots, years } from "@/components/select_options";
3+
import {
4+
campuses,
5+
exams,
6+
semesters,
7+
slots,
8+
years,
9+
} from "@/components/select_options";
410
import { connectToDatabase } from "@/lib/mongoose";
511
import cloudinary from "cloudinary";
612
import { type ICourses, type CloudinaryUploadResult } from "@/interface";
713
import { PaperAdmin } from "@/db/papers";
814
import axios from "axios";
915
import processAndAnalyze from "@/util/mistral";
1016
import { examMap } from "./map";
17+
import Fuse from "fuse.js";
1118
// import processAndAnalyze from "./mistral";
1219
// TODO: REMOVE THUMBNAIL FROM admin-buffer DB
1320
cloudinary.v2.config({
@@ -26,57 +33,54 @@ export async function POST(req: Request) {
2633
const files: File[] = formData.getAll("files") as File[];
2734
const isPdf = formData.get("isPdf") === "true"; // Convert string to boolean
2835

29-
let imageURL = ""
30-
if(isPdf)
31-
{
32-
imageURL = formData.get("image") as string
33-
}
34-
else
35-
{
36+
let imageURL = "";
37+
if (isPdf) {
38+
imageURL = formData.get("image") as string;
39+
} else {
3640
const bytes = await files[0]?.arrayBuffer();
3741
if (bytes) {
3842
const buffer = await Buffer.from(bytes);
3943
imageURL = `data:${"image/png"};base64,${buffer.toString("base64")}`;
40-
41-
}
42-
}
43-
const tags = await processAndAnalyze({imageURL})
44-
let subject = ""
45-
let slot = ""
46-
let exam = ""
47-
let year = ""
48-
let campus = ""
49-
let semester = ""
50-
51-
if(!tags)
52-
{
53-
console.log("Anaylsis failed, inputing blank strings as fields")
54-
}
55-
else{
56-
subject = tags["course-name"]
57-
slot = tags.slot
58-
if("exam-type" in tags && tags["exam-type"] in examMap)
59-
{
60-
const examType = tags["exam-type"] as keyof typeof examMap;
61-
exam = examMap[examType];
62-
63-
}
64-
year = formData.get("year") as string;
65-
campus = formData.get("campus") as string;
66-
semester = formData.get("semester") as string;
67-
44+
}
6845
}
69-
console.log(exam, slot, subject)
70-
71-
const { data } = await axios.get<ICourses[]>(`${process.env.SERVER_URL}/api/course-list`);
46+
const tags = await processAndAnalyze({ imageURL });
47+
let subject = "";
48+
let slot = "";
49+
let exam = "";
50+
let year = "";
51+
let campus = "";
52+
let semester = "";
53+
const { data } = await axios.get<ICourses[]>(
54+
`${process.env.SERVER_URL}/api/course-list`,
55+
);
7256
const courses = data.map((course: { name: string }) => course.name);
57+
const coursesFuzy = new Fuse(courses);
58+
if (!tags) {
59+
console.log("Anaylsis failed, inputing blank strings as fields");
60+
} else {
61+
const subjectSearch = coursesFuzy.search(tags["course-name"])[0];
62+
if (subjectSearch) {
63+
subject = subjectSearch.item;
64+
}
65+
const slotPattern = new RegExp(`[${tags.slot}]`, "i");
66+
const slotSearchResult = slots.find((s) => slotPattern.test(s));
67+
slot = slotSearchResult ? slotSearchResult : tags.slot;
68+
if ("exam-type" in tags && tags["exam-type"] in examMap) {
69+
const examType = tags["exam-type"] as keyof typeof examMap;
70+
exam = examMap[examType];
71+
}
72+
year = formData.get("year") as string;
73+
campus = formData.get("campus") as string;
74+
semester = formData.get("semester") as string;
75+
}
76+
console.log(exam, slot, subject);
7377

7478
if (
7579
!(
7680
exam.includes(exam) &&
7781
years.includes(year) &&
7882
campuses.includes(campus) &&
79-
semesters.includes(semester)
83+
semesters.includes(semester)
8084
)
8185
) {
8286
return NextResponse.json({ message: "Bad request" }, { status: 400 });
@@ -93,9 +97,8 @@ export async function POST(req: Request) {
9397
{ status: 400 },
9498
);
9599
}
96-
97-
if (!isPdf) {
98100

101+
if (!isPdf) {
99102
try {
100103
if (!process.env.NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET) {
101104
return;
@@ -135,7 +138,7 @@ export async function POST(req: Request) {
135138
year,
136139
exam,
137140
campus,
138-
semester
141+
semester,
139142
});
140143
await paper.save();
141144
return NextResponse.json(
@@ -167,7 +170,6 @@ async function uploadFile(
167170
fileType: string,
168171
) {
169172
try {
170-
171173
const buffer = Buffer.from(bytes);
172174
const dataUrl = `data:${fileType};base64,${buffer.toString("base64")}`;
173175
const uploadResult = (await cloudinary.v2.uploader.unsigned_upload(
@@ -182,7 +184,7 @@ async function uploadFile(
182184

183185
async function CreatePDF(files: File[]) {
184186
const pdfDoc = await PDFDocument.create();
185-
//sort files using name. Later remove to see if u can without names
187+
//sort files using name. Later remove to see if u can without names
186188
const orderedFiles = Array.from(files).sort((a, b) => {
187189
return a.name.localeCompare(b.name);
188190
});

src/util/mistral.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import '@ungap/with-resolvers';
2-
import { PDFDocument, } from "pdf-lib";
3-
import { getDocument, GlobalWorkerOptions, version } from "pdfjs-dist";
4-
52

63

74
import { Mistral } from "@mistralai/mistralai";
85

9-
import { createCanvas } from "canvas";
106
// Type definitions
117
type ExamDetail = {
128
"course-name": string;

0 commit comments

Comments
 (0)