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

Feature/backend scanner #55

Merged
merged 6 commits into from
Feb 4, 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
15 changes: 15 additions & 0 deletions backend/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: "3"

services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: rethread
ports:
- "3306:3306"
volumes:
- mysql:/var/lib/mysql

volumes:
mysql:
Binary file removed backend/eng.traineddata
Binary file not shown.
26 changes: 7 additions & 19 deletions backend/src/abstracts/product.abstract.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
type PrismaProduct = {
id: string;
title: string;
size: string;
color: string;
description: string;
gender: string;
category: string;
price: number;
imageUrl: string;
createdAt: Date;
updatedAt: Date;
};

type PrismaProducts = PrismaProduct[];
import { PrismaProduct, PrismaProducts } from "../../types";

abstract class ProductProvider {
abstract getProducts(): Promise<PrismaProducts | Error>;
abstract getProducts(): Promise<PrismaProducts>;

abstract getProductById(id: string): Promise<PrismaProduct | Error>;
abstract getProductById(id: string): Promise<PrismaProduct>;

abstract createProduct(
title: string,
Expand All @@ -29,7 +15,9 @@ abstract class ProductProvider {
price: number,
imageUrl: string,
url: string
): Promise<PrismaProduct | Error>;
): Promise<PrismaProduct>;

abstract deleteProduct(id: string): Promise<PrismaProduct | Error>;
abstract deleteProduct(id: string): Promise<PrismaProduct>;
}

export default ProductProvider;
9 changes: 9 additions & 0 deletions backend/src/abstracts/scanner.abstract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Tag } from "../../types";

abstract class ScannerProvider {
abstract getMaterials(text: string): Tag[];

abstract getTextFromImage(imagePath: string): Promise<string>;
}

export default ScannerProvider;
32 changes: 0 additions & 32 deletions backend/src/controllers/algorithm.controller.ts

This file was deleted.

14 changes: 9 additions & 5 deletions backend/src/controllers/product.controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { PrismaProduct } from "../../types";
import ProductProvider from "../abstracts/product.abstract";
import { Request, Response, NextFunction } from "express";

