diff --git a/.gitignore b/.gitignore index 336237b..73bfe95 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,6 @@ public/ .vscode/ package-lock.json bundle.js -mydb.sqlite +*.sqlite output/ resources/ \ No newline at end of file diff --git a/backend/app.ts b/backend/app.ts index df38962..c68f87c 100644 --- a/backend/app.ts +++ b/backend/app.ts @@ -22,4 +22,8 @@ app.use('/api', apiRouter); app.listen(httpPort, () => { console.log(`Server running at http://${hostname}:${httpPort}/`); -}); \ No newline at end of file +}); + +import mediaController from "./controllers/mediaController"; + +await mediaController.checkImages(); \ No newline at end of file diff --git a/backend/controllers/mediaController.ts b/backend/controllers/mediaController.ts index 8b5540e..00300f3 100644 --- a/backend/controllers/mediaController.ts +++ b/backend/controllers/mediaController.ts @@ -1,13 +1,16 @@ import { type Request, type Response } from "express"; import UserModel, { values } from '../models/userModel'; import MediaModel, { Table, Media } from '../models/mediaModel'; +import mediaModel from "../models/mediaModel"; -interface omdbRes{ +interface omdbRes { Title: string, Released: string, Response: string, Poster: string, - Type: string + Type: string, + ImdbID: string, + Year: string, } function fromStringToTable(value: string): (Table | undefined) { @@ -22,12 +25,13 @@ async function downloadImage(mData: Media, type: Table) { const outputPath = '/poster/' + type + '/' + mData.code + '.jpg'; // Use Bun's built-in fetch to download the image - const response = await fetch(mData.webImg); + const response = await fetch(mData.poster); // Check if the request was successful if (!response.ok) { console.log("fetch image error"); - return + console.log(mData.title); + return; } // Convert the response to a blob @@ -47,10 +51,6 @@ async function createMed(req: Request, res: Response) { return res.status(500).json({ message: 'Error when creating media' }); } - // remove the tt in front in DB its stored as number - const sub = mediaCode.substring(2); - const cleanCode = parseInt(sub); - try { const uri = `http://www.omdbapi.com/?i=${mediaCode}&apikey=${omdb_key}`; @@ -62,36 +62,32 @@ async function createMed(req: Request, res: Response) { } const media: Media = { - id:0, - code: cleanCode, + id: 0, + code: mData.ImdbID, title: mData.Title, released: mData.Released, - webImg: mData.Poster, + webImg: "", + poster: mData.Poster, + year: mData.Year }; - const seriesFound = MediaModel.findOne(Table.series, cleanCode); - if (seriesFound.length != 0) { - res.status(409).json({ message: 'Media already exists' }); - await downloadImage(media, Table.series); - return; - } - - const moviesFound = MediaModel.findOne(Table.movies, cleanCode); - if (moviesFound.length != 0) { - res.status(409).json({ message: 'Media already exists' }); - await downloadImage(media, Table.movies); - return; - } + var tableType = Table.series; if (mData.Type.localeCompare("movie") == 0) { - const savedMedia = MediaModel.save(Table.movies, cleanCode, mData.Title, mData.Released, mData.Poster); - await downloadImage(media, Table.movies); + tableType = Table.movies; } - else if (mData.Type.localeCompare("series") == 0) { - const savedMedia = MediaModel.save(Table.series, cleanCode, mData.Title, mData.Released, mData.Poster); - await downloadImage(media, Table.series); + + const found = MediaModel.findOne(tableType, mediaCode); + if (found.length != 0) { + res.status(409).json({ message: 'Media already exists' }); + await downloadImage(media, tableType); + return; } + + const savedMedia = MediaModel.save(tableType, "", mData.Title, mData.Released, mData.Poster, mData.ImdbID, mData.Year); + await downloadImage(media, tableType); + res.status(201).json(media); } catch (err) { return res.status(500).json({ message: 'Error when creating media' }); @@ -153,16 +149,18 @@ async function createGame(req: Request, res: Response) { } ) const coverData = await response.json() - const game: Media = { id: 0, code: gameCode, title: gameData[0].name, released: dateStr, - webImg: `https://images.igdb.com/igdb/image/upload/t_cover_big/${coverData[0].image_id}.jpg`, + webImg: "", + poster: `https://images.igdb.com/igdb/image/upload/t_cover_big/${coverData[0].image_id}.jpg`, + year: date.getFullYear().toString(), }; - const savedGame = MediaModel.save(Table.games, game.code, game.title, game.released, game.webImg); + const savedGame = MediaModel.save(Table.games, game.code, game.title, game.released, game.webImg, game.poster, game.year); + await downloadImage(game, Table.games); return res.status(201).json(game); } catch (error) { @@ -171,56 +169,77 @@ async function createGame(req: Request, res: Response) { } } +function list(req: Request, res: Response) { + const mediaTable = fromStringToTable(req.params.mediaType); + if (!mediaTable) { + return res.status(500).json({ + message: 'Error when getting media.' + }); + } + + const media = MediaModel.find(mediaTable); + return res.json(media); +} + +async function create(req: Request, res: Response) { + const mediaCode: string = req.body.code; + if (mediaCode.startsWith("t")) { + return await createMed(req, res); + } else { + return await createGame(req, res); + } +} +function remove(req: Request, res: Response) { + const mediaTable = fromStringToTable(req.params.mediaType); + if (!mediaTable) { + return res.status(500).json({ + message: 'Error when deleting the media.' + }); + } + + const code = req.body.code; + + try { + const mediaTable = req.baseUrl.includes('movies') ? Table.movies : Table.series; + const media = MediaModel.findOneAndDelete(mediaTable, code); + if (!media) { + return res.status(404).json({ message: 'No such media' }); + } + + return res.status(204).json(); + } + catch (err) { + return res.status(500).json({ message: 'Error when deleting the media.' }); + } +} + +async function checkImages() { + await checkTableImages(Table.games); + await checkTableImages(Table.movies); + await checkTableImages(Table.series); +} +function delay(time:number) { + return new Promise(resolve => setTimeout(resolve, time)); +} + +async function checkTableImages(table: Table) { + const list = mediaModel.find(table); + + for (const element of list) { + + const path = "./public/" + element.webImg; + const f = Bun.file(path); + const exists = await f.exists(); + if (!exists){ + await downloadImage(element, table); + await delay(1000); + } + } +} + export default { - - /** - * mediaController.list() - */ - list: function (req: Request, res: Response) { - const mediaTable = fromStringToTable(req.params.mediaType); - if (!mediaTable) { - return res.status(500).json({ - message: 'Error when getting media.' - }); - } - - const media = MediaModel.find(mediaTable); - return res.json(media); - }, - - create: async function (req: Request, res: Response) { - const mediaCode: string = req.body.code; - if (mediaCode.startsWith("t")) { - return await createMed(req, res); - } else { - return await createGame(req, res); - } - }, - - /** - * mediaController.delete() - */ - remove: function (req: Request, res: Response) { - const mediaTable = fromStringToTable(req.params.mediaType); - if (!mediaTable) { - return res.status(500).json({ - message: 'Error when deleting the media.' - }); - } - - const code = req.body.code; - - try { - const mediaTable = req.baseUrl.includes('movies') ? Table.movies : Table.series; - const media = MediaModel.findOneAndDelete(mediaTable, code); - if (!media) { - return res.status(404).json({ message: 'No such media' }); - } - - return res.status(204).json(); - } - catch (err) { - return res.status(500).json({ message: 'Error when deleting the media.' }); - } - }, + list, + create, + remove, + checkImages }; diff --git a/backend/miscellaneous/db.ts b/backend/miscellaneous/db.ts index 8884d5d..470b8a2 100644 --- a/backend/miscellaneous/db.ts +++ b/backend/miscellaneous/db.ts @@ -2,40 +2,43 @@ import { Database } from "bun:sqlite"; const pool = new Database("mydb.sqlite", { strict: true }); -pool.exec(` +pool.run(` CREATE TABLE IF NOT EXISTS series ( id INTEGER PRIMARY KEY AUTOINCREMENT, code INT NOT NULL, title TEXT NOT NULL, released TEXT NOT NULL, webImg TEXT NOT NULL, - UNIQUE (code) + poster TEXT NOT NULL, + year TEXT NOT NULL ); `); -pool.exec(` +pool.run(` CREATE TABLE IF NOT EXISTS movies ( id INTEGER PRIMARY KEY AUTOINCREMENT, code INT NOT NULL, title TEXT NOT NULL, released TEXT NOT NULL, webImg TEXT NOT NULL, - UNIQUE (code) + poster TEXT NOT NULL, + year TEXT NOT NULL ); `); -pool.exec(` +pool.run(` CREATE TABLE IF NOT EXISTS games ( id INTEGER PRIMARY KEY AUTOINCREMENT, code INT NOT NULL, title TEXT NOT NULL, released TEXT NOT NULL, webImg TEXT NOT NULL, - UNIQUE (code) + poster TEXT NOT NULL, + year TEXT NOT NULL ); `); -pool.exec(` +pool.run(` CREATE TABLE IF NOT EXISTS userData ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, @@ -52,7 +55,7 @@ function inset_keys() { return; } - pool.exec(` + pool.run(` INSERT INTO userData (name, value) VALUES ("pass", ""); INSERT INTO userData (name, value) VALUES ("omdb_key", ""); INSERT INTO userData (name, value) VALUES ("twitch_client_id", ""); diff --git a/backend/models/mediaModel.ts b/backend/models/mediaModel.ts index 1f894fa..ddf1f63 100644 --- a/backend/models/mediaModel.ts +++ b/backend/models/mediaModel.ts @@ -3,10 +3,12 @@ import pool from 'backend/miscellaneous/db' export class Media { id!: number; - code!: number; + code!: string title!: string; released!: string; webImg!: string; + poster!: string; + year!: string; } export enum Table { @@ -15,11 +17,11 @@ export enum Table { games = "games", } -function save(table: Table, code: number, title: string, released: string, webImg: string): number { +function save(table: Table, code: string, title: string, released:string, webImg:string, poster: string, year: string): number { try { - const sql = "INSERT INTO " + table + " (code, title, released, webImg) VALUES (?,?,?,?)"; + const sql = "INSERT INTO " + table + " (code, title, released, webImg, poster, year) VALUES (?,?,?,?,?,?)"; - const result = pool.query(sql).run(code, title, released, webImg); + const result = pool.query(sql).run(code, title, released, webImg, poster, year); return result.changes; } catch (err) { @@ -28,7 +30,7 @@ function save(table: Table, code: number, title: string, released: string, webIm return 0; } -function updateWebImg(table: Table, code: number, webImg: string): number { +function updateWebImg(table: Table, code: string, webImg: string): number { try { const sql = "UPDATE " + table + " SET webImg = ? WHERE code = ?;"; const result = pool.query(sql).run(webImg, code); @@ -40,7 +42,7 @@ function updateWebImg(table: Table, code: number, webImg: string): number { return 0; } -function findOneAndDelete(table: Table, code: number): number { +function findOneAndDelete(table: Table, code: string): number { try { const result = pool.query("DELETE FROM " + table + " WHERE code = ?;").run(code); return result.changes; @@ -51,7 +53,7 @@ function findOneAndDelete(table: Table, code: number): number { return 0; } -function findOne(table: Table, code: number): Media[] { +function findOne(table: Table, code: string): Media[] { try { const rows = pool.query("SELECT * FROM " + table + " WHERE code = ?;").as(Media).all(code); return rows;