diff --git a/assets/components/actor/actor.vue b/assets/components/actors/actor.vue similarity index 84% rename from assets/components/actor/actor.vue rename to assets/components/actors/actor.vue index 450f21a7..537b91eb 100644 --- a/assets/components/actor/actor.vue +++ b/assets/components/actors/actor.vue @@ -24,6 +24,7 @@
  • {{ actor.name }}

    @@ -60,7 +61,7 @@ v-if="actor.origin.city" class="city" >{{ actor.origin.city }}{{ actor.origin.city ? `, ${actor.origin.state}` : actor.origin.state }} @@ -71,7 +72,7 @@ {{ actor.origin.country.name }} + >{{ actor.origin.country.alias || actor.origin.country.name }}
  • @@ -98,7 +99,7 @@ {{ actor.residence.country.name }} + >{{ actor.residence.country.alias || actor.residence.country.name }} @@ -180,10 +181,10 @@ Yes -
  • Updated on {{ formatDate(actor.scrapedAt, 'YYYY-MM-DD HH:mm') }}
  • + Updated on {{ formatDate(actor.scrapedAt, 'YYYY-MM-DD HH:mm') }} -
    +

    -

    - - - + - - - -
    +
    @@ -268,6 +244,7 @@ import dayjs from 'dayjs'; import { cmToFeetInches, kgToLbs } from '../../../src/utils/convert'; +import Photos from './photos.vue'; import FilterBar from '../header/filter-bar.vue'; import Releases from '../releases/releases.vue'; @@ -296,7 +273,7 @@ function scrollDescription(event) { } async function mounted() { - [[this.actor]] = await Promise.all([ + [this.actor] = await Promise.all([ this.$store.dispatch('fetchActors', this.$route.params.actorSlug), this.fetchReleases(), ]); @@ -309,6 +286,7 @@ async function mounted() { export default { components: { FilterBar, + Photos, Releases, }, data() { @@ -358,7 +336,7 @@ export default { } .avatar { - height: 12rem; + height: 15rem; width: 12rem; flex-shrink: 0; margin: 0 1rem 0 0; @@ -385,24 +363,28 @@ export default { .bio-item { display: flex; justify-content: space-between; - margin: 0 0 .5rem 0; + padding: 0 0 .25rem 0; + margin: 0 0 .25rem 0; line-height: 1.75; text-align: right; font-size: .9rem; + font-weight: 600; + + &:not(:last-of-type) { + border-bottom: solid 1px $highlight-hint; + } } .bio-label { color: $highlight; - display: flex; - align-items: center; margin: 0 1rem 0 0; flex-shrink: 0; font-style: normal; - font-weight: bold; + font-weight: 400; .icon { fill: $highlight; - margin: 0 .5rem .5rem 0; + margin: 0 .5rem 0 0; } } @@ -469,9 +451,18 @@ export default { padding: 0 .5rem; } -.description { - max-height: 10rem; +.scraped { + color: $highlight-weak; + margin: 1rem 0 0 0; + font-size: .8rem; +} + +.extra { flex-grow: 1; +} + +.description { + max-height: 12rem; position: relative; display: block; box-sizing: border-box; @@ -480,7 +471,6 @@ export default { line-height: 1.5; text-overflow: ellipsis; font-size: .9rem; - cursor: pointer; overflow: auto; scrollbar-width: none; @@ -509,12 +499,6 @@ export default { } } -.scraped { - color: $highlight-weak; - margin: 1rem 0 0 0; - font-size: .8rem; -} - .actor-content { display: flex; flex-grow: 1; @@ -534,27 +518,8 @@ export default { margin: 0 .5rem 0 0; } -.photos { - display: inline-grid; - grid-template-columns: repeat(auto-fit, 15rem); - grid-gap: .5rem; - font-size: 0; - - .avatar-link { - display: none; - } -} - -.photo-link { - height: 15rem; -} - -.photo { - width: 100%; - height: 100%; - object-fit: cover; - object-position: 50% 0; - box-shadow: 0 0 3px $shadow-weak; +.photos.compact { + display: none; } .releases { @@ -568,15 +533,9 @@ export default { } } -@media(min-width: $breakpoint3) { - .photos.wide { - max-width: 35vw; - } -} - @media(max-width: $breakpoint3) { .profile .avatar-link, - .social { + .extra { display: none; } @@ -592,25 +551,11 @@ export default { } .photos { - width: 100%; - max-width: 100%; - display: flex; - overflow-x: scroll; - scrollbar-width: none; - - .avatar-link { - display: inline-block; - } - - &::-webkit-scrollbar { - display: none; - } + display: none; } - .photo-link { - height: 15rem; - flex-shrink: 0; - margin: 0 .5rem 0 0; + .photos.compact { + display: flex; } } diff --git a/assets/components/actors/actors.vue b/assets/components/actors/actors.vue new file mode 100644 index 00000000..31d19a81 --- /dev/null +++ b/assets/components/actors/actors.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/assets/components/actors/photos.vue b/assets/components/actors/photos.vue new file mode 100644 index 00000000..59001590 --- /dev/null +++ b/assets/components/actors/photos.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/assets/components/header/header.vue b/assets/components/header/header.vue index 43737849..fcaa3b4a 100644 --- a/assets/components/header/header.vue +++ b/assets/components/header/header.vue @@ -1,11 +1,40 @@ @@ -13,19 +42,41 @@ @import 'theme'; .header { + display: flex; + align-items: center; background: $background; color: $primary; - padding: .5rem 1rem; border-bottom: solid 1px $shadow-hint; + font-size: 0; } .logo-link { color: inherit; + display: inline-block; text-decoration: none; } .logo { display: inline-block; - margin: 0; + padding: .5rem 1rem; + margin: 0 1rem 0 0; + font-size: 2rem; +} + +.nav { + display: inline-block; +} + +.nav-link { + display: inline-block; + color: $shadow; + padding: 1rem; + text-decoration: none; + font-size: 1rem; + font-weight: bold; + + &:hover { + color: $primary; + } } diff --git a/assets/components/network/network.vue b/assets/components/networks/network.vue similarity index 100% rename from assets/components/network/network.vue rename to assets/components/networks/network.vue diff --git a/assets/components/networks/networks.vue b/assets/components/networks/networks.vue new file mode 100644 index 00000000..2dc7eaa4 --- /dev/null +++ b/assets/components/networks/networks.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/assets/components/tile/actor.vue b/assets/components/tile/actor.vue index f997d2a6..676184d3 100644 --- a/assets/components/tile/actor.vue +++ b/assets/components/tile/actor.vue @@ -7,11 +7,14 @@ :href="`/actor/${actor.slug}`" class="link" > - {{ actor.name }} + {{ actor.name }} @@ -38,6 +41,7 @@ export default { @import 'theme'; .actor { + width: 10rem; background: $background; display: inline-block; margin: 0 .5rem .5rem 0; @@ -57,6 +61,9 @@ export default { .name { display: block; padding: .5rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; font-weight: bold; } @@ -64,10 +71,11 @@ export default { color: $shadow-weak; background: $shadow-hint; height: 12rem; - width: 10rem; + width: 100%; display: flex; align-items: center; justify-content: center; object-fit: cover; + object-position: 50% 0; } diff --git a/assets/components/tile/network.vue b/assets/components/tile/network.vue new file mode 100644 index 00000000..f9bbd31e --- /dev/null +++ b/assets/components/tile/network.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/assets/components/tile/site.vue b/assets/components/tile/site.vue index 3436a4aa..7039d642 100644 --- a/assets/components/tile/site.vue +++ b/assets/components/tile/site.vue @@ -53,6 +53,7 @@ export default { object-fit: contain; font-size: 1rem; font-weight: bold; + filter: drop-shadow(0 0 1px $shadow); } .title { diff --git a/assets/css/_theme.scss b/assets/css/_theme.scss index 2624dcae..83ab8070 100644 --- a/assets/css/_theme.scss +++ b/assets/css/_theme.scss @@ -17,9 +17,10 @@ $shadow-weak: rgba(0, 0, 0, .2); $shadow-hint: rgba(0, 0, 0, .1); $highlight: rgba(255, 255, 255, .5); -$highlight-weak: rgba(255, 255, 255, .2); $highlight-extreme: rgba(255, 255, 255, .9); $highlight-strong: rgba(255, 255, 255, .7); +$highlight-weak: rgba(255, 255, 255, .2); +$highlight-hint: rgba(255, 255, 255, .075); $profile: #222; diff --git a/assets/img/fancentro.svg b/assets/img/fancentro.svg new file mode 100644 index 00000000..62728f50 --- /dev/null +++ b/assets/img/fancentro.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/assets/js/router.js b/assets/js/router.js index 4de30722..65f9b038 100644 --- a/assets/js/router.js +++ b/assets/js/router.js @@ -4,8 +4,10 @@ import VueRouter from 'vue-router'; import Home from '../components/home/home.vue'; import Release from '../components/release/release.vue'; import Site from '../components/site/site.vue'; -import Network from '../components/network/network.vue'; -import Actor from '../components/actor/actor.vue'; +import Network from '../components/networks/network.vue'; +import Networks from '../components/networks/networks.vue'; +import Actor from '../components/actors/actor.vue'; +import Actors from '../components/actors/actors.vue'; import Tag from '../components/tag/tag.vue'; import NotFound from '../components/errors/404.vue'; @@ -47,6 +49,16 @@ const routes = [ component: Tag, name: 'tag', }, + { + path: '/actors', + component: Actors, + name: 'actors', + }, + { + path: '/networks', + component: Networks, + name: 'networks', + }, { path: '*', component: NotFound, diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js index dad14f33..74dc1aa9 100644 --- a/migrations/20190325001339_releases.js +++ b/migrations/20190325001339_releases.js @@ -4,10 +4,18 @@ exports.up = knex => Promise.resolve() .unique() .primary(); + table.string('alpha3', 3) + .unique(); + table.string('name') .notNullable(); + table.string('alias'); + table.integer('code', 3); + table.string('nationality'); + table.integer('priority', 2) + .defaultTo(0); })) .then(() => knex.schema.createTable('actors', (table) => { table.increments('id', 12); diff --git a/public/css/style.css b/public/css/style.css index 962887af..0671035f 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -254,6 +254,7 @@ /* $primary: #ff886c; */ .actor[data-v-6989dc6f] { + width: 10rem; background: #fff; display: inline-block; margin: 0 .5rem .5rem 0; @@ -270,18 +271,23 @@ .name[data-v-6989dc6f] { display: block; padding: .5rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; font-weight: bold; } .avatar[data-v-6989dc6f] { color: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.1); height: 12rem; - width: 10rem; + width: 100%; display: flex; align-items: center; justify-content: center; -o-object-fit: cover; object-fit: cover; + -o-object-position: 50% 0; + object-position: 50% 0; } /* $primary: #ff886c; */ @@ -535,6 +541,8 @@ object-fit: contain; font-size: 1rem; font-weight: bold; + -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5)); + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5)); } .title[data-v-f4958086] { color: #222; @@ -545,51 +553,142 @@ } /* $primary: #ff886c; */ -.header[data-v-757c14c2] { +.header[data-v-e2e12602] { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: top; margin: 0 0 2rem 0; } -.title[data-v-757c14c2] { +.title[data-v-e2e12602] { display: inline-flex; align-items: top; margin: 0 1rem 0 0; } -.title:hover .icon[data-v-757c14c2] { +.title:hover .icon[data-v-e2e12602] { fill: #ff6c88; } -.logo[data-v-757c14c2] { +.logo[data-v-e2e12602] { width: 20rem; max-height: 8rem; -o-object-fit: contain; object-fit: contain; margin: 0 .5rem 0 0; } -.sites[data-v-757c14c2] { +.sites[data-v-e2e12602] { display: grid; grid-gap: 1rem; margin: 0 0 2rem 0; } -.sites[data-v-757c14c2] { +.sites[data-v-e2e12602] { grid-template-columns: repeat(auto-fit, 15rem); } @media (max-width: 720px) { -.sites[data-v-757c14c2] { +.sites[data-v-e2e12602] { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); } } /* $primary: #ff886c; */ -.actor-inner[data-v-677a8360] { +.tile[data-v-8b4c90b0] { + background: #fff; + display: flex; + flex-direction: column; + align-items: center; + box-sizing: border-box; + padding: .5rem 1rem; + border-radius: .25rem; + box-shadow: 0 0 3px rgba(0, 0, 0, 0.25); + height: 100%; + text-align: center; +} +.link[data-v-8b4c90b0] { + text-decoration: none; +} +.logo[data-v-8b4c90b0] { + width: 100%; + height: 5rem; + color: #222; + display: flex; + align-items: center; + justify-content: center; + -o-object-fit: contain; + object-fit: contain; + font-size: 1rem; + font-weight: bold; + -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5)); + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5)); +} +.title[data-v-8b4c90b0] { + color: #222; + height: 100%; + display: flex; + align-items: center; + margin: 0; +} + +.networks[data-v-4709d404] { + display: grid; + grid-template-columns: repeat(auto-fit, 15rem); + grid-gap: 1rem; + padding: 1rem; +} + +/* $primary: #ff886c; */ +.photos[data-v-0a0430c7] { + display: inline-grid; + grid-template-columns: repeat(auto-fit, 12rem); + grid-gap: .5rem; + font-size: 0; +} +.photos .avatar-link[data-v-0a0430c7] { + display: none; +} +.photo-link[data-v-0a0430c7] { + height: 15rem; +} +.photo[data-v-0a0430c7] { + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + box-shadow: 0 0 3px rgba(0, 0, 0, 0.2); +} +@media (min-width: 1200px) { +.photos.wide[data-v-0a0430c7] { + max-width: 30vw; +} +} +@media (max-width: 1200px) { +.photos[data-v-0a0430c7] { + width: 100%; + max-width: 100%; + display: flex; + overflow-x: scroll; + scrollbar-width: none; +} +.photos .avatar-link[data-v-0a0430c7] { + display: inline-block; +} +.photos[data-v-0a0430c7]::-webkit-scrollbar { + display: none; +} +.photo-link[data-v-0a0430c7] { + height: 15rem; + flex-shrink: 0; + margin: 0 .5rem 0 0; +} +} + +/* $primary: #ff886c; */ +.actor-inner[data-v-ea0483c2] { height: 100%; display: flex; flex-direction: column; padding: 0; overflow-x: auto; } -.profile[data-v-677a8360] { +.profile[data-v-ea0483c2] { background: #222; color: rgba(255, 255, 255, 0.9); width: 100%; @@ -597,12 +696,12 @@ flex-direction: row; flex-shrink: 0; } -.profile .avatar-link[data-v-677a8360] { +.profile .avatar-link[data-v-ea0483c2] { font-size: 0; padding: 1rem 0 1rem 1rem; } -.profile .avatar[data-v-677a8360] { - height: 12rem; +.profile .avatar[data-v-ea0483c2] { + height: 15rem; width: 12rem; flex-shrink: 0; margin: 0 1rem 0 0; @@ -611,94 +710,104 @@ -o-object-position: 50% 0; object-position: 50% 0; } -.bio[data-v-677a8360] { +.bio[data-v-ea0483c2] { flex-grow: 1; min-width: 20rem; box-sizing: border-box; padding: 1rem; margin: 0 2rem 0 0; } -.bio-header[data-v-677a8360] { +.bio-header[data-v-ea0483c2] { display: flex; justify-content: space-between; align-items: center; margin: 0 0 1rem 0; } -.bio-item[data-v-677a8360] { +.bio-item[data-v-ea0483c2] { display: flex; justify-content: space-between; - margin: 0 0 .5rem 0; + padding: 0 0 .25rem 0; + margin: 0 0 .25rem 0; line-height: 1.75; text-align: right; font-size: .9rem; + font-weight: 600; } -.bio-label[data-v-677a8360] { +.bio-item[data-v-ea0483c2]:not(:last-of-type) { + border-bottom: solid 1px rgba(255, 255, 255, 0.075); +} +.bio-label[data-v-ea0483c2] { color: rgba(255, 255, 255, 0.5); - display: flex; - align-items: center; margin: 0 1rem 0 0; flex-shrink: 0; font-style: normal; - font-weight: bold; + font-weight: 400; } -.bio-label .icon[data-v-677a8360] { +.bio-label .icon[data-v-ea0483c2] { fill: rgba(255, 255, 255, 0.5); - margin: 0 .5rem .5rem 0; + margin: 0 .5rem 0 0; } -.bio-value[data-v-677a8360] { +.bio-value[data-v-ea0483c2] { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } -.flag[data-v-677a8360] { +.flag[data-v-ea0483c2] { margin: 0 .25rem 0 0; } -.bio-name[data-v-677a8360] { +.bio-name[data-v-ea0483c2] { display: inline-block; padding: 0; margin: 0; } -.bio-gender[data-v-677a8360] { +.bio-gender[data-v-ea0483c2] { display: inline-block; font-weight: bold; text-transform: capitalize; font-weight: normal; } -.bio-gender .icon[data-v-677a8360] { +.bio-gender .icon[data-v-ea0483c2] { width: 1.25rem; height: 1.25rem; } -.bio-gender.female .icon[data-v-677a8360] { +.bio-gender.female .icon[data-v-ea0483c2] { fill: #f0a; } -.bio-gender.male .icon[data-v-677a8360] { +.bio-gender.male .icon[data-v-ea0483c2] { fill: #0af; } -.birthdate[data-v-677a8360] { +.birthdate[data-v-ea0483c2] { display: block; } -.age[data-v-677a8360] { +.age[data-v-ea0483c2] { font-weight: bold; padding: 0 0 0 .5rem; border-left: solid 1px rgba(255, 255, 255, 0.2); margin: 0 0 0 .5rem; } -.country[data-v-677a8360] { +.country[data-v-ea0483c2] { display: block; } -.height-imperial[data-v-677a8360], -.weight-imperial[data-v-677a8360] { +.height-imperial[data-v-ea0483c2], +.weight-imperial[data-v-ea0483c2] { padding: 0 0 0 .5rem; border-left: solid 1px rgba(255, 255, 255, 0.2); margin: 0 0 0 .5rem; } -.enhanced.icon[data-v-677a8360] { +.enhanced.icon[data-v-ea0483c2] { fill: #ff6c88; padding: 0 .5rem; } -.description[data-v-677a8360] { - max-height: 10rem; +.scraped[data-v-ea0483c2] { + color: rgba(255, 255, 255, 0.2); + margin: 1rem 0 0 0; + font-size: .8rem; +} +.extra[data-v-ea0483c2] { flex-grow: 1; +} +.description[data-v-ea0483c2] { + max-height: 12rem; position: relative; display: block; box-sizing: border-box; @@ -707,146 +816,112 @@ line-height: 1.5; text-overflow: ellipsis; font-size: .9rem; - cursor: pointer; overflow: auto; scrollbar-width: none; } -.description[data-v-677a8360]::-webkit-scrollbar { +.description[data-v-ea0483c2]::-webkit-scrollbar { display: none; } -.social[data-v-677a8360] { +.social[data-v-ea0483c2] { display: block; margin: 1rem 0; } -.social-link[data-v-677a8360] { +.social-link[data-v-ea0483c2] { display: inline-block; padding: 0 1rem 0 0; } -.social-link .icon[data-v-677a8360] { +.social-link .icon[data-v-ea0483c2] { fill: rgba(255, 255, 255, 0.5); width: 1.5rem; height: 1.5rem; } -.social-link:hover .icon[data-v-677a8360] { +.social-link:hover .icon[data-v-ea0483c2] { fill: #ff6c88; } -.scraped[data-v-677a8360] { - color: rgba(255, 255, 255, 0.2); - margin: 1rem 0 0 0; - font-size: .8rem; -} -.actor-content[data-v-677a8360] { +.actor-content[data-v-ea0483c2] { display: flex; flex-grow: 1; flex-direction: row; } -.heading[data-v-677a8360] { +.heading[data-v-ea0483c2] { padding: 0; margin: 0 0 1rem 0; } -.photos-container[data-v-677a8360] { +.photos-container[data-v-ea0483c2] { min-width: 15rem; box-sizing: border-box; border-right: solid 1px rgba(0, 0, 0, 0.1); padding: 1rem 1.5rem 1rem 1rem; margin: 0 .5rem 0 0; } -.photos[data-v-677a8360] { - display: inline-grid; - grid-template-columns: repeat(auto-fit, 15rem); - grid-gap: .5rem; - font-size: 0; +.photos.compact[data-v-ea0483c2] { + display: none; } -.photos .avatar-link[data-v-677a8360] { - display: none; -} -.photo-link[data-v-677a8360] { - height: 15rem; -} -.photo[data-v-677a8360] { - width: 100%; - height: 100%; - -o-object-fit: cover; - object-fit: cover; - -o-object-position: 50% 0; - object-position: 50% 0; - box-shadow: 0 0 3px rgba(0, 0, 0, 0.2); -} -.releases[data-v-677a8360] { +.releases[data-v-ea0483c2] { flex-grow: 1; padding: 1rem; } @media (max-width: 1500px) { -.description[data-v-677a8360] { +.description[data-v-ea0483c2] { display: none; } } -@media (min-width: 1200px) { -.photos.wide[data-v-677a8360] { - max-width: 35vw; -} -} @media (max-width: 1200px) { -.profile .avatar-link[data-v-677a8360], - .social[data-v-677a8360] { +.profile .avatar-link[data-v-ea0483c2], + .extra[data-v-ea0483c2] { display: none; } -.actor-content[data-v-677a8360] { +.actor-content[data-v-ea0483c2] { flex-direction: column; } -.photos-container[data-v-677a8360] { +.photos-container[data-v-ea0483c2] { border: none; border-bottom: solid 1px rgba(0, 0, 0, 0.1); padding: 1rem 1rem 1.5rem 1rem; margin: 0 0 .5rem 0; } -.photos[data-v-677a8360] { - width: 100%; - max-width: 100%; +.photos[data-v-ea0483c2] { + display: none; +} +.photos.compact[data-v-ea0483c2] { display: flex; - overflow-x: scroll; - scrollbar-width: none; -} -.photos .avatar-link[data-v-677a8360] { - display: inline-block; -} -.photos[data-v-677a8360]::-webkit-scrollbar { - display: none; -} -.photo-link[data-v-677a8360] { - height: 15rem; - flex-shrink: 0; - margin: 0 .5rem 0 0; } } @media (max-width: 720px) { -.profile[data-v-677a8360] { +.profile[data-v-ea0483c2] { flex-direction: column; padding: 0 0 .5rem 0; } -.bio[data-v-677a8360] { +.bio[data-v-ea0483c2] { width: 100%; padding: 0 1rem; margin: 0; } -.bio-header[data-v-677a8360] { +.bio-header[data-v-ea0483c2] { margin: 1rem 0; } -.city[data-v-677a8360], - .state[data-v-677a8360], - .ethnicity[data-v-677a8360], - .residence[data-v-677a8360], - .weight[data-v-677a8360], - .tattoos[data-v-677a8360], - .piercings[data-v-677a8360], - .scraped[data-v-677a8360] { +.city[data-v-ea0483c2], + .state[data-v-ea0483c2], + .ethnicity[data-v-ea0483c2], + .residence[data-v-ea0483c2], + .weight[data-v-ea0483c2], + .tattoos[data-v-ea0483c2], + .piercings[data-v-ea0483c2], + .scraped[data-v-ea0483c2] { display: none; } -.social[data-v-677a8360] { +.social[data-v-ea0483c2] { padding: 0 1rem; } } +.actors[data-v-4f34b238] { + display: grid; + grid-template-columns: repeat(auto-fit, 10rem); + grid-gap: 0 .5rem; + padding: 1rem; +} + /* $primary: #ff886c; */ .header[data-v-80991bcc] { display: flex; @@ -1006,18 +1081,37 @@ body { /* $primary: #ff886c; */ .header[data-v-10b7ec04] { + display: flex; + align-items: center; background: #fff; color: #ff6c88; - padding: .5rem 1rem; border-bottom: solid 1px rgba(0, 0, 0, 0.1); + font-size: 0; } .logo-link[data-v-10b7ec04] { color: inherit; + display: inline-block; text-decoration: none; } .logo[data-v-10b7ec04] { display: inline-block; - margin: 0; + padding: .5rem 1rem; + margin: 0 1rem 0 0; + font-size: 2rem; +} +.nav[data-v-10b7ec04] { + display: inline-block; +} +.nav-link[data-v-10b7ec04] { + display: inline-block; + color: rgba(0, 0, 0, 0.5); + padding: 1rem; + text-decoration: none; + font-size: 1rem; + font-weight: bold; +} +.nav-link[data-v-10b7ec04]:hover { + color: #ff6c88; } /* $primary: #ff886c; */ diff --git a/public/img/logos/21sextury/network.png b/public/img/logos/21sextury/network.png new file mode 100644 index 00000000..0923f419 Binary files /dev/null and b/public/img/logos/21sextury/network.png differ diff --git a/public/img/logos/bangbros/network.png b/public/img/logos/bangbros/network.png new file mode 100644 index 00000000..81364bac Binary files /dev/null and b/public/img/logos/bangbros/network.png differ diff --git a/public/img/logos/blowpass/1000facials.png b/public/img/logos/blowpass/1000facials.png new file mode 100644 index 00000000..6bd0bb9e Binary files /dev/null and b/public/img/logos/blowpass/1000facials.png differ diff --git a/public/img/logos/blowpass/immorallive.png b/public/img/logos/blowpass/immorallive.png new file mode 100644 index 00000000..0ad21edb Binary files /dev/null and b/public/img/logos/blowpass/immorallive.png differ diff --git a/public/img/logos/blowpass/mommyblowsbest.png b/public/img/logos/blowpass/mommyblowsbest.png new file mode 100644 index 00000000..041429e3 Binary files /dev/null and b/public/img/logos/blowpass/mommyblowsbest.png differ diff --git a/public/img/logos/blowpass/network.png b/public/img/logos/blowpass/network.png new file mode 100644 index 00000000..5f73e98d Binary files /dev/null and b/public/img/logos/blowpass/network.png differ diff --git a/public/img/logos/blowpass/onlyteenblowjobs.png b/public/img/logos/blowpass/onlyteenblowjobs.png new file mode 100644 index 00000000..7dece06a Binary files /dev/null and b/public/img/logos/blowpass/onlyteenblowjobs.png differ diff --git a/public/img/logos/blowpass/throated.png b/public/img/logos/blowpass/throated.png new file mode 100644 index 00000000..42bff523 Binary files /dev/null and b/public/img/logos/blowpass/throated.png differ diff --git a/public/img/logos/brazzers/network.png b/public/img/logos/brazzers/network.png index f93e4cdc..9ab9c5a9 100644 Binary files a/public/img/logos/brazzers/network.png and b/public/img/logos/brazzers/network.png differ diff --git a/public/img/logos/ddfnetwork/network.png b/public/img/logos/ddfnetwork/network.png new file mode 100644 index 00000000..66ce40e7 Binary files /dev/null and b/public/img/logos/ddfnetwork/network.png differ diff --git a/public/img/logos/naughtyamerica/network.png b/public/img/logos/naughtyamerica/network.png new file mode 100644 index 00000000..1bada75c Binary files /dev/null and b/public/img/logos/naughtyamerica/network.png differ diff --git a/public/img/logos/pervcity/network.png b/public/img/logos/pervcity/network.png new file mode 100644 index 00000000..e6907c83 Binary files /dev/null and b/public/img/logos/pervcity/network.png differ diff --git a/public/img/logos/pornpros/network.png b/public/img/logos/pornpros/network.png new file mode 100644 index 00000000..7a5b54db Binary files /dev/null and b/public/img/logos/pornpros/network.png differ diff --git a/public/img/logos/vixen/blacked.png b/public/img/logos/vixen/blacked.png index 4f84bb96..949858e9 100644 Binary files a/public/img/logos/vixen/blacked.png and b/public/img/logos/vixen/blacked.png differ diff --git a/public/img/logos/vixen/blackedraw.png b/public/img/logos/vixen/blackedraw.png index 5ab327a5..5f3a152e 100644 Binary files a/public/img/logos/vixen/blackedraw.png and b/public/img/logos/vixen/blackedraw.png differ diff --git a/public/img/logos/vixen/deeper.png b/public/img/logos/vixen/deeper.png index 267505bd..d5aaba1e 100644 Binary files a/public/img/logos/vixen/deeper.png and b/public/img/logos/vixen/deeper.png differ diff --git a/public/img/logos/vixen/network.png b/public/img/logos/vixen/network.png index f420297e..b5e83fb3 100644 Binary files a/public/img/logos/vixen/network.png and b/public/img/logos/vixen/network.png differ diff --git a/public/img/logos/vixen/tushy.png b/public/img/logos/vixen/tushy.png index 58a8364c..bd93af0f 100644 Binary files a/public/img/logos/vixen/tushy.png and b/public/img/logos/vixen/tushy.png differ diff --git a/public/img/logos/vixen/tushyraw.png b/public/img/logos/vixen/tushyraw.png index 1f36c707..6c99067e 100644 Binary files a/public/img/logos/vixen/tushyraw.png and b/public/img/logos/vixen/tushyraw.png differ diff --git a/public/img/logos/vixen/vixen.png b/public/img/logos/vixen/vixen.png index 77483b26..907ebf2b 100644 Binary files a/public/img/logos/vixen/vixen.png and b/public/img/logos/vixen/vixen.png differ diff --git a/seeds/04_countries.js b/seeds/04_countries.js index 8d0298a1..02a6dc13 100644 --- a/seeds/04_countries.js +++ b/seeds/04_countries.js @@ -3,1248 +3,1754 @@ const upsert = require('../src/utils/upsert'); const countries = [ { name: 'Afghanistan', - code: '004', + code: 4, alpha2: 'AF', + alpha3: 'AFG', + nationality: 'Afghan', }, { name: 'Åland Islands', - code: '248', + code: 248, alpha2: 'AX', + alpha3: 'ALA', + nationality: 'Åland Island', }, { name: 'Albania', - code: '008', + code: 8, alpha2: 'AL', + alpha3: 'ALB', + nationality: 'Albanian', }, { name: 'Algeria', - code: '012', + code: 12, alpha2: 'DZ', + alpha3: 'DZA', + nationality: 'Algerian', }, { name: 'American Samoa', - code: '016', + code: 16, alpha2: 'AS', + alpha3: 'ASM', + nationality: 'American Samoan', + priority: 0, }, { name: 'Andorra', - code: '020', + code: 20, alpha2: 'AD', + alpha3: 'AND', + nationality: 'Andorran', }, { name: 'Angola', - code: '024', + code: 24, alpha2: 'AO', + alpha3: 'AGO', + nationality: 'Angolan', }, { name: 'Anguilla', - code: '660', + code: 660, alpha2: 'AI', + alpha3: 'AIA', + nationality: 'Anguillan', }, { name: 'Antarctica', - code: '010', + code: 10, alpha2: 'AQ', + alpha3: 'ATA', + nationality: 'Antarctic', }, { name: 'Antigua and Barbuda', - code: '028', + code: 28, alpha2: 'AG', + alpha3: 'ATG', + nationality: 'Antiguan or Barbudan', }, { name: 'Argentina', - code: '032', + code: 32, alpha2: 'AR', + alpha3: 'ARG', + nationality: 'Argentine', }, { name: 'Armenia', - code: '051', + code: 51, alpha2: 'AM', + alpha3: 'ARM', + nationality: 'Armenian', }, { name: 'Aruba', - code: '533', + code: 533, alpha2: 'AW', + alpha3: 'ABW', + nationality: 'Aruban', }, { name: 'Australia', - code: '036', + code: 36, alpha2: 'AU', + alpha3: 'AUS', + nationality: 'Australian', }, { name: 'Austria', - code: '040', + code: 40, alpha2: 'AT', + alpha3: 'AUT', + nationality: 'Austrian', }, { name: 'Azerbaijan', - code: '031', + code: 31, alpha2: 'AZ', + alpha3: 'AZE', + nationality: 'Azerbaijani, Azeri', }, { name: 'Bahamas', - code: '044', + code: 44, alpha2: 'BS', + alpha3: 'BHS', + nationality: 'Bahamian', }, { name: 'Bahrain', - code: '048', + code: 48, alpha2: 'BH', + alpha3: 'BHR', + nationality: 'Bahraini', }, { name: 'Bangladesh', - code: '050', + code: 50, alpha2: 'BD', + alpha3: 'BGD', + nationality: 'Bangladeshi', }, { name: 'Barbados', - code: '052', + code: 52, alpha2: 'BB', + alpha3: 'BRB', + nationality: 'Barbadian', }, { name: 'Belarus', - code: '112', + code: 112, alpha2: 'BY', + alpha3: 'BLR', + nationality: 'Belarusian', }, { name: 'Belgium', - code: '056', + code: 56, alpha2: 'BE', + alpha3: 'BEL', + nationality: 'Belgian', }, { name: 'Belize', - code: '084', + code: 84, alpha2: 'BZ', + alpha3: 'BLZ', + nationality: 'Belizean', }, { name: 'Benin', - code: '204', + code: 204, alpha2: 'BJ', + alpha3: 'BEN', + nationality: 'Beninese, Beninois', }, { name: 'Bermuda', - code: '060', + code: 60, alpha2: 'BM', + alpha3: 'BMU', + nationality: 'Bermudian, Bermudan', }, { name: 'Bhutan', - code: '064', + code: 64, alpha2: 'BT', + alpha3: 'BTN', + nationality: 'Bhutanese', }, { - name: 'Bolivia', - code: '068', + name: 'Bolivia (Plurinational State of)', + code: 68, alpha2: 'BO', + alpha3: 'BOL', + nationality: 'Bolivian', }, { name: 'Bonaire, Sint Eustatius and Saba', - code: '535', + code: 535, alpha2: 'BQ', + alpha3: 'BES', + nationality: 'Bonaire', }, { name: 'Bosnia and Herzegovina', - code: '070', + code: 70, alpha2: 'BA', + alpha3: 'BIH', + nationality: 'Bosnian or Herzegovinian', }, { name: 'Botswana', - code: '072', + code: 72, alpha2: 'BW', + alpha3: 'BWA', + nationality: 'Motswana, Botswanan', }, { name: 'Bouvet Island', - code: '074', + code: 74, alpha2: 'BV', + alpha3: 'BVT', + nationality: 'Bouvet Islander', }, { name: 'Brazil', - code: '076', + code: 76, alpha2: 'BR', + alpha3: 'BRA', + nationality: 'Brazilian', }, { name: 'British Indian Ocean Territory', - code: '086', + code: 86, alpha2: 'IO', + alpha3: 'IOT', + nationality: 'BIOT', }, { name: 'Brunei Darussalam', - code: '096', + code: 96, alpha2: 'BN', + alpha3: 'BRN', + nationality: 'Bruneian', }, { name: 'Bulgaria', - code: '100', + code: 100, alpha2: 'BG', + alpha3: 'BGR', + nationality: 'Bulgarian', }, { name: 'Burkina Faso', - code: '854', + code: 854, alpha2: 'BF', + alpha3: 'BFA', + nationality: 'Burkinabé', }, { name: 'Burundi', - code: '108', + code: 108, alpha2: 'BI', + alpha3: 'BDI', + nationality: 'Burundian', }, { name: 'Cabo Verde', - code: '132', + code: 132, alpha2: 'CV', + alpha3: 'CPV', + nationality: 'Cabo Verdean', }, { name: 'Cambodia', - code: '116', + code: 116, alpha2: 'KH', + alpha3: 'KHM', + nationality: 'Cambodian', }, { name: 'Cameroon', - code: '120', + code: 120, alpha2: 'CM', + alpha3: 'CMR', + nationality: 'Cameroonian', }, { name: 'Canada', - code: '124', + code: 124, alpha2: 'CA', + alpha3: 'CAN', + nationality: 'Canadian', }, { name: 'Cayman Islands', - code: '136', + code: 136, alpha2: 'KY', + alpha3: 'CYM', + nationality: 'Caymanian', }, { name: 'Central African Republic', - code: '140', + code: 140, alpha2: 'CF', + alpha3: 'CAF', + nationality: 'Central African', }, { name: 'Chad', - code: '148', + code: 148, alpha2: 'TD', + alpha3: 'TCD', + nationality: 'Chadian', }, { name: 'Chile', - code: '152', + code: 152, alpha2: 'CL', + alpha3: 'CHL', + nationality: 'Chilean', }, { name: 'China', - code: '156', + code: 156, alpha2: 'CN', + alpha3: 'CHN', + nationality: 'Chinese', + priority: 1, }, { name: 'Christmas Island', - code: '162', + code: 162, alpha2: 'CX', + alpha3: 'CXR', + nationality: 'Christmas Islander', }, { name: 'Cocos (Keeling) Islands', - code: '166', + code: 166, alpha2: 'CC', + alpha3: 'CCK', + nationality: 'Cocos Islander, Cocos Malays', }, { name: 'Colombia', - code: '170', + code: 170, alpha2: 'CO', + alpha3: 'COL', + nationality: 'Colombian', }, { name: 'Comoros', - code: '174', + code: 174, alpha2: 'KM', + alpha3: 'COM', + nationality: 'Comoran, Comorian', }, { - name: 'Congo', - code: '178', + name: 'Congo (Republic of the)', + code: 178, alpha2: 'CG', + alpha3: 'COG', + nationality: 'Congolese', }, { - name: 'Congo', - code: '180', + name: 'Congo (Democratic Republic of the)', + code: 180, alpha2: 'CD', + alpha3: 'COD', + nationality: 'Congolese', }, { name: 'Cook Islands', - code: '184', + code: 184, alpha2: 'CK', + alpha3: 'COK', + nationality: 'Cook Islander', }, { name: 'Costa Rica', - code: '188', + code: 188, alpha2: 'CR', + alpha3: 'CRI', + nationality: 'Costa Rican', }, { - name: 'Côte d\'Ivoire', - code: '384', + name: "Côte d'Ivoire", + code: 384, alpha2: 'CI', + alpha3: 'CIV', + nationality: 'Ivorian', }, { name: 'Croatia', - code: '191', + code: 191, alpha2: 'HR', + alpha3: 'HRV', + nationality: 'Croatian', }, { name: 'Cuba', - code: '192', + code: 192, alpha2: 'CU', + alpha3: 'CUB', + nationality: 'Cuban', }, { name: 'Curaçao', - code: '531', + code: 531, alpha2: 'CW', + alpha3: 'CUW', + nationality: 'Curaçaoan', }, { name: 'Cyprus', - code: '196', + code: 196, alpha2: 'CY', + alpha3: 'CYP', + nationality: 'Cypriot', }, { - name: 'Czechia', - code: '203', + name: 'Czech Republic', + code: 203, alpha2: 'CZ', + alpha3: 'CZE', + nationality: 'Czech', }, { name: 'Denmark', - code: '208', + code: 208, alpha2: 'DK', + alpha3: 'DNK', + nationality: 'Danish', }, { name: 'Djibouti', - code: '262', + code: 262, alpha2: 'DJ', + alpha3: 'DJI', + nationality: 'Djiboutian', }, { name: 'Dominica', - code: '212', + code: 212, alpha2: 'DM', + alpha3: 'DMA', + nationality: 'Dominican', }, { name: 'Dominican Republic', - code: '214', + code: 214, alpha2: 'DO', + alpha3: 'DOM', + nationality: 'Dominican', }, { name: 'Ecuador', - code: '218', + code: 218, alpha2: 'EC', + alpha3: 'ECU', + nationality: 'Ecuadorian', }, { name: 'Egypt', - code: '818', + code: 818, alpha2: 'EG', + alpha3: 'EGY', + nationality: 'Egyptian', }, { name: 'El Salvador', - code: '222', + code: 222, alpha2: 'SV', + alpha3: 'SLV', + nationality: 'Salvadoran', }, { name: 'Equatorial Guinea', - code: '226', + code: 226, alpha2: 'GQ', + alpha3: 'GNQ', + nationality: 'Equatorial Guinean, Equatoguinean', }, { name: 'Eritrea', - code: '232', + code: 232, alpha2: 'ER', + alpha3: 'ERI', + nationality: 'Eritrean', }, { name: 'Estonia', - code: '233', + code: 233, alpha2: 'EE', + alpha3: 'EST', + nationality: 'Estonian', }, { name: 'Ethiopia', - code: '231', + code: 231, alpha2: 'ET', + alpha3: 'ETH', + nationality: 'Ethiopian', }, { - name: 'Falkland Islands', - code: '238', + name: 'Falkland Islands (Malvinas)', + code: 238, alpha2: 'FK', + alpha3: 'FLK', + nationality: 'Falkland Islander', }, { name: 'Faroe Islands', - code: '234', + code: 234, alpha2: 'FO', + alpha3: 'FRO', + nationality: 'Faroese', }, { name: 'Fiji', - code: '242', + code: 242, alpha2: 'FJ', + alpha3: 'FJI', + nationality: 'Fijian', }, { name: 'Finland', - code: '246', + code: 246, alpha2: 'FI', + alpha3: 'FIN', + nationality: 'Finnish', }, { name: 'France', - code: '250', + code: 250, alpha2: 'FR', + alpha3: 'FRA', + nationality: 'French', }, { name: 'French Guiana', - code: '254', + code: 254, alpha2: 'GF', + alpha3: 'GUF', + nationality: 'French Guianese', }, { name: 'French Polynesia', - code: '258', + code: 258, alpha2: 'PF', + alpha3: 'PYF', + nationality: 'French Polynesian', }, { name: 'French Southern Territories', - code: '260', + code: 260, alpha2: 'TF', + alpha3: 'ATF', + nationality: 'French Southern Territories', }, { name: 'Gabon', - code: '266', + code: 266, alpha2: 'GA', + alpha3: 'GAB', + nationality: 'Gabonese', }, { name: 'Gambia', - code: '270', + code: 270, alpha2: 'GM', + alpha3: 'GMB', + nationality: 'Gambian', }, { name: 'Georgia', - code: '268', + code: 268, alpha2: 'GE', + alpha3: 'GEO', + nationality: 'Georgian', }, { name: 'Germany', - code: '276', + code: 276, alpha2: 'DE', + alpha3: 'DEU', + nationality: 'German', }, { name: 'Ghana', - code: '288', + code: 288, alpha2: 'GH', + alpha3: 'GHA', + nationality: 'Ghanaian', }, { name: 'Gibraltar', - code: '292', + code: 292, alpha2: 'GI', + alpha3: 'GIB', + nationality: 'Gibraltar', }, { name: 'Greece', - code: '300', + code: 300, alpha2: 'GR', + alpha3: 'GRC', + nationality: 'Greek, Hellenic', }, { name: 'Greenland', - code: '304', + code: 304, alpha2: 'GL', + alpha3: 'GRL', + nationality: 'Greenlandic', }, { name: 'Grenada', - code: '308', + code: 308, alpha2: 'GD', + alpha3: 'GRD', + nationality: 'Grenadian', }, { name: 'Guadeloupe', - code: '312', + code: 312, alpha2: 'GP', + alpha3: 'GLP', + nationality: 'Guadeloupean', }, { name: 'Guam', - code: '316', + code: 316, alpha2: 'GU', + alpha3: 'GUM', + nationality: 'Guamanian, Guambat', }, { name: 'Guatemala', - code: '320', + code: 320, alpha2: 'GT', + alpha3: 'GTM', + nationality: 'Guatemalan', }, { name: 'Guernsey', - code: '831', + code: 831, alpha2: 'GG', + alpha3: 'GGY', + nationality: 'Channel Islander', }, { name: 'Guinea', - code: '324', + code: 324, alpha2: 'GN', + alpha3: 'GIN', + nationality: 'Guinean', }, { name: 'Guinea-Bissau', - code: '624', + code: 624, alpha2: 'GW', + alpha3: 'GNB', + nationality: 'Bissau-Guinean', }, { name: 'Guyana', - code: '328', + code: 328, alpha2: 'GY', + alpha3: 'GUY', + nationality: 'Guyanese', }, { name: 'Haiti', - code: '332', + code: 332, alpha2: 'HT', + alpha3: 'HTI', + nationality: 'Haitian', }, { name: 'Heard Island and McDonald Islands', - code: '334', + code: 334, alpha2: 'HM', + alpha3: 'HMD', + nationality: 'Heard Islander, McDonald Islander', }, { - name: 'Holy See', - code: '336', + name: 'Vatican City State', + code: 336, alpha2: 'VA', + alpha3: 'VAT', + nationality: 'Vatican', }, { name: 'Honduras', - code: '340', + code: 340, alpha2: 'HN', + alpha3: 'HND', + nationality: 'Honduran', }, { name: 'Hong Kong', - code: '344', + code: 344, alpha2: 'HK', + alpha3: 'HKG', + nationality: 'Hongkonger, Hong Konger, Hong Kongese', }, { name: 'Hungary', - code: '348', + code: 348, alpha2: 'HU', + alpha3: 'HUN', + nationality: 'Hungarian, Magyar', }, { name: 'Iceland', - code: '352', + code: 352, alpha2: 'IS', + alpha3: 'ISL', + nationality: 'Icelandic', }, { name: 'India', - code: '356', + code: 356, alpha2: 'IN', + alpha3: 'IND', + nationality: 'Indian', }, { name: 'Indonesia', - code: '360', + code: 360, alpha2: 'ID', + alpha3: 'IDN', + nationality: 'Indonesian', }, { name: 'Iran', - code: '364', + code: 364, alpha2: 'IR', + alpha3: 'IRN', + nationality: 'Iranian, Persian', }, { name: 'Iraq', - code: '368', + code: 368, alpha2: 'IQ', + alpha3: 'IRQ', + nationality: 'Iraqi', }, { name: 'Ireland', - code: '372', + code: 372, alpha2: 'IE', + alpha3: 'IRL', + nationality: 'Irish', }, { name: 'Isle of Man', - code: '833', + code: 833, alpha2: 'IM', + alpha3: 'IMN', + nationality: 'Manx', }, { name: 'Israel', - code: '376', + code: 376, alpha2: 'IL', + alpha3: 'ISR', + nationality: 'Israeli', }, { name: 'Italy', - code: '380', + code: 380, alpha2: 'IT', + alpha3: 'ITA', + nationality: 'Italian', }, { name: 'Jamaica', - code: '388', + code: 388, alpha2: 'JM', + alpha3: 'JAM', + nationality: 'Jamaican', }, { name: 'Japan', - code: '392', + code: 392, alpha2: 'JP', + alpha3: 'JPN', + nationality: 'Japanese', }, { name: 'Jersey', - code: '832', + code: 832, alpha2: 'JE', + alpha3: 'JEY', + nationality: 'Channel Island', }, { name: 'Jordan', - code: '400', + code: 400, alpha2: 'JO', + alpha3: 'JOR', + nationality: 'Jordanian', }, { name: 'Kazakhstan', - code: '398', + code: 398, alpha2: 'KZ', + alpha3: 'KAZ', + nationality: 'Kazakhstani, Kazakh', }, { name: 'Kenya', - code: '404', + code: 404, alpha2: 'KE', + alpha3: 'KEN', + nationality: 'Kenyan', }, { name: 'Kiribati', - code: '296', + code: 296, alpha2: 'KI', + alpha3: 'KIR', + nationality: 'I-Kiribati', }, { - name: 'North Korea', - code: '408', + name: "Korea (Democratic People's Republic of)", + code: 408, alpha2: 'KP', + alpha3: 'PRK', + nationality: 'North Korean', }, { - name: 'South Korea', - code: '410', + name: 'Korea (Republic of)', + code: 410, alpha2: 'KR', + alpha3: 'KOR', + nationality: 'South Korean', }, { name: 'Kuwait', - code: '414', + code: 414, alpha2: 'KW', + alpha3: 'KWT', + nationality: 'Kuwaiti', }, { name: 'Kyrgyzstan', - code: '417', + code: 417, alpha2: 'KG', + alpha3: 'KGZ', + nationality: 'Kyrgyzstani, Kyrgyz, Kirgiz, Kirghiz', }, { - name: 'Laos', - code: '418', + name: "Lao People's Democratic Republic", + code: 418, alpha2: 'LA', + alpha3: 'LAO', + nationality: 'Lao, Laotian', }, { name: 'Latvia', - code: '428', + code: 428, alpha2: 'LV', + alpha3: 'LVA', + nationality: 'Latvian', }, { name: 'Lebanon', - code: '422', + code: 422, alpha2: 'LB', + alpha3: 'LBN', + nationality: 'Lebanese', }, { name: 'Lesotho', - code: '426', + code: 426, alpha2: 'LS', + alpha3: 'LSO', + nationality: 'Basotho', }, { name: 'Liberia', - code: '430', + code: 430, alpha2: 'LR', + alpha3: 'LBR', + nationality: 'Liberian', }, { name: 'Libya', - code: '434', + code: 434, alpha2: 'LY', + alpha3: 'LBY', + nationality: 'Libyan', }, { name: 'Liechtenstein', - code: '438', + code: 438, alpha2: 'LI', + alpha3: 'LIE', + nationality: 'Liechtenstein', }, { name: 'Lithuania', - code: '440', + code: 440, alpha2: 'LT', + alpha3: 'LTU', + nationality: 'Lithuanian', }, { name: 'Luxembourg', - code: '442', + code: 442, alpha2: 'LU', + alpha3: 'LUX', + nationality: 'Luxembourg, Luxembourgish', }, { name: 'Macao', - code: '446', + code: 446, alpha2: 'MO', + alpha3: 'MAC', + nationality: 'Macanese, Chinese', + priority: 0, }, { - name: 'Macedonia', - code: '807', + name: 'Macedonia (the former Yugoslav Republic of)', + code: 807, alpha2: 'MK', + alpha3: 'MKD', + nationality: 'Macedonian', }, { name: 'Madagascar', - code: '450', + code: 450, alpha2: 'MG', + alpha3: 'MDG', + nationality: 'Malagasy', }, { name: 'Malawi', - code: '454', + code: 454, alpha2: 'MW', + alpha3: 'MWI', + nationality: 'Malawian', }, { name: 'Malaysia', - code: '458', + code: 458, alpha2: 'MY', + alpha3: 'MYS', + nationality: 'Malaysian', }, { name: 'Maldives', - code: '462', + code: 462, alpha2: 'MV', + alpha3: 'MDV', + nationality: 'Maldivian', }, { name: 'Mali', - code: '466', + code: 466, alpha2: 'ML', + alpha3: 'MLI', + nationality: 'Malian, Malinese', }, { name: 'Malta', - code: '470', + code: 470, alpha2: 'MT', + alpha3: 'MLT', + nationality: 'Maltese', }, { name: 'Marshall Islands', - code: '584', + code: 584, alpha2: 'MH', + alpha3: 'MHL', + nationality: 'Marshallese', }, { name: 'Martinique', - code: '474', + code: 474, alpha2: 'MQ', + alpha3: 'MTQ', + nationality: 'Martiniquais, Martinican', }, { name: 'Mauritania', - code: '478', + code: 478, alpha2: 'MR', + alpha3: 'MRT', + nationality: 'Mauritanian', }, { name: 'Mauritius', - code: '480', + code: 480, alpha2: 'MU', + alpha3: 'MUS', + nationality: 'Mauritian', }, { name: 'Mayotte', - code: '175', + code: 175, alpha2: 'YT', + alpha3: 'MYT', + nationality: 'Mahoran', }, { name: 'Mexico', - code: '484', + code: 484, alpha2: 'MX', + alpha3: 'MEX', + nationality: 'Mexican', }, { - name: 'Micronesia', - code: '583', + name: 'Micronesia (Federated States of)', + code: 583, alpha2: 'FM', + alpha3: 'FSM', + nationality: 'Micronesian', }, { - name: 'Moldova', - code: '498', + name: 'Moldova (Republic of)', + code: 498, alpha2: 'MD', + alpha3: 'MDA', + nationality: 'Moldovan', }, { name: 'Monaco', - code: '492', + code: 492, alpha2: 'MC', + alpha3: 'MCO', + nationality: 'Monégasque, Monacan', }, { name: 'Mongolia', - code: '496', + code: 496, alpha2: 'MN', + alpha3: 'MNG', + nationality: 'Mongolian', }, { name: 'Montenegro', - code: '499', + code: 499, alpha2: 'ME', + alpha3: 'MNE', + nationality: 'Montenegrin', }, { name: 'Montserrat', - code: '500', + code: 500, alpha2: 'MS', + alpha3: 'MSR', + nationality: 'Montserratian', }, { name: 'Morocco', - code: '504', + code: 504, alpha2: 'MA', + alpha3: 'MAR', + nationality: 'Moroccan', }, { name: 'Mozambique', - code: '508', + code: 508, alpha2: 'MZ', + alpha3: 'MOZ', + nationality: 'Mozambican', }, { name: 'Myanmar', - code: '104', + code: 104, alpha2: 'MM', + alpha3: 'MMR', + nationality: 'Burmese', }, { name: 'Namibia', - code: '516', + code: 516, alpha2: 'NA', + alpha3: 'NAM', + nationality: 'Namibian', }, { name: 'Nauru', - code: '520', + code: 520, alpha2: 'NR', + alpha3: 'NRU', + nationality: 'Nauruan', }, { name: 'Nepal', - code: '524', + code: 524, alpha2: 'NP', + alpha3: 'NPL', + nationality: 'Nepali, Nepalese', }, { name: 'Netherlands', - code: '528', + code: 528, alpha2: 'NL', + alpha3: 'NLD', + nationality: 'Dutch', }, { name: 'New Caledonia', - code: '540', + code: 540, alpha2: 'NC', + alpha3: 'NCL', + nationality: 'New Caledonian', }, { name: 'New Zealand', - code: '554', + code: 554, alpha2: 'NZ', + alpha3: 'NZL', + nationality: 'New Zealander, Kiwi', }, { name: 'Nicaragua', - code: '558', + code: 558, alpha2: 'NI', + alpha3: 'NIC', + nationality: 'Nicaraguan', }, { name: 'Niger', - code: '562', + code: 562, alpha2: 'NE', + alpha3: 'NER', + nationality: 'Nigerien', }, { name: 'Nigeria', - code: '566', + code: 566, alpha2: 'NG', + alpha3: 'NGA', + nationality: 'Nigerian', }, { name: 'Niue', - code: '570', + code: 570, alpha2: 'NU', + alpha3: 'NIU', + nationality: 'Niuean', }, { name: 'Norfolk Island', - code: '574', + code: 574, alpha2: 'NF', + alpha3: 'NFK', + nationality: 'Norfolk Islander', }, { name: 'Northern Mariana Islands', - code: '580', + code: 580, alpha2: 'MP', + alpha3: 'MNP', + nationality: 'Northern Marianan', }, { name: 'Norway', - code: '578', + code: 578, alpha2: 'NO', + alpha3: 'NOR', + nationality: 'Norwegian', }, { name: 'Oman', - code: '512', + code: 512, alpha2: 'OM', + alpha3: 'OMN', + nationality: 'Omani', }, { name: 'Pakistan', - code: '586', + code: 586, alpha2: 'PK', + alpha3: 'PAK', + nationality: 'Pakistani', }, { name: 'Palau', - code: '585', + code: 585, alpha2: 'PW', + alpha3: 'PLW', + nationality: 'Palauan', }, { - name: 'Palestine', - code: '275', + name: 'Palestine, State of', + code: 275, alpha2: 'PS', + alpha3: 'PSE', + nationality: 'Palestinian', }, { name: 'Panama', - code: '591', + code: 591, alpha2: 'PA', + alpha3: 'PAN', + nationality: 'Panamanian', }, { name: 'Papua New Guinea', - code: '598', + code: 598, alpha2: 'PG', + alpha3: 'PNG', + nationality: 'Papua New Guinean, Papuan', }, { name: 'Paraguay', - code: '600', + code: 600, alpha2: 'PY', + alpha3: 'PRY', + nationality: 'Paraguayan', }, { name: 'Peru', - code: '604', + code: 604, alpha2: 'PE', + alpha3: 'PER', + nationality: 'Peruvian', }, { name: 'Philippines', - code: '608', + code: 608, alpha2: 'PH', + alpha3: 'PHL', + nationality: 'Philippine, Filipino', }, { name: 'Pitcairn', - code: '612', + code: 612, alpha2: 'PN', + alpha3: 'PCN', + nationality: 'Pitcairn Island', }, { name: 'Poland', - code: '616', + code: 616, alpha2: 'PL', + alpha3: 'POL', + nationality: 'Polish', }, { name: 'Portugal', - code: '620', + code: 620, alpha2: 'PT', + alpha3: 'PRT', + nationality: 'Portuguese', }, { name: 'Puerto Rico', - code: '630', + code: 630, alpha2: 'PR', + alpha3: 'PRI', + nationality: 'Puerto Rican', }, { name: 'Qatar', - code: '634', + code: 634, alpha2: 'QA', + alpha3: 'QAT', + nationality: 'Qatari', }, { name: 'Réunion', - code: '638', + code: 638, alpha2: 'RE', + alpha3: 'REU', + nationality: 'Réunionese, Réunionnais', }, { name: 'Romania', - code: '642', + code: 642, alpha2: 'RO', + alpha3: 'ROU', + nationality: 'Romanian', }, { - name: 'Russia', - code: '643', + name: 'Russian Federation', + alias: 'Russia', + code: 643, alpha2: 'RU', + alpha3: 'RUS', + nationality: 'Russian', }, { name: 'Rwanda', - code: '646', + code: 646, alpha2: 'RW', + alpha3: 'RWA', + nationality: 'Rwandan', }, { name: 'Saint Barthélemy', - code: '652', + code: 652, alpha2: 'BL', + alpha3: 'BLM', + nationality: 'Barthélemois', }, { name: 'Saint Helena, Ascension and Tristan da Cunha', - code: '654', + code: 654, alpha2: 'SH', + alpha3: 'SHN', + nationality: 'Saint Helenian', }, { name: 'Saint Kitts and Nevis', - code: '659', + code: 659, alpha2: 'KN', + alpha3: 'KNA', + nationality: 'Kittitian or Nevisian', }, { name: 'Saint Lucia', - code: '662', + code: 662, alpha2: 'LC', + alpha3: 'LCA', + nationality: 'Saint Lucian', }, { - name: 'Saint Martin (French)', - code: '663', + name: 'Saint Martin (French part)', + code: 663, alpha2: 'MF', + alpha3: 'MAF', + nationality: 'Saint-Martinoise', }, { name: 'Saint Pierre and Miquelon', - code: '666', + code: 666, alpha2: 'PM', + alpha3: 'SPM', + nationality: 'Saint-Pierrais or Miquelonnais', }, { name: 'Saint Vincent and the Grenadines', - code: '670', + code: 670, alpha2: 'VC', + alpha3: 'VCT', + nationality: 'Saint Vincentian, Vincentian', }, { name: 'Samoa', - code: '882', + code: 882, alpha2: 'WS', + alpha3: 'WSM', + nationality: 'Samoan', }, { name: 'San Marino', - code: '674', + code: 674, alpha2: 'SM', + alpha3: 'SMR', + nationality: 'Sammarinese', }, { name: 'Sao Tome and Principe', - code: '678', + code: 678, alpha2: 'ST', + alpha3: 'STP', + nationality: 'São Toméan', }, { name: 'Saudi Arabia', - code: '682', + code: 682, alpha2: 'SA', + alpha3: 'SAU', + nationality: 'Saudi, Saudi Arabian', }, { name: 'Senegal', - code: '686', + code: 686, alpha2: 'SN', + alpha3: 'SEN', + nationality: 'Senegalese', }, { name: 'Serbia', - code: '688', + code: 688, alpha2: 'RS', + alpha3: 'SRB', + nationality: 'Serbian', }, { name: 'Seychelles', - code: '690', + code: 690, alpha2: 'SC', + alpha3: 'SYC', + nationality: 'Seychellois', }, { name: 'Sierra Leone', - code: '694', + code: 694, alpha2: 'SL', + alpha3: 'SLE', + nationality: 'Sierra Leonean', }, { name: 'Singapore', - code: '702', + code: 702, alpha2: 'SG', + alpha3: 'SGP', + nationality: 'Singaporean', }, { - name: 'Sint Maarten (Dutch)', - code: '534', + name: 'Sint Maarten (Dutch part)', + code: 534, alpha2: 'SX', + alpha3: 'SXM', + nationality: 'Sint Maarten', }, { name: 'Slovakia', - code: '703', + code: 703, alpha2: 'SK', + alpha3: 'SVK', + nationality: 'Slovak', }, { name: 'Slovenia', - code: '705', + code: 705, alpha2: 'SI', + alpha3: 'SVN', + nationality: 'Slovenian, Slovene', }, { name: 'Solomon Islands', - code: '090', + code: 90, alpha2: 'SB', + alpha3: 'SLB', + nationality: 'Solomon Island', }, { name: 'Somalia', - code: '706', + code: 706, alpha2: 'SO', + alpha3: 'SOM', + nationality: 'Somali, Somalian', }, { name: 'South Africa', - code: '710', + code: 710, alpha2: 'ZA', + alpha3: 'ZAF', + nationality: 'South African', }, { name: 'South Georgia and the South Sandwich Islands', - code: '239', + code: 239, alpha2: 'GS', + alpha3: 'SGS', + nationality: 'South Georgia or South Sandwich Islands', }, { name: 'South Sudan', - code: '728', + code: 728, alpha2: 'SS', + alpha3: 'SSD', + nationality: 'South Sudanese', }, { name: 'Spain', - code: '724', + code: 724, alpha2: 'ES', + alpha3: 'ESP', + nationality: 'Spanish', }, { name: 'Sri Lanka', - code: '144', + code: 144, alpha2: 'LK', + alpha3: 'LKA', + nationality: 'Sri Lankan', }, { name: 'Sudan', - code: '729', + code: 729, alpha2: 'SD', + alpha3: 'SDN', + nationality: 'Sudanese', }, { name: 'Suriname', - code: '740', + code: 740, alpha2: 'SR', + alpha3: 'SUR', + nationality: 'Surinamese', }, { name: 'Svalbard and Jan Mayen', - code: '744', + code: 744, alpha2: 'SJ', + alpha3: 'SJM', + nationality: 'Svalbard', }, { name: 'Swaziland', - code: '748', + code: 748, alpha2: 'SZ', + alpha3: 'SWZ', + nationality: 'Swazi', }, { name: 'Sweden', - code: '752', + code: 752, alpha2: 'SE', + alpha3: 'SWE', + nationality: 'Swedish', }, { name: 'Switzerland', - code: '756', + code: 756, alpha2: 'CH', + alpha3: 'CHE', + nationality: 'Swiss', }, { name: 'Syrian Arab Republic', - code: '760', + code: 760, alpha2: 'SY', + alpha3: 'SYR', + nationality: 'Syrian', }, { name: 'Taiwan, Province of China', - code: '158', + code: 158, alpha2: 'TW', + alpha3: 'TWN', + nationality: 'Chinese, Taiwanese', + priority: 0, }, { name: 'Tajikistan', - code: '762', + code: 762, alpha2: 'TJ', + alpha3: 'TJK', + nationality: 'Tajikistani', }, { - name: 'Tanzania', - code: '834', + name: 'Tanzania, United Republic of', + code: 834, alpha2: 'TZ', + alpha3: 'TZA', + nationality: 'Tanzanian', }, { name: 'Thailand', - code: '764', + code: 764, alpha2: 'TH', + alpha3: 'THA', + nationality: 'Thai', }, { name: 'Timor-Leste', - code: '626', + code: 626, alpha2: 'TL', + alpha3: 'TLS', + nationality: 'Timorese', }, { name: 'Togo', - code: '768', + code: 768, alpha2: 'TG', + alpha3: 'TGO', + nationality: 'Togolese', }, { name: 'Tokelau', - code: '772', + code: 772, alpha2: 'TK', + alpha3: 'TKL', + nationality: 'Tokelauan', }, { name: 'Tonga', - code: '776', + code: 776, alpha2: 'TO', + alpha3: 'TON', + nationality: 'Tongan', }, { - name: 'Trinalpha2ad and Tobago', - code: '780', + name: 'Trinidad and Tobago', + code: 780, alpha2: 'TT', + alpha3: 'TTO', + nationality: 'Trinidadian or Tobagonian', }, { name: 'Tunisia', - code: '788', + code: 788, alpha2: 'TN', + alpha3: 'TUN', + nationality: 'Tunisian', }, { name: 'Turkey', - code: '792', + code: 792, alpha2: 'TR', + alpha3: 'TUR', + nationality: 'Turkish', }, { name: 'Turkmenistan', - code: '795', + code: 795, alpha2: 'TM', + alpha3: 'TKM', + nationality: 'Turkmen', }, { name: 'Turks and Caicos Islands', - code: '796', + code: 796, alpha2: 'TC', + alpha3: 'TCA', + nationality: 'Turks and Caicos Island', }, { name: 'Tuvalu', - code: '798', + code: 798, alpha2: 'TV', + alpha3: 'TUV', + nationality: 'Tuvaluan', }, { name: 'Uganda', - code: '800', + code: 800, alpha2: 'UG', + alpha3: 'UGA', + nationality: 'Ugandan', }, { name: 'Ukraine', - code: '804', + code: 804, alpha2: 'UA', + alpha3: 'UKR', + nationality: 'Ukrainian', }, { name: 'United Arab Emirates', - code: '784', + code: 784, alpha2: 'AE', + alpha3: 'ARE', + nationality: 'Emirati, Emirian, Emiri', }, { - name: 'United Kingdom', - code: '826', + name: 'United Kingdom of Great Britain and Northern Ireland', + code: 826, alpha2: 'GB', + alpha3: 'GBR', + nationality: 'British, English', }, { - name: 'United States', - code: '840', - alpha2: 'US', - }, - { - name: 'United States, Minor Outlying Islands', - code: '581', + name: 'United States Minor Outlying Islands', + code: 581, alpha2: 'UM', + alpha3: 'UMI', + nationality: 'American', + priority: 0, + }, + { + name: 'United States of America', + alias: 'United States', + code: 840, + alpha2: 'US', + alpha3: 'USA', + nationality: 'American', + priority: 1, }, { name: 'Uruguay', - code: '858', + code: 858, alpha2: 'UY', + alpha3: 'URY', + nationality: 'Uruguayan', }, { name: 'Uzbekistan', - code: '860', + code: 860, alpha2: 'UZ', + alpha3: 'UZB', + nationality: 'Uzbekistani, Uzbek', }, { name: 'Vanuatu', - code: '548', + code: 548, alpha2: 'VU', + alpha3: 'VUT', + nationality: 'Ni-Vanuatu, Vanuatuan', }, { - name: 'Venezuela', - code: '862', + name: 'Venezuela (Bolivarian Republic of)', + code: 862, alpha2: 'VE', + alpha3: 'VEN', + nationality: 'Venezuelan', }, { name: 'Vietnam', - code: '704', + code: 704, alpha2: 'VN', + alpha3: 'VNM', + nationality: 'Vietnamese', }, { - name: 'Virgin Islands (UK)', - code: '092', + name: 'Virgin Islands (British)', + code: 92, alpha2: 'VG', + alpha3: 'VGB', + nationality: 'British Virgin Island', }, { - name: 'Virgin Islands (US)', - code: '850', + name: 'Virgin Islands (U.S.)', + code: 850, alpha2: 'VI', + alpha3: 'VIR', + nationality: 'U.S. Virgin Island', }, { name: 'Wallis and Futuna', - code: '876', + code: 876, alpha2: 'WF', + alpha3: 'WLF', + nationality: 'Wallis and Futuna, Wallisian or Futunan', }, { name: 'Western Sahara', - code: '732', + code: 732, alpha2: 'EH', + alpha3: 'ESH', + nationality: 'Sahrawi, Sahrawian, Sahraouian', }, { name: 'Yemen', - code: '887', + code: 887, alpha2: 'YE', + alpha3: 'YEM', + nationality: 'Yemeni', }, { name: 'Zambia', - code: '894', + code: 894, alpha2: 'ZM', + alpha3: 'ZMB', + nationality: 'Zambian', }, { name: 'Zimbabwe', - code: '716', + code: 716, alpha2: 'ZW', + alpha3: 'ZWE', + nationality: 'Zimbabwean', }, ]; diff --git a/src/actors.js b/src/actors.js index c2035903..b4b3a7ff 100644 --- a/src/actors.js +++ b/src/actors.js @@ -1,6 +1,7 @@ 'use strict'; const Promise = require('bluebird'); +const UrlPattern = require('url-pattern'); const knex = require('./knex'); const argv = require('./argv'); @@ -54,6 +55,7 @@ async function curateActor(actor) { curatedActor.origin.country = { alpha2: actor.birth_country_alpha2, name: actor.birth_country_name, + alias: actor.birth_country_alias, }; } @@ -64,6 +66,7 @@ async function curateActor(actor) { curatedActor.residence.country = { alpha2: actor.residence_country_alpha2, name: actor.residence_country_name, + alias: actor.residence_country_alias, }; } @@ -124,12 +127,54 @@ function curateActorEntry(actor, scraped, scrapeSuccess) { } function curateSocialEntry(url, actorId) { - const { hostname, origin, pathname } = new URL(url); - const platform = ['facebook', 'twitter', 'instagram', 'tumblr', 'snapchat', 'amazon', 'youtube', 'fancentro'].find(platformName => hostname.match(platformName)); + const platforms = [ + { + label: 'twitter', + pattern: 'http(s)\\://(*)twitter.com/:username(/)(?*)', + format: username => `https://www.twitter.com/${username}`, + }, + { + label: 'instagram', + pattern: 'http(s)\\://(*)instagram.com/:username(/)(?*)', + format: username => `https://www.instagram.com/${username}`, + }, + { + label: 'snapchat', + pattern: 'http(s)\\://(*)snapchat.com/add/:username(/)(?*)', + format: username => `https://www.snapchat.com/add/${username}`, + }, + { + label: 'tumblr', + pattern: 'http(s)\\://:username.tumblr.com(*)', + format: username => `https://${username}.tumblr.com`, + }, + { + label: 'fancentro', + pattern: 'http(s)\\://(www.)fancentro.com/:username(/)(?*)', + format: username => `https://www.fancentro.com/${username}`, + }, + ]; + + const match = platforms.reduce((acc, platform) => { + if (acc) return acc; + + const patternMatch = new UrlPattern(platform.pattern).match(url); + + if (patternMatch) { + return { + platform: platform.label, + original: url, + username: patternMatch.username, + url: platform.format ? platform.format(patternMatch.username) : url, + }; + } + + return null; + }, null) || { url }; return { - url: `${origin}${pathname}`, - platform, + url: match.url, + platform: match.platform, domain: 'actors', target_id: actorId, }; @@ -148,7 +193,7 @@ async function curateSocialEntries(urls, actorId) { return urls.reduce((acc, url) => { const socialEntry = curateSocialEntry(url, actorId); - if (acc.some(entry => socialEntry.url === entry.url) || existingSocialLinks.some(entry => socialEntry.url === entry.url)) { + if (acc.some(entry => socialEntry.url.toLowerCase() === entry.url.toLowerCase()) || existingSocialLinks.some(entry => socialEntry.url.toLowerCase() === entry.url.toLowerCase())) { // prevent duplicates return acc; } @@ -161,11 +206,12 @@ async function fetchActors(queryObject) { const releases = await knex('actors') .select( 'actors.*', - 'birth_countries.alpha2 as birth_country_alpha2', 'birth_countries.name as birth_country_name', - 'residence_countries.alpha2 as residence_country_alpha2', 'residence_countries.name as residence_country_name', + 'birth_countries.alpha2 as birth_country_alpha2', 'birth_countries.name as birth_country_name', 'birth_countries.alias as birth_country_alias', + 'residence_countries.alpha2 as residence_country_alpha2', 'residence_countries.name as residence_country_name', 'residence_countries.alias as residence_country_alias', ) .leftJoin('countries as birth_countries', 'actors.birth_country_alpha2', 'birth_countries.alpha2') .leftJoin('countries as residence_countries', 'actors.residence_country_alpha2', 'residence_countries.alpha2') + .orderBy(['actors.name', 'actors.gender']) .where(builder => whereOr(queryObject, 'actors', builder)) .limit(100); @@ -215,7 +261,7 @@ async function mergeProfiles(profiles, actor) { return { id: actor ? actor.id : null, - name: actor ? actor.name : profile.name, + name: actor ? actor.name : (prevProfile.name || profile.name), description: prevProfile.description || profile.description, gender: prevProfile.gender || profile.gender, birthdate: Number.isNaN(Number(prevProfile.birthdate)) ? profile.birthdate : prevProfile.birthdate, @@ -257,9 +303,10 @@ async function scrapeActors(actorNames) { await Promise.map(actorNames || argv.actors, async (actorName) => { try { const actorSlug = actorName.toLowerCase().replace(/\s+/g, '-'); - const actorEntry = await knex('actors').where({ slug: actorSlug }).first(); - const profiles = await Promise.map(Object.entries(scrapers.actors), async ([scraperSlug, scraper]) => { + const sources = argv.sources ? argv.sources.map(source => [source, scrapers.actors[source]]) : Object.entries(scrapers.actors); + + const profiles = await Promise.map(sources, async ([scraperSlug, scraper]) => { const profile = await scraper.fetchProfile(actorEntry ? actorEntry.name : actorName); return { diff --git a/src/argv.js b/src/argv.js index cf6d2575..a36593ae 100644 --- a/src/argv.js +++ b/src/argv.js @@ -24,6 +24,11 @@ const { argv } = yargs type: 'array', alias: 'actor', }) + .option('sources', { + describe: 'Only use these scrapers for actor data', + type: 'array', + alias: 'source', + }) .option('deep', { describe: 'Fetch details for all releases', type: 'boolean', diff --git a/src/scrape-sites.js b/src/scrape-sites.js index 6a402b55..67cc9dbc 100644 --- a/src/scrape-sites.js +++ b/src/scrape-sites.js @@ -117,6 +117,9 @@ async function scrapeReleases() { try { const siteReleases = await scrapeSiteReleases(scraper, site); + const siteActors = siteReleases.reduce((acc, release) => [...acc, ...release.actors], []); + + console.log(siteActors); if (argv.save) { await storeReleases(siteReleases); diff --git a/src/scrapers/brazzers.js b/src/scrapers/brazzers.js index 59e66084..b74a1fe9 100644 --- a/src/scrapers/brazzers.js +++ b/src/scrapers/brazzers.js @@ -130,7 +130,7 @@ function scrapeActorSearch(html, url, actorName) { const { document } = new JSDOM(html).window; const actorLink = document.querySelector(`a[title="${actorName}" i]`); - return actorLink; + return actorLink ? actorLink.href : null; } function scrapeProfile(html, url, actorName) { @@ -157,6 +157,9 @@ function scrapeProfile(html, url, actorName) { if (bio.Weight) profile.weight = lbsToKg(bio.Weight.match(/\d+/)[0]); if (bio['Hair Color']) profile.hair = hairMap[bio['Hair Color']] || bio['Hair Color'].toLowerCase(); + if (bio['Tits Type'] && bio['Tits Type'].match('Natural')) profile.naturalBoobs = true; + if (bio['Tits Type'] && bio['Tits Type'].match('Enhanced')) profile.naturalBoobs = false; + if (bio['Body Art'] && bio['Body Art'].match('Tattoo')) profile.hasTattoos = true; if (bio['Body Art'] && bio['Body Art'].match('Piercing')) profile.hasPiercings = true; diff --git a/src/scrapers/ddfnetwork.js b/src/scrapers/ddfnetwork.js index 381dbd6a..f84cfd27 100644 --- a/src/scrapers/ddfnetwork.js +++ b/src/scrapers/ddfnetwork.js @@ -2,9 +2,10 @@ const bhttp = require('bhttp'); const cheerio = require('cheerio'); +const { JSDOM } = require('jsdom'); const moment = require('moment'); -// const knex = require('../knex'); +const knex = require('../knex'); const { matchTags } = require('../tags'); /* eslint-disable newline-per-chained-call */ @@ -105,6 +106,67 @@ async function scrapeScene(html, url, site) { }; } +async function scrapeProfile(html, _url, actorName) { + const { document } = new JSDOM(html).window; + + const keys = Array.from(document.querySelectorAll('.about-title'), el => el.textContent.trim().replace(':', '')); + const values = Array.from(document.querySelectorAll('.about-info'), (el) => { + if (el.children.length > 0) { + return Array.from(el.children, child => child.textContent.trim()).join(', '); + } + + return el.textContent.trim(); + }); + + const bio = keys.reduce((acc, key, index) => { + if (values[index] === '-') { + return acc; + } + + return { + ...acc, + [key]: values[index], + }; + }, {}); + + const descriptionEl = document.querySelector('.description-box'); + const avatarEl = document.querySelector('.pornstar-details .card-img-top'); + + const country = await knex('countries') + .where('nationality', 'ilike', `%${bio.Nationality}%`) + .orderBy('priority', 'desc') + .first(); + + const profile = { + name: actorName, + }; + + profile.birthdate = moment.utc(bio.Birthday, 'MMMM DD, YYYY').toDate(); + if (country) profile.birthPlace = country.name; + + if (bio['Bra size']) [profile.bust] = bio['Bra size'].match(/\d+\w+/); + if (bio.Waist) profile.waist = Number(bio.Waist.match(/\d+/)[0]); + if (bio.Hips) profile.hip = Number(bio.Hips.match(/\d+/)[0]); + + if (bio.Height) profile.height = Number(bio.Height.match(/\d{2,}/)[0]); + + if (bio['Tit Style'] && bio['Tit Style'].match('Enhanced')) profile.naturalBoobs = false; + if (bio['Tit Style'] && bio['Tit Style'].match('Natural')) profile.naturalBoobs = true; + + if (bio['Body Art'] && bio['Body Art'].match('Tattoo')) profile.hasTattoos = true; + if (bio['Body Art'] && bio['Body Art'].match('Piercing')) profile.hasPiercings = true; + + if (bio['Hair Style']) profile.hair = bio['Hair Style'].split(',')[0].trim().toLowerCase(); + if (bio['Eye Color']) profile.eyes = bio['Eye Color'].match(/\w+/)[0].toLowerCase(); + + if (bio['Shoe size']) profile.shoes = Number(bio['Shoe size'].split('|')[1]); + + if (descriptionEl) profile.description = descriptionEl.textContent.trim(); + if (avatarEl) profile.avatar = `https:${avatarEl.dataset.src}`; + + return profile; +} + async function fetchLatest(site, page = 1) { const res = await bhttp.get(`https://ddfnetwork.com/videos/search/latest/ever/${new URL(site.url).hostname}/-/${page}`); @@ -117,7 +179,41 @@ async function fetchScene(url, site) { return scrapeScene(res.body.toString(), url, site); } +async function fetchProfile(actorName) { + const resSearch = await bhttp.post('https://ddfnetwork.com/search/ajax', + { + type: 'hints', + word: actorName, + }, + { + decodeJSON: true, + headers: { + 'x-requested-with': 'XMLHttpRequest', + }, + }); + + if (resSearch.statusCode !== 200 || Array.isArray(resSearch.body.list)) { + return null; + } + + if (!resSearch.body.list.pornstarsName || resSearch.body.list.pornstarsName.length === 0) { + return null; + } + + const [actor] = resSearch.body.list.pornstarsName; + const url = `https://ddfnetwork.com${actor.href}`; + + const resActor = await bhttp.get(url); + + if (resActor.statusCode !== 200) { + return null; + } + + return scrapeProfile(resActor.body.toString(), url, actorName); +} + module.exports = { fetchLatest, + fetchProfile, fetchScene, }; diff --git a/src/scrapers/scrapers.js b/src/scrapers/scrapers.js index 568fa054..77d0872b 100644 --- a/src/scrapers/scrapers.js +++ b/src/scrapers/scrapers.js @@ -4,7 +4,6 @@ const twentyonesextury = require('./21sextury'); const bangbros = require('./bangbros'); const blowpass = require('./blowpass'); -const ddfnetwork = require('./ddfnetwork'); const dogfart = require('./dogfart'); const evilangel = require('./evilangel'); const kink = require('./kink'); @@ -15,12 +14,13 @@ const privateNetwork = require('./private'); // reserved keyword const naughtyamerica = require('./naughtyamerica'); const realitykings = require('./realitykings'); const vixen = require('./vixen'); -const xempire = require('./xempire'); // releases and profiles +const ddfnetwork = require('./ddfnetwork'); const brazzers = require('./brazzers'); const julesjordan = require('./julesjordan'); const legalporno = require('./legalporno'); +const xempire = require('./xempire'); // profiles const freeones = require('./freeones'); @@ -49,10 +49,13 @@ module.exports = { xempire, }, actors: { + // ordered by data priority + xempire, brazzers, freeones, julesjordan, legalporno, pornhub, + ddfnetwork, }, }; diff --git a/src/scrapers/xempire.js b/src/scrapers/xempire.js index 29db4d06..e0f3ac38 100644 --- a/src/scrapers/xempire.js +++ b/src/scrapers/xempire.js @@ -3,9 +3,10 @@ const Promise = require('bluebird'); const bhttp = require('bhttp'); const cheerio = require('cheerio'); +const { JSDOM } = require('jsdom'); const moment = require('moment'); -const knex = require('../knex'); +const { fetchSites } = require('../sites'); const { matchTags } = require('../tags'); const pluckPhotos = require('../utils/pluck-photos'); @@ -142,7 +143,7 @@ async function scrapeScene(html, url, site) { const duration = moment.duration(data.duration.slice(2).split(':')).asSeconds(); const siteDomain = $('meta[name="twitter:domain"]').attr('content'); - const siteId = siteDomain && siteDomain.split('.')[0].toLowerCase(); + const siteSlug = siteDomain && siteDomain.split('.')[0].toLowerCase(); const siteUrl = siteDomain && `https://www.${siteDomain}`; const poster = videoData.picPreview; @@ -152,14 +153,14 @@ async function scrapeScene(html, url, site) { const rawTags = data.keywords.split(', '); - const [channelSite, tags] = await Promise.all([ + const [[channelSite], tags] = await Promise.all([ site.isFallback - ? knex('sites') - .where({ url: siteUrl }) - .orWhere({ slug: siteId }) - .first() - : site, - matchTags([...defaultTags[siteId], ...rawTags]), + ? fetchSites({ + url: siteUrl, + slug: siteSlug, + }) + : [site], + matchTags([...defaultTags[siteSlug], ...rawTags]), ]); return { @@ -185,6 +186,31 @@ async function scrapeScene(html, url, site) { }; } +function scrapeActorSearch(html, url, actorName) { + const { document } = new JSDOM(html).window; + const actorLink = document.querySelector(`a[title="${actorName}" i]`); + + return actorLink ? actorLink.href : null; +} + +function scrapeProfile(html, url, actorName) { + const { document } = new JSDOM(html).window; + + const avatarEl = document.querySelector('img.actorPicture'); + const descriptionEl = document.querySelector('.actorBio p:not(.bioTitle)'); + + const profile = { + name: actorName, + }; + + if (avatarEl) profile.avatar = avatarEl.src; + if (descriptionEl) profile.description = descriptionEl.textContent.trim(); + + profile.releases = Array.from(document.querySelectorAll('.sceneList .scene a.imgLink'), el => `https://xempire.com${el.href}`); + + return profile; +} + async function fetchLatest(site, page = 1) { const res = await bhttp.get(`${site.url}/en/videos/AllCategories/0/${page}`); @@ -203,8 +229,34 @@ async function fetchScene(url, site) { return scrapeScene(res.body.toString(), url, site); } +async function fetchProfile(actorName) { + const actorSlug = actorName.toLowerCase().replace(/\s+/, '+'); + const searchUrl = `https://www.xempire.com/en/search/xempire/actor/${actorSlug}`; + const searchRes = await bhttp.get(searchUrl); + + if (searchRes.statusCode !== 200) { + return null; + } + + const actorUrl = scrapeActorSearch(searchRes.body.toString(), searchUrl, actorName); + + if (actorUrl) { + const url = `https://xempire.com${actorUrl}`; + const actorRes = await bhttp.get(url); + + if (actorRes.statusCode !== 200) { + return null; + } + + return scrapeProfile(actorRes.body.toString(), url, actorName); + } + + return null; +} + module.exports = { fetchLatest, + fetchProfile, fetchUpcoming, fetchScene, }; diff --git a/src/utils/where-or.js b/src/utils/where-or.js index c4cf8c5f..800d2f65 100644 --- a/src/utils/where-or.js +++ b/src/utils/where-or.js @@ -1,11 +1,17 @@ 'use strict'; function whereOr(query, table, builder) { + if (!query) { + return {}; + } + Object.entries(query).forEach(([key, value]) => { if (value !== undefined) { builder.orWhere(`${table}.${key}`, value); } }); + + return builder; } module.exports = whereOr; diff --git a/src/web/actors.js b/src/web/actors.js index daadbe15..c87c89e6 100644 --- a/src/web/actors.js +++ b/src/web/actors.js @@ -6,10 +6,22 @@ async function fetchActorsApi(req, res) { const actorId = typeof req.params.actorId === 'number' ? req.params.actorId : null; const actorSlug = typeof req.params.actorId === 'string' ? req.params.actorId : null; - const actors = await fetchActors({ - id: actorId, - slug: actorSlug, - }); + if (actorId || actorSlug) { + const actors = await fetchActors({ + id: actorId, + slug: actorSlug, + }); + + if (actors.length > 0) { + res.send(actors[0]); + return; + } + + res.status(404).send(); + return; + } + + const actors = await fetchActors(); res.send(actors); }