class ProductController {
constructor(private service: ProductProvider) {
this.service = service;
}

getProducts = async (
public getProducts = async (
req: Request,
res: Response,
next: NextFunction
Expand All @@ -18,20 +20,22 @@ class ProductController {
}
};

getProductById = async (
public getProductById = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
try {
const product = await this.service.getProductById(req.params.id);
const product: PrismaProduct = await this.service.getProductById(
req.params.id
);
return res.status(200).json(product);
} catch (e) {
next(e);
}
};

postProduct = async (
public postProduct = async (
req: Request,
res: Response,
next: NextFunction
Expand All @@ -54,7 +58,7 @@ class ProductController {
}
};

deleteProduct = async (
public deleteProduct = async (
req: Request,
res: Response,
next: NextFunction
Expand Down
41 changes: 18 additions & 23 deletions backend/src/controllers/scanner.controller.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
import { Request, Response, NextFunction, response } from "express";
import ScannerService from "../services/scanner.service.js";
import { Tag } from "../../types.js";
import ScannerProvider from "../abstracts/scanner.abstract.js";
import { Request, Response, NextFunction } from "express";

class ScannerController {
constructor(private service: ScannerService) {
this.service = service;
}
postMaterials = async (//must send image as tag "image" and value base64 string. Returns JSON with the percentage and material of each material found on the tag
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
constructor(private service: ScannerProvider) {
this.service = service;
}

public postMaterials = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
try {
console.log("postMaterials called");
let materials = await (async () => {
var str;
str = await this.service.getMaterials(await this.service.getTextFromImage(req.body.image));
// console.log("Fuck: ", await str);
return str;
})();
console.log("materials: ",materials);
return res.status(201).json(JSON.parse(materials));
const text: string = await this.service.getTextFromImage(req.body.image);
const materials: Tag[] = this.service.getMaterials(text);
return res.status(201).json(materials);
} catch (e) {
console.log("Error: ", e);
next(e);
next(e);
}
};
};
}

export default ScannerController;
export default ScannerController;
1 change: 1 addition & 0 deletions backend/src/errors/tesseract.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class TesseractServiceError extends Error {}
5 changes: 1 addition & 4 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ import cors from "cors";
import { PORT } from "./config/config.js";
import errorHandler from "./middlewares/error.middleware.js";
import { PrismaClient } from "@prisma/client";
import algorithmRouter from "./routes/algorithm.routes.js";
import productRouter from "./routes/product.routes.js";
import scannerRouter from "./routes/scanner.routes.js";

export const app: Express = express();
export const prisma = new PrismaClient();

app.use(express.json({ limit: '50mb' }));
app.use(express.json({ limit: "50mb" }));

app.use(cors());

app.use("/api/v1/scanner", scannerRouter);

app.use("/api/v1/algorithm", algorithmRouter);

app.use("/api/v1/products", productRouter);

app.use(errorHandler);
Expand Down
6 changes: 5 additions & 1 deletion backend/src/middlewares/error.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import {
PrismaGenericError,
} from "../errors/prisma.error.js";
import { ProductNotFoundError } from "../errors/product.error.js";
import { TesseractServiceError } from "../errors/tesseract.error.js";

export default function errorHandler(
e: Error,
req: Request,
_: Request,
res: Response,
next: NextFunction
) {
Expand All @@ -39,6 +41,8 @@ export default function errorHandler(
res.status(500).json({ error: "Prisma Generic Error" });
} else if (e instanceof ProductNotFoundError) {
res.status(500).json({ error: "Product Not Found Error" });
} else if (e instanceof TesseractServiceError) {
res.status(500).json({ error: "Tesseract Service Error" });
} else {
res.status(500).json({ error: "Unexpected error" });
}
Expand Down
12 changes: 7 additions & 5 deletions backend/src/repositories/product.repository.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import ProductProvider from "../abstracts/product.abstract.js";
import { prisma } from "../index.js";
import { Prisma } from "@prisma/client";
import { ProductNotFoundError } from "../errors/product.error.js";
import { PrismaProduct, PrismaProducts } from "../../types.js";
import {
PrismaClientInitializationError,
PrismaClientRustPanicError,
Expand All @@ -10,7 +12,7 @@ import {
} from "../errors/prisma.error.js";

class ProductRepository implements ProductProvider {
getProducts = async (): Promise<PrismaProducts | Error> => {
public getProducts = async (): Promise<PrismaProducts> => {
try {
const products: PrismaProducts = await prisma.product.findMany();
return products;
Expand All @@ -31,7 +33,7 @@ class ProductRepository implements ProductProvider {
}
};

getProductById = async (id: string): Promise<PrismaProduct | Error> => {
public getProductById = async (id: string): Promise<PrismaProduct> => {
try {
const product: PrismaProduct | null = await prisma.product.findUnique({
where: { id: id },
Expand Down Expand Up @@ -59,7 +61,7 @@ class ProductRepository implements ProductProvider {
}
};

createProduct = async (
public createProduct = async (
title: string,
size: string,
color: string,
Expand All @@ -68,7 +70,7 @@ class ProductRepository implements ProductProvider {
category: string,
price: number,
imageUrl: string
): Promise<PrismaProduct | Error> => {
): Promise<PrismaProduct> => {
try {
const newProduct: PrismaProduct = await prisma.product.create({
data: {
Expand Down Expand Up @@ -100,7 +102,7 @@ class ProductRepository implements ProductProvider {
}
};

deleteProduct = async (id: string): Promise<PrismaProduct | Error> => {
public deleteProduct = async (id: string): Promise<PrismaProduct> => {
try {
const product: PrismaProduct | null = await prisma.product.delete({
where: { id: id },
Expand Down
23 changes: 23 additions & 0 deletions backend/src/repositories/scanner.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createWorker } from "tesseract.js";
import { Tag } from "../../types.js";
import ScannerProvider from "../abstracts/scanner.abstract.js";
import { TesseractServiceError } from "../errors/tesseract.error.js";

class ScannerRepository implements ScannerProvider {
public getMaterials = (_: string): Tag[] => {
throw new Error("Method not implemented.");
};

public getTextFromImage = async (imagePath: string): Promise<string> => {
try {
const worker: Tesseract.Worker = await createWorker("eng");
const ret: Tesseract.RecognizeResult = await worker.recognize(imagePath);
await worker.terminate();
return ret.data.text;
} catch (e) {
throw new TesseractServiceError();
}
};
}

export default ScannerRepository;
16 changes: 0 additions & 16 deletions backend/src/routes/algorithm.routes.ts

This file was deleted.

2 changes: 1 addition & 1 deletion backend/src/routes/product.routes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Router } from "express";
import ProductController from "../controllers/product.controller.js";
import ProductService from "../services/product.service.js";
import ProductRepository from "../repositories/product.repository.js";
import { Router } from "express";

const productRouter = Router();
const productController = new ProductController(
Expand Down
10 changes: 6 additions & 4 deletions backend/src/routes/scanner.routes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Router } from "express";
import ScannerController from "../controllers/scanner.controller.js";
import ScannerService from "../services/scanner.service.js";
import ScannerRepository from "../repositories/scanner.repository.js";
import { Router } from "express";

const scannerRouter = Router();

const scannerController = new ScannerController(new ScannerService());
const scannerController = new ScannerController(
new ScannerService(new ScannerRepository())
);

scannerRouter.post("/", scannerController.postMaterials);

export default scannerRouter;
export default scannerRouter;
22 changes: 0 additions & 22 deletions backend/src/services/algorithm.service.ts

This file was deleted.

Loading
Loading