From f9f9cc7977b277393062ec76596601c7d4b07d5a Mon Sep 17 00:00:00 2001 From: Niels Simenon Date: Wed, 13 Nov 2019 03:14:24 +0100 Subject: [PATCH] Added tag filter to releases query, enabled on homepage. --- assets/components/home/filter.vue | 172 +++++++++++++++++++++++ assets/components/home/home.vue | 137 ++++-------------- assets/components/release/release.vue | 2 +- assets/components/site/site.vue | 2 +- assets/css/_tooltip.scss | 109 ++++++++++++++ assets/css/style.scss | 1 + assets/js/api.js | 8 +- assets/js/main.js | 3 + assets/js/releases/actions.js | 4 +- package-lock.json | 62 ++++++-- package.json | 2 + public/css/style.css | 156 +++++++++++++++----- public/img/logos/evilangel/evilangel.png | Bin 0 -> 6670 bytes public/img/logos/evilangel/network.png | Bin 0 -> 6670 bytes seeds/02_tags.js | 8 +- src/actors.js | 6 +- src/networks.js | 6 +- src/releases.js | 21 ++- src/scrapers/xempire.js | 9 +- src/sites.js | 4 +- src/tags.js | 6 +- src/utils/where-or.js | 4 +- src/web/actors.js | 5 +- src/web/networks.js | 9 +- src/web/releases.js | 2 +- src/web/tags.js | 9 +- 26 files changed, 555 insertions(+), 192 deletions(-) create mode 100644 assets/components/home/filter.vue create mode 100644 assets/css/_tooltip.scss create mode 100644 public/img/logos/evilangel/evilangel.png create mode 100644 public/img/logos/evilangel/network.png diff --git a/assets/components/home/filter.vue b/assets/components/home/filter.vue new file mode 100644 index 00000000..709b3296 --- /dev/null +++ b/assets/components/home/filter.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/assets/components/home/home.vue b/assets/components/home/home.vue index 8ddbb61e..f7e98281 100644 --- a/assets/components/home/home.vue +++ b/assets/components/home/home.vue @@ -1,62 +1,9 @@ - - diff --git a/assets/components/release/release.vue b/assets/components/release/release.vue index 11a24a43..c4e195db 100644 --- a/assets/components/release/release.vue +++ b/assets/components/release/release.vue @@ -168,7 +168,7 @@ function photos() { } async function mounted() { - [this.release] = await this.$store.dispatch('fetchReleases', this.$route.params.releaseId); + [this.release] = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId }); } export default { diff --git a/assets/components/site/site.vue b/assets/components/site/site.vue index 5a3b852a..0bf23d9e 100644 --- a/assets/components/site/site.vue +++ b/assets/components/site/site.vue @@ -116,7 +116,7 @@ export default { } .logo { - width: 15rem; + width: 20rem; max-height: 8rem; object-fit: contain; margin: 0 .5rem 1rem 0; diff --git a/assets/css/_tooltip.scss b/assets/css/_tooltip.scss new file mode 100644 index 00000000..c5df08db --- /dev/null +++ b/assets/css/_tooltip.scss @@ -0,0 +1,109 @@ +.tooltip { + display: block !important; + z-index: 10000; + + .tooltip-inner { + background: #222; + color: white; + border-radius: 16px; + padding: 5px 10px 4px; + } + + .tooltip-arrow { + width: 0; + height: 0; + border-style: solid; + position: absolute; + margin: 5px; + border-color: #222; + z-index: 1; + } + + &[x-placement^="top"] { + margin-bottom: 5px; + + .tooltip-arrow { + border-width: 5px 5px 0 5px; + border-left-color: transparent !important; + border-right-color: transparent !important; + border-bottom-color: transparent !important; + bottom: -5px; + left: calc(50% - 5px); + margin-top: 0; + margin-bottom: 0; + } + } + + &[x-placement^="bottom"] { + margin-top: 5px; + + .tooltip-arrow { + border-width: 0 5px 5px 5px; + border-left-color: transparent !important; + border-right-color: transparent !important; + border-top-color: transparent !important; + top: -5px; + left: calc(50% - 5px); + margin-top: 0; + margin-bottom: 0; + } + } + + &[x-placement^="right"] { + margin-left: 5px; + + .tooltip-arrow { + border-width: 5px 5px 5px 0; + border-left-color: transparent !important; + border-top-color: transparent !important; + border-bottom-color: transparent !important; + left: -5px; + top: calc(50% - 5px); + margin-left: 0; + margin-right: 0; + } + } + + &[x-placement^="left"] { + margin-right: 5px; + + .tooltip-arrow { + border-width: 5px 0 5px 5px; + border-top-color: transparent !important; + border-right-color: transparent !important; + border-bottom-color: transparent !important; + right: -5px; + top: calc(50% - 5px); + margin-left: 0; + margin-right: 0; + } + } + + &.popover { + $color: #f9f9f9; + + .popover-inner { + background: $color; + color: black; + padding: 24px; + border-radius: 5px; + box-shadow: 0 5px 30px rgba(black, .1); + } + + .popover-arrow { + border-color: $color; + } + } + + &[aria-hidden='true'] { + visibility: hidden; + opacity: 0; + /* transition: opacity .15s, visibility .15s; */ + } + + &[aria-hidden='false'] { + visibility: visible; + opacity: 1; + /* transition: opacity .15s; */ + } +} diff --git a/assets/css/style.scss b/assets/css/style.scss index 03f1d2dc..d4ccac2e 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -1,5 +1,6 @@ @import 'theme'; @import 'states'; +@import 'tooltip'; html, body { diff --git a/assets/js/api.js b/assets/js/api.js index 4ca374ab..ad0a5586 100644 --- a/assets/js/api.js +++ b/assets/js/api.js @@ -1,9 +1,11 @@ import config from 'config'; -async function get(endpoint, query = {}) { - const queryString = Object.entries(query).reduce((acc, [key, value], index) => `${acc}${index > 0 ? '&' : ''}${key}=${value}`, '?'); +import queryString from 'query-string'; - const res = await fetch(`${config.api.url}${endpoint}${queryString}`, { +async function get(endpoint, query = {}) { + const q = queryString.stringify(query); + + const res = await fetch(`${config.api.url}${endpoint}?${q}`, { method: 'GET', mode: 'cors', credentials: 'same-origin', diff --git a/assets/js/main.js b/assets/js/main.js index f3ad6bd3..07393365 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,5 +1,6 @@ import Vue from 'vue'; import dayjs from 'dayjs'; +import VTooltip from 'v-tooltip'; import router from './router'; import initStore from './store'; @@ -31,6 +32,8 @@ function init() { }, }); + Vue.use(VTooltip); + new Vue({ // eslint-disable-line no-new el: '#container', store, diff --git a/assets/js/releases/actions.js b/assets/js/releases/actions.js index bb870018..c1da8aa5 100644 --- a/assets/js/releases/actions.js +++ b/assets/js/releases/actions.js @@ -1,8 +1,8 @@ import { get } from '../api'; function initReleasesActions(_store, _router) { - async function fetchReleases({ _commit }, releaseId) { - const releases = await get(`/releases/${releaseId || ''}`); + async function fetchReleases({ _commit }, { id, filter }) { + const releases = await get(`/releases/${id || ''}`, { filter }); return releases; } diff --git a/package-lock.json b/package-lock.json index 41e6b7dc..c89345ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7700,6 +7700,24 @@ "prepend-http": "^1.0.0", "query-string": "^4.1.0", "sort-keys": "^1.0.0" + }, + "dependencies": { + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + } } }, "npm-run-path": { @@ -8335,6 +8353,11 @@ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, + "popper.js": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz", + "integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw==" + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -8709,13 +8732,13 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.3.tgz", + "integrity": "sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ==", "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" } }, "querystring": { @@ -10065,6 +10088,11 @@ "through": "2" } }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -10210,10 +10238,9 @@ "integrity": "sha512-1q+dL790Ps0NV33rISMq9OLtfDA9KMJZdo1PHZXE85orrWsM4FAh8CVyAOTHO0rhyeM138KNPngBPrx33bFsxw==" }, "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" }, "string": { "version": "3.3.3", @@ -10997,6 +11024,16 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" }, + "v-tooltip": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.0.2.tgz", + "integrity": "sha512-xQ+qzOFfywkLdjHknRPgMMupQNS8yJtf9Utd5Dxiu/0n4HtrxqsgDtN2MLZ0LKbburtSAQgyypuE/snM8bBZhw==", + "requires": { + "lodash": "^4.17.11", + "popper.js": "^1.15.0", + "vue-resize": "^0.4.5" + } + }, "v8-compile-cache": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", @@ -11121,6 +11158,11 @@ "vue-style-loader": "^4.1.0" } }, + "vue-resize": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-0.4.5.tgz", + "integrity": "sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg==" + }, "vue-router": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.6.tgz", diff --git a/package.json b/package.json index f400f50e..37a3571a 100644 --- a/package.json +++ b/package.json @@ -85,11 +85,13 @@ "opn": "^5.4.0", "pg": "^7.9.0", "prop-types": "^15.7.2", + "query-string": "^6.8.3", "react": "^16.8.6", "react-dom": "^16.8.6", "sharp": "^0.23.2", "tough-cookie": "^3.0.1", "tty-table": "^2.7.0", + "v-tooltip": "^2.0.2", "vue": "^2.6.10", "vue-router": "^3.0.6", "vuex": "^3.1.1", diff --git a/public/css/style.css b/public/css/style.css index 0047fc9c..71c4527a 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,3 +1,44 @@ +/* $primary: #ff886c; */ +.filters-bar[data-v-7de6ddc6] { + display: block; + background: rgba(0, 0, 0, 0.1); + padding: .5rem 1rem; + font-size: 0; +} +.filters-bar .icon[data-v-7de6ddc6] { + fill: rgba(0, 0, 0, 0.5); +} +.filters[data-v-7de6ddc6] { + display: inline-block; + list-style: none; + padding: .5rem; + margin: 0; +} +.filters[data-v-7de6ddc6]:not(:last-child) { + border-right: solid 1px rgba(0, 0, 0, 0.2); +} +.filter[data-v-7de6ddc6] { + display: inline-block; +} +.toggle[data-v-7de6ddc6] { + color: rgba(0, 0, 0, 0.5); + background: rgba(0, 0, 0, 0.1); + box-sizing: border-box; + padding: .5rem; + margin: 0 .25rem; + border-radius: .5rem; + font-size: .9rem; + font-weight: bold; + cursor: pointer; +} +.toggle .check[data-v-7de6ddc6] { + display: none; +} +.toggle.active[data-v-7de6ddc6] { + color: #fff; + background: #ff6c88; +} + /* $primary: #ff886c; */ .tile[data-v-3abcf101] { display: flex; @@ -118,42 +159,6 @@ color: rgba(0, 0, 0, 0.7); } -/* $primary: #ff886c; */ -.filters-bar[data-v-5533e378] { - display: block; - background: rgba(0, 0, 0, 0.1); - padding: .5rem 1rem; -} -.filters-bar .icon[data-v-5533e378] { - fill: rgba(0, 0, 0, 0.5); -} -.filters[data-v-5533e378] { - display: inline-block; - list-style: none; - padding: .5rem; - margin: 0; -} -.filters .toggle[data-v-5533e378] { - color: rgba(0, 0, 0, 0.5); - background: rgba(0, 0, 0, 0.1); - box-sizing: border-box; - padding: .5rem; - border-radius: .5rem; - font-size: .9rem; - font-weight: bold; - cursor: pointer; -} -.filters .toggle .check[data-v-5533e378] { - display: none; -} -.filters .toggle.active[data-v-5533e378] { - color: #fff; - background: #ff6c88; -} -.filter[data-v-5533e378] { - display: inline-block; -} - /* $primary: #ff886c; */ .banner[data-v-2bc41e74] { background: #222; @@ -246,7 +251,7 @@ align-items: flex-end; } .logo[data-v-3e57cf44] { - width: 15rem; + width: 20rem; max-height: 8rem; -o-object-fit: contain; object-fit: contain; @@ -423,6 +428,83 @@ -ms-user-select: none; -webkit-tap-highlight-color: transparent; } +.tooltip { + display: block !important; + z-index: 10000; } + .tooltip .tooltip-inner { + background: #222; + color: white; + border-radius: 16px; + padding: 5px 10px 4px; } + .tooltip .tooltip-arrow { + width: 0; + height: 0; + border-style: solid; + position: absolute; + margin: 5px; + border-color: #222; + z-index: 1; } + .tooltip[x-placement^="top"] { + margin-bottom: 5px; } + .tooltip[x-placement^="top"] .tooltip-arrow { + border-width: 5px 5px 0 5px; + border-left-color: transparent !important; + border-right-color: transparent !important; + border-bottom-color: transparent !important; + bottom: -5px; + left: calc(50% - 5px); + margin-top: 0; + margin-bottom: 0; } + .tooltip[x-placement^="bottom"] { + margin-top: 5px; } + .tooltip[x-placement^="bottom"] .tooltip-arrow { + border-width: 0 5px 5px 5px; + border-left-color: transparent !important; + border-right-color: transparent !important; + border-top-color: transparent !important; + top: -5px; + left: calc(50% - 5px); + margin-top: 0; + margin-bottom: 0; } + .tooltip[x-placement^="right"] { + margin-left: 5px; } + .tooltip[x-placement^="right"] .tooltip-arrow { + border-width: 5px 5px 5px 0; + border-left-color: transparent !important; + border-top-color: transparent !important; + border-bottom-color: transparent !important; + left: -5px; + top: calc(50% - 5px); + margin-left: 0; + margin-right: 0; } + .tooltip[x-placement^="left"] { + margin-right: 5px; } + .tooltip[x-placement^="left"] .tooltip-arrow { + border-width: 5px 0 5px 5px; + border-top-color: transparent !important; + border-right-color: transparent !important; + border-bottom-color: transparent !important; + right: -5px; + top: calc(50% - 5px); + margin-left: 0; + margin-right: 0; } + .tooltip.popover .popover-inner { + background: #f9f9f9; + color: black; + padding: 24px; + border-radius: 5px; + box-shadow: 0 5px 30px rgba(0, 0, 0, 0.1); } + .tooltip.popover .popover-arrow { + border-color: #f9f9f9; } + .tooltip[aria-hidden='true'] { + visibility: hidden; + opacity: 0; + /* transition: opacity .15s, visibility .15s; */ } + .tooltip[aria-hidden='false'] { + visibility: visible; + opacity: 1; + /* transition: opacity .15s; */ } + html, body { height: 100%; } diff --git a/public/img/logos/evilangel/evilangel.png b/public/img/logos/evilangel/evilangel.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2cd90332e431258c9db21f0ab25f7c1395eab7 GIT binary patch literal 6670 zcmV+p8u8_cP)EX>4Tx04R}tkv&MmKp2MKrb32Q=L_ z)5(OG&8>=|SM(u_AkCP}EMrcRQt%yL_XzO)F3z+3>;4@5YTjZ%KqQ`JhG`RT5KnK~ z2Iqa^2rJ1d@i}qKqze*1a$WKGjdRgufoDd{OnRO;LM#?LSm|I^GBx5U;;5?WlrLmG zRyl8R)+#mDx+i~OIIpiPbDh=*l32tNB#2N@Lm3s=h|{izBx-kgE(v zjs;YqL3aJ%fAG7vR$+3&OA04|?ia`T7zIMRK(p>R-^Y&AJOP5wz?I(iR~x|0C+YRJ z7Ciz6wtmpj1FlOdb3D+Or@g#z$?M&FbJ25*7hHLq{2bDTZ^8R}K)1~@nb z#)_1^?(^=R&c6Ly)9T+39q)35L{9~^00006VoOIv03rY)03xjG6mb9m010qNS#tmY zE+YT{E+YYWr9XB6000McNliru;|mM}1tnEC(|!N|02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{02k&-L_t(|+U;F$Y+F^9|GoDdr>$6=iBrwDae_(dh!2)t z0;y+0&lYp>m*1>yZR42gooo6_ zq0YCde*dy%f>ROog*zk8%CLOUtI<$>z6#CrRn?!fJmV%JO3u%I!_U{_C7`N!o^rge zzs7J-)|N;l*v2jvi^yc;*1B;cPC9)i9M+!TT0<^}p2LSx$mjE~EG#Sp_KdpOr}ZY4 z3N8h44_m>;rQeT#W>Yyg9k&i4aBl&J#)*#T|rr!rfEga@l6xkImg#^y~q)w z2dZKEKmU3Df7>CtFg8Z3MB70$4Ic;5pzrUGANBG)nll`r#Dn-yE|g2&zf9$2L-~Zy zT(!rXq8(79(%gz4ggfOgUt9Tg@ZEAHw;nGi!@&6LZ2nH-2*%c+tS_JERf?*L$C)ql zf9HxcEH797QY;qnU6!E0YV9Pdiq|}SuQ?@)Xb=}~+K}+}i4?v978oZry|=$F-1)FD z+EGy-H6Hl4CAp}^{%(>9cW7_1J!pc6*JaCOi-@#RvRQ1MpPwfu4^}F8EC}n9g%RAy zrAtdgGT*l>al|4V=HY2vyM~WXpFZ6d=Tz5qHtQxxu-Yx^L7|PZIGr^&l1L;lKJE?j zXfonpZ(DaJ7nQ>2GOEmFArIqxxpa&M`(OGIiBjey9NNmgvO^RsYj!<)4l678n8V|& zR4Rc8eRIPI0I;yIfNa)#ghf>w&oLH@v5@!DX^c`wnc7t-lqr{ZRnT6}nrk1gL-VXR zn#x6Vn+_;cbfuE_=zwBJ`@$RkW)0;pfmhpeL|Tp9sB(%n)F6tdXfy=w3A|EP>|F$7 z{O5YRFbxB*bA|D%o~+*THL9vV-ekFq?SMB0Z<>{c5sS^6qbvsX#fwWMDS44d1o3#B z-100G3SEnfi}jv&f$@w;E7MpkhG;bEc^@px>N<1gj1Pu%Wk_}mH(5Z^hC}N3?X6sQM8UftS6(P22t$e{EbWo!_*#A^O29nDU1UH`rPbnp5$IpRg41OE>sa* zP^sX327_^2HhUrxiD1i?_!C^DO&|&&3d6v-s$#rSp(P2{i!9Ux0MTf4k6h}n20%wH zhn}lf@wlpDbY;aFpUeE6Up6u;c#EW$W3|qim{WfRszZV8I>}H;dq%##h>C3^ z6N|-OuJ>#uJh_pk5nNOu1JU2ZVS2+sQE)(Z3|^z5?)|MQW42lx*(|nFq@dn*8_jd7 zWh&IxOj|>Zg3BSxHF5uj*ou5bM8*CrXcun~ivXog?C;hp_7U-3hMyw)z3GXe!0)AP zN}s>=#&4LKLe>vboNdcx8_0?qrA!3{oIZWp6FXnDM;!cyY!+K(qb#vl41O35en<^s zg6w{@L#imn`>3k;y)TACx26pQ*&_{v!Y5L|s4TrGN{yr=MApPwk%lRxxGV17mcT

|$YdMH6%19)FWD;j7p#U!)ohbXHrzbi`y(i_eyz=1UU9>`K z5Yu;JKPWPtDit~C(Uswlnw}VnNcMDKXWYvuJ)$B|uoUUciq!PPkfyNCmUM;hobF;x*L#gtFUG%aCqqC&-dNw#LgElQapnxur- zym<=46#&*tZ;GiYd?11-;_>(!$t2Dy3e810KR@5nluXg@uPWta5@#ck2+8j?>(Mzu zDWMR(LZaxc!NI#|g;0?N+hISP&YBxZBofk)j61`DAb*~&S#TBd3i?_p_zfK$nzRGu%5czthlA{q5?Bsjw0Z`q z6Z^ZnHSG=Ihe92HOa8;ADP4bppWhICD8(<&N|d)>2T=f^EjrVxs(hv?z9{S0NC^ov zAn3FJq%bqQfZ}9DH1(Z@1C)> z^tQ_5ViIQL4~Af z&hV3s{(jjq0j-;*4KztKNdqIlVQ+unp%fp)Ffi^GqPS6+Y9yYNsCiNMPQ@pnAPcSr9lY*Ct@Zp}ih|ME*?d|C_dvF|l9#jA#D0-P znuJhA>cswTlKudM66AUit6se8&$=N*c7&c{o2&(S(xI)gk`99orErU3U|iJwun|P@ zjb{*|spUXX&ey{Q-0-4o#ND8T2HbSyYz9gRit?!ET@ZTgu4K!W_!E@b3lw}0a(}GC z)7M3G)?7ylLOvJ{6s?xYH;<_v1YHp*tKa zYhdLGqF5D5+&`1?H?u<2w5U-_U`l8}WVoz8ACW=Dp+G434fV#ApXI~{2lb=W&<(|Y zPzzPRi)PN6TcNrSRCbS)Ufc16oqa9>l{!8-;@C2qi4eJ}lu4pVp$&|rLwUpXe0li_ zb-^sZWM#!WL{TrXSd7X8_pO3tE{7fmrTkvA(FjVz1#pH^s1-;yi>(w5&FYo6U)+^Q zB!W$wkfa=wg6}~s6vdUioHaK>37t7a9PDifnsBAnQT2&;TLj8pdDkJbvX58c$t&dx z3(ThviCVlNk5^N}iOKK3sK9Tq41W_p=;g;lRajFwM#k!G4iNz|_XdZE_@N52ZcQ>cml+ z)QSDw-D>C`#AfRTeu#*s+axQ$A^1=Vk5EArb(a|l8O_gTSE8mxP9<|GA%aE*j0}|G zRh*!cW)+)X{05G)+W-w&kXktUT~PJnpyZb{X6D)EBe$eMHYpd%C73omEBk0j>%G06 zJjhu#xC(*%OkN>F%yFm`eiae6%q|}^c4p6UA8?Xr5@)wb`|`FXy1q9&f5y%u=g>wn zHHEAQqUi1Ig{I+TlR4)kd6d<#w(iS5h%QQ}lDT7JxU{$!!{Xv1kpXk-IdpC?#N^jp>}f>JmXhzK%iMtRh)Lsjwo3ok^4Ug+V&(JvMk z7o|LVj&jaae2-KL5*>{-06NlXjB-YAL}$&dP(x=SR*#e*4X#GMd$aZ*pD4F~0$i0I zMwmWmue=L%Iv83$WB?E-W%f4d6i^EA$96It%H_&OL7!u-+0}czkG}CG>{cn)q7p+~ zYZgH%n>RY4V|fLd-?LcATE?kXs0wd%DJXa z?7t;6ocb{NmLnljGCJd{QdVr%qDmx&Ya8(!rlydkz%jYSk7ie*6hXHob1AXrn++K! z%$cJ5Ad~WFif6!4-kNYfhWy@-Rtd$uKn&D1zm!~RdSWQ}-6qS@^+VX96v9jJ;>D%kw#z%hT`)vO0&k!Bk%Y*GZLlDRrZ_6aAi*wC6HVW zJ?GBN3n7ZZLH#H|7fz+(QKZutrEXTVDk2ttvn=@Wah&{&s6<)Kpn1*-bJjHaOS%=x zgChNtBl-dalPt*PSjdjSWxTC*L+>IOx9#{1)td>YXzT_=od}VaEfWZB81r*^sp-A_ zf#)|67_J4=S_t}4yLL@n9dd9`KRP*yM=5{v;>Fn06h)CNOD6Zdu{g2#y_C$=b-hTT zc&i4@9gdhYwLwMEk<^RwpnwB7qAx)u3vviW1{0U@b_-OY0T0WYBcV^wj$((1I%MK| zPK3yURXON8oKr2NB_(9-#~TYle+nhgFoj`Ye0DZ}XQRI-5(!Wn4M6alU74o%qV%Ga zsdDv;#Ue5p4BK|&IZ}2XtW&l7;m>24yozA z{lWr9E~J_Umu`y(v&Km$QRIE$&WIBs(%6}OwgoGcSIW%YCP@reMkqyAayj(O&(9wg zeWtThyPxG{SMevJ%X>T1{2r%P%9M?LOcUEFp%j;1=UslE(R3Q46kHY#I4h`RK@OoP zzQtj@{pL5gEp&@VDrq=Sr@^JB_x7Vwx)&9UA*B5ir%__;ICSpSlPP}3U+H+X6$g<- zDQjTlH^>{V03DQ4E#$Sd3l)sP#{U@)Wu>8|YuE6(C>*cr`WqaWWbMK{3qabFv~3=! zLd4?ts+1=t@ZPCYRQp$XnHoxQVN7k69bT1poVdwT*AQ}X?6zsWy{3v1U!I7QX@qAo(e>zl%aO=!B7N->wlL^NS#Q& z?M*Wve#6-dg|J$h`+P-_zQ7FwuZu3eTJ8MjxVE?Eee9#TylI?$NEzSY~?3&TLh%Xbw8!$1`#o12^OsyAYWhxKDOXh==5pOl?!O*!>> z{CdOhnNSY;@sbrxYvFb+)XQa*_)UnURLZq%1x{YZE~4}IQ&MBER9Y||lIyaW$zV92 z&o@-skw^sLFmE~MjT`AA8QCnhQWDIZnik1a`K#sZvpOBr-3RLoCbFy=QP)+5d6P%Y zs2WL0>_ZoTI~zTJO2d(Y-%x9a_YCDT7#Ps!cJIdjsN^0gm-tyEiOVQy1tF49DRXBl zkU%LMqTnr=ujg{;acW={kH_EOW_nXr%A@E`c$0@JY-}YncRzCWxe5w#VAOsHN4g_- z)l#|Vq`g2n9tFRFLu?zb0rlia>+9V?eJJP4rDMJoNn&E;w~!DC0O;1Vhl9E|Rl{{+ zD2RsZWy=KAs8p?uYuE6xCN(Hm-7wz4YJuFe)J^ZGEQ0vf5`Ou zpf-YYIrLEQ8@TrAw%fcx0&9t3V4Q;AKrOXqo>gw;0e@Yq6Q&o%yah;ntM}PUv z9D!Ot1wqT_R?3BPiMgTD%}e&Wq*S+cV8Atagt4&@E8||qLCyL2`CEw z)ysFk`syq4`7A9h?L$CCRUOZ-Ysux%BZ|JY_A0Ex6yHW1Y%{PPy-C0VZ|)W&DgsrL zTB!S}mMP`qlOuiMa36v!m8BPh7!f&NUcTZr{ns#XAfL~_?B=tYhJqjK@u~;}29NZ3 zwSFB#4u-{cg1NFq1h@+djg8^b#*NzDTq%xg84Zz$_IEcr zYen%CZD_`50Q@QPV;FdynpHnLn~%%DA8uQU7Ya+#M6qy~&v5XgpinZ2v#AuKx~}gT z7|`cr_y?lMiLUE!L?YVv$Hs6;riO%J(1hD-1=C(eK!uVNnaN<7s-FzG8nM5PHUPl? Y180KBMUmW-6951J07*qoM6N<$f@$%%*8l(j literal 0 HcmV?d00001 diff --git a/public/img/logos/evilangel/network.png b/public/img/logos/evilangel/network.png new file mode 100644 index 0000000000000000000000000000000000000000..d2a7833aa3c09c0fe0607e97ac62f4e48f3daa26 GIT binary patch literal 6670 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 Y180KBMUmW-6951J07*qoM6N<$f=I2p2><{9 literal 0 HcmV?d00001 diff --git a/seeds/02_tags.js b/seeds/02_tags.js index ab7b1317..f0943267 100644 --- a/seeds/02_tags.js +++ b/seeds/02_tags.js @@ -1399,6 +1399,10 @@ function getTagAliases(tagsMap) { name: 'tittyfuck', alias_for: tagsMap['titty-fuck'], }, + { + name: 'tp', + alias_for: tagsMap['triple-penetration'], + }, { name: 'trans', alias_for: tagsMap['transsexual'], @@ -1408,8 +1412,8 @@ function getTagAliases(tagsMap) { alias_for: tagsMap['trimmed'], }, { - name: 'tp', - alias_for: tagsMap['triple-penetration'], + name: 'ts', + alias_for: tagsMap['transsexual'], }, { name: 'whipping', diff --git a/src/actors.js b/src/actors.js index df04e07b..e436c6e3 100644 --- a/src/actors.js +++ b/src/actors.js @@ -1,6 +1,7 @@ 'use strict'; const knex = require('./knex'); +const whereOr = require('./utils/where-or'); async function curateActor(actor) { const aliases = await knex('actors') @@ -26,10 +27,9 @@ function curateActors(releases) { return Promise.all(releases.map(async release => curateActor(release))); } -async function fetchActors(actorId, actorSlug) { +async function fetchActors(queryObject) { const releases = await knex('actors') - .where({ id: actorId }) - .orWhere({ slug: actorSlug }) + .where(builder => whereOr(queryObject, 'actors', builder)) .limit(100); return curateActors(releases); diff --git a/src/networks.js b/src/networks.js index 0af65db2..14d509e4 100644 --- a/src/networks.js +++ b/src/networks.js @@ -1,6 +1,7 @@ 'use strict'; const knex = require('./knex'); +const whereOr = require('./utils/where-or'); async function curateNetwork(network) { const [sites, studios] = await Promise.all([ @@ -44,10 +45,9 @@ function curateNetworks(releases) { return Promise.all(releases.map(async release => curateNetwork(release))); } -async function fetchNetworks(networkId, networkSlug) { +async function fetchNetworks(queryObject) { const releases = await knex('networks') - .where({ id: networkId }) - .orWhere({ slug: networkSlug }) + .where(builder => whereOr(queryObject, 'networks', builder)) .limit(100); return curateNetworks(releases); diff --git a/src/releases.js b/src/releases.js index 7ccd1987..f4dee5e7 100644 --- a/src/releases.js +++ b/src/releases.js @@ -66,18 +66,29 @@ function curateReleases(releases) { return Promise.all(releases.map(async release => curateRelease(release))); } -async function fetchReleases(releaseId) { +async function fetchReleases(releaseId, filter = []) { + // const straightFilter = filter.includes('straight') ? ['gay', 'lesbian'] : []; + const releases = await knex('releases') - .where(releaseId ? { 'releases.id': releaseId } : {}) + .leftJoin('sites', 'releases.site_id', 'sites.id') + .leftJoin('studios', 'releases.studio_id', 'studios.id') + .leftJoin('networks', 'sites.network_id', 'networks.id') .select( 'releases.*', 'sites.name as site_name', 'sites.slug as site_slug', 'sites.url as site_url', 'sites.network_id', 'studios.name as studio_name', 'sites.slug as site_slug', 'studios.url as studio_url', 'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url', ) - .leftJoin('sites', 'releases.site_id', 'sites.id') - .leftJoin('studios', 'releases.studio_id', 'studios.id') - .leftJoin('networks', 'sites.network_id', 'networks.id') + .whereNotExists((builder) => { + // apply filters + builder + .select('*') + .from('tags_associated') + .leftJoin('tags', 'tags_associated.tag_id', 'tags.id') + .whereIn('tags.slug', filter) + .andWhereRaw('tags_associated.release_id = releases.id'); + }) + .andWhere(releaseId ? { 'releases.id': releaseId } : {}) .orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }]) .limit(100); diff --git a/src/scrapers/xempire.js b/src/scrapers/xempire.js index 2d3af903..f97e226c 100644 --- a/src/scrapers/xempire.js +++ b/src/scrapers/xempire.js @@ -8,6 +8,13 @@ const moment = require('moment'); const { matchTags } = require('../tags'); +const defaultTags = { + hardx: [], + darkx: ['interracial'], + eroticax: [], + lesbianx: ['lesbian'], +}; + async function fetchPhotos(url) { const res = await bhttp.get(url); @@ -144,7 +151,7 @@ async function scrapeScene(html, url, site) { .orWhere({ slug: siteId }) .first() : site, - matchTags(rawTags), + matchTags([...defaultTags[siteId], ...rawTags]), ]); return { diff --git a/src/sites.js b/src/sites.js index 62786009..2f75bb7c 100644 --- a/src/sites.js +++ b/src/sites.js @@ -23,9 +23,9 @@ function curateSites(sites) { return Promise.all(sites.map(async site => curateSite(site))); } -async function fetchSites(query) { +async function fetchSites(queryObject) { const sites = await knex('sites') - .where(builder => whereOr(query, builder)) + .where(builder => whereOr(queryObject, 'sites', builder)) .select( 'sites.*', 'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url', diff --git a/src/tags.js b/src/tags.js index 935c6090..f505de04 100644 --- a/src/tags.js +++ b/src/tags.js @@ -1,6 +1,7 @@ 'use strict'; const knex = require('./knex'); +const whereOr = require('./utils/where-or'); async function curateTag(tag) { const aliases = await knex('tags').where({ alias_for: tag.id }); @@ -30,10 +31,9 @@ async function storeTags(release, releaseEntry) { }))); } -async function fetchTags(tagId, tagSlug) { +async function fetchTags(queryObject) { const tags = await knex('tags') - .where({ 'tags.id': tagId }) - .orWhere({ 'tags.slug': tagSlug }) + .where(builder => whereOr(queryObject, 'tags', builder)) .andWhere({ 'tags.alias_for': null }) .select( 'tags.*', diff --git a/src/utils/where-or.js b/src/utils/where-or.js index ef4553bf..c4cf8c5f 100644 --- a/src/utils/where-or.js +++ b/src/utils/where-or.js @@ -1,9 +1,9 @@ 'use strict'; -function whereOr(query, builder) { +function whereOr(query, table, builder) { Object.entries(query).forEach(([key, value]) => { if (value !== undefined) { - builder.orWhere(`sites.${key}`, value); + builder.orWhere(`${table}.${key}`, value); } }); } diff --git a/src/web/actors.js b/src/web/actors.js index 81f32dac..daadbe15 100644 --- a/src/web/actors.js +++ b/src/web/actors.js @@ -6,7 +6,10 @@ 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(actorId, actorSlug); + const actors = await fetchActors({ + id: actorId, + slug: actorSlug, + }); res.send(actors); } diff --git a/src/web/networks.js b/src/web/networks.js index d77dac43..909afd18 100644 --- a/src/web/networks.js +++ b/src/web/networks.js @@ -3,10 +3,13 @@ const { fetchNetworks, fetchNetworksFromReleases } = require('../networks'); async function fetchNetworksApi(req, res) { - const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : null; - const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : null; + const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : undefined; // null will literally include NULL results + const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : undefined; - const networks = await fetchNetworks(networkId, networkSlug); + const networks = await fetchNetworks({ + id: networkId, + slug: networkSlug, + }); res.send(networks); } diff --git a/src/web/releases.js b/src/web/releases.js index 5b612a70..b970e54d 100644 --- a/src/web/releases.js +++ b/src/web/releases.js @@ -9,7 +9,7 @@ const { } = require('../releases'); async function fetchReleasesApi(req, res) { - const releases = await fetchReleases(req.params.releaseId); + const releases = await fetchReleases(req.params.releaseId, req.query.filter ? [].concat(req.query.filter) : []); res.send(releases); } diff --git a/src/web/tags.js b/src/web/tags.js index f2073b31..4a3966da 100644 --- a/src/web/tags.js +++ b/src/web/tags.js @@ -3,10 +3,13 @@ const { fetchTags } = require('../tags'); async function fetchTagsApi(req, res) { - const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : null; - const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : null; + const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : undefined; // null will literally include NULL results + const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : undefined; - const tags = await fetchTags(tagId, tagSlug); + const tags = await fetchTags({ + id: tagId, + slug: tagSlug, + }); res.send(tags); }