Skip to content

Commit

Permalink
Merge pull request #45 from GerardPolloRebozado/feature/videoGameDb
Browse files Browse the repository at this point in the history
Feature/video game db
  • Loading branch information
GerardPolloRebozado authored Sep 18, 2024
2 parents 45631d4 + 3a67186 commit 4d6bff7
Show file tree
Hide file tree
Showing 69 changed files with 21,879 additions and 20,141 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/$
JWT_SECRET=
#Go to https://www.themoviedb.org/settings/api to get your api key
TMDB_API_KEY=
TWICH_CLIENT_ID=
TWICH_CLIENT_SECRET=
3 changes: 0 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
},
{
"files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"],
"env": {
"jest": true
},
"rules": {}
}
]
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ Thumbs.db
# Next.js
.next
out

#prisma generatred tipes that are in the libs folder inside types/src/generated
libs/types/src/generated
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ COPY . .

EXPOSE 4444
RUN chmod +x ./docker/entrypoint.sh
RUN npx prisma generate --schema ./apps/api/prisma/schema.prisma
RUN npx prisma generate
RUN npx nx run api:build
RUN npx nx run web:build

Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/controllers/chartController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request, Response } from "express"
import prisma from "../services/prisma"
import { MediaRuntimeChartData } from "@anytrack/type"
import { MediaRuntimeChartData } from '@anytrack/types'

