Skip to content

Commit

Permalink
Merge pull request #55 from techstartucalgary/feature/backend-scanner
Browse files Browse the repository at this point in the history
Feature/backend scanner
  • Loading branch information
Axeloooo authored Feb 4, 2024
2 parents 55d0470 + abb239e commit 3b98dc4
Show file tree
Hide file tree
Showing 20 changed files with 163 additions and 206 deletions.
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

0 comments on commit 3b98dc4

Please sign in to comment.