[READ-ONLY] Mirror of https://github.com/flo-bit/skywatched. review movies and tv shows, based on at proto skywatched.app
0

Configure Feed

Select the types of activity you want to include in your feed.

skywatched / src / lib / server / movies.ts
5.5 kB 217 lines
1import { env } from '$env/dynamic/private'; 2 3import type { Agent } from '@atproto/api'; 4 5export type Kind = 'movie' | 'tv'; 6 7export async function searchMulti(query: string) { 8 const apiUrl = `https://api.themoviedb.org/3/search/multi?query=${query}&include_adult=false&language=en-US&page=1`; 9 const options = { 10 method: 'GET', 11 headers: { 12 accept: 'application/json', 13 Authorization: `Bearer ${env.TMDB_API_KEY}` 14 } 15 }; 16 17 const response = await fetch(apiUrl, options); 18 const data = await response.json(); 19 20 return data.results; 21} 22 23export async function getDetails(id: number, kind: Kind) { 24 const url = `https://api.themoviedb.org/3/${kind}/${id}?language=en-US`; 25 const options = { 26 method: 'GET', 27 headers: { 28 accept: 'application/json', 29 Authorization: `Bearer ${env.TMDB_API_KEY}` 30 } 31 }; 32 33 const response = await fetch(url, options); 34 const data = await response.json(); 35 36 return data; 37} 38 39export async function getTrailer(id: number, kind: Kind): Promise<string | null> { 40 const url = `https://api.themoviedb.org/3/${kind}/${id}/videos?language=en-US`; 41 const options = { 42 method: 'GET', 43 headers: { 44 accept: 'application/json', 45 Authorization: `Bearer ${env.TMDB_API_KEY}` 46 } 47 }; 48 49 const response = await fetch(url, options); 50 const data = await response.json(); 51 52 let trailer = data.results?.find( 53 // eslint-disable-next-line @typescript-eslint/no-explicit-any 54 (video: any) => video.site === 'YouTube' && video.type === 'Trailer' && video.official 55 ); 56 57 if (!trailer) { 58 trailer = data.results?.find( 59 // eslint-disable-next-line @typescript-eslint/no-explicit-any 60 (video: any) => video.site === 'YouTube' && video.type === 'Trailer' 61 ); 62 } 63 64 return trailer?.key ?? null; 65} 66 67export async function getRecommendations(id: number, kind: Kind) { 68 const url = `https://api.themoviedb.org/3/${kind}/${id}/recommendations?language=en-US`; 69 const options = { 70 method: 'GET', 71 headers: { 72 accept: 'application/json', 73 Authorization: `Bearer ${env.TMDB_API_KEY}` 74 } 75 }; 76 77 const response = await fetch(url, options); 78 const data = await response.json(); 79 80 return data.results; 81} 82 83export async function getWatchProviders(id: number, kind: Kind) { 84 const url = `https://api.themoviedb.org/3/${kind}/${id}/watch/providers?language=en-US`; 85 const options = { 86 method: 'GET', 87 headers: { 88 accept: 'application/json', 89 Authorization: `Bearer ${env.TMDB_API_KEY}` 90 } 91 }; 92 93 const response = await fetch(url, options); 94 const data = await response.json(); 95 96 return data.results; 97} 98 99export async function getWatchedMoviesIdsFromPDS(agent: Agent, did: string) { 100 const allRecords = await agent.com.atproto.repo.listRecords({ 101 repo: did, 102 collection: 'my.skylights.rel' 103 }); 104 105 const movies = allRecords.data.records.filter((record) => record.value.item.ref === 'tmdb:m'); 106 107 return new Map( 108 movies.map((movie) => [ 109 parseInt(movie.value.item.value ?? '0'), 110 { 111 rating: movie.value.rating.value / 2, 112 ratingText: movie.value.note?.value, 113 updatedAt: movie.value.note?.updatedAt ?? movie.value.rating.createdAt 114 } 115 ]) 116 ); 117} 118 119export async function getWatchedShowsIdsFromPDS(agent: Agent, did: string) { 120 const allRecords = await agent.com.atproto.repo.listRecords({ 121 repo: did, 122 collection: 'my.skylights.rel' 123 }); 124 125 const shows = allRecords.data.records.filter((record) => record.value.item.ref === 'tmdb:s'); 126 127 return new Map( 128 shows.map((show) => [ 129 parseInt(show.value.item.value ?? '0'), 130 { 131 rating: show.value.rating.value / 2, 132 ratingText: show.value.note?.value, 133 updatedAt: show.value.note?.updatedAt ?? show.value.rating.createdAt 134 } 135 ]) 136 ); 137} 138 139export async function getCast(id: number, kind: Kind) { 140 const url = `https://api.themoviedb.org/3/${kind}/${id}/credits?language=en-US`; 141 const options = { 142 method: 'GET', 143 headers: { 144 accept: 'application/json', 145 Authorization: `Bearer ${env.TMDB_API_KEY}` 146 } 147 }; 148 149 const response = await fetch(url, options); 150 const data = await response.json(); 151 152 return data.cast; 153} 154 155export async function getPopularMovies() { 156 const url = `https://api.themoviedb.org/3/movie/popular?language=en-US&page=1`; 157 const options = { 158 method: 'GET', 159 headers: { 160 accept: 'application/json', 161 Authorization: `Bearer ${env.TMDB_API_KEY}` 162 } 163 }; 164 165 const response = await fetch(url, options); 166 const data = await response.json(); 167 168 return data.results; 169} 170 171export async function getPopularShows() { 172 const url = `https://api.themoviedb.org/3/tv/popular?language=en-US&page=1`; 173 const options = { 174 method: 'GET', 175 headers: { 176 accept: 'application/json', 177 Authorization: `Bearer ${env.TMDB_API_KEY}` 178 } 179 }; 180 181 const response = await fetch(url, options); 182 const data = await response.json(); 183 184 return data.results; 185} 186 187export async function getPersonDetails(personId: number) { 188 const url = `https://api.themoviedb.org/3/person/${personId}?language=en-US`; 189 const options = { 190 method: 'GET', 191 headers: { 192 accept: 'application/json', 193 Authorization: `Bearer ${env.TMDB_API_KEY}` 194 } 195 }; 196 197 const response = await fetch(url, options); 198 const data = await response.json(); 199 200 return data; 201} 202 203export async function getCombinedCredits(personId: number) { 204 const url = `https://api.themoviedb.org/3/person/${personId}/combined_credits?language=en-US`; 205 const options = { 206 method: 'GET', 207 headers: { 208 accept: 'application/json', 209 Authorization: `Bearer ${env.TMDB_API_KEY}` 210 } 211 }; 212 213 const response = await fetch(url, options); 214 const data = await response.json(); 215 216 return data; 217}