export const getMediaRuntimeChart = async (req: Request, res: Response) => {
try {
Expand Down
165 changes: 165 additions & 0 deletions apps/api/src/controllers/gameController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { Request, Response } from "express";
import prisma from "../services/prisma";
import { getVGameByIdService } from "../services/igdbService";
import { Game } from "igdb-api-types";
import { gameCategoryConverter, gameStatusConverter, markedGameResponse } from '@anytrack/types';

export const markVGame = async (req: Request, res: Response) => {
try {
const { startedTime, finishedTime } = req.body
const id = Number(req.body.id)
const userId = res.locals.user.id
const gameDb = await prisma.game.findUnique({
where: {
id,
}
})

if (!gameDb) {
const igdbGame: Game = await getVGameByIdService(id, true)
if (!igdbGame) {
return res.status(404).json({ message: "Game not found" })
}
if (igdbGame.parent_game && igdbGame.parent_game && typeof igdbGame.parent_game === "number") {
const parentGame = await prisma.game.findUnique({
where: {
id: igdbGame.parent_game
}
})
if (!parentGame) {
const parentIgdbGame: Game = await getVGameByIdService(igdbGame.parent_game, true)
if (!parentIgdbGame) {
return res.status(404).json({ message: "Parent game not found" })
}
await prisma.game.create({
data: {
id: parentIgdbGame.id,
name: parentIgdbGame.name,
status: gameStatusConverter(parentIgdbGame.status).toString(),
genres: {
connectOrCreate: parentIgdbGame.genres.map((genre: any) => ({
where: { id: genre.id },
create: { id: genre.id, name: genre.name }
}))
},
category: gameCategoryConverter(parentIgdbGame.category).toString(),
coverId: typeof parentIgdbGame.cover === 'object' && parentIgdbGame.cover.image_id ? parentIgdbGame.cover.image_id : undefined,
totalRating: parentIgdbGame.total_rating,
totalRatingCount: parentIgdbGame.total_rating_count,
firstReleaseDate: new Date(parentIgdbGame.first_release_date * 1000),
}
})
}
}
await prisma.game.create({
data: {
id: igdbGame.id,
name: igdbGame.name,
status: gameStatusConverter(igdbGame.status).toString(),
genres: {
connectOrCreate: igdbGame.genres.map((genre: any) => ({
where: { id: genre.id },
create: { id: genre.id, name: genre.name }
}))
},
category: gameCategoryConverter(igdbGame.category).toString(),
coverId: typeof igdbGame.cover === 'object' && igdbGame.cover.image_id ? igdbGame.cover.image_id : undefined,
totalRating: igdbGame.total_rating,
totalRatingCount: igdbGame.total_rating_count,
firstReleaseDate: new Date(igdbGame.first_release_date * 1000),
parentGame: typeof igdbGame.parent_game === 'number' ? { connect: { id: igdbGame.parent_game } } : undefined
}
})
}
if (!startedTime && !finishedTime) {
const checkMarkedGame = await prisma.userGame.findFirst({
where: {
userId,
gameId: id,
startedTime: null,
finishedTime: null
}
})
if (checkMarkedGame) {
res.status(409).json({ message: "Game already marked as pending" })
return
}
} else {
await prisma.userGame.deleteMany({
where: {
userId,
gameId: id,
startedTime: null,
finishedTime: null
}
})
}
const markedGame = await prisma.userGame.create({
data: {
userId,
gameId: id,
startedTime,
finishedTime,
}
})
res.status(200).json(markedGame)
} catch (error) {
res.status(500).json({ message: "An unexpected error occurred while marking the game.", error: error.message || error });
}

}

export const getMarkedVGames = async (req: Request, res: Response) => {
try {
const userId = res.locals.user.id
const markedGames = new Map<number, markedGameResponse>();
const markedGamesDb = await prisma.userGame.findMany({
where: {
userId,
},
})
if (!markedGamesDb) {
res.status(404).json({ message: "No marked games found" })
return
}
for (const markedGame of markedGamesDb) {
if (!markedGames.has(markedGame.gameId)) {
const game = await prisma.game.findUnique({
where: {
id: markedGame.gameId
}
})
game.firstReleaseDate = new Date(game.firstReleaseDate)
markedGames.set(markedGame.gameId, { game, playHistory: [], playTime: 0 });
}
if (markedGame.finishedTime && markedGame.startedTime) {
markedGames.get(markedGame.gameId).playHistory.push(markedGame)
markedGames.get(markedGame.gameId).playTime += (markedGame.finishedTime.getTime() - markedGame.startedTime.getTime())
}
}
res.status(200).json(Array.from(markedGames.values()))
} catch (error) {
console.log(error)
res.status(500).json({ message: "An unexpected error occurred while marking the game.", error: error.message || error });
}
}

export const removeMarkedVGame = async (req: Request, res: Response) => {
try {
const userId = res.locals.user.id
const id = Number(req.params.id)
const markedGame = await prisma.userGame.deleteMany({
where: {
userId,
gameId: id
}
})
if (!markedGame) {
res.status(404).json({ message: "Game not found" })
return
}
res.status(200).json(markedGame)
} catch (error) {
res.status(500).json({ message: "An unexpected error occurred while removing the game.", error: error.message || error });
}
}
47 changes: 47 additions & 0 deletions apps/api/src/controllers/igdbController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Request, Response } from "express";
import { getManyVGameGenreService, getVGameGenreByIdService, getVGameByIdService, getVGameByNameService } from "../services/igdbService";
import { parseBoolean } from "@anytrack/utils";

export const getVGameById = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const lessData = parseBoolean(String(req.query.lessData));
const game = await getVGameByIdService(Number(id), lessData);
res.json(game);
} catch (error) {
console.log(error);
res.status(500).json({ error: error });
}
}

export const getVGameGenreById = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const genre = await getVGameGenreByIdService(Number(id));
res.json(genre);
} catch (error) {
console.log(error);
res.status(500).json({ error: error });
}
}

export const getVGameManyGenre = async (req: Request, res: Response) => {
try {
const manyGenre = await getManyVGameGenreService();
res.json(await manyGenre);
} catch (error) {
console.log(error);
res.status(500).json({ error: error });
}
}

export const getVGameByName = async (req: Request, res: Response) => {
try {
const { name } = req.params;
const manyGames = await getVGameByNameService(name)
res.status(200).json(await manyGames)
} catch (error) {
console.log(error)
res.status(500).json({ error: error })
}
}
24 changes: 23 additions & 1 deletion apps/api/src/controllers/mediaController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request, Response } from "express";
import prisma from "../services/prisma";
import { MediaType, groupedFutureMedia } from "@anytrack/type";
import { MediaType, groupedFutureMedia } from "@anytrack/types";

export const getManyFutureMedia = async (req: Request, res: Response) => {
try {
Expand Down Expand Up @@ -39,6 +39,18 @@ export const getManyFutureMedia = async (req: Request, res: Response) => {
}
},
});
const futureGames = await prisma.game.findMany({
where: {
userGame: {
some: {
userId
}
},
firstReleaseDate: {
gte: new Date()
}
},
});
const groupedFutureMedia: groupedFutureMedia[] = futureEpisodes.map((episode) => ({
mediaType: MediaType.show,
tmdbId: episode.season.show.tmdbId,
Expand All @@ -56,6 +68,16 @@ export const getManyFutureMedia = async (req: Request, res: Response) => {
releaseDate: movie.releaseDate
})
})
futureGames.forEach((game) => {
groupedFutureMedia.push({
mediaType: MediaType.vgame,
igdbId: game.id,
title: game.name,
poster: game.coverId && `https://images.igdb.com/igdb/image/upload/t_cover_big_2x/${game.coverId}.jpg` || undefined,
releaseDate: game.firstReleaseDate
})
})


groupedFutureMedia.sort((a, b) => b.releaseDate.getTime() - a.releaseDate.getTime());
res.status(200).json(groupedFutureMedia)
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/controllers/movieController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Request, Response } from "express";
import { searchMovieService, searchMoviebyIdService } from "../services/tmdbService";
import prisma from "../services/prisma";
import { genre } from "@prisma/client";
import { movieGenre } from "@anytrack/types";
import { SearchMovieRequest } from "moviedb-promise";

export const getMovieByTerm = async (req: Request, res: Response) => {
Expand Down Expand Up @@ -49,7 +49,7 @@ export const markMovie = async (req: Request, res: Response) => {
});
if (!movieItem) {
const movie = await searchMoviebyIdService({ id: tmdbId });
const genreData = await Promise.all(await movie.genres.map((genre: genre) => prisma.genre.upsert({ where: { name: genre.name }, update: { name: genre.name }, create: { name: genre.name } })));
const genreData = await Promise.all(await movie.genres.map((genre: movieGenre) => prisma.movieGenre.upsert({ where: { name: genre.name }, update: { name: genre.name }, create: { name: genre.name } })));
movieItem = await prisma.movie.create({
data: {
tmdbId: movie.id,
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/controllers/settingsController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { setting } from "@prisma/client";
import { Request, Response } from "express";
import prisma from "../services/prisma";
import { setting } from "@anytrack/types";

export async function changeSettings(req: Request, res: Response) {
try {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/controllers/showController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const markShow = async (req: Request, res: Response) => {
genre: {
connect: await Promise.all(tmdbShow.genres.map(async (genre: any) => {
return {
id: (await prisma.genre.upsert({ where: { name: genre.name }, create: { name: genre.name }, update: { name: genre.name } })).id
id: (await prisma.movieGenre.upsert({ where: { name: genre.name }, create: { name: genre.name }, update: { name: genre.name } })).id
}
})),
}
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/controllers/tmdbController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request, Response } from 'express';
import { getAgregatedShowCreditsService, getMovieCredits, getMovieProvidersService, getMovieVideosService, getOnePeopleService, getShowProvidersService, getShowVideosService, searchShowSeasonsService, searchShowTmdbIdService } from '../services/tmdbService';
import { MediaType } from '@anytrack/type';
import { MediaType } from '@anytrack/types';
import { Cast, VideosResponse } from 'moviedb-promise';

export const getShowSeasons = async (req: Request, res: Response) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/controllers/userController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Request, Response } from "express";
import { comparePasswords, hashPassword } from "../services/bcryptService";
import jwt from 'jsonwebtoken';
import { user } from "@prisma/client";
import { user } from "@anytrack/types";
import prisma from "../services/prisma";

export async function signup(req: Request, res: Response) {
Expand Down
Loading

0 comments on commit 4d6bff7

Please sign in to comment.