diff --git a/assets/components/actor/actor.vue b/assets/components/actor/actor.vue index 3236ce93..b4e0939e 100644 --- a/assets/components/actor/actor.vue +++ b/assets/components/actor/actor.vue @@ -3,6 +3,8 @@ v-if="actor" class="content actor" > + +

{{ actor.name }}

@@ -61,17 +63,25 @@ diff --git a/assets/components/release/banner.vue b/assets/components/release/banner.vue index cba68eeb..ca1d3395 100644 --- a/assets/components/release/banner.vue +++ b/assets/components/release/banner.vue @@ -96,8 +96,7 @@ export default { } .item { - height: 100%; - max-height: 18rem; + height: 18rem; vertical-align: middle; } diff --git a/assets/components/release/release.vue b/assets/components/release/release.vue index 2aa20196..894adb28 100644 --- a/assets/components/release/release.vue +++ b/assets/components/release/release.vue @@ -9,28 +9,27 @@
- - {{ formatDate(release.date, 'MMMM D, YYYY') }} - + - - - {{ formatDate(release.date, 'MMM D, YYYY') }} + + + {{ formatDate(release.date, 'MMM D, YYYY') }} + {{ formatDate(release.date, 'MMMM D, YYYY') }} + +
diff --git a/assets/components/tag/tag.vue b/assets/components/tag/tag.vue index 336bb645..e73bb7bf 100644 --- a/assets/components/tag/tag.vue +++ b/assets/components/tag/tag.vue @@ -3,6 +3,8 @@ v-if="tag" class="content tag" > + +

