diff --git a/assets/components/actors/actors.vue b/assets/components/actors/actors.vue
index 1fc0c6d0..13c437cd 100644
--- a/assets/components/actors/actors.vue
+++ b/assets/components/actors/actors.vue
@@ -14,6 +14,7 @@
:to="{ name: 'actors', params: { gender: 'male', letter } }"
:class="{ selected: gender === 'male' }"
class="gender-link male"
+ replace
>
@@ -21,6 +22,7 @@
:to="{ name: 'actors', params: { gender: 'trans', letter } }"
:class="{ selected: gender === 'trans' }"
class="gender-link transsexual"
+ replace
>
@@ -28,6 +30,7 @@
:to="{ name: 'actors', params: { gender: 'other', letter } }"
:class="{ selected: gender === 'other' }"
class="gender-link other"
+ replace
>
@@ -42,6 +45,7 @@
:to="{ name: 'actors', params: { gender, letter: letterX } }"
:class="{ selected: letterX === letter }"
class="letter-link"
+ replace
>{{ letterX || 'All' }}
diff --git a/assets/components/networks/network.vue b/assets/components/networks/network.vue
index 521a3ac2..c03c0988 100644
--- a/assets/components/networks/network.vue
+++ b/assets/components/networks/network.vue
@@ -130,30 +130,22 @@ import FilterBar from '../header/filter-bar.vue';
import Releases from '../releases/releases.vue';
import Sites from '../sites/sites.vue';
import Network from '../tile/network.vue';
+import Entity from '../tile/entity.vue';
async function fetchNetwork() {
- const { network, totalCount } = await this.$store.dispatch('fetchNetworkBySlug', {
- networkSlug: this.$route.params.networkSlug,
+ const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', {
+ entitySlug: this.$route.params.networkSlug,
+ entityType: 'network',
limit: this.limit,
range: this.$route.params.range,
pageNumber: Number(this.$route.params.pageNumber),
});
- this.network = network;
- this.totalCount = totalCount;
-
- if (this.network.studios) {
- this.studios = this.network.studios.map(studio => ({
- ...studio,
- network: this.network,
- }));
- }
-
- this.networks = this.network.networks;
- this.sites = this.network.sites
- .filter(site => !site.independent);
-
+ this.network = entity;
+ this.networks = this.network.children;
this.releases = this.network.releases;
+
+ this.totalCount = totalCount;
}
async function route() {
@@ -171,6 +163,7 @@ export default {
Releases,
Sites,
Network,
+ Entity,
},
data() {
return {
diff --git a/assets/components/networks/networks.vue b/assets/components/networks/networks.vue
index f7c4e3f1..73ede419 100644
--- a/assets/components/networks/networks.vue
+++ b/assets/components/networks/networks.vue
@@ -2,13 +2,13 @@
@@ -135,7 +133,7 @@ export default {
}
}
-.network-tiles {
+.entity-tiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
grid-gap: 1rem;
diff --git a/assets/components/releases/release.vue b/assets/components/releases/release.vue
index 2ad155fb..b2fb2a3d 100644
--- a/assets/components/releases/release.vue
+++ b/assets/components/releases/release.vue
@@ -211,25 +211,15 @@
target="_blank"
rel="noopener noreferrer"
class="link added"
- >{{ formatDate(release.dateAdded, 'MMMM D, YYYY') }}
+ >{{ formatDate(release.createdAt, 'MMMM D, YYYY HH:mm') }}
-
-
-
-
-
-
diff --git a/assets/components/tile/entity.vue b/assets/components/tile/entity.vue
new file mode 100644
index 00000000..f08c1d6e
--- /dev/null
+++ b/assets/components/tile/entity.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/components/tile/network.vue b/assets/components/tile/network.vue
index fbcae7d4..4b1c2f3f 100644
--- a/assets/components/tile/network.vue
+++ b/assets/components/tile/network.vue
@@ -1,33 +1,33 @@
-
-
-
+
+
+
@@ -39,7 +39,7 @@ export default {
background: var(--profile);
display: flex;
flex-shrink: 0;
- flex-direction: column;
+ justify-content: center;
align-items: center;
box-sizing: border-box;
padding: .5rem 1rem;
@@ -52,16 +52,9 @@ export default {
}
.logo {
- width: 100%;
- height: 100%;
- color: $text;
- display: flex;
- align-items: center;
- justify-content: center;
- object-fit: contain;
+ max-width: 100%;
+ max-height: 100%;
font-size: 1rem;
- font-weight: bold;
- /* filter: $logo-highlight; */
}
.title {
diff --git a/assets/js/curate.js b/assets/js/curate.js
index bb6c5d05..f9f12aff 100644
--- a/assets/js/curate.js
+++ b/assets/js/curate.js
@@ -100,6 +100,7 @@ function curateSite(site, network) {
function curateNetwork(network, releases) {
const curatedNetwork = {
+ ...network,
id: network.id,
name: network.name,
slug: network.slug,
@@ -116,6 +117,19 @@ function curateNetwork(network, releases) {
return curatedNetwork;
}
+function curateEntity(entity, parent, releases) {
+ const curatedEntity = {
+ ...entity,
+ children: [],
+ };
+
+ if (entity.parent || parent) curatedEntity.parent = curateEntity(entity.parent || parent);
+ if (entity.children) curatedEntity.children = entity.children.map(childEntity => curateEntity(childEntity, curatedEntity));
+ if (releases) curatedEntity.releases = releases.map(release => curateRelease(release));
+
+ return curatedEntity;
+}
+
function curateTag(tag) {
const curatedTag = {
...tag,
@@ -130,6 +144,7 @@ function curateTag(tag) {
export {
curateActor,
+ curateEntity,
curateRelease,
curateSite,
curateNetwork,
diff --git a/assets/js/entities/actions.js b/assets/js/entities/actions.js
new file mode 100644
index 00000000..7ad6f13e
--- /dev/null
+++ b/assets/js/entities/actions.js
@@ -0,0 +1,179 @@
+import { graphql } from '../api';
+// import { sitesFragment, releaseFields } from '../fragments';
+import { releaseFields } from '../fragments';
+import { curateEntity } from '../curate';
+import getDateRange from '../get-date-range';
+
+function initEntitiesActions(store, _router) {
+ async function fetchEntityBySlugAndType({ _commit }, {
+ entitySlug,
+ entityType,
+ limit = 10,
+ pageNumber = 1,
+ range = 'latest',
+ }) {
+ const { before, after, orderBy } = getDateRange(range);
+
+ const { entity, connection: { releases, totalCount } } = await graphql(`
+ query Entity(
+ $entitySlug: String!
+ $entityType: String! = "channel"
+ $limit: Int = 10,
+ $offset: Int = 0,
+ $after: Date = "1900-01-01",
+ $before: Date = "2100-01-01",
+ $afterTime: Datetime = "1900-01-01",
+ $beforeTime: Datetime = "2100-01-01",
+ $orderBy: [ReleasesOrderBy!]
+ $exclude: [String!]
+ ) {
+ entity: entityBySlugAndType(slug: $entitySlug, type: $entityType) {
+ id
+ name
+ slug
+ url
+ children: childEntities(
+ orderBy: [PRIORITY_DESC, NAME_ASC],
+ ) {
+ id
+ name
+ slug
+ url
+ type
+ priority
+ }
+ parent {
+ id
+ name
+ slug
+ type
+ url
+ }
+ }
+ connection: releasesConnection(
+ first: $limit
+ offset: $offset
+ orderBy: $orderBy
+ filter: {
+ entity: {
+ or: [
+ { parent: { slug: { equalTo: $entitySlug } } },
+ { parent: { parent: { slug: { equalTo: $entitySlug } } } }
+ ]
+ }
+ or: [
+ {
+ date: {
+ lessThan: $before,
+ greaterThan: $after
+ }
+ },
+ {
+ date: {
+ isNull: true
+ },
+ createdAt: {
+ lessThan: $beforeTime,
+ greaterThan: $afterTime,
+ }
+ }
+ ]
+ releasesTagsConnection: {
+ none: {
+ tag: {
+ slug: {
+ in: $exclude
+ }
+ }
+ }
+ }
+ }
+ ) {
+ releases: nodes {
+ ${releaseFields}
+ }
+ totalCount
+ }
+ }
+ `, {
+ entitySlug,
+ entityType,
+ limit,
+ offset: Math.max(0, (pageNumber - 1)) * limit,
+ after,
+ before,
+ orderBy,
+ afterTime: store.getters.after,
+ beforeTime: store.getters.before,
+ exclude: store.state.ui.filter,
+ });
+
+ return {
+ entity: curateEntity(entity, null, releases),
+ totalCount,
+ };
+ }
+
+ async function fetchEntities({ _commit }, { type }) {
+ const { entities } = await graphql(`
+ query Entities(
+ $type: String! = "network"
+ ) {
+ entities(
+ orderBy: NAME_ASC
+ filter: {
+ type: {
+ equalTo: $type
+ }
+ }
+ ) {
+ id
+ name
+ slug
+ type
+ url
+ }
+ }
+ `, { type });
+
+ return entities.map(entity => curateEntity(entity));
+ }
+
+ async function searchEntities({ _commit }, { query, limit = 20 }) {
+ const { entities } = await graphql(`
+ query SearchEntities(
+ $query: String!
+ $limit:Int = 20,
+ ) {
+ entities: searchEntities(
+ search: $query,
+ first: $limit
+ ) {
+ name
+ slug
+ type
+ url
+ parent {
+ name
+ slug
+ type
+ url
+ }
+ }
+ }
+ `, {
+ query,
+ limit,
+ });
+
+ return entities.map(entity => curateEntity(entity));
+ }
+
+ return {
+ fetchEntityBySlugAndType,
+ fetchEntities,
+ searchEntities,
+ };
+}
+
+export default initEntitiesActions;
diff --git a/assets/js/entities/entities.js b/assets/js/entities/entities.js
new file mode 100644
index 00000000..bc8e4faa
--- /dev/null
+++ b/assets/js/entities/entities.js
@@ -0,0 +1,13 @@
+import state from './state';
+import mutations from './mutations';
+import actions from './actions';
+
+function initEntitiesStore(store, router) {
+ return {
+ state,
+ mutations,
+ actions: actions(store, router),
+ };
+}
+
+export default initEntitiesStore;
diff --git a/assets/js/entities/mutations.js b/assets/js/entities/mutations.js
new file mode 100644
index 00000000..ff8b4c56
--- /dev/null
+++ b/assets/js/entities/mutations.js
@@ -0,0 +1 @@
+export default {};
diff --git a/assets/js/entities/state.js b/assets/js/entities/state.js
new file mode 100644
index 00000000..ff8b4c56
--- /dev/null
+++ b/assets/js/entities/state.js
@@ -0,0 +1 @@
+export default {};
diff --git a/assets/js/networks/actions.js b/assets/js/networks/actions.js
index c2887059..d2e9fcf5 100644
--- a/assets/js/networks/actions.js
+++ b/assets/js/networks/actions.js
@@ -25,7 +25,7 @@ function initNetworksActions(store, _router) {
$orderBy: [ReleasesOrderBy!]
$exclude: [String!]
) {
- network: entityBySlugAndType(slug: $networkSlug, type: 1) {
+ network: entityBySlugAndType(slug: $networkSlug, type: "network") {
id
name
slug
@@ -37,12 +37,14 @@ function initNetworksActions(store, _router) {
name
slug
url
+ type
priority
}
parent {
id
name
slug
+ type
url
}
}
@@ -51,10 +53,10 @@ function initNetworksActions(store, _router) {
offset: $offset
orderBy: $orderBy
filter: {
- site: {
+ entity: {
or: [
- { network: { slug: { equalTo: $networkSlug } } },
- { network: { parent: { slug: { equalTo: $networkSlug } } } }
+ { parent: { slug: { equalTo: $networkSlug } } },
+ { parent: { parent: { slug: { equalTo: $networkSlug } } } }
]
}
or: [
@@ -116,13 +118,14 @@ function initNetworksActions(store, _router) {
orderBy: NAME_ASC
filter: {
type: {
- equalTo: 1
+ equalTo: "network"
}
}
) {
id
name
slug
+ type
url
}
}
diff --git a/assets/js/sites/actions.js b/assets/js/sites/actions.js
index 5cfc6a59..3b616ad3 100644
--- a/assets/js/sites/actions.js
+++ b/assets/js/sites/actions.js
@@ -22,18 +22,18 @@ function initSitesActions(store, _router) {
$orderBy:[ReleasesOrderBy!]
$exclude: [String!]
) {
- site: siteBySlug(slug: $siteSlug) {
+ site: entityBySlugAndType(slug: $siteSlug, type: 2) {
name
slug
url
- tags: sitesTags {
+ tags: entitiesTags {
tag {
id
slug
name
}
}
- network {
+ network: parent {
id
name
slug
@@ -70,7 +70,7 @@ function initSitesActions(store, _router) {
offset: $offset
orderBy: $orderBy
filter: {
- site: {
+ entity: {
slug: {
equalTo: $siteSlug
}
@@ -122,7 +122,7 @@ function initSitesActions(store, _router) {
$after:Date = "1900-01-01",
$before:Date = "2100-01-01",
) {
- site {
+ site: entity {
name
slug
url
@@ -137,38 +137,9 @@ function initSitesActions(store, _router) {
return sites;
}
- async function searchSites({ _commit }, { query, limit = 20 }) {
- const { sites } = await graphql(`
- query SearchSites(
- $query: String!
- $limit:Int = 20,
- ) {
- sites: searchSites(
- search: $query,
- first: $limit
- ) {
- name
- slug
- url
- network {
- name
- slug
- url
- }
- }
- }
- `, {
- query,
- limit,
- });
-
- return sites;
- }
-
return {
fetchSiteBySlug,
fetchSites,
- searchSites,
};
}
diff --git a/assets/js/store.js b/assets/js/store.js
index 663fae27..8bd6b49d 100644
--- a/assets/js/store.js
+++ b/assets/js/store.js
@@ -4,6 +4,7 @@ import Vuex from 'vuex';
import initUiStore from './ui/ui';
import initAuthStore from './auth/auth';
import initReleasesStore from './releases/releases';
+import initEntitiesStore from './entities/entities';
import initSitesStore from './sites/sites';
import initNetworksStore from './networks/networks';
import initActorsStore from './actors/actors';
@@ -18,6 +19,7 @@ function initStore(router) {
store.registerModule('auth', initAuthStore(store, router));
store.registerModule('releases', initReleasesStore(store, router));
store.registerModule('actors', initActorsStore(store, router));
+ store.registerModule('entities', initEntitiesStore(store, router));
store.registerModule('sites', initSitesStore(store, router));
store.registerModule('networks', initNetworksStore(store, router));
store.registerModule('tags', initTagsStore(store, router));
diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js
index b7cfa5ae..c6bdaeb4 100644
--- a/migrations/20190325001339_releases.js
+++ b/migrations/20190325001339_releases.js
@@ -141,8 +141,8 @@ exports.up = knex => Promise.resolve()
table.unique(['tag_id', 'media_id']);
}))
.then(() => knex.schema.createTable('entities_types', (table) => {
- table.increments('id', 4);
- table.text('type');
+ table.text('type')
+ .primary();
}))
.then(() => knex('entities_types').insert([
{ type: 'network' },
@@ -160,10 +160,11 @@ exports.up = knex => Promise.resolve()
table.text('name');
table.text('slug', 32);
- table.integer('type', 4)
- .references('id')
+ table.text('type')
+ .notNullable()
+ .references('type')
.inTable('entities_types')
- .defaultTo(2);
+ .defaultTo('channel');
table.unique(['slug', 'type']);
@@ -196,114 +197,18 @@ exports.up = knex => Promise.resolve()
table.unique(['tag_id', 'entity_id']);
}))
- .then(() => knex.schema.createTable('networks', (table) => {
- table.increments('id', 12);
-
- table.text('name');
- table.text('alias');
- table.text('url');
- table.text('description');
- table.json('parameters');
-
- table.integer('parent_id', 12)
- .references('id')
- .inTable('networks');
-
- table.text('slug', 32)
- .unique();
-
- table.datetime('created_at')
- .defaultTo(knex.fn.now());
- }))
- .then(() => knex.schema.createTable('networks_social', (table) => {
+ .then(() => knex.schema.createTable('entities_social', (table) => {
table.increments('id', 16);
table.text('url');
table.text('platform');
- table.integer('network_id', 12)
+ table.integer('entity_id', 12)
.notNullable()
.references('id')
- .inTable('networks');
+ .inTable('entities');
- table.unique(['url', 'network_id']);
-
- table.datetime('created_at')
- .defaultTo(knex.fn.now());
- }))
- .then(() => knex.schema.createTable('sites', (table) => {
- table.increments('id', 12);
-
- table.integer('network_id', 12)
- .notNullable()
- .references('id')
- .inTable('networks');
-
- table.text('name');
- table.text('slug', 32)
- .unique();
-
- table.text('alias');
-
- table.text('url');
- table.text('description');
- table.json('parameters');
-
- table.integer('priority', 3)
- .defaultTo(0);
-
- table.boolean('show')
- .defaultTo(true);
-
- table.datetime('created_at')
- .defaultTo(knex.fn.now());
- }))
- .then(() => knex.schema.createTable('sites_tags', (table) => {
- table.integer('tag_id', 12)
- .notNullable()
- .references('id')
- .inTable('tags');
-
- table.integer('site_id', 12)
- .notNullable()
- .references('id')
- .inTable('sites');
-
- table.boolean('inherit')
- .defaultTo(false);
-
- table.unique(['tag_id', 'site_id']);
- }))
- .then(() => knex.schema.createTable('sites_social', (table) => {
- table.increments('id', 16);
-
- table.text('url');
- table.text('platform');
-
- table.integer('site_id', 12)
- .notNullable()
- .references('id')
- .inTable('sites');
-
- table.unique(['url', 'site_id']);
-
- table.datetime('created_at')
- .defaultTo(knex.fn.now());
- }))
- .then(() => knex.schema.createTable('studios', (table) => {
- table.increments('id', 12);
-
- table.integer('network_id', 12)
- .notNullable()
- .references('id')
- .inTable('networks');
-
- table.text('name');
- table.text('url');
- table.text('description');
-
- table.text('slug', 32)
- .unique();
+ table.unique(['url', 'entity_id']);
table.datetime('created_at')
.defaultTo(knex.fn.now());
@@ -683,7 +588,7 @@ exports.up = knex => Promise.resolve()
table.integer('studio_id', 12)
.references('id')
- .inTable('studios');
+ .inTable('entities');
table.text('type', 10)
.defaultTo('scene');
@@ -878,8 +783,8 @@ exports.up = knex => Promise.resolve()
);
$$ LANGUAGE SQL STABLE;
- CREATE FUNCTION search_sites(search text) RETURNS SETOF sites AS $$
- SELECT * FROM sites
+ CREATE FUNCTION search_entities(search text) RETURNS SETOF entities AS $$
+ SELECT * FROM entities
WHERE
name ILIKE ('%' || search || '%') OR
slug ILIKE ('%' || search || '%') OR
@@ -944,6 +849,7 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP TABLE IF EXISTS body CASCADE;
DROP TABLE IF EXISTS entities_tags CASCADE;
+ DROP TABLE IF EXISTS entities_social CASCADE;
DROP TABLE IF EXISTS sites_tags CASCADE;
DROP TABLE IF EXISTS sites_social CASCADE;
DROP TABLE IF EXISTS networks_social CASCADE;
@@ -966,6 +872,7 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP TABLE IF EXISTS entities CASCADE;
DROP FUNCTION IF EXISTS search_sites;
+ DROP FUNCTION IF EXISTS search_entities;
DROP FUNCTION IF EXISTS search_actors;
DROP FUNCTION IF EXISTS get_random_sfw_media_id;
diff --git a/public/img/logos/kink/kinkybites.png b/public/img/logos/kink/kinkybites.png
new file mode 100644
index 00000000..da521f0d
Binary files /dev/null and b/public/img/logos/kink/kinkybites.png differ
diff --git a/public/img/logos/kink/lazy/boundgangbangs.png b/public/img/logos/kink/lazy/boundgangbangs.png
index cc703604..1bbcbb05 100644
Binary files a/public/img/logos/kink/lazy/boundgangbangs.png and b/public/img/logos/kink/lazy/boundgangbangs.png differ
diff --git a/public/img/logos/kink/lazy/boundgods.png b/public/img/logos/kink/lazy/boundgods.png
index c5736e59..764fe63a 100644
Binary files a/public/img/logos/kink/lazy/boundgods.png and b/public/img/logos/kink/lazy/boundgods.png differ
diff --git a/public/img/logos/kink/lazy/boundinpublic.png b/public/img/logos/kink/lazy/boundinpublic.png
index dc439393..1592beba 100644
Binary files a/public/img/logos/kink/lazy/boundinpublic.png and b/public/img/logos/kink/lazy/boundinpublic.png differ
diff --git a/public/img/logos/kink/lazy/brutalsessions.png b/public/img/logos/kink/lazy/brutalsessions.png
index b497ee2d..cc49655e 100644
Binary files a/public/img/logos/kink/lazy/brutalsessions.png and b/public/img/logos/kink/lazy/brutalsessions.png differ
diff --git a/public/img/logos/kink/lazy/buttmachineboys.png b/public/img/logos/kink/lazy/buttmachineboys.png
index 738f9211..a0a80d9d 100644
Binary files a/public/img/logos/kink/lazy/buttmachineboys.png and b/public/img/logos/kink/lazy/buttmachineboys.png differ
diff --git a/public/img/logos/kink/lazy/devicebondage.png b/public/img/logos/kink/lazy/devicebondage.png
index 403fa6c8..26bdfd34 100644
Binary files a/public/img/logos/kink/lazy/devicebondage.png and b/public/img/logos/kink/lazy/devicebondage.png differ
diff --git a/public/img/logos/kink/lazy/divinebitches.png b/public/img/logos/kink/lazy/divinebitches.png
index 4e85d4d5..c7704821 100644
Binary files a/public/img/logos/kink/lazy/divinebitches.png and b/public/img/logos/kink/lazy/divinebitches.png differ
diff --git a/public/img/logos/kink/lazy/electrosluts.png b/public/img/logos/kink/lazy/electrosluts.png
index d619c2d2..514a2867 100644
Binary files a/public/img/logos/kink/lazy/electrosluts.png and b/public/img/logos/kink/lazy/electrosluts.png differ
diff --git a/public/img/logos/kink/lazy/everythingbutt.png b/public/img/logos/kink/lazy/everythingbutt.png
index 34a8cc4a..699a151d 100644
Binary files a/public/img/logos/kink/lazy/everythingbutt.png and b/public/img/logos/kink/lazy/everythingbutt.png differ
diff --git a/public/img/logos/kink/lazy/familiestied.png b/public/img/logos/kink/lazy/familiestied.png
index d5f82caf..66c18b53 100644
Binary files a/public/img/logos/kink/lazy/familiestied.png and b/public/img/logos/kink/lazy/familiestied.png differ
diff --git a/public/img/logos/kink/lazy/favicon.png b/public/img/logos/kink/lazy/favicon.png
index 3e15b4e4..ee0720b1 100644
Binary files a/public/img/logos/kink/lazy/favicon.png and b/public/img/logos/kink/lazy/favicon.png differ
diff --git a/public/img/logos/kink/lazy/filthyfemdom.png b/public/img/logos/kink/lazy/filthyfemdom.png
index a1a9911f..33a121f5 100644
Binary files a/public/img/logos/kink/lazy/filthyfemdom.png and b/public/img/logos/kink/lazy/filthyfemdom.png differ
diff --git a/public/img/logos/kink/lazy/footworship.png b/public/img/logos/kink/lazy/footworship.png
index fa1c6b60..da1958e6 100644
Binary files a/public/img/logos/kink/lazy/footworship.png and b/public/img/logos/kink/lazy/footworship.png differ
diff --git a/public/img/logos/kink/lazy/fuckedandbound.png b/public/img/logos/kink/lazy/fuckedandbound.png
index b338f041..3c7cdd7a 100644
Binary files a/public/img/logos/kink/lazy/fuckedandbound.png and b/public/img/logos/kink/lazy/fuckedandbound.png differ
diff --git a/public/img/logos/kink/lazy/fuckingmachines.png b/public/img/logos/kink/lazy/fuckingmachines.png
index ab9c963e..842958de 100644
Binary files a/public/img/logos/kink/lazy/fuckingmachines.png and b/public/img/logos/kink/lazy/fuckingmachines.png differ
diff --git a/public/img/logos/kink/lazy/hardcoregangbang.png b/public/img/logos/kink/lazy/hardcoregangbang.png
index 8913ca75..a5813b4f 100644
Binary files a/public/img/logos/kink/lazy/hardcoregangbang.png and b/public/img/logos/kink/lazy/hardcoregangbang.png differ
diff --git a/public/img/logos/kink/lazy/hogtied.png b/public/img/logos/kink/lazy/hogtied.png
index de1f4a39..111c5d9b 100644
Binary files a/public/img/logos/kink/lazy/hogtied.png and b/public/img/logos/kink/lazy/hogtied.png differ
diff --git a/public/img/logos/kink/lazy/kink-dvd.png b/public/img/logos/kink/lazy/kink-dvd.png
index 6a4c458c..649d69cb 100644
Binary files a/public/img/logos/kink/lazy/kink-dvd.png and b/public/img/logos/kink/lazy/kink-dvd.png differ
diff --git a/public/img/logos/kink/lazy/kinkfeatures.png b/public/img/logos/kink/lazy/kinkfeatures.png
index b72c052f..ba29b586 100644
Binary files a/public/img/logos/kink/lazy/kinkfeatures.png and b/public/img/logos/kink/lazy/kinkfeatures.png differ
diff --git a/public/img/logos/kink/lazy/kinkuniversity.png b/public/img/logos/kink/lazy/kinkuniversity.png
index 3bafd0c2..cee0c96e 100644
Binary files a/public/img/logos/kink/lazy/kinkuniversity.png and b/public/img/logos/kink/lazy/kinkuniversity.png differ
diff --git a/public/img/logos/kink/lazy/kinkybites.png b/public/img/logos/kink/lazy/kinkybites.png
new file mode 100644
index 00000000..d467e44c
Binary files /dev/null and b/public/img/logos/kink/lazy/kinkybites.png differ
diff --git a/public/img/logos/kink/lazy/meninpain.png b/public/img/logos/kink/lazy/meninpain.png
index e1b14738..4e6bdd34 100644
Binary files a/public/img/logos/kink/lazy/meninpain.png and b/public/img/logos/kink/lazy/meninpain.png differ
diff --git a/public/img/logos/kink/lazy/menonedge.png b/public/img/logos/kink/lazy/menonedge.png
index 2f0a5c60..7a583346 100644
Binary files a/public/img/logos/kink/lazy/menonedge.png and b/public/img/logos/kink/lazy/menonedge.png differ
diff --git a/public/img/logos/kink/lazy/nakedkombat.png b/public/img/logos/kink/lazy/nakedkombat.png
index 455931b5..58921dba 100644
Binary files a/public/img/logos/kink/lazy/nakedkombat.png and b/public/img/logos/kink/lazy/nakedkombat.png differ
diff --git a/public/img/logos/kink/lazy/network.png b/public/img/logos/kink/lazy/network.png
index 37d377f6..5a59322b 100644
Binary files a/public/img/logos/kink/lazy/network.png and b/public/img/logos/kink/lazy/network.png differ
diff --git a/public/img/logos/kink/lazy/publicdisgrace.png b/public/img/logos/kink/lazy/publicdisgrace.png
index 7e501a50..7a6bc365 100644
Binary files a/public/img/logos/kink/lazy/publicdisgrace.png and b/public/img/logos/kink/lazy/publicdisgrace.png differ
diff --git a/public/img/logos/kink/lazy/sadisticrope.png b/public/img/logos/kink/lazy/sadisticrope.png
index 06240c4f..cc289dda 100644
Binary files a/public/img/logos/kink/lazy/sadisticrope.png and b/public/img/logos/kink/lazy/sadisticrope.png differ
diff --git a/public/img/logos/kink/lazy/sexandsubmission.png b/public/img/logos/kink/lazy/sexandsubmission.png
index 43cc4817..682a3b08 100644
Binary files a/public/img/logos/kink/lazy/sexandsubmission.png and b/public/img/logos/kink/lazy/sexandsubmission.png differ
diff --git a/public/img/logos/kink/lazy/strugglingbabes.png b/public/img/logos/kink/lazy/strugglingbabes.png
index 544be857..c308fc19 100644
Binary files a/public/img/logos/kink/lazy/strugglingbabes.png and b/public/img/logos/kink/lazy/strugglingbabes.png differ
diff --git a/public/img/logos/kink/lazy/thetrainingofo.png b/public/img/logos/kink/lazy/thetrainingofo.png
index 6dfa0894..1e8513f2 100644
Binary files a/public/img/logos/kink/lazy/thetrainingofo.png and b/public/img/logos/kink/lazy/thetrainingofo.png differ
diff --git a/public/img/logos/kink/lazy/theupperfloor.png b/public/img/logos/kink/lazy/theupperfloor.png
index 3362ecd3..645f70b5 100644
Binary files a/public/img/logos/kink/lazy/theupperfloor.png and b/public/img/logos/kink/lazy/theupperfloor.png differ
diff --git a/public/img/logos/kink/lazy/thirtyminutesoftorment.png b/public/img/logos/kink/lazy/thirtyminutesoftorment.png
index 5550b06a..af5ded00 100644
Binary files a/public/img/logos/kink/lazy/thirtyminutesoftorment.png and b/public/img/logos/kink/lazy/thirtyminutesoftorment.png differ
diff --git a/public/img/logos/kink/lazy/tspussyhunters.png b/public/img/logos/kink/lazy/tspussyhunters.png
index 4cbaa7ab..eebada52 100644
Binary files a/public/img/logos/kink/lazy/tspussyhunters.png and b/public/img/logos/kink/lazy/tspussyhunters.png differ
diff --git a/public/img/logos/kink/lazy/tsseduction.png b/public/img/logos/kink/lazy/tsseduction.png
index d65401d9..542250e1 100644
Binary files a/public/img/logos/kink/lazy/tsseduction.png and b/public/img/logos/kink/lazy/tsseduction.png differ
diff --git a/public/img/logos/kink/lazy/ultimatesurrender.png b/public/img/logos/kink/lazy/ultimatesurrender.png
index 6340be90..6eb621e0 100644
Binary files a/public/img/logos/kink/lazy/ultimatesurrender.png and b/public/img/logos/kink/lazy/ultimatesurrender.png differ
diff --git a/public/img/logos/kink/lazy/waterbondage.png b/public/img/logos/kink/lazy/waterbondage.png
index e31f301b..69e511d1 100644
Binary files a/public/img/logos/kink/lazy/waterbondage.png and b/public/img/logos/kink/lazy/waterbondage.png differ
diff --git a/public/img/logos/kink/lazy/whippedass.png b/public/img/logos/kink/lazy/whippedass.png
index 0947df11..cef334fc 100644
Binary files a/public/img/logos/kink/lazy/whippedass.png and b/public/img/logos/kink/lazy/whippedass.png differ
diff --git a/public/img/logos/kink/lazy/wiredpussy.png b/public/img/logos/kink/lazy/wiredpussy.png
index 30612b66..781e6e87 100644
Binary files a/public/img/logos/kink/lazy/wiredpussy.png and b/public/img/logos/kink/lazy/wiredpussy.png differ
diff --git a/public/img/logos/kink/thumbs/boundgangbangs.png b/public/img/logos/kink/thumbs/boundgangbangs.png
index 31bc5f6e..05cc3999 100644
Binary files a/public/img/logos/kink/thumbs/boundgangbangs.png and b/public/img/logos/kink/thumbs/boundgangbangs.png differ
diff --git a/public/img/logos/kink/thumbs/boundgods.png b/public/img/logos/kink/thumbs/boundgods.png
index ab692507..bd42fd4c 100644
Binary files a/public/img/logos/kink/thumbs/boundgods.png and b/public/img/logos/kink/thumbs/boundgods.png differ
diff --git a/public/img/logos/kink/thumbs/boundinpublic.png b/public/img/logos/kink/thumbs/boundinpublic.png
index 6879726a..125915a5 100644
Binary files a/public/img/logos/kink/thumbs/boundinpublic.png and b/public/img/logos/kink/thumbs/boundinpublic.png differ
diff --git a/public/img/logos/kink/thumbs/brutalsessions.png b/public/img/logos/kink/thumbs/brutalsessions.png
index 110d01ec..e73b6dd4 100644
Binary files a/public/img/logos/kink/thumbs/brutalsessions.png and b/public/img/logos/kink/thumbs/brutalsessions.png differ
diff --git a/public/img/logos/kink/thumbs/buttmachineboys.png b/public/img/logos/kink/thumbs/buttmachineboys.png
index a4c61861..de6f2eec 100644
Binary files a/public/img/logos/kink/thumbs/buttmachineboys.png and b/public/img/logos/kink/thumbs/buttmachineboys.png differ
diff --git a/public/img/logos/kink/thumbs/devicebondage.png b/public/img/logos/kink/thumbs/devicebondage.png
index 050ab89b..db572a2a 100644
Binary files a/public/img/logos/kink/thumbs/devicebondage.png and b/public/img/logos/kink/thumbs/devicebondage.png differ
diff --git a/public/img/logos/kink/thumbs/divinebitches.png b/public/img/logos/kink/thumbs/divinebitches.png
index 9a4cbfae..0c8427a5 100644
Binary files a/public/img/logos/kink/thumbs/divinebitches.png and b/public/img/logos/kink/thumbs/divinebitches.png differ
diff --git a/public/img/logos/kink/thumbs/electrosluts.png b/public/img/logos/kink/thumbs/electrosluts.png
index 0ac2d54c..0f483a35 100644
Binary files a/public/img/logos/kink/thumbs/electrosluts.png and b/public/img/logos/kink/thumbs/electrosluts.png differ
diff --git a/public/img/logos/kink/thumbs/everythingbutt.png b/public/img/logos/kink/thumbs/everythingbutt.png
index 0d6aed99..6734970b 100644
Binary files a/public/img/logos/kink/thumbs/everythingbutt.png and b/public/img/logos/kink/thumbs/everythingbutt.png differ
diff --git a/public/img/logos/kink/thumbs/familiestied.png b/public/img/logos/kink/thumbs/familiestied.png
index 3e53a7da..709a1873 100644
Binary files a/public/img/logos/kink/thumbs/familiestied.png and b/public/img/logos/kink/thumbs/familiestied.png differ
diff --git a/public/img/logos/kink/thumbs/favicon.png b/public/img/logos/kink/thumbs/favicon.png
index 28fca58a..b06d0113 100644
Binary files a/public/img/logos/kink/thumbs/favicon.png and b/public/img/logos/kink/thumbs/favicon.png differ
diff --git a/public/img/logos/kink/thumbs/filthyfemdom.png b/public/img/logos/kink/thumbs/filthyfemdom.png
index 4b796fe4..9bfbde45 100644
Binary files a/public/img/logos/kink/thumbs/filthyfemdom.png and b/public/img/logos/kink/thumbs/filthyfemdom.png differ
diff --git a/public/img/logos/kink/thumbs/footworship.png b/public/img/logos/kink/thumbs/footworship.png
index 26ebda62..cea93074 100644
Binary files a/public/img/logos/kink/thumbs/footworship.png and b/public/img/logos/kink/thumbs/footworship.png differ
diff --git a/public/img/logos/kink/thumbs/fuckedandbound.png b/public/img/logos/kink/thumbs/fuckedandbound.png
index b338f041..3c7cdd7a 100644
Binary files a/public/img/logos/kink/thumbs/fuckedandbound.png and b/public/img/logos/kink/thumbs/fuckedandbound.png differ
diff --git a/public/img/logos/kink/thumbs/fuckingmachines.png b/public/img/logos/kink/thumbs/fuckingmachines.png
index 7f173547..e5c1cd2a 100644
Binary files a/public/img/logos/kink/thumbs/fuckingmachines.png and b/public/img/logos/kink/thumbs/fuckingmachines.png differ
diff --git a/public/img/logos/kink/thumbs/hardcoregangbang.png b/public/img/logos/kink/thumbs/hardcoregangbang.png
index 3577ad13..163aa0c2 100644
Binary files a/public/img/logos/kink/thumbs/hardcoregangbang.png and b/public/img/logos/kink/thumbs/hardcoregangbang.png differ
diff --git a/public/img/logos/kink/thumbs/hogtied.png b/public/img/logos/kink/thumbs/hogtied.png
index 25bcc58c..abc26023 100644
Binary files a/public/img/logos/kink/thumbs/hogtied.png and b/public/img/logos/kink/thumbs/hogtied.png differ
diff --git a/public/img/logos/kink/thumbs/kink-dvd.png b/public/img/logos/kink/thumbs/kink-dvd.png
index c3ffd644..95db997f 100644
Binary files a/public/img/logos/kink/thumbs/kink-dvd.png and b/public/img/logos/kink/thumbs/kink-dvd.png differ
diff --git a/public/img/logos/kink/thumbs/kinkfeatures.png b/public/img/logos/kink/thumbs/kinkfeatures.png
index 4a6b62ca..2015ad21 100644
Binary files a/public/img/logos/kink/thumbs/kinkfeatures.png and b/public/img/logos/kink/thumbs/kinkfeatures.png differ
diff --git a/public/img/logos/kink/thumbs/kinkuniversity.png b/public/img/logos/kink/thumbs/kinkuniversity.png
index 41e4be99..e3589b9e 100644
Binary files a/public/img/logos/kink/thumbs/kinkuniversity.png and b/public/img/logos/kink/thumbs/kinkuniversity.png differ
diff --git a/public/img/logos/kink/thumbs/kinkybites.png b/public/img/logos/kink/thumbs/kinkybites.png
new file mode 100644
index 00000000..e65ad9a6
Binary files /dev/null and b/public/img/logos/kink/thumbs/kinkybites.png differ
diff --git a/public/img/logos/kink/thumbs/meninpain.png b/public/img/logos/kink/thumbs/meninpain.png
index 77374421..7dee04d9 100644
Binary files a/public/img/logos/kink/thumbs/meninpain.png and b/public/img/logos/kink/thumbs/meninpain.png differ
diff --git a/public/img/logos/kink/thumbs/menonedge.png b/public/img/logos/kink/thumbs/menonedge.png
index 7ec3fc28..27daf019 100644
Binary files a/public/img/logos/kink/thumbs/menonedge.png and b/public/img/logos/kink/thumbs/menonedge.png differ
diff --git a/public/img/logos/kink/thumbs/nakedkombat.png b/public/img/logos/kink/thumbs/nakedkombat.png
index 20098fb3..e31201a1 100644
Binary files a/public/img/logos/kink/thumbs/nakedkombat.png and b/public/img/logos/kink/thumbs/nakedkombat.png differ
diff --git a/public/img/logos/kink/thumbs/network.png b/public/img/logos/kink/thumbs/network.png
index d8a83448..45b489b8 100644
Binary files a/public/img/logos/kink/thumbs/network.png and b/public/img/logos/kink/thumbs/network.png differ
diff --git a/public/img/logos/kink/thumbs/publicdisgrace.png b/public/img/logos/kink/thumbs/publicdisgrace.png
index 3a0a2e02..4ef0172b 100644
Binary files a/public/img/logos/kink/thumbs/publicdisgrace.png and b/public/img/logos/kink/thumbs/publicdisgrace.png differ
diff --git a/public/img/logos/kink/thumbs/sadisticrope.png b/public/img/logos/kink/thumbs/sadisticrope.png
index 52a491b6..92cf72e5 100644
Binary files a/public/img/logos/kink/thumbs/sadisticrope.png and b/public/img/logos/kink/thumbs/sadisticrope.png differ
diff --git a/public/img/logos/kink/thumbs/sexandsubmission.png b/public/img/logos/kink/thumbs/sexandsubmission.png
index 139aab93..4c3cdc71 100644
Binary files a/public/img/logos/kink/thumbs/sexandsubmission.png and b/public/img/logos/kink/thumbs/sexandsubmission.png differ
diff --git a/public/img/logos/kink/thumbs/strugglingbabes.png b/public/img/logos/kink/thumbs/strugglingbabes.png
index a80423f3..cc224f7e 100644
Binary files a/public/img/logos/kink/thumbs/strugglingbabes.png and b/public/img/logos/kink/thumbs/strugglingbabes.png differ
diff --git a/public/img/logos/kink/thumbs/thetrainingofo.png b/public/img/logos/kink/thumbs/thetrainingofo.png
index b702e3d1..4a022d15 100644
Binary files a/public/img/logos/kink/thumbs/thetrainingofo.png and b/public/img/logos/kink/thumbs/thetrainingofo.png differ
diff --git a/public/img/logos/kink/thumbs/theupperfloor.png b/public/img/logos/kink/thumbs/theupperfloor.png
index 0e636826..c3c119d1 100644
Binary files a/public/img/logos/kink/thumbs/theupperfloor.png and b/public/img/logos/kink/thumbs/theupperfloor.png differ
diff --git a/public/img/logos/kink/thumbs/thirtyminutesoftorment.png b/public/img/logos/kink/thumbs/thirtyminutesoftorment.png
index ee38d8d0..a061c9ec 100644
Binary files a/public/img/logos/kink/thumbs/thirtyminutesoftorment.png and b/public/img/logos/kink/thumbs/thirtyminutesoftorment.png differ
diff --git a/public/img/logos/kink/thumbs/tspussyhunters.png b/public/img/logos/kink/thumbs/tspussyhunters.png
index ea0e5c22..9bad63fa 100644
Binary files a/public/img/logos/kink/thumbs/tspussyhunters.png and b/public/img/logos/kink/thumbs/tspussyhunters.png differ
diff --git a/public/img/logos/kink/thumbs/tsseduction.png b/public/img/logos/kink/thumbs/tsseduction.png
index 1955a6dc..bad5bcff 100644
Binary files a/public/img/logos/kink/thumbs/tsseduction.png and b/public/img/logos/kink/thumbs/tsseduction.png differ
diff --git a/public/img/logos/kink/thumbs/ultimatesurrender.png b/public/img/logos/kink/thumbs/ultimatesurrender.png
index 2e39e114..7371d604 100644
Binary files a/public/img/logos/kink/thumbs/ultimatesurrender.png and b/public/img/logos/kink/thumbs/ultimatesurrender.png differ
diff --git a/public/img/logos/kink/thumbs/waterbondage.png b/public/img/logos/kink/thumbs/waterbondage.png
index 353b7060..a83ade92 100644
Binary files a/public/img/logos/kink/thumbs/waterbondage.png and b/public/img/logos/kink/thumbs/waterbondage.png differ
diff --git a/public/img/logos/kink/thumbs/whippedass.png b/public/img/logos/kink/thumbs/whippedass.png
index 22d8d985..386489f3 100644
Binary files a/public/img/logos/kink/thumbs/whippedass.png and b/public/img/logos/kink/thumbs/whippedass.png differ
diff --git a/public/img/logos/kink/thumbs/wiredpussy.png b/public/img/logos/kink/thumbs/wiredpussy.png
index 46a0131e..b217c0eb 100644
Binary files a/public/img/logos/kink/thumbs/wiredpussy.png and b/public/img/logos/kink/thumbs/wiredpussy.png differ
diff --git a/public/img/logos/wgcz/favicon.png b/public/img/logos/wgcz/favicon.png
new file mode 100644
index 00000000..ef5ea108
Binary files /dev/null and b/public/img/logos/wgcz/favicon.png differ
diff --git a/public/img/logos/wgcz/lazy/favicon.png b/public/img/logos/wgcz/lazy/favicon.png
new file mode 100644
index 00000000..3d453e5c
Binary files /dev/null and b/public/img/logos/wgcz/lazy/favicon.png differ
diff --git a/public/img/logos/wgcz/lazy/network.png b/public/img/logos/wgcz/lazy/network.png
new file mode 100644
index 00000000..be20716b
Binary files /dev/null and b/public/img/logos/wgcz/lazy/network.png differ
diff --git a/public/img/logos/wgcz/misc/xvideos_bg.png b/public/img/logos/wgcz/misc/xvideos_bg.png
new file mode 100644
index 00000000..2b1cd842
Binary files /dev/null and b/public/img/logos/wgcz/misc/xvideos_bg.png differ
diff --git a/public/img/logos/wgcz/network.png b/public/img/logos/wgcz/network.png
new file mode 100644
index 00000000..00784fd2
Binary files /dev/null and b/public/img/logos/wgcz/network.png differ
diff --git a/public/img/logos/wgcz/thumbs/favicon.png b/public/img/logos/wgcz/thumbs/favicon.png
new file mode 100644
index 00000000..fddd0810
Binary files /dev/null and b/public/img/logos/wgcz/thumbs/favicon.png differ
diff --git a/public/img/logos/wgcz/thumbs/network.png b/public/img/logos/wgcz/thumbs/network.png
new file mode 100644
index 00000000..2b81bc9f
Binary files /dev/null and b/public/img/logos/wgcz/thumbs/network.png differ
diff --git a/seeds/01_networks.js b/seeds/01_networks.js
index 8ceda11a..9b85e167 100644
--- a/seeds/01_networks.js
+++ b/seeds/01_networks.js
@@ -21,6 +21,10 @@ const parentNetworks = [
slug: 'whalemember',
name: 'Whale Member',
},
+ {
+ slug: 'wgcz',
+ name: 'WGCZ Holding',
+ },
];
const networks = [
@@ -98,6 +102,7 @@ const networks = [
name: 'Bang Bros',
url: 'https://bangbros.com',
description: 'Here at Bang Bros, we only film the best highest quality porn with the sexiest Amateur girls and the top pornstars. Updated daily on Bangbros.com.',
+ parent: 'wgcz',
},
{
slug: 'blowpass',
@@ -120,7 +125,7 @@ const networks = [
slug: 'boobpedia',
name: 'Boobpedia',
url: 'https://www.boobpedia.com',
- type: 4,
+ type: 'info',
},
{
slug: 'burningangel',
@@ -142,13 +147,14 @@ const networks = [
slug: 'freeones',
name: 'FreeOnes',
url: 'https://www.freeones.com',
- type: 4,
+ type: 'info',
},
{
slug: 'ddfnetwork',
name: 'DDF Network',
url: 'https://ddfnetwork.com',
description: 'European porn videos hub with exclusive VR, 4K and full HD XXX videos and hot sex photos of Europes finest porn star babes.',
+ parent: 'wgcz',
},
{
slug: 'digitalplayground',
@@ -272,6 +278,7 @@ const networks = [
name: 'LegalPorno',
url: 'https://www.legalporno.com',
description: 'The Best HD Porn For You!',
+ parent: 'wgcz',
},
{
slug: 'men',
@@ -355,6 +362,7 @@ const networks = [
name: 'Private',
url: 'https://www.private.com',
description: 'Private is the best source for adult movies and videos. Featuring the most popular hardcore adult stars in hundreds of porn movies, Private.com delivers...',
+ parent: 'wgcz',
},
{
slug: 'puretaboo',
@@ -437,13 +445,13 @@ const networks = [
exports.seed = knex => Promise.resolve()
.then(async () => {
- const { inserted, updated } = await upsert('entities', parentNetworks.map(network => ({ ...network, type: 1 })), ['slug', 'type'], knex);
+ const { inserted, updated } = await upsert('entities', parentNetworks.map(network => ({ ...network, type: 'network' })), ['slug', 'type'], knex);
const parentNetworksBySlug = [].concat(inserted, updated).reduce((acc, network) => ({ ...acc, [network.slug]: network.id }), {});
const networksWithParent = networks.map(network => ({
slug: network.slug,
name: network.name,
- type: network.type || 1,
+ type: network.type || 'network',
alias: network.alias ? network.alias.join(',') : null,
url: network.url,
description: network.description,
diff --git a/seeds/02_sites.js b/seeds/02_sites.js
index 7ddd9bd2..16c37c81 100644
--- a/seeds/02_sites.js
+++ b/seeds/02_sites.js
@@ -2830,6 +2830,13 @@ const sites = [
description: 'Learn BDSM Technical Skills & Theories From Respected Teachers In The Kink Community. Learn BDSM skills and improve your sex techniques. Video tutorials feature top sex ed experts and hardcore demos on topics from bondage to relationships.',
network: 'kink',
},
+ {
+ slug: 'kinkybites',
+ name: 'Kinky Bites',
+ url: 'https://www.kink.com/channel/kinkybites',
+ description: 'Come see what the hottest kink models have for you at home. Sink your teeth into this kinky private collection made just for you.',
+ network: 'kink',
+ },
{
slug: 'meninpain',
name: 'Men In Pain',
@@ -6369,7 +6376,7 @@ exports.seed = knex => Promise.resolve()
const sitesWithNetworks = sites.map(site => ({
slug: site.slug,
name: site.name,
- type: site.type || 2,
+ type: site.type || 'channel',
alias: (site.alias || []).join(','),
description: site.description,
url: site.url,
diff --git a/seeds/03_studios.js b/seeds/03_studios.js
index 0b54d534..6994aa35 100644
--- a/seeds/03_studios.js
+++ b/seeds/03_studios.js
@@ -153,17 +153,13 @@ function getStudios(networksMap) {
/* eslint-disable max-len */
exports.seed = knex => Promise.resolve()
.then(async () => {
- const [networks, types] = await Promise.all([
- knex('entities').select('*'),
- knex('entities_types').select('*'),
- ]);
+ const networks = await knex('entities').select('*').where('type', 'network');
const networksMap = networks.reduce((acc, { id, slug }) => ({ ...acc, [slug]: id }), {});
- const typesMap = types.reduce((acc, type) => ({ [type.type]: type.id }), {});
const studios = getStudios(networksMap).map(studio => ({
...studio,
- type: typesMap.studio,
+ type: 'studio',
}));
return upsert('entities', studios, 'slug', knex);
diff --git a/src/app.js b/src/app.js
index 6bed361c..a9474948 100644
--- a/src/app.js
+++ b/src/app.js
@@ -24,7 +24,7 @@ async function init() {
const actors = argv.actors && await scrapeActors(argv.actors);
const actorBaseScenes = argv.actors && argv.actorScenes && actors.map(actor => actor.releases).flat().filter(Boolean);
- const updateBaseScenes = (argv.scrape || argv.sites || argv.networks) && await fetchUpdates();
+ const updateBaseScenes = (argv.scrape || argv.channels || argv.networks) && await fetchUpdates();
const deepScenes = argv.deep
? await fetchScenes([...(argv.scenes || []), ...(updateBaseScenes || []), ...(actorBaseScenes || [])])
diff --git a/src/argv.js b/src/argv.js
index a1851dfb..632ce9eb 100644
--- a/src/argv.js
+++ b/src/argv.js
@@ -11,23 +11,18 @@ const { argv } = yargs
alias: 'web',
})
.option('scrape', {
- describe: 'Scrape sites and networks defined in configuration',
+ describe: 'Scrape channels and networks defined in configuration',
type: 'boolean',
})
.option('networks', {
- describe: 'Networks to scrape (overrides configuration)',
+ describe: 'Network to scrape all channels from (overrides configuration)',
type: 'array',
alias: 'network',
})
- .option('sites', {
- describe: 'Sites to scrape (overrides configuration)',
+ .option('channels', {
+ describe: 'Channel to scrape (overrides configuration)',
type: 'array',
- alias: 'site',
- })
- .option('entities', {
- describe: 'Networks or sites to scrape (overrides configuration)',
- type: 'array',
- alias: 'entity',
+ alias: 'channel',
})
.option('actors', {
describe: 'Scrape actors by name or slug',
diff --git a/src/entities.js b/src/entities.js
index 1984319c..4e93c86b 100644
--- a/src/entities.js
+++ b/src/entities.js
@@ -20,7 +20,7 @@ function curateEntity(entity, includeParameters = false) {
children: (entity.children || []).map(child => curateEntity({
...child,
parent: entity,
- })),
+ }, includeParameters)),
};
return curatedEntity;
@@ -30,39 +30,40 @@ async function curateEntities(entities, includeParameters) {
return Promise.all(entities.map(async entity => curateEntity(entity, includeParameters)));
}
-async function fetchSitesFromArgv() {
+async function fetchChannelsFromArgv() {
const rawNetworks = await knex.raw(`
- /* networks from argument with sites as children */
- WITH RECURSIVE temp AS (
+ /* networks from argument with channels as children */
+ WITH RECURSIVE children AS (
SELECT
id, parent_id, name, slug, type, url, description, parameters
FROM
entities
WHERE
- slug = ANY(?) AND entities.type = 1
+ slug = ANY(?) AND entities.type = 'network'
UNION ALL
SELECT
entities.id, entities.parent_id, entities.name, entities.slug, entities.type, entities.url, entities.description, entities.parameters
FROM
entities
INNER JOIN
- temp ON temp.id = entities.parent_id
+ children ON children.id = entities.parent_id
)
SELECT
- entities.*, row_to_json(parents) as parent, json_agg(temp) as children
+ entities.*, row_to_json(parents) as parent, json_agg(children) as children
FROM
- temp
+ children
LEFT JOIN
- entities ON entities.id = temp.parent_id
+ entities ON entities.id = children.parent_id
LEFT JOIN
entities AS parents ON parents.id = entities.parent_id
WHERE
- temp.type = 2
+ children.type = 'channel'
GROUP BY
- temp.parent_id, entities.id, entities.name, parents.id
+ children.parent_id, entities.id, entities.name, parents.id
+
UNION ALL
- /* sites from argument as the child of network with parent */
+ /* channels from argument as the child of network with parent */
SELECT
entities.*, row_to_json(parents) as parent, json_agg(row_to_json(children))
FROM
@@ -72,10 +73,10 @@ async function fetchSitesFromArgv() {
LEFT JOIN
entities AS parents ON parents.id = entities.parent_id
WHERE
- children.slug = ANY(?) AND children.type = 2
+ children.slug = ANY(?) AND children.type = 'channel'
GROUP BY
entities.id, parents.id;
- `, [argv.networks || [], argv.sites || []]);
+ `, [argv.networks || [], argv.channels || []]);
const curatedNetworks = await curateEntities(rawNetworks.rows, true);
logger.info(`Found ${curatedNetworks.length} networks in database`);
@@ -83,10 +84,10 @@ async function fetchSitesFromArgv() {
return curatedNetworks;
}
-async function fetchSitesFromConfig() {
+async function fetchChannelsFromConfig() {
const rawSites = await knex('entities')
- .select('entities.*')
- .leftJoin('entities as entities_parents', 'entities_parents.id', 'entities.id')
+ .select(knex.raw('entities.*, row_to_json(parents) as parent'))
+ .leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
.where((builder) => {
if (config.include) {
builder.whereIn('entities.slug', config.include);
@@ -103,14 +104,14 @@ async function fetchSitesFromConfig() {
}
async function fetchIncludedEntities() {
- if (argv.networks || argv.sites) {
- return fetchSitesFromArgv();
+ if (argv.networks || argv.channels) {
+ return fetchChannelsFromArgv();
}
- return fetchSitesFromConfig();
+ return fetchChannelsFromConfig();
}
-async function fetchSites(queryObject) {
+async function fetchChannels(queryObject) {
const sites = await knex('sites')
.where(builder => whereOr(queryObject, 'sites', builder))
.select(
@@ -123,7 +124,7 @@ async function fetchSites(queryObject) {
return curateEntities(sites);
}
-async function fetchSitesFromReleases() {
+async function fetchChannelsFromReleases() {
const sites = await knex('releases')
.select('site_id', '')
.leftJoin('sites', 'sites.id', 'releases.site_id')
@@ -137,8 +138,8 @@ module.exports = {
curateEntity,
curateEntities,
fetchIncludedEntities,
- fetchSites,
- fetchSitesFromConfig,
- fetchSitesFromArgv,
- fetchSitesFromReleases,
+ fetchChannels,
+ fetchChannelsFromConfig,
+ fetchChannelsFromArgv,
+ fetchChannelsFromReleases,
};
diff --git a/src/scrapers/kink.js b/src/scrapers/kink.js
index 35ed5f5b..a63ad7e2 100644
--- a/src/scrapers/kink.js
+++ b/src/scrapers/kink.js
@@ -1,117 +1,97 @@
'use strict';
-const bhttp = require('bhttp');
-const cheerio = require('cheerio');
-const moment = require('moment');
+const { get, getAll } = require('../utils/qu');
-function scrapeLatest(html, site) {
- const $ = cheerio.load(html, { normalizeWhitespace: true });
- const sceneElements = $('.shoot-list .shoot').toArray();
+function scrapeLatest(scenes) {
+ return scenes.map(({ qu }) => {
+ const release = {};
- return sceneElements.map((element) => {
- const sceneLinkElement = $(element).find('.shoot-thumb-title a');
- const href = sceneLinkElement.attr('href');
- const url = `https://kink.com${href}`;
- const shootId = href.split('/')[2];
- const title = sceneLinkElement.text().trim();
+ const href = qu.url('.shoot-thumb-title a');
+ release.url = `https://kink.com${href}`;
- const poster = $(element).find('.adimage').attr('src');
- const photos = $(element).find('.rollover .roll-image').map((photoIndex, photoElement) => $(photoElement).attr('data-imagesrc')).toArray();
+ release.shootId = href.split('/').slice(-1)[0];
+ release.entryId = release.shootId;
- 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;
+ release.title = qu.q('.shoot-thumb-title a', true);
+ release.date = qu.date('.date', 'MMM DD, YYYY');
- const timestamp = $(element).find('.video span').text();
- const timestampComponents = timestamp.split(':'); // fix mixed hh:mm:ss and mm:ss format
- const duration = moment.duration(timestampComponents.length > 2 ? timestamp : `0:${timestamp}`).asSeconds();
+ release.actors = qu.all('.shoot-thumb-models a', true);
+ release.stars = qu.q('.average-rating', 'data-rating') / 10;
- return {
- url,
- shootId,
- entryId: shootId,
- title,
- actors,
- date,
- photos,
- poster,
- rating: {
- stars,
- },
- duration,
- site,
- };
+ release.poster = qu.img('.adimage');
+ release.photos = qu.imgs('.rollover .roll-image', 'data-imagesrc').map(photo => [
+ photo.replace('410/', '830/'),
+ photo,
+ ]);
+
+ release.duration = qu.dur('.video span');
+
+ return release;
});
}
-async function scrapeScene(html, url, shootId, ratingRes, site) {
- const $ = cheerio.load(html, { normalizeWhitespace: true });
+async function scrapeScene({ qu }, url) {
+ const release = { url };
- // const title = $('h1.shoot-title').text().replace(/\ue800/, ''); // fallback, special character is 'like'-heart
- const title = $('h1.shoot-title span.favorite-button').attr('data-title');
- const actorsRaw = $('.shoot-info p.starring');
+ release.shootId = new URL(url).pathname.split('/')[2];
+ release.entryId = release.shootId;
- const photos = $('.gallery .thumb img').map((photoIndex, photoElement) => $(photoElement).attr('data-image-file')).toArray();
- const trailerVideo = $('.player span[data-type="trailer-src"]').attr('data-url');
- const trailerPoster = $('.player video#kink-player').attr('poster');
+ release.title = qu.q('.shoot-title span.favorite-button', 'data-title');
+ release.description = qu.q('.description-text', true);
- const date = moment.utc($(actorsRaw)
- .prev()
- .text()
- .trim()
- .replace('Date: ', ''),
- 'MMMM DD, YYYY')
- .toDate();
+ release.date = qu.date('.shoot-date', 'MMMM DD, YYYY');
+ release.actors = qu.all('.names a', true).map(actor => actor.replace(/,\s*/, ''));
+ release.director = qu.q('.director-name', true);
- const actors = $(actorsRaw).find('span.names a').map((actorIndex, actorElement) => $(actorElement).text()).toArray();
- const description = $('.shoot-info .description').text().trim();
+ release.photos = qu.imgs('.gallery .thumb img', 'data-image-file');
+ release.poster = qu.poster();
- const { average: stars } = ratingRes.body;
+ release.tags = qu.all('.tag-list a[href*="/tag"]', true).map(tag => tag.replace(/,\s*/, ''));
- const siteName = $('.shoot-logo a').attr('href').split('/')[2];
- const siteSlug = siteName.replace(/\s+/g, '').toLowerCase();
+ const trailer = qu.q('.player span[data-type="trailer-src"]', 'data-url');
- const tags = $('.tag-list > a[href*="/tag"]').map((tagIndex, tagElement) => $(tagElement).text()).toArray();
- const channel = siteSlug;
-
- return {
- url,
- shootId,
- entryId: shootId,
- title,
- date,
- actors,
- description,
- photos,
- poster: trailerPoster,
- trailer: {
- src: trailerVideo,
+ release.trailer = [
+ {
+ src: trailer.replace('480p', '1080p'),
+ quality: 1080,
+ },
+ {
+ src: trailer.replace('480p', '720p'),
+ quality: 720,
+ },
+ {
+ src: trailer,
quality: 480,
},
- rating: {
- stars,
+ {
+ src: trailer.replace('480p', '360p'),
+ quality: 360,
},
- tags,
- site,
- channel,
- };
+ ];
+
+ release.channel = qu.url('.shoot-logo a').split('/').slice(-1)[0];
+
+ return release;
}
async function fetchLatest(site, page = 1) {
- const res = await bhttp.get(`${site.url}/latest/page/${page}`);
+ const res = await getAll(`${site.url}/latest/page/${page}`, '.shoot-list .shoot');
- return scrapeLatest(res.body.toString(), site);
+ if (res.ok) {
+ return scrapeLatest(res.items, site);
+ }
+
+ return res.status;
}
async function fetchScene(url, site) {
- const shootId = new URL(url).pathname.split('/')[2];
+ const res = await get(url);
- const [res, ratingRes] = await Promise.all([
- bhttp.get(url),
- bhttp.get(`https://kink.com/api/ratings/${shootId}`),
- ]);
+ if (res.ok) {
+ return scrapeScene(res.item, url, site);
+ }
- return scrapeScene(res.body.toString(), url, shootId, ratingRes, site);
+ return res.status;
}
module.exports = {
diff --git a/src/updates.js b/src/updates.js
index d2eaa5b1..8019f632 100644
--- a/src/updates.js
+++ b/src/updates.js
@@ -8,7 +8,7 @@ const logger = require('./logger')(__filename);
const knex = require('./knex');
const include = require('./utils/argv-include')(argv);
const scrapers = require('./scrapers/scrapers');
-const { fetchSitesFromArgv, fetchSitesFromConfig } = require('./entities');
+const { fetchChannelsFromArgv, fetchChannelsFromConfig } = require('./entities');
const afterDate = (() => {
if (/\d{2,4}-\d{2}-\d{2,4}/.test(argv.after)) {
@@ -27,7 +27,7 @@ const afterDate = (() => {
async function filterUniqueReleases(latestReleases, accReleases) {
const latestReleaseIdentifiers = latestReleases
- .map(release => [release.site.id, release.entryId]);
+ .map(release => [release.entity.id, release.entryId]);
const duplicateReleases = await knex('releases')
.whereIn(['entity_id', 'entry_id'], latestReleaseIdentifiers);
@@ -37,17 +37,17 @@ async function filterUniqueReleases(latestReleases, accReleases) {
const duplicateReleasesSiteIdAndEntryIds = duplicateReleases
.concat(accReleases)
.reduce((acc, release) => {
- const siteId = release.entity_id || release.site.id;
+ const entityId = release.entity_id || release.entity.id;
const entryId = release.entry_id || release.entryId;
- if (!acc[siteId]) acc[siteId] = {};
- acc[siteId][entryId] = true;
+ if (!acc[entityId]) acc[entityId] = {};
+ acc[entityId][entryId] = true;
return acc;
}, {});
const uniqueReleases = latestReleases
- .filter(release => !duplicateReleasesSiteIdAndEntryIds[release.site.id]?.[release.entryId]);
+ .filter(release => !duplicateReleasesSiteIdAndEntryIds[release.entity.id]?.[release.entryId]);
return uniqueReleases;
}
@@ -77,15 +77,15 @@ function needNextPage(uniqueReleases, pageAccReleases) {
return pageAccReleases.length <= argv.nullDateLimit;
}
-async function scrapeReleases(scraper, site, preData, upcoming = false) {
+async function scrapeReleases(scraper, entity, preData, upcoming = false) {
const scrapePage = async (page = 1, accReleases = []) => {
const latestReleases = upcoming
- ? await scraper.fetchUpcoming(site, page, preData, include)
- : await scraper.fetchLatest(site, page, preData, include);
+ ? await scraper.fetchUpcoming(entity, page, preData, include)
+ : await scraper.fetchLatest(entity, page, preData, include);
if (!Array.isArray(latestReleases)) {
// scraper is unable to fetch the releases and returned a HTTP code or null
- logger.warn(`Scraper returned ${latestReleases} when fetching latest from '${site.name}' (${site.parent?.name})`);
+ logger.warn(`Scraper returned ${latestReleases} when fetching latest from '${entity.name}' (${entity.parent?.name})`);
return accReleases;
}
@@ -94,15 +94,15 @@ async function scrapeReleases(scraper, site, preData, upcoming = false) {
return accReleases;
}
- const latestReleasesWithSite = latestReleases.map(release => ({ ...release, site: release.site || site })); // attach site release is assigned to when stored
+ const latestReleasesWithEntity = latestReleases.map(release => ({ ...release, entity })); // attach entity the release is assigned to when stored
const uniqueReleases = argv.redownload
- ? latestReleasesWithSite
- : await filterUniqueReleases(latestReleasesWithSite, accReleases);
+ ? latestReleasesWithEntity
+ : await filterUniqueReleases(latestReleasesWithEntity, accReleases);
const pageAccReleases = accReleases.concat(uniqueReleases);
- logger.verbose(`Scraped '${site.name}' (${site.parent?.name}) ${upcoming ? 'upcoming' : 'latest'} page ${page}, found ${uniqueReleases.length} unique updates`);
+ logger.verbose(`Scraped '${entity.name}' (${entity.parent?.name}) ${upcoming ? 'upcoming' : 'latest'} page ${page}, found ${uniqueReleases.length} unique updates`);
if (needNextPage(uniqueReleases, pageAccReleases)) {
return scrapePage(page + 1, pageAccReleases);
@@ -127,70 +127,70 @@ async function scrapeReleases(scraper, site, preData, upcoming = false) {
return releases.slice(0, argv.nullDateLimit);
}
-async function scrapeLatestReleases(scraper, site, preData) {
+async function scrapeLatestReleases(scraper, entity, preData) {
if (!scraper.fetchLatest) {
return [];
}
try {
- return await scrapeReleases(scraper, site, preData, false);
+ return await scrapeReleases(scraper, entity, preData, false);
} catch (error) {
- logger.warn(`Failed to scrape latest updates for '${site.slug}' (${site.parent?.slug}): ${error.message}`);
+ logger.warn(`Failed to scrape latest updates for '${entity.slug}' (${entity.parent?.slug}): ${error.message}`);
}
return [];
}
-async function scrapeUpcomingReleases(scraper, site, preData) {
+async function scrapeUpcomingReleases(scraper, entity, preData) {
if (!scraper.fetchUpcoming) {
return [];
}
try {
- return await scrapeReleases(scraper, site, preData, true);
+ return await scrapeReleases(scraper, entity, preData, true);
} catch (error) {
- logger.warn(`Failed to scrape upcoming updates for '${site.slug}' (${site.parent?.slug}): ${error.message}`);
+ logger.warn(`Failed to scrape upcoming updates for '${entity.slug}' (${entity.parent?.slug}): ${error.message}`);
}
return [];
}
-async function scrapeSiteReleases(scraper, site, preData) {
+async function scrapeChannelReleases(scraper, channelEntity, preData) {
const [latestReleases, upcomingReleases] = await Promise.all([
argv.latest
- ? scrapeLatestReleases(scraper, site, preData)
+ ? scrapeLatestReleases(scraper, channelEntity, preData)
: [],
argv.upcoming
- ? scrapeUpcomingReleases(scraper, site, preData)
+ ? scrapeUpcomingReleases(scraper, channelEntity, preData)
: [],
]);
- logger.info(`Fetching ${latestReleases.length} latest and ${upcomingReleases.length} upcoming updates for '${site.name}' (${site.parent.name})`);
+ logger.info(`Fetching ${latestReleases.length} latest and ${upcomingReleases.length} upcoming updates for '${channelEntity.name}' (${channelEntity.parent.name})`);
return [...latestReleases, ...upcomingReleases];
}
-async function scrapeSite(site, accSiteReleases) {
- const scraper = scrapers.releases[site.slug]
- || scrapers.releases[site.parent?.slug]
- || scrapers.releases[site.parent?.parent?.slug];
+async function scrapeChannel(channelEntity, accNetworkReleases) {
+ const scraper = scrapers.releases[channelEntity.slug]
+ || scrapers.releases[channelEntity.parent?.slug]
+ || scrapers.releases[channelEntity.parent?.parent?.slug];
if (!scraper) {
- logger.warn(`No scraper found for '${site.name}' (${site.parent.name})`);
+ logger.warn(`No scraper found for '${channelEntity.name}' (${channelEntity.parent.name})`);
return [];
}
try {
- const beforeFetchLatest = await scraper.beforeFetchLatest?.(site);
+ const beforeFetchLatest = await scraper.beforeFetchLatest?.(channelEntity);
- const siteReleases = await scrapeSiteReleases(scraper, site, {
- accSiteReleases,
+ const channelEntityReleases = await scrapeChannelReleases(scraper, channelEntity, {
+ accNetworkReleases,
beforeFetchLatest,
});
- return siteReleases.map(release => ({ ...release, site }));
+ return channelEntityReleases.map(release => ({ ...release, channelEntity }));
} catch (error) {
- logger.error(`Failed to scrape releases from ${site.name} using ${scraper.slug}: ${error.message}`);
+ logger.error(`Failed to scrape releases from ${channelEntity.name} using ${scraper.slug}: ${error.message}`);
return [];
}
@@ -199,11 +199,11 @@ async function scrapeSite(site, accSiteReleases) {
async function scrapeNetworkSequential(networkEntity) {
return Promise.reduce(
networkEntity.children,
- async (chain, siteEntity) => {
- const accSiteReleases = await chain;
- const siteReleases = await scrapeSite(siteEntity, networkEntity, accSiteReleases);
+ async (chain, channelEntity) => {
+ const accNetworkReleases = await chain;
+ const channelReleases = await scrapeChannel(channelEntity, networkEntity, accNetworkReleases);
- return accSiteReleases.concat(siteReleases);
+ return accNetworkReleases.concat(channelReleases);
},
Promise.resolve([]),
);
@@ -212,21 +212,21 @@ async function scrapeNetworkSequential(networkEntity) {
async function scrapeNetworkParallel(networkEntity) {
return Promise.map(
networkEntity.children,
- async siteEntity => scrapeSite(siteEntity, networkEntity),
+ async channelEntity => scrapeChannel(channelEntity, networkEntity),
{ concurrency: 3 },
);
}
async function fetchUpdates() {
- const includedNetworks = argv.sites || argv.networks || argv.from
- ? await fetchSitesFromArgv()
- : await fetchSitesFromConfig();
+ const includedNetworks = argv.channels || argv.networks
+ ? await fetchChannelsFromArgv()
+ : await fetchChannelsFromConfig();
const scrapedNetworks = await Promise.map(
includedNetworks,
- async network => (network.parameters?.sequential
- ? scrapeNetworkSequential(network)
- : scrapeNetworkParallel(network)),
+ async networkEntity => (networkEntity.parameters?.sequential
+ ? scrapeNetworkSequential(networkEntity)
+ : scrapeNetworkParallel(networkEntity)),
{ concurrency: 5 },
);