forked from DebaucheryLibrarian/traxxx
				
			Generating thumbnails. Added site overview page.
This commit is contained in:
		
							parent
							
								
									948597d265
								
							
						
					
					
						commit
						50816d7b28
					
				| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
        "no-console": 0,
 | 
			
		||||
        "indent": ["error", 4],
 | 
			
		||||
        "max-len": [2, {
 | 
			
		||||
            "code": 200,
 | 
			
		||||
            "code": 300,
 | 
			
		||||
            "tabWidth": 4,
 | 
			
		||||
            "ignoreUrls": true
 | 
			
		||||
        }],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,8 @@ import ReleaseTile from '../tile/release.vue';
 | 
			
		|||
 | 
			
		||||
async function mounted() {
 | 
			
		||||
    this.releases = await this.$store.dispatch('fetchReleases');
 | 
			
		||||
    this.networks = await this.$store.dispatch('fetchNetworks');
 | 
			
		||||
 | 
			
		||||
    this.pageTitle = '';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +93,7 @@ export default {
 | 
			
		|||
            showGay: false,
 | 
			
		||||
            showTrans: false,
 | 
			
		||||
            releases: [],
 | 
			
		||||
            networks: [],
 | 
			
		||||
            pageTitle: null,
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,6 +125,6 @@ export default {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.sites {
 | 
			
		||||
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
 | 
			
		||||
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
                <video
 | 
			
		||||
                    v-if="release.trailer"
 | 
			
		||||
                    :src="`/media/${release.trailer.path}`"
 | 
			
		||||
                    :poster="`/media/${(release.poster && release.poster.path) || (release.photos.length && release.photos[Math.floor(Math.random() * release.photos.length)].path)}`"
 | 
			
		||||
                    :poster="`/media/${(release.poster && release.poster.thumbnail) || (release.photos.length && release.photos[Math.floor(Math.random() * release.photos.length)].path)}`"
 | 
			
		||||
                    :alt="release.title"
 | 
			
		||||
                    class="banner-item"
 | 
			
		||||
                    controls
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +23,7 @@
 | 
			
		|||
                rel="noopener noreferrer"
 | 
			
		||||
            >
 | 
			
		||||
                <img
 | 
			
		||||
                    :src="`/media/${photo.path}`"
 | 
			
		||||
                    :src="`/media/${photo.thumbnail}`"
 | 
			
		||||
                    :alt="`Photo ${photo.index + 1}`"
 | 
			
		||||
                    class="banner-item"
 | 
			
		||||
                >
 | 
			
		||||
| 
						 | 
				
			
			@ -77,15 +77,11 @@
 | 
			
		|||
 | 
			
		||||
            <a
 | 
			
		||||
                :href="`/network/${release.network.slug}`"
 | 
			
		||||
                target="_blank"
 | 
			
		||||
                rel="noopener noreferrer"
 | 
			
		||||
                class="network-link"
 | 
			
		||||
            >{{ release.network.name }}:</a>
 | 
			
		||||
 | 
			
		||||
            <a
 | 
			
		||||
                :href="`/site/${release.site.slug}`"
 | 
			
		||||
                target="_blank"
 | 
			
		||||
                rel="noopener noreferrer"
 | 
			
		||||
                class="site-link"
 | 
			
		||||
            >{{ release.site.name }}</a>
 | 
			
		||||
        </span>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,157 @@
 | 
			
		|||
<template>
 | 
			
		||||
    <div>
 | 
			
		||||
        <h1>Site</h1>
 | 
			
		||||
    <div
 | 
			
		||||
        v-if="site"
 | 
			
		||||
        class="content site"
 | 
			
		||||
    >
 | 
			
		||||
        <div class="header">
 | 
			
		||||
            <span class="intro">
 | 
			
		||||
                <h2 class="title">
 | 
			
		||||
                    {{ site.name }}
 | 
			
		||||
                    <a
 | 
			
		||||
                        v-if="site.url"
 | 
			
		||||
                        :href="site.url"
 | 
			
		||||
                        target="_blank"
 | 
			
		||||
                        rel="noopener noreferrer"
 | 
			
		||||
                    >
 | 
			
		||||
                        <Icon
 | 
			
		||||
                            icon="new-tab"
 | 
			
		||||
                            class="icon-href"
 | 
			
		||||
                        />
 | 
			
		||||
                    </a>
 | 
			
		||||
                </h2>
 | 
			
		||||
 | 
			
		||||
                <span class="description">{{ site.description }}</span>
 | 
			
		||||
            </span>
 | 
			
		||||
 | 
			
		||||
            <span class="link">
 | 
			
		||||
                <a
 | 
			
		||||
                    v-if="site.url"
 | 
			
		||||
                    :href="site.url"
 | 
			
		||||
                    target="_blank"
 | 
			
		||||
                    rel="noopener noreferrer"
 | 
			
		||||
                    class="logo-link"
 | 
			
		||||
                >
 | 
			
		||||
                    <object
 | 
			
		||||
                        :data="`/img/logos/${site.network.slug}/${site.slug}.png`"
 | 
			
		||||
                        :title="site.name"
 | 
			
		||||
                        type="image/png"
 | 
			
		||||
                        class="logo"
 | 
			
		||||
                    >{{ site.name }}</object>
 | 
			
		||||
                </a>
 | 
			
		||||
 | 
			
		||||
                <span class="networklogo-container">
 | 
			
		||||
                    Part of
 | 
			
		||||
                    <a
 | 
			
		||||
                        :href="site.network.url"
 | 
			
		||||
                        target="_blank"
 | 
			
		||||
                        rel="noopener noreferrer"
 | 
			
		||||
                        class="networklogo-link"
 | 
			
		||||
                    >
 | 
			
		||||
                        <object
 | 
			
		||||
                            :data="`/img/logos/${site.network.slug}/network.png`"
 | 
			
		||||
                            :title="site.network.name"
 | 
			
		||||
                            type="image/png"
 | 
			
		||||
                            class="networklogo"
 | 
			
		||||
                        >{{ site.network.name }}</object>
 | 
			
		||||
                    </a>
 | 
			
		||||
                </span>
 | 
			
		||||
            </span>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="content-inner">
 | 
			
		||||
            <h3 class="heading">Latest releases</h3>
 | 
			
		||||
 | 
			
		||||
            <ul class="nolist scenes">
 | 
			
		||||
                <li
 | 
			
		||||
                    v-for="release in releases"
 | 
			
		||||
                    :key="`release-${release.id}`"
 | 
			
		||||
                >
 | 
			
		||||
                    <ReleaseTile :release="release" />
 | 
			
		||||
                </li>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import ReleaseTile from '../tile/release.vue';
 | 
			
		||||
 | 
			
		||||
async function mounted() {
 | 
			
		||||
    [this.site] = await this.$store.dispatch('fetchSites', this.$route.params.siteSlug);
 | 
			
		||||
    this.releases = await this.$store.dispatch('fetchSiteReleases', this.$route.params.siteSlug);
 | 
			
		||||
 | 
			
		||||
    this.pageTitle = this.site.name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
        ReleaseTile,
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            site: null,
 | 
			
		||||
            releases: null,
 | 
			
		||||
            pageTitle: null,
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    mounted,
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
@import 'theme';
 | 
			
		||||
 | 
			
		||||
.header {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    padding: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.title {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    margin: 0 .5rem 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.heading {
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    margin: 0 0 1rem 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.link {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-shrink: 0;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    align-items: flex-end;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.logo {
 | 
			
		||||
    height: 3rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.networklogo-container {
 | 
			
		||||
    color: $shadow;
 | 
			
		||||
    display: block;
 | 
			
		||||
    margin: .5rem 0 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.networklogo {
 | 
			
		||||
    color: $text;
 | 
			
		||||
    height: 1rem;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sites,
 | 
			
		||||
.scenes {
 | 
			
		||||
    display: grid;
 | 
			
		||||
    grid-gap: 1rem;
 | 
			
		||||
    margin: 0 0 1rem 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.scenes {
 | 
			
		||||
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sites {
 | 
			
		||||
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,6 @@
 | 
			
		|||
                <a
 | 
			
		||||
                    :href="`/site/${release.site.slug}`"
 | 
			
		||||
                    :title="release.network.name"
 | 
			
		||||
                    target="_blank"
 | 
			
		||||
                    rel="noopener noreferrer"
 | 
			
		||||
                    class="site site-link"
 | 
			
		||||
                >{{ release.site.name }}</a>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,14 +32,14 @@
 | 
			
		|||
            >
 | 
			
		||||
                <img
 | 
			
		||||
                    v-if="release.poster"
 | 
			
		||||
                    :src="`/media/${release.poster.path}`"
 | 
			
		||||
                    :src="`/media/${release.poster.thumbnail}`"
 | 
			
		||||
                    :alt="release.title"
 | 
			
		||||
                    class="thumbnail"
 | 
			
		||||
                >
 | 
			
		||||
 | 
			
		||||
                <img
 | 
			
		||||
                    v-else-if="release.photos.length > 0"
 | 
			
		||||
                    :src="`/media/${release.photos[0].path}`"
 | 
			
		||||
                    :src="`/media/${release.photos[0].thumbnail}`"
 | 
			
		||||
                    :alt="release.title"
 | 
			
		||||
                    class="thumbnail"
 | 
			
		||||
                >
 | 
			
		||||
| 
						 | 
				
			
			@ -92,8 +90,6 @@
 | 
			
		|||
                    >
 | 
			
		||||
                        <a
 | 
			
		||||
                            :href="`/tag/${tag.slug}`"
 | 
			
		||||
                            target="_blank"
 | 
			
		||||
                            rel="noopener noreferrer"
 | 
			
		||||
                            class="tag-link"
 | 
			
		||||
                        >{{ tag.name }}</a>
 | 
			
		||||
                    </li>
 | 
			
		||||
| 
						 | 
				
			
			@ -135,11 +131,8 @@ export default {
 | 
			
		|||
 | 
			
		||||
.thumbnail {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 12rem;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    object-fit: cover;
 | 
			
		||||
    object-position: 50% 0;
 | 
			
		||||
    background-position: center;
 | 
			
		||||
    background-size: cover;
 | 
			
		||||
    background-color: $shadow-hint;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ export default {
 | 
			
		|||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    height: 4rem;
 | 
			
		||||
    height: 3rem;
 | 
			
		||||
    object-fit: contain;
 | 
			
		||||
    font-size: 1rem;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
import { get } from '../api';
 | 
			
		||||
 | 
			
		||||
function initSitesActions(_store, _router) {
 | 
			
		||||
    async function fetchSites({ _commit }, siteId) {
 | 
			
		||||
        const sites = await get(`/sites/${siteId || ''}`);
 | 
			
		||||
 | 
			
		||||
        return sites;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async function fetchSiteReleases({ _commit }, siteId) {
 | 
			
		||||
        const releases = await get(`/sites/${siteId}/releases`);
 | 
			
		||||
 | 
			
		||||
        return releases;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        fetchSites,
 | 
			
		||||
        fetchSiteReleases,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default initSitesActions;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
export default {};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
import state from './state';
 | 
			
		||||
import mutations from './mutations';
 | 
			
		||||
import actions from './actions';
 | 
			
		||||
 | 
			
		||||
function initSitesStore(store, router) {
 | 
			
		||||
    return {
 | 
			
		||||
        state,
 | 
			
		||||
        mutations,
 | 
			
		||||
        actions: actions(store, router),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default initSitesStore;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
export default {};
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ import Vuex from 'vuex';
 | 
			
		|||
 | 
			
		||||
import initAuthStore from './auth/auth';
 | 
			
		||||
import initReleasesStore from './releases/releases';
 | 
			
		||||
import initSitesStore from './sites/sites';
 | 
			
		||||
import initNetworksStore from './networks/networks';
 | 
			
		||||
import initActorsStore from './actors/actors';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,7 @@ function initStore(router) {
 | 
			
		|||
    store.registerModule('auth', initAuthStore(store, router));
 | 
			
		||||
    store.registerModule('releases', initReleasesStore(store, router));
 | 
			
		||||
    store.registerModule('actors', initActorsStore(store, router));
 | 
			
		||||
    store.registerModule('sites', initSitesStore(store, router));
 | 
			
		||||
    store.registerModule('networks', initNetworksStore(store, router));
 | 
			
		||||
 | 
			
		||||
    return store;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,8 @@ module.exports = {
 | 
			
		|||
        '21sextury',
 | 
			
		||||
        'blowpass',
 | 
			
		||||
        'brazzers',
 | 
			
		||||
        'dogfart',
 | 
			
		||||
        'evilangel',
 | 
			
		||||
        'julesjordan',
 | 
			
		||||
        ['kink', [
 | 
			
		||||
            'boundgangbangs',
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +29,7 @@ module.exports = {
 | 
			
		|||
            'waterbondage',
 | 
			
		||||
        ]],
 | 
			
		||||
        'legalporno',
 | 
			
		||||
        'mikeadriano',
 | 
			
		||||
        'mofos',
 | 
			
		||||
        'naughtyamerica',
 | 
			
		||||
        'pervcity',
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +82,10 @@ module.exports = {
 | 
			
		|||
            width: 30,
 | 
			
		||||
        },
 | 
			
		||||
    ],
 | 
			
		||||
    photoPath: './',
 | 
			
		||||
    media: {
 | 
			
		||||
        path: './',
 | 
			
		||||
        thumbnailSize: 324, // width for 16:9 will be exactly 576px
 | 
			
		||||
    },
 | 
			
		||||
    filename: {
 | 
			
		||||
        dateFormat: 'DD-MM-YYYY',
 | 
			
		||||
        actorsJoin: ', ',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -145,8 +145,10 @@ exports.up = knex => Promise.resolve()
 | 
			
		|||
        table.increments('id', 16);
 | 
			
		||||
 | 
			
		||||
        table.string('path');
 | 
			
		||||
        table.string('thumbnail');
 | 
			
		||||
        table.integer('index');
 | 
			
		||||
        table.string('mime');
 | 
			
		||||
        table.string('hash');
 | 
			
		||||
 | 
			
		||||
        table.enum('domain', ['networks', 'sites', 'releases', 'actors', 'directors']);
 | 
			
		||||
        table.integer('target_id', 16);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1584,8 +1584,7 @@
 | 
			
		|||
    "aproba": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
 | 
			
		||||
    },
 | 
			
		||||
    "arch": {
 | 
			
		||||
      "version": "2.1.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -1596,7 +1595,6 @@
 | 
			
		|||
      "version": "1.1.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
 | 
			
		||||
      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "delegates": "^1.0.0",
 | 
			
		||||
        "readable-stream": "^2.0.6"
 | 
			
		||||
| 
						 | 
				
			
			@ -2446,6 +2444,41 @@
 | 
			
		|||
      "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "bl": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "readable-stream": "^3.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "readable-stream": {
 | 
			
		||||
          "version": "3.4.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
 | 
			
		||||
          "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "inherits": "^2.0.3",
 | 
			
		||||
            "string_decoder": "^1.1.1",
 | 
			
		||||
            "util-deprecate": "^1.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "blake2": {
 | 
			
		||||
      "version": "4.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/blake2/-/blake2-4.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-PIOc6RXAZYBYcdpyMzI6/SCU3BH8EbmA9vr0BAVyQv48CQTXDN6viHOTM+8KQue2IPsyHNpIR3UDisz8rZDPTA==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "nan": "^2.14.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "nan": {
 | 
			
		||||
          "version": "2.14.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
 | 
			
		||||
          "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "block-stream": {
 | 
			
		||||
      "version": "0.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -2859,8 +2892,7 @@
 | 
			
		|||
    "chownr": {
 | 
			
		||||
      "version": "1.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g=="
 | 
			
		||||
    },
 | 
			
		||||
    "chrome-trace-event": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -3003,6 +3035,15 @@
 | 
			
		|||
        "object-visit": "^1.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "color": {
 | 
			
		||||
      "version": "3.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
 | 
			
		||||
      "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "color-convert": "^1.9.1",
 | 
			
		||||
        "color-string": "^1.5.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "color-convert": {
 | 
			
		||||
      "version": "1.9.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -3016,6 +3057,15 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
 | 
			
		||||
      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
 | 
			
		||||
    },
 | 
			
		||||
    "color-string": {
 | 
			
		||||
      "version": "1.5.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
 | 
			
		||||
      "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "color-name": "^1.0.0",
 | 
			
		||||
        "simple-swizzle": "^0.2.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "colors": {
 | 
			
		||||
      "version": "1.3.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -3121,8 +3171,7 @@
 | 
			
		|||
    "console-control-strings": {
 | 
			
		||||
      "version": "1.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
 | 
			
		||||
      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
 | 
			
		||||
    },
 | 
			
		||||
    "consolidate": {
 | 
			
		||||
      "version": "0.15.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -3480,6 +3529,19 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
 | 
			
		||||
      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
 | 
			
		||||
    },
 | 
			
		||||
    "decompress-response": {
 | 
			
		||||
      "version": "4.2.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
 | 
			
		||||
      "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "mimic-response": "^2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "deep-extend": {
 | 
			
		||||
      "version": "0.6.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
 | 
			
		||||
      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
 | 
			
		||||
    },
 | 
			
		||||
    "deep-is": {
 | 
			
		||||
      "version": "0.1.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -3547,8 +3609,7 @@
 | 
			
		|||
    "delegates": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
 | 
			
		||||
    },
 | 
			
		||||
    "depd": {
 | 
			
		||||
      "version": "1.1.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -3584,6 +3645,11 @@
 | 
			
		|||
        "repeating": "^2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "detect-libc": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
 | 
			
		||||
    },
 | 
			
		||||
    "dev-null": {
 | 
			
		||||
      "version": "0.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/dev-null/-/dev-null-0.1.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -4293,6 +4359,11 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "expand-template": {
 | 
			
		||||
      "version": "2.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
 | 
			
		||||
    },
 | 
			
		||||
    "expand-tilde": {
 | 
			
		||||
      "version": "2.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -4809,6 +4880,11 @@
 | 
			
		|||
        "readable-stream": "^2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "fs-constants": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
 | 
			
		||||
    },
 | 
			
		||||
    "fs-extra": {
 | 
			
		||||
      "version": "7.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -4819,6 +4895,14 @@
 | 
			
		|||
        "universalify": "^0.1.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "fs-minipass": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "minipass": "^3.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "fs-readdir-recursive": {
 | 
			
		||||
      "version": "1.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -5418,7 +5502,6 @@
 | 
			
		|||
      "version": "2.7.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
 | 
			
		||||
      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "aproba": "^1.0.3",
 | 
			
		||||
        "console-control-strings": "^1.0.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -5433,14 +5516,12 @@
 | 
			
		|||
        "ansi-regex": {
 | 
			
		||||
          "version": "2.1.1",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
 | 
			
		||||
          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
 | 
			
		||||
          "dev": true
 | 
			
		||||
          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
 | 
			
		||||
        },
 | 
			
		||||
        "is-fullwidth-code-point": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
 | 
			
		||||
          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "number-is-nan": "^1.0.0"
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -5449,7 +5530,6 @@
 | 
			
		|||
          "version": "1.0.2",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
 | 
			
		||||
          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "code-point-at": "^1.0.0",
 | 
			
		||||
            "is-fullwidth-code-point": "^1.0.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -5460,7 +5540,6 @@
 | 
			
		|||
          "version": "3.0.1",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
 | 
			
		||||
          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "ansi-regex": "^2.0.0"
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -5508,6 +5587,11 @@
 | 
			
		|||
        "assert-plus": "^1.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "github-from-package": {
 | 
			
		||||
      "version": "0.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
 | 
			
		||||
    },
 | 
			
		||||
    "glob": {
 | 
			
		||||
      "version": "7.1.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -5679,8 +5763,7 @@
 | 
			
		|||
    "has-unicode": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
 | 
			
		||||
    },
 | 
			
		||||
    "has-value": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -7137,6 +7220,11 @@
 | 
			
		|||
      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "mimic-response": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "mini-css-extract-plugin": {
 | 
			
		||||
      "version": "0.7.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.7.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -7174,6 +7262,37 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
 | 
			
		||||
      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
 | 
			
		||||
    },
 | 
			
		||||
    "minipass": {
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "yallist": "^4.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "yallist": {
 | 
			
		||||
          "version": "4.0.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
 | 
			
		||||
          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "minizlib": {
 | 
			
		||||
      "version": "2.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "minipass": "^3.0.0",
 | 
			
		||||
        "yallist": "^4.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "yallist": {
 | 
			
		||||
          "version": "4.0.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
 | 
			
		||||
          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "mississippi": {
 | 
			
		||||
      "version": "3.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -7310,6 +7429,11 @@
 | 
			
		|||
        "to-regex": "^3.0.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "napi-build-utils": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA=="
 | 
			
		||||
    },
 | 
			
		||||
    "natural-compare": {
 | 
			
		||||
      "version": "1.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -7337,6 +7461,14 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
 | 
			
		||||
      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
 | 
			
		||||
    },
 | 
			
		||||
    "node-abi": {
 | 
			
		||||
      "version": "2.12.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.12.0.tgz",
 | 
			
		||||
      "integrity": "sha512-VhPBXCIcvmo/5K8HPmnWJyyhvgKxnHTUMXR/XwGHV68+wrgkzST4UmQrY/XszSWA5dtnXpNp528zkcyJ/pzVcw==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "semver": "^5.4.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node-gyp": {
 | 
			
		||||
      "version": "3.8.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -7520,6 +7652,11 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "noop-logger": {
 | 
			
		||||
      "version": "0.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
 | 
			
		||||
      "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
 | 
			
		||||
    },
 | 
			
		||||
    "nopt": {
 | 
			
		||||
      "version": "4.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -7577,7 +7714,6 @@
 | 
			
		|||
      "version": "4.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
 | 
			
		||||
      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "are-we-there-yet": "~1.1.2",
 | 
			
		||||
        "console-control-strings": "~1.1.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -8379,6 +8515,35 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "prebuild-install": {
 | 
			
		||||
      "version": "5.3.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
 | 
			
		||||
      "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "detect-libc": "^1.0.3",
 | 
			
		||||
        "expand-template": "^2.0.3",
 | 
			
		||||
        "github-from-package": "0.0.0",
 | 
			
		||||
        "minimist": "^1.2.0",
 | 
			
		||||
        "mkdirp": "^0.5.1",
 | 
			
		||||
        "napi-build-utils": "^1.0.1",
 | 
			
		||||
        "node-abi": "^2.7.0",
 | 
			
		||||
        "noop-logger": "^0.1.1",
 | 
			
		||||
        "npmlog": "^4.0.1",
 | 
			
		||||
        "pump": "^3.0.0",
 | 
			
		||||
        "rc": "^1.2.7",
 | 
			
		||||
        "simple-get": "^3.0.3",
 | 
			
		||||
        "tar-fs": "^2.0.0",
 | 
			
		||||
        "tunnel-agent": "^0.6.0",
 | 
			
		||||
        "which-pm-runs": "^1.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "minimist": {
 | 
			
		||||
          "version": "1.2.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
 | 
			
		||||
          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "prelude-ls": {
 | 
			
		||||
      "version": "1.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -8655,6 +8820,24 @@
 | 
			
		|||
        "schema-utils": "^1.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "rc": {
 | 
			
		||||
      "version": "1.2.8",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
 | 
			
		||||
      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "deep-extend": "^0.6.0",
 | 
			
		||||
        "ini": "~1.3.0",
 | 
			
		||||
        "minimist": "^1.2.0",
 | 
			
		||||
        "strip-json-comments": "~2.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "minimist": {
 | 
			
		||||
          "version": "1.2.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
 | 
			
		||||
          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "react": {
 | 
			
		||||
      "version": "16.8.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -9506,6 +9689,34 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "sharp": {
 | 
			
		||||
      "version": "0.23.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.2.tgz",
 | 
			
		||||
      "integrity": "sha512-BSo0tq6Jtzwa6GDKvVMNNPCP/HLczrFLGVcorYv7OtxlKx4UPHy7x9DdfT8F+PK7FCFDemVRwtsjWpvaJI9v6w==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "color": "^3.1.2",
 | 
			
		||||
        "detect-libc": "^1.0.3",
 | 
			
		||||
        "nan": "^2.14.0",
 | 
			
		||||
        "npmlog": "^4.1.2",
 | 
			
		||||
        "prebuild-install": "^5.3.2",
 | 
			
		||||
        "semver": "^6.3.0",
 | 
			
		||||
        "simple-get": "^3.1.0",
 | 
			
		||||
        "tar": "^5.0.5",
 | 
			
		||||
        "tunnel-agent": "^0.6.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "nan": {
 | 
			
		||||
          "version": "2.14.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
 | 
			
		||||
          "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
 | 
			
		||||
        },
 | 
			
		||||
        "semver": {
 | 
			
		||||
          "version": "6.3.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
 | 
			
		||||
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "shebang-command": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -9529,6 +9740,36 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
 | 
			
		||||
      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
 | 
			
		||||
    },
 | 
			
		||||
    "simple-concat": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
 | 
			
		||||
    },
 | 
			
		||||
    "simple-get": {
 | 
			
		||||
      "version": "3.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "decompress-response": "^4.2.0",
 | 
			
		||||
        "once": "^1.3.1",
 | 
			
		||||
        "simple-concat": "^1.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "simple-swizzle": {
 | 
			
		||||
      "version": "0.2.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
 | 
			
		||||
      "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "is-arrayish": "^0.3.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "is-arrayish": {
 | 
			
		||||
          "version": "0.3.2",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
 | 
			
		||||
          "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "slash": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -10027,8 +10268,7 @@
 | 
			
		|||
    "strip-json-comments": {
 | 
			
		||||
      "version": "2.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
 | 
			
		||||
    },
 | 
			
		||||
    "style-loader": {
 | 
			
		||||
      "version": "0.23.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -10099,6 +10339,66 @@
 | 
			
		|||
      "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "tar": {
 | 
			
		||||
      "version": "5.0.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz",
 | 
			
		||||
      "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "chownr": "^1.1.3",
 | 
			
		||||
        "fs-minipass": "^2.0.0",
 | 
			
		||||
        "minipass": "^3.0.0",
 | 
			
		||||
        "minizlib": "^2.1.0",
 | 
			
		||||
        "mkdirp": "^0.5.0",
 | 
			
		||||
        "yallist": "^4.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "chownr": {
 | 
			
		||||
          "version": "1.1.3",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz",
 | 
			
		||||
          "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw=="
 | 
			
		||||
        },
 | 
			
		||||
        "yallist": {
 | 
			
		||||
          "version": "4.0.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
 | 
			
		||||
          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "tar-fs": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "chownr": "^1.1.1",
 | 
			
		||||
        "mkdirp": "^0.5.1",
 | 
			
		||||
        "pump": "^3.0.0",
 | 
			
		||||
        "tar-stream": "^2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "tar-stream": {
 | 
			
		||||
      "version": "2.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "bl": "^3.0.0",
 | 
			
		||||
        "end-of-stream": "^1.4.1",
 | 
			
		||||
        "fs-constants": "^1.0.0",
 | 
			
		||||
        "inherits": "^2.0.3",
 | 
			
		||||
        "readable-stream": "^3.1.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "readable-stream": {
 | 
			
		||||
          "version": "3.4.0",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
 | 
			
		||||
          "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "inherits": "^2.0.3",
 | 
			
		||||
            "string_decoder": "^1.1.1",
 | 
			
		||||
            "util-deprecate": "^1.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "tarn": {
 | 
			
		||||
      "version": "1.1.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/tarn/-/tarn-1.1.4.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -11103,11 +11403,15 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
 | 
			
		||||
    },
 | 
			
		||||
    "which-pm-runs": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
 | 
			
		||||
    },
 | 
			
		||||
    "wide-align": {
 | 
			
		||||
      "version": "1.1.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
 | 
			
		||||
      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "string-width": "^1.0.2 || 2"
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,7 @@
 | 
			
		|||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "bhttp": "^1.2.4",
 | 
			
		||||
        "blake2": "^4.0.0",
 | 
			
		||||
        "bluebird": "^3.5.4",
 | 
			
		||||
        "body-parser": "^1.19.0",
 | 
			
		||||
        "cheerio": "^1.0.0-rc.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +87,7 @@
 | 
			
		|||
        "prop-types": "^15.7.2",
 | 
			
		||||
        "react": "^16.8.6",
 | 
			
		||||
        "react-dom": "^16.8.6",
 | 
			
		||||
        "sharp": "^0.23.2",
 | 
			
		||||
        "tough-cookie": "^3.0.1",
 | 
			
		||||
        "tty-table": "^2.7.0",
 | 
			
		||||
        "vue": "^2.6.10",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,12 +15,10 @@
 | 
			
		|||
}
 | 
			
		||||
.thumbnail[data-v-3abcf101] {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 12rem;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  -o-object-fit: cover;
 | 
			
		||||
     object-fit: cover;
 | 
			
		||||
  -o-object-position: 50% 0;
 | 
			
		||||
     object-position: 50% 0;
 | 
			
		||||
  background-position: center;
 | 
			
		||||
  background-size: cover;
 | 
			
		||||
  background-color: rgba(0, 0, 0, 0.1);
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +224,52 @@
 | 
			
		|||
    color: #ff6c88;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* $primary: #ff886c; */
 | 
			
		||||
.header[data-v-3e57cf44] {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  padding: 1rem;
 | 
			
		||||
}
 | 
			
		||||
.title[data-v-3e57cf44] {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin: 0 .5rem 0 0;
 | 
			
		||||
}
 | 
			
		||||
.heading[data-v-3e57cf44] {
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin: 0 0 1rem 0;
 | 
			
		||||
}
 | 
			
		||||
.link[data-v-3e57cf44] {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-shrink: 0;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  align-items: flex-end;
 | 
			
		||||
}
 | 
			
		||||
.logo[data-v-3e57cf44] {
 | 
			
		||||
  height: 3rem;
 | 
			
		||||
}
 | 
			
		||||
.networklogo-container[data-v-3e57cf44] {
 | 
			
		||||
  color: rgba(0, 0, 0, 0.5);
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin: .5rem 0 0 0;
 | 
			
		||||
}
 | 
			
		||||
.networklogo[data-v-3e57cf44] {
 | 
			
		||||
  color: #222;
 | 
			
		||||
  height: 1rem;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
.sites[data-v-3e57cf44],
 | 
			
		||||
.scenes[data-v-3e57cf44] {
 | 
			
		||||
  display: grid;
 | 
			
		||||
  grid-gap: 1rem;
 | 
			
		||||
  margin: 0 0 1rem 0;
 | 
			
		||||
}
 | 
			
		||||
.scenes[data-v-3e57cf44] {
 | 
			
		||||
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
.sites[data-v-3e57cf44] {
 | 
			
		||||
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* $primary: #ff886c; */
 | 
			
		||||
.tile[data-v-f4958086] {
 | 
			
		||||
  display: flex;
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +291,7 @@
 | 
			
		|||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  height: 4rem;
 | 
			
		||||
  height: 3rem;
 | 
			
		||||
  -o-object-fit: contain;
 | 
			
		||||
     object-fit: contain;
 | 
			
		||||
  font-size: 1rem;
 | 
			
		||||
| 
						 | 
				
			
			@ -288,7 +332,7 @@
 | 
			
		|||
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
.sites[data-v-757c14c2] {
 | 
			
		||||
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
 | 
			
		||||
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* $primary: #ff886c; */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 57 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 57 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 28 KiB  | 
| 
						 | 
				
			
			@ -8,6 +8,6 @@
 | 
			
		|||
        "no-unused-vars": ["error", {"argsIgnorePattern": "^_"}],
 | 
			
		||||
        "no-console": 0,
 | 
			
		||||
        "indent": ["error", 4],
 | 
			
		||||
        "max-len": [2, {"code": 200, "tabWidth": 4, "ignoreUrls": true}]
 | 
			
		||||
        "max-len": [2, {"code": 300, "tabWidth": 4, "ignoreUrls": true}]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,24 @@ async function fetchActors(actorId, actorSlug) {
 | 
			
		|||
    return curateActors(releases);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storeActors(release, releaseEntry) {
 | 
			
		||||
    const actors = await knex('actors').whereIn('name', release.actors);
 | 
			
		||||
    const newActors = release.actors.filter(actorName => !actors.some(actor => actor.name === actorName));
 | 
			
		||||
 | 
			
		||||
    const { rows: insertedActors } = newActors.length
 | 
			
		||||
        ? await knex.raw(`${knex('actors').insert(newActors.map(actorName => ({
 | 
			
		||||
            name: actorName,
 | 
			
		||||
            slug: actorName.toLowerCase().replace(/\s+/g, '-'),
 | 
			
		||||
        })))} ON CONFLICT DO NOTHING RETURNING *`)
 | 
			
		||||
        : { rows: [] };
 | 
			
		||||
 | 
			
		||||
    return knex('actors_associated').insert(actors.concat(insertedActors).map(actor => ({
 | 
			
		||||
        release_id: releaseEntry.id,
 | 
			
		||||
        actor_id: actor.id,
 | 
			
		||||
    })), '*');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    fetchActors,
 | 
			
		||||
    storeActors,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,14 @@ const fs = require('fs-extra');
 | 
			
		|||
const path = require('path');
 | 
			
		||||
const Promise = require('bluebird');
 | 
			
		||||
const moment = require('moment');
 | 
			
		||||
const mime = require('mime');
 | 
			
		||||
const bhttp = require('bhttp');
 | 
			
		||||
 | 
			
		||||
const argv = require('./argv');
 | 
			
		||||
const knex = require('./knex');
 | 
			
		||||
const scrapers = require('./scrapers');
 | 
			
		||||
const fetchScene = require('./fetch-scene');
 | 
			
		||||
const { storeTags } = require('./tags');
 | 
			
		||||
const { storeActors } = require('./actors');
 | 
			
		||||
const { storePoster, storePhotos, storeTrailer } = require('./media');
 | 
			
		||||
 | 
			
		||||
function destructConfigNetworks(networks) {
 | 
			
		||||
    return networks.reduce((acc, network) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -87,112 +88,6 @@ async function findDuplicateReleases(latestReleases, _siteId) {
 | 
			
		|||
        .orWhereIn('entry_id', latestReleasesEntryIds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storeActors(release, releaseEntry) {
 | 
			
		||||
    const actors = await knex('actors').whereIn('name', release.actors);
 | 
			
		||||
    const newActors = release.actors.filter(actorName => !actors.some(actor => actor.name === actorName));
 | 
			
		||||
 | 
			
		||||
    const { rows: insertedActors } = newActors.length
 | 
			
		||||
        ? await knex.raw(`${knex('actors').insert(newActors.map(actorName => ({
 | 
			
		||||
            name: actorName,
 | 
			
		||||
            slug: actorName.toLowerCase().replace(/\s+/g, '-'),
 | 
			
		||||
        })))} ON CONFLICT DO NOTHING RETURNING *`)
 | 
			
		||||
        : { rows: [] };
 | 
			
		||||
 | 
			
		||||
    return knex('actors_associated').insert(actors.concat(insertedActors).map(actor => ({
 | 
			
		||||
        release_id: releaseEntry.id,
 | 
			
		||||
        actor_id: actor.id,
 | 
			
		||||
    })), '*');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storeTags(release, releaseEntry) {
 | 
			
		||||
    return knex('tags_associated').insert(release.tags.map(tagId => ({
 | 
			
		||||
        tag_id: tagId,
 | 
			
		||||
        release_id: releaseEntry.id,
 | 
			
		||||
    })));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storePhotos(release, releaseEntry) {
 | 
			
		||||
    console.log(`Storing ${release.photos.length} photos for (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
    const files = await Promise.map(release.photos, async (photoUrl, index) => {
 | 
			
		||||
        const { pathname } = new URL(photoUrl);
 | 
			
		||||
        const mimetype = mime.getType(pathname);
 | 
			
		||||
 | 
			
		||||
        const res = await bhttp.get(photoUrl);
 | 
			
		||||
 | 
			
		||||
        if (res.statusCode === 200) {
 | 
			
		||||
            const filepath = path.join(release.site.slug, releaseEntry.id.toString(), `${index + 1}.${mime.getExtension(mimetype)}`);
 | 
			
		||||
            await fs.writeFile(path.join(config.photoPath, filepath), res.body);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                filepath,
 | 
			
		||||
                mimetype,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        console.warn(`Failed to store photo ${index + 1} for (${release.site.name}, ${releaseEntry.id}) "${release.title}": ${res.statusCode}`);
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }, {
 | 
			
		||||
        concurrency: 2,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await knex('media').insert(files.filter(file => file).map(({ filepath, mimetype }, index) => ({
 | 
			
		||||
        path: filepath,
 | 
			
		||||
        mime: mimetype,
 | 
			
		||||
        index,
 | 
			
		||||
        domain: 'releases',
 | 
			
		||||
        target_id: releaseEntry.id,
 | 
			
		||||
        role: 'photo',
 | 
			
		||||
    })));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storePoster(release, releaseEntry) {
 | 
			
		||||
    console.log(`Storing poster for (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
    const res = await bhttp.get(release.poster);
 | 
			
		||||
 | 
			
		||||
    if (res.statusCode === 200) {
 | 
			
		||||
        const { pathname } = new URL(release.poster);
 | 
			
		||||
        const mimetype = res.headers['content-type'] || mime.getType(pathname) || 'image/jpeg';
 | 
			
		||||
 | 
			
		||||
        const filepath = path.join(release.site.slug, releaseEntry.id.toString(), `poster.${mime.getExtension(mimetype)}`);
 | 
			
		||||
        await fs.writeFile(path.join(config.photoPath, filepath), res.body);
 | 
			
		||||
 | 
			
		||||
        await knex('media').insert({
 | 
			
		||||
            path: filepath,
 | 
			
		||||
            mime: mimetype,
 | 
			
		||||
            domain: 'releases',
 | 
			
		||||
            target_id: releaseEntry.id,
 | 
			
		||||
            role: 'poster',
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    console.warn(`Failed to store poster for (${release.site.name}, ${releaseEntry.id}) "${release.title}": ${res.statusCode}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storeTrailer(release, releaseEntry) {
 | 
			
		||||
    console.log(`Storing trailer for (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
    const { pathname } = new URL(release.trailer.src);
 | 
			
		||||
    const mimetype = release.trailer.type || mime.getType(pathname);
 | 
			
		||||
 | 
			
		||||
    const res = await bhttp.get(release.trailer.src);
 | 
			
		||||
    const filepath = path.join(release.site.slug, releaseEntry.id.toString(), `trailer${release.trailer.quality ? `_${release.trailer.quality}` : ''}.${mime.getExtension(mimetype)}`);
 | 
			
		||||
    await fs.writeFile(path.join(config.photoPath, filepath), res.body);
 | 
			
		||||
 | 
			
		||||
    await knex('media').insert({
 | 
			
		||||
        path: filepath,
 | 
			
		||||
        mime: mimetype,
 | 
			
		||||
        domain: 'releases',
 | 
			
		||||
        target_id: releaseEntry.id,
 | 
			
		||||
        role: 'trailer',
 | 
			
		||||
        quality: release.trailer.quality || null,
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storeReleases(releases = []) {
 | 
			
		||||
    return Promise.map(releases, async (release) => {
 | 
			
		||||
        const curatedRelease = {
 | 
			
		||||
| 
						 | 
				
			
			@ -212,11 +107,6 @@ async function storeReleases(releases = []) {
 | 
			
		|||
            deep: argv.deep,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        const releaseQuery = `${knex('releases').insert(curatedRelease).toString()} ON CONFLICT DO NOTHING RETURNING *`;
 | 
			
		||||
        const releaseEntry = await knex.raw(releaseQuery);
 | 
			
		||||
        */
 | 
			
		||||
 | 
			
		||||
        const releaseEntries = await knex('releases')
 | 
			
		||||
            .insert(curatedRelease)
 | 
			
		||||
            .returning('*');
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +117,7 @@ async function storeReleases(releases = []) {
 | 
			
		|||
            console.log(`Stored (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
            if (release.poster || (release.photos && release.photos.length)) {
 | 
			
		||||
                await fs.mkdir(path.join(config.photoPath, release.site.slug, releaseEntry.id.toString()), { recursive: true });
 | 
			
		||||
                await fs.mkdir(path.join(config.media.path, release.site.network.slug, release.site.slug, releaseEntry.id.toString()), { recursive: true });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await Promise.all([
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,137 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
const config = require('config');
 | 
			
		||||
const Promise = require('bluebird');
 | 
			
		||||
const path = require('path');
 | 
			
		||||
const fs = require('fs-extra');
 | 
			
		||||
const bhttp = require('bhttp');
 | 
			
		||||
const mime = require('mime');
 | 
			
		||||
const sharp = require('sharp');
 | 
			
		||||
const blake2 = require('blake2');
 | 
			
		||||
 | 
			
		||||
const knex = require('./knex');
 | 
			
		||||
 | 
			
		||||
function getHash(buffer) {
 | 
			
		||||
    const hash = blake2.createHash('blake2b', { digestLength: 24 });
 | 
			
		||||
 | 
			
		||||
    hash.update(buffer);
 | 
			
		||||
 | 
			
		||||
    return hash.digest('hex');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storePoster(release, releaseEntry) {
 | 
			
		||||
    console.log(`Storing poster for (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
    const res = await bhttp.get(release.poster);
 | 
			
		||||
    const thumbnail = await sharp(res.body)
 | 
			
		||||
        .resize({ width: Math.floor((config.media.thumbnailSize / 9) * 16), height: config.media.thumbnailSize }) // ensure thumbnail is 16:9
 | 
			
		||||
        .toBuffer();
 | 
			
		||||
 | 
			
		||||
    if (res.statusCode === 200) {
 | 
			
		||||
        const { pathname } = new URL(release.poster);
 | 
			
		||||
        const mimetype = res.headers['content-type'] || mime.getType(pathname) || 'image/jpeg';
 | 
			
		||||
        const extension = mime.getExtension(mimetype);
 | 
			
		||||
 | 
			
		||||
        const filepath = path.join(release.site.network.slug, release.site.slug, releaseEntry.id.toString(), `poster.${extension}`);
 | 
			
		||||
        const thumbpath = path.join(release.site.network.slug, release.site.slug, releaseEntry.id.toString(), `poster_thumb.${extension}`);
 | 
			
		||||
        const hash = getHash(res.body);
 | 
			
		||||
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
            fs.writeFile(path.join(config.media.path, filepath), res.body),
 | 
			
		||||
            fs.writeFile(path.join(config.media.path, thumbpath), thumbnail),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        await knex('media').insert({
 | 
			
		||||
            path: filepath,
 | 
			
		||||
            thumbnail: thumbpath,
 | 
			
		||||
            mime: mimetype,
 | 
			
		||||
            hash,
 | 
			
		||||
            domain: 'releases',
 | 
			
		||||
            target_id: releaseEntry.id,
 | 
			
		||||
            role: 'poster',
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    console.warn(`Failed to store poster for (${release.site.name}, ${releaseEntry.id}) "${release.title}": ${res.statusCode}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storePhotos(release, releaseEntry) {
 | 
			
		||||
    console.log(`Storing ${release.photos.length} photos for (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
    const files = await Promise.map(release.photos, async (photoUrl, index) => {
 | 
			
		||||
        const { pathname } = new URL(photoUrl);
 | 
			
		||||
        const mimetype = mime.getType(pathname);
 | 
			
		||||
 | 
			
		||||
        const res = await bhttp.get(photoUrl);
 | 
			
		||||
        const thumbnail = await sharp(res.body).resize({ height: config.media.thumbnailSize }).toBuffer();
 | 
			
		||||
 | 
			
		||||
        if (res.statusCode === 200) {
 | 
			
		||||
            const extension = mime.getExtension(mimetype);
 | 
			
		||||
 | 
			
		||||
            const filepath = path.join(release.site.network.slug, release.site.slug, releaseEntry.id.toString(), `${index + 1}.${extension}`);
 | 
			
		||||
            const thumbpath = path.join(release.site.network.slug, release.site.slug, releaseEntry.id.toString(), `${index + 1}_thumb.${extension}`);
 | 
			
		||||
            const hash = getHash(res.body);
 | 
			
		||||
 | 
			
		||||
            await Promise.all([
 | 
			
		||||
                fs.writeFile(path.join(config.media.path, filepath), res.body),
 | 
			
		||||
                fs.writeFile(path.join(config.media.path, thumbpath), thumbnail),
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                filepath,
 | 
			
		||||
                thumbpath,
 | 
			
		||||
                mimetype,
 | 
			
		||||
                hash,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        console.warn(`Failed to store photo ${index + 1} for (${release.site.name}, ${releaseEntry.id}) "${release.title}": ${res.statusCode}`);
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }, {
 | 
			
		||||
        concurrency: 2,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await knex('media')
 | 
			
		||||
        .insert(files.filter(file => file)
 | 
			
		||||
            .map((file, index) => ({
 | 
			
		||||
                path: file.filepath,
 | 
			
		||||
                thumbnail: file.thumbpath,
 | 
			
		||||
                mime: file.mimetype,
 | 
			
		||||
                hash: file.hash,
 | 
			
		||||
                index,
 | 
			
		||||
                domain: 'releases',
 | 
			
		||||
                target_id: releaseEntry.id,
 | 
			
		||||
                role: 'photo',
 | 
			
		||||
            })));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function storeTrailer(release, releaseEntry) {
 | 
			
		||||
    console.log(`Storing trailer for (${release.site.name}, ${releaseEntry.id}) "${release.title}"`);
 | 
			
		||||
 | 
			
		||||
    const { pathname } = new URL(release.trailer.src);
 | 
			
		||||
    const mimetype = release.trailer.type || mime.getType(pathname);
 | 
			
		||||
 | 
			
		||||
    const res = await bhttp.get(release.trailer.src);
 | 
			
		||||
    const filepath = path.join(release.site.network.slug, release.site.slug, releaseEntry.id.toString(), `trailer${release.trailer.quality ? `_${release.trailer.quality}` : ''}.${mime.getExtension(mimetype)}`);
 | 
			
		||||
 | 
			
		||||
    await Promise.all([
 | 
			
		||||
        fs.writeFile(path.join(config.media.path, filepath), res.body),
 | 
			
		||||
        knex('media').insert({
 | 
			
		||||
            path: filepath,
 | 
			
		||||
            mime: mimetype,
 | 
			
		||||
            domain: 'releases',
 | 
			
		||||
            target_id: releaseEntry.id,
 | 
			
		||||
            role: 'trailer',
 | 
			
		||||
            quality: release.trailer.quality || null,
 | 
			
		||||
        }),
 | 
			
		||||
    ]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    storePoster,
 | 
			
		||||
    storePhotos,
 | 
			
		||||
    storeTrailer,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										32
									
								
								src/sites.js
								
								
								
								
							
							
						
						
									
										32
									
								
								src/sites.js
								
								
								
								
							| 
						 | 
				
			
			@ -3,8 +3,6 @@
 | 
			
		|||
const knex = require('./knex');
 | 
			
		||||
 | 
			
		||||
async function curateSite(site) {
 | 
			
		||||
    const network = await knex('network').where({ id: site.network_id });
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        id: site.id,
 | 
			
		||||
        name: site.name,
 | 
			
		||||
| 
						 | 
				
			
			@ -12,36 +10,40 @@ async function curateSite(site) {
 | 
			
		|||
        description: site.description,
 | 
			
		||||
        slug: site.slug,
 | 
			
		||||
        network: {
 | 
			
		||||
            id: network.id,
 | 
			
		||||
            name: network.name,
 | 
			
		||||
            url: network.url,
 | 
			
		||||
            description: network.description,
 | 
			
		||||
            slug: network.slug,
 | 
			
		||||
            id: site.network_id,
 | 
			
		||||
            name: site.network_name,
 | 
			
		||||
            slug: site.network_slug,
 | 
			
		||||
            url: site.network_url,
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function curateSites(releases) {
 | 
			
		||||
    return Promise.all(releases.map(async site => curateSite(site)));
 | 
			
		||||
function curateSites(sites) {
 | 
			
		||||
    return Promise.all(sites.map(async site => curateSite(site)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function fetchSites(siteId, siteSlug) {
 | 
			
		||||
    const releases = await knex('sites')
 | 
			
		||||
        .where({ id: siteId })
 | 
			
		||||
        .orWhere({ slug: siteSlug })
 | 
			
		||||
    const sites = await knex('sites')
 | 
			
		||||
        .where({ 'sites.id': siteId })
 | 
			
		||||
        .orWhere({ 'sites.slug': siteSlug })
 | 
			
		||||
        .select(
 | 
			
		||||
            'sites.*',
 | 
			
		||||
            'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url',
 | 
			
		||||
        )
 | 
			
		||||
        .leftJoin('networks', 'sites.network_id', 'networks.id')
 | 
			
		||||
        .limit(100);
 | 
			
		||||
 | 
			
		||||
    return curateSites(releases);
 | 
			
		||||
    return curateSites(sites);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function fetchSitesFromReleases() {
 | 
			
		||||
    const releases = await knex('releases')
 | 
			
		||||
    const sites = await knex('releases')
 | 
			
		||||
        .select('site_id', '')
 | 
			
		||||
        .leftJoin('sites', 'sites.id', 'releases.site_id')
 | 
			
		||||
        .groupBy('sites.id')
 | 
			
		||||
        .limit(100);
 | 
			
		||||
 | 
			
		||||
    return curateSites(releases);
 | 
			
		||||
    return curateSites(sites);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								src/tags.js
								
								
								
								
							
							
						
						
									
										12
									
								
								src/tags.js
								
								
								
								
							| 
						 | 
				
			
			@ -25,4 +25,14 @@ async function matchTags(rawTags) {
 | 
			
		|||
    return tagEntries;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = { matchTags };
 | 
			
		||||
async function storeTags(release, releaseEntry) {
 | 
			
		||||
    return knex('tags_associated').insert(release.tags.map(tagId => ({
 | 
			
		||||
        tag_id: tagId,
 | 
			
		||||
        release_id: releaseEntry.id,
 | 
			
		||||
    })));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    matchTags,
 | 
			
		||||
    storeTags,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ function initServer() {
 | 
			
		|||
    const app = express();
 | 
			
		||||
    const router = Router();
 | 
			
		||||
 | 
			
		||||
    router.use('/media', express.static(config.photoPath));
 | 
			
		||||
    router.use('/media', express.static(config.media.path));
 | 
			
		||||
    router.use(express.static('public'));
 | 
			
		||||
 | 
			
		||||
    router.use('/img', (req, res) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
const { fetchSites, fetchSitesFromReleases } = require('../networks');
 | 
			
		||||
const { fetchSites, fetchSitesFromReleases } = require('../sites');
 | 
			
		||||
 | 
			
		||||
async function fetchSitesApi(req, res) {
 | 
			
		||||
    const siteId = typeof req.params.siteId === 'number' ? req.params.siteId : null;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue