Refactored various modules for entities. Updated and refactored Kink scraper.

This commit is contained in:
2020-06-27 02:57:30 +02:00
parent 4959dfd14f
commit af56378ee2
107 changed files with 539 additions and 414 deletions

View File

@@ -14,6 +14,7 @@
:to="{ name: 'actors', params: { gender: 'male', letter } }"
:class="{ selected: gender === 'male' }"
class="gender-link male"
replace
><Gender gender="male" /></router-link>
</li>
<li class="gender">
@@ -21,6 +22,7 @@
:to="{ name: 'actors', params: { gender: 'trans', letter } }"
:class="{ selected: gender === 'trans' }"
class="gender-link transsexual"
replace
><Gender gender="transsexual" /></router-link>
</li>
<li class="gender">
@@ -28,6 +30,7 @@
:to="{ name: 'actors', params: { gender: 'other', letter } }"
:class="{ selected: gender === 'other' }"
class="gender-link other"
replace
><Icon icon="question5" /></router-link>
</li>
</ul>
@@ -42,6 +45,7 @@
:to="{ name: 'actors', params: { gender, letter: letterX } }"
:class="{ selected: letterX === letter }"
class="letter-link"
replace
>{{ letterX || 'All' }}</router-link>
</li>
</ul>

View File

@@ -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 {

View File

@@ -2,13 +2,13 @@
<div class="networks">
<form
class="search"
@submit.prevent="searchSites"
@submit.prevent="searchEntities"
>
<input
v-model="query"
:placeholder="`Find ${siteCount} sites in ${networks.length} networks`"
class="query"
@input="searchSites"
@input="searchEntities"
>
<button
@@ -19,12 +19,12 @@
<div
v-if="query.length"
class="network-tiles"
class="entity-tiles"
>
<Site
v-for="site in searchResults"
:key="`site-tile-${site.slug}`"
:site="site"
<Entity
v-for="entity in searchResults"
:key="`${entity.type}-tile-${entity.slug}`"
:entity="entity"
/>
<span v-if="searchResults.length === 0">No results for "{{ query }}"</span>
@@ -32,41 +32,39 @@
<div
v-if="query.length === 0"
class="network-tiles"
class="entity-tiles"
>
<Network
<Entity
v-for="network in networks"
:key="`network-tile-${network.slug}`"
:network="network"
:entity="network"
/>
</div>
</div>
</template>
<script>
import Network from '../tile/network.vue';
import Site from '../tile/site.vue';
import Entity from '../tile/entity.vue';
async function searchSites() {
this.searchResults = await this.$store.dispatch('searchSites', {
async function searchEntities() {
this.searchResults = await this.$store.dispatch('searchEntities', {
query: this.query,
limit: 20,
limit: 50,
});
}
async function mounted() {
this.networks = await this.$store.dispatch('fetchNetworks');
this.networks = await this.$store.dispatch('fetchEntities', { type: 'network' });
this.pageTitle = 'Networks';
}
function siteCount() {
return this.networks.map(network => network.sites).flat().length;
return this.networks.map(network => network.children).flat().length;
}
export default {
components: {
Network,
Site,
Entity,
},
data() {
return {
@@ -81,7 +79,7 @@ export default {
},
mounted,
methods: {
searchSites,
searchEntities,
},
};
</script>
@@ -135,7 +133,7 @@ export default {
}
}
.network-tiles {
.entity-tiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
grid-gap: 1rem;

View File

@@ -211,25 +211,15 @@
target="_blank"
rel="noopener noreferrer"
class="link added"
>{{ formatDate(release.dateAdded, 'MMMM D, YYYY') }}</a>
>{{ formatDate(release.createdAt, 'MMMM D, YYYY HH:mm') }}</a>
</span>
<div class="row">
<Icon icon="paste2" />
<input
class="filename"
:value="filename"
@focus="copyFilename"
>
</div>
</div>
</div>
</template>
<script>
import config from 'config';
import format from 'template-format';
// import config from 'config';
// import format from 'template-format';
import Banner from './banner.vue';
import Actor from '../tile/actor.vue';
@@ -240,13 +230,9 @@ function pageTitle() {
return this.release && this.release.title;
}
function copyFilename(event) {
event.target.setSelectionRange(0, event.target.value.length);
document.execCommand('copy');
}
async function mounted() {
this.release = await this.$store.dispatch('fetchReleaseById', this.$route.params.releaseId);
/*
this.filename = format(config.filename.pattern, {
...this.release,
shootId: this.release.shootId || '',
@@ -254,6 +240,7 @@ async function mounted() {
}, {
spreadSeparator: config.filename.separator,
});
*/
}
export default {
@@ -273,9 +260,6 @@ export default {
pageTitle,
},
mounted,
methods: {
copyFilename,
},
};
</script>

View File

@@ -0,0 +1,74 @@
<template>
<a
:href="`/${entity.type}/${entity.slug}`"
:title="entity.name"
class="tile"
>
<img
v-if="entity.type === 'channel'"
:src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`"
:alt="entity.name"
class="logo"
>
<img
v-else
:src="`/img/logos/${entity.slug}/thumbs/network.png`"
:alt="entity.name"
class="logo"
>
</a>
</template>
<script>
export default {
props: {
entity: {
type: Object,
default: null,
},
},
};
</script>
<style lang="scss" scoped>
@import 'theme';
.tile {
height: 6rem;
background: $tile;
display: flex;
flex-shrink: 0;
justify-content: center;
align-items: center;
box-sizing: border-box;
padding: .5rem 1rem;
border-radius: .25rem;
box-shadow: 0 0 3px rgba(0, 0, 0, .25);
text-align: center;
}
.link {
text-decoration: none;
}
.logo {
max-width: 100%;
max-height: 100%;
color: $text-contrast;
display: flex;
align-items: center;
justify-content: center;
font-size: 1rem;
font-weight: bold;
filter: $logo-highlight;
}
.title {
color: $text;
height: 100%;
display: flex;
align-items: center;
margin: 0;
}
</style>

View File

@@ -1,33 +1,33 @@
<template>
<a
:href="`/network/${network.slug}`"
:title="network.name"
class="tile"
:class="{ sfw }"
>
<img
:src="`/img/logos/${network.slug}/thumbs/network.png`"
:alt="network.name"
class="logo"
>
</a>
<a
:href="`/network/${network.slug}`"
:title="network.name"
class="tile"
:class="{ sfw }"
>
<img
:src="`/img/logos/${network.slug}/thumbs/network.png`"
:alt="network.name"
class="logo lazy"
>
</a>
</template>
<script>
function sfw() {
return this.$store.state.ui.sfw;
return this.$store.state.ui.sfw;
}
export default {
props: {
network: {
type: Object,
default: null,
},
},
computed: {
sfw,
},
props: {
network: {
type: Object,
default: null,
},
},
computed: {
sfw,
},
};
</script>
@@ -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 {

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -0,0 +1 @@
export default {};

View File

@@ -0,0 +1 @@
export default {};

View File

@@ -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
}
}

View File

@@ -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,
};
}

View File

@@ -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));