diff --git a/src/actors.js b/src/actors.js index 8faa6cf7..8678eda6 100644 --- a/src/actors.js +++ b/src/actors.js @@ -130,7 +130,7 @@ function toBaseActors(actorsOrNames, release) { }); } -function curateActor(actor) { +function curateActor(actor, withDetails = false) { if (!actor) { return null; } @@ -140,58 +140,64 @@ function curateActor(actor) { name: actor.name, slug: actor.slug, gender: actor.gender, - alias: actor.alias && { - id: actor.alias.id, - name: actor.alias.name, - gender: actor.alias.gender, - }, - network: actor.network && { - id: actor.network.id, - name: actor.network.name, - slug: actor.network.slug, - }, + networkId: actor.network_id, + aliasFor: actor.alias_for, dateOfBirth: actor.date_of_birth, - dateOfDeath: actor.date_of_death, - cup: actor.cup, - bust: actor.bust, - waist: actor.waist, - hip: actor.hip, - naturalBoobs: actor.natural_boobs, - height: actor.height, - weight: actor.weight, - eyes: actor.eyes, - hair: actor.hair, - hasTattoos: actor.has_tattoos, - hasPiercings: actor.has_piercings, - tattoos: actor.tattoos, - piercings: actor.piercings, - description: actor.description, - origin: actor.birth_country && { - country: { - alpha2: actor.birth_country.alpha2, - name: actor.birth_country.name, - alias: actor.birth_country.alias, + birthCountry: actor.birth_country_alpha2, + ...(withDetails && { + alias: actor.alias && { + id: actor.alias.id, + name: actor.alias.name, + slug: actor.slug, + gender: actor.alias.gender, }, - state: actor.birth_state, - city: actor.birth_city, - }, - residence: actor.residence_country && { - country: { - alpha2: actor.residence_country.alpha2, - name: actor.residence_country.name, - alias: actor.residence_country.alias, + network: actor.network && { + id: actor.network.id, + name: actor.network.name, + slug: actor.network.slug, }, - state: actor.residence_state, - city: actor.residence_city, - }, - avatar: actor.avatar && { - id: actor.avatar.id, - path: actor.avatar.path, - width: actor.avatar.width, - height: actor.avatar.height, - size: actor.avatar.size, - source: actor.avatar.source, - }, + dateOfDeath: actor.date_of_death, + cup: actor.cup, + bust: actor.bust, + waist: actor.waist, + hip: actor.hip, + naturalBoobs: actor.natural_boobs, + height: actor.height, + weight: actor.weight, + eyes: actor.eyes, + hair: actor.hair, + hasTattoos: actor.has_tattoos, + hasPiercings: actor.has_piercings, + tattoos: actor.tattoos, + piercings: actor.piercings, + description: actor.description, + placeOfBirth: actor.birth_country && { + country: { + alpha2: actor.birth_country.alpha2, + name: actor.birth_country.name, + alias: actor.birth_country.alias, + }, + state: actor.birth_state, + city: actor.birth_city, + }, + placeOfResidence: actor.residence_country && { + country: { + alpha2: actor.residence_country.alpha2, + name: actor.residence_country.name, + alias: actor.residence_country.alias, + }, + state: actor.residence_state, + city: actor.residence_city, + }, + avatar: actor.avatar && { + id: actor.avatar.id, + path: actor.avatar.path, + width: actor.avatar.width, + height: actor.avatar.height, + size: actor.avatar.size, + source: actor.avatar.source, + }, + }), }; return curatedActor; @@ -724,11 +730,21 @@ async function fetchActor(actorId) { .leftJoin('media', 'media.id', 'actors.avatar_media_id') .first(); - return curateActor(actor); + return curateActor(actor, true); +} + +async function searchActors(query) { + const actors = await knex + .select('*') + .from(knex.raw('search_actors(?) as actors', [query])) + .limit(10); + + return actors.map(actor => curateActor(actor)); } module.exports = { associateActors, fetchActor, scrapeActors, + searchActors, }; diff --git a/src/releases.js b/src/releases.js index b8e7df8a..43a7c563 100644 --- a/src/releases.js +++ b/src/releases.js @@ -31,7 +31,12 @@ function curateRelease(release, withMedia = false) { actors: (release.actors || []).map(actor => ({ id: actor.id, name: actor.name, + slug: actor.slug, gender: actor.gender, + networkId: actor.network_id, + aliasFor: actor.alias_for, + dateOfBirth: actor.date_of_birth, + birthCountry: actor.birth_country_alpha2, })), ...(withMedia && { poster: release.poster ? { @@ -55,7 +60,7 @@ function curateRelease(release, withMedia = false) { }; } -function withRelations(queryBuilder, withMedia = false) { +function withRelations(queryBuilder, withMedia = false, type = 'scene') { queryBuilder .select(knex.raw(` releases.id, releases.entry_id, releases.shoot_id, releases.title, releases.url, releases.date, releases.description, releases.duration, releases.created_at, @@ -64,6 +69,7 @@ function withRelations(queryBuilder, withMedia = false) { row_to_json(site_networks) as site_network, json_agg(DISTINCT actors) as actors `)) + .where('type', type) .leftJoin('sites', 'sites.id', 'releases.site_id') .leftJoin('networks', 'networks.id', 'releases.network_id') .leftJoin('networks as site_networks', 'site_networks.id', 'sites.network_id') @@ -88,28 +94,27 @@ function withRelations(queryBuilder, withMedia = false) { } } -async function fetchRelease(releaseId) { +async function fetchRelease(releaseId, type = 'scene') { const release = await knex('releases') .where('releases.id', releaseId) - .modify(withRelations, true) + .modify(withRelations, true, type) .first(); return curateRelease(release, true); } -async function fetchReleases(limit = 100) { +async function fetchReleases(limit = 100, type = 'scene') { const releases = await knex('releases') - .modify(withRelations) + .modify(withRelations, false, type) .limit(Math.min(limit, 1000)); return releases.map(release => curateRelease(release)); } -async function searchReleases(query, limit = 100) { - // const releases = await knex.raw('SELECT * FROM search_releases(?) LIMIT ?;', [query, limit]); +async function searchReleases(query, limit = 100, type = 'scene') { const releases = await knex .from(knex.raw('search_releases(?) as releases', [query])) - .modify(withRelations) + .modify(withRelations, false, type) .limit(Math.min(limit, 1000)); return releases.map(release => curateRelease(release)); diff --git a/src/web/actors.js b/src/web/actors.js index 2dd61957..8bfe40d1 100644 --- a/src/web/actors.js +++ b/src/web/actors.js @@ -1,6 +1,6 @@ 'use strict'; -const { fetchActor } = require('../actors'); +const { fetchActor, searchActors } = require('../actors'); async function fetchActorApi(req, res) { const actor = await fetchActor(req.params.actorId); @@ -13,6 +13,20 @@ async function fetchActorApi(req, res) { res.status(404).send({ actor: null }); } +async function fetchActorsApi(req, res) { + const query = req.query.query || req.query.q; + + if (query) { + const actors = await searchActors(query, req.query.limit); + + res.send({ actors }); + return; + } + + res.send({ hint: 'specify a query or ID', actors: [] }); +} + module.exports = { fetchActor: fetchActorApi, + fetchActors: fetchActorsApi, }; diff --git a/src/web/releases.js b/src/web/releases.js index b6094cea..59a16ac5 100644 --- a/src/web/releases.js +++ b/src/web/releases.js @@ -2,28 +2,48 @@ const { fetchRelease, fetchReleases, searchReleases } = require('../releases'); -async function fetchReleaseApi(req, res) { - const release = await fetchRelease(req.params.releaseId); +async function fetchReleaseApi(req, res, type = 'scene') { + const release = await fetchRelease(req.params.releaseId, type); if (release) { - res.send({ release }); + res.send({ [type]: release }); return; } - res.status(404).send({ release: null }); + res.status(404).send({ [type]: null }); } -async function fetchReleasesApi(req, res) { +async function fetchReleasesApi(req, res, type = 'scene') { const query = req.query.query || req.query.q; const releases = query - ? await searchReleases(query, req.query.limit) - : await fetchReleases(req.query.limit); + ? await searchReleases(query, req.query.limit, type) + : await fetchReleases(req.query.limit, type); - res.send({ releases }); + res.send({ [`${type}s`]: releases }); +} + +async function fetchSceneApi(req, res) { + return fetchReleaseApi(req, res, 'scene'); +} + +async function fetchScenesApi(req, res) { + return fetchReleasesApi(req, res, 'scene'); +} + +async function fetchMovieApi(req, res) { + return fetchReleaseApi(req, res, 'movie'); +} + +async function fetchMoviesApi(req, res) { + return fetchReleasesApi(req, res, 'movie'); } module.exports = { fetchRelease: fetchReleaseApi, fetchReleases: fetchReleasesApi, + fetchScene: fetchSceneApi, + fetchMovie: fetchMovieApi, + fetchScenes: fetchScenesApi, + fetchMovies: fetchMoviesApi, }; diff --git a/src/web/server.js b/src/web/server.js index a53b2440..d672abb3 100644 --- a/src/web/server.js +++ b/src/web/server.js @@ -15,11 +15,16 @@ const logger = require('../logger')(__filename); const { ActorPlugins, SitePlugins, ReleasePlugins } = require('./plugins/plugins'); const { - fetchRelease, - fetchReleases, + fetchScene, + fetchScenes, + fetchMovie, + fetchMovies, } = require('./releases'); -const { fetchActor } = require('./actors'); +const { + fetchActor, + fetchActors, +} = require('./actors'); function initServer() { const app = express(); @@ -63,9 +68,13 @@ function initServer() { router.use(bodyParser.json({ strict: false })); - router.get('/api/releases', fetchReleases); - router.get('/api/releases/:releaseId', fetchRelease); + router.get('/api/scenes', fetchScenes); + router.get('/api/scenes/:releaseId', fetchScene); + router.get('/api/movies', fetchMovies); + router.get('/api/movies/:releaseId', fetchMovie); + + router.get('/api/actors', fetchActors); router.get('/api/actors/:actorId', fetchActor); router.get('*', (req, res) => {