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 { Title: string, Released: string, Response: string, Poster: string, Type: string, imdbID: string, Year: string, } function fromStringToTable(value: string): (Table | undefined) { if (value.localeCompare("games") == 0) return Table.games; if (value.localeCompare("movies") == 0) return Table.movies; if (value.localeCompare("series") == 0) return Table.series; return; } async function downloadImage(mData: Media, type: Table) { // Specify the path where you want to save the image const outputPath = '/poster/' + type + '/' + mData.code + '.jpg'; // Use Bun's built-in fetch to download the image const response = await fetch(mData.poster); // Check if the request was successful if (!response.ok) { console.log("fetch image error"); console.log(mData.title); return; } // Convert the response to a blob const imageBlob = await response.blob(); // Use Bun's write to save the image to a file await Bun.write('./public/' + outputPath, await imageBlob.arrayBuffer()); MediaModel.updateWebImg(type, mData.code, outputPath); } async function createMed(req: Request, res: Response) { const mediaCode: string = req.body.code; const omdb_key = UserModel.getValue(values.omdb_key); if (!omdb_key) { return res.status(500).json({ message: 'Error when creating media' }); } try { const uri = `http://www.omdbapi.com/?i=${mediaCode}&apikey=${omdb_key}`; const mJson = await fetch(uri); const mData: omdbRes = await mJson.json(); if (mData.Response == 'False') { return res.status(404).json({ message: 'wrong code' }); } const media: Media = { id: 0, code: mData.imdbID, title: mData.Title, released: mData.Released, webImg: "", poster: mData.Poster, year: mData.Year }; var tableType = Table.series; if (mData.Type.localeCompare("movie") == 0) { tableType = Table.movies; } 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.imdbID, mData.Title, mData.Released, "", mData.Poster, mData.Year); await downloadImage(media, tableType); res.status(201).json(media); } catch (err) { return res.status(500).json({ message: 'Error when creating media' }); } } async function createGame(req: Request, res: Response) { var gameCode = req.body.code; const twitch_client_id = UserModel.getValue(values.twitch_client_id); const twitch_client_secret = UserModel.getValue(values.twitch_client_secret); if (!twitch_client_id || !twitch_client_secret) { return res.status(500).json({ message: 'Error when creating game' }); } try { const gameFound = MediaModel.findOne(Table.games, gameCode); if (gameFound) { return res.status(409).json({ message: 'Game already exists' }); } const uri = "https://id.twitch.tv/oauth2/token?client_id=" + twitch_client_id + "&client_secret=" + twitch_client_secret + "&grant_type=client_credentials"; var response = await fetch(uri, { method: 'POST' }); const mData = await response.json(); const mheaders: HeadersInit = { 'Accept': 'application/json', 'Client-ID': twitch_client_id, 'Authorization': 'Bearer ' + mData.access_token } gameCode = parseInt(gameCode) response = await fetch( "https://api.igdb.com/v4/games", { method: 'POST', headers: mheaders, body: `fields name, first_release_date; where id = ${gameCode};` } ) const gameData = await response.json() if (gameData.length == 0) { return res.status(404).json({ message: 'wrong code' }); } const date = new Date(gameData[0].first_release_date * 1000); const options: Intl.DateTimeFormatOptions = { day: 'numeric', month: 'short', year: 'numeric' } const dateStr = date.toLocaleDateString(undefined, options); response = await fetch( "https://api.igdb.com/v4/covers", { method: 'POST', headers: mheaders, body: `fields image_id; where game = ${gameCode};` } ) const coverData = await response.json() const game: Media = { id: 0, code: gameCode, title: gameData[0].name, released: dateStr, 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, game.poster, game.year); await downloadImage(game, Table.games); return res.status(201).json(game); } catch (error) { return res.status(500).json({ message: 'Error when creating game', error: error }); } } 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){ console.log(element.title); await downloadImage(element, table); await delay(1000); } } } export default { list, create, remove, checkImages };