235 lines
5.0 KiB
JavaScript
235 lines
5.0 KiB
JavaScript
import { stringify } from '@brillout/json-serializer/stringify';
|
|
import { Router } from 'express';
|
|
import omit from 'object.omit';
|
|
|
|
import {
|
|
createActor,
|
|
createActorRevision,
|
|
fetchActorRevisions,
|
|
fetchActors,
|
|
fetchActorsById,
|
|
mergeActors,
|
|
reviewActorRevision,
|
|
} from '../actors.js';
|
|
|
|
import { fetchStashByUsernameAndSlug } from '../stashes.js';
|
|
|
|
export function curateActorsQuery(query) {
|
|
return {
|
|
query: query.q,
|
|
gender: query.gender,
|
|
age: query.age?.split(',').map((age) => Number(age)),
|
|
dateOfBirth: query.dob && new Date(query.dob),
|
|
dobType: ({ dob: 'dateOfBirth', bd: 'birthday' })[query.dobt] || 'birthday',
|
|
cup: query.cup?.split(','),
|
|
country: query.c,
|
|
naturalBoobs: query.nb,
|
|
height: query.height?.split(',').map((height) => Number(height)),
|
|
weight: query.weight?.split(',').map((weight) => Number(weight)),
|
|
requireAvatar: query.avatar,
|
|
stashId: Number(query.stashId) || null,
|
|
isGlobal: Object.hasOwn(query, 'global'),
|
|
includeAliased: Object.hasOwn(query, 'alias'),
|
|
};
|
|
}
|
|
|
|
export async function fetchActorsApi(req, res) {
|
|
const {
|
|
actors,
|
|
countries,
|
|
limit,
|
|
total,
|
|
} = await fetchActors(curateActorsQuery(req.query), {
|
|
page: Number(req.query.page) || 1,
|
|
limit: Number(req.query.limit) || 120,
|
|
order: req.query.order?.split('.') || ['likes', 'desc'],
|
|
}, req.user);
|
|
|
|
res.send(stringify({
|
|
actors,
|
|
countries,
|
|
limit,
|
|
total,
|
|
}));
|
|
}
|
|
|
|
export const actorsSchema = `
|
|
extend type Query {
|
|
actors(
|
|
query: String
|
|
stash: String
|
|
limit: Int! = 30
|
|
page: Int! = 1
|
|
order: [String!]
|
|
): ActorsResult
|
|
|
|
actor(
|
|
id: Int!
|
|
): Actor
|
|
|
|
actorsById(
|
|
ids: [Int!]!
|
|
): [Actor]
|
|
}
|
|
|
|
type Country {
|
|
alpha2: String
|
|
name: String
|
|
}
|
|
|
|
type Location {
|
|
country: Country
|
|
city: String
|
|
state: String
|
|
}
|
|
|
|
type ActorsResult {
|
|
nodes: [Actor!]!
|
|
total: Int
|
|
}
|
|
|
|
type Actor {
|
|
id: Int!
|
|
name: String
|
|
slug: String
|
|
allowGlobalMatch: Boolean
|
|
gender: String
|
|
dateOfBirth: Date
|
|
dateOfDeath: Date
|
|
age: Int
|
|
ageFromBirth: Int
|
|
ageThen: Int
|
|
origin: Location
|
|
residence: Location
|
|
ethnicity: String
|
|
height: Int
|
|
bust: String
|
|
hip: Int
|
|
waist: Int
|
|
naturalBoobs: Boolean
|
|
naturalButt: Boolean
|
|
penisLength: Int
|
|
penisGirth: Int
|
|
isCircumcised: Boolean
|
|
eyes: String
|
|
hairColor: String
|
|
hasTattoos: Boolean
|
|
tattoos: String
|
|
hasPiercings: Boolean
|
|
piercings: String
|
|
agency: String
|
|
entity: Entity
|
|
aliases: [Actor!]!
|
|
scenes: Int
|
|
likes: Int
|
|
stashes: [Stash!]!
|
|
}
|
|
`;
|
|
|
|
function curateGraphqlActor(actor) {
|
|
return {
|
|
...actor,
|
|
age: actor.ageFromBirth,
|
|
height: actor.height?.metric,
|
|
weight: actor.weight?.metric,
|
|
};
|
|
}
|
|
|
|
function getOrder(query) {
|
|
if (query.order) {
|
|
return query.order;
|
|
}
|
|
|
|
if (query.query) {
|
|
return ['results', 'desc'];
|
|
}
|
|
|
|
if (query.stash) {
|
|
return ['stashed', 'desc'];
|
|
}
|
|
|
|
return ['likes', 'desc'];
|
|
}
|
|
|
|
export async function fetchActorsGraphql(query, req) {
|
|
const stash = query.stash && req.user
|
|
? await fetchStashByUsernameAndSlug(req.user.id, query.stash, req.user)
|
|
: null;
|
|
|
|
const {
|
|
actors,
|
|
total,
|
|
} = await fetchActors({
|
|
query: query.query,
|
|
stashId: stash?.id,
|
|
}, {
|
|
limit: query.limit,
|
|
page: query.page,
|
|
order: getOrder(query),
|
|
aggregateCountries: false,
|
|
}, req.user);
|
|
|
|
return {
|
|
nodes: actors.map((actor) => curateGraphqlActor(actor)),
|
|
total,
|
|
};
|
|
}
|
|
|
|
export async function fetchActorsByIdGraphql(query, _req, _info) {
|
|
const actors = await fetchActorsById([].concat(query.id, query.ids).filter(Boolean));
|
|
const curatedActors = actors.map((actor) => curateGraphqlActor(actor));
|
|
|
|
if (query.ids) {
|
|
return curatedActors;
|
|
}
|
|
|
|
return curatedActors[0];
|
|
}
|
|
|
|
export async function createActorApi(req, res) {
|
|
const actor = await createActor(req.body.actor, omit(req.body, ['actor']), req.user);
|
|
|
|
res.send(stringify({ actor }));
|
|
}
|
|
|
|
export async function mergeActorsApi(req, res) {
|
|
const result = await mergeActors(
|
|
Number(req.params.targetActorId),
|
|
req.params.sourceActorIds.split(',').map((actorId) => Number(actorId)),
|
|
req.body.comment,
|
|
req.user,
|
|
);
|
|
|
|
res.send(stringify(result));
|
|
}
|
|
|
|
async function fetchActorRevisionsApi(req, res) {
|
|
const revisions = await fetchActorRevisions(Number(req.params.revisionId) || null, req.query, req.user);
|
|
|
|
res.send(stringify(revisions));
|
|
}
|
|
|
|
async function createActorRevisionApi(req, res) {
|
|
await createActorRevision(Number(req.body.actorId), req.body, req.user);
|
|
|
|
res.status(204).send();
|
|
}
|
|
|
|
async function reviewActorRevisionApi(req, res) {
|
|
await reviewActorRevision(Number(req.params.revisionId), req.body.isApproved, req.body, req.user);
|
|
|
|
res.status(204).send();
|
|
}
|
|
|
|
export const actorsRouter = Router();
|
|
|
|
actorsRouter.get('/api/actors', fetchActorsApi);
|
|
actorsRouter.post('/api/actors', createActorApi);
|
|
|
|
actorsRouter.post('/api/actors/:targetActorId/merge/:sourceActorIds', mergeActorsApi);
|
|
|
|
actorsRouter.get('/api/revisions/actors', fetchActorRevisionsApi);
|
|
actorsRouter.get('/api/revisions/actors/:revisionId', fetchActorRevisionsApi);
|
|
actorsRouter.post('/api/revisions/actors', createActorRevisionApi);
|
|
actorsRouter.post('/api/revisions/actors/:revisionId/reviews', reviewActorRevisionApi);
|