diff --git a/assets/components/filters/filter-bar.vue b/assets/components/filters/filter-bar.vue
index 6f9ce732..9692b062 100644
--- a/assets/components/filters/filter-bar.vue
+++ b/assets/components/filters/filter-bar.vue
@@ -22,13 +22,13 @@
@@ -251,6 +251,14 @@ export default {
.filter-applied {
display: none;
}
+
+ .filters-filter:not(:last-child) .filter {
+ padding: 1rem .5rem;
+ }
+
+ .filters-filter:last-child .filter {
+ padding: 1rem 0 1rem .5rem;
+ }
}
@@ -312,7 +320,7 @@ export default {
}
}
-.filter {
+.filters-filter {
display: inline-block;
flex-shrink: 0;
diff --git a/config/default.js b/config/default.js
index 1d95a5cc..c343e340 100644
--- a/config/default.js
+++ b/config/default.js
@@ -161,14 +161,15 @@ module.exports = {
'pervertgallery',
'povperverts',
],
+ 'kellymadison',
'private',
'ddfnetwork',
'bangbros',
+ 'hitzefrei',
[
'silverstonedvd',
'silviasaint',
],
- 'kellymadison',
'gangbangcreampie',
'gloryholesecrets',
'aziani',
diff --git a/public/img/logos/hitzefrei/citycheck.png b/public/img/logos/hitzefrei/citycheck.png
new file mode 100644
index 00000000..c2e41429
Binary files /dev/null and b/public/img/logos/hitzefrei/citycheck.png differ
diff --git a/public/img/logos/hitzefrei/cuffemall.png b/public/img/logos/hitzefrei/cuffemall.png
new file mode 100644
index 00000000..e81deed6
Binary files /dev/null and b/public/img/logos/hitzefrei/cuffemall.png differ
diff --git a/public/img/logos/hitzefrei/familyaffairs.png b/public/img/logos/hitzefrei/familyaffairs.png
new file mode 100644
index 00000000..bddb0cab
Binary files /dev/null and b/public/img/logos/hitzefrei/familyaffairs.png differ
diff --git a/public/img/logos/hitzefrei/fanalarm.png b/public/img/logos/hitzefrei/fanalarm.png
new file mode 100644
index 00000000..834dcc29
Binary files /dev/null and b/public/img/logos/hitzefrei/fanalarm.png differ
diff --git a/public/img/logos/hitzefrei/favicon.png b/public/img/logos/hitzefrei/favicon.png
new file mode 100644
index 00000000..c9f92419
Binary files /dev/null and b/public/img/logos/hitzefrei/favicon.png differ
diff --git a/public/img/logos/hitzefrei/fuckonarrival.png b/public/img/logos/hitzefrei/fuckonarrival.png
new file mode 100644
index 00000000..e7a07cf8
Binary files /dev/null and b/public/img/logos/hitzefrei/fuckonarrival.png differ
diff --git a/public/img/logos/hitzefrei/lazy/citycheck.png b/public/img/logos/hitzefrei/lazy/citycheck.png
new file mode 100644
index 00000000..52d4e2bf
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/citycheck.png differ
diff --git a/public/img/logos/hitzefrei/lazy/cuffemall.png b/public/img/logos/hitzefrei/lazy/cuffemall.png
new file mode 100644
index 00000000..51441fca
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/cuffemall.png differ
diff --git a/public/img/logos/hitzefrei/lazy/familyaffairs.png b/public/img/logos/hitzefrei/lazy/familyaffairs.png
new file mode 100644
index 00000000..fee039d4
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/familyaffairs.png differ
diff --git a/public/img/logos/hitzefrei/lazy/fanalarm.png b/public/img/logos/hitzefrei/lazy/fanalarm.png
new file mode 100644
index 00000000..cdaeedd1
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/fanalarm.png differ
diff --git a/public/img/logos/hitzefrei/lazy/fuckonarrival.png b/public/img/logos/hitzefrei/lazy/fuckonarrival.png
new file mode 100644
index 00000000..f29f12ab
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/fuckonarrival.png differ
diff --git a/public/img/logos/hitzefrei/lazy/hitzefrei.png b/public/img/logos/hitzefrei/lazy/hitzefrei.png
new file mode 100644
index 00000000..490484a6
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/hitzefrei.png differ
diff --git a/public/img/logos/hitzefrei/lazy/milfhunters.png b/public/img/logos/hitzefrei/lazy/milfhunters.png
new file mode 100644
index 00000000..355829c4
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/milfhunters.png differ
diff --git a/public/img/logos/hitzefrei/lazy/network.png b/public/img/logos/hitzefrei/lazy/network.png
new file mode 100644
index 00000000..7eaa9d2b
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/network.png differ
diff --git a/public/img/logos/hitzefrei/lazy/pattisanals.png b/public/img/logos/hitzefrei/lazy/pattisanals.png
new file mode 100644
index 00000000..6066aef3
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/pattisanals.png differ
diff --git a/public/img/logos/hitzefrei/lazy/unleashed.png b/public/img/logos/hitzefrei/lazy/unleashed.png
new file mode 100644
index 00000000..497d57e4
Binary files /dev/null and b/public/img/logos/hitzefrei/lazy/unleashed.png differ
diff --git a/public/img/logos/hitzefrei/milfhunters.png b/public/img/logos/hitzefrei/milfhunters.png
new file mode 100644
index 00000000..d3cdc346
Binary files /dev/null and b/public/img/logos/hitzefrei/milfhunters.png differ
diff --git a/public/img/logos/hitzefrei/misc/hitzefrei.png b/public/img/logos/hitzefrei/misc/hitzefrei.png
new file mode 100644
index 00000000..31031c1b
Binary files /dev/null and b/public/img/logos/hitzefrei/misc/hitzefrei.png differ
diff --git a/public/img/logos/hitzefrei/network.png b/public/img/logos/hitzefrei/network.png
new file mode 100644
index 00000000..0fb143f5
Binary files /dev/null and b/public/img/logos/hitzefrei/network.png differ
diff --git a/public/img/logos/hitzefrei/pattisanals.png b/public/img/logos/hitzefrei/pattisanals.png
new file mode 100644
index 00000000..b979e9ed
Binary files /dev/null and b/public/img/logos/hitzefrei/pattisanals.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/citycheck.png b/public/img/logos/hitzefrei/thumbs/citycheck.png
new file mode 100644
index 00000000..0bc2b644
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/citycheck.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/cuffemall.png b/public/img/logos/hitzefrei/thumbs/cuffemall.png
new file mode 100644
index 00000000..82021932
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/cuffemall.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/familyaffairs.png b/public/img/logos/hitzefrei/thumbs/familyaffairs.png
new file mode 100644
index 00000000..9266cff5
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/familyaffairs.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/fanalarm.png b/public/img/logos/hitzefrei/thumbs/fanalarm.png
new file mode 100644
index 00000000..72e8cca9
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/fanalarm.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/fuckonarrival.png b/public/img/logos/hitzefrei/thumbs/fuckonarrival.png
new file mode 100644
index 00000000..9676c9af
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/fuckonarrival.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/hitzefrei.png b/public/img/logos/hitzefrei/thumbs/hitzefrei.png
new file mode 100644
index 00000000..84d5fb8e
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/hitzefrei.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/milfhunters.png b/public/img/logos/hitzefrei/thumbs/milfhunters.png
new file mode 100644
index 00000000..db7e740f
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/milfhunters.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/network.png b/public/img/logos/hitzefrei/thumbs/network.png
new file mode 100644
index 00000000..eaef2d28
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/network.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/pattisanals.png b/public/img/logos/hitzefrei/thumbs/pattisanals.png
new file mode 100644
index 00000000..935b6ed5
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/pattisanals.png differ
diff --git a/public/img/logos/hitzefrei/thumbs/unleashed.png b/public/img/logos/hitzefrei/thumbs/unleashed.png
new file mode 100644
index 00000000..c66571db
Binary files /dev/null and b/public/img/logos/hitzefrei/thumbs/unleashed.png differ
diff --git a/public/img/logos/hitzefrei/unleashed.png b/public/img/logos/hitzefrei/unleashed.png
new file mode 100644
index 00000000..6f27fa96
Binary files /dev/null and b/public/img/logos/hitzefrei/unleashed.png differ
diff --git a/seeds/01_networks.js b/seeds/01_networks.js
index e26f5d7d..504650d3 100644
--- a/seeds/01_networks.js
+++ b/seeds/01_networks.js
@@ -218,6 +218,11 @@ const networks = [
description: 'Girlsway.com has the best lesbian porn videos online! The hottest pornstars & first time lesbians in real girl on girl sex, tribbing, squirting & pussy licking action right HERE!',
parent: 'gamma',
},
+ {
+ slug: 'hitzefrei',
+ name: 'Hitzefrei',
+ url: 'http://www.hitzefrei.com',
+ },
{
slug: 'hussiepass',
name: 'Hussie Pass',
diff --git a/seeds/02_sites.js b/seeds/02_sites.js
index cff532f7..a0d96441 100644
--- a/seeds/02_sites.js
+++ b/seeds/02_sites.js
@@ -2354,6 +2354,83 @@ const sites = [
referer: 'https://www.girlsway.com',
},
},
+ // HITZEFREI
+ {
+ slug: 'unleashed',
+ name: 'Unleashed',
+ url: 'https://unleashed.hitzefrei.com',
+ parent: 'hitzefrei',
+ parameters: {
+ siteId: 10,
+ },
+ },
+ {
+ slug: 'citycheck',
+ name: 'City Check',
+ url: 'https://citycheck.hitzefrei.com',
+ parent: 'hitzefrei',
+ parameters: {
+ siteId: 3,
+ },
+ },
+ {
+ slug: 'milfhunters',
+ name: 'MILF Hunters',
+ url: 'https://milfhunters.hitzefrei.com',
+ parent: 'hitzefrei',
+ tags: ['milf'],
+ parameters: {
+ siteId: 7,
+ },
+ },
+ {
+ slug: 'cuffemall',
+ name: 'Cuff\'em All',
+ url: 'https://cuffemall.hitzefrei.com',
+ parent: 'hitzefrei',
+ parameters: {
+ siteId: 8,
+ },
+ },
+ {
+ slug: 'fanalarm',
+ name: 'fANALarm',
+ url: 'https://fanalarm.hitzefrei.com',
+ parent: 'hitzefrei',
+ tags: ['anal'],
+ parameters: {
+ siteId: 9,
+ },
+ },
+ {
+ slug: 'fuckonarrival',
+ name: 'Fuck On Arrival',
+ url: 'https://fuckonarrival.hitzefrei.com',
+ parent: 'hitzefrei',
+ parameters: {
+ siteId: 5,
+ },
+ },
+ {
+ slug: 'familyaffairs',
+ name: 'Family Affairs',
+ url: 'https://familyaffairs.hitzefrei.com',
+ parent: 'hitzefrei',
+ tags: ['family'],
+ parameters: {
+ siteId: 2,
+ },
+ },
+ {
+ slug: 'pattisanals',
+ name: 'Patti\'s Anals',
+ url: 'https://pattisanals.hitzefrei.com',
+ parent: 'hitzefrei',
+ tags: ['anal'],
+ parameters: {
+ siteId: 1,
+ },
+ },
// HUSSIE PASS
{
slug: 'hussiepass',
diff --git a/src/actors.js b/src/actors.js
index 0f091768..d3e879e8 100644
--- a/src/actors.js
+++ b/src/actors.js
@@ -97,11 +97,11 @@ function getMostFrequentDate(dates) {
const month = getMostFrequent(dates.map(dateX => dateX.getMonth()));
const date = getMostFrequent(dates.map(dateX => dateX.getDate()));
- if (year && month && date) {
- return moment({ year, month, date }).toDate();
+ if (year === null || month === null || date === null) {
+ return null;
}
- return null;
+ return moment({ year, month, date }).toDate();
}
function getLongest(items) {
@@ -216,7 +216,7 @@ function curateActorEntry(baseActor, batchId) {
name: baseActor.name,
slug: baseActor.slug,
entity_id: null,
- entry_id: baseActor.entry_id,
+ entry_id: baseActor.entryId,
batch_id: batchId,
};
}
@@ -615,6 +615,8 @@ async function scrapeActors(actorNames) {
const [batchId] = newBaseActors.length > 0 ? await knex('batches').insert({ comment: null }).returning('id') : [null];
const curatedActorEntries = batchId && curateActorEntries(newBaseActors, batchId);
+ // TODO: associate entity when entry ID is provided
+
const newActorEntries = batchId && await knex('actors')
.insert(curatedActorEntries)
.returning(['id', 'name', 'slug', 'entry_id']);
diff --git a/src/scrapers/brazzers.js b/src/scrapers/brazzers.js
index 4d0aa2d9..8e8ee34c 100644
--- a/src/scrapers/brazzers.js
+++ b/src/scrapers/brazzers.js
@@ -57,8 +57,8 @@ async function scrapeScene({ query, html }, url, _site) {
release.description = query.text('#scene-description p[itemprop="description"]');
release.date = query.date('.more-scene-info .scene-date', 'MMMM DD, YYYY');
- release.duration = Number(query.q('#trailer-player-container', 'data-duration')) // more accurate
- || Number(query.q('.scene-length[itemprop="duration"]', 'content').slice(1, -1) * 60);
+ release.duration = query.number('#trailer-player-container', 'data-duration') // more accurate
+ || query.number('.scene-length[itemprop="duration"]', 'content') * 60; // fallback
// actor cards have avatar, but truncated name
const actorImagesByActorId = query.imgs('.featured-model .card-image img').reduce((acc, img) => ({
diff --git a/src/scrapers/hitzefrei.js b/src/scrapers/hitzefrei.js
new file mode 100644
index 00000000..8edbfaf8
--- /dev/null
+++ b/src/scrapers/hitzefrei.js
@@ -0,0 +1,157 @@
+'use strict';
+
+const qu = require('../utils/qu');
+const http = require('../utils/http');
+const { lbsToKg, feetInchesToCm } = require('../utils/convert');
+const slugify = require('../utils/slugify');
+
+function scrapeAll(scenes) {
+ return scenes.map(({ query }) => {
+ const release = {};
+
+ release.url = query.url('.content-title a');
+ release.entryId = new URL(release.url).pathname.match(/\/view\/(\d+)/)[1];
+
+ release.title = query.cnt('.content-title a');
+ release.date = query.date('.content-date strong', 'DD/MM/YYYY');
+ release.duration = query.dur('.content-date');
+
+ release.actors = query.cnts('.content-models a');
+
+ release.poster = query.img('.content-thumbnail img, .large-thumbnail img') || query.poster('.content-thumbnail video, .large-thumbnail video');
+
+ const teaser = query.video('.vid-hover source');
+ release.teaser = { src: teaser };
+
+ release.channel = slugify(query.cnt('.content-site a'), '');
+
+ return release;
+ });
+}
+
+function scrapeScene({ query }, url) {
+ const release = {};
+
+ release.entryId = new URL(url).pathname.match(/\/view\/(\d+)/)[1];
+
+ release.title = query.cnt('.content-title');
+ release.description = query.cnt('.content-description p');
+
+ release.date = query.date('.content-metas span:nth-child(4)', 'DD/MM/YYYY');
+ release.duration = query.dur('.content-metas span:nth-child(2)');
+ release.likes = query.number('.content-metas span:nth-child(6)');
+
+ release.actors = query.all('.model-thumb img').map(el => ({
+ name: query.q(el, null, 'alt'),
+ avatar: query.img(el, null, 'src'),
+ }));
+
+ release.poster = query.poster('.content-video video');
+ release.photos = query.urls('#photo-carousel a').map(photo => [
+ photo.replace('/full', ''),
+ photo,
+ photo.replace('/full', '/thumbs'),
+ ]);
+
+ const trailer = query.video('.content-video source');
+ release.trailer = { src: trailer };
+
+ return release;
+}
+
+async function fetchActorScenes({ query }, accReleases = []) {
+ const releases = scrapeAll(qu.initAll(query.all('.container-large-video-thumb')));
+ const nextPage = query.url('.pagination li:nth-last-child(2) a');
+
+ if (nextPage) {
+ const res = await qu.get(nextPage);
+
+ if (res.ok) {
+ return fetchActorScenes(res.item, accReleases.concat(releases));
+ }
+ }
+
+ return accReleases.concat(releases);
+}
+
+async function scrapeProfile({ query }, include) {
+ const profile = {};
+
+ /*
+ const bio = query.all('.model-stats-info div div').reduce((acc, el) => ({
+ ...acc,
+ [slugify(query.cnt(el, '.stat-label'), '_')]: query.cnt(el, '.stat-value'),
+ }), {});
+ */
+
+ profile.dateOfBirth = query.date('.col-birtdate .stat-value, .col-birthdate .stat-value', 'YYYY-MM-DD'); // sic
+ profile.birthPlace = query.cnt('.col-birth .stat-value');
+
+ [profile.bust, profile.waist, profile.hip] = query.cnt('.col-measurements .stat-value').split('-').map(Number);
+ profile.height = feetInchesToCm(query.cnt('.col-height .stat-value'));
+ profile.weight = lbsToKg(query.number('.col-weight .stat-value'));
+
+ profile.eyes = query.cnt('.col-eyes .stat-value');
+ profile.hair = query.cnt('.col-hair .stat-value');
+
+ profile.description = query.cnt('.model-profile .model-profile');
+ profile.avatar = query.img('.model-thumbnail img');
+
+ if (include.releases) {
+ profile.releases = await fetchActorScenes({ query });
+ }
+
+ return profile;
+}
+
+async function fetchLatest(channel, page = 1) {
+ const res = await qu.getAll(`https://tour.hitzefrei.com/videos?site=${channel.parameters.siteId}&page=${page}`, '.hitem');
+
+ if (res.ok) {
+ return scrapeAll(res.items, channel);
+ }
+
+ return res.status;
+}
+
+async function fetchScene(url) {
+ const res = await qu.get(url, '#content-details');
+
+ if (res.ok) {
+ return scrapeScene(res.item, url);
+ }
+
+ return res.status;
+}
+
+async function fetchProfile(baseActor, entity, include) {
+ const searchRes = await http.post('https://tour.hitzefrei.com/search-preview', {
+ q: baseActor.name,
+ }, {
+ 'Accept-Language': 'en-US',
+ });
+
+ if (searchRes.ok) {
+ const actor = searchRes.body.find(result => result.type === 'model' && result.title === baseActor.name);
+
+ if (actor) {
+ const actorRes = await qu.get(actor.url);
+
+ if (actorRes.ok) {
+ return scrapeProfile(actorRes.item, include);
+ }
+
+ return actorRes.status;
+ }
+
+ return null;
+ }
+
+ return searchRes.status;
+}
+
+module.exports = {
+ fetchLatest,
+ fetchScene,
+ fetchProfile,
+};
diff --git a/src/scrapers/scrapers.js b/src/scrapers/scrapers.js
index 2162ac0b..bb5f7201 100644
--- a/src/scrapers/scrapers.js
+++ b/src/scrapers/scrapers.js
@@ -23,6 +23,7 @@ const fantasymassage = require('./fantasymassage');
const fcuk = require('./fcuk');
const fullpornnetwork = require('./fullpornnetwork');
const girlsway = require('./girlsway');
+const hitzefrei = require('./hitzefrei');
const hush = require('./hush');
const iconmale = require('./iconmale');
const insex = require('./insex');
@@ -101,6 +102,7 @@ module.exports = {
fullpornnetwork,
girlsway,
girlgirl: julesjordan,
+ hitzefrei,
hussiepass: hush,
hushpass: hush,
insex,
@@ -183,6 +185,7 @@ module.exports = {
girlfaction: fullpornnetwork,
gloryholesecrets: aziani,
hergape: fullpornnetwork,
+ hitzefrei,
homemadeanalwhores: fullpornnetwork,
hotcrazymess: nubiles,
hushpass: hush,