diff --git a/package-lock.json b/package-lock.json index 2df62f6b..4ed62b0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4527,6 +4527,11 @@ } } }, + "faker": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.1.0.tgz", + "integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw==" + }, "fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", diff --git a/package.json b/package.json index 1f0ff555..dbb90144 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "express-promise-router": "^3.0.3", "express-react-views": "^0.11.0", "face-api.js": "^0.21.0", + "faker": "^5.1.0", "file-type": "^14.1.4", "fluent-ffmpeg": "^2.1.2", "fs-extra": "^7.0.1", diff --git a/public/img/tags/airtight/8.jpeg b/public/img/tags/airtight/8.jpeg new file mode 100644 index 00000000..7e27f50b Binary files /dev/null and b/public/img/tags/airtight/8.jpeg differ diff --git a/public/img/tags/airtight/lazy/8.jpeg b/public/img/tags/airtight/lazy/8.jpeg new file mode 100644 index 00000000..2506a685 Binary files /dev/null and b/public/img/tags/airtight/lazy/8.jpeg differ diff --git a/public/img/tags/airtight/thumbs/8.jpeg b/public/img/tags/airtight/thumbs/8.jpeg new file mode 100644 index 00000000..81d092a5 Binary files /dev/null and b/public/img/tags/airtight/thumbs/8.jpeg differ diff --git a/seeds/04_media.js b/seeds/04_media.js index ef04ec87..083c7a77 100644 --- a/seeds/04_media.js +++ b/seeds/04_media.js @@ -675,6 +675,7 @@ const tagPhotos = [ ['69', 2, 'Abigail Mac and Kissa Sins in "Lesbian Anal Workout" for HardX'], ['airtight', 6, 'Remy Lacroix in "Ass Worship 14" for Jules Jordan'], ['airtight', 2, 'Dakota Skye in "Dakota Goes Nuts" for ArchAngel'], + ['airtight', 8, 'Veronica Leal in LegalPorno SZ2520'], ['airtight', 5, 'Chloe Amour in "DP Masters 4" for Jules Jordan'], ['airtight', 1, 'Jynx Maze in "Pump My Ass Full of Cum 3" for Jules Jordan'], ['airtight', 3, 'Anita Bellini in "Triple Dick Gangbang" for Hands On Hardcore (DDF Network)'], diff --git a/src/media.js b/src/media.js index 379b8bd7..5995c227 100644 --- a/src/media.js +++ b/src/media.js @@ -761,7 +761,7 @@ async function flushOrphanedMedia() { knex('releases_teasers').select('media_id'), knex('movies_covers').select('media_id'), knex('movies_trailers').select('media_id'), - knex('actors_avatars').select('media_id'), + knex('actors_profiles').select('avatar_media_id').as('media_id'), knex('actors_photos').select('media_id'), knex('clips_photos').select('media_id'), knex('clips_posters').select('media_id'), diff --git a/src/scrapers/traxxx.js b/src/scrapers/traxxx.js index 6d943bbb..c3ed905a 100644 --- a/src/scrapers/traxxx.js +++ b/src/scrapers/traxxx.js @@ -1,14 +1,261 @@ 'use strict'; -async function fetchLatest() { - console.log('latest!'); - return [ - { - title: 'Hot chick arse fucked', - date: new Date(), - entryId: 'traxxx1', - }, - ]; +/* eslint-disable no-unused-vars */ + +const config = require('config'); +const faker = require('faker'); +const nanoid = require('nanoid'); +const moment = require('moment'); + +const knex = require('../knex'); +const capitalize = require('../utils/capitalize'); + +function random(array) { + return array[Math.floor(Math.random() * array.length)]; +} + +function femaleAdjective() { + return random([ + 'hot', + 'young', + 'new', + 'busty', + 'insatiable', + 'depraved', + 'horny', + 'flexible', + 'bubble butt', + 'voluptuous', + 'curvy', + 'skinny', + 'nerdy', + 'oiled', + 'tied up', + 'bound', + 'Asian', + 'Russian', + 'Latina', + 'ebony', + ]); +} + +function maleAdjective() { + return random([ + 'toned', + 'nerdy', + ]); +} + +function sceneAdjective() { + return random([ + 'first', + 'hottest', + 'wildest', + 'deepest', + ]); +} + +function groupSceneAdjective() { + return random([ + 'biggest', + ]); +} + +function dickAdjective() { + return random([ + 'big', + 'giant', + 'throbbing', + 'thick', + 'long', + 'monster', + `${Math.floor(Math.random() * 12) + 9} inch`, + ]); +} + +function femaleNoun() { + return random([ + 'MILF', + 'teen', + 'spinner', + 'coed', + 'redhead', + 'beauty', + 'blonde', + 'nympho', + 'brunette', + 'maid', + 'student', + 'dominatrix', + 'stepsister', + 'schoolgirl', + 'nurse', + ]); +} + +function maleNoun() { + return random([ + 'guy', + 'stud', + 'man', + 'boyfriend', + 'stranger', + 'stepbrother', + 'stepdad', + ]); +} + +function sceneNoun() { + return random([ + 'anal', + 'sex', + 'pounding', + ]); +} + +function groupSceneNoun() { + return random([ + 'double penetration', + 'gangbang', + 'airtight', + 'orgy', + 'bukkake', + 'double anal', + 'triple anal', + 'triple penetration', + ]); +} + +function bodyNoun() { + return random([ + 'ass', + 'asshole', + 'gaping asshole', + 'squirting pussy', + 'pussy', + 'cunt', + ]); +} + +function dickNoun() { + return random([ + 'dick', + 'cock', + 'BBC', + 'BWC', + ]); +} + +function verb() { + return random([ + 'fucked', + 'fingered', + 'fisted', + 'titty-fucked', + 'creampied', + 'facialized', + 'plowed', + 'creamed', + 'gaped', + 'dicked', + 'pounded', + 'manhandled', + 'facefucked', + 'ass-fucked', + 'analized', + 'banged', + 'sodomized', + ]); +} + +function groupVerb() { + return random([ + 'gangbanged', + 'DP\'d', + 'double dicked', + 'double penetrated', + ]); +} + +function title(release) { + if (release.actors.length > 3) { + // group scene + return capitalize(random([ + `${femaleAdjective()} ${femaleNoun()} gets ${groupVerb()} by ${release.actors.length - 1} ${maleNoun()}s`, + `${femaleNoun()} does her ${groupSceneAdjective()} ${groupSceneNoun()}`, + `${femaleNoun()} in ${sceneAdjective()} ${groupSceneNoun()}`, + `${femaleAdjective()} ${femaleNoun()}'s ${groupSceneNoun()} with ${release.actors.length - 1} ${dickNoun()}s`, + `${femaleAdjective()} ${femaleNoun()}'s ${release.actors.length - 1}-${dickNoun()} ${groupSceneNoun()}`, + `${sceneAdjective()} ${groupSceneNoun()} for ${femaleAdjective()} ${femaleNoun()}`, + ])); + } + + return capitalize(random([ + `${femaleAdjective()} ${femaleNoun()} gets ${verb()} by ${dickAdjective()} ${dickNoun()}`, + `${femaleAdjective()} ${femaleNoun()} gets her ${bodyNoun()} ${verb()}`, + `${femaleAdjective()} ${femaleNoun()} in her ${sceneAdjective()} ${sceneNoun()} scene`, + `${sceneAdjective()} ${sceneNoun()} for ${femaleAdjective()} ${femaleNoun()}`, + `${femaleAdjective()} ${femaleNoun()}'s ${sceneAdjective()} ${sceneNoun()} scene`, + `${femaleAdjective()} ${femaleNoun()} ${verb()} in her ${bodyNoun()}`, + `${femaleAdjective()} ${femaleNoun()}'s ${bodyNoun()} ${verb()}`, + `${femaleAdjective()} ${femaleNoun()} does ${sceneAdjective()} ${sceneNoun()} with ${dickAdjective()} ${dickNoun()}`, + ])); +} + +function gender() { + return random([ + 'female', + 'female', + 'female', + 'female', + 'female', + 'male', + 'male', + 'male', + 'transsexual', + ]); +} + +function actors(release) { + const length = release.tags.some(tag => ['dp', 'dap', 'gangbang'].includes(tag)) + ? Math.floor(Math.random() * 6) + 3 + : Math.floor(Math.random() * 3) + 2; + + return Array.from({ length }, () => ({ + name: faker.name.findName(), + gender: gender(), + })); +} + +async function fetchLatest(entity) { + return Promise.all(Array.from({ length: 100 }, async (value, index) => { + const release = {}; + + release.entryId = nanoid(); + release.date = moment().subtract(Math.floor(Math.random() * index), 'days').toDate(); + + const [poster, ...photos] = await knex('media') + .select('path') + .where('is_sfw', true) + .pluck('path') + .orderByRaw('random()') + .limit(Math.floor(Math.random() * 10) + 1); + + release.poster = `http://${config.web.host}:${config.web.port}/img/${poster}?id=${nanoid()}`; // ensure source is unique + release.photos = photos.map(photo => `http://${config.web.host}:${config.web.port}/img/${photo}?id=${nanoid()}`); + + release.tags = await knex('tags') + .select('name') + .where('priority', '>', 5) + .orderByRaw('random()') + .limit(faker.random.number({ min: 2, max: 15 })) + .pluck('name'); + + release.actors = actors(release); + release.title = title(release); + + return release; + })); } module.exports = {