Using grid layout with thumbnails.
This commit is contained in:
parent
8eb2dcfd89
commit
e3558fc0c5
10
.eslintrc
10
.eslintrc
|
@ -1,15 +1,21 @@
|
|||
{
|
||||
"root": true,
|
||||
"parser": "babel-eslint",
|
||||
"extends": "airbnb-base",
|
||||
"extends": ["airbnb", "plugin:react/recommended"],
|
||||
"plugins": ["react"],
|
||||
"parserOptions": {
|
||||
"sourceType": "script",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"strict": 0,
|
||||
"no-unused-vars": ["error", {"argsIgnorePattern": "^_"}],
|
||||
"no-console": 0,
|
||||
"indent": ["error", 4],
|
||||
"max-len": [2, {"code": 200, "tabWidth": 4, "ignoreUrls": true}]
|
||||
"max-len": [2, {"code": 200, "tabWidth": 4, "ignoreUrls": true}],
|
||||
"react/jsx-uses-vars": 2,
|
||||
"react/jsx-indent": ["error", 4],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,32 +3,88 @@
|
|||
const React = require('react');
|
||||
const moment = require('moment');
|
||||
|
||||
const Layout = require('./layout.jsx');
|
||||
|
||||
class Home extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>ID</th>
|
||||
<th>Shoot ID / Entry ID</th>
|
||||
<th>Site</th>
|
||||
<th>Title</th>
|
||||
<th>Actors</th>
|
||||
<th>Tags</th>
|
||||
</tr>
|
||||
<Layout>
|
||||
<ul className="scenes">
|
||||
{this.props.releases.map(release => (
|
||||
<li key={release.id} className="scene">
|
||||
<a
|
||||
href={`/item/${release.id}`}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
src={`/${release.site.id}/${release.id}/0.jpg`}
|
||||
className="scene-thumbnail"
|
||||
/>
|
||||
</a>
|
||||
|
||||
{this.props.releases.map(release => (
|
||||
<tr key={release.id}>
|
||||
<td>{ moment(release.date).format('YYYY-MM-DD') }</td>
|
||||
<td>{ release.id }</td>
|
||||
<td>{ release.shootId || release.entryId }</td>
|
||||
<td>{ release.site.name }</td>
|
||||
<td>{ release.title }</td>
|
||||
<td>{ release.actors.map(actor => actor.name).join(', ') }</td>
|
||||
<td>{ release.tags.map(tag => tag.tag).join(', ') }</td>
|
||||
</tr>
|
||||
))}
|
||||
</table>
|
||||
<div className="scene-info">
|
||||
<a
|
||||
href={`/item/${release.id}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="scene-row scene-link"
|
||||
><h2 className="scene-title">{release.title}</h2></a>
|
||||
|
||||
<span className="scene-row">
|
||||
<a
|
||||
href={`/site/${release.site.id}`}
|
||||
className="scene-site site-link"
|
||||
>{release.site.name}</a>
|
||||
|
||||
<span>
|
||||
<a
|
||||
className="scene-network"
|
||||
href={`/network/${release.network.id}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>{release.network.name}</a>
|
||||
|
||||
<a
|
||||
href={release.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="scene-date"
|
||||
>{moment(release.date).format('YYYY-MM-DD')}</a>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="scene-row">
|
||||
<ul className="scene-actors nolist">{release.actors.map(actor =>
|
||||
<li
|
||||
key={actor.id}
|
||||
className="scene-actor"
|
||||
>
|
||||
<a
|
||||
href={`/actor/${actor.id}`}
|
||||
className="actor-link"
|
||||
>{actor.name}</a>
|
||||
</li>
|
||||
)}</ul>
|
||||
</span>
|
||||
|
||||
<span className="scene-row">
|
||||
<ul className="scene-tags nolist">{release.tags.map(tag =>
|
||||
<li
|
||||
key={tag.tag}
|
||||
className="scene-tag"
|
||||
>
|
||||
<a
|
||||
href={`/tag/${tag.tag}`}
|
||||
className="tag-link"
|
||||
>{tag.tag}</a>
|
||||
</li>
|
||||
)}</ul>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
|
||||
class Layout extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Traxxx</title>
|
||||
|
||||
<link href="/css/style.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{this.props.children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Layout;
|
|
@ -81,6 +81,7 @@ module.exports = {
|
|||
width: 30,
|
||||
},
|
||||
],
|
||||
thumbnailPath: '/home/niels/Pictures/traxxx',
|
||||
filename: {
|
||||
dateFormat: 'DD-MM-YYYY',
|
||||
actorsJoin: ', ',
|
||||
|
|
|
@ -969,6 +969,16 @@
|
|||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"aria-query": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
|
||||
"integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ast-types-flow": "0.0.7",
|
||||
"commander": "^2.11.0"
|
||||
}
|
||||
},
|
||||
"arr-diff": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
|
@ -994,6 +1004,16 @@
|
|||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"array-includes": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
|
||||
"integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-properties": "^1.1.2",
|
||||
"es-abstract": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"array-slice": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
|
||||
|
@ -1022,6 +1042,12 @@
|
|||
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
|
||||
},
|
||||
"ast-types-flow": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
|
||||
"integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
|
||||
"dev": true
|
||||
},
|
||||
"astral-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
|
||||
|
@ -1054,6 +1080,15 @@
|
|||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
||||
},
|
||||
"axobject-query": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
|
||||
"integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ast-types-flow": "0.0.7"
|
||||
}
|
||||
},
|
||||
"babel-eslint": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz",
|
||||
|
@ -1740,6 +1775,12 @@
|
|||
"lodash.get": "~4.4.2"
|
||||
}
|
||||
},
|
||||
"damerau-levenshtein": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz",
|
||||
"integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
|
@ -2079,6 +2120,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"eslint-config-airbnb": {
|
||||
"version": "17.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz",
|
||||
"integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"object.assign": "^4.1.0",
|
||||
"object.entries": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"eslint-config-airbnb-base": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz",
|
||||
|
@ -2140,6 +2192,57 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"eslint-plugin-jsx-a11y": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz",
|
||||
"integrity": "sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aria-query": "^3.0.0",
|
||||
"array-includes": "^3.0.3",
|
||||
"ast-types-flow": "^0.0.7",
|
||||
"axobject-query": "^2.0.2",
|
||||
"damerau-levenshtein": "^1.0.4",
|
||||
"emoji-regex": "^7.0.2",
|
||||
"has": "^1.0.3",
|
||||
"jsx-ast-utils": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"eslint-plugin-react": {
|
||||
"version": "7.13.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz",
|
||||
"integrity": "sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-includes": "^3.0.3",
|
||||
"doctrine": "^2.1.0",
|
||||
"has": "^1.0.3",
|
||||
"jsx-ast-utils": "^2.1.0",
|
||||
"object.fromentries": "^2.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"resolve": "^1.10.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"doctrine": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz",
|
||||
"integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-restricted-globals": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
|
||||
|
@ -4031,6 +4134,15 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"jsx-ast-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-includes": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"keypress": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz",
|
||||
|
@ -4668,6 +4780,18 @@
|
|||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"object.fromentries": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz",
|
||||
"integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-properties": "^1.1.2",
|
||||
"es-abstract": "^1.11.0",
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"object.map": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
"babel-eslint": "^10.0.1",
|
||||
"babel-preset-airbnb": "^3.2.0",
|
||||
"eslint": "^5.15.0",
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"eslint-config-airbnb": "^17.1.0",
|
||||
"eslint-plugin-import": "^2.16.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.1",
|
||||
"eslint-plugin-react": "^7.13.0",
|
||||
"eslint-watch": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nolist {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nolist li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.scenes {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.scene {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
margin: .5rem;
|
||||
height: 22rem;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
.scene-thumbnail {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.scene-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: .25rem .5rem;
|
||||
}
|
||||
|
||||
.scene-info {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.scene-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.scene-title {
|
||||
color: #000;
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.scene-site {
|
||||
font-weight: bold;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
.scene-date {
|
||||
color: #555;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
.scene-network {
|
||||
color: #555;
|
||||
margin: 0 .25rem 0 0;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
.scene-tags {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scene-actor,
|
||||
.scene-tag {
|
||||
margin: 0 .25rem 0 0;
|
||||
}
|
||||
|
||||
.scene-tag {
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
.scene-actor:not(:last-of-type)::after,
|
||||
.scene-tag:not(:last-of-type):after {
|
||||
content: ",";
|
||||
}
|
||||
|
||||
.site-link {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.actor-link,
|
||||
.tag-link {
|
||||
color: #000;
|
||||
}
|
|
@ -882,8 +882,8 @@ exports.seed = knex => Promise.resolve()
|
|||
network_id: 'kink',
|
||||
},
|
||||
{
|
||||
id: 'devinebitches',
|
||||
name: 'Devine Bitches',
|
||||
id: 'divinebitches',
|
||||
name: 'Divine Bitches',
|
||||
url: 'https://www.kink.com/channel/divinebitches',
|
||||
description: 'Beautiful Women Dominate Submissive Men With Pain, Humiliation And Strap-On Fucking. The best in femdom and bondage. Men on Divine Bitches respond with obedience, ass worship, cunt worship, oral servitude, pantyhose worship, and foot worship.',
|
||||
network_id: 'kink',
|
||||
|
@ -1008,7 +1008,7 @@ exports.seed = knex => Promise.resolve()
|
|||
network_id: 'kink',
|
||||
},
|
||||
{
|
||||
id: 'tspussyhunts',
|
||||
id: 'tspussyhunters',
|
||||
name: 'TS Pussy Hunters',
|
||||
url: 'https://www.kink.com/channel/tspussyhunters',
|
||||
description: 'Hot TS cocks prey on the wet pussies of submissive ladies who are fucked hard till they cum. Dominant TS femme fatales with the hardest dicks, the softest tits, and the worst intentions dominate, bind, and punish bitches on the ultimate transfucking porn site.',
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
const config = require('config');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const Promise = require('bluebird');
|
||||
const moment = require('moment');
|
||||
const bhttp = require('bhttp');
|
||||
|
||||
const argv = require('./argv');
|
||||
const knex = require('./knex');
|
||||
|
@ -75,9 +78,7 @@ async function findDuplicateReleases(latestReleases, _siteId) {
|
|||
}
|
||||
|
||||
async function storeReleases(releases = []) {
|
||||
return Promise.reduce(releases, async (acc, release) => {
|
||||
await acc;
|
||||
|
||||
return Promise.map(releases, async (release) => {
|
||||
const curatedRelease = {
|
||||
site_id: release.site.id,
|
||||
shoot_id: release.shootId || null,
|
||||
|
@ -115,7 +116,23 @@ async function storeReleases(releases = []) {
|
|||
release_id: releaseEntry.rows[0].id,
|
||||
})));
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (release.thumbnails && release.thumbnails.length > 0) {
|
||||
const thumbnailPath = path.join(config.thumbnailPath, release.site.id, releaseEntry.rows[0].id.toString());
|
||||
|
||||
await fs.mkdir(thumbnailPath, { recursive: true });
|
||||
|
||||
await Promise.map(release.thumbnails, async (thumbnailUrl, index) => {
|
||||
const res = await bhttp.get(thumbnailUrl);
|
||||
|
||||
await fs.writeFile(path.join(thumbnailPath, `${index}.jpg`), res.body);
|
||||
}, {
|
||||
concurrency: 2,
|
||||
});
|
||||
}
|
||||
}, {
|
||||
concurrency: 2,
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchNewReleases(scraper, site, afterDate, accReleases = [], page = 1) {
|
||||
|
@ -151,7 +168,7 @@ async function fetchNewReleases(scraper, site, afterDate, accReleases = [], page
|
|||
async function fetchReleases() {
|
||||
const sites = await accumulateIncludedSites();
|
||||
|
||||
const scenesPerSite = await Promise.all(sites.map(async (site) => {
|
||||
const scenesPerSite = await Promise.map(sites, async (site) => {
|
||||
const scraper = scrapers[site.id] || scrapers[site.network.id];
|
||||
|
||||
if (scraper) {
|
||||
|
@ -167,13 +184,18 @@ async function fetchReleases() {
|
|||
|
||||
if (argv.save) {
|
||||
const finalReleases = argv.deep
|
||||
? await Promise.all(newReleases.map(async (release) => {
|
||||
? await Promise.map(newReleases, async (release) => {
|
||||
if (release.url) {
|
||||
return fetchScene(release.url);
|
||||
const scene = await fetchScene(release.url, release);
|
||||
|
||||
return {
|
||||
...release,
|
||||
...scene,
|
||||
};
|
||||
}
|
||||
|
||||
return release;
|
||||
}), {
|
||||
}, {
|
||||
concurrency: 2,
|
||||
})
|
||||
: newReleases;
|
||||
|
@ -204,7 +226,9 @@ async function fetchReleases() {
|
|||
}
|
||||
|
||||
return [];
|
||||
}));
|
||||
}, {
|
||||
concurrency: 2,
|
||||
});
|
||||
|
||||
const accumulatedScenes = scenesPerSite.reduce((acc, siteScenes) => ([...acc, ...siteScenes]), []);
|
||||
const sortedScenes = accumulatedScenes.sort(({ date: dateA }, { date: dateB }) => moment(dateB).diff(dateA));
|
||||
|
|
|
@ -32,7 +32,11 @@ async function curateRelease(release) {
|
|||
site: {
|
||||
id: release.site_id,
|
||||
name: release.site_name,
|
||||
network: release.network_id,
|
||||
},
|
||||
network: {
|
||||
id: release.network_id,
|
||||
name: release.network_name,
|
||||
url: release.network_url,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -43,8 +47,9 @@ function curateReleases(releases) {
|
|||
|
||||
async function fetchReleases() {
|
||||
const releases = await knex('releases')
|
||||
.select('releases.*', 'sites.name as site_name')
|
||||
.select('releases.*', 'sites.name as site_name', 'sites.network_id', 'networks.name as network_name', 'networks.url as network_url')
|
||||
.leftJoin('sites', 'releases.site_id', 'sites.id')
|
||||
.leftJoin('networks', 'sites.network_id', 'networks.id')
|
||||
.orderBy('date', 'desc')
|
||||
.limit(100);
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@ function scrapeLatest(html, site) {
|
|||
const scenesElements = $('.update_details').toArray();
|
||||
|
||||
return scenesElements.map((element) => {
|
||||
const thumbnailElement = $(element).find('a img.thumbs');
|
||||
const thumbnailCount = Number(thumbnailElement.attr('cnt'));
|
||||
const thumbnails = Array.from({ length: thumbnailCount }, (value, index) => thumbnailElement.attr(`src${index}_1x`)).filter(thumbnailUrl => thumbnailUrl !== undefined);
|
||||
|
||||
const sceneLinkElement = $(element).children('a').eq(1);
|
||||
const url = sceneLinkElement.attr('href');
|
||||
const title = sceneLinkElement.text();
|
||||
|
@ -32,6 +36,7 @@ function scrapeLatest(html, site) {
|
|||
actors,
|
||||
date,
|
||||
site,
|
||||
thumbnails,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -41,6 +46,10 @@ function scrapeUpcoming(html, site) {
|
|||
const scenesElements = $('#coming_soon_carousel').find('.table').toArray();
|
||||
|
||||
return scenesElements.map((element) => {
|
||||
const thumbnailElement = $(element).find('a img.thumbs');
|
||||
const thumbnailCount = Number(thumbnailElement.attr('cnt'));
|
||||
const thumbnails = Array.from({ length: thumbnailCount }, (value, index) => thumbnailElement.attr(`src${index}_1x`)).filter(thumbnailUrl => thumbnailUrl !== undefined);
|
||||
|
||||
const shootId = $(element).find('.upcoming_updates_thumb').attr('id').match(/\d+/)[0];
|
||||
|
||||
const details = $(element).find('.update_details_comingsoon')
|
||||
|
@ -66,8 +75,9 @@ function scrapeUpcoming(html, site) {
|
|||
url: null,
|
||||
shootId,
|
||||
title,
|
||||
actors,
|
||||
date,
|
||||
actors,
|
||||
thumbnails,
|
||||
rating: null,
|
||||
site,
|
||||
};
|
||||
|
|
|
@ -18,6 +18,8 @@ function scrapeLatest(html, site) {
|
|||
const shootId = href.split('/')[2];
|
||||
const title = sceneLinkElement.text().trim();
|
||||
|
||||
const thumbnails = $(element).find('.rollover .roll-image').map((thumbnailIndex, thumbnailElement) => $(thumbnailElement).attr('data-imagesrc')).toArray();
|
||||
|
||||
const date = moment.utc($(element).find('.date').text(), 'MMM DD, YYYY').toDate();
|
||||
const actors = $(element).find('.shoot-thumb-models a').map((actorIndex, actorElement) => $(actorElement).text()).toArray();
|
||||
const stars = $(element).find('.average-rating').attr('data-rating') / 10;
|
||||
|
@ -33,6 +35,7 @@ function scrapeLatest(html, site) {
|
|||
title,
|
||||
actors,
|
||||
date,
|
||||
thumbnails,
|
||||
rating: {
|
||||
stars,
|
||||
},
|
||||
|
@ -49,6 +52,10 @@ async function scrapeScene(html, url, shootId, ratingRes, site) {
|
|||
const title = $('h1.shoot-title span.favorite-button').attr('data-title');
|
||||
const actorsRaw = $('.shoot-info p.starring');
|
||||
|
||||
const thumbnails = $('.gallery .thumb img').map((thumbnailIndex, thumbnailElement) => `https://cdnp.kink.com${$(thumbnailElement).attr('data-image-file')}`).toArray();
|
||||
const trailerVideo = $('.player span[data-type="trailer-src"]').attr('data-url');
|
||||
const trailerPoster = $('.player video#kink-player').attr('poster');
|
||||
|
||||
const date = moment.utc($(actorsRaw)
|
||||
.prev()
|
||||
.text()
|
||||
|
@ -78,6 +85,15 @@ async function scrapeScene(html, url, shootId, ratingRes, site) {
|
|||
date,
|
||||
actors,
|
||||
description,
|
||||
thumbnails,
|
||||
trailer: {
|
||||
video: {
|
||||
default: trailerVideo,
|
||||
sd: trailerVideo,
|
||||
hd: trailerVideo.replace('480p', '720p'),
|
||||
},
|
||||
poster: trailerPoster,
|
||||
},
|
||||
rating: {
|
||||
stars,
|
||||
},
|
||||
|
|
|
@ -12,6 +12,9 @@ function initServer() {
|
|||
const app = express();
|
||||
const router = Router();
|
||||
|
||||
app.use(express.static(config.thumbnailPath));
|
||||
app.use(express.static('public'));
|
||||
|
||||
app.set('views', path.join(__dirname, '../../assets/views'));
|
||||
app.set('view engine', 'jsx');
|
||||
app.engine('jsx', createEngine());
|
||||
|
|
Loading…
Reference in New Issue