Skip to content

Commit

Permalink
Merge pull request #20 from benjifs/feat/media
Browse files Browse the repository at this point in the history
Feat: media
  • Loading branch information
benjifs authored Dec 9, 2023
2 parents dd443c4 + 12ce9cc commit 3e56250
Show file tree
Hide file tree
Showing 16 changed files with 541 additions and 480 deletions.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
VITE_OMDB_API_KEY="1234abcd"
OMDB_API_KEY="1234abcd"
LASTFM_API_KEY="abcd1234"
GIANTBOMB_API_KEY="wxyz7890"
# Only use in development
VITE_MICROPUB_ENDPOINT="http://localhost:1234/micropub"
10 changes: 9 additions & 1 deletion netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
command = "npm run start:vite"
publish = "dist"
targetPort = 5173
functionsPort = 5174
port = 9000
framework = "#custom"

[build]
command = "npm run build:vite"
Expand All @@ -13,9 +15,15 @@
node_bundler = "esbuild"

[[redirects]]
from = "/*"
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200

[[redirects]]
from = "/*"
to = "/index.html"
status = 200

[template.environment]
OMDB_API_KEY = "OMDB API Key"
LASTFM_API_KEY = "last.fm API key"
34 changes: 17 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sparkles",
"version": "0.6.2",
"version": "0.7.0",
"description": "micropub client",
"main": "./src/js/app.js",
"scripts": {
Expand Down Expand Up @@ -28,7 +28,7 @@
"url": "https://github.com/benjifs/sparkles/issues"
},
"devDependencies": {
"eslint": "^8.54.0",
"eslint": "^8.55.0",
"sass": "^1.69.5",
"vite": "^4.5.0"
},
Expand Down
1 change: 0 additions & 1 deletion public/_redirects

This file was deleted.

6 changes: 4 additions & 2 deletions src/functions/micropub.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exports.handler = async e => {
// return Response.error(Error.INVALID, 'Could not parse request body')
}

console.log(`⇒ ${e.httpMethod}: ${endpoint}`, body)
const res = await fetch(endpoint + (Array.from(params).length > 0 ? '?' + params : ''), {
method: e.httpMethod,
...(body && { body: JSON.stringify(body) }),
Expand All @@ -27,7 +28,8 @@ exports.handler = async e => {
}
})

console.log(`⇒ [${res.status}]`, res.headers)
const response = await res.text()
console.log(` [${res.status}]`, res.headers, response)
const location = res.headers.get('location')
const contentType = res.headers.get('content-type')

Expand All @@ -38,6 +40,6 @@ exports.handler = async e => {
'Content-Type': contentType,
...(location && { 'Location': location })
},
body: await res.text()
body: response
}
}
114 changes: 114 additions & 0 deletions src/functions/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import fetch from 'node-fetch'

import { Error, Response } from './lib/utils'

