diff --git a/assets/components/tags/tags.vue b/assets/components/tags/tags.vue index dd4129cb..ee1b96e2 100644 --- a/assets/components/tags/tags.vue +++ b/assets/components/tags/tags.vue @@ -72,6 +72,7 @@ async function mounted() { roleplay: [ 'family', 'schoolgirl', + 'nurse', 'maid', ], tricks: [ diff --git a/assets/js/releases/actions.js b/assets/js/releases/actions.js index 19ded2d3..6bfb650c 100644 --- a/assets/js/releases/actions.js +++ b/assets/js/releases/actions.js @@ -37,51 +37,49 @@ function initReleasesActions(store, _router) { query: $query first: $limit ) { - release { + id + title + slug + date + url + type + isNew + site { id - title slug - date + name url - type - isNew - site { + network { id slug name url - network { - id - slug - name - url - } } - actors: releasesActors { - actor { - id - slug - name - } + } + actors: releasesActors { + actor { + id + slug + name } - tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) { - tag { - id - name - slug - } + } + tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) { + tag { + id + name + slug } - poster: releasesPosterByReleaseId { - media { - id - thumbnail - } + } + poster: releasesPosterByReleaseId { + media { + id + thumbnail } - covers: releasesCovers { - media { - id - thumbnail - } + } + covers: releasesCovers { + media { + id + thumbnail } } } @@ -93,7 +91,7 @@ function initReleasesActions(store, _router) { if (!res) return []; - return res.releases.map(release => curateRelease(release.release)); + return res.releases.map(release => curateRelease(release)); } async function fetchReleaseById({ _commit }, releaseId) { diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index 57a6e966..2512a8b9 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -18,7 +18,8 @@ exports.up = knex => Promise.resolve() .defaultTo(0); })) .then(() => knex.schema.createTable('media', (table) => { - table.increments('id', 16); + table.string('id', 21) + .primary(); table.string('path'); table.string('thumbnail'); @@ -35,7 +36,9 @@ exports.up = knex => Promise.resolve() table.string('scraper', 32); table.string('copyright', 100); - table.string('source', 1000); + + table.string('source', 2100); + table.string('source_page', 2100); table.text('comment'); table.string('group'); @@ -47,23 +50,23 @@ exports.up = knex => Promise.resolve() .defaultTo(knex.fn.now()); })) .then(() => knex.schema.createTable('media_sfw', (table) => { - table.increments('id', 12); + table.string('id', 21) + .primary(); - table.integer('media_id', 16) + table.string('media_id', 21) .references('id') - .inTable('media'); - - table.unique('media_id'); + .inTable('media') + .unique(); })) .then(() => knex.raw(` - CREATE FUNCTION get_random_sfw_media_id() RETURNS int AS $$ + CREATE FUNCTION get_random_sfw_media_id() RETURNS varchar AS $$ SELECT media_id FROM media_sfw ORDER BY random() LIMIT 1; $$ LANGUAGE sql STABLE; `)) .then(() => knex.schema.alterTable('media', (table) => { - table.integer('sfw_media_id', 16) + table.string('sfw_media_id', 21) .references('id') .inTable('media') .defaultTo(knex.raw('get_random_sfw_media_id()')); @@ -112,7 +115,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('tags'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -125,7 +128,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('tags'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -472,7 +475,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('actors'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -485,7 +488,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('actors'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -622,7 +625,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('releases'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -635,7 +638,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('releases'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -648,7 +651,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('releases'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -661,7 +664,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('releases'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -674,7 +677,7 @@ exports.up = knex => Promise.resolve() .references('id') .inTable('releases'); - table.integer('media_id', 16) + table.string('media_id', 21) .notNullable() .references('id') .inTable('media'); @@ -718,10 +721,12 @@ exports.up = knex => Promise.resolve() CREATE UNIQUE INDEX releases_search_unique ON releases_search (release_id); CREATE INDEX releases_search_index ON releases_search USING GIN (document); - CREATE FUNCTION search_releases(query text) RETURNS SETOF releases_search AS $$ - SELECT * FROM releases_search AS search - WHERE search.document @@ plainto_tsquery('traxxx', regexp_replace(query, '\\.|-|(XXX\\.[\\d+|hd|sd].*$)', ' ', 'ig')) - ORDER BY ts_rank(search.document, plainto_tsquery('traxxx', regexp_replace(query, '\\.|-|(XXX\\.[\\d+|hd|sd].*$)', ' ', 'ig'))) DESC; + CREATE FUNCTION search_releases(query text) RETURNS SETOF releases AS $$ + SELECT * FROM releases WHERE releases.id IN ( + SELECT release_id FROM releases_search AS search + WHERE search.document @@ plainto_tsquery('traxxx', regexp_replace(query, '\\.|-|(XXX\\.[\\d+|hd|sd].*$)', ' ', 'ig')) + ORDER BY ts_rank(search.document, plainto_tsquery('traxxx', regexp_replace(query, '\\.|-|(XXX\\.[\\d+|hd|sd].*$)', ' ', 'ig'))) DESC + ); $$ LANGUAGE SQL STABLE; CREATE FUNCTION search_sites(search text) RETURNS SETOF sites AS $$ diff --git a/public/img/logos/perfectgonzo/favicon.png b/public/img/logos/perfectgonzo/favicon.png index 6d9dd1aa..0680d364 100644 Binary files a/public/img/logos/perfectgonzo/favicon.png and b/public/img/logos/perfectgonzo/favicon.png differ diff --git a/public/img/tags/nurse/0.jpeg b/public/img/tags/nurse/0.jpeg new file mode 100644 index 00000000..4f8534f7 Binary files /dev/null and b/public/img/tags/nurse/0.jpeg differ diff --git a/public/img/tags/nurse/0_thumb.jpeg b/public/img/tags/nurse/0_thumb.jpeg new file mode 100644 index 00000000..1f1b1438 Binary files /dev/null and b/public/img/tags/nurse/0_thumb.jpeg differ diff --git a/public/index.html b/public/index.html deleted file mode 100644 index ac97df7c..00000000 --- a/public/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - traxxx - - - - - - - - - - -
- - diff --git a/seeds/00_tags.js b/seeds/00_tags.js index a5cb4937..311930e2 100644 --- a/seeds/00_tags.js +++ b/seeds/00_tags.js @@ -565,6 +565,11 @@ const tags = [ name: 'oil', slug: 'oil', }, + { + name: 'nurse', + slug: 'nurse', + group: 'roleplay', + }, { name: 'cum in mouth', slug: 'cum-in-mouth', diff --git a/seeds/04_media.js b/seeds/04_media.js index f1fd7692..1278baf4 100644 --- a/seeds/04_media.js +++ b/seeds/04_media.js @@ -1,3 +1,4 @@ +const nanoid = require('nanoid/non-secure'); const upsert = require('../src/utils/upsert'); const tagPosters = [ @@ -16,6 +17,7 @@ const tagPosters = [ ['bukkake', 'poster', 'Mia Malkova in "Facialized 2" for HardX'], ['caucasian', 0, 'Remy Lacroix for HardX'], ['creampie', 'poster', 'ALina Lopez in "Making Yourself Unforgettable" for Blacked'], + ['cum-in-mouth', 1, 'Keisha Grey in Brazzers House'], ['da-tp', 0, 'Natasha Teen in LegalPorno SZ2164'], ['deepthroat', 0, 'Chanel Grey in "Deepthroating Is Fun" for Throated'], ['double-anal', 7, 'Adriana Chechik in "DP Masters 6" for Jules Jordan'], @@ -35,7 +37,7 @@ const tagPosters = [ ['milf', 0, 'Olivia Austin in "Dredd 3" for Jules Jordan'], ['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'], ['mfm', 5, 'Vina Sky in "Slut Puppies 15" for Jules Jordan'], - ['cum-in-mouth', 1, 'Keisha Grey in Brazzers House'], + ['nurse', 0, 'Sarah Vandella in "Cum For Nurse Sarah" for Brazzers'], ['orgy', 1, 'Megan Rain (DP), Morgan Lee (anal), Jessa Rhodes, Melissa Moore and Kimmy Granger in "Orgy Masters 8" for Jules Jordan'], ['pussy-eating', 0, 'Elena Kosha and Ivy Wolfe in "Bare" for Jules Jordan'], ['redhead', 0, 'Penny Pax in "The Submission of Emma Marx: Boundaries" for New Sensations'], @@ -47,6 +49,7 @@ const tagPosters = [ ['triple-anal', 'poster', 'Kristy Black in SZ1986 for LegalPorno'], ] .map(([slug, filename, comment], index) => ({ + id: nanoid(), tagSlug: slug, path: `tags/${slug}/${filename}.jpeg`, thumbnail: `tags/${slug}/${filename}_thumb.jpeg`, @@ -103,6 +106,7 @@ const tagPhotos = [ ['cum-in-mouth', 'poster', 'Khloe Kapri'], ] .map(([slug, fileIndex, comment], index) => ({ + id: nanoid(), tagSlug: slug, path: `tags/${slug}/${fileIndex}.jpeg`, thumbnail: `tags/${slug}/${fileIndex}_thumb.jpeg`, @@ -715,6 +719,7 @@ const sfw = Object.entries({ ], }) .map(([category, photos]) => photos.map(([photo, copyright], index) => ({ + id: nanoid(), path: `sfw/${category}/${photo}.jpeg`, thumbnail: `sfw/${category}/thumbs/${photo}.jpeg`, mime: 'image/jpeg', @@ -730,7 +735,11 @@ const sfw = Object.entries({ exports.seed = knex => Promise.resolve() .then(async () => { const { inserted } = await upsert('media', sfw, 'path'); - const sfwMediaIds = inserted.map(mediaEntry => ({ media_id: mediaEntry.id })); + + const sfwMediaIds = inserted.map(mediaEntry => ({ + id: nanoid(), + media_id: mediaEntry.id, + })); await upsert('media_sfw', sfwMediaIds, 'media_id'); }) @@ -740,9 +749,9 @@ exports.seed = knex => Promise.resolve() const tags = await knex('tags').whereIn('slug', tagMedia.map(item => item.tagSlug)); const { inserted, updated } = await upsert('media', tagMedia.map(({ - path, thumbnail, mime, index, comment, + id, path, thumbnail, mime, index, comment, }) => ({ - path, thumbnail, mime, index, comment, + id, path, thumbnail, mime, index, comment, })), 'path', knex); const tagIdsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag.id }), {}); diff --git a/src/app.js b/src/app.js index 372d66bc..21f6893f 100644 --- a/src/app.js +++ b/src/app.js @@ -6,8 +6,7 @@ const initServer = require('./web/server'); const knex = require('./knex'); const fetchUpdates = require('./updates'); const { fetchScenes, fetchMovies } = require('./deep'); -const { storeReleases } = require('./store-releases'); -const { updateReleasesSearch } = require('./releases'); +const { storeReleases, updateReleasesSearch } = require('./store-releases'); const { scrapeActors } = require('./actors-legacy'); async function init() { @@ -38,8 +37,6 @@ async function init() { ...(deepScenes || []), ...(deepMovies || []), ]); - - // await storeReleaseActors(updateReleases); } knex.destroy(); diff --git a/src/media-legacy.js b/src/media-legacy.js index 3ace2b8a..5827e626 100644 --- a/src/media-legacy.js +++ b/src/media-legacy.js @@ -329,8 +329,6 @@ async function storeMedia(sources, domain, role, { entropyFilter = 2.5 } = {}) { return {}; } - console.log(presentSources, presentSources.length); - // split up source list to prevent excessive RAM usage const itemChunksBySource = await Promise.all(chunk(presentSources, 50).map(async (sourceChunk, index) => { try { diff --git a/src/media.js b/src/media.js index 83af21e5..c0b534f1 100644 --- a/src/media.js +++ b/src/media.js @@ -1,9 +1,170 @@ 'use strict'; -function toBaseAvatars() { +const Promise = require('bluebird'); +const nanoid = require('nanoid/non-secure'); +const logger = require('./logger')(__filename); +const argv = require('./argv'); +const knex = require('./knex'); +const { get } = require('./utils/qu'); + +function itemsByKey(items, key) { + return items.reduce((acc, item) => ({ ...acc, [item[key]]: item }), {}); +} + +function toBaseSource(rawSource) { + if (rawSource.src || (rawSource.extract && rawSource.url)) { + const baseSource = {}; + + if (rawSource.src) baseSource.src = rawSource.src; + if (rawSource.quality) baseSource.quality = rawSource.quality; + if (rawSource.type) baseSource.type = rawSource.type; + + if (rawSource.url) baseSource.url = rawSource.url; + if (rawSource.extract) baseSource.extract = rawSource.extract; + + return baseSource; + } + + if (typeof rawSource === 'string') { + return { + src: rawSource, + }; + } + + return null; +} + +function baseSourceToBaseMedia(baseSource) { + if (Array.isArray(baseSource)) { + if (baseSource.length > 0) { + return { + id: nanoid(), + sources: baseSource, + }; + } + + return null; + } + + if (baseSource) { + return { + id: nanoid(), + sources: [baseSource], + }; + } + + return null; +} + +function fallbackMediaToBaseMedia(rawMedia) { + const baseSources = rawMedia + .map(source => toBaseSource(source)) + .filter(Boolean); + + return baseSourceToBaseMedia(baseSources); +} + +function toBaseMedias(rawMedias) { + if (!rawMedias || rawMedias.length === 0) { + return []; + } + + return rawMedias.map((rawMedia) => { + if (!rawMedia) { + return null; + } + + if (Array.isArray(rawMedia)) { + // fallback sources provided + return fallbackMediaToBaseMedia(rawMedia); + } + + const baseSource = toBaseSource(rawMedia); + + return baseSourceToBaseMedia(baseSource); + }).filter(Boolean); +} + +async function findSourceDuplicates(baseMedias) { + const sourceUrls = baseMedias + .map(baseMedia => baseMedia.sources.map(source => source.src)) + .flat() + .filter(Boolean); + + const extractUrls = baseMedias + .map(baseMedia => baseMedia.sources.map(source => source.url)) + .flat() + .filter(Boolean); + + + const [existingSourceMedia, existingExtractMedia] = await Promise.all([ + knex('media').whereIn('source', sourceUrls), + knex('media').whereIn('source_page', extractUrls), + ]); + + const existingSourceMediaByUrl = itemsByKey(existingSourceMedia, 'source'); + const existingExtractMediaByUrl = itemsByKey(existingExtractMedia, 'source_page'); + + return { + existingSourceMediaByUrl, + existingExtractMediaByUrl, + }; +} + +async function extractSource(baseSource) { + if (!baseSource.extract || !baseSource.url) { + return baseSource; + } + + const res = await get(baseSource.url); + + console.log(res); + return baseSource; +} + +async function fetchSource(baseSource, { existingSourceMediaByUrl, existingExtractMediaByUrl }) { + // attempts + // extract + const extractedSource = await extractSource(baseSource, existingExtractMediaByUrl); + + console.log(extractedSource); +} + +async function fetchMedia(baseMedia, existingMedias) { + await baseMedia.sources.reduce((result, baseSource, _baseSourceIndex) => result.catch(async () => { + await fetchSource(baseSource, existingMedias); + }), Promise.reject(new Error())); +} + +async function storeMedias(baseMedias) { + const { existingSourceMediaByUrl, existingExtractMediaByUrl } = await findSourceDuplicates(baseMedias); + + await Promise.map(baseMedias, async baseMedia => fetchMedia(baseMedia, { existingSourceMediaByUrl, existingExtractMediaByUrl })); + + console.log(existingSourceMediaByUrl, existingExtractMediaByUrl); +} + +async function associateReleaseMedia(releases) { + if (!argv.media) { + return; + } + + const baseMediasByReleaseId = releases.reduce((acc, release) => ({ + ...acc, + [release.id]: { + poster: argv.images && argv.poster && toBaseMedias([release.poster]), + photos: argv.images && argv.photos && toBaseMedias(release.photos), + trailer: argv.videos && argv.trailer && toBaseMedias([release.trailer]), + teaser: argv.videos && argv.teaser && toBaseMedias([release.teaser]), + }, + }), {}); + + const baseMedias = Object.values(baseMediasByReleaseId).map(releaseMedia => Object.values(releaseMedia)).flat(2); + + await storeMedias(baseMedias); } module.exports = { - + associateReleaseMedia, }; diff --git a/src/releases.js b/src/releases.js index 612f666e..ecf59981 100644 --- a/src/releases.js +++ b/src/releases.js @@ -1,48 +1,20 @@ 'use strict'; -const logger = require('./logger')(__filename); const knex = require('./knex'); -async function updateReleasesSearch(releaseIds) { - logger.info(`Updating search documents for ${releaseIds ? releaseIds.length : 'all' } releases`); +async function fetchReleases(limit = 100) { + const releases = await knex('releases').limit(limit); - const documents = await knex.raw(` - SELECT - releases.id AS release_id, - TO_TSVECTOR( - 'traxxx', - releases.title || ' ' || - networks.name || ' ' || - networks.slug || ' ' || - networks.url || ' ' || - sites.name || ' ' || - sites.slug || ' ' || - COALESCE(sites.url, '') || ' ' || - COALESCE(sites.alias, '') || ' ' || - COALESCE(releases.shoot_id, '') || ' ' || - COALESCE(TO_CHAR(releases.date, 'YYYY YY MM FMMM FMmonth mon DD FMDD'), '') || ' ' || - STRING_AGG(COALESCE(actors.name, ''), ' ') || ' ' || - STRING_AGG(COALESCE(tags.name, ''), ' ') || ' ' || - STRING_AGG(COALESCE(tags_aliases.name, ''), ' ') - ) as document - FROM releases - LEFT JOIN sites ON releases.site_id = sites.id - LEFT JOIN networks ON sites.network_id = networks.id - LEFT JOIN releases_actors AS local_actors ON local_actors.release_id = releases.id - LEFT JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id - LEFT JOIN actors ON local_actors.actor_id = actors.id - LEFT JOIN tags ON local_tags.tag_id = tags.id - LEFT JOIN tags as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for - ${releaseIds ? 'WHERE releases.id = ANY(?)' : ''} - GROUP BY releases.id, sites.name, sites.slug, sites.alias, sites.url, networks.name, networks.slug, networks.url; - `, releaseIds && [releaseIds]); + return releases; +} - if (documents.rows?.length > 0) { - const query = knex('releases_search').insert(documents.rows).toString(); - await knex.raw(`${query} ON CONFLICT (release_id) DO UPDATE SET document = EXCLUDED.document`); - } +async function searchReleases(query, limit = 100) { + const releases = await knex.raw('SELECT * FROM search_releases(?) LIMIT ?;', [query, limit]); + + return releases.rows; } module.exports = { - updateReleasesSearch, + fetchReleases, + searchReleases, }; diff --git a/src/scrapers/dogfart.js b/src/scrapers/dogfart.js index a3d4f17b..acdcb80a 100644 --- a/src/scrapers/dogfart.js +++ b/src/scrapers/dogfart.js @@ -18,7 +18,7 @@ async function getPhotos(albumUrl) { const pageUrl = `https://blacksonblondes.com${lastPhotoPage.replace(/\d+.jpg/, `${(index + 1).toString().padStart(3, '0')}.jpg`)}`; return { - src: pageUrl, + url: pageUrl, extract: q => q('.scenes-module img', 'src'), }; }); diff --git a/src/store-releases.js b/src/store-releases.js index 1c84f8c6..39fbc63c 100644 --- a/src/store-releases.js +++ b/src/store-releases.js @@ -5,8 +5,9 @@ const config = require('config'); const logger = require('./logger')(__filename); const knex = require('./knex'); const slugify = require('./utils/slugify'); -const { associateTags } = require('./tags'); const { associateActors } = require('./actors'); +const { associateReleaseTags } = require('./tags'); +const { associateReleaseMedia } = require('./media'); function curateReleaseEntry(release, batchId, existingRelease) { const slug = slugify(release.title, '-', { @@ -149,6 +150,46 @@ async function filterDuplicateReleases(releases) { }; } +async function updateReleasesSearch(releaseIds) { + logger.info(`Updating search documents for ${releaseIds ? releaseIds.length : 'all' } releases`); + + const documents = await knex.raw(` + SELECT + releases.id AS release_id, + TO_TSVECTOR( + 'traxxx', + releases.title || ' ' || + networks.name || ' ' || + networks.slug || ' ' || + networks.url || ' ' || + sites.name || ' ' || + sites.slug || ' ' || + COALESCE(sites.url, '') || ' ' || + COALESCE(sites.alias, '') || ' ' || + COALESCE(releases.shoot_id, '') || ' ' || + COALESCE(TO_CHAR(releases.date, 'YYYY YY MM FMMM FMmonth mon DD FMDD'), '') || ' ' || + STRING_AGG(COALESCE(actors.name, ''), ' ') || ' ' || + STRING_AGG(COALESCE(tags.name, ''), ' ') || ' ' || + STRING_AGG(COALESCE(tags_aliases.name, ''), ' ') + ) as document + FROM releases + LEFT JOIN sites ON releases.site_id = sites.id + LEFT JOIN networks ON sites.network_id = networks.id + LEFT JOIN releases_actors AS local_actors ON local_actors.release_id = releases.id + LEFT JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id + LEFT JOIN actors ON local_actors.actor_id = actors.id + LEFT JOIN tags ON local_tags.tag_id = tags.id AND tags.priority >= 7 + LEFT JOIN tags as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for AND tags_aliases.secondary = true + ${releaseIds ? 'WHERE releases.id = ANY(?)' : ''} + GROUP BY releases.id, sites.name, sites.slug, sites.alias, sites.url, networks.name, networks.slug, networks.url; + `, releaseIds && [releaseIds]); + + if (documents.rows?.length > 0) { + const query = knex('releases_search').insert(documents.rows).toString(); + await knex.raw(`${query} ON CONFLICT (release_id) DO UPDATE SET document = EXCLUDED.document`); + } +} + async function storeReleases(releases) { const [batchId] = await knex('batches').insert({ comment: null }).returning('id'); @@ -169,15 +210,19 @@ async function storeReleases(releases) { const releasesWithId = attachReleaseIds([].concat(uniqueReleases, duplicateReleases), [].concat(storedReleaseEntries, duplicateReleaseEntries)); await Promise.all([ - associateTags(releasesWithId), associateActors(releasesWithId), + associateReleaseTags(releasesWithId), + associateReleaseMedia(releasesWithId), ]); logger.info(`Stored ${storedReleaseEntries.length} releases`); + await updateReleasesSearch(releasesWithId.map(release => release.id)); + return releasesWithId; } module.exports = { storeReleases, + updateReleasesSearch, }; diff --git a/src/tags.js b/src/tags.js index fa8d91a7..78333fdb 100644 --- a/src/tags.js +++ b/src/tags.js @@ -92,7 +92,7 @@ async function filterUniqueAssociations(tagAssociations) { return uniqueAssociations; } -async function associateTags(releases) { +async function associateReleaseTags(releases) { const tagIdsBySlug = await matchReleaseTags(releases); const siteTagIdsBySiteId = await getSiteTags(releases); @@ -103,5 +103,5 @@ async function associateTags(releases) { } module.exports = { - associateTags, + associateReleaseTags, }; diff --git a/src/updates.js b/src/updates.js index 2004f04e..0f383f83 100644 --- a/src/updates.js +++ b/src/updates.js @@ -62,13 +62,15 @@ function needNextPage(uniqueReleases, pageAccReleases) { return true; } - const oldestReleaseOnPage = uniqueReleases - .sort((releaseA, releaseB) => releaseB.date - releaseA.date) - .slice(-1)[0]; + if (uniqueReleases.every(release => !!release.date)) { + const oldestReleaseOnPage = uniqueReleases + .sort((releaseA, releaseB) => releaseB.date - releaseA.date) + .slice(-1)[0]; - if (oldestReleaseOnPage && moment(oldestReleaseOnPage.date).isAfter(afterDate)) { - // oldest release on page is newer than the specified date cut-off - return true; + if (moment(oldestReleaseOnPage.date).isAfter(afterDate)) { + // oldest release on page is newer than the specified date cut-off + return true; + } } // dates missing, and limit for scenes without dates not yet reached diff --git a/src/web/releases.js b/src/web/releases.js index 606b8215..2c24c1a3 100644 --- a/src/web/releases.js +++ b/src/web/releases.js @@ -1,80 +1,17 @@ 'use strict'; -const { - fetchReleases, - fetchActorReleases, - fetchNetworkReleases, - fetchSiteReleases, - fetchTagReleases, -} = require('../releases'); +const { fetchReleases, searchReleases } = require('../releases'); async function fetchReleasesApi(req, res) { - const releases = await fetchReleases({}, req.query); + const query = req.query.query || req.query.q; - res.send(releases); -} - -async function fetchReleaseByIdApi(req, res) { - const [release] = await fetchReleases({ - id: req.params.releaseId, - }); - - res.send(release); -} - -async function fetchActorReleasesApi(req, res) { - const actorId = Number.isInteger(Number(req.params.actorId)) ? Number(req.params.actorId) : null; - const actorSlug = typeof req.params.actorId === 'string' ? req.params.actorId : null; - - const releases = await fetchActorReleases({ - id: actorId, - slug: actorSlug, - }, req.query); - - res.send(releases); -} - -async function fetchNetworkReleasesApi(req, res) { - const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : null; - const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : null; - - const releases = await fetchNetworkReleases({ - id: networkId, - slug: networkSlug, - }, req.query); - - res.send(releases); -} - -async function fetchSiteReleasesApi(req, res) { - const siteId = typeof req.params.siteId === 'number' ? req.params.siteId : null; - const siteSlug = typeof req.params.siteId === 'string' ? req.params.siteId : null; - - const releases = await fetchSiteReleases({ - id: siteId, - slug: siteSlug, - }, req.query); - - res.send(releases); -} - -async function fetchTagReleasesApi(req, res) { - const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : null; - const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : null; - - const releases = await fetchTagReleases({ - id: tagId, - slug: tagSlug, - }, req.query); + const releases = query + ? await searchReleases(query, req.query.limit) + : await fetchReleases(req.query.limit); res.send(releases); } module.exports = { fetchReleases: fetchReleasesApi, - fetchReleaseById: fetchReleaseByIdApi, - fetchActorReleases: fetchActorReleasesApi, - fetchNetworkReleases: fetchNetworkReleasesApi, - fetchSiteReleases: fetchSiteReleasesApi, - fetchTagReleases: fetchTagReleasesApi, }; diff --git a/src/web/server.js b/src/web/server.js index 7f765160..43eee6f9 100644 --- a/src/web/server.js +++ b/src/web/server.js @@ -16,22 +16,8 @@ const { ActorPlugins, SitePlugins, ReleasePlugins } = require('./plugins/plugins const { fetchReleases, - fetchReleaseById, - fetchActorReleases, - fetchNetworkReleases, - fetchSiteReleases, - fetchTagReleases, } = require('./releases'); -const { - fetchNetworks, - fetchNetworksFromReleases, -} = require('./networks'); - -const { fetchActors } = require('./actors'); -const { fetchSites } = require('./sites'); -const { fetchTags } = require('./tags'); - function initServer() { const app = express(); const router = Router(); @@ -75,24 +61,6 @@ function initServer() { router.use(bodyParser.json({ strict: false })); router.get('/api/releases', fetchReleases); - router.get('/api/releases/:releaseId', fetchReleaseById); - router.get('/api/releases/networks', fetchNetworksFromReleases); - - router.get('/api/actors', fetchActors); - router.get('/api/actors/:actorId', fetchActors); - router.get('/api/actors/:actorId/releases', fetchActorReleases); - - router.get('/api/networks', fetchNetworks); - router.get('/api/networks/:networkId', fetchNetworks); - router.get('/api/networks/:networkId/releases', fetchNetworkReleases); - - router.get('/api/sites', fetchSites); - router.get('/api/sites/:siteId', fetchSites); - router.get('/api/sites/:siteId/releases', fetchSiteReleases); - - router.get('/api/tags', fetchTags); - router.get('/api/tags/:tagId', fetchTags); - router.get('/api/tags/:tagId/releases', fetchTagReleases); router.get('*', (req, res) => { res.render(path.join(__dirname, '../../assets/index.ejs'), {