diff --git a/assets/components/home/home.vue b/assets/components/home/home.vue
index d621739b..f3eec400 100644
--- a/assets/components/home/home.vue
+++ b/assets/components/home/home.vue
@@ -13,7 +13,7 @@ import FilterBar from '../header/filter-bar.vue';
import Releases from '../releases/releases.vue';
async function fetchReleases() {
- this.releases = await this.$store.dispatch('fetchReleases', { limit: 20 });
+ this.releases = await this.$store.dispatch('fetchReleases', { limit: 50 });
this.$store.commit('setCache', {
target: 'home',
releases: this.releases,
diff --git a/assets/components/tile/release.vue b/assets/components/tile/release.vue
index 2257b850..97a6a630 100644
--- a/assets/components/tile/release.vue
+++ b/assets/components/tile/release.vue
@@ -69,14 +69,14 @@
>
diff --git a/assets/js/fragments.js b/assets/js/fragments.js
index 1a700945..92d79bf3 100644
--- a/assets/js/fragments.js
+++ b/assets/js/fragments.js
@@ -125,6 +125,7 @@ const releaseFields = `
date
slug
type
+ batch
createdAt
url
${releaseActorsFragment}
diff --git a/assets/js/releases/actions.js b/assets/js/releases/actions.js
index 35672040..8bd1302a 100644
--- a/assets/js/releases/actions.js
+++ b/assets/js/releases/actions.js
@@ -40,6 +40,7 @@ function initReleasesActions(store, _router) {
title
date
url
+ batch
site {
id
slug
diff --git a/migrations/20190325001339_releases.js b/migrations/20190325001339_releases.js
index d0e6c13e..df0439af 100644
--- a/migrations/20190325001339_releases.js
+++ b/migrations/20190325001339_releases.js
@@ -33,10 +33,10 @@ exports.up = knex => Promise.resolve()
table.integer('height', 6);
table.float('entropy');
- table.text('comment');
table.string('scraper', 32);
table.string('copyright', 100);
table.string('source', 1000);
+ table.text('comment');
table.unique('hash');
table.unique('source');
@@ -359,6 +359,7 @@ exports.up = knex => Promise.resolve()
table.boolean('deep');
table.string('deep_url', 1000);
+ table.string('batch');
table.datetime('created_at')
.defaultTo(knex.fn.now());
}))
diff --git a/package-lock.json b/package-lock.json
index d8b44761..89adbed1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -828,6 +828,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.8.3.tgz",
"integrity": "sha512-0QEgn2zkCzqGIkSWWAEmvxD7e00Nm9asTtQvi7HdlYvMhjy/J38V/1Y9ode0zEJeIuxAI0uftiAzqc7nVeWUGg==",
+ "dev": true,
"requires": {
"core-js": "^2.6.5",
"regenerator-runtime": "^0.13.2"
@@ -836,7 +837,8 @@
"regenerator-runtime": {
"version": "0.13.3",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
- "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
+ "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==",
+ "dev": true
}
}
},
@@ -1072,11 +1074,6 @@
"@types/node": "*"
}
},
- "@types/bluebird": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.29.tgz",
- "integrity": "sha512-kmVtnxTuUuhCET669irqQmPAez4KFnFVKvpleVRyfC3g+SHD1hIkFZcWLim9BVcwUBLO59o8VZE4yGCmTif8Yw=="
- },
"@types/body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
@@ -1829,15 +1826,15 @@
"dev": true
},
"babel-eslint": {
- "version": "10.0.3",
- "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz",
- "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
+ "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@babel/parser": "^7.0.0",
- "@babel/traverse": "^7.0.0",
- "@babel/types": "^7.0.0",
+ "@babel/parser": "^7.7.0",
+ "@babel/traverse": "^7.7.0",
+ "@babel/types": "^7.7.0",
"eslint-visitor-keys": "^1.0.0",
"resolve": "^1.12.0"
}
@@ -2476,6 +2473,15 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
+ "casual": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/casual/-/casual-1.6.2.tgz",
+ "integrity": "sha512-NQObL800rg32KZ9bBajHbyDjxLXxxuShChQg7A4tbSeG3n1t7VYGOSkzFSI9gkSgOHp+xilEJ7G0L5l6M30KYA==",
+ "requires": {
+ "mersenne-twister": "^1.0.1",
+ "moment": "^2.15.2"
+ }
+ },
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2692,9 +2698,9 @@
}
},
"colorette": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.0.7.tgz",
- "integrity": "sha512-KeK4klsvAgdODAjFPm6QLzvStizJqlxMBtVo4KQMCgk5tt/tf9rAzxmxLHNRynJg3tJjkKGKbHx3j4HLox27Lw=="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz",
+ "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg=="
},
"colornames": {
"version": "1.1.1",
@@ -3175,9 +3181,9 @@
}
},
"dayjs": {
- "version": "1.8.20",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.20.tgz",
- "integrity": "sha512-mH0MCDxw6UCGJYxVN78h8ugWycZAO8thkj3bW6vApL5tS0hQplIDdAQcmbvl7n35H0AKdCJQaArTrIQw2xt4Qg=="
+ "version": "1.8.21",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.21.tgz",
+ "integrity": "sha512-1kbWK0hziklUHkGgiKr7xm59KwAg/K3Tp7H/8X+f58DnNCwY3pKYjOCJpIlVs125FRBukGVZdKZojC073D0IeQ=="
},
"de-indent": {
"version": "1.0.2",
@@ -4013,6 +4019,11 @@
}
}
},
+ "esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="
+ },
"espree": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
@@ -5354,9 +5365,9 @@
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
"getopts": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.3.tgz",
- "integrity": "sha512-viEcb8TpgeG05+Nqo5EzZ8QR0hxdyrYDp6ZSTZqe2M/h53Bk036NmqG38Vhf5RGirC/Of9Xql+v66B2gp256SQ=="
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz",
+ "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA=="
},
"getpass": {
"version": "0.1.7",
@@ -6021,7 +6032,8 @@
"interpret": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
- "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw=="
+ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
+ "dev": true
},
"invariant": {
"version": "2.2.4",
@@ -6513,29 +6525,33 @@
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="
},
"knex": {
- "version": "0.16.5",
- "resolved": "https://registry.npmjs.org/knex/-/knex-0.16.5.tgz",
- "integrity": "sha512-1RVxMU8zGOBqgmXlAvs8vohg9MD14iiRZZPe0IeQXd554n4xxPmoMkbH4hlFeqfM6eOdFE3AVqVSncL3YuocqA==",
+ "version": "0.20.10",
+ "resolved": "https://registry.npmjs.org/knex/-/knex-0.20.10.tgz",
+ "integrity": "sha512-07D6fvY5NdvrfRPmkLLG+OrHvmAy55OX7eXkN8TMiOOI5lWJh1dC2zKjeEQJqUILMOsTnZCGqTKGaRm4t1E9xg==",
"requires": {
- "@babel/polyfill": "^7.4.3",
- "@types/bluebird": "^3.5.26",
- "bluebird": "^3.5.4",
- "colorette": "1.0.7",
- "commander": "^2.20.0",
+ "bluebird": "^3.7.2",
+ "colorette": "1.1.0",
+ "commander": "^4.1.1",
"debug": "4.1.1",
- "getopts": "2.2.3",
- "inherits": "~2.0.3",
- "interpret": "^1.2.0",
+ "esm": "^3.2.25",
+ "getopts": "2.2.5",
+ "inherits": "~2.0.4",
+ "interpret": "^2.0.0",
"liftoff": "3.1.0",
- "lodash": "^4.17.11",
+ "lodash": "^4.17.15",
"mkdirp": "^0.5.1",
- "pg-connection-string": "2.0.0",
- "tarn": "^1.1.5",
- "tildify": "1.2.0",
- "uuid": "^3.3.2",
- "v8flags": "^3.1.2"
+ "pg-connection-string": "2.1.0",
+ "tarn": "^2.0.0",
+ "tildify": "2.0.0",
+ "uuid": "^3.4.0",
+ "v8flags": "^3.1.3"
},
"dependencies": {
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="
+ },
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -6544,6 +6560,16 @@
"ms": "^2.1.1"
}
},
+ "interpret": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.0.0.tgz",
+ "integrity": "sha512-e0/LknJ8wpMMhTiWcjivB+ESwIuvHnBSlBbmP/pSb8CQJldoj1p2qv7xGZ/+BtbTziYRFSz8OsvdbiX45LtYQA=="
+ },
+ "pg-connection-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.1.0.tgz",
+ "integrity": "sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg=="
+ },
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@@ -7073,6 +7099,11 @@
}
}
},
+ "mersenne-twister": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz",
+ "integrity": "sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o="
+ },
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -7294,6 +7325,11 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
},
+ "nanoid": {
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz",
+ "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA=="
+ },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -8811,9 +8847,9 @@
}
},
"react": {
- "version": "16.12.0",
- "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz",
- "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==",
+ "version": "16.13.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz",
+ "integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
@@ -8821,14 +8857,14 @@
}
},
"react-dom": {
- "version": "16.12.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz",
- "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==",
+ "version": "16.13.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz",
+ "integrity": "sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
- "scheduler": "^0.18.0"
+ "scheduler": "^0.19.0"
}
},
"react-is": {
@@ -9495,9 +9531,9 @@
}
},
"scheduler": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz",
- "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==",
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.0.tgz",
+ "integrity": "sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
@@ -10613,9 +10649,9 @@
}
},
"tarn": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/tarn/-/tarn-1.1.5.tgz",
- "integrity": "sha512-PMtJ3HCLAZeedWjJPgGnCvcphbCOMbtZpjKgLq3qM5Qq9aQud+XHrL0WlrlgnTyS8U+jrjGbEXprFcQrxPy52g=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tarn/-/tarn-2.0.0.tgz",
+ "integrity": "sha512-7rNMCZd3s9bhQh47ksAQd92ADFcJUjjbyOvyFjNLwTPpGieFHMC84S+LOzw0fx1uh6hnDz/19r8CPMnIjJlMMA=="
},
"template-format": {
"version": "1.2.5",
@@ -10742,12 +10778,9 @@
}
},
"tildify": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",
- "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=",
- "requires": {
- "os-homedir": "^1.0.0"
- }
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
+ "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw=="
},
"timers-browserify": {
"version": "2.0.11",
@@ -11030,6 +11063,11 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
+ "txtgen": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/txtgen/-/txtgen-2.2.4.tgz",
+ "integrity": "sha512-eVt2Luabn0BG6K3DfHkqEBkldVYpAKgneVteEljzM5a0gLoff6sZI9SQMCm0GSyYhQQiSgiJ4HZaV9iYR+gm4g=="
+ },
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -11387,9 +11425,9 @@
"integrity": "sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg=="
},
"vue-router": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.5.tgz",
- "integrity": "sha512-BszkPvhl7I9h334GjckCh7sVFyjTPMMJFJ4Bsrem/Ik+B/9gt5tgrk8k4gGLO4ZpdvciVdg7O41gW4DisQWurg=="
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.6.tgz",
+ "integrity": "sha512-GYhn2ynaZlysZMkFE5oCHRUTqE8BWs/a9YbKpNLi0i7xD6KG1EzDqpHQmv1F5gXjr8kL5iIVS8EOtRaVUEXTqA=="
},
"vue-style-loader": {
"version": "4.1.2",
diff --git a/package.json b/package.json
index 8b6f3ec4..bd846fc1 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
"@babel/preset-env": "^7.8.4",
"@babel/register": "^7.8.3",
"autoprefixer": "^9.7.4",
- "babel-eslint": "^10.0.3",
+ "babel-eslint": "^10.1.0",
"babel-loader": "^8.0.6",
"babel-preset-airbnb": "^3.3.2",
"css-loader": "^2.1.1",
@@ -75,10 +75,11 @@
"bluebird": "^3.7.2",
"body-parser": "^1.19.0",
"canvas": "^2.6.1",
+ "casual": "^1.6.2",
"cheerio": "^1.0.0-rc.3",
"cli-confirm": "^1.0.1",
"config": "^3.2.5",
- "dayjs": "^1.8.20",
+ "dayjs": "^1.8.21",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"express-react-views": "^0.11.0",
@@ -87,11 +88,12 @@
"graphile-utils": "^4.5.6",
"iconv-lite": "^0.5.1",
"jsdom": "^15.2.1",
- "knex": "^0.16.5",
+ "knex": "^0.20.10",
"knex-migrate": "^1.7.4",
"longjohn": "^0.2.12",
"mime": "^2.4.4",
"moment": "^2.24.0",
+ "nanoid": "^2.1.11",
"opencv4nodejs": "^5.5.0",
"opn": "^5.5.0",
"pg": "^7.18.1",
@@ -99,18 +101,19 @@
"postgraphile-plugin-connection-filter": "^1.1.3",
"promise-task-queue": "^1.2.0",
"prop-types": "^15.7.2",
- "react": "^16.12.0",
- "react-dom": "^16.12.0",
+ "react": "^16.13.0",
+ "react-dom": "^16.13.0",
"sharp": "^0.23.4",
"showdown": "^1.9.1",
"source-map-support": "^0.5.16",
"template-format": "^1.2.5",
"tough-cookie": "^3.0.1",
"tty-table": "^2.8.12",
+ "txtgen": "^2.2.4",
"url-pattern": "^1.0.3",
"v-tooltip": "^2.0.3",
"vue": "^2.6.11",
- "vue-router": "^3.1.5",
+ "vue-router": "^3.1.6",
"vuex": "^3.1.2",
"winston": "^3.2.1",
"winston-daily-rotate-file": "^4.4.2",
diff --git a/seeds/ignore/99_fake.js b/seeds/ignore/99_fake.js
new file mode 100644
index 00000000..e3372cb7
--- /dev/null
+++ b/seeds/ignore/99_fake.js
@@ -0,0 +1,95 @@
+const txtgen = require('txtgen');
+const casual = require('casual');
+const nanoid = require('nanoid');
+
+const capitalize = require('../src/utils/capitalize');
+const slugify = require('../src/utils/slugify');
+
+async function updateReleasesSearch(releaseIds, knex) {
+ const documents = await knex.raw(`
+ SELECT
+ releases.id as release_id,
+ to_tsvector(
+ releases.title || ' ' ||
+ sites.name || ' ' ||
+ sites.slug || ' ' ||
+ replace(CAST(releases.date AS VARCHAR), '-', ' ') || ' ' ||
+ string_agg(actors.name, ' ') || ' ' ||
+ string_agg(tags.name, ' ')
+ ) as document
+ FROM releases
+ LEFT JOIN releases_actors AS local_actors ON local_actors.release_id = releases.id
+ JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id
+ JOIN sites ON releases.site_id = sites.id
+ LEFT JOIN actors ON local_actors.actor_id = actors.id
+ JOIN tags ON local_tags.tag_id = tags.id
+ GROUP BY releases.id, sites.name, sites.slug;
+ `);
+
+ const query = knex('releases_search').insert(documents.rows).toString();
+ return knex.raw(`${query} ON CONFLICT (release_id) DO UPDATE SET document = EXCLUDED.document`);
+}
+
+exports.seed = async knex => Promise.resolve()
+ .then(async () => {
+ const [sites, tags, media] = await Promise.all([
+ knex('sites').select('*'),
+ knex('tags').select('*').where('alias_for', null),
+ knex('media').select('*'),
+ ]);
+
+ const releases = Array.from({ length: 1000 }, () => {
+ const title = txtgen.sentence();
+ const site = casual.random_value(sites);
+
+ return {
+ entry_id: nanoid(),
+ title,
+ slug: slugify(title, { limit: 50 }),
+ site_id: site.id,
+ date: new Date(Math.random() * (new Date().getTime() - 1500000000000) + 1500000000000),
+ batch: 'dummy',
+ };
+ });
+
+ const actors = Array.from({ length: 100 }, () => {
+ const name = capitalize(casual.full_name);
+ const slug = slugify(name);
+
+ return {
+ name,
+ slug,
+ gender: casual.random_element(['male', 'female']),
+ };
+ });
+
+ const uniqueActors = Object.values(actors.reduce((acc, actor) => ({ ...acc, [actor.slug]: actor }), {}));
+
+ const releaseIds = await knex('releases').insert(releases).returning('id');
+ const actorIds = await knex('actors').insert(uniqueActors).returning('id');
+
+ const actorAssociations = releaseIds.map((releaseId) => {
+ const releaseActorIds = Array.from({ length: Math.floor(Math.random() * 3) + 1 }, () => casual.random_value(actorIds));
+
+ return Array.from(new Set(releaseActorIds)).map(actorId => ({ release_id: releaseId, actor_id: actorId }));
+ }).flat();
+
+ const tagAssociations = releaseIds.map((releaseId) => {
+ const releaseTags = Array.from({ length: Math.floor(Math.random() * 20) }, () => casual.random_value(tags));
+
+ return Array.from(new Set(releaseTags)).map(tag => ({ release_id: releaseId, tag_id: tag.id }));
+ }).flat();
+
+ const posterAssociations = releaseIds.map(releaseId => ({
+ release_id: releaseId,
+ media_id: casual.random_value(media).id,
+ }));
+
+ await Promise.all([
+ knex('releases_actors').insert(actorAssociations),
+ knex('releases_tags').insert(tagAssociations),
+ knex('releases_posters').insert(posterAssociations),
+ ]);
+
+ await updateReleasesSearch(releaseIds, knex);
+ });
diff --git a/src/argv.js b/src/argv.js
index 56724664..294450ac 100644
--- a/src/argv.js
+++ b/src/argv.js
@@ -161,6 +161,11 @@ const { argv } = yargs
describe: 'Show error stack traces',
type: 'boolean',
default: process.env.NODE_ENV === 'development',
+ })
+ .option('dummy', {
+ describe: 'Generate dummy data during seed',
+ type: 'boolean',
+ default: false,
});
module.exports = argv;
diff --git a/src/utils/pick-random.js b/src/utils/pick-random.js
new file mode 100644
index 00000000..729d5c51
--- /dev/null
+++ b/src/utils/pick-random.js
@@ -0,0 +1,5 @@
+function pickRandom(array) {
+ return array[Math.floor(Math.random() * array.length)];
+}
+
+module.exports = pickRandom;