const types = {
movie: {
url: 'https://www.omdbapi.com',
buildParams: ({ query, year, page }) => ({
apikey: process.env.OMDB_API_KEY,
type: 'movie',
s: query,
year: year,
page: page
}),
buildError: ({ status, response }) => Response.error({ statusCode: status }, response.Error),
parseResponse: res => ({
totalResults: res?.totalResults || 0,
results: res?.Search?.map(m => ({
id: `imdb:${m.imdbID}`,
title: m.Title,
image: m.Poster,
year: m.Year,
url: `https://imdb.com/title/${m.imdbID}`
}))
})
},
book: {
url: 'https://openlibrary.org/search.json',
buildParams: ({ query, page }) => ({
limit: 10,
q: query,
page: page
}),
buildError: ({ status, response }) => Response.error({ statusCode: status }, response.error),
parseResponse: res => ({
totalResults: res?.num_found || 0,
results: res?.docs.map(b => ({
id: `olid:${b.key.replace('/works/', '')}`,
title: b.title,
author: b.author_name ? b.author_name.join(', ') : '',
image: `https://covers.openlibrary.org/b/id/${b.cover_i}-M.jpg`,
year: b.first_publish_year,
url: `https://openlibrary.org${b.key}`
}))
})
},
music: {
url: 'https://ws.audioscrobbler.com/2.0/',
buildParams: ({ type, query, page }) => ({
api_key: process.env.LASTFM_API_KEY,
limit: 10,
format: 'json',
method: `${type}.search`,
[type]: query,
page: page
}),
buildError: ({ status, response }) => Response.error({
statusCode: status,
error: response.error
}, response.message),
parseResponse: (res, category) => ({
totalResults: parseInt(res?.results['opensearch:totalResults'] || 0),
results: res.results[`${category}matches`][category]
.map(r => ({
...(r.mbid && { id: `mbid:${r.mbid}` }),
title: r.name,
author: r.artist,
...(category == 'album' && { image: r.image?.pop()['#text'] }),
url: r.url
}))
})
},
game: {
url: 'https://www.giantbomb.com/api/search/',
buildParams: ({ query, page }) => ({
api_key: process.env.GIANTBOMB_API_KEY,
limit: 10,
format: 'json',
resources: 'game',
query: query,
page: page
}),
buildError: ({ status, response }) => Response.error({ statusCode: status }, response.error),
parseResponse: res => ({
totalResults: res?.number_of_total_results || 0,
results: res?.results.map(g => ({
id: `gbid:${g.guid}`,
title: g.name,
image: g.image.original_url,
year: g.original_release_date ? new Date(g.original_release_date).getFullYear() : null,
url: g.site_detail_url
}))
})
},
}

export const handler = async (e) => {
const { type } = e.queryStringParameters
if (!['movie', 'book', 'artist', 'album', 'track', 'game'].includes(type)) {
return Response.error(Error.NOT_SUPPORTED, 'Search type not supported')
}

const opts = types[['artist', 'album', 'track'].includes(type) ? 'music' : type]
const params = new URLSearchParams(opts.buildParams(e.queryStringParameters))
const res = await fetch(`${opts.url}?${params.toString()}`)
const response = await res.json()
if (res.status !== 200) {
return opts.buildError({ status: res.status, response })
} else if (type == 'game' && response.error != 'OK') {
return opts.buildError({ status: 400, response})
}

return Response.success(opts.parseResponse(response, type))
}
12 changes: 5 additions & 7 deletions src/js/Controllers/Proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import m from 'mithril'

import Store from '../Models/Store'

const FUNCTIONS = window.location.host === 'localhost:5173' ? 'http://localhost:9000' : ''
const CLIENT = window.location.origin

const Proxy = {
discover: url =>
m
.request({
method: 'GET',
url: `${FUNCTIONS}/.netlify/functions/discover`,
url: '/.netlify/functions/discover',
params: { url: url }
}),
validate: params => {
Expand All @@ -22,7 +21,7 @@ const Proxy = {
return m
.request({
method: 'GET',
url: `${FUNCTIONS}/.netlify/functions/token`,
url: '/.netlify/functions/token',
params: {
'token_endpoint': session.token_endpoint,
'code': code,
Expand All @@ -41,7 +40,7 @@ const Proxy = {
return m
.request({
method: method || 'GET',
url: `${FUNCTIONS}/.netlify/functions/micropub`,
url: '/.netlify/functions/micropub',
headers: {
// 'Content-Type': 'application/json',
'Authorization': `Bearer ${session.access_token}`,
Expand All @@ -58,7 +57,7 @@ const Proxy = {
return m
.request({
method: method || 'GET',
url: `${FUNCTIONS}/.netlify/functions/media`,
url: '/.netlify/functions/media',
headers: {
'Authorization': `Bearer ${session.access_token}`,
'x-media-endpoint': session['media-endpoint']
Expand Down Expand Up @@ -87,13 +86,12 @@ const Proxy = {
try {
await m.request({
method: 'GET',
url: `${FUNCTIONS}/.netlify/functions/redirect?url=${url}`
url: `/.netlify/functions/redirect?url=${url}`
})
return true
} catch (err) {
console.error(`could not fetch ${url}`)
}

return false
}
}
Expand Down
Loading

0 comments on commit 3e56250

Please sign in to comment.