@@ -30,17 +32,25 @@ diff --git a/assets/components/tile/release.vue b/assets/components/tile/release.vue index a788c89b..a0d95cd4 100644 --- a/assets/components/tile/release.vue +++ b/assets/components/tile/release.vue @@ -18,9 +18,10 @@ + +female + + diff --git a/assets/img/male.svg b/assets/img/male.svg new file mode 100644 index 00000000..068da80a --- /dev/null +++ b/assets/img/male.svg @@ -0,0 +1,5 @@ + + +male + + diff --git a/assets/img/sun3.svg b/assets/img/sun3.svg new file mode 100644 index 00000000..54b6a535 --- /dev/null +++ b/assets/img/sun3.svg @@ -0,0 +1,5 @@ + + +sun3 + + diff --git a/assets/js/actors/actions.js b/assets/js/actors/actions.js index 86d2d66a..a7fe35ff 100644 --- a/assets/js/actors/actions.js +++ b/assets/js/actors/actions.js @@ -1,6 +1,6 @@ import { get } from '../api'; -function initActorActions(_store, _router) { +function initActorActions(store, _router) { async function fetchActors({ _commit }, actorId) { const networks = await get(`/actors/${actorId || ''}`); @@ -8,7 +8,11 @@ function initActorActions(_store, _router) { } async function fetchActorReleases({ _commit }, actorId) { - const releases = await get(`/actors/${actorId}/releases`); + const releases = await get(`/actors/${actorId}/releases`, { + filter: store.state.ui.filter, + after: store.getters.after, + before: store.getters.before, + }); return releases; } diff --git a/assets/js/main.js b/assets/js/main.js index 07393365..03868b7e 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -29,6 +29,8 @@ function init() { }, methods: { formatDate: (date, format) => dayjs(date).format(format), + isAfter: (dateA, dateB) => dayjs(dateA).isAfter(dateB), + isBefore: (dateA, dateB) => dayjs(dateA).isBefore(dateB), }, }); diff --git a/assets/js/sites/actions.js b/assets/js/sites/actions.js index 552ce372..446324c2 100644 --- a/assets/js/sites/actions.js +++ b/assets/js/sites/actions.js @@ -1,6 +1,6 @@ import { get } from '../api'; -function initSitesActions(_store, _router) { +function initSitesActions(store, _router) { async function fetchSites({ _commit }, siteId) { const sites = await get(`/sites/${siteId || ''}`); @@ -8,7 +8,11 @@ function initSitesActions(_store, _router) { } async function fetchSiteReleases({ _commit }, siteId) { - const releases = await get(`/sites/${siteId}/releases`); + const releases = await get(`/sites/${siteId}/releases`, { + filter: store.state.ui.filter, + after: store.getters.after, + before: store.getters.before, + }); return releases; } diff --git a/assets/js/tags/actions.js b/assets/js/tags/actions.js index b4e2bac1..894e73a9 100644 --- a/assets/js/tags/actions.js +++ b/assets/js/tags/actions.js @@ -1,6 +1,6 @@ import { get } from '../api'; -function initTagsActions(_store, _router) { +function initTagsActions(store, _router) { async function fetchTags({ _commit }, tagId) { const tags = await get(`/tags/${tagId || ''}`); @@ -8,7 +8,11 @@ function initTagsActions(_store, _router) { } async function fetchTagReleases({ _commit }, tagId) { - const releases = await get(`/tags/${tagId}/releases`); + const releases = await get(`/tags/${tagId}/releases`, { + filter: store.state.ui.filter, + after: store.getters.after, + before: store.getters.before, + }); return releases; } diff --git a/public/css/style.css b/public/css/style.css index af3b3eb2..6f2a959f 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -132,15 +132,31 @@ align-items: center; justify-content: space-between; position: absolute; + font-size: 0; } .site[data-v-3abcf101], .date[data-v-3abcf101] { color: #fff; background: rgba(0, 0, 0, 0.5); + position: relative; font-size: .8rem; padding: .25rem; text-decoration: none; } +.date.upcoming[data-v-3abcf101]:before { + content: ''; + color: #fff; + background: #ff6c88; + width: .25rem; + display: inline-block; + position: absolute; + top: 0; + bottom: 0; + left: -.75rem; + padding: .25rem; + font-size: .8rem; + font-weight: bold; +} .site[data-v-3abcf101] { font-weight: bold; } @@ -245,8 +261,7 @@ max-width: 100%; } .item[data-v-cbb14462] { - height: 100%; - max-height: 18rem; + height: 18rem; vertical-align: middle; } @@ -377,9 +392,12 @@ .hideable[data-v-2bc41e74] { display: none; } -.showable[data-v-2bc41e74] { +.row .showable[data-v-2bc41e74] { display: block; } +.tidbit .showable[data-v-2bc41e74] { + display: inline-block; +} .logo-site[data-v-2bc41e74] { width: 15rem; max-width: 100%; diff --git a/src/fetch-releases.js b/src/fetch-releases.js index b3206af6..ec063d2c 100644 --- a/src/fetch-releases.js +++ b/src/fetch-releases.js @@ -103,7 +103,7 @@ async function storeRelease(release) { likes: release.rating && release.rating.likes, dislikes: release.rating && release.rating.dislikes, rating: release.rating && release.rating.stars && Math.floor(release.rating.stars), - deep: argv.deep, + deep: Boolean(argv.deep && release.url && !release.upcoming), }; const releaseEntries = await knex('releases') @@ -201,13 +201,15 @@ async function fetchReleases() { const [newReleases, upcomingReleases] = await Promise.all([ fetchNewReleases(scraper, site, afterDate), - scraper.fetchUpcoming ? await scraper.fetchUpcoming(site) : [], + scraper.fetchUpcoming ? scraper.fetchUpcoming(site) : [], ]); console.log(`${site.name}: Found ${newReleases.length} recent releases, ${upcomingReleases.length} upcoming releases`); + const markedUpcomingReleases = upcomingReleases.map(release => ({ ...release, upcoming: true })); + const finalReleases = argv.deep - ? await Promise.map(newReleases, async (release) => { + ? await Promise.map([...newReleases, ...markedUpcomingReleases], async (release) => { if (release.url) { const scene = await fetchScene(release.url, release); diff --git a/src/scrapers/julesjordan.js b/src/scrapers/julesjordan.js index fe6abaa2..297a379d 100644 --- a/src/scrapers/julesjordan.js +++ b/src/scrapers/julesjordan.js @@ -7,6 +7,8 @@ const moment = require('moment'); const { matchTags } = require('../tags'); +const pluckPhotos = require('../utils/pluck-photos'); + async function fetchPhotos(url) { const res = await bhttp.get(url); @@ -23,7 +25,7 @@ function scrapePhotos(html) { return photos; } -async function getPhotos(entryId, page = 1) { +async function getPhotos(entryId, site, page = 1) { const albumUrl = `https://www.julesjordan.com/trial/gallery.php?id=${entryId}&type=highres&page=${page}`; const html = await fetchPhotos(albumUrl); @@ -41,7 +43,14 @@ async function getPhotos(entryId, page = 1) { concurrency: 2, }); - return photos.concat(otherPhotos.flat()); + const allPhotos = photos.concat(otherPhotos.flat()); + + const photoLimit = (site.network.parameters && site.network.parameters.photoLimit) || 25; + const photoIndexes = pluckPhotos(allPhotos.length - 1, photoLimit); + + const pluckedPhotos = photoIndexes.map(photoIndex => allPhotos[photoIndex]); + + return pluckedPhotos; } function scrapeLatest(html, site) { @@ -51,7 +60,7 @@ function scrapeLatest(html, site) { return scenesElements.map((element) => { const photoElement = $(element).find('a img.thumbs'); const photoCount = Number(photoElement.attr('cnt')); - const photos = Array.from({ length: photoCount }, (value, index) => photoElement.attr(`src${index}_1x`)).filter(photoUrl => photoUrl !== undefined); + const [poster, ...photos] = Array.from({ length: photoCount }, (value, index) => photoElement.attr(`src${index}_1x`)).filter(photoUrl => photoUrl !== undefined); const sceneLinkElement = $(element).children('a').eq(1); const url = sceneLinkElement.attr('href'); @@ -73,8 +82,9 @@ function scrapeLatest(html, site) { title, actors, date, - site, + poster, photos, + site, }; }); } @@ -84,10 +94,6 @@ function scrapeUpcoming(html, site) { const scenesElements = $('#coming_soon_carousel').find('.table').toArray(); return scenesElements.map((element) => { - const photoElement = $(element).find('a img.thumbs'); - const photoCount = Number(photoElement.attr('cnt')); - const photos = Array.from({ length: photoCount }, (value, index) => photoElement.attr(`src${index}_1x`)).filter(photoUrl => photoUrl !== undefined); - const entryId = $(element).find('.upcoming_updates_thumb').attr('id').match(/\d+/)[0]; const details = $(element).find('.update_details_comingsoon') @@ -109,13 +115,23 @@ function scrapeUpcoming(html, site) { .utc($(element).find('.update_date_comingsoon').text().slice(7), 'MM/DD/YYYY') .toDate(); + const photoElement = $(element).find('a img.thumbs'); + const poster = photoElement.attr('src'); + + const videoClass = $(element).find('.update_thumbnail div').attr('class'); + const videoScript = $(element).find(`script:contains(${videoClass})`).html(); + const trailer = videoScript.slice(videoScript.indexOf('https://'), videoScript.indexOf('.mp4') + 4); + return { url: null, entryId, title, date, actors, - photos, + poster, + trailer: { + src: trailer, + }, rating: null, site, }; @@ -148,7 +164,7 @@ async function scrapeScene(html, url, site) { const trailerLine = infoLines.find(line => line.match('movie["Trailer_720"]')); const trailer = trailerLine.slice(trailerLine.indexOf('path:"') + 6, trailerLine.indexOf('",movie')); - const photos = await getPhotos(entryId); + const photos = await getPhotos(entryId, site); const rawTags = $('.update_tags a').map((tagIndex, tagElement) => $(tagElement).text()).toArray(); const tags = await matchTags(rawTags); diff --git a/src/utils/pluck-photos.js b/src/utils/pluck-photos.js index f5b5d2f2..566c30be 100644 --- a/src/utils/pluck-photos.js +++ b/src/utils/pluck-photos.js @@ -2,7 +2,7 @@ // pick {photoLimit} photos evenly distributed photos from a set with {photoTotal} photos, return array of indexes starting at 1 function pluckPhotos(photoTotal, photoLimit) { - return [1].concat(Array.from({ length: photoLimit - 1 }, (value, index) => Math.floor((index + 1) * (photoTotal / (photoLimit - 1))))); + return [1].concat(Array.from({ length: photoLimit - 1 }, (value, index) => Math.round((index + 1) * (photoTotal / (photoLimit - 1))))); } module.exports = pluckPhotos; diff --git a/src/web/releases.js b/src/web/releases.js index ce5c6fe7..606b8215 100644 --- a/src/web/releases.js +++ b/src/web/releases.js @@ -29,7 +29,7 @@ async function fetchActorReleasesApi(req, res) { const releases = await fetchActorReleases({ id: actorId, slug: actorSlug, - }); + }, req.query); res.send(releases); } @@ -53,7 +53,7 @@ async function fetchSiteReleasesApi(req, res) { const releases = await fetchSiteReleases({ id: siteId, slug: siteSlug, - }); + }, req.query); res.send(releases); } @@ -65,7 +65,7 @@ async function fetchTagReleasesApi(req, res) { const releases = await fetchTagReleases({ id: tagId, slug: tagSlug, - }); + }, req.query); res.send(releases); }