Merge branch 'main' into graphql

This commit is contained in:
DebaucheryLibrarian 2024-06-25 02:43:13 +02:00
commit 80e9a6bf86
5 changed files with 33 additions and 177 deletions

4
package-lock.json generated
View File

@ -1,11 +1,11 @@
{ {
"name": "traxxx-web", "name": "traxxx-web",
"version": "0.25.5", "version": "0.25.7",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "0.25.5", "version": "0.25.7",
"dependencies": { "dependencies": {
"@brillout/json-serializer": "^0.5.8", "@brillout/json-serializer": "^0.5.8",
"@dicebear/collection": "^7.0.5", "@dicebear/collection": "^7.0.5",

View File

@ -78,5 +78,5 @@
"postcss-custom-media": "^10.0.2", "postcss-custom-media": "^10.0.2",
"postcss-nesting": "^12.0.2" "postcss-nesting": "^12.0.2"
}, },
"version": "0.25.5" "version": "0.25.7"
} }

View File

@ -105,6 +105,7 @@ const query = pageContext.urlParsed.search.q;
.page { .page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-grow: 1;
} }
.row { .row {

View File

@ -8,6 +8,7 @@ import { curateMedia } from './media.js';
import { fetchTagsById } from './tags.js'; import { fetchTagsById } from './tags.js';
import { fetchEntitiesById } from './entities.js'; import { fetchEntitiesById } from './entities.js';
import { curateStash } from './stashes.js'; import { curateStash } from './stashes.js';
import escape from '../utils/escape-manticore.js';
import promiseProps from '../utils/promise-props.js'; import promiseProps from '../utils/promise-props.js';
function curateMovie(rawMovie, assets) { function curateMovie(rawMovie, assets) {
@ -171,179 +172,6 @@ function curateOptions(options) {
}; };
} }
/*
function buildQuery(filters = {}) {
const query = {
bool: {
must: [],
},
};
let sort = [{ effective_date: 'desc' }];
if (!filters.scope || filters.scope === 'latest') {
query.bool.must.push({
range: {
effective_date: {
lte: Math.round(Date.now() / 1000),
},
},
});
}
if (filters.scope === 'upcoming') {
query.bool.must.push({
range: {
effective_date: {
gt: Math.round(Date.now() / 1000),
},
},
});
sort = [{ effective_date: 'asc' }];
}
if (filters.scope === 'new') {
sort = [{ created_at: 'desc' }, { effective_date: 'asc' }];
}
if (filters.scope === 'likes') {
sort = [{ stashed: 'desc' }, { effective_date: 'desc' }];
}
if (filters.scope === 'results') {
sort = [{ _score: 'desc' }, { effective_date: 'desc' }];
}
if (filters.query) {
query.bool.must.push({
bool: {
should: [
{ match: { title_filtered: filters.query } },
{ match: { actors: filters.query } },
{ match: { tags: filters.query } },
{ match: { channel_name: filters.query } },
{ match: { network_name: filters.query } },
{ match: { channel_slug: filters.query } },
{ match: { network_slug: filters.query } },
{ match: { meta: filters.query } }, // date
],
},
});
}
if (filters.tagIds) {
filters.tagIds.forEach((tagId) => {
query.bool.must.push({ equals: { 'any(tag_ids)': tagId } });
});
}
if (filters.entityId) {
query.bool.must.push({
bool: {
should: [
{ equals: { channel_id: filters.entityId } },
{ equals: { network_id: filters.entityId } },
],
},
});
}
if (filters.actorIds) {
filters.actorIds.forEach((actorId) => {
query.bool.must.push({ equals: { 'any(actor_ids)': actorId } });
});
}
if (filters.requireCover) {
query.bool.must.push({
equals: {
has_cover: 1,
},
});
}
return { query, sort };
}
function buildAggregates(options) {
const aggregates = {};
if (options.aggregateActors) {
aggregates.actorIds = {
terms: {
field: 'actor_ids',
size: config.database.manticore.maxAggregateSize,
},
// sort: [{ 'count(*)': { order: 'desc' } }],
};
}
if (options.aggregateTags) {
aggregates.tagIds = {
terms: {
field: 'tag_ids',
size: config.database.manticore.maxAggregateSize,
},
};
}
if (options.aggregateChannels) {
aggregates.channelIds = {
terms: {
field: 'channel_id',
size: config.database.manticore.maxAggregateSize,
},
};
}
return aggregates;
}
async function queryManticoreJson(filters, options) {
const { query, sort } = buildQuery(filters);
console.log('query', query.bool.must);
console.time('manticore');
const result = await searchApi.search({
index: 'movies',
query,
limit: options.limit,
offset: (options.page - 1) * options.limit,
sort,
aggs: buildAggregates(options),
options: {
max_matches: config.database.manticore.maxMatches,
max_query_time: config.database.manticore.maxQueryTime,
field_weights: {
title_filtered: 7,
actors: 10,
tags: 9,
meta: 6,
channel_name: 2,
channel_slug: 3,
network_name: 1,
network_slug: 1,
},
},
});
const movies = result.hits.hits.map((hit) => ({
id: hit._id,
...hit._source,
_score: hit._score,
}));
return {
movies,
total: result.hits.total,
aggregations: result.aggregations && Object.fromEntries(Object.entries(result.aggregations).map(([key, { buckets }]) => [key, buckets])),
};
}
*/
async function queryManticoreSql(filters, options) { async function queryManticoreSql(filters, options) {
const aggSize = config.database.manticore.maxAggregateSize; const aggSize = config.database.manticore.maxAggregateSize;
@ -393,7 +221,7 @@ async function queryManticoreSql(filters, options) {
} }
if (filters.query) { if (filters.query) {
builder.whereRaw('match(\'@!title :query:\', movies)', { query: filters.query }); builder.whereRaw('match(\'@!title :query:\', movies)', { query: escape(filters.query) });
} }
filters.tagIds?.forEach((tagId) => { filters.tagIds?.forEach((tagId) => {

27
src/web/graphql.js Normal file
View File

@ -0,0 +1,27 @@
import { graphql, buildSchema } from 'graphql';
import { scenesSchema, fetchScenesGraphql } from './scenes.js';
const schema = buildSchema(`
type Query {
scenes: [Scene]
}
${scenesSchema}
`);
const rootValue = {
scenes: fetchScenesGraphql,
};
export async function graphqlApi(req, res) {
const data = await graphql({
schema,
source: req.body.query,
variableValues: req.body.variables,
rootValue,
});
console.log(data);
res.send(data);
}