Compare commits

..

No commits in common. "2b101c29671469c59f13d005a8512cec68a60570" and "5fb84d153e7b3dc6d5891ac613dbac558e696725" have entirely different histories.

29 changed files with 54 additions and 473 deletions

View File

@ -55,7 +55,7 @@ To build traxxx, run the following command:
`npm run build`
To generate thumbnails for new logos and tag photos, install ImageMagick and run:
To generate thumbnails for logos and tag photos, install ImageMagick and run:
`npm run logos-thumbs`

View File

@ -105,20 +105,18 @@ function sfw() {
}
function photos() {
const photosWithChapterPosters = (this.release.photos || []).concat(this.release.chapters ? this.release.chapters.map(chapter => chapter.poster) : []);
if (this.release.trailer || this.release.teaser) {
// poster will be on trailer video
return photosWithChapterPosters;
return this.release.photos;
}
if (this.release.poster) {
// no trailer, add poster to photos
return [this.release.poster].concat(this.release.photos).concat(photosWithChapterPosters);
return [this.release.poster].concat(this.release.photos);
}
// no poster available
return photosWithChapterPosters;
return this.release.photos;
}
export default {

View File

@ -53,7 +53,6 @@ export default {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(25rem, 1fr));
grid-gap: 1rem;
padding: 1rem;
}
@media(max-width: $breakpoint) {

View File

@ -99,51 +99,6 @@
<p class="description">{{ release.description }}</p>
</div>
<ul
v-if="release.chapters && release.chapters.length > 0"
class="chapters row nolist"
>
<span class="row-label">Chapters</span>
<li
v-for="chapter in release.chapters"
:key="`chapter-${chapter.id}`"
class="chapter"
>
<a
v-if="chapter.poster"
:href="`/media/${chapter.poster.path}`"
target="_blank"
rel="noopener noreferrer"
class="chapter-poster-link"
>
<img
:src="`/media/${chapter.poster.thumbnail}`"
class="chapter-poster"
>
</a>
<div class="chapter-info">
<div class="chapter-header">
<h3 class="chapter-title">{{ chapter.title }}</h3>
<span
v-if="chapter.duration"
class="chapter-duration"
>{{ chapter.duration }}</span>
</div>
<p
v-if="chapter.description"
class="chapter-description"
>{{ chapter.description }}</p>
<ul class="nolist"><li
v-for="tag in chapter.tags"
:key="`chapter-tag-${tag.id}`"
>{{ tag.name }}</li></ul>
</div>
</li>
</ul>
<div class="row row-tidbits">
<div
v-if="release.duration"
@ -188,32 +143,6 @@
<span class="row-label">Shoot date</span>
{{ formatDate(release.productionDate, 'MMMM D, YYYY') }}
</div>
<div
v-if="release.productionLocation"
class="row-tidbit"
>
<span class="row-label">Location</span>
<span class="location">
<span
v-if="release.productionLocation.city"
class="location-segment"
>{{ release.productionLocation.city }}, </span>
<span
v-if="release.productionLocation.state"
class="location-segment"
>{{ release.productionLocation.state }}, </span>
<span
v-if="release.productionLocation.country"
class="location-segment"
>{{ release.productionLocation.country.alias || release.productionLocation.country.name }}
<img
class="flag"
:src="`/img/flags/${release.productionLocation.country.alpha2.toLowerCase()}.svg`"
>
</span>
</span>
</div>
</div>
<div
@ -395,41 +324,6 @@ export default {
text-overflow: ellipsis;
}
.chapter {
display: flex;
background: var(--background);
box-shadow: 0 0 3px var(--shadow-weak);
margin: 0 0 .5rem 0;
}
.chapter-poster {
width: 12rem;
height: 100%;
object-fit: cover;
object-position: center;
}
.chapter-info {
flex-grow: 1;
padding: 1rem 1rem .5rem 1rem;
}
.chapter-header {
display: flex;
justify-content: space-between;
}
.chapter-title {
display: inline-block;
padding: 0;
margin: 0;
}
.flag {
height: 1rem;
margin: 0 0 -.15rem .1rem;
}
.link {
display: inline-flex;
color: var(--link);

View File

@ -69,7 +69,6 @@ function curateRelease(release) {
if (release.scenes) curatedRelease.scenes = release.scenes.map(({ scene }) => curateRelease(scene));
if (release.movies) curatedRelease.movies = release.movies.map(({ movie }) => curateRelease(movie));
if (release.chapters) curatedRelease.chapters = release.chapters.map(chapter => curateRelease(chapter));
if (release.photos) curatedRelease.photos = release.photos.map(({ media }) => media);
if (release.covers) curatedRelease.covers = release.covers.map(({ media }) => media);
if (release.trailer) curatedRelease.trailer = release.trailer.media;
@ -78,15 +77,6 @@ function curateRelease(release) {
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.map(({ tag }) => tag);
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.map(({ actor }) => curateActor(actor, curatedRelease));
if (release.productionLocation) {
curatedRelease.productionLocation = {
raw: release.productionLocation,
city: release.productionCity,
state: release.productionState,
country: release.productionCountry,
};
}
return curatedRelease;
}

View File

@ -237,14 +237,6 @@ const releaseFragment = `
createdAt
shootId
productionDate
productionLocation
productionCity
productionState
productionCountry: countryByProductionCountryAlpha2 {
alpha2
name
alias
}
comment
url
${releaseActorsFragment}
@ -255,35 +247,6 @@ const releaseFragment = `
${releaseTrailerFragment}
${releaseTeaserFragment}
${siteFragment}
chapters {
id
title
description
duration
tags: chaptersTags {
tag {
id
name
slug
}
}
poster: chaptersPosterByChapterId {
media {
index
path
thumbnail
lazy
comment
sfw: sfwMedia {
id
thumbnail
lazy
path
comment
}
}
}
}
studio {
id
name
@ -295,7 +258,7 @@ const releaseFragment = `
id
title
slug
covers: moviesCovers {
covers: moviesCoversByReleaseId {
media {
index
path

View File

@ -7,6 +7,8 @@ function initReleasesActions(store, _router) {
async function fetchReleases({ _commit }, { limit = 10, pageNumber = 1, range = 'latest' }) {
const { before, after, orderBy } = getDateRange(range);
console.log(after, before, orderBy);
const { connection: { releases, totalCount } } = await graphql(`
query Releases(
$limit:Int = 1000,
@ -87,7 +89,7 @@ function initReleasesActions(store, _router) {
type
}
}
covers: moviesCovers {
covers: moviesCoversByReleaseId {
media {
id
path
@ -137,14 +139,14 @@ function initReleasesActions(store, _router) {
lazy
}
}
covers: moviesCovers {
covers: moviesCoversByReleaseId {
media {
id
path
thumbnail
}
}
trailer: moviesTrailerByMovieId {
trailer: moviesTrailerByReleaseId {
media {
id
path

View File

@ -26,6 +26,8 @@ module.exports = {
'amberathome',
'marycarey',
'racqueldevonshire',
// boobpedia
'boobpedia',
// blowpass
'sunlustxxx',
// ddfnetwork

View File

@ -614,7 +614,6 @@ exports.up = knex => Promise.resolve()
table.text('shoot_id');
table.text('entry_id');
table.unique(['entity_id', 'entry_id']);
table.text('url', 1000);
@ -626,13 +625,6 @@ exports.up = knex => Promise.resolve()
table.date('production_date');
table.text('production_location');
table.text('production_city');
table.text('production_state');
table.text('production_country_alpha2', 2)
.references('alpha2')
.inTable('countries');
table.enum('date_precision', ['year', 'month', 'day', 'hour', 'minute', 'second'])
.defaultTo('day');
@ -829,7 +821,7 @@ exports.up = knex => Promise.resolve()
.defaultTo(knex.fn.now());
}))
.then(() => knex.schema.createTable('movies_covers', (table) => {
table.integer('movie_id', 16)
table.integer('release_id', 16)
.notNullable()
.references('id')
.inTable('movies');
@ -839,10 +831,10 @@ exports.up = knex => Promise.resolve()
.references('id')
.inTable('media');
table.unique(['movie_id', 'media_id']);
table.unique(['release_id', 'media_id']);
}))
.then(() => knex.schema.createTable('movies_trailers', (table) => {
table.integer('movie_id', 16)
table.integer('release_id', 16)
.unique()
.notNullable()
.references('id')
@ -853,74 +845,6 @@ exports.up = knex => Promise.resolve()
.references('id')
.inTable('media');
}))
.then(() => knex.schema.createTable('chapters', (table) => {
table.increments('id', 16);
table.integer('release_id', 12)
.references('id')
.inTable('releases')
.notNullable();
table.integer('chapter', 6);
table.unique(['release_id', 'chapter']);
table.text('title');
table.text('description');
table.integer('duration')
.unsigned();
table.integer('created_batch_id', 12)
.references('id')
.inTable('batches');
table.integer('updated_batch_id', 12)
.references('id')
.inTable('batches');
table.datetime('created_at')
.defaultTo(knex.fn.now());
}))
.then(() => knex.schema.createTable('chapters_posters', (table) => {
table.integer('chapter_id', 16)
.notNullable()
.references('id')
.inTable('chapters');
table.text('media_id', 21)
.notNullable()
.references('id')
.inTable('media');
table.unique('chapter_id');
}))
.then(() => knex.schema.createTable('chapters_photos', (table) => {
table.integer('chapter_id', 16)
.notNullable()
.references('id')
.inTable('chapters');
table.text('media_id', 21)
.notNullable()
.references('id')
.inTable('media');
table.unique(['chapter_id', 'media_id']);
}))
.then(() => knex.schema.createTable('chapters_tags', (table) => {
table.integer('tag_id', 12)
.notNullable()
.references('id')
.inTable('tags');
table.integer('chapter_id', 16)
.notNullable()
.references('id')
.inTable('chapters');
table.unique(['tag_id', 'chapter_id']);
}))
// SEARCH
.then(() => { // eslint-disable-line arrow-body-style
// allow vim fold
@ -1100,10 +1024,6 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP TABLE IF EXISTS movies_scenes CASCADE;
DROP TABLE IF EXISTS movies_trailers CASCADE;
DROP TABLE IF EXISTS chapters_tags CASCADE;
DROP TABLE IF EXISTS chapters_posters CASCADE;
DROP TABLE IF EXISTS chapters_photos CASCADE;
DROP TABLE IF EXISTS batches CASCADE;
DROP TABLE IF EXISTS actors_avatars CASCADE;
@ -1122,7 +1042,6 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP TABLE IF EXISTS tags_posters CASCADE;
DROP TABLE IF EXISTS tags_photos CASCADE;
DROP TABLE IF EXISTS movies CASCADE;
DROP TABLE IF EXISTS chapters CASCADE;
DROP TABLE IF EXISTS releases CASCADE;
DROP TABLE IF EXISTS actors CASCADE;
DROP TABLE IF EXISTS directors CASCADE;

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "traxxx",
"version": "1.123.0",
"version": "1.122.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "traxxx",
"version": "1.123.0",
"version": "1.122.1",
"description": "All the latest porn releases in one place",
"main": "src/app.js",
"scripts": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -57,11 +57,6 @@ const groups = [
];
const tags = [
{
name: '3d',
slug: '3d',
description: 'Available in 3D.',
},
{
name: '4K',
slug: '4k',

View File

@ -2645,12 +2645,6 @@ const sites = [
accFilter: true,
},
},
// IN THE CRACK
{
slug: 'inthecrack',
name: 'InTheCrack',
url: 'https://inthecrack.com/',
},
// INTERRACIAL PASS
{
slug: '2bigtobetrue',

View File

@ -608,7 +608,7 @@ async function scrapeActors(argNames) {
logger.info(`Scraping profiles for ${actorNames.length} actors`);
const sources = argv.actorsSources || config.profiles || Object.keys(scrapers.actors);
const sources = argv.sources || config.profiles || Object.keys(scrapers.actors);
const entitySlugs = sources.flat();
const [entities, existingActorEntries] = await Promise.all([

View File

@ -617,7 +617,7 @@ async function storeMedias(baseMedias) {
return [...newMediaWithEntries, ...existingHashMedias];
}
async function associateReleaseMedia(releases, type = 'release') {
async function associateReleaseMedia(releases, type = 'releases') {
if (!argv.media) {
return;
}
@ -664,7 +664,7 @@ async function associateReleaseMedia(releases, type = 'release') {
if (media) {
acc.push({
[`${type}_id`]: releaseId,
release_id: releaseId,
media_id: media.use || media.entry.id,
});
}
@ -675,7 +675,7 @@ async function associateReleaseMedia(releases, type = 'release') {
.filter(Boolean);
if (associations.length > 0) {
await bulkInsert(`${type}s_${role}`, associations, false);
await bulkInsert(`${type}_${role}`, associations, false);
}
}, Promise.resolve());
}

View File

@ -1,124 +0,0 @@
'use strict';
const moment = require('moment');
const qu = require('../utils/q');
const slugify = require('../utils/slugify');
function scrapeAll(scenes, channel) {
return scenes.map(({ query }) => {
const release = {};
release.url = query.url('a', 'href', { origin: channel.url });
release.entryId = new URL(release.url).pathname.match(/\/Collection\/(\d+)/)[1];
release.shootId = query.cnt('a span:nth-of-type(1)').match(/^\d+/)?.[0];
release.date = query.date('a span:nth-of-type(2)', 'YYYY-MM-DD');
release.actors = (query.q('a img', 'alt') || query.cnt('a span:nth-of-type(1)'))?.match(/[a-zA-Z]+(\s[A-Za-z]+)*/g);
release.poster = release.shootId
? `https://inthecrack.com/assets/images/posters/collections/${release.shootId}.jpg`
: query.img('a img', 'src', { origin: channel.url });
return release;
});
}
function scrapeScene({ query, html }, url, channel) {
const release = {};
release.entryId = new URL(url).pathname.match(/\/Collection\/(\d+)/)[1];
release.shootId = query.cnt('h2 span').match(/^\d+/)?.[0];
release.actors = query.cnt('h2 span')?.match(/[a-zA-Z]+(\s[A-Za-z]+)*/g);
release.description = query.cnt('p#CollectionDescription');
release.productionLocation = query.cnt('.modelCollectionHeader p')?.match(/Shoot Location: (.*)/)?.[1];
release.poster = qu.prefixUrl(html.match(/background-image: url\('(.*)'\)/)?.[1], channel.url);
release.chapters = query.all('.ClipOuter').map((el) => {
const chapter = {};
chapter.title = query.text(el, 'h4');
chapter.description = query.cnt(el, 'p');
chapter.duration = query.dur(el, '.InlineDuration');
const posterStyle = query.style(el, '.clipImage', 'background-image');
const poster = qu.prefixUrl(posterStyle.match(/url\((.*)\)/)?.[1], channel.url);
if (poster) {
const { origin, pathname } = new URL(poster);
chapter.poster = [
`${origin}${pathname}`, // full size
poster,
];
}
if (query.exists(el, '.ThreeDInfo')) {
chapter.tags = ['3d'];
}
return chapter;
});
return release;
}
function scrapeProfile({ query, el }, actorName, entity, include) {
const profile = {};
profile.description = query.cnt('.bio-text');
profile.birthPlace = query.cnt('.birth-place span');
profile.avatar = query.img('.actor-photo img');
if (include.releases) {
return scrapeAll(qu.initAll(el, '.scene'));
}
console.log(profile);
return profile;
}
async function fetchLatest(channel, page = 1) {
const year = moment().subtract(page - 1, ' year').year();
const url = `${channel.url}/Collections/Date/${year}`;
const res = await qu.getAll(url, '.collectionGridLayout li');
if (res.ok) {
return scrapeAll(res.items, channel);
}
return res.status;
}
async function fetchScene(url, channel) {
const res = await qu.get(url);
if (res.ok) {
return scrapeScene(res.item, url, channel);
}
return res.status;
}
async function fetchProfile({ name: actorName }, entity, include) {
const url = `${entity.url}/actors/${slugify(actorName, '_')}`;
const res = await qu.get(url);
if (res.ok) {
return scrapeProfile(res.item, actorName, entity, include);
}
return res.status;
}
module.exports = {
fetchLatest,
fetchScene,
// fetchProfile,
};

View File

@ -27,7 +27,6 @@ const hitzefrei = require('./hitzefrei');
const hush = require('./hush');
const iconmale = require('./iconmale');
const insex = require('./insex');
const inthecrack = require('./inthecrack');
const jayrock = require('./jayrock');
const jesseloadsmonsterfacials = require('./jesseloadsmonsterfacials');
const julesjordan = require('./julesjordan');
@ -109,7 +108,6 @@ module.exports = {
hushpass: hush,
insex,
interracialpass: hush,
inthecrack,
jayrock,
jesseloadsmonsterfacials,
julesjordan,

View File

@ -7,14 +7,13 @@ const logger = require('./logger')(__filename);
const knex = require('./knex');
const slugify = require('./utils/slugify');
const bulkInsert = require('./utils/bulk-insert');
const resolvePlace = require('./utils/resolve-place');
const { formatDate } = require('./utils/qu');
const { associateActors, scrapeActors } = require('./actors');
const { associateReleaseTags } = require('./tags');
const { curateEntity } = require('./entities');
const { associateReleaseMedia } = require('./media');
async function curateReleaseEntry(release, batchId, existingRelease, type = 'scene') {
function curateReleaseEntry(release, batchId, existingRelease, type = 'scene') {
const slugBase = release.title
|| (release.actors?.length && `${release.entity.slug} ${release.actors.map(actor => actor.name).join(' ')}`)
|| (release.date && `${release.entity.slug} ${formatDate(release.date, 'YYYY MM DD')}`)
@ -51,20 +50,6 @@ async function curateReleaseEntry(release, batchId, existingRelease, type = 'sce
curatedRelease.duration = release.duration;
}
if (release.productionLocation) {
curatedRelease.production_location = release.productionLocation;
if (argv.resolvePlace) {
const productionLocation = await resolvePlace(release.productionLocation);
if (productionLocation) {
curatedRelease.production_city = productionLocation.city;
curatedRelease.production_state = productionLocation.state;
curatedRelease.production_country_alpha2 = productionLocation.country;
}
}
}
if (!existingRelease && !release.id) {
curatedRelease.created_batch_id = batchId;
}
@ -243,46 +228,6 @@ async function updateReleasesSearch(releaseIds) {
}
}
async function storeChapters(releases) {
const chapters = releases.map(release => release.chapters?.map((chapter, index) => ({
title: chapter.title,
description: chapter.description,
releaseId: release.id,
chapter: index + 1,
duration: chapter.duration,
poster: chapter.poster,
photos: chapter.photos,
tags: chapter.tags,
}))).flat().filter(Boolean);
const curatedChapterEntries = chapters.map(chapter => ({
title: chapter.title,
description: chapter.description,
duration: chapter.duration,
release_id: chapter.releaseId,
chapter: chapter.chapter,
}));
const storedChapters = await bulkInsert('chapters', curatedChapterEntries);
const chapterIdsByReleaseIdAndChapter = storedChapters.reduce((acc, chapter) => ({
...acc,
[chapter.release_id]: {
...acc[chapter.release_id],
[chapter.chapter]: chapter.id,
},
}), {});
const chaptersWithId = chapters.map(chapter => ({
...chapter,
id: chapterIdsByReleaseIdAndChapter[chapter.releaseId][chapter.chapter],
}));
await associateReleaseTags(chaptersWithId, 'chapter');
// media is more error-prone, associate separately
await associateReleaseMedia(chaptersWithId, 'chapter');
}
async function storeScenes(releases) {
if (releases.length === 0) {
return [];
@ -296,7 +241,7 @@ async function storeScenes(releases) {
// uniqueness is entity ID + entry ID, filter uniques after adding entities
const { uniqueReleases, duplicateReleases, duplicateReleaseEntries } = await filterDuplicateReleases(releasesWithStudios);
const curatedNewReleaseEntries = await Promise.all(uniqueReleases.map(release => curateReleaseEntry(release, batchId)));
const curatedNewReleaseEntries = uniqueReleases.map(release => curateReleaseEntry(release, batchId));
const storedReleases = await bulkInsert('releases', curatedNewReleaseEntries);
// TODO: update duplicate releases
@ -318,8 +263,6 @@ async function storeScenes(releases) {
await scrapeActors(actors.map(actor => actor.name));
}
await storeChapters(releasesWithId);
logger.info(`Stored ${storedReleaseEntries.length} releases`);
return releasesWithId;
@ -360,13 +303,13 @@ async function storeMovies(movies, movieScenes) {
const { uniqueReleases } = await filterDuplicateReleases(movies);
const [batchId] = await knex('batches').insert({ comment: null }).returning('id');
const curatedMovieEntries = await Promise.all(uniqueReleases.map(release => curateReleaseEntry(release, batchId, null, 'movie')));
const curatedMovieEntries = uniqueReleases.map(release => curateReleaseEntry(release, batchId, null, 'movie'));
const storedMovies = await bulkInsert('movies', curatedMovieEntries, ['entity_id', 'entry_id'], true);
const moviesWithId = attachReleaseIds(movies, storedMovies);
await associateMovieScenes(moviesWithId, movieScenes);
await associateReleaseMedia(moviesWithId, 'movie');
await associateReleaseMedia(moviesWithId, 'movies');
return storedMovies;
}

View File

@ -2,7 +2,6 @@
const knex = require('./knex');
const slugify = require('./utils/slugify');
const bulkInsert = require('./utils/bulk-insert');
async function matchReleaseTags(releases) {
const rawTags = releases
@ -29,7 +28,7 @@ async function matchReleaseTags(releases) {
}
async function getEntityTags(releases) {
const entityIds = releases.map(release => release.entity?.id).filter(Boolean);
const entityIds = releases.map(release => release.entity.id);
const entityTags = await knex('entities_tags').whereIn('entity_id', entityIds);
const entityTagIdsByEntityId = entityTags.reduce((acc, entityTag) => {
@ -45,10 +44,10 @@ async function getEntityTags(releases) {
return entityTagIdsByEntityId;
}
function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntityId, type) {
function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntityId) {
const tagAssociations = releases
.map((release) => {
const entityTagIds = entityTagIdsByEntityId[release.entity?.id] || [];
const entityTagIds = entityTagIdsByEntityId[release.entity.id];
const releaseTags = release.tags || [];
const releaseTagIds = releaseTags.every(tag => typeof tag === 'number')
@ -62,7 +61,7 @@ function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntit
.filter(Boolean),
)]
.map(tagId => ({
[`${type}_id`]: release.id,
release_id: release.id,
tag_id: tagId,
}));
@ -73,13 +72,34 @@ function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntit
return tagAssociations;
}
async function associateReleaseTags(releases, type = 'release') {
async function filterUniqueAssociations(tagAssociations) {
const duplicateAssociations = await knex('releases_tags')
.whereIn(['release_id', 'tag_id'], tagAssociations.map(association => [association.release_id, association.tag_id]));
const duplicateAssociationsByReleaseIdAndTagId = duplicateAssociations.reduce((acc, association) => {
if (!acc[association.release_id]) {
acc[association.release_id] = {};
}
acc[association.release_id][association.tag_id] = true;
return acc;
}, {});
const uniqueAssociations = tagAssociations
.filter(association => !duplicateAssociationsByReleaseIdAndTagId[association.release_id]?.[association.tag_id]);
return uniqueAssociations;
}
async function associateReleaseTags(releases) {
const tagIdsBySlug = await matchReleaseTags(releases);
const EntityTagIdsByEntityId = await getEntityTags(releases);
const tagAssociations = buildReleaseTagAssociations(releases, tagIdsBySlug, EntityTagIdsByEntityId, type);
const tagAssociations = buildReleaseTagAssociations(releases, tagIdsBySlug, EntityTagIdsByEntityId);
const uniqueAssociations = await filterUniqueAssociations(tagAssociations);
await bulkInsert(`${type}s_tags`, tagAssociations, false);
await knex('releases_tags').insert(uniqueAssociations);
}
module.exports = {

View File

@ -4,10 +4,6 @@ const knex = require('../knex');
const chunk = require('./chunk');
async function bulkUpsert(table, items, conflict, update = true, chunkSize) {
if (items.length === 0) {
return [];
}
const updated = (conflict === false && ':query ON CONFLICT DO NOTHING RETURNING *;')
|| (conflict && update && `
:query ON CONFLICT (${conflict})

View File

@ -20,15 +20,7 @@ async function resolvePlace(query) {
const rawPlace = item.address;
const place = {};
if (item.class === 'place' || item.class === 'boundary') {
const location = rawPlace[item.type] || rawPlace.city || rawPlace.place;
if (location) {
place.place = location;
place.city = rawPlace.city || location;
}
}
if (rawPlace.city) place.city = rawPlace.city;
if (rawPlace.state) place.state = rawPlace.state;
if (rawPlace.country_code) place.country = rawPlace.country_code.toUpperCase();
if (rawPlace.continent) place.continent = rawPlace.continent;