import { type Request, type Response } from "express"; import UserModel, { values } from '../models/userModel'; import MediaModel, { Table, Media } from '../models/mediaModel'; interface omdbRes{ Title: string, Released: string, Response: string, Poster: string, Type: 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.webImg); // Check if the request was successful if (!response.ok) { console.log("fetch image error"); 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' }); } // 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}`; 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: cleanCode, title: mData.Title, released: mData.Released, webImg: mData.Poster, }; 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; } if (mData.Type.localeCompare("movie") == 0) { const savedMedia = MediaModel.save(Table.movies, cleanCode, mData.Title, mData.Released, mData.Poster); await downloadImage(media, 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); } 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: `https://images.igdb.com/igdb/image/upload/t_cover_big/${coverData[0].image_id}.jpg`, }; const savedGame = MediaModel.save(Table.games, game.code, game.title, game.released, game.webImg); return res.status(201).json(game); } catch (error) { return res.status(500).json({ message: 'Error when creating game', error: error }); } } 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.' }); } }, };