From fbd52ddf58dfc6112592ae9fca40139e5ce4ffbd Mon Sep 17 00:00:00 2001 From: ilim Date: Sat, 14 Sep 2019 00:51:23 +0900 Subject: [PATCH 01/60] Fixed bugs due to connect-redis specification changes --- web/src/main.js | 3 +- web/src/package-lock.json | 272 +++++++++++++++++++++++++++++--------- web/src/package.json | 1 + 3 files changed, 209 insertions(+), 67 deletions(-) diff --git a/web/src/main.js b/web/src/main.js index 82ada40..31213d1 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -9,6 +9,7 @@ const querystring = require('querystring'); const proxy = require('proxy-middleware'); const session = require('express-session'); +const Redis = require('ioredis'); const RedisStore = require('connect-redis')(session); @@ -63,7 +64,7 @@ app.set('view engine', 'ejs'); app.use( session({ store: new RedisStore({ - host: 'redis', + client: new Redis({ host: 'redis' }), prefix: 'web:', }), secret: process.env.SESSION_SECRET, diff --git a/web/src/package-lock.json b/web/src/package-lock.json index a041ae9..b4cc5b2 100644 --- a/web/src/package-lock.json +++ b/web/src/package-lock.json @@ -511,6 +511,11 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, + "cluster-key-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", + "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -745,6 +750,11 @@ } } }, + "denque": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", + "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1518,25 +1528,29 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "optional": true, "requires": { @@ -1546,13 +1560,15 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, "requires": { @@ -1562,37 +1578,43 @@ }, "chownr": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "optional": true, "requires": { @@ -1601,25 +1623,29 @@ }, "deep-extend": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, "requires": { @@ -1628,13 +1654,15 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, "requires": { @@ -1650,7 +1678,8 @@ }, "glob": { "version": "7.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "optional": true, "requires": { @@ -1664,13 +1693,15 @@ }, "has-unicode": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "bundled": true, + "resolved": false, + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "optional": true, "requires": { @@ -1679,7 +1710,8 @@ }, "ignore-walk": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, "requires": { @@ -1688,7 +1720,8 @@ }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, "requires": { @@ -1698,19 +1731,22 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, "requires": { @@ -1719,13 +1755,15 @@ }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, "requires": { @@ -1734,13 +1772,15 @@ }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true, "optional": true }, "minipass": { "version": "2.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "optional": true, "requires": { @@ -1750,7 +1790,8 @@ }, "minizlib": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "dev": true, "optional": true, "requires": { @@ -1759,7 +1800,8 @@ }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "optional": true, "requires": { @@ -1768,13 +1810,15 @@ }, "ms": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true, "optional": true }, "needle": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", "dev": true, "optional": true, "requires": { @@ -1785,7 +1829,8 @@ }, "node-pre-gyp": { "version": "0.12.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, "requires": { @@ -1803,7 +1848,8 @@ }, "nopt": { "version": "4.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, "requires": { @@ -1813,13 +1859,15 @@ }, "npm-bundled": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "optional": true, "requires": { @@ -1829,7 +1877,8 @@ }, "npmlog": { "version": "4.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, "requires": { @@ -1841,19 +1890,22 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, "requires": { @@ -1862,19 +1914,22 @@ }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, "requires": { @@ -1884,19 +1939,22 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "bundled": true, + "resolved": false, + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, "requires": { @@ -1908,7 +1966,8 @@ "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true } @@ -1916,7 +1975,8 @@ }, "readable-stream": { "version": "2.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, "requires": { @@ -1931,7 +1991,8 @@ }, "rimraf": { "version": "2.6.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "optional": true, "requires": { @@ -1940,43 +2001,50 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, "requires": { @@ -1987,7 +2055,8 @@ }, "string_decoder": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, "requires": { @@ -1996,7 +2065,8 @@ }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, "requires": { @@ -2005,13 +2075,15 @@ }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.8", - "bundled": true, + "resolved": false, + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, "optional": true, "requires": { @@ -2026,13 +2098,15 @@ }, "util-deprecate": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "optional": true, "requires": { @@ -2041,13 +2115,15 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true, "optional": true } @@ -2376,6 +2452,45 @@ "through": "^2.3.6" } }, + "ioredis": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.14.1.tgz", + "integrity": "sha512-94W+X//GHM+1GJvDk6JPc+8qlM7Dul+9K+lg3/aHixPN7ZGkW6qlvX0DG6At9hWtH2v3B32myfZqWoANUJYGJA==", + "requires": { + "cluster-key-slot": "^1.1.0", + "debug": "^4.1.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "redis-commands": "1.5.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "requires": { + "redis-errors": "^1.0.0" + } + } + } + }, "ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", @@ -2733,6 +2848,16 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -3501,6 +3626,16 @@ "readable-stream": "^2.0.2" } }, + "redis-commands": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.5.0.tgz", + "integrity": "sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==" + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" + }, "referrer-policy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", @@ -3972,6 +4107,11 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "standard-as-callback": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.0.1.tgz", + "integrity": "sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg==" + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", diff --git a/web/src/package.json b/web/src/package.json index be0d2cb..aa8cad3 100644 --- a/web/src/package.json +++ b/web/src/package.json @@ -18,6 +18,7 @@ "express": "^4.17.1", "express-session": "^1.16.2", "helmet": "^3.21.0", + "ioredis": "^4.14.1", "morgan": "^1.9.1", "proxy-middleware": "^0.15.0" }, From 9e06a37a43712372be2ce1e90d5dbcd1b1ef439e Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 18 Sep 2019 01:51:06 +0900 Subject: [PATCH 02/60] Add dockerignore --- media/.dockerignore | 2 ++ tunnel/.dockerignore | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 media/.dockerignore create mode 100644 tunnel/.dockerignore diff --git a/media/.dockerignore b/media/.dockerignore new file mode 100644 index 0000000..2d71cf8 --- /dev/null +++ b/media/.dockerignore @@ -0,0 +1,2 @@ +src/node_modules +src/.venv diff --git a/tunnel/.dockerignore b/tunnel/.dockerignore new file mode 100644 index 0000000..2d71cf8 --- /dev/null +++ b/tunnel/.dockerignore @@ -0,0 +1,2 @@ +src/node_modules +src/.venv From 2bf64cb9b38550291805975b12bd2bf62d6af39c Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 25 Sep 2019 16:02:45 +0900 Subject: [PATCH 03/60] Fix --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4db5c85..e176f07 100644 --- a/README.md +++ b/README.md @@ -144,20 +144,20 @@ URL が`https://app.slack.com/client/VYS39C27C/UC7CHE35J`のようになって `.env`ファイルに以下の様に書き保存してください。 ```text -AWS_REST_API_ID="j3i..." # 二回目以降に必要 -AWS_ACCESS_KEY_ID="FUB..." -AWS_SECRET_ACCESS_KEY="vKw..." +AWS_REST_API_ID=j3i... # 二回目以降に必要 +AWS_ACCESS_KEY_ID=FUB... +AWS_SECRET_ACCESS_KEY=vKw... -NGROK_AUTH="8HU..." +NGROK_AUTH=8HU... -SESSION_SECRET="presetprivatekey" # 暗に暗号化へ使う任意の頑強な文字列 +SESSION_SECRET=presetprivatekey # 暗に暗号化へ使う任意の頑強な文字列 -SLACK_CLIENT_ID="179..." -SLACK_CLIENT_SECRET="38b..." -WORKSTATION_ID="VOW38CP2D" +SLACK_CLIENT_ID=179... +SLACK_CLIENT_SECRET=38b... +WORKSTATION_ID=VOW38CP2D -SLACK_BOT_ACCESS_TOKEN="xoxb-3814..." -SLACK_SIGNING_SECRET="fb36..." +SLACK_BOT_ACCESS_TOKEN=xoxb-3814... +SLACK_SIGNING_SECRET=fb36... ``` > ファイルを作成せずに [direnv](https://direnv.net/)などで環境変数に代入しても動作します From 42ae4008e7b3b5312c244eb2e8a30b0de20beacd Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 19 Aug 2019 01:53:51 +0900 Subject: [PATCH 04/60] Add openvino image --- object-detection/Dockerfile | 14 +++++++++ object-detection/install | 62 +++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 object-detection/Dockerfile create mode 100644 object-detection/install diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile new file mode 100644 index 0000000..cb12fe7 --- /dev/null +++ b/object-detection/Dockerfile @@ -0,0 +1,14 @@ +FROM ubuntu:16.04 + +RUN apt-get update && \ + apt-get install -y wget expect cpio pciutils python3-minimal python3-pip + +RUN cd / && \ + wget http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz && \ + tar -xvzf l_openvino_toolkit_p_2019.2.242_online.tgz && \ + rm l_openvino_toolkit_p_2019.2.242_online.tgz + +COPY install /l_openvino_toolkit_p_2019.2.242_online/ +RUN cd /l_openvino_toolkit_p_2019.2.242_online && \ + ./install_openvino_dependencies.sh && \ + expect ./install diff --git a/object-detection/install b/object-detection/install new file mode 100644 index 0000000..b2997a6 --- /dev/null +++ b/object-detection/install @@ -0,0 +1,62 @@ + #!/usr/bin/expect +spawn ./install.sh +expect "Please type a selection" +send "\n" +expect "Press \"Enter\" key to continue" +send "\n" +expect "End User License Agreement" +send "q" +expect "Type \"accept\" to continue" +send "accept\n" +expect "Please type a selection" +send "2\n" +expect "Please type a selection" +send "\n" +expect "'q' to quit." +send "q" +expect "Please type a selection" +send "2\n" + +expect "Please type a selection" +send "3\n" +expect "Please type a selection" +send "a\n" +expect "Please type a selection" +send "a\n" + +# Inference Engine +expect "Please type a selection" +send "2\n" +expect "Please type a selection" +send "3\n" +expect "Please type a selection" +send "4\n" +expect "Please type a selection" +send "6\n" +expect "Please type a selection" +send "b\n" + +# Model Optimizer +expect "Please type a selection" +send "3\n" +expect "Please type a selection" +send "2\n" +expect "Please type a selection" +send "b\n" + +# OpenCV +expect "Please type a selection" +send "5\n" +expect "Please type a selection" +send "2\n" +expect "Please type a selection" +send "b\n" + +expect "Please type a selection" +send "\n" +expect "Please type a selection" +send "\n" + +expect "Press \"Enter\" key" +send "\n" +expect eof From d9b9adbf5bd3d803a43f7a129ac28b2e2f64a6e9 Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 28 Jul 2019 17:07:40 +0900 Subject: [PATCH 05/60] Bugfix --- object-detection/src/main.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/object-detection/src/main.py b/object-detection/src/main.py index c87c1d1..df5f89f 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -4,7 +4,7 @@ import numpy as np import torch -from typing import Dict, Union +from typing import Dict, Union, List from matplotlib import cm from tqdm import tqdm @@ -110,14 +110,15 @@ def __init__(self) -> None: ) self.model.eval() - self.color = cm.hsv( - np.linspace(0, 1, len(COCO_INSTANCE_CATEGORY_NAMES) - 1) - ).tolist() + self.color: List[List[int]] = ( + cm.hsv(np.linspace(0, 1, len(COCO_INSTANCE_CATEGORY_NAMES) - 1)) * 255 + ).astype(np.uint8).tolist() def __call__(self, img: np.ndarray) -> Dict[str, torch.Tensor]: - prediction, = self.model( - [torch.from_numpy(img).permute((2, 0, 1)).float() / 255] - ) + with torch.no_grad(): + prediction, = self.model( + [torch.from_numpy(img).permute((2, 0, 1)).float() / 255] + ) prediction = self.select_top_prediction(prediction) return prediction @@ -153,7 +154,7 @@ def overlay_boxes( for box, color in zip(boxes, colors): box = box.long() - top_left, bottom_right = box[:2].tolist(), box[2:].tolist() + top_left, bottom_right = box[:2], box[2:] image = cv2.rectangle( image, tuple(top_left), tuple(bottom_right), tuple(color), 1 ) From c305e3a41048dbdb1e63810f66f500d57f47215b Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 8 Sep 2019 13:55:20 +0900 Subject: [PATCH 06/60] Add image for object detection --- docker-compose.debug.yml | 7 ++++++- docker-compose.prod.yml | 8 +++++++- object-detection/Dockerfile | 23 ++++++++++++++++++++++- object-detection/src/Pipfile | 5 ++++- utils/docker-compose.install.yml | 7 +++++++ 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 8b3ea91..14aeefd 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -118,4 +118,9 @@ services: # command: redis-server --appendonly yes --requirepass foobared volumes: - ./redis:/data - # python: + object-detection: + build: ./object-detection + working_dir: /app + command: pipenv run start + volumes: + - ./object-detection/src:/app diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index e11057c..ce364e8 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -112,4 +112,10 @@ services: # command: redis-server --appendonly yes --requirepass foobared volumes: - ./redis:/data - # python: + + object-detection: + build: ./object-detection + working_dir: /app + command: bash -c "pipenv install && pipenv run start" + volumes: + - ./object-detection/src:/app diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index cb12fe7..d9a8c96 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,7 +1,28 @@ FROM ubuntu:16.04 RUN apt-get update && \ - apt-get install -y wget expect cpio pciutils python3-minimal python3-pip + apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ + libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ + xz-utils tk-dev libffi-dev liblzma-dev python-openssl git + +RUN curl https://pyenv.run | bash && \ + echo 'export PATH="/root/.pyenv/bin:$PATH"' >> ~/.bashrc && \ + echo 'eval "$(pyenv init -)"' >> ~/.bashrc && \ + echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc + +ENV PATH $PATH:/root/.pyenv/bin:/root/.local/bin +ENV PIPENV_YES true +ENV PIPENV_VENV_IN_PROJECT true + +WORKDIR /root + +RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ + python get-pip.py && \ + rm get-pip.py + +RUN pip install --user pipenv + +RUN apt-get install -y wget expect cpio pciutils python3-minimal python3-pip RUN cd / && \ wget http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz && \ diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index f50a59e..354c490 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -13,4 +13,7 @@ matplotlib = "*" tqdm = "*" [requires] -python_version = "3.7" +python_version = "3.7.4" + +[scripts] +start = "python main.py" diff --git a/utils/docker-compose.install.yml b/utils/docker-compose.install.yml index 9826911..c715e21 100644 --- a/utils/docker-compose.install.yml +++ b/utils/docker-compose.install.yml @@ -42,3 +42,10 @@ services: command: ash -c "npm install && npm audit fix" volumes: - ../endpoint/src:/app + + object-detection: + build: ../object-detection + working_dir: /app + command: bash -c "pipenv install && pipenv update" + volumes: + - ../object-detection/src:/app From 230fc2c068cc9b9f660961073dfe7d84ac058484 Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 8 Sep 2019 19:04:33 +0900 Subject: [PATCH 07/60] Update Python environment --- docker-compose.debug.yml | 5 +- object-detection/Dockerfile | 26 +++-- object-detection/src/Pipfile | 4 +- object-detection/src/Pipfile.lock | 159 ++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 19 deletions(-) create mode 100644 object-detection/src/Pipfile.lock diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 14aeefd..f125afe 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -119,7 +119,10 @@ services: volumes: - ./redis:/data object-detection: - build: ./object-detection + build: + context: ./object-detection + args: + PYTHON_VERSION: 3.7.4 working_dir: /app command: pipenv run start volumes: diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index d9a8c96..d4a9f26 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,28 +1,24 @@ FROM ubuntu:16.04 +ARG PYTHON_VERSION=3.7.4 -RUN apt-get update && \ - apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ +RUN apt-get update && apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev libffi-dev liblzma-dev python-openssl git -RUN curl https://pyenv.run | bash && \ - echo 'export PATH="/root/.pyenv/bin:$PATH"' >> ~/.bashrc && \ - echo 'eval "$(pyenv init -)"' >> ~/.bashrc && \ - echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc +RUN git clone git://github.com/pyenv/pyenv.git && \ + cd pyenv/plugins/python-build && \ + ./install.sh && \ + python-build ${PYTHON_VERSION} ~/local/python-${PYTHON_VERSION} -ENV PATH $PATH:/root/.pyenv/bin:/root/.local/bin +WORKDIR /root +ENV PATH $PATH:/root/local/python-${PYTHON_VERSION}/bin ENV PIPENV_YES true ENV PIPENV_VENV_IN_PROJECT true -WORKDIR /root - -RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ - python get-pip.py && \ - rm get-pip.py - -RUN pip install --user pipenv +RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python3 && \ + pip install pipenv -RUN apt-get install -y wget expect cpio pciutils python3-minimal python3-pip +RUN apt-get install -y wget expect cpio pciutils RUN cd / && \ wget http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz && \ diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 354c490..82465b3 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -7,13 +7,11 @@ verify_ssl = true [packages] opencv-python = "*" -torch = "*" -torchvision = "*" matplotlib = "*" tqdm = "*" [requires] -python_version = "3.7.4" +python_version = "3.7" [scripts] start = "python main.py" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock new file mode 100644 index 0000000..d319d68 --- /dev/null +++ b/object-detection/src/Pipfile.lock @@ -0,0 +1,159 @@ +{ + "_meta": { + "hash": { + "sha256": "b0b8f9e9dfdb64fac9109b420fe40aadbcbecd16afb5ef790e14383296366ed7" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "cycler": { + "hashes": [ + "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", + "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8" + ], + "version": "==0.10.0" + }, + "kiwisolver": { + "hashes": [ + "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", + "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", + "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", + "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", + "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", + "sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75", + "sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187", + "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", + "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", + "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", + "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", + "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", + "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", + "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", + "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", + "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", + "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", + "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", + "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", + "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", + "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", + "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", + "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", + "sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004", + "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", + "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", + "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", + "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" + ], + "version": "==1.1.0" + }, + "matplotlib": { + "hashes": [ + "sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93", + "sha256:31a30d03f39528c79f3a592857be62a08595dec4ac034978ecd0f814fa0eec2d", + "sha256:4442ce720907f67a79d45de9ada47be81ce17e6c2f448b3c64765af93f6829c9", + "sha256:796edbd1182cbffa7e1e7a97f1e141f875a8501ba8dd834269ae3cd45a8c976f", + "sha256:934e6243df7165aad097572abf5b6003c77c9b6c480c3c4de6f2ef1b5fdd4ec0", + "sha256:bab9d848dbf1517bc58d1f486772e99919b19efef5dd8596d4b26f9f5ee08b6b", + "sha256:c1fe1e6cdaa53f11f088b7470c2056c0df7d80ee4858dadf6cbe433fcba4323b", + "sha256:e5b8aeca9276a3a988caebe9f08366ed519fff98f77c6df5b64d7603d0e42e36", + "sha256:ec6bd0a6a58df3628ff269978f4a4b924a0d371ad8ce1f8e2b635b99e482877a" + ], + "index": "pypi", + "version": "==3.1.1" + }, + "numpy": { + "hashes": [ + "sha256:05dbfe72684cc14b92568de1bc1f41e5f62b00f714afc9adee42f6311738091f", + "sha256:0d82cb7271a577529d07bbb05cb58675f2deb09772175fab96dc8de025d8ac05", + "sha256:10132aa1fef99adc85a905d82e8497a580f83739837d7cbd234649f2e9b9dc58", + "sha256:12322df2e21f033a60c80319c25011194cd2a21294cc66fee0908aeae2c27832", + "sha256:16f19b3aa775dddc9814e02a46b8e6ae6a54ed8cf143962b4e53f0471dbd7b16", + "sha256:3d0b0989dd2d066db006158de7220802899a1e5c8cf622abe2d0bd158fd01c2c", + "sha256:438a3f0e7b681642898fd7993d38e2bf140a2d1eafaf3e89bb626db7f50db355", + "sha256:5fd214f482ab53f2cea57414c5fb3e58895b17df6e6f5bca5be6a0bb6aea23bb", + "sha256:73615d3edc84dd7c4aeb212fa3748fb83217e00d201875a47327f55363cef2df", + "sha256:7bd355ad7496f4ce1d235e9814ec81ee3d28308d591c067ce92e49f745ba2c2f", + "sha256:7d077f2976b8f3de08a0dcf5d72083f4af5411e8fddacd662aae27baa2601196", + "sha256:a4092682778dc48093e8bda8d26ee8360153e2047826f95a3f5eae09f0ae3abf", + "sha256:b458de8624c9f6034af492372eb2fee41a8e605f03f4732f43fc099e227858b2", + "sha256:e70fc8ff03a961f13363c2c95ef8285e0cf6a720f8271836f852cc0fa64e97c8", + "sha256:ee8e9d7cad5fe6dde50ede0d2e978d81eafeaa6233fb0b8719f60214cf226578", + "sha256:f4a4f6aba148858a5a5d546a99280f71f5ee6ec8182a7d195af1a914195b21a2" + ], + "version": "==1.17.2" + }, + "opencv-python": { + "hashes": [ + "sha256:01505b131dc35f60e99a5da98b77156e37f872ae0ff5596e5e68d526bb572d3c", + "sha256:0478a1037505ddde312806c960a5e8958d2cf7a2885e8f2f5dde74c4028e0b04", + "sha256:17810b89f9ef8e8537e75332acf533e619e26ccadbf1b73f24bf338f2d327ddd", + "sha256:19ad2ea9fb32946761b47b9d6eed51876a8329da127f27788263fecd66651ba0", + "sha256:1a250edb739baf3e7c25d99a2ee252aac4f59a97e0bee39237eaa490fd0281d3", + "sha256:3505468970448f66cd776cb9e179570c87988f94b5cf9bcbc4c2d88bd88bbdf1", + "sha256:4e04a91da157885359f487534433340b2d709927559c80acf62c28167e59be02", + "sha256:5a49cffcdec5e37217672579c3343565926d999642844efa9c6a031ed5f32318", + "sha256:604b2ce3d4a86480ced0813da7fba269b4605ad9fea26cd2144d8077928d4b49", + "sha256:61cbb8fa9565a0480c46028599431ad8f19181a7fac8070a700515fd54cd7377", + "sha256:62d7c6e511c9454f099616315c695d02a584048e1affe034b39160db7a2ae34d", + "sha256:6555272dd9efd412d17cdc1a4f4c2da5753c099d95d9ff01aca54bb9782fb5cf", + "sha256:67d994c6b2b14cb9239e85dc7dfa6c08ef7cf6eb4def80c0af6141dfacc8cbb9", + "sha256:68c9cbe538666c4667523821cc56caee49389bea06bae4c0fc2cd68bd264226a", + "sha256:822ad8f628a9498f569c57d30865f5ef9ee17824cee0a1d456211f742028c135", + "sha256:82d972429eb4fee22c1dc4204af2a2e981f010e5e4f66daea2a6c68381b79184", + "sha256:9128924f5b58269ee221b8cf2d736f31bd3bb0391b92ee8504caadd68c8176a2", + "sha256:9172cf8270572c494d8b2ae12ef87c0f6eed9d132927e614099f76843b0c91d7", + "sha256:952bce4d30a8287b17721ddaad7f115dab268efee8576249ddfede80ec2ce404", + "sha256:a8147718e70b1f170a3d26518e992160137365a4db0ed82a9efd3040f9f660d4", + "sha256:bfdb636a3796ff223460ea0fcfda906b3b54f4bef22ae433a5b67e66fab00b25", + "sha256:c9c3f27867153634e1083390920067008ebaaab78aeb09c4e0274e69746cb2c8", + "sha256:d69be21973d450a4662ae6bd1b3df6b1af030e448d7276380b0d1adf7c8c2ae6", + "sha256:db1479636812a6579a3753b72a6fefaa73190f32bf7b19e483f8bc750cebe1a5", + "sha256:db8313d755962a7dd61e5c22a651e0743208adfdb255c6ec8904ce9cb02940c6", + "sha256:e4625a6b032e7797958aeb630d6e3e91e3896d285020aae612e6d7b342d6dfea", + "sha256:e8397a26966a1290836a52c34b362aabc65a422b9ffabcbbdec1862f023ccab8" + ], + "index": "pypi", + "version": "==4.1.1.26" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "version": "==2.8.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "tqdm": { + "hashes": [ + "sha256:1be3e4e3198f2d0e47b928e9d9a8ec1b63525db29095cec1467f4c5a4ea8ebf9", + "sha256:7e39a30e3d34a7a6539378e39d7490326253b7ee354878a92255656dc4284457" + ], + "index": "pypi", + "version": "==4.35.0" + } + }, + "develop": {} +} From e22c1f5571004910b446feb6469445cb43bc1b23 Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 8 Sep 2019 20:40:11 +0900 Subject: [PATCH 08/60] Tweak --- object-detection/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index d4a9f26..3080dff 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y make build-essential libssl-dev zlib1g- libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev libffi-dev liblzma-dev python-openssl git -RUN git clone git://github.com/pyenv/pyenv.git && \ +RUN git clone https://github.com/pyenv/pyenv.git && \ cd pyenv/plugins/python-build && \ ./install.sh && \ python-build ${PYTHON_VERSION} ~/local/python-${PYTHON_VERSION} From 0d79f2481c790a73f215acb45114675d63806774 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 9 Sep 2019 17:23:09 +0900 Subject: [PATCH 09/60] Update Dockerfile for object detection & Tweak --- docker-compose.debug.yml | 5 + docker-compose.prod.yml | 9 +- object-detection/Dockerfile | 95 +++++++++++--- object-detection/install | 62 --------- object-detection/src/Pipfile | 2 - object-detection/src/Pipfile.lock | 86 +------------ object-detection/src/main.py | 205 +----------------------------- 7 files changed, 91 insertions(+), 373 deletions(-) delete mode 100644 object-detection/install diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index f125afe..866d47e 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -118,6 +118,7 @@ services: # command: redis-server --appendonly yes --requirepass foobared volumes: - ./redis:/data + object-detection: build: context: ./object-detection @@ -125,5 +126,9 @@ services: PYTHON_VERSION: 3.7.4 working_dir: /app command: pipenv run start + privileged: true volumes: - ./object-detection/src:/app + - /dev:/dev + depends_on: + - streamer diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index ce364e8..952efa3 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -114,8 +114,15 @@ services: - ./redis:/data object-detection: - build: ./object-detection + build: + context: ./object-detection + args: + PYTHON_VERSION: 3.7.4 working_dir: /app command: bash -c "pipenv install && pipenv run start" + privileged: true volumes: - ./object-detection/src:/app + - /dev:/dev + depends_on: + - streamer diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 3080dff..eea21fe 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,31 +1,84 @@ +FROM python:3.7.4-slim-stretch AS python FROM ubuntu:16.04 -ARG PYTHON_VERSION=3.7.4 -RUN apt-get update && apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ - libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ - xz-utils tk-dev libffi-dev liblzma-dev python-openssl git - -RUN git clone https://github.com/pyenv/pyenv.git && \ - cd pyenv/plugins/python-build && \ - ./install.sh && \ - python-build ${PYTHON_VERSION} ~/local/python-${PYTHON_VERSION} +# COPY --from=python /bin /bin +# COPY --from=python /boot /boot +# COPY --from=python /dev /dev +COPY --from=python /etc /etc +# COPY --from=python /home /home +COPY --from=python /lib /lib +COPY --from=python /lib64 /lib64 +# COPY --from=python /media /media +# COPY --from=python /mnt /mnt +# COPY --from=python /opt /opt +# COPY --from=python /proc /proc +# COPY --from=python /root /root +# COPY --from=python /run /run +# COPY --from=python /sbin /sbin +# COPY --from=python /srv /srv +# COPY --from=python /sys /sys +# COPY --from=python /tmp /tmp +COPY --from=python /usr /usr +# COPY --from=python /var /var WORKDIR /root -ENV PATH $PATH:/root/local/python-${PYTHON_VERSION}/bin +RUN pip install pipenv +# ARG PYTHON_VERSION=3.7.4 +# RUN apt-get update && apt-get install -y --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev \ +# libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ +# xz-utils tk-dev libffi-dev liblzma-dev python-openssl git + +# RUN git config --global http.sslVerify false && \ +# git clone https://github.com/pyenv/pyenv.git && \ +# cd pyenv/plugins/python-build && \ +# ./install.sh && \ +# python-build ${PYTHON_VERSION} ~/local/python-${PYTHON_VERSION} + +# WORKDIR /root +# ENV PATH $PATH:/root/local/python-${PYTHON_VERSION}/bin +# ENV PIPENV_YES true +# ENV PIPENV_VENV_IN_PROJECT true + +# RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python3 && \ +# pip install pipenv + ENV PIPENV_YES true ENV PIPENV_VENV_IN_PROJECT true -RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python3 && \ - pip install pipenv +# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html +ENV http_proxy $HTTP_PROXY +ENV https_proxy $HTTPS_PROXY +ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/15792/l_openvino_toolkit_p_2019.2.275_online.tgz +ARG INSTALL_DIR=/opt/intel/openvino +ARG TEMP_DIR=/tmp/openvino_installer +# TODO lsb-releaseがpythonをいれてしまう +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget \ + cpio \ + sudo \ + lsb-release && \ + rm -rf /var/lib/apt/lists/* +RUN mkdir -p $TEMP_DIR && cd $TEMP_DIR && \ + wget -c $DOWNLOAD_LINK && \ + tar xf l_openvino_toolkit*.tgz && \ + cd l_openvino_toolkit* && \ + sed -i 's/decline/accept/g' silent.cfg && \ + ./install.sh -s silent.cfg && \ + rm -rf $TEMP_DIR +# TODO install_openvino_dependencies.shがpythonをいれてしまう -RUN apt-get install -y wget expect cpio pciutils +RUN sed -i 's/libpng12-dev/libpng-dev/g' $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh && \ + $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh -RUN cd / && \ - wget http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz && \ - tar -xvzf l_openvino_toolkit_p_2019.2.242_online.tgz && \ - rm l_openvino_toolkit_p_2019.2.242_online.tgz +# build Inference Engine samples +RUN mkdir $INSTALL_DIR/deployment_tools/inference_engine/samples/build && cd $INSTALL_DIR/deployment_tools/inference_engine/samples/build && \ + /bin/bash -c "source $INSTALL_DIR/bin/setupvars.sh && cmake .. && make -j1" -COPY install /l_openvino_toolkit_p_2019.2.242_online/ -RUN cd /l_openvino_toolkit_p_2019.2.242_online && \ - ./install_openvino_dependencies.sh && \ - expect ./install +RUN apt-get install -y --no-install-recommends unzip && \ + cd /tmp/ && \ + wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ + unzip v1.0.22.zip && cd libusb-1.0.22 && \ + ./bootstrap.sh && \ + ./configure --disable-udev --enable-shared && \ + make -j4 && make install && \ + rm -rf /tmp/* diff --git a/object-detection/install b/object-detection/install deleted file mode 100644 index b2997a6..0000000 --- a/object-detection/install +++ /dev/null @@ -1,62 +0,0 @@ - #!/usr/bin/expect -spawn ./install.sh -expect "Please type a selection" -send "\n" -expect "Press \"Enter\" key to continue" -send "\n" -expect "End User License Agreement" -send "q" -expect "Type \"accept\" to continue" -send "accept\n" -expect "Please type a selection" -send "2\n" -expect "Please type a selection" -send "\n" -expect "'q' to quit." -send "q" -expect "Please type a selection" -send "2\n" - -expect "Please type a selection" -send "3\n" -expect "Please type a selection" -send "a\n" -expect "Please type a selection" -send "a\n" - -# Inference Engine -expect "Please type a selection" -send "2\n" -expect "Please type a selection" -send "3\n" -expect "Please type a selection" -send "4\n" -expect "Please type a selection" -send "6\n" -expect "Please type a selection" -send "b\n" - -# Model Optimizer -expect "Please type a selection" -send "3\n" -expect "Please type a selection" -send "2\n" -expect "Please type a selection" -send "b\n" - -# OpenCV -expect "Please type a selection" -send "5\n" -expect "Please type a selection" -send "2\n" -expect "Please type a selection" -send "b\n" - -expect "Please type a selection" -send "\n" -expect "Please type a selection" -send "\n" - -expect "Press \"Enter\" key" -send "\n" -expect eof diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 82465b3..de68875 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -7,8 +7,6 @@ verify_ssl = true [packages] opencv-python = "*" -matplotlib = "*" -tqdm = "*" [requires] python_version = "3.7" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index d319d68..200c162 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b0b8f9e9dfdb64fac9109b420fe40aadbcbecd16afb5ef790e14383296366ed7" + "sha256": "1214c859d02ce9388e7b68c4d42ceffccbc72ef0ac44a087df66d881be4f8333" }, "pipfile-spec": 6, "requires": { @@ -16,61 +16,6 @@ ] }, "default": { - "cycler": { - "hashes": [ - "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", - "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8" - ], - "version": "==0.10.0" - }, - "kiwisolver": { - "hashes": [ - "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", - "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", - "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", - "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", - "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", - "sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75", - "sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187", - "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", - "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", - "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", - "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", - "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", - "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", - "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", - "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", - "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", - "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", - "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", - "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", - "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", - "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", - "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", - "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", - "sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004", - "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", - "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", - "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", - "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" - ], - "version": "==1.1.0" - }, - "matplotlib": { - "hashes": [ - "sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93", - "sha256:31a30d03f39528c79f3a592857be62a08595dec4ac034978ecd0f814fa0eec2d", - "sha256:4442ce720907f67a79d45de9ada47be81ce17e6c2f448b3c64765af93f6829c9", - "sha256:796edbd1182cbffa7e1e7a97f1e141f875a8501ba8dd834269ae3cd45a8c976f", - "sha256:934e6243df7165aad097572abf5b6003c77c9b6c480c3c4de6f2ef1b5fdd4ec0", - "sha256:bab9d848dbf1517bc58d1f486772e99919b19efef5dd8596d4b26f9f5ee08b6b", - "sha256:c1fe1e6cdaa53f11f088b7470c2056c0df7d80ee4858dadf6cbe433fcba4323b", - "sha256:e5b8aeca9276a3a988caebe9f08366ed519fff98f77c6df5b64d7603d0e42e36", - "sha256:ec6bd0a6a58df3628ff269978f4a4b924a0d371ad8ce1f8e2b635b99e482877a" - ], - "index": "pypi", - "version": "==3.1.1" - }, "numpy": { "hashes": [ "sha256:05dbfe72684cc14b92568de1bc1f41e5f62b00f714afc9adee42f6311738091f", @@ -124,35 +69,6 @@ ], "index": "pypi", "version": "==4.1.1.26" - }, - "pyparsing": { - "hashes": [ - "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", - "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" - ], - "version": "==2.4.2" - }, - "python-dateutil": { - "hashes": [ - "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", - "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" - ], - "version": "==2.8.0" - }, - "six": { - "hashes": [ - "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", - "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" - ], - "version": "==1.12.0" - }, - "tqdm": { - "hashes": [ - "sha256:1be3e4e3198f2d0e47b928e9d9a8ec1b63525db29095cec1467f4c5a4ea8ebf9", - "sha256:7e39a30e3d34a7a6539378e39d7490326253b7ee354878a92255656dc4284457" - ], - "index": "pypi", - "version": "==4.35.0" } }, "develop": {} diff --git a/object-detection/src/main.py b/object-detection/src/main.py index df5f89f..6d039c8 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -1,209 +1,10 @@ #!/usr/bin/env python3 -import cv2 -import torchvision -import numpy as np - -import torch -from typing import Dict, Union, List -from matplotlib import cm -from tqdm import tqdm - -COCO_INSTANCE_CATEGORY_NAMES = [ - "__background__", - "person", - "bicycle", - "car", - "motorcycle", - "airplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "N/A", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "N/A", - "backpack", - "umbrella", - "N/A", - "N/A", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "N/A", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "couch", - "potted plant", - "bed", - "N/A", - "dining table", - "N/A", - "N/A", - "toilet", - "N/A", - "tv", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "N/A", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush", -] - - -class ObjectDetector: - def __init__(self) -> None: - self.model = torchvision.models.detection.fasterrcnn_resnet50_fpn( - pretrained=True - ) - self.model.eval() - - self.color: List[List[int]] = ( - cm.hsv(np.linspace(0, 1, len(COCO_INSTANCE_CATEGORY_NAMES) - 1)) * 255 - ).astype(np.uint8).tolist() - - def __call__(self, img: np.ndarray) -> Dict[str, torch.Tensor]: - with torch.no_grad(): - prediction, = self.model( - [torch.from_numpy(img).permute((2, 0, 1)).float() / 255] - ) - prediction = self.select_top_prediction(prediction) - return prediction - - def draw(self, img: np.ndarray, prediction: Dict[str, torch.Tensor]) -> np.ndarray: - img = self.overlay_boxes(img, prediction) - img = self.overlay_class_names(img, prediction) - - if isinstance(img, cv2.UMat): - img = img.get() - return img - - # https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/demo/predictor.py - def select_top_prediction( - self, prediction: Dict[str, torch.Tensor], threshold: float = 0.8 - ) -> Dict[str, torch.Tensor]: - scores = prediction["scores"] - keep = torch.nonzero(scores > threshold).squeeze(1) - prediction = prediction.copy() - - for key, value in prediction.items(): - prediction[key] = value[keep] - - # scores.sort(0, descending=True) - return prediction - - def overlay_boxes( - self, image: Union[np.ndarray, cv2.UMat], prediction: Dict[str, torch.Tensor] - ) -> Union[np.ndarray, cv2.UMat]: - labels = prediction["labels"] - boxes = prediction["boxes"] - - colors = [self.color[i - 1] for i in labels] - - for box, color in zip(boxes, colors): - box = box.long() - top_left, bottom_right = box[:2], box[2:] - image = cv2.rectangle( - image, tuple(top_left), tuple(bottom_right), tuple(color), 1 - ) - return image - - def overlay_class_names( - self, image: Union[np.ndarray, cv2.UMat], prediction: Dict[str, torch.Tensor] - ) -> Union[np.ndarray, cv2.UMat]: - scores = prediction["scores"] - labels = prediction["labels"] - boxes = prediction["boxes"] - - labels = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in labels] - - for box, score, label in zip(boxes, scores, labels): - x, y = box[:2] - text = f"{label}: {score :.2f}" - cv2.putText( - image, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1 - ) - return image +from time import sleep def main(): - cap = cv2.VideoCapture("rtmp://localhost:1935/live/bushitsuchan") - cv2.namedWindow("img", cv2.WINDOW_NORMAL) - cv2.setWindowProperty("img", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) - - detector = ObjectDetector() - - with tqdm() as pbar: - while True: - ret, frame = cap.read() - if not ret: - break - - frame = np.asarray(frame) - prediction = detector(frame) - frame = detector.draw(frame, prediction) - - cv2.imshow("img", frame) - - key = cv2.waitKey(1) - if key == 27: - break - pbar.update(1) - - cap.release() - cv2.destroyAllWindows() + while 1: + sleep(1) if __name__ == "__main__": From ffc4991c0275dcd916da8028d93f0d196bb6dec4 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 9 Sep 2019 23:03:41 +0900 Subject: [PATCH 10/60] Add linter and formatter & Tweak --- object-detection/Dockerfile | 2 + object-detection/src/Pipfile | 4 ++ object-detection/src/Pipfile.lock | 77 ++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index eea21fe..bc3de2d 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,6 +1,8 @@ FROM python:3.7.4-slim-stretch AS python FROM ubuntu:16.04 +ENV LANG C.UTF-8 + # COPY --from=python /bin /bin # COPY --from=python /boot /boot # COPY --from=python /dev /dev diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index de68875..d540bd2 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -4,6 +4,8 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] +black = "*" +flake8 = "*" [packages] opencv-python = "*" @@ -13,3 +15,5 @@ python_version = "3.7" [scripts] start = "python main.py" +lint = "flake8 --exclude .venv ." +format = "black ." diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index 200c162..440fa07 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "1214c859d02ce9388e7b68c4d42ceffccbc72ef0ac44a087df66d881be4f8333" + "sha256": "76d4264581afd0f643ecdcc96f51fd6721e711fb89dcb4a24c2099c1b34a9d15" }, "pipfile-spec": 6, "requires": { @@ -71,5 +71,78 @@ "version": "==4.1.1.26" } }, - "develop": {} + "develop": { + "appdirs": { + "hashes": [ + "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", + "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + ], + "version": "==1.4.3" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "black": { + "hashes": [ + "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", + "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" + ], + "index": "pypi", + "version": "==19.3b0" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "version": "==0.3" + }, + "flake8": { + "hashes": [ + "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", + "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" + ], + "index": "pypi", + "version": "==3.7.8" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, + "pyflakes": { + "hashes": [ + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" + ], + "version": "==2.1.1" + }, + "toml": { + "hashes": [ + "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", + "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + ], + "version": "==0.10.0" + } + } } From 100a85865a0e78a7f66bea17a6d0e46f69302b7f Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 15 Sep 2019 19:29:03 +0900 Subject: [PATCH 11/60] Added startup command for debug mode --- docker-compose.debug.yml | 2 +- docker-compose.prod.yml | 2 +- object-detection/src/Pipfile | 11 ++- object-detection/src/Pipfile.lock | 148 ------------------------------ utils/docker-compose.install.yml | 2 +- 5 files changed, 11 insertions(+), 154 deletions(-) delete mode 100644 object-detection/src/Pipfile.lock diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 866d47e..6c85087 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -125,7 +125,7 @@ services: args: PYTHON_VERSION: 3.7.4 working_dir: /app - command: pipenv run start + command: pipenv run dev privileged: true volumes: - ./object-detection/src:/app diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 952efa3..6ebf3d3 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -119,7 +119,7 @@ services: args: PYTHON_VERSION: 3.7.4 working_dir: /app - command: bash -c "pipenv install && pipenv run start" + command: bash -c "pipenv sync && pipenv run start" privileged: true volumes: - ./object-detection/src:/app diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index d540bd2..933f90a 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -4,16 +4,21 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -black = "*" -flake8 = "*" +black = "~=19.3b0" +flake8 = "~=3.7.8" +watchdog = "~=0.9.0" [packages] -opencv-python = "*" +opencv-python = "~=4.1.1.26" [requires] python_version = "3.7" [scripts] start = "python main.py" +dev = "watchmedo shell-command --patterns='*.py' --command='python main.py' ." lint = "flake8 --exclude .venv ." format = "black ." + +[pipenv] +allow_prereleases = true diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock deleted file mode 100644 index 440fa07..0000000 --- a/object-detection/src/Pipfile.lock +++ /dev/null @@ -1,148 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "76d4264581afd0f643ecdcc96f51fd6721e711fb89dcb4a24c2099c1b34a9d15" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.7" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "numpy": { - "hashes": [ - "sha256:05dbfe72684cc14b92568de1bc1f41e5f62b00f714afc9adee42f6311738091f", - "sha256:0d82cb7271a577529d07bbb05cb58675f2deb09772175fab96dc8de025d8ac05", - "sha256:10132aa1fef99adc85a905d82e8497a580f83739837d7cbd234649f2e9b9dc58", - "sha256:12322df2e21f033a60c80319c25011194cd2a21294cc66fee0908aeae2c27832", - "sha256:16f19b3aa775dddc9814e02a46b8e6ae6a54ed8cf143962b4e53f0471dbd7b16", - "sha256:3d0b0989dd2d066db006158de7220802899a1e5c8cf622abe2d0bd158fd01c2c", - "sha256:438a3f0e7b681642898fd7993d38e2bf140a2d1eafaf3e89bb626db7f50db355", - "sha256:5fd214f482ab53f2cea57414c5fb3e58895b17df6e6f5bca5be6a0bb6aea23bb", - "sha256:73615d3edc84dd7c4aeb212fa3748fb83217e00d201875a47327f55363cef2df", - "sha256:7bd355ad7496f4ce1d235e9814ec81ee3d28308d591c067ce92e49f745ba2c2f", - "sha256:7d077f2976b8f3de08a0dcf5d72083f4af5411e8fddacd662aae27baa2601196", - "sha256:a4092682778dc48093e8bda8d26ee8360153e2047826f95a3f5eae09f0ae3abf", - "sha256:b458de8624c9f6034af492372eb2fee41a8e605f03f4732f43fc099e227858b2", - "sha256:e70fc8ff03a961f13363c2c95ef8285e0cf6a720f8271836f852cc0fa64e97c8", - "sha256:ee8e9d7cad5fe6dde50ede0d2e978d81eafeaa6233fb0b8719f60214cf226578", - "sha256:f4a4f6aba148858a5a5d546a99280f71f5ee6ec8182a7d195af1a914195b21a2" - ], - "version": "==1.17.2" - }, - "opencv-python": { - "hashes": [ - "sha256:01505b131dc35f60e99a5da98b77156e37f872ae0ff5596e5e68d526bb572d3c", - "sha256:0478a1037505ddde312806c960a5e8958d2cf7a2885e8f2f5dde74c4028e0b04", - "sha256:17810b89f9ef8e8537e75332acf533e619e26ccadbf1b73f24bf338f2d327ddd", - "sha256:19ad2ea9fb32946761b47b9d6eed51876a8329da127f27788263fecd66651ba0", - "sha256:1a250edb739baf3e7c25d99a2ee252aac4f59a97e0bee39237eaa490fd0281d3", - "sha256:3505468970448f66cd776cb9e179570c87988f94b5cf9bcbc4c2d88bd88bbdf1", - "sha256:4e04a91da157885359f487534433340b2d709927559c80acf62c28167e59be02", - "sha256:5a49cffcdec5e37217672579c3343565926d999642844efa9c6a031ed5f32318", - "sha256:604b2ce3d4a86480ced0813da7fba269b4605ad9fea26cd2144d8077928d4b49", - "sha256:61cbb8fa9565a0480c46028599431ad8f19181a7fac8070a700515fd54cd7377", - "sha256:62d7c6e511c9454f099616315c695d02a584048e1affe034b39160db7a2ae34d", - "sha256:6555272dd9efd412d17cdc1a4f4c2da5753c099d95d9ff01aca54bb9782fb5cf", - "sha256:67d994c6b2b14cb9239e85dc7dfa6c08ef7cf6eb4def80c0af6141dfacc8cbb9", - "sha256:68c9cbe538666c4667523821cc56caee49389bea06bae4c0fc2cd68bd264226a", - "sha256:822ad8f628a9498f569c57d30865f5ef9ee17824cee0a1d456211f742028c135", - "sha256:82d972429eb4fee22c1dc4204af2a2e981f010e5e4f66daea2a6c68381b79184", - "sha256:9128924f5b58269ee221b8cf2d736f31bd3bb0391b92ee8504caadd68c8176a2", - "sha256:9172cf8270572c494d8b2ae12ef87c0f6eed9d132927e614099f76843b0c91d7", - "sha256:952bce4d30a8287b17721ddaad7f115dab268efee8576249ddfede80ec2ce404", - "sha256:a8147718e70b1f170a3d26518e992160137365a4db0ed82a9efd3040f9f660d4", - "sha256:bfdb636a3796ff223460ea0fcfda906b3b54f4bef22ae433a5b67e66fab00b25", - "sha256:c9c3f27867153634e1083390920067008ebaaab78aeb09c4e0274e69746cb2c8", - "sha256:d69be21973d450a4662ae6bd1b3df6b1af030e448d7276380b0d1adf7c8c2ae6", - "sha256:db1479636812a6579a3753b72a6fefaa73190f32bf7b19e483f8bc750cebe1a5", - "sha256:db8313d755962a7dd61e5c22a651e0743208adfdb255c6ec8904ce9cb02940c6", - "sha256:e4625a6b032e7797958aeb630d6e3e91e3896d285020aae612e6d7b342d6dfea", - "sha256:e8397a26966a1290836a52c34b362aabc65a422b9ffabcbbdec1862f023ccab8" - ], - "index": "pypi", - "version": "==4.1.1.26" - } - }, - "develop": { - "appdirs": { - "hashes": [ - "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", - "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" - ], - "version": "==1.4.3" - }, - "attrs": { - "hashes": [ - "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", - "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" - ], - "version": "==19.1.0" - }, - "black": { - "hashes": [ - "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", - "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" - ], - "index": "pypi", - "version": "==19.3b0" - }, - "click": { - "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" - ], - "version": "==7.0" - }, - "entrypoints": { - "hashes": [ - "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", - "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" - ], - "version": "==0.3" - }, - "flake8": { - "hashes": [ - "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", - "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" - ], - "index": "pypi", - "version": "==3.7.8" - }, - "mccabe": { - "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" - ], - "version": "==0.6.1" - }, - "pycodestyle": { - "hashes": [ - "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", - "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" - ], - "version": "==2.5.0" - }, - "pyflakes": { - "hashes": [ - "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", - "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" - ], - "version": "==2.1.1" - }, - "toml": { - "hashes": [ - "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", - "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" - ], - "version": "==0.10.0" - } - } -} diff --git a/utils/docker-compose.install.yml b/utils/docker-compose.install.yml index c715e21..41a51c8 100644 --- a/utils/docker-compose.install.yml +++ b/utils/docker-compose.install.yml @@ -46,6 +46,6 @@ services: object-detection: build: ../object-detection working_dir: /app - command: bash -c "pipenv install && pipenv update" + command: bash -c "pipenv install --dev && pipenv update" volumes: - ../object-detection/src:/app From 4d86f849b50e977f7e81939909163a4c0c2559a0 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 16 Sep 2019 03:04:52 +0900 Subject: [PATCH 12/60] Update Python environment --- docker-compose.debug.yml | 2 - docker-compose.prod.yml | 2 - object-detection/Dockerfile | 96 +++------------ object-detection/src/Pipfile.lock | 187 ++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 83 deletions(-) create mode 100644 object-detection/src/Pipfile.lock diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 6c85087..0a3e288 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -122,8 +122,6 @@ services: object-detection: build: context: ./object-detection - args: - PYTHON_VERSION: 3.7.4 working_dir: /app command: pipenv run dev privileged: true diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 6ebf3d3..b79c103 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -116,8 +116,6 @@ services: object-detection: build: context: ./object-detection - args: - PYTHON_VERSION: 3.7.4 working_dir: /app command: bash -c "pipenv sync && pipenv run start" privileged: true diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index bc3de2d..04980c5 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,86 +1,24 @@ -FROM python:3.7.4-slim-stretch AS python -FROM ubuntu:16.04 +FROM ubuntu:18.04 -ENV LANG C.UTF-8 +RUN apt-get update && \ + apt-get install -y --no-install-recommends python3.7 wget gnupg curl ca-certificates && \ + apt-get download python3-distutils && \ + dpkg-deb -x python3-distutils* / && \ + rm python3-distutils* && \ + update-ca-certificates -# COPY --from=python /bin /bin -# COPY --from=python /boot /boot -# COPY --from=python /dev /dev -COPY --from=python /etc /etc -# COPY --from=python /home /home -COPY --from=python /lib /lib -COPY --from=python /lib64 /lib64 -# COPY --from=python /media /media -# COPY --from=python /mnt /mnt -# COPY --from=python /opt /opt -# COPY --from=python /proc /proc -# COPY --from=python /root /root -# COPY --from=python /run /run -# COPY --from=python /sbin /sbin -# COPY --from=python /srv /srv -# COPY --from=python /sys /sys -# COPY --from=python /tmp /tmp -COPY --from=python /usr /usr -# COPY --from=python /var /var +RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python3.7 && \ + pip3 install pipenv -WORKDIR /root -RUN pip install pipenv -# ARG PYTHON_VERSION=3.7.4 -# RUN apt-get update && apt-get install -y --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev \ -# libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ -# xz-utils tk-dev libffi-dev liblzma-dev python-openssl git - -# RUN git config --global http.sslVerify false && \ -# git clone https://github.com/pyenv/pyenv.git && \ -# cd pyenv/plugins/python-build && \ -# ./install.sh && \ -# python-build ${PYTHON_VERSION} ~/local/python-${PYTHON_VERSION} - -# WORKDIR /root -# ENV PATH $PATH:/root/local/python-${PYTHON_VERSION}/bin # ENV PIPENV_YES true -# ENV PIPENV_VENV_IN_PROJECT true - -# RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python3 && \ -# pip install pipenv - -ENV PIPENV_YES true ENV PIPENV_VENV_IN_PROJECT true -# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html -ENV http_proxy $HTTP_PROXY -ENV https_proxy $HTTPS_PROXY -ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/15792/l_openvino_toolkit_p_2019.2.275_online.tgz -ARG INSTALL_DIR=/opt/intel/openvino -ARG TEMP_DIR=/tmp/openvino_installer -# TODO lsb-releaseがpythonをいれてしまう -RUN apt-get update && apt-get install -y --no-install-recommends \ - wget \ - cpio \ - sudo \ - lsb-release && \ - rm -rf /var/lib/apt/lists/* -RUN mkdir -p $TEMP_DIR && cd $TEMP_DIR && \ - wget -c $DOWNLOAD_LINK && \ - tar xf l_openvino_toolkit*.tgz && \ - cd l_openvino_toolkit* && \ - sed -i 's/decline/accept/g' silent.cfg && \ - ./install.sh -s silent.cfg && \ - rm -rf $TEMP_DIR -# TODO install_openvino_dependencies.shがpythonをいれてしまう - -RUN sed -i 's/libpng12-dev/libpng-dev/g' $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh && \ - $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh - -# build Inference Engine samples -RUN mkdir $INSTALL_DIR/deployment_tools/inference_engine/samples/build && cd $INSTALL_DIR/deployment_tools/inference_engine/samples/build && \ - /bin/bash -c "source $INSTALL_DIR/bin/setupvars.sh && cmake .. && make -j1" +RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-2019 && \ + apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2019 & \ + bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ + apt-key adv --keyserver apt.repos.intel.com --recv-keys && \ + apt-get update && \ + apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release +# TODO /opt/intel/openvino/install_dependicy.sh の必要性とその中で行われるので省略できる処理の確認 -RUN apt-get install -y --no-install-recommends unzip && \ - cd /tmp/ && \ - wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ - unzip v1.0.22.zip && cd libusb-1.0.22 && \ - ./bootstrap.sh && \ - ./configure --disable-udev --enable-shared && \ - make -j4 && make install && \ - rm -rf /tmp/* +RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock new file mode 100644 index 0000000..78c5a78 --- /dev/null +++ b/object-detection/src/Pipfile.lock @@ -0,0 +1,187 @@ +{ + "_meta": { + "hash": { + "sha256": "cbf5e8f168d2961b7627c7aa00d042add27561b73ec84413588655c52f404dbe" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "numpy": { + "hashes": [ + "sha256:05dbfe72684cc14b92568de1bc1f41e5f62b00f714afc9adee42f6311738091f", + "sha256:0d82cb7271a577529d07bbb05cb58675f2deb09772175fab96dc8de025d8ac05", + "sha256:10132aa1fef99adc85a905d82e8497a580f83739837d7cbd234649f2e9b9dc58", + "sha256:12322df2e21f033a60c80319c25011194cd2a21294cc66fee0908aeae2c27832", + "sha256:16f19b3aa775dddc9814e02a46b8e6ae6a54ed8cf143962b4e53f0471dbd7b16", + "sha256:3d0b0989dd2d066db006158de7220802899a1e5c8cf622abe2d0bd158fd01c2c", + "sha256:438a3f0e7b681642898fd7993d38e2bf140a2d1eafaf3e89bb626db7f50db355", + "sha256:5fd214f482ab53f2cea57414c5fb3e58895b17df6e6f5bca5be6a0bb6aea23bb", + "sha256:73615d3edc84dd7c4aeb212fa3748fb83217e00d201875a47327f55363cef2df", + "sha256:7bd355ad7496f4ce1d235e9814ec81ee3d28308d591c067ce92e49f745ba2c2f", + "sha256:7d077f2976b8f3de08a0dcf5d72083f4af5411e8fddacd662aae27baa2601196", + "sha256:a4092682778dc48093e8bda8d26ee8360153e2047826f95a3f5eae09f0ae3abf", + "sha256:b458de8624c9f6034af492372eb2fee41a8e605f03f4732f43fc099e227858b2", + "sha256:e70fc8ff03a961f13363c2c95ef8285e0cf6a720f8271836f852cc0fa64e97c8", + "sha256:ee8e9d7cad5fe6dde50ede0d2e978d81eafeaa6233fb0b8719f60214cf226578", + "sha256:f4a4f6aba148858a5a5d546a99280f71f5ee6ec8182a7d195af1a914195b21a2" + ], + "version": "==1.17.2" + }, + "opencv-python": { + "hashes": [ + "sha256:01505b131dc35f60e99a5da98b77156e37f872ae0ff5596e5e68d526bb572d3c", + "sha256:0478a1037505ddde312806c960a5e8958d2cf7a2885e8f2f5dde74c4028e0b04", + "sha256:17810b89f9ef8e8537e75332acf533e619e26ccadbf1b73f24bf338f2d327ddd", + "sha256:19ad2ea9fb32946761b47b9d6eed51876a8329da127f27788263fecd66651ba0", + "sha256:1a250edb739baf3e7c25d99a2ee252aac4f59a97e0bee39237eaa490fd0281d3", + "sha256:3505468970448f66cd776cb9e179570c87988f94b5cf9bcbc4c2d88bd88bbdf1", + "sha256:4e04a91da157885359f487534433340b2d709927559c80acf62c28167e59be02", + "sha256:5a49cffcdec5e37217672579c3343565926d999642844efa9c6a031ed5f32318", + "sha256:604b2ce3d4a86480ced0813da7fba269b4605ad9fea26cd2144d8077928d4b49", + "sha256:61cbb8fa9565a0480c46028599431ad8f19181a7fac8070a700515fd54cd7377", + "sha256:62d7c6e511c9454f099616315c695d02a584048e1affe034b39160db7a2ae34d", + "sha256:6555272dd9efd412d17cdc1a4f4c2da5753c099d95d9ff01aca54bb9782fb5cf", + "sha256:67d994c6b2b14cb9239e85dc7dfa6c08ef7cf6eb4def80c0af6141dfacc8cbb9", + "sha256:68c9cbe538666c4667523821cc56caee49389bea06bae4c0fc2cd68bd264226a", + "sha256:822ad8f628a9498f569c57d30865f5ef9ee17824cee0a1d456211f742028c135", + "sha256:82d972429eb4fee22c1dc4204af2a2e981f010e5e4f66daea2a6c68381b79184", + "sha256:9128924f5b58269ee221b8cf2d736f31bd3bb0391b92ee8504caadd68c8176a2", + "sha256:9172cf8270572c494d8b2ae12ef87c0f6eed9d132927e614099f76843b0c91d7", + "sha256:952bce4d30a8287b17721ddaad7f115dab268efee8576249ddfede80ec2ce404", + "sha256:a8147718e70b1f170a3d26518e992160137365a4db0ed82a9efd3040f9f660d4", + "sha256:bfdb636a3796ff223460ea0fcfda906b3b54f4bef22ae433a5b67e66fab00b25", + "sha256:c9c3f27867153634e1083390920067008ebaaab78aeb09c4e0274e69746cb2c8", + "sha256:d69be21973d450a4662ae6bd1b3df6b1af030e448d7276380b0d1adf7c8c2ae6", + "sha256:db1479636812a6579a3753b72a6fefaa73190f32bf7b19e483f8bc750cebe1a5", + "sha256:db8313d755962a7dd61e5c22a651e0743208adfdb255c6ec8904ce9cb02940c6", + "sha256:e4625a6b032e7797958aeb630d6e3e91e3896d285020aae612e6d7b342d6dfea", + "sha256:e8397a26966a1290836a52c34b362aabc65a422b9ffabcbbdec1862f023ccab8" + ], + "index": "pypi", + "version": "==4.1.1.26" + } + }, + "develop": { + "appdirs": { + "hashes": [ + "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", + "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + ], + "version": "==1.4.3" + }, + "argh": { + "hashes": [ + "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3", + "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65" + ], + "version": "==0.26.2" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "black": { + "hashes": [ + "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", + "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" + ], + "index": "pypi", + "version": "==19.3b0" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "version": "==0.3" + }, + "flake8": { + "hashes": [ + "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", + "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" + ], + "index": "pypi", + "version": "==3.7.8" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "pathtools": { + "hashes": [ + "sha256:609a312e8044d2d9243a98df8fe4aa06c82e2efdf8a4360237a1723092ee9f20", + "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0" + ], + "version": "==0.1.2" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, + "pyflakes": { + "hashes": [ + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" + ], + "version": "==2.1.1" + }, + "pyyaml": { + "hashes": [ + "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", + "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", + "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", + "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", + "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", + "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", + "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", + "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", + "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", + "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", + "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", + "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", + "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8" + ], + "version": "==5.1.2" + }, + "toml": { + "hashes": [ + "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", + "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + ], + "version": "==0.10.0" + }, + "watchdog": { + "hashes": [ + "sha256:965f658d0732de3188211932aeb0bb457587f04f63ab4c1e33eab878e9de961d" + ], + "index": "pypi", + "version": "==0.9.0" + } + } +} From 37bae6b2d05eb74039b15f1799bb1d4631b9fd1f Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 16 Sep 2019 15:25:35 +0900 Subject: [PATCH 13/60] Update Python environment --- object-detection/Dockerfile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 04980c5..64475ed 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,13 +1,10 @@ FROM ubuntu:18.04 -RUN apt-get update && \ - apt-get install -y --no-install-recommends python3.7 wget gnupg curl ca-certificates && \ - apt-get download python3-distutils && \ - dpkg-deb -x python3-distutils* / && \ - rm python3-distutils* && \ - update-ca-certificates +ENV LANG C.UTF-8 -RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python3.7 && \ +RUN apt-get update && \ + apt-get install -y --no-install-recommends python3.7 libpython3.7-dev python3-pip wget curl gnupg ca-certificates && \ + update-ca-certificates && \ pip3 install pipenv # ENV PIPENV_YES true @@ -18,7 +15,8 @@ RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-20 bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ apt-key adv --keyserver apt.repos.intel.com --recv-keys && \ apt-get update && \ - apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release + apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release libgtk-3-dev # TODO /opt/intel/openvino/install_dependicy.sh の必要性とその中で行われるので省略できる処理の確認 RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc +# ENV PYTHONPATH /opt/intel/openvino/python/python3.7:$PYTHONPATH From 8a459d16bd3ed69ea9f767409dd3e49e33bb3cfa Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 18 Sep 2019 00:56:08 +0900 Subject: [PATCH 14/60] Update Python environment --- object-detection/Dockerfile | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 64475ed..3a0ee67 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -1,22 +1,36 @@ FROM ubuntu:18.04 +ARG NUM_THREADS=1 ENV LANG C.UTF-8 RUN apt-get update && \ - apt-get install -y --no-install-recommends python3.7 libpython3.7-dev python3-pip wget curl gnupg ca-certificates && \ + apt-get install -y --no-install-recommends python3.7 libpython3.7-dev python3-pip wget curl unzip gnupg ca-certificates lsb-release && \ update-ca-certificates && \ pip3 install pipenv # ENV PIPENV_YES true ENV PIPENV_VENV_IN_PROJECT true +# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_apt.html RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-2019 && \ apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2019 & \ bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ apt-key adv --keyserver apt.repos.intel.com --recv-keys && \ apt-get update && \ - apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release libgtk-3-dev -# TODO /opt/intel/openvino/install_dependicy.sh の必要性とその中で行われるので省略できる処理の確認 + apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libgtk-3-dev + +# install_openvino_dependencies.sh か libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release のすべてのどちらか +RUN apt-get install -y --no-install-recommends && \ + /opt/intel/openvino/install_dependencies/install_openvino_dependencies.sh +# libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release + +# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#run_the_docker_image_for_intel_movidius_neural_compute_stick_and_intel_neural_compute_stick_2 +RUN cd /tmp/ && \ + wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ + unzip v1.0.22.zip && cd libusb-1.0.22 && \ + ./bootstrap.sh && \ + ./configure --disable-udev --enable-shared && \ + make -j${NUM_THREADS} && make install && \ + rm -rf /tmp/* RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc -# ENV PYTHONPATH /opt/intel/openvino/python/python3.7:$PYTHONPATH From 7e8fbd851e1a01050ebea4ab4467abbeff6c5611 Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 18 Sep 2019 01:48:39 +0900 Subject: [PATCH 15/60] Add dockerignore --- object-detection/.dockerignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 object-detection/.dockerignore diff --git a/object-detection/.dockerignore b/object-detection/.dockerignore new file mode 100644 index 0000000..2d71cf8 --- /dev/null +++ b/object-detection/.dockerignore @@ -0,0 +1,2 @@ +src/node_modules +src/.venv From febad5fb76aa61c07c08bf52fcccb6fb683575c1 Mon Sep 17 00:00:00 2001 From: ilim Date: Thu, 19 Sep 2019 00:48:08 +0900 Subject: [PATCH 16/60] Add Python startup command & use OpenVINO Inference Engine Python API --- docker-compose.debug.yml | 9 ++++ docker-compose.prod.yml | 7 +++ object-detection/src/Pipfile | 7 ++- object-detection/src/Pipfile.lock | 89 +++++++++++++++++++++++++++++-- object-detection/src/main.py | 68 +++++++++++++++++++++-- object-detection/src/model.py | 59 ++++++++++++++++++++ 6 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 object-detection/src/model.py diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 0a3e288..d991634 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -124,9 +124,18 @@ services: context: ./object-detection working_dir: /app command: pipenv run dev + environment: + - RTMP_SERVER_URL=rtmp://streaming-server:1935/live + - STREAM_NAME=bushitsuchan + - INFERENCE_INTERVAL_SEC=60 + - DEVICE=CPU + - MODEL_FILE=classification/alexnet.xml + - WEIGHTS_FILE=classification/alexnet.bin privileged: true volumes: - ./object-detection/src:/app - /dev:/dev + ports: + - 5678:5678 depends_on: - streamer diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index b79c103..6077f67 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -118,6 +118,13 @@ services: context: ./object-detection working_dir: /app command: bash -c "pipenv sync && pipenv run start" + environment: + - RTMP_SERVER_URL=rtmp://streaming-server:1935/live + - STREAM_NAME=bushitsuchan + - INFERENCE_INTERVAL_SEC=60 + - DEVICE=MYRIAD + - MODEL_FILE=classification/alexnet.xml + - WEIGHTS_FILE=classification/alexnet.bin privileged: true volumes: - ./object-detection/src:/app diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 933f90a..b5d73de 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -6,7 +6,9 @@ verify_ssl = true [dev-packages] black = "~=19.3b0" flake8 = "~=3.7.8" +mypy = "~=0.720" watchdog = "~=0.9.0" +ptvsd = "~=4.3.2" [packages] opencv-python = "~=4.1.1.26" @@ -15,8 +17,9 @@ opencv-python = "~=4.1.1.26" python_version = "3.7" [scripts] -start = "python main.py" -dev = "watchmedo shell-command --patterns='*.py' --command='python main.py' ." +start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" +# dev = "watchmedo shell-command --patterns='*.py' --command='source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 --port 5678 --wait main,py' ." +dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" lint = "flake8 --exclude .venv ." format = "black ." diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index 78c5a78..1029f47 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "cbf5e8f168d2961b7627c7aa00d042add27561b73ec84413588655c52f404dbe" + "sha256": "95c152d37c0bae952231ffd2d0ad21e2e3bf7f3b999c5045d18aac87a1f1e2e4" }, "pipfile-spec": 6, "requires": { @@ -130,13 +130,68 @@ ], "version": "==0.6.1" }, + "mypy": { + "hashes": [ + "sha256:0107bff4f46a289f0e4081d59b77cef1c48ea43da5a0dbf0005d54748b26df2a", + "sha256:07957f5471b3bb768c61f08690c96d8a09be0912185a27a68700f3ede99184e4", + "sha256:10af62f87b6921eac50271e667cc234162a194e742d8e02fc4ddc121e129a5b0", + "sha256:11fd60d2f69f0cefbe53ce551acf5b1cec1a89e7ce2d47b4e95a84eefb2899ae", + "sha256:15e43d3b1546813669bd1a6ec7e6a11d2888db938e0607f7b5eef6b976671339", + "sha256:352c24ba054a89bb9a35dd064ee95ab9b12903b56c72a8d3863d882e2632dc76", + "sha256:437020a39417e85e22ea8edcb709612903a9924209e10b3ec6d8c9f05b79f498", + "sha256:49925f9da7cee47eebf3420d7c0e00ec662ec6abb2780eb0a16260a7ba25f9c4", + "sha256:6724fcd5777aa6cebfa7e644c526888c9d639bd22edd26b2a8038c674a7c34bd", + "sha256:7a17613f7ea374ab64f39f03257f22b5755335b73251d0d253687a69029701ba", + "sha256:cdc1151ced496ca1496272da7fc356580e95f2682be1d32377c22ddebdf73c91" + ], + "index": "pypi", + "version": "==0.720" + }, + "mypy-extensions": { + "hashes": [ + "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812", + "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e" + ], + "version": "==0.4.1" + }, "pathtools": { "hashes": [ - "sha256:609a312e8044d2d9243a98df8fe4aa06c82e2efdf8a4360237a1723092ee9f20", - "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0" + "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0", + "sha256:85bd793aca926dad9e38432b4fd4fae33c96935a04981a6c537aeafc6430f578" ], "version": "==0.1.2" }, + "ptvsd": { + "hashes": [ + "sha256:10745fbb788001959b4de405198d8bd5243611a88fb5a2e2c6800245bc0ddd74", + "sha256:1d3d82ecc82186d099992a748556e6e54037f5c5e4d3fc9bba3e2302354be0d4", + "sha256:20f48ffed42a6beb879c250d82662e175ad59cc46a29c95c6a4472ae413199c5", + "sha256:22b699369a18ff28d4d1aa6a452739e50c7b7790cb16c6312d766e023c12fe27", + "sha256:2bbc121bce3608501998afbe742f02b80e7d26b8fecd38f78b903f22f52a81d9", + "sha256:3b05c06018fdbce5943c50fb0baac695b5c11326f9e21a5266c854306bda28ab", + "sha256:3f839fe91d9ddca0d6a3a0afd6a1c824be1768498a737ab9333d084c5c3f3591", + "sha256:459137736068bb02515040b2ed2738169cb30d69a38e0fd5dffcba255f41e68d", + "sha256:58508485a1609a495dd45829bd6d219303cf9edef5ca1f01a9ed8ffaa87f390c", + "sha256:612948a045fcf9c8931cd306972902440278f34de7ca684b49d4caeec9f1ec62", + "sha256:70260b4591c07bff95566d49b6a5dc3051d8558035c43c847bad9a954def46bb", + "sha256:72d114baa5737baf29c8068d1ccdd93cbb332d2030601c888eed0e3761b588d7", + "sha256:90cbd082e7a9089664888d0d94aca760202f080133fca8f3fe65c48ed6b9e39d", + "sha256:92d26aa7c8f7ffe41cb4b50a00846027027fa17acdf2d9dd8c24de77b25166c6", + "sha256:b9970e3dc987eb2a6001af6c9d2f726dd6455cfc6d47e0f51925cbdee7ea2157", + "sha256:c01204e3f025c3f7252c79c1a8a028246d29e3ef339e1a01ddf652999f47bdea", + "sha256:c893fb9d1c2ef8f980cc00ced3fd90356f86d9f59b58ee97e0e7e622b8860f76", + "sha256:c97c71835dde7e67fc7b06398bee1c012559a0784ebda9cf8acaf176c7ae766c", + "sha256:ccc5c533135305709461f545feed5061c608714db38fa0f58e3f848a127b7fde", + "sha256:cf09fd4d90c4c42ddd9bf853290f1a80bc2128993a3923bd3b96b68cc1acd03f", + "sha256:d2662ec37ee049c0f8f2f9a378abeb7e570d9215c19eaf0a6d7189464195009f", + "sha256:d9337ebba4d099698982e090b203e85670086c4b29cf1185b2e45cd353a8053e", + "sha256:de5234bec74c47da668e1a1a21bcc9821af0cbb28b5153df78cd5abc744b29a2", + "sha256:eda10ecd43daacc180a6fbe524992be76a877c3559e2b78016b4ada8fec10273", + "sha256:fad06de012a78f277318d0c308dd3d7cc1f67167f3b2e1e2f7c6caf04c03440c" + ], + "index": "pypi", + "version": "==4.3.2" + }, "pycodestyle": { "hashes": [ "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", @@ -176,6 +231,34 @@ ], "version": "==0.10.0" }, + "typed-ast": { + "hashes": [ + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "version": "==1.4.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:2ed632b30bb54fc3941c382decfd0ee4148f5c591651c9272473fea2c6397d95", + "sha256:b1edbbf0652660e32ae780ac9433f4231e7339c7f9a8057d0f042fcbcea49b87", + "sha256:d8179012ec2c620d3791ca6fe2bf7979d979acdbef1fca0bc56b37411db682ed" + ], + "version": "==3.7.4" + }, "watchdog": { "hashes": [ "sha256:965f658d0732de3188211932aeb0bb457587f04f63ab4c1e33eab878e9de961d" diff --git a/object-detection/src/main.py b/object-detection/src/main.py index 6d039c8..8653ec2 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -1,11 +1,73 @@ #!/usr/bin/env python3 -from time import sleep +import os +import argparse +import cv2 +# from logging import getLogger +import json +import asyncio +from model import Net + +# logger = getLogger(__name__) + +parser = argparse.ArgumentParser() +parser.add_argument( + "-l", "--cpu-extension", + help="Required for CPU custom layers. MKLDNN (CPU)-targeted custom layers. Absolute path to a shared library with " + "the kernels implementations.", + type=str) +parser.add_argument( + "-d", "--device", + help="Specify the target device to infer. The sample will look for a suitable plugin for device specified.", + default=os.getenv("DEVICE", "CPU"), + choices=["CPU", "GPU", "FPGA", "HDDL", "MYRIAD", "HETERO"], + type=str) +parser.add_argument( + "--interval", + help="Infers through the network every specified number of seconds.", + default=os.getenv("INFERENCE_INTERVAL_SEC", 60 * 5), + type=int) +parser.add_argument( + "--rtmp-server-url", + help="Streaming server address starting with rtmp:// .", + default=os.getenv("RTMP_SERVER_URL", "rtmp://streaming-server/live"), + type=str) +parser.add_argument( + "--stream-name", + help="The stream name assigned to the stream on the streaming server.", + default=os.getenv("STREAM_NAME"), + type=str) +parser.add_argument( + "--model-file", + help="The path of .xml file where network model data is described.", + default=os.getenv("MODEL_FILE"), + type=str) +parser.add_argument( + "--weights-file", + help="The path of the .bin file that describes the network weight.", + default=os.getenv("WEIGHTS_FILE"), + type=str) def main(): - while 1: - sleep(1) + args = parser.parse_args() + print(json.dumps(args.__dict__, indent=2)) + + cap = cv2.VideoCapture(f"{args.rtmp_server_url}/{args.stream_name}") + net = Net(args.model_file, args.weights_file, args.device, args.cpu_extension, cap) + + loop = asyncio.get_event_loop() + loop.call_later(args.interval, inference, net, loop) + loop.run_forever() + + # loop.close() + + +def inference(net: Net, loop=None): + loop = loop or asyncio.get_event_loop() + ouput = net() + loop.stop() if __name__ == "__main__": + print("start") main() diff --git a/object-detection/src/model.py b/object-detection/src/model.py new file mode 100644 index 0000000..ce83f52 --- /dev/null +++ b/object-detection/src/model.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +from openvino.inference_engine import IENetwork, IECore +import cv2 +import numpy as np + + +class Net: + def __init__(self, model_file: str, weights_file: str, cap: cv2.VideoCapture, device: str = "CPU", + cpu_extension: str = None) -> None: + self.cap = cap + self.device = device # TODO MYRIAD無いのに指定されたときの処理 + self.ie = IECore() + self.network = self.get_network(model_file, weights_file, device, cpu_extension) + + self.input_blob: str = next(iter(self.network.inputs)) + self.out_blob: str = next(iter(self.network.outputs)) + self.network.batch_size = 1 + + self.input_shape = self.network.inputs[self.input_blob].shape # TODO type hint + + def get_network(self, model_file: str, weights_file: str, device: str, cpu_extension: str) -> IENetwork: + if cpu_extension and device == "CPU": + self.ie.add_extension(cpu_extension, "CPU") + + network = IENetwork(model=model_file, weights=weights_file) + + if "CPU" == device: + supported_layers = self.ie.query_network(network, "CPU") + if len(supported_layers) == len(network.layers): # TODO check len(network.layers) return int + print("Several layers are not supported by the plugin for specified device.") + print("Please try to specify cpu extensions library path in sample's command line parameters using -l " + "or --cpu_extension command line argument") + raise + + assert len(network.inputs.keys()) == 1, "Sample supports only single input topologies" # TODO keysの必要性 + assert len(network.outputs) == 1, "Sample supports only single output topologies" + + return network + + def __call__(self): # TODO return type + ret, frame = self.cap.read() + assert ret, f"Can't get image from {self.cap}" # TODO capのf-string内での表示 + images = np.expand_dims(self.transform(frame), 0) + + output = self.forward(images) + return output + + @staticmethod + def transform(x: np.ndarray) -> np.ndarray: + # TODO RGBの順序 + x = x.transpose((2, 0, 1)) + + return x + + def forward(self, x: np.ndarray): # TODO return type + exec_net = self.ie.load_network(network=self.network, device_name=self.device) + output = exec_net.infer(inputs={self.input_blob: x})[self.out_blob] + return output From b30cc1bf374de3ee6fec2a5da3f9f5b760936913 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 23 Sep 2019 01:26:25 +0900 Subject: [PATCH 17/60] Change to formatter due to conflict & preparation for model_downloader --- docker-compose.debug.yml | 6 +- object-detection/.dockerignore | 2 + object-detection/Dockerfile | 2 +- object-detection/src/Pipfile | 17 +- object-detection/src/Pipfile.lock | 336 +++++++++++++++++++++++++++--- 5 files changed, 320 insertions(+), 43 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index d991634..459e40f 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -123,14 +123,14 @@ services: build: context: ./object-detection working_dir: /app - command: pipenv run dev + command: sleep 10000000 environment: - RTMP_SERVER_URL=rtmp://streaming-server:1935/live - STREAM_NAME=bushitsuchan - INFERENCE_INTERVAL_SEC=60 - DEVICE=CPU - - MODEL_FILE=classification/alexnet.xml - - WEIGHTS_FILE=classification/alexnet.bin + - MODEL_FILE=object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.xml + - WEIGHTS_FILE=object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.bin privileged: true volumes: - ./object-detection/src:/app diff --git a/object-detection/.dockerignore b/object-detection/.dockerignore index 2d71cf8..d3bc956 100644 --- a/object-detection/.dockerignore +++ b/object-detection/.dockerignore @@ -1,2 +1,4 @@ +openvino src/node_modules src/.venv +src/object_detection diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 3a0ee67..b021890 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -15,7 +15,7 @@ ENV PIPENV_VENV_IN_PROJECT true RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-2019 && \ apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2019 & \ bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ - apt-key adv --keyserver apt.repos.intel.com --recv-keys && \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1A8497B11911E097 && \ apt-get update && \ apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libgtk-3-dev diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index b5d73de..716d6fb 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -4,15 +4,23 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -black = "~=19.3b0" flake8 = "~=3.7.8" mypy = "~=0.720" +autopep8 = "~=1.4.4" +isort = "~=4.3.21" watchdog = "~=0.9.0" ptvsd = "~=4.3.2" [packages] +requests = "~=2.22.0" +pyyaml = "~=5.1.2" +networkx = ">=1.11" +tensorflow = ">=1.2.0,<2.0.0" +defusedxml = ">=0.5.0" +test-generator = "==0.1.1" opencv-python = "~=4.1.1.26" + [requires] python_version = "3.7" @@ -20,8 +28,5 @@ python_version = "3.7" start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" # dev = "watchmedo shell-command --patterns='*.py' --command='source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 --port 5678 --wait main,py' ." dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" -lint = "flake8 --exclude .venv ." -format = "black ." - -[pipenv] -allow_prereleases = true +lint = "bash -c 'mypy . && flake8 --show-source --exclude .venv .'" +format = "bash -c 'isort -rc . && autopep8 -ivr .'" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index 1029f47..e07f1a1 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "95c152d37c0bae952231ffd2d0ad21e2e3bf7f3b999c5045d18aac87a1f1e2e4" + "sha256": "b1eb0bea1fcb6b1ebf5d6db01ea45a8bc96dbe91d993becd9f32ff3fe01c9a81" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,166 @@ ] }, "default": { + "absl-py": { + "hashes": [ + "sha256:0ce45920056fbbb66f52fcee7408ba6311da19f55589b2b3aab9f8af92a0e1f2" + ], + "version": "==0.8.0" + }, + "astor": { + "hashes": [ + "sha256:0e41295809baf43ae8303350e031aff81ae52189b6f881f36d623fa8b2f1960e", + "sha256:37a6eed8b371f1228db08234ed7f6cfdc7817a3ed3824797e20cbb11dc2a7862" + ], + "version": "==0.8.0" + }, + "certifi": { + "hashes": [ + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" + ], + "version": "==2019.9.11" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "decorator": { + "hashes": [ + "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", + "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" + ], + "version": "==4.4.0" + }, + "defusedxml": { + "hashes": [ + "sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93", + "sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5" + ], + "index": "pypi", + "version": "==0.6.0" + }, + "gast": { + "hashes": [ + "sha256:5c7617f1f6c8b8b426819642b16b9016727ddaecd16af9a07753e537eba8a3a5" + ], + "version": "==0.3.2" + }, + "google-pasta": { + "hashes": [ + "sha256:40b4f55ba7b44823eac96d055000572c84ce48cacb3e91c100869844064b2d07", + "sha256:79d1ce28b381d68e98ef7707d19909adb58912f8dae8734402454424fc76b8fe", + "sha256:7ca8afc4cfeebf4a079cdf586333d5447cecd19a997475136138fc83c3351bc4" + ], + "version": "==0.1.7" + }, + "grpcio": { + "hashes": [ + "sha256:1303578092f1f6e4bfbc354c04ac422856c393723d3ffa032fff0f7cb5cfd693", + "sha256:229c6b313cd82bec8f979b059d87f03cc1a48939b543fe170b5a9c5cf6a6bc69", + "sha256:3cd3d99a8b5568d0d186f9520c16121a0f2a4bcad8e2b9884b76fb88a85a7774", + "sha256:41cfb222db358227521f9638a6fbc397f310042a4db5539a19dea01547c621cd", + "sha256:43330501660f636fd6547d1e196e395cd1e2c2ae57d62219d6184a668ffebda0", + "sha256:45d7a2bd8b4f25a013296683f4140d636cdbb507d94a382ea5029a21e76b1648", + "sha256:47dc935658a13b25108823dabd010194ddea9610357c5c1ef1ad7b3f5157ebee", + "sha256:480aa7e2b56238badce0b9413a96d5b4c90c3bfbd79eba5a0501e92328d9669e", + "sha256:4a0934c8b0f97e1d8c18e76c45afc0d02d33ab03125258179f2ac6c7a13f3626", + "sha256:5624dab19e950f99e560400c59d87b685809e4cfcb2c724103f1ab14c06071f7", + "sha256:60515b1405bb3dadc55e6ca99429072dad3e736afcf5048db5452df5572231ff", + "sha256:610f97ebae742a57d336a69b09a9c7d7de1f62aa54aaa8adc635b38f55ba4382", + "sha256:64ea189b2b0859d1f7b411a09185028744d494ef09029630200cc892e366f169", + "sha256:686090c6c1e09e4f49585b8508d0a31d58bc3895e4049ea55b197d1381e9f70f", + "sha256:7745c365195bb0605e3d47b480a2a4d1baa8a41a5fd0a20de5fa48900e2c886a", + "sha256:79491e0d2b77a1c438116bf9e5f9e2e04e78b78524615e2ce453eff62db59a09", + "sha256:825177dd4c601c487836b7d6b4ba268db59787157911c623ba59a7c03c8d3adc", + "sha256:8a060e1f72fb94eee8a035ed29f1201ce903ad14cbe27bda56b4a22a8abda045", + "sha256:90168cc6353e2766e47b650c963f21cfff294654b10b3a14c67e26a4e3683634", + "sha256:94b7742734bceeff6d8db5edb31ac844cb68fc7f13617eca859ff1b78bb20ba1", + "sha256:962aebf2dd01bbb2cdb64580e61760f1afc470781f9ecd5fe8f3d8dcd8cf4556", + "sha256:9c8d9eacdce840b72eee7924c752c31b675f8aec74790e08cff184a4ea8aa9c1", + "sha256:af5b929debc336f6bab9b0da6915f9ee5e41444012aed6a79a3c7e80d7662fdf", + "sha256:b9cdb87fc77e9a3eabdc42a512368538d648fa0760ad30cf97788076985c790a", + "sha256:c5e6380b90b389454669dc67d0a39fb4dc166416e01308fcddd694236b8329ef", + "sha256:d60c90fe2bfbee735397bf75a2f2c4e70c5deab51cd40c6e4fa98fae018c8db6", + "sha256:d8582c8b1b1063249da1588854251d8a91df1e210a328aeb0ece39da2b2b763b", + "sha256:ddbf86ba3aa0ad8fed2867910d2913ee237d55920b55f1d619049b3399f04efc", + "sha256:e46bc0664c5c8a0545857aa7a096289f8db148e7f9cca2d0b760113e8994bddc", + "sha256:f6437f70ec7fed0ca3a0eef1146591bb754b418bb6c6b21db74f0333d624e135", + "sha256:f71693c3396530c6b00773b029ea85e59272557e9bd6077195a6593e4229892a", + "sha256:f79f7455f8fbd43e8e9d61914ecf7f48ba1c8e271801996fef8d6a8f3cc9f39f" + ], + "version": "==1.23.0" + }, + "h5py": { + "hashes": [ + "sha256:063947eaed5f271679ed4ffa36bb96f57bc14f44dd4336a827d9a02702e6ce6b", + "sha256:13c87efa24768a5e24e360a40e0bc4c49bcb7ce1bb13a3a7f9902cec302ccd36", + "sha256:16ead3c57141101e3296ebeed79c9c143c32bdd0e82a61a2fc67e8e6d493e9d1", + "sha256:3dad1730b6470fad853ef56d755d06bb916ee68a3d8272b3bab0c1ddf83bb99e", + "sha256:51ae56894c6c93159086ffa2c94b5b3388c0400548ab26555c143e7cfa05b8e5", + "sha256:54817b696e87eb9e403e42643305f142cd8b940fe9b3b490bbf98c3b8a894cf4", + "sha256:549ad124df27c056b2e255ea1c44d30fb7a17d17676d03096ad5cd85edb32dc1", + "sha256:6998be619c695910cb0effe5eb15d3a511d3d1a5d217d4bd0bebad1151ec2262", + "sha256:6ef7ab1089e3ef53ca099038f3c0a94d03e3560e6aff0e9d6c64c55fb13fc681", + "sha256:769e141512b54dee14ec76ed354fcacfc7d97fea5a7646b709f7400cf1838630", + "sha256:79b23f47c6524d61f899254f5cd5e486e19868f1823298bc0c29d345c2447172", + "sha256:7be5754a159236e95bd196419485343e2b5875e806fe68919e087b6351f40a70", + "sha256:84412798925dc870ffd7107f045d7659e60f5d46d1c70c700375248bf6bf512d", + "sha256:86868dc07b9cc8cb7627372a2e6636cdc7a53b7e2854ad020c9e9d8a4d3fd0f5", + "sha256:8bb1d2de101f39743f91512a9750fb6c351c032e5cd3204b4487383e34da7f75", + "sha256:a5f82cd4938ff8761d9760af3274acf55afc3c91c649c50ab18fcff5510a14a5", + "sha256:aac4b57097ac29089f179bbc2a6e14102dd210618e94d77ee4831c65f82f17c0", + "sha256:bffbc48331b4a801d2f4b7dac8a72609f0b10e6e516e5c480a3e3241e091c878", + "sha256:c0d4b04bbf96c47b6d360cd06939e72def512b20a18a8547fa4af810258355d5", + "sha256:c54a2c0dd4957776ace7f95879d81582298c5daf89e77fb8bee7378f132951de", + "sha256:cbf28ae4b5af0f05aa6e7551cee304f1d317dbed1eb7ac1d827cee2f1ef97a99", + "sha256:d3c59549f90a891691991c17f8e58c8544060fdf3ccdea267100fa5f561ff62f", + "sha256:d7ae7a0576b06cb8e8a1c265a8bc4b73d05fdee6429bffc9a26a6eb531e79d72", + "sha256:ecf4d0b56ee394a0984de15bceeb97cbe1fe485f1ac205121293fc44dcf3f31f", + "sha256:f0e25bb91e7a02efccb50aba6591d3fe2c725479e34769802fcdd4076abfa917", + "sha256:f23951a53d18398ef1344c186fb04b26163ca6ce449ebd23404b153fd111ded9", + "sha256:ff7d241f866b718e4584fa95f520cb19405220c501bd3a53ee11871ba5166ea2" + ], + "version": "==2.10.0" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "keras-applications": { + "hashes": [ + "sha256:5579f9a12bcde9748f4a12233925a59b93b73ae6947409ff34aa2ba258189fe5", + "sha256:df4323692b8c1174af821bf906f1e442e63fa7589bf0f1230a0b6bdc5a810c95" + ], + "version": "==1.0.8" + }, + "keras-preprocessing": { + "hashes": [ + "sha256:44aee5f2c4d80c3b29f208359fcb336df80f293a0bb6b1c738da43ca206656fb", + "sha256:5a8debe01d840de93d49e05ccf1c9b81ae30e210d34dacbcc47aeb3049b528e5" + ], + "version": "==1.1.0" + }, + "markdown": { + "hashes": [ + "sha256:2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", + "sha256:56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c" + ], + "version": "==3.1.1" + }, + "networkx": { + "hashes": [ + "sha256:8311ddef63cf5c5c5e7c1d0212dd141d9a1fe3f474915281b73597ed5f1d4e3d" + ], + "index": "pypi", + "version": "==2.3" + }, "numpy": { "hashes": [ "sha256:05dbfe72684cc14b92568de1bc1f41e5f62b00f714afc9adee42f6311738091f", @@ -69,44 +229,153 @@ ], "index": "pypi", "version": "==4.1.1.26" - } - }, - "develop": { - "appdirs": { + }, + "protobuf": { "hashes": [ - "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", - "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + "sha256:00a1b0b352dc7c809749526d1688a64b62ea400c5b05416f93cfb1b11a036295", + "sha256:01acbca2d2c8c3f7f235f1842440adbe01bbc379fa1cbdd80753801432b3fae9", + "sha256:0a795bca65987b62d6b8a2d934aa317fd1a4d06a6dd4df36312f5b0ade44a8d9", + "sha256:0ec035114213b6d6e7713987a759d762dd94e9f82284515b3b7331f34bfaec7f", + "sha256:31b18e1434b4907cb0113e7a372cd4d92c047ce7ba0fa7ea66a404d6388ed2c1", + "sha256:32a3abf79b0bef073c70656e86d5bd68a28a1fbb138429912c4fc07b9d426b07", + "sha256:55f85b7808766e5e3f526818f5e2aeb5ba2edcc45bcccede46a3ccc19b569cb0", + "sha256:64ab9bc971989cbdd648c102a96253fdf0202b0c38f15bd34759a8707bdd5f64", + "sha256:64cf847e843a465b6c1ba90fb6c7f7844d54dbe9eb731e86a60981d03f5b2e6e", + "sha256:917c8662b585470e8fd42f052661fc66d59fccaae450a60044307dcbf82a3335", + "sha256:afed9003d7f2be2c3df20f64220c30faec441073731511728a2cb4cab4cd46a6", + "sha256:bf8e05d638b585d1752c5a84247134a0350d3a8b73d3632489a014a9f6f1e758", + "sha256:d831b047bd69becaf64019a47179eb22118a50dd008340655266a906c69c6417", + "sha256:de2760583ed28749ff885789c1cbc6c9c06d6de92fc825740ab99deb2f25ea4d", + "sha256:eabc4cf1bc19689af8022ba52fd668564a8d96e0d08f3b4732d26a64255216a4", + "sha256:fcff6086c86fb1628d94ea455c7b9de898afc50378042927a59df8065a79a549" ], - "version": "==1.4.3" + "version": "==3.9.1" }, - "argh": { + "pyyaml": { "hashes": [ - "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3", - "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65" + "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", + "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", + "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", + "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", + "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", + "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", + "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", + "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", + "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", + "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", + "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", + "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", + "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8" ], - "version": "==0.26.2" + "index": "pypi", + "version": "==5.1.2" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" }, - "attrs": { + "tensorboard": { "hashes": [ - "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", - "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + "sha256:50e0b1bdcd488dbe39fd9416976e089b2ff4df18d9f1fab47abf4c498209c3fc", + "sha256:c35ba681a52d4922be6b225623cf77285033e7e4e68bac5c1d5490e47d129bb2" ], - "version": "==19.1.0" + "version": "==1.14.0" }, - "black": { + "tensorflow": { "hashes": [ - "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", - "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" + "sha256:0a3784c6ab223b85a87ba6b752d2e6dc97b9345c078172d9b0bb90f3e448a320", + "sha256:0a95ab659de39748c418f342fd09bc444a21a7d66f4501593cf7ff6de3c603b1", + "sha256:2fc989a5d3be9f3dc96c20deaa3d5cc66d2bf76fe069c202c2914a7f4b5a9a35", + "sha256:4008a56940d23345e52ac4885fb4782604eb02574c2d95f3946f5b6baf0e1276", + "sha256:4643fcb6aa7bf9261620efe332f821ccdb63422ed5df33479e3c9592659cd64e", + "sha256:46fc216db780b1a7b7a28cf6536d6ec0a171ef2fa546a24934ffe077c734c891", + "sha256:5a9555eee142324a1cc3d6a5a9c0c8154ded8d013bf18cb459bc375e5d365191", + "sha256:5ce034dba1db7cd829af2bf092c48dce96bb3da3e89223d7cb50f3eac2ddc19f", + "sha256:7dfefd6fc79fed477c2c550cb79f766fb40533e907e4efbfabc81339b45551a4", + "sha256:a3851118d2cc5e9e697503753c2d247dca0e98d5a85b5ea091103f27d9e57a38", + "sha256:a4f154fa98cde5974117e05af444e0bed84cf431b8129c78a2de03a1ff7201c9", + "sha256:c77888375ef02a5e7e55f81572db1bfa41e6f6597ae297e7bdafb22bf633f79e", + "sha256:d982a6fef251ec1358129213385ec027f87ee72246dffe1136ca6109def209f7", + "sha256:e20b5d81b07798db5054802405758fb685367772f1d602d359ba60baa34b6b46", + "sha256:e84f2c8c7f23ad546076b1e73cec85706da19910b9a89c29cba3b64e297b2eb0" ], "index": "pypi", - "version": "==19.3b0" + "version": "==1.14.0" }, - "click": { + "tensorflow-estimator": { "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + "sha256:ca073f66063407a091d610ec1b22e39ea30248710198cc6f13769320bdbe3992" ], - "version": "==7.0" + "version": "==1.14.0" + }, + "termcolor": { + "hashes": [ + "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" + ], + "version": "==1.1.0" + }, + "test-generator": { + "hashes": [ + "sha256:01e6aa3e01b5a0cb2ef05c80cdb259abae820d82f07ffcd0ded9bce03f3c38d4", + "sha256:da9cfc2a26bc5bd1f43ef20050fd531790cc5283adcc49e34e0cf33345d6583d" + ], + "index": "pypi", + "version": "==0.1.1" + }, + "urllib3": { + "hashes": [ + "sha256:2f3eadfea5d92bc7899e75b5968410b749a054b492d5a6379c1344a1481bc2cb", + "sha256:9c6c593cb28f52075016307fc26b0a0f8e82bc7d1ff19aaaa959b91710a56c47" + ], + "version": "==1.25.5" + }, + "werkzeug": { + "hashes": [ + "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", + "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" + ], + "version": "==0.16.0" + }, + "wheel": { + "hashes": [ + "sha256:10c9da68765315ed98850f8e048347c3eb06dd81822dc2ab1d4fde9dc9702646", + "sha256:f4da1763d3becf2e2cd92a14a7c920f0f00eca30fdde9ea992c836685b9faf28" + ], + "markers": "python_version >= '3'", + "version": "==0.33.6" + }, + "wrapt": { + "hashes": [ + "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + ], + "version": "==1.11.2" + } + }, + "develop": { + "argh": { + "hashes": [ + "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3", + "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65" + ], + "version": "==0.26.2" + }, + "autopep8": { + "hashes": [ + "sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee" + ], + "index": "pypi", + "version": "==1.4.4" }, "entrypoints": { "hashes": [ @@ -123,6 +392,14 @@ "index": "pypi", "version": "==3.7.8" }, + "isort": { + "hashes": [ + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + ], + "index": "pypi", + "version": "==4.3.21" + }, "mccabe": { "hashes": [ "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", @@ -156,8 +433,7 @@ }, "pathtools": { "hashes": [ - "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0", - "sha256:85bd793aca926dad9e38432b4fd4fae33c96935a04981a6c537aeafc6430f578" + "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0" ], "version": "==0.1.2" }, @@ -222,15 +498,9 @@ "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8" ], + "index": "pypi", "version": "==5.1.2" }, - "toml": { - "hashes": [ - "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", - "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" - ], - "version": "==0.10.0" - }, "typed-ast": { "hashes": [ "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", From 38147be05d43fb3ac396e4879b7dc11bf47ae887 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 23 Sep 2019 15:31:00 +0900 Subject: [PATCH 18/60] Organize class for models --- .gitignore | 4 +++ docker-compose.debug.yml | 6 ++-- object-detection/.dockerignore | 3 +- object-detection/Dockerfile | 2 +- object-detection/src/Pipfile | 3 +- object-detection/src/get_model.sh | 9 ++++++ object-detection/src/main.py | 4 +-- object-detection/src/model.py | 54 +++++++++++++++++++++++-------- 8 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 object-detection/src/get_model.sh diff --git a/.gitignore b/.gitignore index 5fe6973..f7fb29c 100644 --- a/.gitignore +++ b/.gitignore @@ -244,3 +244,7 @@ dmypy.json *.http yarn.lock + +# model data +openvino +models diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 459e40f..a74d2fc 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -123,14 +123,14 @@ services: build: context: ./object-detection working_dir: /app - command: sleep 10000000 + command: pipenv run dev environment: - RTMP_SERVER_URL=rtmp://streaming-server:1935/live - STREAM_NAME=bushitsuchan - INFERENCE_INTERVAL_SEC=60 - DEVICE=CPU - - MODEL_FILE=object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.xml - - WEIGHTS_FILE=object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.bin + - MODEL_FILE=models/object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.xml + - WEIGHTS_FILE=models/object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.bin privileged: true volumes: - ./object-detection/src:/app diff --git a/object-detection/.dockerignore b/object-detection/.dockerignore index d3bc956..32f0268 100644 --- a/object-detection/.dockerignore +++ b/object-detection/.dockerignore @@ -1,4 +1,5 @@ openvino src/node_modules src/.venv -src/object_detection +src/.cache +src/models diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index b021890..063b747 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -15,7 +15,7 @@ ENV PIPENV_VENV_IN_PROJECT true RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-2019 && \ apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2019 & \ bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1A8497B11911E097 && \ + apt-key adv --recv-keys 1A8497B11911E097 && \ apt-get update && \ apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libgtk-3-dev diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 716d6fb..77f17d9 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -26,7 +26,6 @@ python_version = "3.7" [scripts] start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" -# dev = "watchmedo shell-command --patterns='*.py' --command='source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 --port 5678 --wait main,py' ." -dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" +dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 --port 5678 --wait main.py'" lint = "bash -c 'mypy . && flake8 --show-source --exclude .venv .'" format = "bash -c 'isort -rc . && autopep8 -ivr .'" diff --git a/object-detection/src/get_model.sh b/object-detection/src/get_model.sh new file mode 100644 index 0000000..a8aa793 --- /dev/null +++ b/object-detection/src/get_model.sh @@ -0,0 +1,9 @@ +python /opt/intel/openvino/deployment_tools/tools/model_downloader/downloader.py \ + --name faster_rcnn_resnet101_coco \ + --cache_dir ./.cache \ + --output_dir ./models + +python /opt/intel/openvino/deployment_tools/tools/model_downloader/converter.py \ + --name faster_rcnn_resnet101_coco \ + --mo /opt/intel/openvino/deployment_tools/model_optimizer/mo.py \ + --download_dir ./models diff --git a/object-detection/src/main.py b/object-detection/src/main.py index 8653ec2..873d2c8 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -5,7 +5,7 @@ # from logging import getLogger import json import asyncio -from model import Net +from model import Net, FasterRCNNResnet101Coco # logger = getLogger(__name__) @@ -53,7 +53,7 @@ def main(): print(json.dumps(args.__dict__, indent=2)) cap = cv2.VideoCapture(f"{args.rtmp_server_url}/{args.stream_name}") - net = Net(args.model_file, args.weights_file, args.device, args.cpu_extension, cap) + net = FasterRCNNResnet101Coco(args.model_file, args.weights_file, args.device, args.cpu_extension, cap) loop = asyncio.get_event_loop() loop.call_later(args.interval, inference, net, loop) diff --git a/object-detection/src/model.py b/object-detection/src/model.py index ce83f52..478e06a 100644 --- a/object-detection/src/model.py +++ b/object-detection/src/model.py @@ -1,25 +1,36 @@ #!/usr/bin/env python3 +from typing import List, Dict from openvino.inference_engine import IENetwork, IECore import cv2 import numpy as np class Net: - def __init__(self, model_file: str, weights_file: str, cap: cv2.VideoCapture, device: str = "CPU", - cpu_extension: str = None) -> None: + def __init__( + self, + model_file: str, + weights_file: str, + cap: cv2.VideoCapture, + device: str = "CPU", + cpu_extension: str = None, + ) -> None: self.cap = cap self.device = device # TODO MYRIAD無いのに指定されたときの処理 self.ie = IECore() self.network = self.get_network(model_file, weights_file, device, cpu_extension) - self.input_blob: str = next(iter(self.network.inputs)) + self.input_blobs: List[str] = list(self.network.inputs) self.out_blob: str = next(iter(self.network.outputs)) self.network.batch_size = 1 - self.input_shape = self.network.inputs[self.input_blob].shape # TODO type hint + self.input_shapes: Dict[str, List[int]] = { + key: value.shape for key, value in self.network.inputs.items() + } - def get_network(self, model_file: str, weights_file: str, device: str, cpu_extension: str) -> IENetwork: + def get_network( + self, model_file: str, weights_file: str, device: str, cpu_extension: str + ) -> IENetwork: if cpu_extension and device == "CPU": self.ie.add_extension(cpu_extension, "CPU") @@ -27,17 +38,31 @@ def get_network(self, model_file: str, weights_file: str, device: str, cpu_exten if "CPU" == device: supported_layers = self.ie.query_network(network, "CPU") - if len(supported_layers) == len(network.layers): # TODO check len(network.layers) return int - print("Several layers are not supported by the plugin for specified device.") - print("Please try to specify cpu extensions library path in sample's command line parameters using -l " - "or --cpu_extension command line argument") + if len(supported_layers) == len( + network.layers + ): # TODO check len(network.layers) return int + print( + "Several layers are not supported by the plugin for specified device." + ) + print( + "Please try to specify cpu extensions library path in sample's command line parameters using -l " + "or --cpu_extension command line argument" + ) raise - assert len(network.inputs.keys()) == 1, "Sample supports only single input topologies" # TODO keysの必要性 - assert len(network.outputs) == 1, "Sample supports only single output topologies" - + assert ( + len(network.outputs) == 1 + ), "Sample supports only single output topologies" return network + def __call__(): + raise NotImplementedError + + +class FasterRCNNResnet101Coco(Net): + def __init__(self, *args, **kwargs) -> None: + super(self).__init__(*args, **kwargs) + def __call__(self): # TODO return type ret, frame = self.cap.read() assert ret, f"Can't get image from {self.cap}" # TODO capのf-string内での表示 @@ -48,12 +73,13 @@ def __call__(self): # TODO return type @staticmethod def transform(x: np.ndarray) -> np.ndarray: - # TODO RGBの順序 + # TODO RGBの順序 resize x = x.transpose((2, 0, 1)) return x def forward(self, x: np.ndarray): # TODO return type exec_net = self.ie.load_network(network=self.network, device_name=self.device) - output = exec_net.infer(inputs={self.input_blob: x})[self.out_blob] + inputs = {key: x for key in self.input_blobs} # TODO x + output = exec_net.infer(inputs=inputs)[self.out_blob] return output From 4be6beeea107793bca414bb9e80781487dd5d41f Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 23 Sep 2019 19:41:56 +0900 Subject: [PATCH 19/60] Add docker-compose.update.yml --- utils/docker-compose.install.yml | 14 ++++----- utils/docker-compose.update.yml | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 utils/docker-compose.update.yml diff --git a/utils/docker-compose.install.yml b/utils/docker-compose.install.yml index 41a51c8..b0f7bbe 100644 --- a/utils/docker-compose.install.yml +++ b/utils/docker-compose.install.yml @@ -3,14 +3,14 @@ services: streaming-server: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm ci" volumes: - ../streaming-server/src:/app media: build: ../media working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm ci" entrypoint: docker-entrypoint.sh volumes: - ../media/src:/app @@ -18,34 +18,34 @@ services: tunnel: build: ../tunnel working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm ci" volumes: - ../tunnel/src:/app web: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm ci" volumes: - ../web/src:/app slack: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm ci" volumes: - ../slack/src:/app endpoint: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm ci" volumes: - ../endpoint/src:/app object-detection: build: ../object-detection working_dir: /app - command: bash -c "pipenv install --dev && pipenv update" + command: bash -c "pipenv sync --dev" volumes: - ../object-detection/src:/app diff --git a/utils/docker-compose.update.yml b/utils/docker-compose.update.yml new file mode 100644 index 0000000..41a51c8 --- /dev/null +++ b/utils/docker-compose.update.yml @@ -0,0 +1,51 @@ +version: "3.7" +services: + streaming-server: + image: node:alpine + working_dir: /app + command: ash -c "npm install && npm audit fix" + volumes: + - ../streaming-server/src:/app + + media: + build: ../media + working_dir: /app + command: ash -c "npm install && npm audit fix" + entrypoint: docker-entrypoint.sh + volumes: + - ../media/src:/app + + tunnel: + build: ../tunnel + working_dir: /app + command: ash -c "npm install && npm audit fix" + volumes: + - ../tunnel/src:/app + + web: + image: node:alpine + working_dir: /app + command: ash -c "npm install && npm audit fix" + volumes: + - ../web/src:/app + + slack: + image: node:alpine + working_dir: /app + command: ash -c "npm install && npm audit fix" + volumes: + - ../slack/src:/app + + endpoint: + image: node:alpine + working_dir: /app + command: ash -c "npm install && npm audit fix" + volumes: + - ../endpoint/src:/app + + object-detection: + build: ../object-detection + working_dir: /app + command: bash -c "pipenv install --dev && pipenv update" + volumes: + - ../object-detection/src:/app From a207fc6cf6fdfab010c12c8e263ede2e684f8bf7 Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 24 Sep 2019 01:39:01 +0900 Subject: [PATCH 20/60] Update human detector --- docker-compose.debug.yml | 2 - object-detection/src/Pipfile | 4 +- object-detection/src/get_model.sh | 4 +- object-detection/src/main.py | 55 ++++++++----- object-detection/src/model.py | 130 +++++++++++++++++------------- 5 files changed, 113 insertions(+), 82 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index a74d2fc..1b214f9 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -129,8 +129,6 @@ services: - STREAM_NAME=bushitsuchan - INFERENCE_INTERVAL_SEC=60 - DEVICE=CPU - - MODEL_FILE=models/object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.xml - - WEIGHTS_FILE=models/object_detection/common/faster_rcnn/faster_rcnn_resnet101_coco/tf/FP32/faster_rcnn_resnet101_coco.bin privileged: true volumes: - ./object-detection/src:/app diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 77f17d9..d95f810 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -27,5 +27,5 @@ python_version = "3.7" [scripts] start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 --port 5678 --wait main.py'" -lint = "bash -c 'mypy . && flake8 --show-source --exclude .venv .'" -format = "bash -c 'isort -rc . && autopep8 -ivr .'" +lint = "bash -c 'mypy . --ignore-missing-imports && flake8 --show-source --exclude .venv --max-line-length 120 .'" +format = "bash -c 'isort -rc . && autopep8 --max-line-length 120 -ivr .'" diff --git a/object-detection/src/get_model.sh b/object-detection/src/get_model.sh index a8aa793..9793040 100644 --- a/object-detection/src/get_model.sh +++ b/object-detection/src/get_model.sh @@ -1,9 +1,9 @@ python /opt/intel/openvino/deployment_tools/tools/model_downloader/downloader.py \ - --name faster_rcnn_resnet101_coco \ + --name $1 \ --cache_dir ./.cache \ --output_dir ./models python /opt/intel/openvino/deployment_tools/tools/model_downloader/converter.py \ - --name faster_rcnn_resnet101_coco \ + --name $1 \ --mo /opt/intel/openvino/deployment_tools/model_optimizer/mo.py \ --download_dir ./models diff --git a/object-detection/src/main.py b/object-detection/src/main.py index 873d2c8..eabfdae 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -1,25 +1,28 @@ #!/usr/bin/env python3 -import os import argparse -import cv2 -# from logging import getLogger -import json import asyncio -from model import Net, FasterRCNNResnet101Coco +import json +import os +from typing import Dict + +import cv2 +import numpy as np -# logger = getLogger(__name__) +from model import FasterRCNNResnet101Coco, Model +from openvino.inference_engine import IECore parser = argparse.ArgumentParser() parser.add_argument( "-l", "--cpu-extension", help="Required for CPU custom layers. MKLDNN (CPU)-targeted custom layers. Absolute path to a shared library with " "the kernels implementations.", + default="/opt/intel/openvino/inference_engine/lib/intel64/libcpu_extension_avx2.so", type=str) parser.add_argument( "-d", "--device", help="Specify the target device to infer. The sample will look for a suitable plugin for device specified.", default=os.getenv("DEVICE", "CPU"), - choices=["CPU", "GPU", "FPGA", "HDDL", "MYRIAD", "HETERO"], + choices=IECore().available_devices, type=str) parser.add_argument( "--interval", @@ -34,18 +37,14 @@ parser.add_argument( "--stream-name", help="The stream name assigned to the stream on the streaming server.", - default=os.getenv("STREAM_NAME"), + default=os.getenv("STREAM_NAME", "bushitsuchan"), type=str) parser.add_argument( - "--model-file", - help="The path of .xml file where network model data is described.", - default=os.getenv("MODEL_FILE"), - type=str) -parser.add_argument( - "--weights-file", - help="The path of the .bin file that describes the network weight.", - default=os.getenv("WEIGHTS_FILE"), - type=str) + "-t", + "--threshold", + help="Ignore predictions below a specified value.", + default=os.getenv("THRESHOLD", 0.7), + type=float) def main(): @@ -53,21 +52,33 @@ def main(): print(json.dumps(args.__dict__, indent=2)) cap = cv2.VideoCapture(f"{args.rtmp_server_url}/{args.stream_name}") - net = FasterRCNNResnet101Coco(args.model_file, args.weights_file, args.device, args.cpu_extension, cap) + cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) + net = FasterRCNNResnet101Coco(args.device, args.cpu_extension) loop = asyncio.get_event_loop() - loop.call_later(args.interval, inference, net, loop) + loop.call_later(args.interval, inference, net, cap, args.threshold, loop) loop.run_forever() - # loop.close() -def inference(net: Net, loop=None): +def inference(net: Model, cap: cv2.VideoCapture, threshold: float, loop=None): loop = loop or asyncio.get_event_loop() - ouput = net() + ret, frame = cap.read() + assert ret, f"Can't get image from {cap}" # TODO capのf-string内での表示 + + frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + output = net(frame) + output = select_top_prediction(output, threshold) loop.stop() +def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: + assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." + keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] + prediction = {key: value[keep] for key, value in prediction.items()} + return prediction + + if __name__ == "__main__": print("start") main() diff --git a/object-detection/src/model.py b/object-detection/src/model.py index 478e06a..1a7264d 100644 --- a/object-detection/src/model.py +++ b/object-detection/src/model.py @@ -1,85 +1,107 @@ #!/usr/bin/env python3 +import subprocess +from pathlib import Path +from typing import Dict, List, Optional -from typing import List, Dict -from openvino.inference_engine import IENetwork, IECore import cv2 import numpy as np +import yaml +from openvino.inference_engine import IECore, IENetwork -class Net: - def __init__( - self, - model_file: str, - weights_file: str, - cap: cv2.VideoCapture, - device: str = "CPU", - cpu_extension: str = None, - ) -> None: - self.cap = cap - self.device = device # TODO MYRIAD無いのに指定されたときの処理 + +class Model: + def __init__(self, model_file: str, weights_file: str, + device: str = "CPU", cpu_extension: str = None) -> None: + self.device = device self.ie = IECore() - self.network = self.get_network(model_file, weights_file, device, cpu_extension) + assert self.device in self.ie.available_devices, f"Cannot find the specified device: {self.device}." + + self.network = self.get_network(model_file, weights_file, cpu_extension) self.input_blobs: List[str] = list(self.network.inputs) - self.out_blob: str = next(iter(self.network.outputs)) + self.out_blobs: List[str] = list(self.network.outputs) self.network.batch_size = 1 - self.input_shapes: Dict[str, List[int]] = { - key: value.shape for key, value in self.network.inputs.items() - } + self.input_shapes: Dict[str, List[int]] = {key: value.shape for key, value in self.network.inputs.items()} - def get_network( - self, model_file: str, weights_file: str, device: str, cpu_extension: str - ) -> IENetwork: - if cpu_extension and device == "CPU": + self.network = self.ie.load_network(network=self.network, device_name=device) + + def get_network(self, model_file: str, weights_file: str, cpu_extension: Optional[str]) -> IENetwork: + if cpu_extension and self.device == "CPU": self.ie.add_extension(cpu_extension, "CPU") network = IENetwork(model=model_file, weights=weights_file) - if "CPU" == device: - supported_layers = self.ie.query_network(network, "CPU") - if len(supported_layers) == len( - network.layers - ): # TODO check len(network.layers) return int - print( - "Several layers are not supported by the plugin for specified device." - ) - print( - "Please try to specify cpu extensions library path in sample's command line parameters using -l " - "or --cpu_extension command line argument" - ) + if "CPU" == self.device: + supported_layers = set(self.ie.query_network(network, "CPU")) + unsupported_layers = set(network.layers) - supported_layers + if len(unsupported_layers): + print("Several layers are not supported by the plugin for specified device.") + print(f"The following layers are not supported.\n{unsupported_layers}") + print("Please try to specify cpu extensions library path in sample's command line parameters using -l " + "or --cpu_extension command line argument") raise - assert ( - len(network.outputs) == 1 - ), "Sample supports only single output topologies" + assert len(network.outputs) == 1, "Sample supports only single output topologies" return network - def __call__(): + def __call__(self, frame: np.ndarray) -> Dict[str, np.ndarray]: raise NotImplementedError + def forward(self, inputs: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]: + output = self.network.infer(inputs=inputs) + return output + + +class PreparedModel(Model): + model_name: str + file: str -class FasterRCNNResnet101Coco(Net): def __init__(self, *args, **kwargs) -> None: - super(self).__init__(*args, **kwargs) + with open("/opt/intel/openvino/deployment_tools/tools/model_downloader/list_topologies.yml") as f: + topologies = yaml.load(f, Loader=yaml.SafeLoader) + topologies = {topologie["name"]: topologie for topologie in topologies["topologies"]} - def __call__(self): # TODO return type - ret, frame = self.cap.read() - assert ret, f"Can't get image from {self.cap}" # TODO capのf-string内での表示 - images = np.expand_dims(self.transform(frame), 0) + assert self.model_name in topologies, \ + f"{self.model_name} is not found in model zoo.\nPlease specify from the following.\n{topologies.keys()}" + + output = topologies[self.model_name]["output"] + self.file + model_file = Path("models") / f"{output}.xml" + weights_file = Path("models") / f"{output}.bin" + + if not all(file.exists() for file in [model_file, weights_file]): + subprocess.call(["sh", "./get_model.sh", self.model_name]) # TODO check + + super(PreparedModel, self).__init__(model_file.__str__(), weights_file.__str__(), *args, **kwargs) - output = self.forward(images) + +class FasterRCNNResnet101Coco(PreparedModel): + def __init__(self, *args, **kwargs) -> None: + self.model_name = "faster_rcnn_resnet101_coco" + self.file = "FP32/faster_rcnn_resnet101_coco" + + super(FasterRCNNResnet101Coco, self).__init__(*args, **kwargs) + + def __call__(self, frame: np.ndarray) -> Dict[str, np.ndarray]: + images = np.expand_dims(self.transform(frame), 0) + inputs = { + "image_tensor": images, + "image_info": np.array([600, 600, 1]) + } + output = self.forward(inputs)["detection_output"].squeeze(0) # (1,N,7) + output = output.squeeze(0) + output = { + "image_id": output[:, 0], + "label": output[:, 1], + "conf": output[:, 2], + "bbox": output[:, 3:7] # [x_min, y_min, x_max, y_max] + } return output @staticmethod def transform(x: np.ndarray) -> np.ndarray: - # TODO RGBの順序 resize - x = x.transpose((2, 0, 1)) - + x = cv2.resize(x, dsize=(600, 600)) + x = cv2.cvtColor(x, cv2.COLOR_RGB2BGR) + x = x.transpose([2, 0, 1]) # [H, W, C] -> [C, H, W] return x - - def forward(self, x: np.ndarray): # TODO return type - exec_net = self.ie.load_network(network=self.network, device_name=self.device) - inputs = {key: x for key in self.input_blobs} # TODO x - output = exec_net.infer(inputs=inputs)[self.out_blob] - return output From 970553e02d910fddab634f3023609fd4002a638a Mon Sep 17 00:00:00 2001 From: ilim Date: Fri, 4 Oct 2019 00:21:55 +0900 Subject: [PATCH 21/60] Use flask --- docker-compose.debug.yml | 1 + object-detection/Dockerfile | 2 +- object-detection/src/Pipfile | 2 +- object-detection/src/Pipfile.lock | 130 ++++++++++++++++++++++-------- 4 files changed, 99 insertions(+), 36 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 1b214f9..67905b6 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -134,6 +134,7 @@ services: - ./object-detection/src:/app - /dev:/dev ports: + - 3005:5000 - 5678:5678 depends_on: - streamer diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 063b747..b021890 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -15,7 +15,7 @@ ENV PIPENV_VENV_IN_PROJECT true RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-2019 && \ apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2019 & \ bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ - apt-key adv --recv-keys 1A8497B11911E097 && \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1A8497B11911E097 && \ apt-get update && \ apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libgtk-3-dev diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index d95f810..6da39bc 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -19,7 +19,7 @@ tensorflow = ">=1.2.0,<2.0.0" defusedxml = ">=0.5.0" test-generator = "==0.1.1" opencv-python = "~=4.1.1.26" - +flask = "~=1.1.1" [requires] python_version = "3.7" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index e07f1a1..13e33bf 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b1eb0bea1fcb6b1ebf5d6db01ea45a8bc96dbe91d993becd9f32ff3fe01c9a81" + "sha256": "70aeb6a39aae90612698848080514d7f1a2acb3d44116920884443120285b1a2" }, "pipfile-spec": 6, "requires": { @@ -43,6 +43,13 @@ ], "version": "==3.0.4" }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, "decorator": { "hashes": [ "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", @@ -58,6 +65,14 @@ "index": "pypi", "version": "==0.6.0" }, + "flask": { + "hashes": [ + "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", + "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + ], + "index": "pypi", + "version": "==1.1.1" + }, "gast": { "hashes": [ "sha256:5c7617f1f6c8b8b426819642b16b9016727ddaecd16af9a07753e537eba8a3a5" @@ -148,6 +163,20 @@ ], "version": "==2.8" }, + "itsdangerous": { + "hashes": [ + "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", + "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + ], + "version": "==1.1.0" + }, + "jinja2": { + "hashes": [ + "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", + "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" + ], + "version": "==2.10.1" + }, "keras-applications": { "hashes": [ "sha256:5579f9a12bcde9748f4a12233925a59b93b73ae6947409ff34aa2ba258189fe5", @@ -169,6 +198,39 @@ ], "version": "==3.1.1" }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" + }, "networkx": { "hashes": [ "sha256:8311ddef63cf5c5c5e7c1d0212dd141d9a1fe3f474915281b73597ed5f1d4e3d" @@ -232,24 +294,24 @@ }, "protobuf": { "hashes": [ - "sha256:00a1b0b352dc7c809749526d1688a64b62ea400c5b05416f93cfb1b11a036295", - "sha256:01acbca2d2c8c3f7f235f1842440adbe01bbc379fa1cbdd80753801432b3fae9", - "sha256:0a795bca65987b62d6b8a2d934aa317fd1a4d06a6dd4df36312f5b0ade44a8d9", - "sha256:0ec035114213b6d6e7713987a759d762dd94e9f82284515b3b7331f34bfaec7f", - "sha256:31b18e1434b4907cb0113e7a372cd4d92c047ce7ba0fa7ea66a404d6388ed2c1", - "sha256:32a3abf79b0bef073c70656e86d5bd68a28a1fbb138429912c4fc07b9d426b07", - "sha256:55f85b7808766e5e3f526818f5e2aeb5ba2edcc45bcccede46a3ccc19b569cb0", - "sha256:64ab9bc971989cbdd648c102a96253fdf0202b0c38f15bd34759a8707bdd5f64", - "sha256:64cf847e843a465b6c1ba90fb6c7f7844d54dbe9eb731e86a60981d03f5b2e6e", - "sha256:917c8662b585470e8fd42f052661fc66d59fccaae450a60044307dcbf82a3335", - "sha256:afed9003d7f2be2c3df20f64220c30faec441073731511728a2cb4cab4cd46a6", - "sha256:bf8e05d638b585d1752c5a84247134a0350d3a8b73d3632489a014a9f6f1e758", - "sha256:d831b047bd69becaf64019a47179eb22118a50dd008340655266a906c69c6417", - "sha256:de2760583ed28749ff885789c1cbc6c9c06d6de92fc825740ab99deb2f25ea4d", - "sha256:eabc4cf1bc19689af8022ba52fd668564a8d96e0d08f3b4732d26a64255216a4", - "sha256:fcff6086c86fb1628d94ea455c7b9de898afc50378042927a59df8065a79a549" - ], - "version": "==3.9.1" + "sha256:26c0d756c7ad6823fccbc3b5f84c619b9cc7ac281496fe0a9d78e32023c45034", + "sha256:3200046e4d4f6c42ed66257dbe15e2e5dc76072c280e9b3d69dc8f3a4fa3fbbc", + "sha256:368f1bae6dd22d04fd2254d30cd301863408a96ff604422e3ddd8ab601f095a4", + "sha256:3902fa1920b4ef9f710797496b309efc5ccd0faeba44dc82ed6a711a244764a0", + "sha256:3a7a8925ba6481b9241cdb5d69cd0b0700f23efed6bb691dc9543faa4aa25d6f", + "sha256:4bc33d49f43c6e9916fb56b7377cb4478cbf25824b4d2bedfb8a4e3df31c12ca", + "sha256:568b434a36e31ed30d60d600b2227666ce150b8b5275948f50411481a4575d6d", + "sha256:5c393cd665d03ce6b29561edd6b0cc4bcb3fb8e2a7843e8f223d693f07f61b40", + "sha256:80072e9ba36c73cf89c01f669c7b123733fc2de1780b428082a850f53cc7865f", + "sha256:843f498e98ad1469ad54ecb4a7ccf48605a1c5d2bd26ae799c7a2cddab4a37ec", + "sha256:aa45443035651cbfae74c8deb53358ba660d8e7a5fbab3fc4beb33fb3e3ca4be", + "sha256:aaab817d9d038dd5f56a6fb2b2e8ae68caf1fd28cc6a963c755fa73268495c13", + "sha256:e6f68b9979dc8f75299293d682f67fecb72d78f98652da2eeb85c85edef1ca94", + "sha256:e7366cabddff3441d583fdc0176ab42eba4ee7090ef857d50c4dd59ad124003a", + "sha256:f0144ad97cd28bfdda0567b9278d25061ada5ad2b545b538cd3577697b32bda3", + "sha256:f655338491481f482042f19016647e50365ab41b75b486e0df56e0dcc425abf4" + ], + "version": "==3.9.2" }, "pyyaml": { "hashes": [ @@ -335,10 +397,10 @@ }, "urllib3": { "hashes": [ - "sha256:2f3eadfea5d92bc7899e75b5968410b749a054b492d5a6379c1344a1481bc2cb", - "sha256:9c6c593cb28f52075016307fc26b0a0f8e82bc7d1ff19aaaa959b91710a56c47" + "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", + "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" ], - "version": "==1.25.5" + "version": "==1.25.6" }, "werkzeug": { "hashes": [ @@ -409,20 +471,20 @@ }, "mypy": { "hashes": [ - "sha256:0107bff4f46a289f0e4081d59b77cef1c48ea43da5a0dbf0005d54748b26df2a", - "sha256:07957f5471b3bb768c61f08690c96d8a09be0912185a27a68700f3ede99184e4", - "sha256:10af62f87b6921eac50271e667cc234162a194e742d8e02fc4ddc121e129a5b0", - "sha256:11fd60d2f69f0cefbe53ce551acf5b1cec1a89e7ce2d47b4e95a84eefb2899ae", - "sha256:15e43d3b1546813669bd1a6ec7e6a11d2888db938e0607f7b5eef6b976671339", - "sha256:352c24ba054a89bb9a35dd064ee95ab9b12903b56c72a8d3863d882e2632dc76", - "sha256:437020a39417e85e22ea8edcb709612903a9924209e10b3ec6d8c9f05b79f498", - "sha256:49925f9da7cee47eebf3420d7c0e00ec662ec6abb2780eb0a16260a7ba25f9c4", - "sha256:6724fcd5777aa6cebfa7e644c526888c9d639bd22edd26b2a8038c674a7c34bd", - "sha256:7a17613f7ea374ab64f39f03257f22b5755335b73251d0d253687a69029701ba", - "sha256:cdc1151ced496ca1496272da7fc356580e95f2682be1d32377c22ddebdf73c91" + "sha256:1d98fd818ad3128a5408148c9e4a5edce6ed6b58cc314283e631dd5d9216527b", + "sha256:22ee018e8fc212fe601aba65d3699689dd29a26410ef0d2cc1943de7bec7e3ac", + "sha256:3a24f80776edc706ec8d05329e854d5b9e464cd332e25cde10c8da2da0a0db6c", + "sha256:42a78944e80770f21609f504ca6c8173f7768043205b5ac51c9144e057dcf879", + "sha256:4b2b20106973548975f0c0b1112eceb4d77ed0cafe0a231a1318f3b3a22fc795", + "sha256:591a9625b4d285f3ba69f541c84c0ad9e7bffa7794da3fa0585ef13cf95cb021", + "sha256:5b4b70da3d8bae73b908a90bb2c387b977e59d484d22c604a2131f6f4397c1a3", + "sha256:84edda1ffeda0941b2ab38ecf49302326df79947fa33d98cdcfbf8ca9cf0bb23", + "sha256:b2b83d29babd61b876ae375786960a5374bba0e4aba3c293328ca6ca5dc448dd", + "sha256:cc4502f84c37223a1a5ab700649b5ab1b5e4d2bf2d426907161f20672a21930b", + "sha256:e29e24dd6e7f39f200a5bb55dcaa645d38a397dd5a6674f6042ef02df5795046" ], "index": "pypi", - "version": "==0.720" + "version": "==0.730" }, "mypy-extensions": { "hashes": [ From ac8f213a91becefb97ad759631a52ddc17625d79 Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 6 Oct 2019 17:20:19 +0900 Subject: [PATCH 22/60] Update openvino environment --- object-detection/Dockerfile | 30 +++++++++++----------- object-detection/Dockerfile-wget | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 object-detection/Dockerfile-wget diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index b021890..1dd2a96 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -3,26 +3,21 @@ FROM ubuntu:18.04 ARG NUM_THREADS=1 ENV LANG C.UTF-8 -RUN apt-get update && \ - apt-get install -y --no-install-recommends python3.7 libpython3.7-dev python3-pip wget curl unzip gnupg ca-certificates lsb-release && \ - update-ca-certificates && \ - pip3 install pipenv - -# ENV PIPENV_YES true -ENV PIPENV_VENV_IN_PROJECT true +RUN sed -i.bak -e "s%http://archive.ubuntu.com/ubuntu/%http://jp.archive.ubuntu.com/ubuntu/%g" /etc/apt/sources.list && \ + apt-get update -yqq && \ + apt-get install -yq --no-install-recommends wget unzip gnupg ca-certificates lsb-release && \ + update-ca-certificates # https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_apt.html -RUN wget https://apt.repos.intel.com/openvino/2019/GPG-PUB-KEY-INTEL-OPENVINO-2019 && \ - apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2019 & \ - bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" & \ - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1A8497B11911E097 && \ +RUN wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" && \ apt-get update && \ - apt-get install -y --no-install-recommends intel-openvino-dev-ubuntu18 libgtk-3-dev + apt-get install -yq --no-install-recommends intel-openvino-dev-ubuntu18 -# install_openvino_dependencies.sh か libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release のすべてのどちらか -RUN apt-get install -y --no-install-recommends && \ +RUN apt-get install -yq --no-install-recommends libgtk-3-dev && \ /opt/intel/openvino/install_dependencies/install_openvino_dependencies.sh -# libglib2.0-dev libsm-dev libxrender-dev libxext-dev lsb-release # https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#run_the_docker_image_for_intel_movidius_neural_compute_stick_and_intel_neural_compute_stick_2 RUN cd /tmp/ && \ @@ -34,3 +29,8 @@ RUN cd /tmp/ && \ rm -rf /tmp/* RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc + +RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev python3-pip && \ + pip3 install pipenv + +ENV PIPENV_VENV_IN_PROJECT true diff --git a/object-detection/Dockerfile-wget b/object-detection/Dockerfile-wget new file mode 100644 index 0000000..c54d685 --- /dev/null +++ b/object-detection/Dockerfile-wget @@ -0,0 +1,43 @@ +FROM ubuntu:18.04 + +ARG NUM_THREADS=1 +ENV LANG C.UTF-8 + +# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#building-for-cpu +ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz +ARG INSTALL_DIR=/opt/intel/openvino +ARG TEMP_DIR=/tmp/openvino_installer + + +RUN sed -i.bak -e "s%http://archive.ubuntu.com/ubuntu/%http://jp.archive.ubuntu.com/ubuntu/%g" /etc/apt/sources.list && \ + apt-get update -yqq && \ + apt-get install -yq --no-install-recommends wget unzip cpio sudo lsb-release +RUN mkdir -p $TEMP_DIR && \ + cd $TEMP_DIR && \ + wget -c $DOWNLOAD_LINK && \ + tar xf l_openvino_toolkit*.tgz && \ + cd l_openvino_toolkit* && \ + sed -i 's/decline/accept/g' silent.cfg && \ + sed -i 's/#INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/g' silent.cfg && \ + ./install.sh -s silent.cfg && \ + rm -rf $TEMP_DIR +RUN $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh && \ + apt-get install -yq --no-install-recommends libgtk-3-dev + + +# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#run_the_docker_image_for_intel_movidius_neural_compute_stick_and_intel_neural_compute_stick_2 +RUN cd /tmp/ && \ + apt-get install -yq --no-install-recommends unzip && \ + wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ + unzip v1.0.22.zip && cd libusb-1.0.22 && \ + ./bootstrap.sh && \ + ./configure --disable-udev --enable-shared && \ + make -j${NUM_THREADS} && make install && \ + rm -rf /tmp/* + +RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc + +RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev python3-pip && \ + pip3 install pipenv + +ENV PIPENV_VENV_IN_PROJECT true From 7a86d3e9b878397d446ff29a788e33611709cf58 Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 6 Oct 2019 19:34:19 +0900 Subject: [PATCH 23/60] Update object detection server --- docker-compose.debug.yml | 2 + object-detection/src/Pipfile | 5 +- object-detection/src/Pipfile.lock | 149 ++++++++++++++++++------------ object-detection/src/app.py | 46 +++++++++ object-detection/src/main.py | 84 ----------------- 5 files changed, 141 insertions(+), 145 deletions(-) create mode 100644 object-detection/src/app.py delete mode 100644 object-detection/src/main.py diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 67905b6..dc60b3f 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -129,6 +129,8 @@ services: - STREAM_NAME=bushitsuchan - INFERENCE_INTERVAL_SEC=60 - DEVICE=CPU + - CPU_EXTENSION=/opt/intel/openvino/inference_engine/lib/intel64/libcpu_extension_avx2.so + - FLASK_ENV=development privileged: true volumes: - ./object-detection/src:/app diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 6da39bc..32382d8 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -20,12 +20,13 @@ defusedxml = ">=0.5.0" test-generator = "==0.1.1" opencv-python = "~=4.1.1.26" flask = "~=1.1.1" +pillow = "~=6.2.0" [requires] python_version = "3.7" [scripts] -start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python main.py'" -dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 --port 5678 --wait main.py'" +start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && flask run'" +dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 -m flask run --host=0.0.0.0 --no-reload --no-debugger'" lint = "bash -c 'mypy . --ignore-missing-imports && flake8 --show-source --exclude .venv --max-line-length 120 .'" format = "bash -c 'isort -rc . && autopep8 --max-line-length 120 -ivr .'" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index 13e33bf..5507fa2 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "70aeb6a39aae90612698848080514d7f1a2acb3d44116920884443120285b1a2" + "sha256": "dac253abd993ffb711d3636ab4ba20e8df0b4d48cc020a7daf062cb69b271167" }, "pipfile-spec": 6, "requires": { @@ -89,40 +89,40 @@ }, "grpcio": { "hashes": [ - "sha256:1303578092f1f6e4bfbc354c04ac422856c393723d3ffa032fff0f7cb5cfd693", - "sha256:229c6b313cd82bec8f979b059d87f03cc1a48939b543fe170b5a9c5cf6a6bc69", - "sha256:3cd3d99a8b5568d0d186f9520c16121a0f2a4bcad8e2b9884b76fb88a85a7774", - "sha256:41cfb222db358227521f9638a6fbc397f310042a4db5539a19dea01547c621cd", - "sha256:43330501660f636fd6547d1e196e395cd1e2c2ae57d62219d6184a668ffebda0", - "sha256:45d7a2bd8b4f25a013296683f4140d636cdbb507d94a382ea5029a21e76b1648", - "sha256:47dc935658a13b25108823dabd010194ddea9610357c5c1ef1ad7b3f5157ebee", - "sha256:480aa7e2b56238badce0b9413a96d5b4c90c3bfbd79eba5a0501e92328d9669e", - "sha256:4a0934c8b0f97e1d8c18e76c45afc0d02d33ab03125258179f2ac6c7a13f3626", - "sha256:5624dab19e950f99e560400c59d87b685809e4cfcb2c724103f1ab14c06071f7", - "sha256:60515b1405bb3dadc55e6ca99429072dad3e736afcf5048db5452df5572231ff", - "sha256:610f97ebae742a57d336a69b09a9c7d7de1f62aa54aaa8adc635b38f55ba4382", - "sha256:64ea189b2b0859d1f7b411a09185028744d494ef09029630200cc892e366f169", - "sha256:686090c6c1e09e4f49585b8508d0a31d58bc3895e4049ea55b197d1381e9f70f", - "sha256:7745c365195bb0605e3d47b480a2a4d1baa8a41a5fd0a20de5fa48900e2c886a", - "sha256:79491e0d2b77a1c438116bf9e5f9e2e04e78b78524615e2ce453eff62db59a09", - "sha256:825177dd4c601c487836b7d6b4ba268db59787157911c623ba59a7c03c8d3adc", - "sha256:8a060e1f72fb94eee8a035ed29f1201ce903ad14cbe27bda56b4a22a8abda045", - "sha256:90168cc6353e2766e47b650c963f21cfff294654b10b3a14c67e26a4e3683634", - "sha256:94b7742734bceeff6d8db5edb31ac844cb68fc7f13617eca859ff1b78bb20ba1", - "sha256:962aebf2dd01bbb2cdb64580e61760f1afc470781f9ecd5fe8f3d8dcd8cf4556", - "sha256:9c8d9eacdce840b72eee7924c752c31b675f8aec74790e08cff184a4ea8aa9c1", - "sha256:af5b929debc336f6bab9b0da6915f9ee5e41444012aed6a79a3c7e80d7662fdf", - "sha256:b9cdb87fc77e9a3eabdc42a512368538d648fa0760ad30cf97788076985c790a", - "sha256:c5e6380b90b389454669dc67d0a39fb4dc166416e01308fcddd694236b8329ef", - "sha256:d60c90fe2bfbee735397bf75a2f2c4e70c5deab51cd40c6e4fa98fae018c8db6", - "sha256:d8582c8b1b1063249da1588854251d8a91df1e210a328aeb0ece39da2b2b763b", - "sha256:ddbf86ba3aa0ad8fed2867910d2913ee237d55920b55f1d619049b3399f04efc", - "sha256:e46bc0664c5c8a0545857aa7a096289f8db148e7f9cca2d0b760113e8994bddc", - "sha256:f6437f70ec7fed0ca3a0eef1146591bb754b418bb6c6b21db74f0333d624e135", - "sha256:f71693c3396530c6b00773b029ea85e59272557e9bd6077195a6593e4229892a", - "sha256:f79f7455f8fbd43e8e9d61914ecf7f48ba1c8e271801996fef8d6a8f3cc9f39f" - ], - "version": "==1.23.0" + "sha256:0302331e014fc4bac028b6ad480b33f7abfe20b9bdcca7be417124dda8f22115", + "sha256:0aa0cce9c5eb1261b32173a20ed42b51308d55ce28ecc2021e868b3cb90d9503", + "sha256:0c83947575300499adbc308e986d754e7f629be0bdd9bea1ffdd5cf76e1f1eff", + "sha256:0ca26ff968d45efd4ef73447c4d4b34322ea8c7d06fbb6907ce9e5db78f1bbcb", + "sha256:0cf80a7955760c2498f8821880242bb657d70998065ff0d2a082de5ffce230a7", + "sha256:0d40706e57d9833fe0e023a08b468f33940e8909affa12547874216d36bba208", + "sha256:11872069156de34c6f3f9a1deb46cc88bc35dfde88262c4c73eb22b39b16fc55", + "sha256:16065227faae0ab0abf1789bfb92a2cd2ab5da87630663f93f8178026da40e0d", + "sha256:1e33778277685f6fabb22539136269c87c029e39b6321ef1a639b756a1c0a408", + "sha256:2b16be15b1ae656bc7a36642b8c7045be2dde2048bb4b67478003e9d9db8022a", + "sha256:3701dfca3ada27ceef0d17f728ce9dfef155ed20c57979c2b05083082258c6c1", + "sha256:41912ecaf482abf2de74c69f509878f99223f5dd6b2de1a09c955afd4de3cf9b", + "sha256:4332cbd20544fe7406910137590f38b5b3a1f6170258e038652cf478c639430f", + "sha256:44068ecbdc6467c2bff4d8198816c8a2701b6dd1ec16078fceb6adc7c1f577d6", + "sha256:53115960e37059420e2d16a4b04b00dd2ab3b6c3c67babd01ffbfdcd7881a69b", + "sha256:6e7027bcd4070414751e2a5e60706facb98a1fc636497c9bac5442fe37b8ae6b", + "sha256:6ff57fb2f07b7226b5bec89e8e921ea9bd220f35f11e094f2ba38f09eecd49c6", + "sha256:73240e244d7644654bbda1f309f4911748b6a1804b7a8897ddbe8a04c90f7407", + "sha256:785234bbc469bc75e26c868789a2080ffb30bd6e93930167797729889ad06b0b", + "sha256:82f9d3c7f91d2d1885631335c003c5d45ae1cd69cc0bc4893f21fef50b8151bc", + "sha256:86bdc2a965510658407a1372eb61f0c92f763fdfb2795e4d038944da4320c950", + "sha256:95e925b56676a55e6282b3de80a1cbad5774072159779c61eac02791dface049", + "sha256:96673bb4f14bd3263613526d1e7e33fdb38a9130e3ce87bf52314965706e1900", + "sha256:970014205e76920484679035b6fb4b16e02fc977e5aac4d22025da849c79dab9", + "sha256:ace5e8bf11a1571f855f5dab38a9bd34109b6c9bc2864abf24a597598c7e3695", + "sha256:ad375f03eb3b9cb75a24d91eab8609e134d34605f199efc41e20dd642bdac855", + "sha256:b819c4c7dcf0de76788ce5f95daad6d4e753d6da2b6a5f84e5bb5b5ce95fddc4", + "sha256:c17943fd340cbd906db49f3f03c7545e5a66b617e8348b2c7a0d2c759d216af1", + "sha256:d21247150dea86dabd3b628d8bc4b563036db3d332b3f4db3c5b1b0b122cb4f6", + "sha256:d4d500a7221116de9767229ff5dd10db91f789448d85befb0adf5a37b0cd83b5", + "sha256:e2a942a3cfccbbca21a90c144867112698ef36486345c285da9e98c466f22b22", + "sha256:e983273dca91cb8a5043bc88322eb48e2b8d4e4998ff441a1ee79ced89db3909" + ], + "version": "==1.24.1" }, "h5py": { "hashes": [ @@ -172,10 +172,10 @@ }, "jinja2": { "hashes": [ - "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", - "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" ], - "version": "==2.10.1" + "version": "==2.10.3" }, "keras-applications": { "hashes": [ @@ -292,26 +292,58 @@ "index": "pypi", "version": "==4.1.1.26" }, + "pillow": { + "hashes": [ + "sha256:00fdeb23820f30e43bba78eb9abb00b7a937a655de7760b2e09101d63708b64e", + "sha256:01f948e8220c85eae1aa1a7f8edddcec193918f933fb07aaebe0bfbbcffefbf1", + "sha256:08abf39948d4b5017a137be58f1a52b7101700431f0777bec3d897c3949f74e6", + "sha256:099a61618b145ecb50c6f279666bbc398e189b8bc97544ae32b8fcb49ad6b830", + "sha256:2c1c61546e73de62747e65807d2cc4980c395d4c5600ecb1f47a650c6fa78c79", + "sha256:2ed9c4f694861642401f27dc3cb99772be67cd190e84845c749dae0a06c3bfae", + "sha256:338581b30b908e111be578f0297255f6b57a51358cd16fa0e6f664c9a1f88bff", + "sha256:38c7d48a21cd06fdeee93987147b9b1c55b73b4cfcbf83240568bfbd5adee447", + "sha256:43fd026f613c8e48a25eba1a92f4d2ad7f3903c95d8c33a11611a7717d2ab654", + "sha256:4548236844327a718ce3bb182ab32a16fa2050c61e334e959f554cac052fb0df", + "sha256:5090857876c58885cfa388dc649e5db30aae98a068c26f3fd0ac9d7d9a4d9572", + "sha256:5bbba34f97a26a93f5e8dec469ca4ddd712451418add43da946dbaed7f7a98d2", + "sha256:65a28969a025a0eb4594637b6103201dc4ed2a9508bdab56ac33e43e3081c404", + "sha256:892bb52b70bd5ea9dbbc3ac44f38e84f5a04e9d8b1bff48159d96cb795b81159", + "sha256:8a9becd5cbd5062f973bcd2e7bc79483af310222de112b6541f8af1f93a3cc42", + "sha256:972a7aaeb7c4a2795b52eef52ee991ef040b31009f36deca6207a986607b55f3", + "sha256:97b119c436bfa96a92ac2ca525f7025836d4d4e64b1c9f9eff8dbaf3ff1d86f3", + "sha256:9ba37698e242223f8053cc158f130aee046a96feacbeab65893dbe94f5530118", + "sha256:b1b0e1f626a0f079c0d3696db70132fb1f29aa87c66aecb6501a9b8be64ce9f7", + "sha256:c14c1224fd1a5be2733530d648a316974dbbb3c946913562c6005a76f21ca042", + "sha256:c79a8546c48ae6465189e54e3245a97ddf21161e33ff7eaa42787353417bb2b6", + "sha256:ceb76935ac4ebdf6d7bc845482a4450b284c6ccfb281e34da51d510658ab34d8", + "sha256:e22bffaad04b4d16e1c091baed7f2733fc1ebb91e0c602abf1b6834d17158b1f", + "sha256:ec883b8e44d877bda6f94a36313a1c6063f8b1997aa091628ae2f34c7f97c8d5", + "sha256:f1baa54d50ec031d1a9beb89974108f8f2c0706f49798f4777df879df0e1adb6", + "sha256:f53a5385932cda1e2c862d89460992911a89768c65d176ff8c50cddca4d29bed" + ], + "index": "pypi", + "version": "==6.2.0" + }, "protobuf": { "hashes": [ - "sha256:26c0d756c7ad6823fccbc3b5f84c619b9cc7ac281496fe0a9d78e32023c45034", - "sha256:3200046e4d4f6c42ed66257dbe15e2e5dc76072c280e9b3d69dc8f3a4fa3fbbc", - "sha256:368f1bae6dd22d04fd2254d30cd301863408a96ff604422e3ddd8ab601f095a4", - "sha256:3902fa1920b4ef9f710797496b309efc5ccd0faeba44dc82ed6a711a244764a0", - "sha256:3a7a8925ba6481b9241cdb5d69cd0b0700f23efed6bb691dc9543faa4aa25d6f", - "sha256:4bc33d49f43c6e9916fb56b7377cb4478cbf25824b4d2bedfb8a4e3df31c12ca", - "sha256:568b434a36e31ed30d60d600b2227666ce150b8b5275948f50411481a4575d6d", - "sha256:5c393cd665d03ce6b29561edd6b0cc4bcb3fb8e2a7843e8f223d693f07f61b40", - "sha256:80072e9ba36c73cf89c01f669c7b123733fc2de1780b428082a850f53cc7865f", - "sha256:843f498e98ad1469ad54ecb4a7ccf48605a1c5d2bd26ae799c7a2cddab4a37ec", - "sha256:aa45443035651cbfae74c8deb53358ba660d8e7a5fbab3fc4beb33fb3e3ca4be", - "sha256:aaab817d9d038dd5f56a6fb2b2e8ae68caf1fd28cc6a963c755fa73268495c13", - "sha256:e6f68b9979dc8f75299293d682f67fecb72d78f98652da2eeb85c85edef1ca94", - "sha256:e7366cabddff3441d583fdc0176ab42eba4ee7090ef857d50c4dd59ad124003a", - "sha256:f0144ad97cd28bfdda0567b9278d25061ada5ad2b545b538cd3577697b32bda3", - "sha256:f655338491481f482042f19016647e50365ab41b75b486e0df56e0dcc425abf4" - ], - "version": "==3.9.2" + "sha256:125713564d8cfed7610e52444c9769b8dcb0b55e25cc7841f2290ee7bc86636f", + "sha256:1accdb7a47e51503be64d9a57543964ba674edac103215576399d2d0e34eac77", + "sha256:27003d12d4f68e3cbea9eb67427cab3bfddd47ff90670cb367fcd7a3a89b9657", + "sha256:3264f3c431a631b0b31e9db2ae8c927b79fc1a7b1b06b31e8e5bcf2af91fe896", + "sha256:3c5ab0f5c71ca5af27143e60613729e3488bb45f6d3f143dc918a20af8bab0bf", + "sha256:45dcf8758873e3f69feab075e5f3177270739f146255225474ee0b90429adef6", + "sha256:56a77d61a91186cc5676d8e11b36a5feb513873e4ae88d2ee5cf530d52bbcd3b", + "sha256:5984e4947bbcef5bd849d6244aec507d31786f2dd3344139adc1489fb403b300", + "sha256:6b0441da73796dd00821763bb4119674eaf252776beb50ae3883bed179a60b2a", + "sha256:6f6677c5ade94d4fe75a912926d6796d5c71a2a90c2aeefe0d6f211d75c74789", + "sha256:84a825a9418d7196e2acc48f8746cf1ee75877ed2f30433ab92a133f3eaf8fbe", + "sha256:b842c34fe043ccf78b4a6cf1019d7b80113707d68c88842d061fa2b8fb6ddedc", + "sha256:ca33d2f09dae149a1dcf942d2d825ebb06343b77b437198c9e2ef115cf5d5bc1", + "sha256:db83b5c12c0cd30150bb568e6feb2435c49ce4e68fe2d7b903113f0e221e58fe", + "sha256:f50f3b1c5c1c1334ca7ce9cad5992f098f460ffd6388a3cabad10b66c2006b09", + "sha256:f99f127909731cafb841c52f9216e447d3e4afb99b17bebfad327a75aee206de" + ], + "version": "==3.10.0" }, "pyyaml": { "hashes": [ @@ -488,10 +520,9 @@ }, "mypy-extensions": { "hashes": [ - "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812", - "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e" + "sha256:a161e3b917053de87dbe469987e173e49fb454eca10ef28b48b384538cc11458" ], - "version": "==0.4.1" + "version": "==0.4.2" }, "pathtools": { "hashes": [ diff --git a/object-detection/src/app.py b/object-detection/src/app.py new file mode 100644 index 0000000..b806aa7 --- /dev/null +++ b/object-detection/src/app.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +import io +import os +from typing import Dict + +import numpy as np +import requests +from flask import Flask, jsonify, request +from PIL import Image + +from model import FasterRCNNResnet101Coco + +app = Flask(__name__) +app.logger.info("Loading network") +net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) +app.logger.info("Network loading finished") + + +@app.route('/faster_rcnn_resnet101_coco') +def object_detection(): + url = request.json.get("url") + threshold = request.json.get("threshold", os.getenv("THRESHOLD", 0.7)) + image = requests.get(url) + + image = Image.open(io.BytesIO(image.content)).convert('RGB') + image = np.asarray(image) + + output = net(image) + output = select_top_prediction(output, threshold) + return jsonify({ + "bbox": (output["bbox"].reshape(-1, 2, 2) * np.array(image.shape[:2])).reshape(-1, 4).astype(int).tolist(), + "conf": output["conf"].tolist(), + "label": output["label"].astype(int).tolist() + }) + + +def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: + assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." + keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] + prediction = {key: value[keep] for key, value in prediction.items()} + return prediction + + +if __name__ == "__main__": + app.run() diff --git a/object-detection/src/main.py b/object-detection/src/main.py deleted file mode 100644 index eabfdae..0000000 --- a/object-detection/src/main.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import asyncio -import json -import os -from typing import Dict - -import cv2 -import numpy as np - -from model import FasterRCNNResnet101Coco, Model -from openvino.inference_engine import IECore - -parser = argparse.ArgumentParser() -parser.add_argument( - "-l", "--cpu-extension", - help="Required for CPU custom layers. MKLDNN (CPU)-targeted custom layers. Absolute path to a shared library with " - "the kernels implementations.", - default="/opt/intel/openvino/inference_engine/lib/intel64/libcpu_extension_avx2.so", - type=str) -parser.add_argument( - "-d", "--device", - help="Specify the target device to infer. The sample will look for a suitable plugin for device specified.", - default=os.getenv("DEVICE", "CPU"), - choices=IECore().available_devices, - type=str) -parser.add_argument( - "--interval", - help="Infers through the network every specified number of seconds.", - default=os.getenv("INFERENCE_INTERVAL_SEC", 60 * 5), - type=int) -parser.add_argument( - "--rtmp-server-url", - help="Streaming server address starting with rtmp:// .", - default=os.getenv("RTMP_SERVER_URL", "rtmp://streaming-server/live"), - type=str) -parser.add_argument( - "--stream-name", - help="The stream name assigned to the stream on the streaming server.", - default=os.getenv("STREAM_NAME", "bushitsuchan"), - type=str) -parser.add_argument( - "-t", - "--threshold", - help="Ignore predictions below a specified value.", - default=os.getenv("THRESHOLD", 0.7), - type=float) - - -def main(): - args = parser.parse_args() - print(json.dumps(args.__dict__, indent=2)) - - cap = cv2.VideoCapture(f"{args.rtmp_server_url}/{args.stream_name}") - cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) - net = FasterRCNNResnet101Coco(args.device, args.cpu_extension) - - loop = asyncio.get_event_loop() - loop.call_later(args.interval, inference, net, cap, args.threshold, loop) - loop.run_forever() - # loop.close() - - -def inference(net: Model, cap: cv2.VideoCapture, threshold: float, loop=None): - loop = loop or asyncio.get_event_loop() - ret, frame = cap.read() - assert ret, f"Can't get image from {cap}" # TODO capのf-string内での表示 - - frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) - output = net(frame) - output = select_top_prediction(output, threshold) - loop.stop() - - -def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: - assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." - keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] - prediction = {key: value[keep] for key, value in prediction.items()} - return prediction - - -if __name__ == "__main__": - print("start") - main() From f311ff893475171da2ff0f178fdd28fb64e32910 Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 6 Oct 2019 23:16:06 +0900 Subject: [PATCH 24/60] Update object-detection server --- docker-compose.debug.yml | 4 +- object-detection/src/Pipfile | 4 +- object-detection/src/app.py | 18 ++++--- object-detection/src/labels.json | 92 ++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 object-detection/src/labels.json diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index dc60b3f..f31d997 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -94,6 +94,8 @@ services: - SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET} - CONTACT_CHANNEL=${CONTACT_CHANNEL} - SESSION_SECRET=${SESSION_SECRET} + - NOTIFICATION_CHANNEL=${NOTIFICATION_CHANNEL} + - NOTIFICATION_INTERVAL=${NOTIFICATION_INTERVAL} volumes: - ./slack/src:/app ports: @@ -136,7 +138,7 @@ services: - ./object-detection/src:/app - /dev:/dev ports: - - 3005:5000 + - 3005:80 - 5678:5678 depends_on: - streamer diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 32382d8..b6b8037 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -26,7 +26,7 @@ pillow = "~=6.2.0" python_version = "3.7" [scripts] -start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && flask run'" -dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 -m flask run --host=0.0.0.0 --no-reload --no-debugger'" +start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && flask run --host=0.0.0.0 --port 80'" +dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 -m flask run --host=0.0.0.0 --port 80 --no-reload --no-debugger'" lint = "bash -c 'mypy . --ignore-missing-imports && flake8 --show-source --exclude .venv --max-line-length 120 .'" format = "bash -c 'isort -rc . && autopep8 --max-line-length 120 -ivr .'" diff --git a/object-detection/src/app.py b/object-detection/src/app.py index b806aa7..fffb7a5 100644 --- a/object-detection/src/app.py +++ b/object-detection/src/app.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import io +import json import os from typing import Dict @@ -16,13 +17,17 @@ net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) app.logger.info("Network loading finished") +with open("labels.json") as f: + label_names = json.load(f) + @app.route('/faster_rcnn_resnet101_coco') def object_detection(): - url = request.json.get("url") - threshold = request.json.get("threshold", os.getenv("THRESHOLD", 0.7)) - image = requests.get(url) + photo_id = request.args.get("photo_id") + threshold = request.args.get("threshold", os.getenv("THRESHOLD", 0.7)) + url = f"http://media/photo/{photo_id}" + image = requests.get(url) image = Image.open(io.BytesIO(image.content)).convert('RGB') image = np.asarray(image) @@ -30,8 +35,9 @@ def object_detection(): output = select_top_prediction(output, threshold) return jsonify({ "bbox": (output["bbox"].reshape(-1, 2, 2) * np.array(image.shape[:2])).reshape(-1, 4).astype(int).tolist(), - "conf": output["conf"].tolist(), - "label": output["label"].astype(int).tolist() + "confidence": output["conf"].tolist(), + "label_id": output["label"].astype(int).tolist(), + "label_name": [label_names[label] for label in output["label"].astype(int)] }) @@ -43,4 +49,4 @@ def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) - if __name__ == "__main__": - app.run() + app.run(port=80) diff --git a/object-detection/src/labels.json b/object-detection/src/labels.json new file mode 100644 index 0000000..41bf507 --- /dev/null +++ b/object-detection/src/labels.json @@ -0,0 +1,92 @@ +[ + "unlabeled", + "person", + "bicycle", + "car", + "motorcycle", + "airplane", + "bus", + "train", + "truck", + "boat", + "traffic light", + "fire hydrant", + "street sign", + "stop sign", + "parking meter", + "bench", + "bird", + "cat", + "dog", + "horse", + "sheep", + "cow", + "elephant", + "bear", + "zebra", + "giraffe", + "hat", + "backpack", + "umbrella", + "shoe", + "eye glasses", + "handbag", + "tie", + "suitcase", + "frisbee", + "skis", + "snowboard", + "sports ball", + "kite", + "baseball bat", + "baseball glove", + "skateboard", + "surfboard", + "tennis racket", + "bottle", + "plate", + "wine glass", + "cup", + "fork", + "knife", + "spoon", + "bowl", + "banana", + "apple", + "sandwich", + "orange", + "broccoli", + "carrot", + "hot dog", + "pizza", + "donut", + "cake", + "chair", + "couch", + "potted plant", + "bed", + "mirror", + "dining table", + "window", + "desk", + "toilet", + "door", + "tv", + "laptop", + "mouse", + "remote", + "keyboard", + "cell phone", + "microwave", + "oven", + "toaster", + "sink", + "refrigerator", + "blender", + "book", + "clock", + "vase", + "scissors", + "teddy bear", + "hair drier" +] From 500cc25a0e17c26021dfaadfc1423547e27e536b Mon Sep 17 00:00:00 2001 From: ilim Date: Sun, 6 Oct 2019 23:17:02 +0900 Subject: [PATCH 25/60] Add object notification --- slack/src/block_template_detection.json | 54 ++++++++++++++++++++++++ slack/src/main.js | 6 +-- slack/src/object_detection.js | 56 +++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 slack/src/block_template_detection.json create mode 100644 slack/src/object_detection.js diff --git a/slack/src/block_template_detection.json b/slack/src/block_template_detection.json new file mode 100644 index 0000000..82a4cb7 --- /dev/null +++ b/slack/src/block_template_detection.json @@ -0,0 +1,54 @@ +[ + { + "type": "image", + "title": { + "type": "plain_text", + "text": "[定期]部室スキャン" + }, + "image_url": "{{image_url}}", + "alt_text": "部室の物体検出結果" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "{{text}}" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "{{time}}" + } + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "📷 View photo with `/bushitsu-photo`" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "<{{viewer_url}}|WEB-配信動画版>" + }, + { + "type": "mrkdwn", + "text": "<{{photo_viewer_url}}|WEB-画像版>" + }, + { + "type": "mrkdwn", + "text": "*問い合せ*: <#{{contact_channel}}>" + } + ] + } +] diff --git a/slack/src/main.js b/slack/src/main.js index b3719a7..9768900 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -4,12 +4,12 @@ const { createMessageAdapter } = require('@slack/interactive-messages'); const crypto = require('crypto'); const fs = require('fs'); const object = require('json-templater/object'); -const Redis = require('ioredis'); const base64url = require('base64-url'); const helmet = require('helmet'); const cors = require('cors'); const axios = require('axios'); const morgan = require('morgan'); +const { objectsNotification } = require('./object_detection'); const app = express(); app.set('trust proxy', 1); @@ -37,9 +37,6 @@ const slackInteractions = createMessageAdapter( process.env.SLACK_SIGNING_SECRET, ); -const redis = new Redis({ - host: 'redis', -}); app.use(morgan('<@:user> [:date[clf]] :method :url :status :res[content-length] - :response-time ms', { skip: (req, res) => ['/hls/', '/photo/'].some((element) => req.path.startsWith(element)), @@ -123,3 +120,4 @@ app.get('/photo/:photoId', async (req, res) => { }); app.listen(80, () => console.log('Express app listening on port 80.')); +setInterval(() => objectsNotification(web), Number(process.env.NOTIFICATION_INTERVAL) * 1000); diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js new file mode 100644 index 0000000..ead7235 --- /dev/null +++ b/slack/src/object_detection.js @@ -0,0 +1,56 @@ +const { WebClient } = require('@slack/web-api'); +const axios = require('axios'); +const crypto = require('crypto'); +const object = require('json-templater/object'); +const fs = require('fs'); +const base64url = require('base64-url'); +const Redis = require('ioredis'); + +const redis = new Redis({ + host: 'redis', + keyPrefix: 'slack:', +}); + +module.exports.objectsNotification = async (web) => { + const { photoId } = await axios.post('http://media/photo').then((result) => result.data); + + const [awsUrl, objects] = await Promise.all([ + axios.get('http://tunnel').then((result) => result.data.awsUrl), + axios.get('http://object-detection/faster_rcnn_resnet101_coco', { params: { photo_id: photoId } }).then((result) => result.data), + ]); + + const text = objects.label_name.map((value, index) => `- \`${value}\`: ${objects.confidence[index].toFixed(3)}`).join('\n') || '何も検出されませんでした'; + + const blocks = object( + JSON.parse(fs.readFileSync('./block_template_detection.json', 'utf8')), + { + image_url: 'https://4.bp.blogspot.com/-ZHlXgooA38A/Wn1WVe2XBhI/AAAAAAABKJY/5BE6ZAbyeRwv3UlGsVU2YfPWVS_uT0PFQCLcBGAs/s800/text_kakko_kari.png', + text, + time: new Date().toLocaleString(), + viewer_url: `${awsUrl}/viewer`, + photo_viewer_url: `${awsUrl}/photo-viewer`, + contact_channel: process.env.CONTACT_CHANNEL, + }, + ); + + const ts = await redis.get('previous_ts'); + + if (ts) { + web.chat.update({ + channel: process.env.NOTIFICATION_CHANNEL, + text: '[定期]部室スキャン', + ts, + icon_emoji: ':slack:', + blocks, + }); + } else { + const result = await web.chat.postMessage({ + channel: process.env.NOTIFICATION_CHANNEL, + text: '[定期]部室スキャン', + ts, + icon_emoji: ':slack:', + blocks, + }); + redis.set('previous_ts', result.ts); + } +}; From 9178ac35a0eead559feb41d0f61b61d90844e391 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 7 Oct 2019 01:35:47 +0900 Subject: [PATCH 26/60] Show image on change-notification --- media/src/main.js | 2 +- object-detection/src/app.py | 23 +++++++++++++++++++++-- slack/src/main.js | 7 ++++--- slack/src/object_detection.js | 12 ++++++++---- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/media/src/main.js b/media/src/main.js index 7a6e2ff..d51f19d 100644 --- a/media/src/main.js +++ b/media/src/main.js @@ -9,7 +9,7 @@ const morgan = require('morgan'); const app = express(); app.use(helmet()); app.use(morgan('short')); -const hlsDir = '/dev/shm'; +const hlsDir = '/dev/shm/hls'; const redis = new Redis({ host: 'redis', diff --git a/object-detection/src/app.py b/object-detection/src/app.py index fffb7a5..50a8bdc 100644 --- a/object-detection/src/app.py +++ b/object-detection/src/app.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 +import glob import io import json import os +import time from typing import Dict import numpy as np @@ -12,19 +14,24 @@ from model import FasterRCNNResnet101Coco -app = Flask(__name__) +image_dir = "/dev/shm/photo" +app = Flask(__name__, static_url_path='/photo', static_folder=image_dir) + + app.logger.info("Loading network") net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) app.logger.info("Network loading finished") with open("labels.json") as f: label_names = json.load(f) +os.makedirs(image_dir, exist_ok=True) @app.route('/faster_rcnn_resnet101_coco') def object_detection(): photo_id = request.args.get("photo_id") threshold = request.args.get("threshold", os.getenv("THRESHOLD", 0.7)) + retention = float(request.args.get("retention", os.getenv("RETENTION_SEC", 60*60*24))) url = f"http://media/photo/{photo_id}" image = requests.get(url) @@ -33,14 +40,26 @@ def object_detection(): output = net(image) output = select_top_prediction(output, threshold) + + image = draw(image, output) + for f in glob.glob(f"{image_dir}/*"): + if f.split("/")[-1].isdecimal() and float(f.split("/")[-1]) / 1000 + retention < time.time(): + os.remove(f) + Image.fromarray(image).save(f"{image_dir}/{photo_id}", "JPEG") + return jsonify({ "bbox": (output["bbox"].reshape(-1, 2, 2) * np.array(image.shape[:2])).reshape(-1, 4).astype(int).tolist(), "confidence": output["conf"].tolist(), "label_id": output["label"].astype(int).tolist(), - "label_name": [label_names[label] for label in output["label"].astype(int)] + "label_name": [label_names[label] for label in output["label"].astype(int)], + "photo_id": photo_id }) +def draw(image: np.ndarray, prediction: Dict[str, np.ndarray]) -> np.ndarray: + return image + + def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] diff --git a/slack/src/main.js b/slack/src/main.js index 9768900..179d115 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -93,7 +93,7 @@ app.post('/bushitsu-photo', async (req, res) => { // Others -app.get('/photo/:photoId', async (req, res) => { +app.get(['/photo/:photoId', '/detected-photo/:photoId'], async (req, res) => { const { key } = req.query; const { photoId } = req.params; @@ -109,7 +109,8 @@ app.get('/photo/:photoId', async (req, res) => { return; } - const img = await axios.get(`http://media/photo/${photoId}`, { + const server = req.path.startsWith('/photo') ? 'media' : 'object-detection'; + const img = await axios.get(`http://${server}/photo/${photoId}`, { responseType: 'arraybuffer', headers: { 'Content-Type': 'image/jpg', @@ -120,4 +121,4 @@ app.get('/photo/:photoId', async (req, res) => { }); app.listen(80, () => console.log('Express app listening on port 80.')); -setInterval(() => objectsNotification(web), Number(process.env.NOTIFICATION_INTERVAL) * 1000); +setInterval(() => objectsNotification(web, Number(process.env.NOTIFICATION_INTERVAL)), Number(process.env.NOTIFICATION_INTERVAL) * 1000); diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js index ead7235..b562d1a 100644 --- a/slack/src/object_detection.js +++ b/slack/src/object_detection.js @@ -10,21 +10,26 @@ const redis = new Redis({ host: 'redis', keyPrefix: 'slack:', }); +const hostname = 'slack'; -module.exports.objectsNotification = async (web) => { +module.exports.objectsNotification = async (web, retention) => { const { photoId } = await axios.post('http://media/photo').then((result) => result.data); const [awsUrl, objects] = await Promise.all([ axios.get('http://tunnel').then((result) => result.data.awsUrl), - axios.get('http://object-detection/faster_rcnn_resnet101_coco', { params: { photo_id: photoId } }).then((result) => result.data), + axios.get('http://object-detection/faster_rcnn_resnet101_coco', { params: { photo_id: photoId, retention } }).then((result) => result.data), ]); const text = objects.label_name.map((value, index) => `- \`${value}\`: ${objects.confidence[index].toFixed(3)}`).join('\n') || '何も検出されませんでした'; + const key = crypto + .createHash('md5') + .update(`${photoId}-${process.env.SESSION_SECRET}`, 'utf8') + .digest('Base64'); const blocks = object( JSON.parse(fs.readFileSync('./block_template_detection.json', 'utf8')), { - image_url: 'https://4.bp.blogspot.com/-ZHlXgooA38A/Wn1WVe2XBhI/AAAAAAABKJY/5BE6ZAbyeRwv3UlGsVU2YfPWVS_uT0PFQCLcBGAs/s800/text_kakko_kari.png', + image_url: `${awsUrl}/${hostname}/detected-photo/${photoId}?key=${base64url.escape(key)}`, text, time: new Date().toLocaleString(), viewer_url: `${awsUrl}/viewer`, @@ -47,7 +52,6 @@ module.exports.objectsNotification = async (web) => { const result = await web.chat.postMessage({ channel: process.env.NOTIFICATION_CHANNEL, text: '[定期]部室スキャン', - ts, icon_emoji: ':slack:', blocks, }); From ed72d4d2b612ab92f85df2a48721681cf873a5eb Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 7 Oct 2019 02:28:30 +0900 Subject: [PATCH 27/60] Update preview --- object-detection/src/Pipfile | 1 + object-detection/src/Pipfile.lock | 71 ++++++++++++++++++++++++++++++- object-detection/src/app.py | 25 ++++------- object-detection/src/draw.py | 53 +++++++++++++++++++++++ 4 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 object-detection/src/draw.py diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index b6b8037..1b2ec46 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -21,6 +21,7 @@ test-generator = "==0.1.1" opencv-python = "~=4.1.1.26" flask = "~=1.1.1" pillow = "~=6.2.0" +matplotlib = "~=3.1.1" [requires] python_version = "3.7" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index 5507fa2..a263f09 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "dac253abd993ffb711d3636ab4ba20e8df0b4d48cc020a7daf062cb69b271167" + "sha256": "4e7392b94a2f0f97673ae5f5b1ac6d1ac79e56c805ab402962c8916047625e43" }, "pipfile-spec": 6, "requires": { @@ -50,6 +50,13 @@ ], "version": "==7.0" }, + "cycler": { + "hashes": [ + "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", + "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8" + ], + "version": "==0.10.0" + }, "decorator": { "hashes": [ "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", @@ -191,6 +198,39 @@ ], "version": "==1.1.0" }, + "kiwisolver": { + "hashes": [ + "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", + "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", + "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", + "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", + "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", + "sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75", + "sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187", + "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", + "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", + "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", + "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", + "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", + "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", + "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", + "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", + "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", + "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", + "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", + "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", + "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", + "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", + "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", + "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", + "sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004", + "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", + "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", + "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", + "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" + ], + "version": "==1.1.0" + }, "markdown": { "hashes": [ "sha256:2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", @@ -231,6 +271,21 @@ ], "version": "==1.1.1" }, + "matplotlib": { + "hashes": [ + "sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93", + "sha256:31a30d03f39528c79f3a592857be62a08595dec4ac034978ecd0f814fa0eec2d", + "sha256:4442ce720907f67a79d45de9ada47be81ce17e6c2f448b3c64765af93f6829c9", + "sha256:796edbd1182cbffa7e1e7a97f1e141f875a8501ba8dd834269ae3cd45a8c976f", + "sha256:934e6243df7165aad097572abf5b6003c77c9b6c480c3c4de6f2ef1b5fdd4ec0", + "sha256:bab9d848dbf1517bc58d1f486772e99919b19efef5dd8596d4b26f9f5ee08b6b", + "sha256:c1fe1e6cdaa53f11f088b7470c2056c0df7d80ee4858dadf6cbe433fcba4323b", + "sha256:e5b8aeca9276a3a988caebe9f08366ed519fff98f77c6df5b64d7603d0e42e36", + "sha256:ec6bd0a6a58df3628ff269978f4a4b924a0d371ad8ce1f8e2b635b99e482877a" + ], + "index": "pypi", + "version": "==3.1.1" + }, "networkx": { "hashes": [ "sha256:8311ddef63cf5c5c5e7c1d0212dd141d9a1fe3f474915281b73597ed5f1d4e3d" @@ -345,6 +400,20 @@ ], "version": "==3.10.0" }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "version": "==2.8.0" + }, "pyyaml": { "hashes": [ "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", diff --git a/object-detection/src/app.py b/object-detection/src/app.py index 50a8bdc..78517e4 100644 --- a/object-detection/src/app.py +++ b/object-detection/src/app.py @@ -1,10 +1,9 @@ #!/usr/bin/env python3 import glob -import io -import json import os -import time +from io import BytesIO +from time import time from typing import Dict import numpy as np @@ -12,19 +11,17 @@ from flask import Flask, jsonify, request from PIL import Image +from draw import LABEL_NAME, draw from model import FasterRCNNResnet101Coco image_dir = "/dev/shm/photo" +os.makedirs(image_dir, exist_ok=True) + app = Flask(__name__, static_url_path='/photo', static_folder=image_dir) app.logger.info("Loading network") net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) -app.logger.info("Network loading finished") - -with open("labels.json") as f: - label_names = json.load(f) -os.makedirs(image_dir, exist_ok=True) @app.route('/faster_rcnn_resnet101_coco') @@ -35,7 +32,7 @@ def object_detection(): url = f"http://media/photo/{photo_id}" image = requests.get(url) - image = Image.open(io.BytesIO(image.content)).convert('RGB') + image = Image.open(BytesIO(image.content)).convert('RGB') image = np.asarray(image) output = net(image) @@ -43,23 +40,19 @@ def object_detection(): image = draw(image, output) for f in glob.glob(f"{image_dir}/*"): - if f.split("/")[-1].isdecimal() and float(f.split("/")[-1]) / 1000 + retention < time.time(): + if f.split("/")[-1].isdecimal() and float(f.split("/")[-1]) / 1000 + retention < time(): os.remove(f) Image.fromarray(image).save(f"{image_dir}/{photo_id}", "JPEG") return jsonify({ - "bbox": (output["bbox"].reshape(-1, 2, 2) * np.array(image.shape[:2])).reshape(-1, 4).astype(int).tolist(), + "bbox": (output["bbox"].reshape(-1, 2, 2) * np.array(image.shape[-2::-1])).reshape(-1, 4).astype(int).tolist(), "confidence": output["conf"].tolist(), "label_id": output["label"].astype(int).tolist(), - "label_name": [label_names[label] for label in output["label"].astype(int)], + "label_name": [LABEL_NAME[label] for label in output["label"].astype(int)], "photo_id": photo_id }) -def draw(image: np.ndarray, prediction: Dict[str, np.ndarray]) -> np.ndarray: - return image - - def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] diff --git a/object-detection/src/draw.py b/object-detection/src/draw.py new file mode 100644 index 0000000..5529656 --- /dev/null +++ b/object-detection/src/draw.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import json +from typing import Dict, List + +import cv2 +import numpy as np +from matplotlib import cm + +with open("labels.json") as f: + LABEL_NAME: List[str] = json.load(f) + + +LABEL_COLOR = [[int(j*255) for j in cm.hsv(i)] for i in np.linspace(0, 1, len(LABEL_NAME), endpoint=False)] + + +def draw(image: np.ndarray, prediction: Dict[str, np.ndarray]) -> np.ndarray: + image = overlay_boxes(image, prediction) + image = overlay_class_names(image, prediction) + return image + + +def overlay_boxes(image: np.ndarray, prediction: Dict[str, np.ndarray]) -> np.ndarray: + labels = prediction["label"].astype(int) + boxes = (prediction["bbox"].reshape(-1, 2, 2) * np.array(image.shape[-2::-1])).reshape(-1, 4).astype(int) + + colors = [LABEL_COLOR[i] for i in labels] + + for box, color in zip(boxes, colors): + top_left, bottom_right = box[:2].tolist(), box[2:].tolist() + image = cv2.rectangle( + image, tuple(top_left), tuple(bottom_right), tuple(color), 1 + ) + return image + + +def overlay_class_names(image: np.ndarray, prediction: Dict[str, np.ndarray]) -> np.ndarray: + boxes = (prediction["bbox"].reshape(-1, 2, 2) * np.array(image.shape[-2::-1])).reshape(-1, 4).astype(int) + scores = prediction["conf"] + labels = prediction["label"].astype(int) + + labels = [LABEL_NAME[i] for i in labels] + + for box, score, label in zip(boxes, scores, labels): + x, y = box[:2] + text = f"{label}: {score :.2f}" + image = cv2.putText( + image, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 3 + ) + image = cv2.putText( + image, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2 + ) + return image From c66c1b6a27b5671cc63f96f33635ee2bd49d89d9 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 7 Oct 2019 10:06:12 +0900 Subject: [PATCH 28/60] Update docker-compose --- docker-compose.debug.yml | 1 - docker-compose.prod.yml | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index f31d997..d564009 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -129,7 +129,6 @@ services: environment: - RTMP_SERVER_URL=rtmp://streaming-server:1935/live - STREAM_NAME=bushitsuchan - - INFERENCE_INTERVAL_SEC=60 - DEVICE=CPU - CPU_EXTENSION=/opt/intel/openvino/inference_engine/lib/intel64/libcpu_extension_avx2.so - FLASK_ENV=development diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 6077f67..2c1682f 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -93,6 +93,8 @@ services: - SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET} - CONTACT_CHANNEL=${CONTACT_CHANNEL} - SESSION_SECRET=${SESSION_SECRET} + - NOTIFICATION_CHANNEL=${NOTIFICATION_CHANNEL} + - NOTIFICATION_INTERVAL=${NOTIFICATION_INTERVAL} volumes: - ./slack/src:/app - /etc/localtime:/etc/localtime:ro @@ -121,10 +123,7 @@ services: environment: - RTMP_SERVER_URL=rtmp://streaming-server:1935/live - STREAM_NAME=bushitsuchan - - INFERENCE_INTERVAL_SEC=60 - DEVICE=MYRIAD - - MODEL_FILE=classification/alexnet.xml - - WEIGHTS_FILE=classification/alexnet.bin privileged: true volumes: - ./object-detection/src:/app From 7e5ea240a9a044f5ef4eba5ba64c959eb36b5ef9 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 7 Oct 2019 15:29:46 +0900 Subject: [PATCH 29/60] Update object detection container --- .gitignore | 1 + object-detection/src/draw.py | 2 +- object-detection/src/get_model.sh | 4 ++++ object-detection/src/model.py | 17 +++++++---------- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index f7fb29c..cb08129 100644 --- a/.gitignore +++ b/.gitignore @@ -248,3 +248,4 @@ yarn.lock # model data openvino models +list_topologies.yml diff --git a/object-detection/src/draw.py b/object-detection/src/draw.py index 5529656..22ed936 100644 --- a/object-detection/src/draw.py +++ b/object-detection/src/draw.py @@ -47,7 +47,7 @@ def overlay_class_names(image: np.ndarray, prediction: Dict[str, np.ndarray]) -> image = cv2.putText( image, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 3 ) - image = cv2.putText( + image = cv2.putText( image, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2 ) return image diff --git a/object-detection/src/get_model.sh b/object-detection/src/get_model.sh index 9793040..03ddf73 100644 --- a/object-detection/src/get_model.sh +++ b/object-detection/src/get_model.sh @@ -1,9 +1,13 @@ +sed -e "s/data_type=FP32/data_type=FP16/g" /opt/intel/openvino/deployment_tools/tools/model_downloader/list_topologies.yml > ./list_topologies.yml + python /opt/intel/openvino/deployment_tools/tools/model_downloader/downloader.py \ + --config ./list_topologies.yml \ --name $1 \ --cache_dir ./.cache \ --output_dir ./models python /opt/intel/openvino/deployment_tools/tools/model_downloader/converter.py \ + --config ./list_topologies.yml \ --name $1 \ --mo /opt/intel/openvino/deployment_tools/model_optimizer/mo.py \ --download_dir ./models diff --git a/object-detection/src/model.py b/object-detection/src/model.py index 1a7264d..4f0438b 100644 --- a/object-detection/src/model.py +++ b/object-detection/src/model.py @@ -15,7 +15,7 @@ def __init__(self, model_file: str, weights_file: str, device: str = "CPU", cpu_extension: str = None) -> None: self.device = device self.ie = IECore() - assert self.device in self.ie.available_devices, f"Cannot find the specified device: {self.device}." + assert self.device in self.ie.available_devices, f"Cannot find the specified device: {self.device}. Please choose from available_devices: {self.ie.available_devices}" self.network = self.get_network(model_file, weights_file, cpu_extension) @@ -56,7 +56,7 @@ def forward(self, inputs: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]: class PreparedModel(Model): model_name: str - file: str + precisions = "FP16" def __init__(self, *args, **kwargs) -> None: with open("/opt/intel/openvino/deployment_tools/tools/model_downloader/list_topologies.yml") as f: @@ -66,9 +66,9 @@ def __init__(self, *args, **kwargs) -> None: assert self.model_name in topologies, \ f"{self.model_name} is not found in model zoo.\nPlease specify from the following.\n{topologies.keys()}" - output = topologies[self.model_name]["output"] + self.file - model_file = Path("models") / f"{output}.xml" - weights_file = Path("models") / f"{output}.bin" + output = Path("models") / topologies[self.model_name]["output"] / self.precisions + model_file = output / f"{self.model_name}.xml" + weights_file = output / f"{self.model_name}.bin" if not all(file.exists() for file in [model_file, weights_file]): subprocess.call(["sh", "./get_model.sh", self.model_name]) # TODO check @@ -77,11 +77,8 @@ def __init__(self, *args, **kwargs) -> None: class FasterRCNNResnet101Coco(PreparedModel): - def __init__(self, *args, **kwargs) -> None: - self.model_name = "faster_rcnn_resnet101_coco" - self.file = "FP32/faster_rcnn_resnet101_coco" - - super(FasterRCNNResnet101Coco, self).__init__(*args, **kwargs) + model_name = "faster_rcnn_resnet101_coco" + precisions = "FP32" def __call__(self, frame: np.ndarray) -> Dict[str, np.ndarray]: images = np.expand_dims(self.transform(frame), 0) From 352907914cafcb14eb5422a23142aa43a9615de5 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 7 Oct 2019 16:14:05 +0900 Subject: [PATCH 30/60] Fix bug --- media/src/main.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/media/src/main.js b/media/src/main.js index d51f19d..c722748 100644 --- a/media/src/main.js +++ b/media/src/main.js @@ -16,6 +16,11 @@ const redis = new Redis({ keyPrefix: 'media:', }); + +if (!fs.existsSync(hlsDir)) { + fs.mkdirSync(hlsDir); +} + ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) .inputOptions('-stream_loop -1') .addOption('-hls_flags', '+delete_segments') From 0a3cf7a9fd1de7f90c23e709cb9a76b40d0eaf4f Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 8 Oct 2019 23:19:45 +0900 Subject: [PATCH 31/60] Change how openvino is installed --- object-detection/Dockerfile | 32 ++++++++++++++---------- object-detection/Dockerfile-wget | 43 -------------------------------- 2 files changed, 19 insertions(+), 56 deletions(-) delete mode 100644 object-detection/Dockerfile-wget diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 1dd2a96..d867dda 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -3,24 +3,30 @@ FROM ubuntu:18.04 ARG NUM_THREADS=1 ENV LANG C.UTF-8 +# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#building-for-cpu +ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz +ARG INSTALL_DIR=/opt/intel/openvino +ARG TEMP_DIR=/tmp/openvino_installer + RUN sed -i.bak -e "s%http://archive.ubuntu.com/ubuntu/%http://jp.archive.ubuntu.com/ubuntu/%g" /etc/apt/sources.list && \ apt-get update -yqq && \ - apt-get install -yq --no-install-recommends wget unzip gnupg ca-certificates lsb-release && \ - update-ca-certificates - -# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_apt.html -RUN wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ - apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ - rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ - bash -c "echo 'deb https://apt.repos.intel.com/openvino/2019/ all main' >> /etc/apt/sources.list.d/intel-openvino-2019.list" && \ - apt-get update && \ - apt-get install -yq --no-install-recommends intel-openvino-dev-ubuntu18 + apt-get install -yq --no-install-recommends wget unzip cpio sudo lsb-release +RUN mkdir -p $TEMP_DIR && \ + cd $TEMP_DIR && \ + wget -c $DOWNLOAD_LINK && \ + tar xf l_openvino_toolkit*.tgz && \ + cd l_openvino_toolkit* && \ + sed -i 's/decline/accept/g' silent.cfg && \ + sed -i 's/#INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/g' silent.cfg && \ + ./install.sh -s silent.cfg && \ + rm -rf $TEMP_DIR +RUN $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh && \ + apt-get install -yq --no-install-recommends libgtk-3-dev -RUN apt-get install -yq --no-install-recommends libgtk-3-dev && \ - /opt/intel/openvino/install_dependencies/install_openvino_dependencies.sh # https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#run_the_docker_image_for_intel_movidius_neural_compute_stick_and_intel_neural_compute_stick_2 RUN cd /tmp/ && \ + apt-get install -yq --no-install-recommends unzip && \ wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ unzip v1.0.22.zip && cd libusb-1.0.22 && \ ./bootstrap.sh && \ @@ -30,7 +36,7 @@ RUN cd /tmp/ && \ RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc -RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev python3-pip && \ +RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev q && \ pip3 install pipenv ENV PIPENV_VENV_IN_PROJECT true diff --git a/object-detection/Dockerfile-wget b/object-detection/Dockerfile-wget deleted file mode 100644 index c54d685..0000000 --- a/object-detection/Dockerfile-wget +++ /dev/null @@ -1,43 +0,0 @@ -FROM ubuntu:18.04 - -ARG NUM_THREADS=1 -ENV LANG C.UTF-8 - -# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#building-for-cpu -ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz -ARG INSTALL_DIR=/opt/intel/openvino -ARG TEMP_DIR=/tmp/openvino_installer - - -RUN sed -i.bak -e "s%http://archive.ubuntu.com/ubuntu/%http://jp.archive.ubuntu.com/ubuntu/%g" /etc/apt/sources.list && \ - apt-get update -yqq && \ - apt-get install -yq --no-install-recommends wget unzip cpio sudo lsb-release -RUN mkdir -p $TEMP_DIR && \ - cd $TEMP_DIR && \ - wget -c $DOWNLOAD_LINK && \ - tar xf l_openvino_toolkit*.tgz && \ - cd l_openvino_toolkit* && \ - sed -i 's/decline/accept/g' silent.cfg && \ - sed -i 's/#INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/g' silent.cfg && \ - ./install.sh -s silent.cfg && \ - rm -rf $TEMP_DIR -RUN $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh && \ - apt-get install -yq --no-install-recommends libgtk-3-dev - - -# https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#run_the_docker_image_for_intel_movidius_neural_compute_stick_and_intel_neural_compute_stick_2 -RUN cd /tmp/ && \ - apt-get install -yq --no-install-recommends unzip && \ - wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ - unzip v1.0.22.zip && cd libusb-1.0.22 && \ - ./bootstrap.sh && \ - ./configure --disable-udev --enable-shared && \ - make -j${NUM_THREADS} && make install && \ - rm -rf /tmp/* - -RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc - -RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev python3-pip && \ - pip3 install pipenv - -ENV PIPENV_VENV_IN_PROJECT true From 1943bcd4b56592db63bc0172827945efe9188d40 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 21 Oct 2019 03:24:31 +0900 Subject: [PATCH 32/60] AGE message in slack --- slack/src/object_detection.js | 48 ++++++++++++++++++++++--------- slack/src/package-lock.json | 54 +++++++++++++++++++++++++++++++++++ slack/src/package.json | 1 + 3 files changed, 90 insertions(+), 13 deletions(-) diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js index b562d1a..7aa37ea 100644 --- a/slack/src/object_detection.js +++ b/slack/src/object_detection.js @@ -1,4 +1,4 @@ -const { WebClient } = require('@slack/web-api'); +const { RTMClient } = require('@slack/rtm-api'); const axios = require('axios'); const crypto = require('crypto'); const object = require('json-templater/object'); @@ -12,6 +12,18 @@ const redis = new Redis({ }); const hostname = 'slack'; +const rtm = new RTMClient(process.env.SLACK_BOT_ACCESS_TOKEN); +rtm.start() + .then('start rtmp client') + .catch(console.error); + +rtm.on('message', (event) => { + if (event.subtype == undefined) { + redis.set('age', true); + } +}); + + module.exports.objectsNotification = async (web, retention) => { const { photoId } = await axios.post('http://media/photo').then((result) => result.data); @@ -41,20 +53,30 @@ module.exports.objectsNotification = async (web, retention) => { const ts = await redis.get('previous_ts'); if (ts) { - web.chat.update({ + if (!await redis.get('age')) { + web.chat.update({ + channel: process.env.NOTIFICATION_CHANNEL, + text: '[定期]部室スキャン', + ts, + icon_emoji: ':slack:', + blocks, + }); + return; + } + web.chat.delete({ channel: process.env.NOTIFICATION_CHANNEL, - text: '[定期]部室スキャン', ts, - icon_emoji: ':slack:', - blocks, - }); - } else { - const result = await web.chat.postMessage({ - channel: process.env.NOTIFICATION_CHANNEL, - text: '[定期]部室スキャン', - icon_emoji: ':slack:', - blocks, + }).catch((e) => { + console.error(e); + redis.del('previous_ts'); }); - redis.set('previous_ts', result.ts); + redis.del('age'); } + const result = await web.chat.postMessage({ + channel: process.env.NOTIFICATION_CHANNEL, + text: '[定期]部室スキャン', + icon_emoji: ':slack:', + blocks, + }); + redis.set('previous_ts', result.ts); }; diff --git a/slack/src/package-lock.json b/slack/src/package-lock.json index d2c1ec2..1454413 100644 --- a/slack/src/package-lock.json +++ b/slack/src/package-lock.json @@ -64,6 +64,23 @@ "@types/node": ">=8.9.0" } }, + "@slack/rtm-api": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@slack/rtm-api/-/rtm-api-5.0.3.tgz", + "integrity": "sha512-rzNIFst8iuVYyHdE7e3KSrbAtIA7sfS4Pth9ObKUm5KDemX0zyI7YfAijO1kgr1EMriQkjlpKBhlNq9Y+aQr6g==", + "requires": { + "@slack/logger": "^1.0.0", + "@slack/web-api": "^5.1.0", + "@types/node": ">=8.9.0", + "@types/p-queue": "^2.3.2", + "@types/ws": "^5.1.1", + "eventemitter3": "^3.1.0", + "finity": "^0.5.4", + "p-cancelable": "^1.1.0", + "p-queue": "^2.4.2", + "ws": "^5.2.0" + } + }, "@slack/types": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@slack/types/-/types-1.1.0.tgz", @@ -120,6 +137,11 @@ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==" }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, "@types/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", @@ -210,6 +232,15 @@ "@types/mime": "*" } }, + "@types/ws": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz", + "integrity": "sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -366,6 +397,11 @@ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1658,6 +1694,11 @@ "locate-path": "^2.0.0" } }, + "finity": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/finity/-/finity-0.5.4.tgz", + "integrity": "sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA==" + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -3495,6 +3536,11 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -4803,6 +4849,14 @@ "signal-exit": "^3.0.2" } }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, "x-xss-protection": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", diff --git a/slack/src/package.json b/slack/src/package.json index 044dd5f..87376b1 100644 --- a/slack/src/package.json +++ b/slack/src/package.json @@ -12,6 +12,7 @@ "license": "ISC", "dependencies": { "@slack/interactive-messages": "^1.3.0", + "@slack/rtm-api": "^5.0.3", "@slack/web-api": "^5.1.0", "axios": "^0.19.0", "base64-url": "^2.3.2", From 1042bc693d12561a4b8a240a07269b2941a72b55 Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 9 Oct 2019 18:36:20 +0900 Subject: [PATCH 33/60] Fix Dockerfile typo --- object-detection/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index d867dda..b6254b1 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -36,7 +36,7 @@ RUN cd /tmp/ && \ RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc -RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev q && \ +RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev python3-pip && \ pip3 install pipenv ENV PIPENV_VENV_IN_PROJECT true From 5e6596fb3bbb79521c9d55c93393152a6aeb0e1e Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 21 Oct 2019 15:22:44 +0900 Subject: [PATCH 34/60] Add document for developers --- README.md | 4 +++ docs/developer.md | 76 ++++++++++++++++++++++++++++++++++++++++ docs/vscode/launch.json | 77 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 docs/developer.md create mode 100644 docs/vscode/launch.json diff --git a/README.md b/README.md index e176f07..f9c9e2f 100644 --- a/README.md +++ b/README.md @@ -193,3 +193,7 @@ Forwarding https://[AWS_REST_API_ID].execute-api.[AWS_REGION].amazonaws.com/pro すると,初回実行時(過去に Slack で認証をしていなければ) Slack の認証ページへリダイレクトされます。 Sign in すると自動的に配信再生ページへ移動します。 + +## for Developer + +[developer](docs/developer.md)を参照してください。 diff --git a/docs/developer.md b/docs/developer.md new file mode 100644 index 0000000..bd57b82 --- /dev/null +++ b/docs/developer.md @@ -0,0 +1,76 @@ +# bushitsuchan-PC + +Developer 向けの情報を書き置きます。 + +## 初期設定 + +任意の動画を`sample_movie.mp4`という名前でリポジトリ直下においてください。 +streamer が利用します。 + +## 開発環境 + +以下を使うと開発が楽になります。 + +- [lazydocker](https://github.com/jesseduffield/lazydocker) +- [Visual Studio Code](https://code.visualstudio.com/) + +## Debug + +### Run + +必要な container ごとに起動ができます。 + +例えば + +```sh= +docker-compose -f docker-compose.debug.yml up -d web slack +``` + +と実行すれば web container,slack container が立ち上がります。 +またそれらが依存する container も自動で立ち上がります。 + +Mac の場合 Docker の性能劣化の関係で,実行順序が望むものと異なってしまうという現象が起こります。 +その場合依存関係を解決できなくなるため,lazydocker などでモニタして修正する必要があります。 + +### Log + +```sh= +lazydocker +``` + +と実行すると,各 container の起動状況が確認できます。 +各 container の出力を見れたり,container 内で shell を起動することもできます。 + +### debugger + +各 container では debugger が起動しています。 +VScode で,[launch.json](vscode/launch.json)のように設定すると,各 container の debugger へと接続ができます。 + +## CPU 固有の設定 + +NCS2 を用いずに object-detection を行う場合,つまり CPU で演算をする場合に OpenVINO で SIMD 命令を利用しますが,CPU によって命令セットが異なる場合があります。 + +もし,object-detection container が特別な出力なしに強制終了する場合は,以下の変更が必要です。 +`docker-compose.debug.yml`ファイルの`object-detection`の設定する箇所で, + +```sh= +- CPU_EXTENSION=/opt/intel/openvino/inference_engine/lib/intel64/libcpu_extension_avx2.so +``` + +とあります。 +この行での`avx2`を`sse4`または`avx512`へと,自分の PC に合わせたものへの変更を行ってください。 + +## utils + +以下のコマンドで各 container が必要とする Package を完全にインストールします。 +環境をリセットし lock した情報から復元するため時間がかかりますが,完全に復元できます。 + +```sh= +docker-compose -f utils/docker-compose.install.yml up -d +``` + +以下のコマンドで各 container が必要とする Package の不足分と,脆弱性が見つかった Package の Upgrade を行います。 + +```sh= +docker-compose -f utils/docker-compose.update.yml up -d +``` diff --git a/docs/vscode/launch.json b/docs/vscode/launch.json new file mode 100644 index 0000000..480726b --- /dev/null +++ b/docs/vscode/launch.json @@ -0,0 +1,77 @@ +{ + "version": "0.2.0", + "configurations": [ + + { + "type": "node", + "request": "launch", + "name": "NodeJS", + "program": "${file}" + }, + { + "type": "node", + "request": "attach", + "name": "media: Attach", + "port": 4000, + "address": "localhost", + "localRoot": "${workspaceFolder}/media/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "tunnel: Attach", + "port": 4001, + "address": "localhost", + "localRoot": "${workspaceFolder}/tunnel/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "web: Attach", + "port": 4002, + "address": "localhost", + "localRoot": "${workspaceFolder}/web/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "slack: Attach", + "port": 4003, + "address": "localhost", + "localRoot": "${workspaceFolder}/slack/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "endpoint: Attach", + "port": 4004, + "address": "localhost", + "localRoot": "${workspaceFolder}/endpoint/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "name": "object-detection: Attach", + "type": "python", + "request": "attach", + "port": 5678, + "host": "localhost", + "pathMappings": [ + { + "localRoot": "${workspaceFolder}/object-detection/src", + "remoteRoot": "/app" + } + ], + "justMyCode": false + } + ] + } + \ No newline at end of file From d218e27d66b21b96065df74ce72a5fbe19ff6c31 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 21 Oct 2019 16:10:36 +0900 Subject: [PATCH 35/60] Update packages --- docker-compose.prod.yml | 10 +- endpoint/src/package-lock.json | 58 ++--- endpoint/src/package.json | 4 +- media/src/package-lock.json | 86 +++---- media/src/package.json | 8 +- slack/src/package-lock.json | 98 ++++---- slack/src/package.json | 10 +- streaming-server/src/package-lock.json | 64 ++--- streaming-server/src/package.json | 6 +- tunnel/src/package-lock.json | 94 ++++---- tunnel/src/package.json | 8 +- web/src/package-lock.json | 319 +++++++++++-------------- web/src/package.json | 10 +- 13 files changed, 362 insertions(+), 413 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 2c1682f..c154540 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -3,7 +3,7 @@ services: streaming-server: image: node:alpine working_dir: /app - command: ash -c "npm install && npm start" + command: ash -c "npm ci && npm start" volumes: - ./streaming-server/src:/app ports: @@ -24,7 +24,7 @@ services: media: build: ./media working_dir: /app - command: ash -c "npm install && npm start" + command: ash -c "npm ci && npm start" entrypoint: docker-entrypoint.sh volumes: - ./media/src:/app @@ -51,7 +51,7 @@ services: tunnel: build: ./tunnel working_dir: /app - command: ash -c "npm install && npm start" + command: ash -c "npm ci && npm start" volumes: - ./tunnel/src:/app environment: @@ -73,7 +73,7 @@ services: web: image: node:alpine working_dir: /app - command: ash -c "npm install && npm start" + command: ash -c "npm ci && npm start" environment: - SESSION_SECRET=${SESSION_SECRET} - SLACK_CLIENT_ID=${SLACK_CLIENT_ID} @@ -87,7 +87,7 @@ services: slack: image: node:alpine working_dir: /app - command: ash -c "npm install && npm start" + command: ash -c "npm ci && npm start" environment: - SLACK_BOT_ACCESS_TOKEN=${SLACK_BOT_ACCESS_TOKEN} - SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET} diff --git a/endpoint/src/package-lock.json b/endpoint/src/package-lock.json index 8957768..b15fc8e 100644 --- a/endpoint/src/package-lock.json +++ b/endpoint/src/package-lock.json @@ -40,15 +40,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -784,9 +784,9 @@ "dev": true }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -918,12 +918,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -933,13 +933,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -1898,9 +1898,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2649,18 +2649,18 @@ "dev": true }, "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" diff --git a/endpoint/src/package.json b/endpoint/src/package.json index a666953..9b8e166 100644 --- a/endpoint/src/package.json +++ b/endpoint/src/package.json @@ -14,9 +14,9 @@ "express": "^4.17.1" }, "devDependencies": { - "eslint": "^6.3.0", + "eslint": "^6.5.1", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.2", - "nodemon": "^1.19.2" + "nodemon": "^1.19.4" } } diff --git a/media/src/package-lock.json b/media/src/package-lock.json index f014cee..ff5f156 100644 --- a/media/src/package-lock.json +++ b/media/src/package-lock.json @@ -40,15 +40,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -284,9 +284,9 @@ } }, "bowser": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.5.4.tgz", - "integrity": "sha512-74GGwfc2nzYD19JCiA0RwCxdq7IY5jHeEaSrrgm/5kusEuK+7UK0qDG3gyzN47c4ViNyO4osaKtZE+aSV6nlpQ==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.7.0.tgz", + "integrity": "sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w==" }, "boxen": { "version": "1.3.0", @@ -837,9 +837,9 @@ "dev": true }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -971,12 +971,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -986,13 +986,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -1975,9 +1975,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2077,9 +2077,9 @@ } }, "helmet": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.0.tgz", - "integrity": "sha512-TS3GryQMPR7n/heNnGC0Cl3Ess30g8C6EtqZyylf+Y2/kF4lM8JinOR90rzIICsw4ymWTvji4OhDmqsqxkLrcg==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", "requires": { "depd": "2.0.0", "dns-prefetch-control": "0.2.0", @@ -2088,7 +2088,7 @@ "feature-policy": "0.3.0", "frameguard": "3.1.0", "helmet-crossdomain": "0.4.0", - "helmet-csp": "2.9.1", + "helmet-csp": "2.9.2", "hide-powered-by": "1.1.0", "hpkp": "2.0.0", "hsts": "2.2.0", @@ -2111,11 +2111,11 @@ "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" }, "helmet-csp": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.1.tgz", - "integrity": "sha512-HgdXSJ6AVyXiy5ohVGpK6L7DhjI9KVdKVB1xRoixxYKsFXFwoVqtLKgDnfe3u8FGGKf9Ml9k//C9rnncIIAmyA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", "requires": { - "bowser": "2.5.4", + "bowser": "^2.6.1", "camelize": "1.0.0", "content-security-policy-builder": "2.1.0", "dasherize": "2.0.0" @@ -2254,9 +2254,9 @@ } }, "ioredis": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.14.0.tgz", - "integrity": "sha512-vGzyW9QTdGMjaAPUhMj48Z31mIO5qJLzkbsE5dg+orNi7L5Ph035htmkBZNDTDdDk7kp7e9UJUr+alhRuaWp8g==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.14.1.tgz", + "integrity": "sha512-94W+X//GHM+1GJvDk6JPc+8qlM7Dul+9K+lg3/aHixPN7ZGkW6qlvX0DG6At9hWtH2v3B32myfZqWoANUJYGJA==", "requires": { "cluster-key-slot": "^1.1.0", "debug": "^4.1.1", @@ -2858,18 +2858,18 @@ "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" diff --git a/media/src/package.json b/media/src/package.json index c962376..7b26e00 100644 --- a/media/src/package.json +++ b/media/src/package.json @@ -13,14 +13,14 @@ "dependencies": { "express": "^4.17.1", "fluent-ffmpeg": "^2.1.2", - "helmet": "^3.21.0", - "ioredis": "^4.14.0", + "helmet": "^3.21.1", + "ioredis": "^4.14.1", "morgan": "^1.9.1" }, "devDependencies": { - "eslint": "^6.3.0", + "eslint": "^6.5.1", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.2", - "nodemon": "^1.19.2" + "nodemon": "^1.19.4" } } diff --git a/slack/src/package-lock.json b/slack/src/package-lock.json index 1454413..dea3935 100644 --- a/slack/src/package-lock.json +++ b/slack/src/package-lock.json @@ -82,14 +82,14 @@ } }, "@slack/types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@slack/types/-/types-1.1.0.tgz", - "integrity": "sha512-uak4Jbi8nlX8xmElkPt1ixxVQXMKdBRbzBayn5bRzZ9Yx3bQGlyJdFs6GjEKI+fvFP0ZTiGWKOzlJTH3Tm/9fg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-1.2.1.tgz", + "integrity": "sha512-NyGh7MibW+a0OHkwwOPlv63hC639dzQdkFy4dj0tl4sAdZR4OBaE/OhXixKhCzcT3kJsPXaQmvkUN7sqSf52iA==" }, "@slack/web-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.1.0.tgz", - "integrity": "sha512-bnzS1I8iOfNB4xSX0zQ/uRBnWTy7iPnAd0y+H/D8YRbEiXqAWaxlVQB8pio54hegSVcRRWRKFb2fyViSraMXqw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.2.1.tgz", + "integrity": "sha512-YobhBNMwEFZvfvOIBNU+GNyOqUa/S1rdiWliESYAq9ZcUXGblgEYIL3sxKwuNQckBjCgSYzexT3+nX5dSepwJg==", "requires": { "@slack/logger": "^1.0.0", "@slack/types": "^1.1.0", @@ -257,15 +257,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -558,9 +558,9 @@ } }, "bowser": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.5.4.tgz", - "integrity": "sha512-74GGwfc2nzYD19JCiA0RwCxdq7IY5jHeEaSrrgm/5kusEuK+7UK0qDG3gyzN47c4ViNyO4osaKtZE+aSV6nlpQ==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.7.0.tgz", + "integrity": "sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w==" }, "boxen": { "version": "1.3.0", @@ -1140,9 +1140,9 @@ "dev": true }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1305,12 +1305,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -1320,13 +1320,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -2367,9 +2367,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2475,9 +2475,9 @@ } }, "helmet": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.0.tgz", - "integrity": "sha512-TS3GryQMPR7n/heNnGC0Cl3Ess30g8C6EtqZyylf+Y2/kF4lM8JinOR90rzIICsw4ymWTvji4OhDmqsqxkLrcg==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", "requires": { "depd": "2.0.0", "dns-prefetch-control": "0.2.0", @@ -2486,7 +2486,7 @@ "feature-policy": "0.3.0", "frameguard": "3.1.0", "helmet-crossdomain": "0.4.0", - "helmet-csp": "2.9.1", + "helmet-csp": "2.9.2", "hide-powered-by": "1.1.0", "hpkp": "2.0.0", "hsts": "2.2.0", @@ -2509,11 +2509,11 @@ "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" }, "helmet-csp": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.1.tgz", - "integrity": "sha512-HgdXSJ6AVyXiy5ohVGpK6L7DhjI9KVdKVB1xRoixxYKsFXFwoVqtLKgDnfe3u8FGGKf9Ml9k//C9rnncIIAmyA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", "requires": { - "bowser": "2.5.4", + "bowser": "^2.6.1", "camelize": "1.0.0", "content-security-policy-builder": "2.1.0", "dasherize": "2.0.0" @@ -2652,9 +2652,9 @@ } }, "ioredis": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.14.0.tgz", - "integrity": "sha512-vGzyW9QTdGMjaAPUhMj48Z31mIO5qJLzkbsE5dg+orNi7L5Ph035htmkBZNDTDdDk7kp7e9UJUr+alhRuaWp8g==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.14.1.tgz", + "integrity": "sha512-94W+X//GHM+1GJvDk6JPc+8qlM7Dul+9K+lg3/aHixPN7ZGkW6qlvX0DG6At9hWtH2v3B32myfZqWoANUJYGJA==", "requires": { "cluster-key-slot": "^1.1.0", "debug": "^4.1.1", @@ -3308,18 +3308,18 @@ "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" diff --git a/slack/src/package.json b/slack/src/package.json index 87376b1..d7892fb 100644 --- a/slack/src/package.json +++ b/slack/src/package.json @@ -13,20 +13,20 @@ "dependencies": { "@slack/interactive-messages": "^1.3.0", "@slack/rtm-api": "^5.0.3", - "@slack/web-api": "^5.1.0", + "@slack/web-api": "^5.2.1", "axios": "^0.19.0", "base64-url": "^2.3.2", "cors": "^2.8.5", "express": "^4.17.1", - "helmet": "^3.21.0", - "ioredis": "^4.14.0", + "helmet": "^3.21.1", + "ioredis": "^4.14.1", "json-templater": "^1.2.0", "morgan": "^1.9.1" }, "devDependencies": { - "eslint": "^6.3.0", + "eslint": "^6.5.1", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.2", - "nodemon": "^1.19.2" + "nodemon": "^1.19.4" } } diff --git a/streaming-server/src/package-lock.json b/streaming-server/src/package-lock.json index 6c2f8fa..4901e7a 100644 --- a/streaming-server/src/package-lock.json +++ b/streaming-server/src/package-lock.json @@ -40,15 +40,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -794,9 +794,9 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -928,12 +928,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -943,13 +943,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -1908,9 +1908,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2655,9 +2655,9 @@ "dev": true }, "node-media-server": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-media-server/-/node-media-server-2.1.3.tgz", - "integrity": "sha512-BZf39fpVDSVQT2E+8DqSVOb7oo31rcbA36l9sqtSuyZhBdxjidL5Nk2/G/2vqMGR9Q4JKzkTskGay2dWy5ZsUQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/node-media-server/-/node-media-server-2.1.4.tgz", + "integrity": "sha512-3+6aWrExhZwT70U9Bjgq/dLDo22NcKql/nOCwbJ3BuZDgE8oBe5PkCSpCHyfES2o6vC2pTTvAojIO+bdRcC5cg==", "requires": { "basic-auth-connect": "^1.0.0", "chalk": "^2.4.2", @@ -2669,18 +2669,18 @@ } }, "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" diff --git a/streaming-server/src/package.json b/streaming-server/src/package.json index f17798c..8c50c4a 100644 --- a/streaming-server/src/package.json +++ b/streaming-server/src/package.json @@ -11,12 +11,12 @@ "author": "", "license": "ISC", "dependencies": { - "node-media-server": "^2.1.3" + "node-media-server": "^2.1.4" }, "devDependencies": { - "eslint": "^6.3.0", + "eslint": "^6.5.1", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.2", - "nodemon": "^1.19.2" + "nodemon": "^1.19.4" } } diff --git a/tunnel/src/package-lock.json b/tunnel/src/package-lock.json index 08561ad..13ad813 100644 --- a/tunnel/src/package-lock.json +++ b/tunnel/src/package-lock.json @@ -65,15 +65,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -229,13 +229,13 @@ "dev": true }, "aws-sdk": { - "version": "2.524.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.524.0.tgz", - "integrity": "sha512-nCnKEExs1OqwNG6sIrRy+Lj8Zt2M6BTa6YlEMQ1gIpdwznaAN9XyTnm+MDc3iYsSl58MOBwiKpY8d6CONuxuDw==", + "version": "2.553.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.553.0.tgz", + "integrity": "sha512-tcITF/3ijBumvP13Qrq/VB1eRWW6szKF0xVwZ/ch0MGkaEiTQ9n3zNRPtQc1drllsVEm5u5aXp3inoi5zmq0xg==", "requires": { "buffer": "4.9.1", "events": "1.1.1", - "ieee754": "1.1.8", + "ieee754": "1.1.13", "jmespath": "0.15.0", "querystring": "0.2.0", "sax": "1.2.1", @@ -369,9 +369,9 @@ } }, "bowser": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.5.4.tgz", - "integrity": "sha512-74GGwfc2nzYD19JCiA0RwCxdq7IY5jHeEaSrrgm/5kusEuK+7UK0qDG3gyzN47c4ViNyO4osaKtZE+aSV6nlpQ==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.7.0.tgz", + "integrity": "sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w==" }, "boxen": { "version": "1.3.0", @@ -983,9 +983,9 @@ "dev": true }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1117,12 +1117,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -1132,13 +1132,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -2148,9 +2148,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2263,9 +2263,9 @@ } }, "helmet": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.0.tgz", - "integrity": "sha512-TS3GryQMPR7n/heNnGC0Cl3Ess30g8C6EtqZyylf+Y2/kF4lM8JinOR90rzIICsw4ymWTvji4OhDmqsqxkLrcg==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", "requires": { "depd": "2.0.0", "dns-prefetch-control": "0.2.0", @@ -2274,7 +2274,7 @@ "feature-policy": "0.3.0", "frameguard": "3.1.0", "helmet-crossdomain": "0.4.0", - "helmet-csp": "2.9.1", + "helmet-csp": "2.9.2", "hide-powered-by": "1.1.0", "hpkp": "2.0.0", "hsts": "2.2.0", @@ -2297,11 +2297,11 @@ "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" }, "helmet-csp": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.1.tgz", - "integrity": "sha512-HgdXSJ6AVyXiy5ohVGpK6L7DhjI9KVdKVB1xRoixxYKsFXFwoVqtLKgDnfe3u8FGGKf9Ml9k//C9rnncIIAmyA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", "requires": { - "bowser": "2.5.4", + "bowser": "^2.6.1", "camelize": "1.0.0", "content-security-policy-builder": "2.1.0", "dasherize": "2.0.0" @@ -2369,9 +2369,9 @@ } }, "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "ienoopen": { "version": "1.1.0", @@ -3075,18 +3075,18 @@ "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" diff --git a/tunnel/src/package.json b/tunnel/src/package.json index dc2c8e4..9079e21 100644 --- a/tunnel/src/package.json +++ b/tunnel/src/package.json @@ -11,16 +11,16 @@ "author": "", "license": "ISC", "dependencies": { - "aws-sdk": "^2.524.0", + "aws-sdk": "^2.553.0", "express": "^4.17.1", - "helmet": "^3.21.0", + "helmet": "^3.21.1", "morgan": "^1.9.1", "ngrok": "^3.2.5" }, "devDependencies": { - "eslint": "^6.3.0", + "eslint": "^6.5.1", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.2", - "nodemon": "^1.19.2" + "nodemon": "^1.19.4" } } diff --git a/web/src/package-lock.json b/web/src/package-lock.json index b4cc5b2..faf7f6c 100644 --- a/web/src/package-lock.json +++ b/web/src/package-lock.json @@ -40,15 +40,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -298,9 +298,9 @@ } }, "bowser": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.5.4.tgz", - "integrity": "sha512-74GGwfc2nzYD19JCiA0RwCxdq7IY5jHeEaSrrgm/5kusEuK+7UK0qDG3gyzN47c4ViNyO4osaKtZE+aSV6nlpQ==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.7.0.tgz", + "integrity": "sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w==" }, "boxen": { "version": "1.3.0", @@ -574,9 +574,9 @@ "dev": true }, "connect-redis": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-4.0.2.tgz", - "integrity": "sha512-SuOGp/2dgpH738SYj0rZfoeKpuV/C4W0APGWrvyC3ijgXkKq/LKdgyCfW2oSxIPE1ndeOgmuei2bh3wIU50ZLw==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-4.0.3.tgz", + "integrity": "sha512-Php0P0ShNfilW6f2d/2v7Q0VAiFeBYsg0bIgu8ST3x26CcQ1JtzV6vxPLUwK0uiq10hQSMR+HzSNhWbcvx6nLg==" }, "contains-path": { "version": "0.1.0", @@ -870,9 +870,9 @@ "dev": true }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1035,12 +1035,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -1050,13 +1050,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -1226,25 +1226,20 @@ } }, "express-session": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz", - "integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.0.tgz", + "integrity": "sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg==", "requires": { - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.0.2", "parseurl": "~1.3.3", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.0", "uid-safe": "~2.1.5" }, "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1257,6 +1252,11 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" } } }, @@ -1528,29 +1528,25 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "bundled": true, "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "bundled": true, "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "bundled": true, "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": false, - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1560,15 +1556,13 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "bundled": true, "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1578,43 +1572,37 @@ }, "chownr": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "bundled": true, "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "bundled": true, "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "bundled": true, "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "bundled": true, "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "bundled": true, "dev": true, "optional": true }, "debug": { "version": "4.1.1", - "resolved": false, - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1623,29 +1611,25 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": false, - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "bundled": true, "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "bundled": true, "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bundled": true, "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": false, - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1654,15 +1638,13 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1678,8 +1660,7 @@ }, "glob": { "version": "7.1.3", - "resolved": false, - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1693,15 +1674,13 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "bundled": true, "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": false, - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1710,8 +1689,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": false, - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1720,8 +1698,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1731,22 +1708,19 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "bundled": true, "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "bundled": true, "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1755,15 +1729,13 @@ }, "isarray": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "bundled": true, "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1772,15 +1744,13 @@ }, "minimist": { "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "bundled": true, "dev": true, "optional": true }, "minipass": { "version": "2.3.5", - "resolved": false, - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1790,8 +1760,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": false, - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1800,8 +1769,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1810,15 +1778,13 @@ }, "ms": { "version": "2.1.1", - "resolved": false, - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "bundled": true, "dev": true, "optional": true }, "needle": { "version": "2.3.0", - "resolved": false, - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1829,8 +1795,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": false, - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1848,8 +1813,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1859,15 +1823,13 @@ }, "npm-bundled": { "version": "1.0.6", - "resolved": false, - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "bundled": true, "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "resolved": false, - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1877,8 +1839,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1890,22 +1851,19 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "bundled": true, "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "bundled": true, "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1914,22 +1872,19 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "bundled": true, "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1939,22 +1894,19 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "bundled": true, "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": false, - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1966,8 +1918,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -1975,8 +1926,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -1991,8 +1941,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": false, - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -2001,50 +1950,43 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": false, - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "bundled": true, "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true, "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": false, - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "bundled": true, "dev": true, "optional": true }, "semver": { "version": "5.7.0", - "resolved": false, - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "bundled": true, "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -2055,8 +1997,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -2065,8 +2006,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -2075,15 +2015,13 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "bundled": true, "dev": true, "optional": true }, "tar": { "version": "4.4.8", - "resolved": false, - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -2098,15 +2036,13 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": false, - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -2115,15 +2051,13 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "bundled": true, "dev": true, "optional": true }, "yallist": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "bundled": true, "dev": true, "optional": true } @@ -2168,9 +2102,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2276,9 +2210,9 @@ } }, "helmet": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.0.tgz", - "integrity": "sha512-TS3GryQMPR7n/heNnGC0Cl3Ess30g8C6EtqZyylf+Y2/kF4lM8JinOR90rzIICsw4ymWTvji4OhDmqsqxkLrcg==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", "requires": { "depd": "2.0.0", "dns-prefetch-control": "0.2.0", @@ -2287,7 +2221,7 @@ "feature-policy": "0.3.0", "frameguard": "3.1.0", "helmet-crossdomain": "0.4.0", - "helmet-csp": "2.9.1", + "helmet-csp": "2.9.2", "hide-powered-by": "1.1.0", "hpkp": "2.0.0", "hsts": "2.2.0", @@ -2310,11 +2244,11 @@ "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" }, "helmet-csp": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.1.tgz", - "integrity": "sha512-HgdXSJ6AVyXiy5ohVGpK6L7DhjI9KVdKVB1xRoixxYKsFXFwoVqtLKgDnfe3u8FGGKf9Ml9k//C9rnncIIAmyA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", "requires": { - "bowser": "2.5.4", + "bowser": "^2.6.1", "camelize": "1.0.0", "content-security-policy-builder": "2.1.0", "dasherize": "2.0.0" @@ -3093,23 +3027,38 @@ "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" }, "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", diff --git a/web/src/package.json b/web/src/package.json index aa8cad3..2499b32 100644 --- a/web/src/package.json +++ b/web/src/package.json @@ -12,20 +12,20 @@ "license": "ISC", "dependencies": { "axios": "^0.19.0", - "connect-redis": "^4.0.2", + "connect-redis": "^4.0.3", "cors": "^2.8.5", "ejs": "^2.7.1", "express": "^4.17.1", - "express-session": "^1.16.2", - "helmet": "^3.21.0", + "express-session": "^1.17.0", + "helmet": "^3.21.1", "ioredis": "^4.14.1", "morgan": "^1.9.1", "proxy-middleware": "^0.15.0" }, "devDependencies": { - "eslint": "^6.3.0", + "eslint": "^6.5.1", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.2", - "nodemon": "^1.19.2" + "nodemon": "^1.19.4" } } From 0e43139697b250004e2535248c2d158a40224181 Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 22 Oct 2019 01:06:38 +0900 Subject: [PATCH 36/60] Return image without save in media --- media/src/main.js | 25 +++++++++++++++++++++++++ object-detection/src/app.py | 3 +-- slack/src/object_detection.js | 4 ++-- web/src/main.js | 3 +-- web/src/views/photo-viewer.ejs | 2 +- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/media/src/main.js b/media/src/main.js index c722748..eb009ef 100644 --- a/media/src/main.js +++ b/media/src/main.js @@ -30,6 +30,31 @@ ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) }) .save(`${hlsDir}/output.m3u8`); +app.get('/temporary', async (req, res) => { + const ffstream = ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) + .addOption('-vframes', 1) + .on('error', (err) => { + console.error('ffmpeg command to convert to image failed:\n', err); + }) + .format('image2') + .pipe(); + + const image = await new Promise((resolve, reject) => { + const buffers = []; + ffstream.on('data', (chunk) => { + buffers.push(chunk); + }); + ffstream.on('end', () => { + resolve(Buffer.concat(buffers)); + }); + ffstream.on('error', (e) => { + reject(e); + }); + }); + res.contentType('image/jpg'); + res.status(200).send(image); +}); + app.post('/photo', (req, res) => { const time = Date.now(); redis.set(`${time}-pending`, true, 'EX', 5); diff --git a/object-detection/src/app.py b/object-detection/src/app.py index 78517e4..b051350 100644 --- a/object-detection/src/app.py +++ b/object-detection/src/app.py @@ -30,8 +30,7 @@ def object_detection(): threshold = request.args.get("threshold", os.getenv("THRESHOLD", 0.7)) retention = float(request.args.get("retention", os.getenv("RETENTION_SEC", 60*60*24))) - url = f"http://media/photo/{photo_id}" - image = requests.get(url) + image = requests.get("http://media/temporary") image = Image.open(BytesIO(image.content)).convert('RGB') image = np.asarray(image) diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js index 7aa37ea..304b0d0 100644 --- a/slack/src/object_detection.js +++ b/slack/src/object_detection.js @@ -25,11 +25,11 @@ rtm.on('message', (event) => { module.exports.objectsNotification = async (web, retention) => { - const { photoId } = await axios.post('http://media/photo').then((result) => result.data); + const photoId = Date.now(); const [awsUrl, objects] = await Promise.all([ axios.get('http://tunnel').then((result) => result.data.awsUrl), - axios.get('http://object-detection/faster_rcnn_resnet101_coco', { params: { photo_id: photoId, retention } }).then((result) => result.data), + axios.get('http://object-detection/faster_rcnn_resnet101_coco', { params: { retention } }).then((result) => result.data), ]); const text = objects.label_name.map((value, index) => `- \`${value}\`: ${objects.confidence[index].toFixed(3)}`).join('\n') || '何も検出されませんでした'; diff --git a/web/src/main.js b/web/src/main.js index 31213d1..a31f6bb 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -174,8 +174,7 @@ app.get('/viewer', (req, res) => { }); app.get('/photo-viewer', async (req, res) => { - const { photoId } = await axios.post('http://media/photo').then((result) => result.data); - res.render('photo-viewer.ejs', { photoId }); + res.render('photo-viewer.ejs', { photoPath: `data/temporary?time=${Date.now()}` }); }); app.use('/data', proxy(url.parse('http://media/'))); diff --git a/web/src/views/photo-viewer.ejs b/web/src/views/photo-viewer.ejs index 737f78f..915cf03 100644 --- a/web/src/views/photo-viewer.ejs +++ b/web/src/views/photo-viewer.ejs @@ -12,6 +12,6 @@ 動画版 - + From 8c0c494a3ce6acce599b3356b91ccfa01d1623c8 Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 22 Oct 2019 01:47:53 +0900 Subject: [PATCH 37/60] Split media into photo-storage and hls --- docker-compose.debug.yml | 21 +- docker-compose.prod.yml | 20 +- docs/vscode/launch.json | 139 +- {media => hls}/.dockerignore | 0 {media => hls}/Dockerfile | 0 {media => hls}/src/.eslintrc.yml | 0 hls/src/main.js | 29 + hls/src/package-lock.json | 4273 +++++++++++++++++ hls/src/package.json | 25 + image-storage/.dockerignore | 2 + image-storage/Dockerfile | 4 + image-storage/src/.eslintrc.yml | 12 + {media => image-storage}/src/main.js | 16 - .../src/package-lock.json | 0 {media => image-storage}/src/package.json | 0 utils/docker-compose.install.yml | 14 +- utils/docker-compose.update.yml | 14 +- web/src/main.js | 11 +- web/src/views/viewer.html | 4 +- 19 files changed, 4473 insertions(+), 111 deletions(-) rename {media => hls}/.dockerignore (100%) rename {media => hls}/Dockerfile (100%) rename {media => hls}/src/.eslintrc.yml (100%) create mode 100644 hls/src/main.js create mode 100644 hls/src/package-lock.json create mode 100644 hls/src/package.json create mode 100644 image-storage/.dockerignore create mode 100644 image-storage/Dockerfile create mode 100644 image-storage/src/.eslintrc.yml rename {media => image-storage}/src/main.js (81%) rename {media => image-storage}/src/package-lock.json (100%) rename {media => image-storage}/src/package.json (100%) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index d564009..8d729d4 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -19,13 +19,13 @@ services: environment: - RTMP_SERVER_URL=rtmp://streaming-server:1935/live - STREAM_NAME=bushitsuchan - media: - build: ./media + image-storage: + build: ./image-storage working_dir: /app command: npm run dev entrypoint: docker-entrypoint.sh volumes: - - ./media/src:/app + - ./image-storage/src:/app - ./photo:/photo ports: - 3000:80 @@ -36,6 +36,21 @@ services: depends_on: - streamer - redis + hls: + build: ./hls + working_dir: /app + command: npm run dev + entrypoint: docker-entrypoint.sh + volumes: + - ./hls/src:/app + ports: + - 3006:80 + - 4006:9229 + environment: + - RTMP_SERVER_URL=rtmp://streaming-server:1935/live + - STREAM_NAME=bushitsuchan + depends_on: + - streamer reverse-proxy: image: nginx:alpine diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c154540..f947428 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -21,13 +21,13 @@ services: - STREAM_NAME=bushitsuchan devices: - /dev/video0:/dev/video0 - media: - build: ./media + image-storage: + build: ./image-storage working_dir: /app command: ash -c "npm ci && npm start" entrypoint: docker-entrypoint.sh volumes: - - ./media/src:/app + - ./image-storage/src:/app - ./photo:/photo - /etc/localtime:/etc/localtime:ro environment: @@ -37,6 +37,20 @@ services: - streamer - redis restart: always + hls: + build: ./hls + working_dir: /app + command: ash -c "npm ci && npm start" + entrypoint: docker-entrypoint.sh + volumes: + - ./hls/src:/app + - /etc/localtime:/etc/localtime:ro + environment: + - RTMP_SERVER_URL=rtmp://streaming-server:1935/live + - STREAM_NAME=bushitsuchan + depends_on: + - streamer + restart: always reverse-proxy: image: nginx:alpine diff --git a/docs/vscode/launch.json b/docs/vscode/launch.json index 480726b..a063eae 100644 --- a/docs/vscode/launch.json +++ b/docs/vscode/launch.json @@ -1,77 +1,64 @@ { - "version": "0.2.0", - "configurations": [ - - { - "type": "node", - "request": "launch", - "name": "NodeJS", - "program": "${file}" - }, - { - "type": "node", - "request": "attach", - "name": "media: Attach", - "port": 4000, - "address": "localhost", - "localRoot": "${workspaceFolder}/media/src", - "remoteRoot": "/app", - "protocol": "inspector" - }, - { - "type": "node", - "request": "attach", - "name": "tunnel: Attach", - "port": 4001, - "address": "localhost", - "localRoot": "${workspaceFolder}/tunnel/src", - "remoteRoot": "/app", - "protocol": "inspector" - }, - { - "type": "node", - "request": "attach", - "name": "web: Attach", - "port": 4002, - "address": "localhost", - "localRoot": "${workspaceFolder}/web/src", - "remoteRoot": "/app", - "protocol": "inspector" - }, - { - "type": "node", - "request": "attach", - "name": "slack: Attach", - "port": 4003, - "address": "localhost", - "localRoot": "${workspaceFolder}/slack/src", - "remoteRoot": "/app", - "protocol": "inspector" - }, - { - "type": "node", - "request": "attach", - "name": "endpoint: Attach", - "port": 4004, - "address": "localhost", - "localRoot": "${workspaceFolder}/endpoint/src", - "remoteRoot": "/app", - "protocol": "inspector" - }, - { - "name": "object-detection: Attach", - "type": "python", - "request": "attach", - "port": 5678, - "host": "localhost", - "pathMappings": [ - { - "localRoot": "${workspaceFolder}/object-detection/src", - "remoteRoot": "/app" - } - ], - "justMyCode": false - } - ] - } - \ No newline at end of file + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "NodeJS", + "program": "${file}" + }, + { + "type": "node", + "request": "attach", + "name": "Attach to web container", + "port": 4002, + "address": "localhost", + "localRoot": "${workspaceFolder}/web/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "Attach to slack container", + "port": 4003, + "address": "localhost", + "localRoot": "${workspaceFolder}/slack/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "Attach to image-storage container", + "port": 4000, + "address": "localhost", + "localRoot": "${workspaceFolder}/image-storage/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "type": "node", + "request": "attach", + "name": "Attach to hls container", + "port": 4006, + "address": "localhost", + "localRoot": "${workspaceFolder}/hls/src", + "remoteRoot": "/app", + "protocol": "inspector" + }, + { + "name": "Attach to Object detection container", + "type": "python", + "request": "attach", + "port": 5678, + "host": "localhost", + "pathMappings": [ + { + "localRoot": "${workspaceFolder}/object-detection/src", + "remoteRoot": "/app" + } + ] + } + ] +} diff --git a/media/.dockerignore b/hls/.dockerignore similarity index 100% rename from media/.dockerignore rename to hls/.dockerignore diff --git a/media/Dockerfile b/hls/Dockerfile similarity index 100% rename from media/Dockerfile rename to hls/Dockerfile diff --git a/media/src/.eslintrc.yml b/hls/src/.eslintrc.yml similarity index 100% rename from media/src/.eslintrc.yml rename to hls/src/.eslintrc.yml diff --git a/hls/src/main.js b/hls/src/main.js new file mode 100644 index 0000000..3973ed2 --- /dev/null +++ b/hls/src/main.js @@ -0,0 +1,29 @@ +const express = require('express'); +const helmet = require('helmet'); +const ffmpeg = require('fluent-ffmpeg'); +const fs = require('fs'); +const morgan = require('morgan'); + + +const app = express(); +app.use(helmet()); +app.use(morgan('short')); +const hlsDir = '/dev/shm/hls'; + + +if (!fs.existsSync(hlsDir)) { + fs.mkdirSync(hlsDir); +} + +ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) + .inputOptions('-stream_loop -1') + .addOption('-hls_flags', '+delete_segments') + .addOption('-g', 40) + .on('error', (err) => { + console.error('ffmpeg command to convert to HLS failed or aborted:\n', err); + }) + .save(`${hlsDir}/output.m3u8`); + +app.use(express.static(hlsDir)); + +app.listen(80, () => console.log('Express app listening on port 80.')); diff --git a/hls/src/package-lock.json b/hls/src/package-lock.json new file mode 100644 index 0000000..63e6482 --- /dev/null +++ b/hls/src/package-lock.json @@ -0,0 +1,4273 @@ +{ + "name": "media", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz", + "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bowser": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.7.0.tgz", + "integrity": "sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w==" + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + } + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-security-policy-builder": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", + "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "dasherize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", + "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dns-prefetch-control": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", + "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dont-sniff-mimetype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", + "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "eslint-config-airbnb-base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.7", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "dev": true, + "requires": { + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect-ct": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", + "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "feature-policy": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", + "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "fluent-ffmpeg": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", + "integrity": "sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ=", + "requires": { + "async": ">=0.2.9", + "which": "^1.1.1" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "frameguard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", + "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "helmet": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", + "requires": { + "depd": "2.0.0", + "dns-prefetch-control": "0.2.0", + "dont-sniff-mimetype": "1.1.0", + "expect-ct": "0.2.0", + "feature-policy": "0.3.0", + "frameguard": "3.1.0", + "helmet-crossdomain": "0.4.0", + "helmet-csp": "2.9.2", + "hide-powered-by": "1.1.0", + "hpkp": "2.0.0", + "hsts": "2.2.0", + "ienoopen": "1.1.0", + "nocache": "2.1.0", + "referrer-policy": "1.2.0", + "x-xss-protection": "1.3.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "helmet-crossdomain": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz", + "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" + }, + "helmet-csp": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", + "requires": { + "bowser": "^2.6.1", + "camelize": "1.0.0", + "content-security-policy-builder": "2.1.0", + "dasherize": "2.0.0" + } + }, + "hide-powered-by": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", + "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" + }, + "hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true + }, + "hpkp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", + "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" + }, + "hsts": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", + "requires": { + "depd": "2.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ienoopen": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", + "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" + }, + "nodemon": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "pstree.remy": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", + "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "referrer-policy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", + "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "x-xss-protection": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", + "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==" + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/hls/src/package.json b/hls/src/package.json new file mode 100644 index 0000000..801d33b --- /dev/null +++ b/hls/src/package.json @@ -0,0 +1,25 @@ +{ + "name": "media", + "version": "1.0.0", + "description": "", + "main": "main.js", + "scripts": { + "start": "node main.js", + "dev": "nodemon --inspect=0.0.0.0 main.js", + "lint": "eslint --ext .js --fix ." + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "fluent-ffmpeg": "^2.1.2", + "helmet": "^3.21.1", + "morgan": "^1.9.1" + }, + "devDependencies": { + "eslint": "^6.5.1", + "eslint-config-airbnb-base": "^14.0.0", + "eslint-plugin-import": "^2.18.2", + "nodemon": "^1.19.4" + } +} diff --git a/image-storage/.dockerignore b/image-storage/.dockerignore new file mode 100644 index 0000000..2d71cf8 --- /dev/null +++ b/image-storage/.dockerignore @@ -0,0 +1,2 @@ +src/node_modules +src/.venv diff --git a/image-storage/Dockerfile b/image-storage/Dockerfile new file mode 100644 index 0000000..339283c --- /dev/null +++ b/image-storage/Dockerfile @@ -0,0 +1,4 @@ +FROM node:alpine AS node + +FROM jrottenberg/ffmpeg:alpine +COPY --from=node /usr/local /usr/local diff --git a/image-storage/src/.eslintrc.yml b/image-storage/src/.eslintrc.yml new file mode 100644 index 0000000..bb45477 --- /dev/null +++ b/image-storage/src/.eslintrc.yml @@ -0,0 +1,12 @@ +env: + es6: true + node: true +extends: + - airbnb-base +globals: + Atomics: readonly + SharedArrayBuffer: readonly +parserOptions: + ecmaVersion: 2018 + sourceType: module +rules: {} diff --git a/media/src/main.js b/image-storage/src/main.js similarity index 81% rename from media/src/main.js rename to image-storage/src/main.js index eb009ef..3236560 100644 --- a/media/src/main.js +++ b/image-storage/src/main.js @@ -9,27 +9,12 @@ const morgan = require('morgan'); const app = express(); app.use(helmet()); app.use(morgan('short')); -const hlsDir = '/dev/shm/hls'; const redis = new Redis({ host: 'redis', keyPrefix: 'media:', }); - -if (!fs.existsSync(hlsDir)) { - fs.mkdirSync(hlsDir); -} - -ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) - .inputOptions('-stream_loop -1') - .addOption('-hls_flags', '+delete_segments') - .addOption('-g', 40) - .on('error', (err) => { - console.error('ffmpeg command to convert to HLS failed or aborted:\n', err); - }) - .save(`${hlsDir}/output.m3u8`); - app.get('/temporary', async (req, res) => { const ffstream = ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) .addOption('-vframes', 1) @@ -85,6 +70,5 @@ app.get('/photo/:time', async (req, res) => { res.sendStatus(404); } }); -app.use('/hls', express.static(hlsDir)); app.listen(80, () => console.log('Express app listening on port 80.')); diff --git a/media/src/package-lock.json b/image-storage/src/package-lock.json similarity index 100% rename from media/src/package-lock.json rename to image-storage/src/package-lock.json diff --git a/media/src/package.json b/image-storage/src/package.json similarity index 100% rename from media/src/package.json rename to image-storage/src/package.json diff --git a/utils/docker-compose.install.yml b/utils/docker-compose.install.yml index b0f7bbe..0cb9bdb 100644 --- a/utils/docker-compose.install.yml +++ b/utils/docker-compose.install.yml @@ -7,13 +7,21 @@ services: volumes: - ../streaming-server/src:/app - media: - build: ../media + image-storage: + build: ../image-storage working_dir: /app command: ash -c "npm ci" entrypoint: docker-entrypoint.sh volumes: - - ../media/src:/app + - ../image-storage/src:/app + + hls: + build: ../hls + working_dir: /app + command: ash -c "npm ci" + entrypoint: docker-entrypoint.sh + volumes: + - ../hls/src:/app tunnel: build: ../tunnel diff --git a/utils/docker-compose.update.yml b/utils/docker-compose.update.yml index 41a51c8..eaedbd7 100644 --- a/utils/docker-compose.update.yml +++ b/utils/docker-compose.update.yml @@ -7,13 +7,21 @@ services: volumes: - ../streaming-server/src:/app - media: - build: ../media + image-storage: + build: ../image-storage working_dir: /app command: ash -c "npm install && npm audit fix" entrypoint: docker-entrypoint.sh volumes: - - ../media/src:/app + - ../image-storage/src:/app + + hls: + build: ../hls + working_dir: /app + command: ash -c "npm install && npm audit fix" + entrypoint: docker-entrypoint.sh + volumes: + - ../hls/src:/app tunnel: build: ../tunnel diff --git a/web/src/main.js b/web/src/main.js index a31f6bb..c697f1d 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -76,7 +76,7 @@ app.use( app.use( morgan('<@:user> [:date[clf]] :method :url :status :res[content-length] - :response-time ms', { - skip: (req, res) => req.path.startsWith('/data/'), + skip: (req, res) => ['/photo/', '/hls/'].some((element) => req.path.startsWith(element)), }), ); morgan.token('user', (req, res) => (req.session && req.session.name) || 'anonymous'); @@ -136,14 +136,14 @@ app.get('/logout', (req, res) => { res.send('You have successfully logged out'); }); -app.use(['/viewer', '/photo-viewer', '/data'], (req, res, next) => { +app.use(['/viewer', '/photo-viewer', '/photo', '/hls'], (req, res, next) => { if (req.session.lastAuthedTime < Date.now() - 1000 * 60 * 60 * 24) { req.session.isAuth = false; } next(); }); -app.use(['/viewer', '/photo-viewer', '/data'], (req, res, next) => { +app.use(['/viewer', '/photo-viewer', '/photo', '/hls'], (req, res, next) => { const { token } = req.session; if (token === undefined) { res.redirect(`/prod/login?redirect_path=${req.path.slice(1)}`); @@ -174,9 +174,10 @@ app.get('/viewer', (req, res) => { }); app.get('/photo-viewer', async (req, res) => { - res.render('photo-viewer.ejs', { photoPath: `data/temporary?time=${Date.now()}` }); + res.render('photo-viewer.ejs', { photoPath: `photo/temporary?time=${Date.now()}` }); }); -app.use('/data', proxy(url.parse('http://media/'))); +app.use('/photo', proxy(url.parse('http://media/'))); +app.use('/hls', proxy(url.parse('http://hls/'))); app.listen(80, () => console.log('Express app listening on port 80.')); diff --git a/web/src/views/viewer.html b/web/src/views/viewer.html index 029ba47..c7880c4 100644 --- a/web/src/views/viewer.html +++ b/web/src/views/viewer.html @@ -20,13 +20,13 @@ var video = document.getElementById("video"); if (Hls.isSupported()) { var hls = new Hls(); - hls.loadSource("data/hls/output.m3u8"); + hls.loadSource("hls/output.m3u8"); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, () => { video.play(); }); } else if (video.canPlayType("application/vnd.apple.mpegurl")) { - video.src = "data/hls/output.m3u8"; + video.src = "hls/output.m3u8"; video.addEventListener("loadedmetadata", () => { video.play(); }); From ed47caa4213c0ea53688a2500e84fd1c6d4a217a Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 23 Oct 2019 00:05:11 +0900 Subject: [PATCH 38/60] Don't use cache for images --- web/src/main.js | 7 +------ web/src/package-lock.json | 5 ----- web/src/package.json | 1 - web/src/views/{photo-viewer.ejs => photo-viewer.html} | 5 ++++- 4 files changed, 5 insertions(+), 13 deletions(-) rename web/src/views/{photo-viewer.ejs => photo-viewer.html} (71%) diff --git a/web/src/main.js b/web/src/main.js index c697f1d..9f5ef3d 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -59,7 +59,6 @@ const app = express(); app.set('trust proxy', 1); app.use(helmet()); app.use(cors()); -app.set('view engine', 'ejs'); app.use( session({ @@ -169,14 +168,10 @@ app.use(['/viewer', '/photo-viewer', '/photo', '/hls'], (req, res, next) => { }); }); -app.get('/viewer', (req, res) => { +app.get(['/viewer', '/photo-viewer'], (req, res) => { res.sendFile(`./views/${req.path.slice(1)}.html`, { root: __dirname }); }); -app.get('/photo-viewer', async (req, res) => { - res.render('photo-viewer.ejs', { photoPath: `photo/temporary?time=${Date.now()}` }); -}); - app.use('/photo', proxy(url.parse('http://media/'))); app.use('/hls', proxy(url.parse('http://hls/'))); diff --git a/web/src/package-lock.json b/web/src/package-lock.json index faf7f6c..447e09d 100644 --- a/web/src/package-lock.json +++ b/web/src/package-lock.json @@ -804,11 +804,6 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, - "ejs": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz", - "integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==" - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", diff --git a/web/src/package.json b/web/src/package.json index 2499b32..74e7549 100644 --- a/web/src/package.json +++ b/web/src/package.json @@ -14,7 +14,6 @@ "axios": "^0.19.0", "connect-redis": "^4.0.3", "cors": "^2.8.5", - "ejs": "^2.7.1", "express": "^4.17.1", "express-session": "^1.17.0", "helmet": "^3.21.1", diff --git a/web/src/views/photo-viewer.ejs b/web/src/views/photo-viewer.html similarity index 71% rename from web/src/views/photo-viewer.ejs rename to web/src/views/photo-viewer.html index 915cf03..fe1641c 100644 --- a/web/src/views/photo-viewer.ejs +++ b/web/src/views/photo-viewer.html @@ -12,6 +12,9 @@ 動画版 - + + From 1e4573c95ace11ba940ec0a7e94a402303900047 Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 23 Oct 2019 01:46:35 +0900 Subject: [PATCH 39/60] Update /permament in image-storage --- image-storage/src/main.js | 48 +++++++++++++++++++++++---------------- slack/src/main.js | 19 +++++++--------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/image-storage/src/main.js b/image-storage/src/main.js index 3236560..413fa13 100644 --- a/image-storage/src/main.js +++ b/image-storage/src/main.js @@ -36,39 +36,47 @@ app.get('/temporary', async (req, res) => { reject(e); }); }); - res.contentType('image/jpg'); - res.status(200).send(image); + res.type('image/jpg').send(image).end(); }); -app.post('/photo', (req, res) => { - const time = Date.now(); - redis.set(`${time}-pending`, true, 'EX', 5); +app.get('/permament', async (req, res) => { + const { directory } = req.query; + if (directory === undefined) { + res.sendStatus(400); + return; + } + + const filename = `${Date.now()}.jpg`; + const path = `${directory}/${filename}`; + await redis.set(`${path}-pending`, true, 'EX', 5); + + if (!fs.existsSync(`/photo/${directory}`)) { + fs.mkdirSync(`/photo/${directory}`); + } + ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) - .addOption('-ss', 0.7) .addOption('-vframes', 1) .on('end', () => { - redis.del(`${time}-pending`); + redis.del(`${path}-pending`); }) .on('error', (err) => { - redis.del(`${time}-pending`); + redis.del(`${path}-pending`); console.error('ffmpeg command to convert to image failed:\n', err); }) - .save(`/photo/${time}.jpg`); - res.json({ path: `/photo/${time}`, photoId: time }); + .save(`/photo/${path}`); + res.json({ filename }); }); -app.get('/photo/:time', async (req, res) => { - const { time } = req.params; - const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms)); - while (await redis.get(`${time}-pending`)) { - await wait(100); - } +const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms)); - if (fs.existsSync(`/photo/${time}.jpg`)) { // 非推奨 - res.sendFile(`/photo/${time}.jpg`); - } else { - res.sendStatus(404); +app.get('/permament/:directory(\\w+)/:file', async (req, res) => { + const { directory, file } = req.params; + const path = `${directory}/${file}`; + + while (await redis.get(`${path}-pending`)) { + await wait(100); } + res.sendFile(`/photo/${path}`); }); app.listen(80, () => console.log('Express app listening on port 80.')); diff --git a/slack/src/main.js b/slack/src/main.js index 179d115..0ea43fe 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -65,18 +65,18 @@ slackInteractions.action({ type: 'button' }, (payload, respond) => { // Slash command app.post('/bushitsu-photo', async (req, res) => { - const { photoId } = await axios.post('http://media/photo').then((result) => result.data); + const { filename } = await axios.get('http://image-storage/permament', { params: { directory: 'slack' } }).then((result) => result.data); res.status(200).end(); const key = crypto .createHash('md5') - .update(`${photoId}-${process.env.SESSION_SECRET}`, 'utf8') + .update(`${filename}-${process.env.SESSION_SECRET}`, 'utf8') .digest('Base64'); const { awsUrl } = await axios.get('http://tunnel').then((result) => result.data); const blocks = object( JSON.parse(fs.readFileSync('./block_template.json', 'utf8')), { - image_url: `${awsUrl}/${req.hostname}/photo/${photoId}?key=${base64url.escape(key)}`, + image_url: `${awsUrl}/${req.hostname}/photo/${filename}?key=${base64url.escape(key)}`, viewer_url: `${awsUrl}/viewer`, photo_viewer_url: `${awsUrl}/photo-viewer`, contact_channel: process.env.CONTACT_CHANNEL, @@ -93,31 +93,28 @@ app.post('/bushitsu-photo', async (req, res) => { // Others -app.get(['/photo/:photoId', '/detected-photo/:photoId'], async (req, res) => { +app.get('/photo/:filename', async (req, res) => { const { key } = req.query; - const { photoId } = req.params; + const { filename } = req.params; if (!key) { return; } const correctKey = crypto .createHash('md5') - .update(`${photoId}-${process.env.SESSION_SECRET}`, 'utf8') + .update(`${filename}-${process.env.SESSION_SECRET}`, 'utf8') .digest('Base64'); - if (correctKey !== base64url.unescape(key)) { return; } - const server = req.path.startsWith('/photo') ? 'media' : 'object-detection'; - const img = await axios.get(`http://${server}/photo/${photoId}`, { + const img = await axios.get(`http://image-storage/permament/slack/${filename}`, { responseType: 'arraybuffer', headers: { 'Content-Type': 'image/jpg', }, }); - res.contentType('image/jpg'); - res.send(img.data); + res.type('image/jpg').send(img.data).end(); }); app.listen(80, () => console.log('Express app listening on port 80.')); From 20dee14ddae76f7f117fe4d42b6c7e05caf3530f Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 23 Oct 2019 01:47:27 +0900 Subject: [PATCH 40/60] Fix hostname and path in web --- web/src/main.js | 2 +- web/src/views/photo-viewer.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/main.js b/web/src/main.js index 9f5ef3d..3c5b19b 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -172,7 +172,7 @@ app.get(['/viewer', '/photo-viewer'], (req, res) => { res.sendFile(`./views/${req.path.slice(1)}.html`, { root: __dirname }); }); -app.use('/photo', proxy(url.parse('http://media/'))); +app.use('/photo', proxy(url.parse('http://image-storage/temporary'))); app.use('/hls', proxy(url.parse('http://hls/'))); app.listen(80, () => console.log('Express app listening on port 80.')); diff --git a/web/src/views/photo-viewer.html b/web/src/views/photo-viewer.html index fe1641c..2ef2209 100644 --- a/web/src/views/photo-viewer.html +++ b/web/src/views/photo-viewer.html @@ -14,7 +14,7 @@ From f0efdb39a19238d21f3f032c51d528a3a7d0497f Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 23 Oct 2019 01:48:52 +0900 Subject: [PATCH 41/60] Add error status --- slack/src/main.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/slack/src/main.js b/slack/src/main.js index 0ea43fe..2a65bdc 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -98,6 +98,7 @@ app.get('/photo/:filename', async (req, res) => { const { filename } = req.params; if (!key) { + res.sendStatus(401); return; } const correctKey = crypto @@ -105,6 +106,7 @@ app.get('/photo/:filename', async (req, res) => { .update(`${filename}-${process.env.SESSION_SECRET}`, 'utf8') .digest('Base64'); if (correctKey !== base64url.unescape(key)) { + res.sendStatus(403); return; } From 83ac79dee5a147519d864a72b8616c8e78302d90 Mon Sep 17 00:00:00 2001 From: ilim Date: Thu, 31 Oct 2019 00:39:29 +0900 Subject: [PATCH 42/60] Add temporary image upload API --- image-storage/src/main.js | 37 +++++++- image-storage/src/package-lock.json | 138 +++++++++++++++++++++++++--- image-storage/src/package.json | 3 +- 3 files changed, 162 insertions(+), 16 deletions(-) diff --git a/image-storage/src/main.js b/image-storage/src/main.js index 413fa13..bac660c 100644 --- a/image-storage/src/main.js +++ b/image-storage/src/main.js @@ -4,6 +4,7 @@ const ffmpeg = require('fluent-ffmpeg'); const Redis = require('ioredis'); const fs = require('fs'); const morgan = require('morgan'); +const multer = require('multer'); const app = express(); @@ -15,6 +16,12 @@ const redis = new Redis({ keyPrefix: 'media:', }); +const upload = multer(); +const imageBuffers = {}; + +const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms)); + + app.get('/temporary', async (req, res) => { const ffstream = ffmpeg(`${process.env.RTMP_SERVER_URL}/${process.env.STREAM_NAME}`) .addOption('-vframes', 1) @@ -39,6 +46,34 @@ app.get('/temporary', async (req, res) => { res.type('image/jpg').send(image).end(); }); + +app.post('/temporary', upload.single('file'), (req, res) => { + const retentionTime = Number(req.body.retention_time); + const { buffer, mimetype } = req.file; + if (retentionTime === undefined || buffer === undefined || !(retentionTime > 0)) { + res.sendStatus(400); + return; + } + const id = Date.now(); + imageBuffers[id] = { + mimetype, + buffer, + }; + wait(retentionTime).then(() => { delete imageBuffers[id]; }); + res.status(201).json({ id }); + }); + + + app.get('/temporary/:id', (req, res) => { + const { id } = req.params; + if (!(id in imageBuffers)) { + res.sendStatus(404); + return; + } + const { mimetype, buffer } = imageBuffers[id]; + res.contentType(mimetype).end(buffer); + }); + app.get('/permament', async (req, res) => { const { directory } = req.query; if (directory === undefined) { @@ -67,8 +102,6 @@ app.get('/permament', async (req, res) => { res.json({ filename }); }); -const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms)); - app.get('/permament/:directory(\\w+)/:file', async (req, res) => { const { directory, file } = req.params; const path = `${directory}/${file}`; diff --git a/image-storage/src/package-lock.json b/image-storage/src/package-lock.json index ff5f156..cfb7e61 100644 --- a/image-storage/src/package-lock.json +++ b/image-storage/src/package-lock.json @@ -114,6 +114,11 @@ } } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -342,6 +347,43 @@ } } }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -539,6 +581,17 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", @@ -602,8 +655,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-error-class": { "version": "3.0.2", @@ -737,6 +789,38 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "dns-prefetch-control": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", @@ -2528,8 +2612,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -2753,8 +2836,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mixin-deep": { "version": "1.3.2", @@ -2781,7 +2863,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" } @@ -2803,6 +2884,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", @@ -2942,6 +3038,11 @@ "path-key": "^2.0.0" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -3255,8 +3356,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -3363,7 +3463,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3875,6 +3974,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -3920,7 +4024,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -4110,6 +4213,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -4248,8 +4356,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { "version": "1.0.1", @@ -4337,6 +4444,11 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/image-storage/src/package.json b/image-storage/src/package.json index 7b26e00..d741e87 100644 --- a/image-storage/src/package.json +++ b/image-storage/src/package.json @@ -15,7 +15,8 @@ "fluent-ffmpeg": "^2.1.2", "helmet": "^3.21.1", "ioredis": "^4.14.1", - "morgan": "^1.9.1" + "morgan": "^1.9.1", + "multer": "^1.4.2" }, "devDependencies": { "eslint": "^6.5.1", From 21ae6057cdf57cf45b6c9f8aca77cb93cfbe0010 Mon Sep 17 00:00:00 2001 From: ilim Date: Thu, 31 Oct 2019 12:01:34 +0900 Subject: [PATCH 43/60] Support object-detection for new image-storage --- object-detection/Dockerfile | 2 +- object-detection/src/Pipfile | 16 +- object-detection/src/Pipfile.lock | 325 ++++++++++++++---------------- object-detection/src/app.py | 63 ------ object-detection/src/main.py | 68 +++++++ 5 files changed, 233 insertions(+), 241 deletions(-) delete mode 100644 object-detection/src/app.py create mode 100644 object-detection/src/main.py diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index b6254b1..d563e4b 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -34,7 +34,7 @@ RUN cd /tmp/ && \ make -j${NUM_THREADS} && make install && \ rm -rf /tmp/* -RUN echo '/opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc +RUN echo 'source /opt/intel/openvino/bin/setupvars.sh' >> ~/.bashrc RUN apt-get install -yq --no-install-recommends python3.7 libpython3.7-dev python3-pip && \ pip3 install pipenv diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 1b2ec46..c1410e1 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -12,14 +12,18 @@ watchdog = "~=0.9.0" ptvsd = "~=4.3.2" [packages] -requests = "~=2.22.0" +# Required by /opt/intel/openvino/deployment_tools/tools/model_downloader pyyaml = "~=5.1.2" +requests = "~=2.22.0" + +# Required by /opt/intel/openvino/deployment_tools/model_optimizer +tensorflow = ">=1.2.0,<2.0.0,!=1.15.0" networkx = ">=1.11" -tensorflow = ">=1.2.0,<2.0.0" -defusedxml = ">=0.5.0" +numpy = ">=1.12.0" test-generator = "==0.1.1" +defusedxml = ">=0.5.0" + opencv-python = "~=4.1.1.26" -flask = "~=1.1.1" pillow = "~=6.2.0" matplotlib = "~=3.1.1" @@ -27,7 +31,7 @@ matplotlib = "~=3.1.1" python_version = "3.7" [scripts] -start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && flask run --host=0.0.0.0 --port 80'" -dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -m ptvsd --host 0.0.0.0 -m flask run --host=0.0.0.0 --port 80 --no-reload --no-debugger'" +start = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -u main.py'" +dev = "bash -c 'source /opt/intel/openvino/bin/setupvars.sh && python -u -m ptvsd --host 0.0.0.0 --port 5678 main.py'" lint = "bash -c 'mypy . --ignore-missing-imports && flake8 --show-source --exclude .venv --max-line-length 120 .'" format = "bash -c 'isort -rc . && autopep8 --max-line-length 120 -ivr .'" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index a263f09..1892747 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "4e7392b94a2f0f97673ae5f5b1ac6d1ac79e56c805ab402962c8916047625e43" + "sha256": "85db9ee8b2f53f9bdd74fac802fd7b5619cc0f05f3c8e5c07bfffbfcf5c25b5d" }, "pipfile-spec": 6, "requires": { @@ -18,9 +18,9 @@ "default": { "absl-py": { "hashes": [ - "sha256:0ce45920056fbbb66f52fcee7408ba6311da19f55589b2b3aab9f8af92a0e1f2" + "sha256:d9129186431e150d7fe455f1cb1ecbb92bb5dba9da9bc3ef7b012d98c4db2526" ], - "version": "==0.8.0" + "version": "==0.8.1" }, "astor": { "hashes": [ @@ -43,13 +43,6 @@ ], "version": "==3.0.4" }, - "click": { - "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" - ], - "version": "==7.0" - }, "cycler": { "hashes": [ "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", @@ -59,10 +52,10 @@ }, "decorator": { "hashes": [ - "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", - "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" + "sha256:54c38050039232e1db4ad7375cfce6748d7b41c29e95a081c8a6d2c30364a2ce", + "sha256:5d19b92a3c8f7f101c8dd86afd86b0f061a8ce4540ab8cd401fa2542756bce6d" ], - "version": "==4.4.0" + "version": "==4.4.1" }, "defusedxml": { "hashes": [ @@ -72,14 +65,6 @@ "index": "pypi", "version": "==0.6.0" }, - "flask": { - "hashes": [ - "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", - "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" - ], - "index": "pypi", - "version": "==1.1.1" - }, "gast": { "hashes": [ "sha256:5c7617f1f6c8b8b426819642b16b9016727ddaecd16af9a07753e537eba8a3a5" @@ -96,40 +81,56 @@ }, "grpcio": { "hashes": [ - "sha256:0302331e014fc4bac028b6ad480b33f7abfe20b9bdcca7be417124dda8f22115", - "sha256:0aa0cce9c5eb1261b32173a20ed42b51308d55ce28ecc2021e868b3cb90d9503", - "sha256:0c83947575300499adbc308e986d754e7f629be0bdd9bea1ffdd5cf76e1f1eff", - "sha256:0ca26ff968d45efd4ef73447c4d4b34322ea8c7d06fbb6907ce9e5db78f1bbcb", - "sha256:0cf80a7955760c2498f8821880242bb657d70998065ff0d2a082de5ffce230a7", - "sha256:0d40706e57d9833fe0e023a08b468f33940e8909affa12547874216d36bba208", - "sha256:11872069156de34c6f3f9a1deb46cc88bc35dfde88262c4c73eb22b39b16fc55", - "sha256:16065227faae0ab0abf1789bfb92a2cd2ab5da87630663f93f8178026da40e0d", - "sha256:1e33778277685f6fabb22539136269c87c029e39b6321ef1a639b756a1c0a408", - "sha256:2b16be15b1ae656bc7a36642b8c7045be2dde2048bb4b67478003e9d9db8022a", - "sha256:3701dfca3ada27ceef0d17f728ce9dfef155ed20c57979c2b05083082258c6c1", - "sha256:41912ecaf482abf2de74c69f509878f99223f5dd6b2de1a09c955afd4de3cf9b", - "sha256:4332cbd20544fe7406910137590f38b5b3a1f6170258e038652cf478c639430f", - "sha256:44068ecbdc6467c2bff4d8198816c8a2701b6dd1ec16078fceb6adc7c1f577d6", - "sha256:53115960e37059420e2d16a4b04b00dd2ab3b6c3c67babd01ffbfdcd7881a69b", - "sha256:6e7027bcd4070414751e2a5e60706facb98a1fc636497c9bac5442fe37b8ae6b", - "sha256:6ff57fb2f07b7226b5bec89e8e921ea9bd220f35f11e094f2ba38f09eecd49c6", - "sha256:73240e244d7644654bbda1f309f4911748b6a1804b7a8897ddbe8a04c90f7407", - "sha256:785234bbc469bc75e26c868789a2080ffb30bd6e93930167797729889ad06b0b", - "sha256:82f9d3c7f91d2d1885631335c003c5d45ae1cd69cc0bc4893f21fef50b8151bc", - "sha256:86bdc2a965510658407a1372eb61f0c92f763fdfb2795e4d038944da4320c950", - "sha256:95e925b56676a55e6282b3de80a1cbad5774072159779c61eac02791dface049", - "sha256:96673bb4f14bd3263613526d1e7e33fdb38a9130e3ce87bf52314965706e1900", - "sha256:970014205e76920484679035b6fb4b16e02fc977e5aac4d22025da849c79dab9", - "sha256:ace5e8bf11a1571f855f5dab38a9bd34109b6c9bc2864abf24a597598c7e3695", - "sha256:ad375f03eb3b9cb75a24d91eab8609e134d34605f199efc41e20dd642bdac855", - "sha256:b819c4c7dcf0de76788ce5f95daad6d4e753d6da2b6a5f84e5bb5b5ce95fddc4", - "sha256:c17943fd340cbd906db49f3f03c7545e5a66b617e8348b2c7a0d2c759d216af1", - "sha256:d21247150dea86dabd3b628d8bc4b563036db3d332b3f4db3c5b1b0b122cb4f6", - "sha256:d4d500a7221116de9767229ff5dd10db91f789448d85befb0adf5a37b0cd83b5", - "sha256:e2a942a3cfccbbca21a90c144867112698ef36486345c285da9e98c466f22b22", - "sha256:e983273dca91cb8a5043bc88322eb48e2b8d4e4998ff441a1ee79ced89db3909" - ], - "version": "==1.24.1" + "sha256:01cb705eafba1108e2a947ba0457da4f6a1e8142c729fc61702b5fdd11009eb1", + "sha256:0b5a79e29f167d3cd06faad6b15babbc2661066daaacf79373c3a8e67ca1fca1", + "sha256:1097a61a0e97b3580642e6e1460a3a1f1ba1815e2a70d6057173bcc495417076", + "sha256:13970e665a4ec4cec7d067d7d3504a0398c657d91d26c581144ad9044e429c9a", + "sha256:1557817cea6e0b87fad2a3e20da385170efb03a313db164e8078955add2dfa1b", + "sha256:1b0fb036a2f9dd93d9a35c57c26420eeb4b571fcb14b51cddf5b1e73ea5d882b", + "sha256:24d9e58d08e8cd545d8a3247a18654aff0e5e60414701696a8098fbb0d792b75", + "sha256:2c38b586163d2b91567fe5e6d9e7798f792012365adc838a64b66b22dce3f4d4", + "sha256:2df3ab4348507de60e1cbf75196403df1b9b4c4d4dc5bd11ac4eb63c46f691c7", + "sha256:32f70f7c90454ea568b868af2e96616743718d9233d23f62407e98caed81dfbf", + "sha256:3af2a49d576820045c9c880ff29a5a96d020fe31b35d248519bfc6ccb8be4eac", + "sha256:4ff7d63800a63db031ebac6a6f581ae84877c959401c24c28f2cc51fd36c47ad", + "sha256:502aaa8be56f0ae69cda66bc27e1fb5531ceaa27ca515ec3c34f6178b1297180", + "sha256:55358ce3ec283222e435f7dbc6603521438458f3c65f7c1cb33b8dabf56d70d8", + "sha256:5583b01c67f85fa64a2c3fb085e5517c88b9c1500a2cce12d473cd99d0ed2e49", + "sha256:58d9a5557d3eb7b734a3cea8b16c891099a522b3953a45a30bd4c034f75fc913", + "sha256:5911f042c4ab177757eec5bcb4e2e9a2e823d888835d24577321bf55f02938fa", + "sha256:5e16ea922f4e5017c04fd94e2639b1006e03097e9dd0cbb7a1c852af3ea8bf2e", + "sha256:656e19d3f1b9050ee01b457f92838a9679d7cf84c995f708780f44484048705e", + "sha256:6a1435449a82008c451c7e1a82a834387b9108f9a8d27910f86e7c482f5568e9", + "sha256:6ff02ca6cbed0ddb76e93ba0f8beb6a8c77d83a84eb7cafe2ae3399a8b9d69ea", + "sha256:76de68f60102f333bf4817f38e81ecbee68b850f5a5da9f355235e948ac40981", + "sha256:7c6d7ddd50fc6548ea1dfe09c62509c4f95b8b40082287747be05aa8feb15ee2", + "sha256:836b9d29507de729129e363276fe7c7d6a34c7961e0f155787025552b15d22c0", + "sha256:869242b2baf8a888a4fe0548f86abc47cb4b48bdfd76ae62d6456e939c202e65", + "sha256:8954b24bd08641d906ee50b2d638efc76df893fbd0913149b80484fd0eac40c9", + "sha256:8cdea65d1abb2e698420db8daf20c8d272fbd9d96a51b26a713c1c76f237d181", + "sha256:90161840b4fe9636f91ed0d3ea1e7e615e488cbea4e77594c889e5f3d7a776db", + "sha256:90fb6316b4d7d36700c40db4335902b78dcae13b5466673c21fd3b08a3c1b0c6", + "sha256:91b34f58db2611c9a93ecf751028f97fba1f06e65f49b38f272f6aa5d2977331", + "sha256:9474944a96a33eb8734fa8dc5805403d57973a3526204a5e1c1780d02e0572b6", + "sha256:9a36275db2a4774ac16c6822e7af816ee048071d5030b4c035fd53942b361935", + "sha256:9cbe26e2976b994c5f7c2d35a63354674d6ca0ce62f5b513f078bf63c1745229", + "sha256:9eaeabb3c0eecd6ddd0c16767fd12d130e2cebb8c2618f959a278b1ff336ddc3", + "sha256:a2bc7e10ebcf4be503ae427f9887e75c0cc24e88ce467a8e6eaca6bd2862406e", + "sha256:a5b42e6292ba51b8e67e09fc256963ba4ca9c04026de004d2fe59cc17e3c3776", + "sha256:bd6ec1233c86c0b9bb5d03ec30dbe3ffbfa53335790320d99a7ae9018c5450f2", + "sha256:bef57530816af54d66b1f4c70a8f851f320cb6f84d4b5a0b422b0e9811ea4e59", + "sha256:c146a63eaadc6589b732780061f3c94cd0574388d372baccbb3c1597a9ebdb7a", + "sha256:c2efd3b130dc639d615b6f58980e1bfd1b177ad821f30827afa5001aa30ddd48", + "sha256:c888b18f7392e6cc79a33a803e7ebd7890ac3318f571fca6b356526f35b53b12", + "sha256:ca30721fda297ae22f16bc37aa7ed244970ddfdcb98247570cdd26daaad4665e", + "sha256:cf5f5340dd682ab034baa52f423a0f91326489c262ac9617fa06309ec05880e9", + "sha256:d0726aa0d9b57c56985db5952e90fb1033a317074f2877db5307cdd6eede1564", + "sha256:df442945b2dd6f8ae0e20b403e0fd4548cd5c2aad69200047cc3251257b78f65", + "sha256:e08e758c31919d167c0867539bd3b2441629ef00aa595e3ea2b635273659f40a", + "sha256:e4864339deeeaefaad34dd3a432ee618a039fca28efb292949c855e00878203c", + "sha256:f4cd049cb94d9f517b1cab5668a3b345968beba093bc79a637e671000b3540ec" + ], + "version": "==1.24.3" }, "h5py": { "hashes": [ @@ -170,20 +171,6 @@ ], "version": "==2.8" }, - "itsdangerous": { - "hashes": [ - "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", - "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" - ], - "version": "==1.1.0" - }, - "jinja2": { - "hashes": [ - "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", - "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" - ], - "version": "==2.10.3" - }, "keras-applications": { "hashes": [ "sha256:5579f9a12bcde9748f4a12233925a59b93b73ae6947409ff34aa2ba258189fe5", @@ -201,7 +188,9 @@ "kiwisolver": { "hashes": [ "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", + "sha256:210d8c39d01758d76c2b9a693567e1657ec661229bc32eac30761fa79b2474b0", "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", + "sha256:3b15d56a9cd40c52d7ab763ff0bc700edbb4e1a298dc43715ecccd605002cf11", "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", @@ -210,16 +199,22 @@ "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", + "sha256:76275ee077772c8dde04fb6c5bc24b91af1bb3e7f4816fd1852f1495a64dad93", "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", + "sha256:9105ce82dcc32c73eb53a04c869b6a4bc756b43e4385f76ea7943e827f529e4d", + "sha256:933df612c453928f1c6faa9236161a1d999a26cd40abf1dc5d7ebbc6dbfb8fca", "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", + "sha256:9491578147849b93e70d7c1d23cb1229458f71fc79c51d52dce0809b2ca44eea", "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", + "sha256:aa716b9122307c50686356cfb47bfbc66541868078d0c801341df31dca1232a9", "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", + "sha256:d22702cadb86b6fcba0e6b907d9f84a312db9cd6934ee728144ce3018e715ee1", "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", @@ -227,7 +222,8 @@ "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", - "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" + "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f", + "sha256:fe51b79da0062f8e9d49ed0182a626a7dc7a0cbca0328f612c6ee5e4711c81e4" ], "version": "==1.1.0" }, @@ -238,39 +234,6 @@ ], "version": "==3.1.1" }, - "markupsafe": { - "hashes": [ - "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", - "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", - "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", - "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", - "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", - "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", - "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", - "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", - "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", - "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", - "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", - "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", - "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", - "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", - "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", - "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", - "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", - "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", - "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", - "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", - "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", - "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", - "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", - "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", - "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", - "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", - "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" - ], - "version": "==1.1.1" - }, "matplotlib": { "hashes": [ "sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93", @@ -288,31 +251,38 @@ }, "networkx": { "hashes": [ - "sha256:8311ddef63cf5c5c5e7c1d0212dd141d9a1fe3f474915281b73597ed5f1d4e3d" + "sha256:cdfbf698749a5014bf2ed9db4a07a5295df1d3a53bf80bf3cbd61edf9df05fa1", + "sha256:f8f4ff0b6f96e4f9b16af6b84622597b5334bf9cae8cf9b2e42e7985d5c95c64" ], "index": "pypi", - "version": "==2.3" + "version": "==2.4" }, "numpy": { "hashes": [ - "sha256:05dbfe72684cc14b92568de1bc1f41e5f62b00f714afc9adee42f6311738091f", - "sha256:0d82cb7271a577529d07bbb05cb58675f2deb09772175fab96dc8de025d8ac05", - "sha256:10132aa1fef99adc85a905d82e8497a580f83739837d7cbd234649f2e9b9dc58", - "sha256:12322df2e21f033a60c80319c25011194cd2a21294cc66fee0908aeae2c27832", - "sha256:16f19b3aa775dddc9814e02a46b8e6ae6a54ed8cf143962b4e53f0471dbd7b16", - "sha256:3d0b0989dd2d066db006158de7220802899a1e5c8cf622abe2d0bd158fd01c2c", - "sha256:438a3f0e7b681642898fd7993d38e2bf140a2d1eafaf3e89bb626db7f50db355", - "sha256:5fd214f482ab53f2cea57414c5fb3e58895b17df6e6f5bca5be6a0bb6aea23bb", - "sha256:73615d3edc84dd7c4aeb212fa3748fb83217e00d201875a47327f55363cef2df", - "sha256:7bd355ad7496f4ce1d235e9814ec81ee3d28308d591c067ce92e49f745ba2c2f", - "sha256:7d077f2976b8f3de08a0dcf5d72083f4af5411e8fddacd662aae27baa2601196", - "sha256:a4092682778dc48093e8bda8d26ee8360153e2047826f95a3f5eae09f0ae3abf", - "sha256:b458de8624c9f6034af492372eb2fee41a8e605f03f4732f43fc099e227858b2", - "sha256:e70fc8ff03a961f13363c2c95ef8285e0cf6a720f8271836f852cc0fa64e97c8", - "sha256:ee8e9d7cad5fe6dde50ede0d2e978d81eafeaa6233fb0b8719f60214cf226578", - "sha256:f4a4f6aba148858a5a5d546a99280f71f5ee6ec8182a7d195af1a914195b21a2" - ], - "version": "==1.17.2" + "sha256:0b0dd8f47fb177d00fa6ef2d58783c4f41ad3126b139c91dd2f7c4b3fdf5e9a5", + "sha256:25ffe71f96878e1da7e014467e19e7db90ae7d4e12affbc73101bcf61785214e", + "sha256:26efd7f7d755e6ca966a5c0ac5a930a87dbbaab1c51716ac26a38f42ecc9bc4b", + "sha256:28b1180c758abf34a5c3fea76fcee66a87def1656724c42bb14a6f9717a5bdf7", + "sha256:2e418f0a59473dac424f888dd57e85f77502a593b207809211c76e5396ae4f5c", + "sha256:30c84e3a62cfcb9e3066f25226e131451312a044f1fe2040e69ce792cb7de418", + "sha256:4650d94bb9c947151737ee022b934b7d9a845a7c76e476f3e460f09a0c8c6f39", + "sha256:4dd830a11e8724c9c9379feed1d1be43113f8bcce55f47ea7186d3946769ce26", + "sha256:4f2a2b279efde194877aff1f76cf61c68e840db242a5c7169f1ff0fd59a2b1e2", + "sha256:62d22566b3e3428dfc9ec972014c38ed9a4db4f8969c78f5414012ccd80a149e", + "sha256:669795516d62f38845c7033679c648903200980d68935baaa17ac5c7ae03ae0c", + "sha256:75fcd60d682db3e1f8fbe2b8b0c6761937ad56d01c1dc73edf4ef2748d5b6bc4", + "sha256:9395b0a41e8b7e9a284e3be7060db9d14ad80273841c952c83a5afc241d2bd98", + "sha256:9e37c35fc4e9410093b04a77d11a34c64bf658565e30df7cbe882056088a91c1", + "sha256:a0678793096205a4d784bd99f32803ba8100f639cf3b932dc63b21621390ea7e", + "sha256:b46554ad4dafb2927f88de5a1d207398c5385edbb5c84d30b3ef187c4a3894d8", + "sha256:c867eeccd934920a800f65c6068acdd6b87e80d45cd8c8beefff783b23cdc462", + "sha256:dd0667f5be56fb1b570154c2c0516a528e02d50da121bbbb2cbb0b6f87f59bc2", + "sha256:de2b1c20494bdf47f0160bd88ed05f5e48ae5dc336b8de7cfade71abcc95c0b9", + "sha256:f1df7b2b7740dd777571c732f98adb5aad5450aee32772f1b39249c8a50386f6", + "sha256:ffca69e29079f7880c5392bf675eb8b4146479d976ae1924d01cd92b04cccbcc" + ], + "index": "pypi", + "version": "==1.17.3" }, "opencv-python": { "hashes": [ @@ -349,35 +319,39 @@ }, "pillow": { "hashes": [ - "sha256:00fdeb23820f30e43bba78eb9abb00b7a937a655de7760b2e09101d63708b64e", - "sha256:01f948e8220c85eae1aa1a7f8edddcec193918f933fb07aaebe0bfbbcffefbf1", - "sha256:08abf39948d4b5017a137be58f1a52b7101700431f0777bec3d897c3949f74e6", - "sha256:099a61618b145ecb50c6f279666bbc398e189b8bc97544ae32b8fcb49ad6b830", - "sha256:2c1c61546e73de62747e65807d2cc4980c395d4c5600ecb1f47a650c6fa78c79", - "sha256:2ed9c4f694861642401f27dc3cb99772be67cd190e84845c749dae0a06c3bfae", - "sha256:338581b30b908e111be578f0297255f6b57a51358cd16fa0e6f664c9a1f88bff", - "sha256:38c7d48a21cd06fdeee93987147b9b1c55b73b4cfcbf83240568bfbd5adee447", - "sha256:43fd026f613c8e48a25eba1a92f4d2ad7f3903c95d8c33a11611a7717d2ab654", - "sha256:4548236844327a718ce3bb182ab32a16fa2050c61e334e959f554cac052fb0df", - "sha256:5090857876c58885cfa388dc649e5db30aae98a068c26f3fd0ac9d7d9a4d9572", - "sha256:5bbba34f97a26a93f5e8dec469ca4ddd712451418add43da946dbaed7f7a98d2", - "sha256:65a28969a025a0eb4594637b6103201dc4ed2a9508bdab56ac33e43e3081c404", - "sha256:892bb52b70bd5ea9dbbc3ac44f38e84f5a04e9d8b1bff48159d96cb795b81159", - "sha256:8a9becd5cbd5062f973bcd2e7bc79483af310222de112b6541f8af1f93a3cc42", - "sha256:972a7aaeb7c4a2795b52eef52ee991ef040b31009f36deca6207a986607b55f3", - "sha256:97b119c436bfa96a92ac2ca525f7025836d4d4e64b1c9f9eff8dbaf3ff1d86f3", - "sha256:9ba37698e242223f8053cc158f130aee046a96feacbeab65893dbe94f5530118", - "sha256:b1b0e1f626a0f079c0d3696db70132fb1f29aa87c66aecb6501a9b8be64ce9f7", - "sha256:c14c1224fd1a5be2733530d648a316974dbbb3c946913562c6005a76f21ca042", - "sha256:c79a8546c48ae6465189e54e3245a97ddf21161e33ff7eaa42787353417bb2b6", - "sha256:ceb76935ac4ebdf6d7bc845482a4450b284c6ccfb281e34da51d510658ab34d8", - "sha256:e22bffaad04b4d16e1c091baed7f2733fc1ebb91e0c602abf1b6834d17158b1f", - "sha256:ec883b8e44d877bda6f94a36313a1c6063f8b1997aa091628ae2f34c7f97c8d5", - "sha256:f1baa54d50ec031d1a9beb89974108f8f2c0706f49798f4777df879df0e1adb6", - "sha256:f53a5385932cda1e2c862d89460992911a89768c65d176ff8c50cddca4d29bed" + "sha256:047d9473cf68af50ac85f8ee5d5f21a60f849bc17d348da7fc85711287a75031", + "sha256:0f66dc6c8a3cc319561a633b6aa82c44107f12594643efa37210d8c924fc1c71", + "sha256:12c9169c4e8fe0a7329e8658c7e488001f6b4c8e88740e76292c2b857af2e94c", + "sha256:248cffc168896982f125f5c13e9317c059f74fffdb4152893339f3be62a01340", + "sha256:27faf0552bf8c260a5cee21a76e031acaea68babb64daf7e8f2e2540745082aa", + "sha256:285edafad9bc60d96978ed24d77cdc0b91dace88e5da8c548ba5937c425bca8b", + "sha256:384b12c9aa8ef95558abdcb50aada56d74bc7cc131dd62d28c2d0e4d3aadd573", + "sha256:38950b3a707f6cef09cd3cbb142474357ad1a985ceb44d921bdf7b4647b3e13e", + "sha256:4aad1b88933fd6dc2846552b89ad0c74ddbba2f0884e2c162aa368374bf5abab", + "sha256:4ac6148008c169603070c092e81f88738f1a0c511e07bd2bb0f9ef542d375da9", + "sha256:4deb1d2a45861ae6f0b12ea0a786a03d19d29edcc7e05775b85ec2877cb54c5e", + "sha256:59aa2c124df72cc75ed72c8d6005c442d4685691a30c55321e00ed915ad1a291", + "sha256:5a47d2123a9ec86660fe0e8d0ebf0aa6bc6a17edc63f338b73ea20ba11713f12", + "sha256:5cc901c2ab9409b4b7ac7b5bcc3e86ac14548627062463da0af3b6b7c555a871", + "sha256:6c1db03e8dff7b9f955a0fb9907eb9ca5da75b5ce056c0c93d33100a35050281", + "sha256:7ce80c0a65a6ea90ef9c1f63c8593fcd2929448613fc8da0adf3e6bfad669d08", + "sha256:809c19241c14433c5d6135e1b6c72da4e3b56d5c865ad5736ab99af8896b8f41", + "sha256:83792cb4e0b5af480588601467c0764242b9a483caea71ef12d22a0d0d6bdce2", + "sha256:846fa202bd7ee0f6215c897a1d33238ef071b50766339186687bd9b7a6d26ac5", + "sha256:9f5529fc02009f96ba95bea48870173426879dc19eec49ca8e08cd63ecd82ddb", + "sha256:a423c2ea001c6265ed28700df056f75e26215fd28c001e93ef4380b0f05f9547", + "sha256:ac4428094b42907aba5879c7c000d01c8278d451a3b7cccd2103e21f6397ea75", + "sha256:b1ae48d87f10d1384e5beecd169c77502fcc04a2c00a4c02b85f0a94b419e5f9", + "sha256:bf4e972a88f8841d8fdc6db1a75e0f8d763e66e3754b03006cbc3854d89f1cb1", + "sha256:c6414f6aad598364aaf81068cabb077894eb88fed99c6a65e6e8217bab62ae7a", + "sha256:c710fcb7ee32f67baf25aa9ffede4795fd5d93b163ce95fdc724383e38c9df96", + "sha256:c7be4b8a09852291c3c48d3c25d1b876d2494a0a674980089ac9d5e0d78bd132", + "sha256:c9e5ffb910b14f090ac9c38599063e354887a5f6d7e6d26795e916b4514f2c1a", + "sha256:e0697b826da6c2472bb6488db4c0a7fa8af0d52fa08833ceb3681358914b14e5", + "sha256:e9a3edd5f714229d41057d56ac0f39ad9bdba6767e8c888c951869f0bdd129b0" ], "index": "pypi", - "version": "==6.2.0" + "version": "==6.2.1" }, "protobuf": { "hashes": [ @@ -549,11 +523,11 @@ }, "flake8": { "hashes": [ - "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", - "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" + "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb", + "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca" ], "index": "pypi", - "version": "==3.7.8" + "version": "==3.7.9" }, "isort": { "hashes": [ @@ -572,26 +546,30 @@ }, "mypy": { "hashes": [ - "sha256:1d98fd818ad3128a5408148c9e4a5edce6ed6b58cc314283e631dd5d9216527b", - "sha256:22ee018e8fc212fe601aba65d3699689dd29a26410ef0d2cc1943de7bec7e3ac", - "sha256:3a24f80776edc706ec8d05329e854d5b9e464cd332e25cde10c8da2da0a0db6c", - "sha256:42a78944e80770f21609f504ca6c8173f7768043205b5ac51c9144e057dcf879", - "sha256:4b2b20106973548975f0c0b1112eceb4d77ed0cafe0a231a1318f3b3a22fc795", - "sha256:591a9625b4d285f3ba69f541c84c0ad9e7bffa7794da3fa0585ef13cf95cb021", - "sha256:5b4b70da3d8bae73b908a90bb2c387b977e59d484d22c604a2131f6f4397c1a3", - "sha256:84edda1ffeda0941b2ab38ecf49302326df79947fa33d98cdcfbf8ca9cf0bb23", - "sha256:b2b83d29babd61b876ae375786960a5374bba0e4aba3c293328ca6ca5dc448dd", - "sha256:cc4502f84c37223a1a5ab700649b5ab1b5e4d2bf2d426907161f20672a21930b", - "sha256:e29e24dd6e7f39f200a5bb55dcaa645d38a397dd5a6674f6042ef02df5795046" + "sha256:1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f", + "sha256:31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00", + "sha256:3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae", + "sha256:48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d", + "sha256:540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9", + "sha256:672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391", + "sha256:6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f", + "sha256:9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9", + "sha256:ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990", + "sha256:b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7", + "sha256:d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb", + "sha256:d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453", + "sha256:dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b", + "sha256:f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb" ], "index": "pypi", - "version": "==0.730" + "version": "==0.740" }, "mypy-extensions": { "hashes": [ - "sha256:a161e3b917053de87dbe469987e173e49fb454eca10ef28b48b384538cc11458" + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" ], - "version": "==0.4.2" + "version": "==0.4.3" }, "pathtools": { "hashes": [ @@ -665,31 +643,36 @@ }, "typed-ast": { "hashes": [ + "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", + "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" ], "version": "==1.4.0" }, "typing-extensions": { "hashes": [ - "sha256:2ed632b30bb54fc3941c382decfd0ee4148f5c591651c9272473fea2c6397d95", - "sha256:b1edbbf0652660e32ae780ac9433f4231e7339c7f9a8057d0f042fcbcea49b87", - "sha256:d8179012ec2c620d3791ca6fe2bf7979d979acdbef1fca0bc56b37411db682ed" + "sha256:091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2", + "sha256:910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d", + "sha256:cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575" ], - "version": "==3.7.4" + "version": "==3.7.4.1" }, "watchdog": { "hashes": [ diff --git a/object-detection/src/app.py b/object-detection/src/app.py deleted file mode 100644 index b051350..0000000 --- a/object-detection/src/app.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 - -import glob -import os -from io import BytesIO -from time import time -from typing import Dict - -import numpy as np -import requests -from flask import Flask, jsonify, request -from PIL import Image - -from draw import LABEL_NAME, draw -from model import FasterRCNNResnet101Coco - -image_dir = "/dev/shm/photo" -os.makedirs(image_dir, exist_ok=True) - -app = Flask(__name__, static_url_path='/photo', static_folder=image_dir) - - -app.logger.info("Loading network") -net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) - - -@app.route('/faster_rcnn_resnet101_coco') -def object_detection(): - photo_id = request.args.get("photo_id") - threshold = request.args.get("threshold", os.getenv("THRESHOLD", 0.7)) - retention = float(request.args.get("retention", os.getenv("RETENTION_SEC", 60*60*24))) - - image = requests.get("http://media/temporary") - image = Image.open(BytesIO(image.content)).convert('RGB') - image = np.asarray(image) - - output = net(image) - output = select_top_prediction(output, threshold) - - image = draw(image, output) - for f in glob.glob(f"{image_dir}/*"): - if f.split("/")[-1].isdecimal() and float(f.split("/")[-1]) / 1000 + retention < time(): - os.remove(f) - Image.fromarray(image).save(f"{image_dir}/{photo_id}", "JPEG") - - return jsonify({ - "bbox": (output["bbox"].reshape(-1, 2, 2) * np.array(image.shape[-2::-1])).reshape(-1, 4).astype(int).tolist(), - "confidence": output["conf"].tolist(), - "label_id": output["label"].astype(int).tolist(), - "label_name": [LABEL_NAME[label] for label in output["label"].astype(int)], - "photo_id": photo_id - }) - - -def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: - assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." - keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] - prediction = {key: value[keep] for key, value in prediction.items()} - return prediction - - -if __name__ == "__main__": - app.run(port=80) diff --git a/object-detection/src/main.py b/object-detection/src/main.py new file mode 100644 index 0000000..c80725d --- /dev/null +++ b/object-detection/src/main.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +import os +from io import BytesIO +from typing import Dict, List, Tuple, Union + +import numpy as np +import requests +from PIL import Image + +from draw import LABEL_NAME, draw +from model import FasterRCNNResnet101Coco, Model + + +def main() -> None: + net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) + + threshold = float(os.getenv("THRESHOLD", 0.7)) + retention_time = float(os.getenv("RETENTION_SEC", 60 * 60 * 24)) + + while True: + image, prediction = predict(net, threshold) + + res = requests.post("http://image-storage/temporary", {"retention_time": retention_time}, + files={"file": ("prediction", convert_image_buffer(image), "image/jpeg")}) + print(f"temporary/{res.json()['id']}") + + +def convert_image_buffer(image: np.ndarray) -> bytes: + image = Image.fromarray(image) + byte_io = BytesIO() + image.save(byte_io, format="JPEG") + buffer = byte_io.getvalue() + byte_io.close() + return buffer + + +def predict(net: Model, threshold: float) -> Tuple[np.ndarray, Dict[str, Union[List[int], List[float], List[str]]]]: + image = fetch_camera_image() + output = net(image) + output = select_top_prediction(output, threshold) + + image = draw(image, output) + + output["bbox"] = output["bbox"] * np.tile(np.array(image.shape[-2::-1]), 2) + return image, { + "bbox": output["bbox"].astype(int).tolist(), + "confidence": output["conf"].tolist(), + "label_id": output["label"].astype(int).tolist(), + "label_name": [LABEL_NAME[label] for label in output["label"].astype(int)] + } + + +def fetch_camera_image() -> np.ndarray: + image = requests.get("http://image-storage/temporary") + image = Image.open(BytesIO(image.content)).convert('RGB') + image = np.asarray(image) + return image + + +def select_top_prediction(prediction: Dict[str, np.ndarray], threshold: float) -> Dict[str, np.ndarray]: + assert 0 <= threshold <= 1, "Specify 0 to 1 for threshold." + keep = np.argsort(-prediction["conf"])[:(prediction["conf"] >= threshold).sum()] + prediction = {key: value[keep] for key, value in prediction.items()} + return prediction + + +if __name__ == "__main__": + main() From 18860e4848e31f700b1757cf3864c772037ac285 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 4 Nov 2019 21:11:02 +0900 Subject: [PATCH 44/60] Update OpenVINO --- object-detection/Dockerfile | 4 ++-- object-detection/src/Pipfile | 3 +-- object-detection/src/Pipfile.lock | 21 ++++++--------------- object-detection/src/get_model.sh | 5 +---- object-detection/src/main.py | 7 +++---- object-detection/src/model.py | 9 ++++----- 6 files changed, 17 insertions(+), 32 deletions(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index d563e4b..2f13824 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -4,7 +4,7 @@ ARG NUM_THREADS=1 ENV LANG C.UTF-8 # https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#building-for-cpu -ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/15693/l_openvino_toolkit_p_2019.2.242_online.tgz +ARG DOWNLOAD_LINK=http://registrationcenter-download.intel.com/akdlm/irc_nas/16057/l_openvino_toolkit_p_2019.3.376_online.tgz ARG INSTALL_DIR=/opt/intel/openvino ARG TEMP_DIR=/tmp/openvino_installer @@ -26,7 +26,7 @@ RUN $INSTALL_DIR/install_dependencies/install_openvino_dependencies.sh && \ # https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_docker_linux.html#run_the_docker_image_for_intel_movidius_neural_compute_stick_and_intel_neural_compute_stick_2 RUN cd /tmp/ && \ - apt-get install -yq --no-install-recommends unzip && \ + apt-get install -yq --no-install-recommends unzip dh-autoreconf && \ wget https://github.com/libusb/libusb/archive/v1.0.22.zip && \ unzip v1.0.22.zip && cd libusb-1.0.22 && \ ./bootstrap.sh && \ diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index c1410e1..4d50ae6 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -18,9 +18,8 @@ requests = "~=2.22.0" # Required by /opt/intel/openvino/deployment_tools/model_optimizer tensorflow = ">=1.2.0,<2.0.0,!=1.15.0" -networkx = ">=1.11" +networkx = ">=1.11,<2.4" numpy = ">=1.12.0" -test-generator = "==0.1.1" defusedxml = ">=0.5.0" opencv-python = "~=4.1.1.26" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index 1892747..c78b18c 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "85db9ee8b2f53f9bdd74fac802fd7b5619cc0f05f3c8e5c07bfffbfcf5c25b5d" + "sha256": "3e33b04d169249aa5b1b460cc75ddcbccf7b8c0115c05c765c711703a0292887" }, "pipfile-spec": 6, "requires": { @@ -251,11 +251,10 @@ }, "networkx": { "hashes": [ - "sha256:cdfbf698749a5014bf2ed9db4a07a5295df1d3a53bf80bf3cbd61edf9df05fa1", - "sha256:f8f4ff0b6f96e4f9b16af6b84622597b5334bf9cae8cf9b2e42e7985d5c95c64" + "sha256:8311ddef63cf5c5c5e7c1d0212dd141d9a1fe3f474915281b73597ed5f1d4e3d" ], "index": "pypi", - "version": "==2.4" + "version": "==2.3" }, "numpy": { "hashes": [ @@ -383,10 +382,10 @@ }, "python-dateutil": { "hashes": [ - "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", - "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", + "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" ], - "version": "==2.8.0" + "version": "==2.8.1" }, "pyyaml": { "hashes": [ @@ -462,14 +461,6 @@ ], "version": "==1.1.0" }, - "test-generator": { - "hashes": [ - "sha256:01e6aa3e01b5a0cb2ef05c80cdb259abae820d82f07ffcd0ded9bce03f3c38d4", - "sha256:da9cfc2a26bc5bd1f43ef20050fd531790cc5283adcc49e34e0cf33345d6583d" - ], - "index": "pypi", - "version": "==0.1.1" - }, "urllib3": { "hashes": [ "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", diff --git a/object-detection/src/get_model.sh b/object-detection/src/get_model.sh index 03ddf73..defbdaf 100644 --- a/object-detection/src/get_model.sh +++ b/object-detection/src/get_model.sh @@ -1,13 +1,10 @@ -sed -e "s/data_type=FP32/data_type=FP16/g" /opt/intel/openvino/deployment_tools/tools/model_downloader/list_topologies.yml > ./list_topologies.yml - python /opt/intel/openvino/deployment_tools/tools/model_downloader/downloader.py \ - --config ./list_topologies.yml \ --name $1 \ --cache_dir ./.cache \ --output_dir ./models python /opt/intel/openvino/deployment_tools/tools/model_downloader/converter.py \ - --config ./list_topologies.yml \ --name $1 \ + --precisions=FP16 \ --mo /opt/intel/openvino/deployment_tools/model_optimizer/mo.py \ --download_dir ./models diff --git a/object-detection/src/main.py b/object-detection/src/main.py index c80725d..8a91edc 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -27,10 +27,9 @@ def main() -> None: def convert_image_buffer(image: np.ndarray) -> bytes: image = Image.fromarray(image) - byte_io = BytesIO() - image.save(byte_io, format="JPEG") - buffer = byte_io.getvalue() - byte_io.close() + with BytesIO() as byte_io: + image.save(byte_io, format="JPEG") + buffer = byte_io.getvalue() return buffer diff --git a/object-detection/src/model.py b/object-detection/src/model.py index 4f0438b..7cbd029 100644 --- a/object-detection/src/model.py +++ b/object-detection/src/model.py @@ -59,14 +59,14 @@ class PreparedModel(Model): precisions = "FP16" def __init__(self, *args, **kwargs) -> None: - with open("/opt/intel/openvino/deployment_tools/tools/model_downloader/list_topologies.yml") as f: - topologies = yaml.load(f, Loader=yaml.SafeLoader) - topologies = {topologie["name"]: topologie for topologie in topologies["topologies"]} + model_root = Path("/opt/intel/openvino/deployment_tools/open_model_zoo/models") + topologies = {path.parent.name: path for path in model_root.glob("**/model.yml")} assert self.model_name in topologies, \ f"{self.model_name} is not found in model zoo.\nPlease specify from the following.\n{topologies.keys()}" - output = Path("models") / topologies[self.model_name]["output"] / self.precisions + topology = topologies[self.model_name] + output = Path("models") / topology.parent.relative_to(model_root) / self.precisions model_file = output / f"{self.model_name}.xml" weights_file = output / f"{self.model_name}.bin" @@ -78,7 +78,6 @@ def __init__(self, *args, **kwargs) -> None: class FasterRCNNResnet101Coco(PreparedModel): model_name = "faster_rcnn_resnet101_coco" - precisions = "FP32" def __call__(self, frame: np.ndarray) -> Dict[str, np.ndarray]: images = np.expand_dims(self.transform(frame), 0) From afb8d86d6fdde507ccd995987b55b73b350f82f5 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 4 Nov 2019 21:20:24 +0900 Subject: [PATCH 45/60] Add socket io server & uploader --- slack/src/main.js | 32 +++- slack/src/object_detection.js | 36 ++-- slack/src/package-lock.json | 352 ++++++++++++++++++++++++++++++++++ slack/src/package.json | 3 +- 4 files changed, 401 insertions(+), 22 deletions(-) diff --git a/slack/src/main.js b/slack/src/main.js index 2a65bdc..f15059a 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -9,9 +9,14 @@ const helmet = require('helmet'); const cors = require('cors'); const axios = require('axios'); const morgan = require('morgan'); -const { objectsNotification } = require('./object_detection'); +const http = require('http'); +const io = require('./object_detection')(); + const app = express(); +const server = http.createServer(app); +io.attach(server); + app.set('trust proxy', 1); app.use(helmet()); app.use(cors()); @@ -93,9 +98,8 @@ app.post('/bushitsu-photo', async (req, res) => { // Others -app.get('/photo/:filename', async (req, res) => { +app.get(['/photo/:filename', '/detected-photo/:filename'], async (req, res, next) => { const { key } = req.query; - const { filename } = req.params; if (!key) { res.sendStatus(401); @@ -103,21 +107,29 @@ app.get('/photo/:filename', async (req, res) => { } const correctKey = crypto .createHash('md5') - .update(`${filename}-${process.env.SESSION_SECRET}`, 'utf8') + .update(`${req.params.filename}-${process.env.SESSION_SECRET}`, 'utf8') .digest('Base64'); if (correctKey !== base64url.unescape(key)) { res.sendStatus(403); return; } + next(); +}); - const img = await axios.get(`http://image-storage/permament/slack/${filename}`, { +app.get('/photo/:filename', async (req, res) => { + const img = await axios.get(`http://image-storage/permament/slack/${req.params.filename}`, { responseType: 'arraybuffer', - headers: { - 'Content-Type': 'image/jpg', - }, + headers: { 'Content-Type': 'image/jpg' }, + }); + res.type('image/jpg').send(img.data).end(); +}); +app.get('/detected-photo/:filename', async (req, res) => { + const img = await axios.get(`http://image-storage/temporary/${req.params.filename}`, { + responseType: 'arraybuffer', + headers: { 'Content-Type': 'image/jpg' }, }); res.type('image/jpg').send(img.data).end(); }); -app.listen(80, () => console.log('Express app listening on port 80.')); -setInterval(() => objectsNotification(web, Number(process.env.NOTIFICATION_INTERVAL)), Number(process.env.NOTIFICATION_INTERVAL) * 1000); + +server.listen(80, () => console.log('Express app listening on port 80.')); diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js index 304b0d0..d940fd1 100644 --- a/slack/src/object_detection.js +++ b/slack/src/object_detection.js @@ -5,6 +5,8 @@ const object = require('json-templater/object'); const fs = require('fs'); const base64url = require('base64-url'); const Redis = require('ioredis'); +const { WebClient } = require('@slack/web-api'); + const redis = new Redis({ host: 'redis', @@ -12,36 +14,32 @@ const redis = new Redis({ }); const hostname = 'slack'; +const web = new WebClient(process.env.SLACK_BOT_ACCESS_TOKEN); const rtm = new RTMClient(process.env.SLACK_BOT_ACCESS_TOKEN); rtm.start() .then('start rtmp client') .catch(console.error); rtm.on('message', (event) => { - if (event.subtype == undefined) { + if (event.subtype === undefined) { redis.set('age', true); } }); -module.exports.objectsNotification = async (web, retention) => { - const photoId = Date.now(); - - const [awsUrl, objects] = await Promise.all([ - axios.get('http://tunnel').then((result) => result.data.awsUrl), - axios.get('http://object-detection/faster_rcnn_resnet101_coco', { params: { retention } }).then((result) => result.data), - ]); +const objectsNotification = async (prediction) => { + const { awsUrl } = await axios.get('http://tunnel').then((result) => result.data); - const text = objects.label_name.map((value, index) => `- \`${value}\`: ${objects.confidence[index].toFixed(3)}`).join('\n') || '何も検出されませんでした'; + const text = prediction.label_name.map((value, index) => `- \`${value}\`: ${prediction.confidence[index].toFixed(3)}`).join('\n') || '何も検出されませんでした'; const key = crypto .createHash('md5') - .update(`${photoId}-${process.env.SESSION_SECRET}`, 'utf8') + .update(`${prediction.id}-${process.env.SESSION_SECRET}`, 'utf8') .digest('Base64'); const blocks = object( JSON.parse(fs.readFileSync('./block_template_detection.json', 'utf8')), { - image_url: `${awsUrl}/${hostname}/detected-photo/${photoId}?key=${base64url.escape(key)}`, + image_url: `${awsUrl}/${hostname}/detected-photo/${prediction.id}?key=${base64url.escape(key)}`, text, time: new Date().toLocaleString(), viewer_url: `${awsUrl}/viewer`, @@ -80,3 +78,19 @@ module.exports.objectsNotification = async (web, retention) => { }); redis.set('previous_ts', result.ts); }; + + +module.exports = (path = '/socket.io') => { + const io = require('socket.io')({ + path, + serveClient: false, + }); + + io.on('connection', (socket) => { + socket.on('prediction', (prediction) => { + objectsNotification(prediction); + }); + }); + + return io; +}; diff --git a/slack/src/package-lock.json b/slack/src/package-lock.json index dea3935..6dbdddc 100644 --- a/slack/src/package-lock.json +++ b/slack/src/package-lock.json @@ -268,6 +268,11 @@ "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -379,6 +384,11 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -422,6 +432,11 @@ "is-buffer": "^2.0.2" } }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -483,11 +498,21 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, "base64-url": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-2.3.2.tgz", "integrity": "sha512-2QpXjtjndKqPn9JKBpMTCbDGpgicfLUu+N5Y1vEfbuyqb1MN1D68C9YKCth4SjTHRvJleF3tPuxhLbH79MM0iQ==" }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -496,12 +521,25 @@ "safe-buffer": "5.1.2" } }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -638,6 +676,11 @@ "unset-value": "^1.0.0" } }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -809,12 +852,22 @@ "delayed-stream": "~1.0.0" } }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1090,6 +1143,105 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "engine.io": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.0.tgz", + "integrity": "sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz", + "integrity": "sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==", + "requires": { + "async-limiter": "^1.0.0" + } + } + } + }, + "engine.io-client": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.0.tgz", + "integrity": "sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2424,6 +2576,26 @@ "function-bind": "^1.1.1" } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2609,6 +2781,11 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3382,6 +3559,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -3623,6 +3805,22 @@ "error-ex": "^1.2.0" } }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -4272,6 +4470,145 @@ } } }, + "socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + }, + "socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz", + "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4530,6 +4867,11 @@ "os-tmpdir": "~1.0.2" } }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -4868,11 +5210,21 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } } } diff --git a/slack/src/package.json b/slack/src/package.json index d7892fb..073a02b 100644 --- a/slack/src/package.json +++ b/slack/src/package.json @@ -21,7 +21,8 @@ "helmet": "^3.21.1", "ioredis": "^4.14.1", "json-templater": "^1.2.0", - "morgan": "^1.9.1" + "morgan": "^1.9.1", + "socket.io": "^2.3.0" }, "devDependencies": { "eslint": "^6.5.1", From d7983bf7502a679d76565c529992d7bc1579887f Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 4 Nov 2019 21:22:07 +0900 Subject: [PATCH 46/60] Use socketio in object-detection --- docker-compose.debug.yml | 1 + docker-compose.prod.yml | 1 + object-detection/src/Pipfile | 1 + object-detection/src/Pipfile.lock | 27 ++++++++++++++++++++++++++- object-detection/src/main.py | 11 +++++++++-- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index 8d729d4..f41bbe8 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -156,3 +156,4 @@ services: - 5678:5678 depends_on: - streamer + - image-storage diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index f947428..626fb08 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -144,3 +144,4 @@ services: - /dev:/dev depends_on: - streamer + - image-storage diff --git a/object-detection/src/Pipfile b/object-detection/src/Pipfile index 4d50ae6..d3adc7e 100644 --- a/object-detection/src/Pipfile +++ b/object-detection/src/Pipfile @@ -25,6 +25,7 @@ defusedxml = ">=0.5.0" opencv-python = "~=4.1.1.26" pillow = "~=6.2.0" matplotlib = "~=3.1.1" +python-socketio = {extras = ["client"],version = "~=4.3.1"} [requires] python_version = "3.7" diff --git a/object-detection/src/Pipfile.lock b/object-detection/src/Pipfile.lock index c78b18c..3e4e0a0 100644 --- a/object-detection/src/Pipfile.lock +++ b/object-detection/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3e33b04d169249aa5b1b460cc75ddcbccf7b8c0115c05c765c711703a0292887" + "sha256": "7076f4d072b6698f4ba9a1a1336986a89db343d1fb599bc81a4438feacca1886" }, "pipfile-spec": 6, "requires": { @@ -387,6 +387,24 @@ ], "version": "==2.8.1" }, + "python-engineio": { + "hashes": [ + "sha256:4a13fb87c819b855c55a731fdf82559adb8311c04cfdfebd6b9ecd1c2afbb575", + "sha256:9c9a6035b4b5e5a225f426f846afa14cf627f7571d1ae02167cb703fefd134b7" + ], + "version": "==3.10.0" + }, + "python-socketio": { + "extras": [ + "client" + ], + "hashes": [ + "sha256:506b2cf7a520b40ea0b3f25e1272eff8de134dce6f471c1f6bc0de8c90fe8c57", + "sha256:d4e2c23241afa0aae2a5bcc107523b2fcc71f5020df89a093f3634eb48955967" + ], + "index": "pypi", + "version": "==4.3.1" + }, "pyyaml": { "hashes": [ "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", @@ -468,6 +486,13 @@ ], "version": "==1.25.6" }, + "websocket-client": { + "hashes": [ + "sha256:1151d5fb3a62dc129164292e1227655e4bbc5dd5340a5165dfae61128ec50aa9", + "sha256:1fd5520878b68b84b5748bb30e592b10d0a91529d5383f74f4964e72b297fd3a" + ], + "version": "==0.56.0" + }, "werkzeug": { "hashes": [ "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", diff --git a/object-detection/src/main.py b/object-detection/src/main.py index 8a91edc..11e7556 100644 --- a/object-detection/src/main.py +++ b/object-detection/src/main.py @@ -5,6 +5,7 @@ import numpy as np import requests +import socketio from PIL import Image from draw import LABEL_NAME, draw @@ -13,6 +14,8 @@ def main() -> None: net = FasterRCNNResnet101Coco(os.getenv("DEVICE", "CPU"), os.getenv("CPU_EXTENSION")) + sio = socketio.Client() + sio.connect('http://slack/socket.io/') threshold = float(os.getenv("THRESHOLD", 0.7)) retention_time = float(os.getenv("RETENTION_SEC", 60 * 60 * 24)) @@ -22,7 +25,11 @@ def main() -> None: res = requests.post("http://image-storage/temporary", {"retention_time": retention_time}, files={"file": ("prediction", convert_image_buffer(image), "image/jpeg")}) - print(f"temporary/{res.json()['id']}") + + prediction["id"] = res.json()['id'] + prediction["iamge_path"] = f"temporary/{res.json()['id']}" + + sio.emit('prediction', prediction) def convert_image_buffer(image: np.ndarray) -> bytes: @@ -33,7 +40,7 @@ def convert_image_buffer(image: np.ndarray) -> bytes: return buffer -def predict(net: Model, threshold: float) -> Tuple[np.ndarray, Dict[str, Union[List[int], List[float], List[str]]]]: +def predict(net: Model, threshold: float) -> Tuple[np.ndarray, Dict[str, list]]: image = fetch_camera_image() output = net(image) output = select_top_prediction(output, threshold) From e087583bf5d984af67da0ba1965b3e9d0b413fd2 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 4 Nov 2019 01:34:04 +0900 Subject: [PATCH 47/60] Add allways options --- docker-compose.prod.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 626fb08..73409b1 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -8,6 +8,7 @@ services: - ./streaming-server/src:/app ports: - 1935:1935 + restart: always streamer: build: ./streamer volumes: @@ -21,6 +22,7 @@ services: - STREAM_NAME=bushitsuchan devices: - /dev/video0:/dev/video0 + restart: always image-storage: build: ./image-storage working_dir: /app @@ -98,6 +100,7 @@ services: - /etc/localtime:/etc/localtime:ro depends_on: - redis + restart: always slack: image: node:alpine working_dir: /app @@ -112,6 +115,7 @@ services: volumes: - ./slack/src:/app - /etc/localtime:/etc/localtime:ro + restart: always endpoint: image: node:alpine working_dir: /app @@ -128,6 +132,7 @@ services: # command: redis-server --appendonly yes --requirepass foobared volumes: - ./redis:/data + restart: always object-detection: build: @@ -145,3 +150,4 @@ services: depends_on: - streamer - image-storage + restart: always From 1fdc29f4b1073465767e8a49f7e9f25bb183dbec Mon Sep 17 00:00:00 2001 From: ilim Date: Thu, 31 Oct 2019 18:39:01 +0900 Subject: [PATCH 48/60] Added option to make npm command lighter --- docker-compose.prod.yml | 12 ++++++------ utils/docker-compose.install.yml | 14 +++++++------- utils/docker-compose.update.yml | 14 +++++++------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 626fb08..7abc925 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -3,7 +3,7 @@ services: streaming-server: image: node:alpine working_dir: /app - command: ash -c "npm ci && npm start" + command: ash -c "npm ci --production --no-progress && npm start" volumes: - ./streaming-server/src:/app ports: @@ -24,7 +24,7 @@ services: image-storage: build: ./image-storage working_dir: /app - command: ash -c "npm ci && npm start" + command: ash -c "npm ci --production --no-progress && npm start" entrypoint: docker-entrypoint.sh volumes: - ./image-storage/src:/app @@ -40,7 +40,7 @@ services: hls: build: ./hls working_dir: /app - command: ash -c "npm ci && npm start" + command: ash -c "npm ci --production --no-progress && npm start" entrypoint: docker-entrypoint.sh volumes: - ./hls/src:/app @@ -65,7 +65,7 @@ services: tunnel: build: ./tunnel working_dir: /app - command: ash -c "npm ci && npm start" + command: ash -c "npm ci --production --no-progress && npm start" volumes: - ./tunnel/src:/app environment: @@ -87,7 +87,7 @@ services: web: image: node:alpine working_dir: /app - command: ash -c "npm ci && npm start" + command: ash -c "npm ci --production --no-progress && npm start" environment: - SESSION_SECRET=${SESSION_SECRET} - SLACK_CLIENT_ID=${SLACK_CLIENT_ID} @@ -101,7 +101,7 @@ services: slack: image: node:alpine working_dir: /app - command: ash -c "npm ci && npm start" + command: ash -c "npm ci --production --no-progress && npm start" environment: - SLACK_BOT_ACCESS_TOKEN=${SLACK_BOT_ACCESS_TOKEN} - SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET} diff --git a/utils/docker-compose.install.yml b/utils/docker-compose.install.yml index 0cb9bdb..56ee086 100644 --- a/utils/docker-compose.install.yml +++ b/utils/docker-compose.install.yml @@ -3,14 +3,14 @@ services: streaming-server: image: node:alpine working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" volumes: - ../streaming-server/src:/app image-storage: build: ../image-storage working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" entrypoint: docker-entrypoint.sh volumes: - ../image-storage/src:/app @@ -18,7 +18,7 @@ services: hls: build: ../hls working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" entrypoint: docker-entrypoint.sh volumes: - ../hls/src:/app @@ -26,28 +26,28 @@ services: tunnel: build: ../tunnel working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" volumes: - ../tunnel/src:/app web: image: node:alpine working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" volumes: - ../web/src:/app slack: image: node:alpine working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" volumes: - ../slack/src:/app endpoint: image: node:alpine working_dir: /app - command: ash -c "npm ci" + command: ash -c "npm ci --no-progress" volumes: - ../endpoint/src:/app diff --git a/utils/docker-compose.update.yml b/utils/docker-compose.update.yml index eaedbd7..50065fd 100644 --- a/utils/docker-compose.update.yml +++ b/utils/docker-compose.update.yml @@ -3,14 +3,14 @@ services: streaming-server: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" volumes: - ../streaming-server/src:/app image-storage: build: ../image-storage working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" entrypoint: docker-entrypoint.sh volumes: - ../image-storage/src:/app @@ -18,7 +18,7 @@ services: hls: build: ../hls working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" entrypoint: docker-entrypoint.sh volumes: - ../hls/src:/app @@ -26,28 +26,28 @@ services: tunnel: build: ../tunnel working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" volumes: - ../tunnel/src:/app web: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" volumes: - ../web/src:/app slack: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" volumes: - ../slack/src:/app endpoint: image: node:alpine working_dir: /app - command: ash -c "npm install && npm audit fix" + command: ash -c "npm install --no-progress && npm audit fix" volumes: - ../endpoint/src:/app From e0a1129d8315956e618c753c6652d6d5aacf529d Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 4 Nov 2019 22:00:26 +0900 Subject: [PATCH 49/60] Do not log / detected-photo --- slack/src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slack/src/main.js b/slack/src/main.js index f15059a..ab24337 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -44,7 +44,7 @@ const slackInteractions = createMessageAdapter( app.use(morgan('<@:user> [:date[clf]] :method :url :status :res[content-length] - :response-time ms', { - skip: (req, res) => ['/hls/', '/photo/'].some((element) => req.path.startsWith(element)), + skip: (req, res) => ['/hls/', '/photo/', '/detected-photo/'].some((element) => req.path.startsWith(element)), })); morgan.token('user', (req, res) => { if (req.body.payload !== undefined) { From 3fda7b62fef6017f6ff8eb25e737cbb198397d24 Mon Sep 17 00:00:00 2001 From: ilim Date: Mon, 4 Nov 2019 22:00:38 +0900 Subject: [PATCH 50/60] Tweak --- slack/src/object_detection.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js index d940fd1..dca931a 100644 --- a/slack/src/object_detection.js +++ b/slack/src/object_detection.js @@ -27,9 +27,7 @@ rtm.on('message', (event) => { }); -const objectsNotification = async (prediction) => { - const { awsUrl } = await axios.get('http://tunnel').then((result) => result.data); - +const objectsNotification = async (prediction, awsUrl) => { const text = prediction.label_name.map((value, index) => `- \`${value}\`: ${prediction.confidence[index].toFixed(3)}`).join('\n') || '何も検出されませんでした'; const key = crypto .createHash('md5') @@ -86,9 +84,10 @@ module.exports = (path = '/socket.io') => { serveClient: false, }); - io.on('connection', (socket) => { + io.on('connection', async (socket) => { + const { awsUrl } = await axios.get('http://tunnel').then((result) => result.data); socket.on('prediction', (prediction) => { - objectsNotification(prediction); + objectsNotification(prediction, awsUrl); }); }); From 0f89ec9e67c23ea7938704f7898f09fea6dc798a Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 5 Nov 2019 00:01:10 +0900 Subject: [PATCH 51/60] Update README --- .gitignore | 7 +-- README.md | 128 ++++++++++++++++++----------------------- docs/container.md | 35 +++++++++++ docs/slack_appendix.md | 36 ++++++++++++ slack/README.md | 18 ------ 5 files changed, 128 insertions(+), 96 deletions(-) create mode 100644 docs/container.md create mode 100644 docs/slack_appendix.md delete mode 100644 slack/README.md diff --git a/.gitignore b/.gitignore index cb08129..b57811e 100644 --- a/.gitignore +++ b/.gitignore @@ -232,8 +232,6 @@ dmypy.json *.png *.jpeg *.jpg -*.m3u8 -*.ts *.mp4 # Docker files @@ -246,6 +244,5 @@ dmypy.json yarn.lock # model data -openvino -models -list_topologies.yml +openvino/ +models/ diff --git a/README.md b/README.md index f9c9e2f..2a3b4b6 100644 --- a/README.md +++ b/README.md @@ -3,64 +3,57 @@ OSK の部室の様子をオンラインで確認できるプロジェクト 部室ちゃん その部室に置いてある PC で動かすプログラム -## Support - -以下の OS をサポートします。 - -- Ubuntu 18.04 -- macOS 10.14 (Debug mode のみ) - -Debug mode 下では挙動に以下の差異があります。 +## Description -- ストリーミング映像がカメラからではなく任意の動画ファイルから取得される -- Time zone の設定がされず時刻がずれる +bushitsuchan-PC は単一の Ubuntu PC 上で動作します。 +限られた特定の人に,WEB site と Slack を介して部室の動画,画像または物体検出結果を表示します。 -## Container +### Container bushitsuchan-PC では[Docker](https://www.docker.com/)というソフトフェアを活用しています。 Docker はコンテナ技術を体現したシステムの一つで,独立したサービス単位で環境それぞれを Container という形で OS レベルに分離させることができます。必要最低な構成を独立して扱うため再利用性が高まり,また分離しているため取り回しも良くなります。 -bushitsuchan-PC における container の一覧と用途を記します。 +各 Container の説明は[ここ](/docs/container.md)に置かれています。 -### streaming-server +### Design -同時に複数のプロセスがカメラにアクセスすることができないためこの container で映像を管理し,複数のプロセスへとカメラ画像を受け渡します。 +bushitsuchan-PC 全体のフローは[Sequence 図](/docs/sequence.md)で確認できます。 -### streamer - -**streaming-server** へと実際にカメラ画像をストリーミングします。遅延を減らすための圧縮や codec の変換も行います。 - -### media - -各 container が必要とするカメラ画像や映像を **streaming-server** から代理で取り出します。また取り出す際のさらなる変換も行います。 - -### reverse-proxy - -外部からのアクセスを URL 毎に **web** または **slack** へ振り分ける処理を行います。 +## Setup -### tunnel +bushitsuchan-PC を動作させるための設定を各部分ごとに説明します。 -外部へ **reverse-proxy** サーバを公開する際の初期設定などの処理を行います。 +### 環境変数 -### web +#### 説明 -ブラウザでウェブサイトへアクセスされた際の処理を行います。ログイン処理なども担います。 +環境変数は独立したアプリケーション間で共通の値を参照できる値を設定するもので,通常は不変な ID やパスワードをセットしておきます。 -### slack +#### 設定 -Slack 上での slash command や action への応答を処理しています。 +最終的に`.env`ファイルに以下の様に書き保存してください。 +各変数へと何をセットすれば良いのかはこれから説明します。 -### redis +```text +AWS_REST_API_ID=j3i... # 二回目以降に必要 +AWS_ACCESS_KEY_ID=FUB... +AWS_SECRET_ACCESS_KEY=vKw... -データベースとして機能し,ログイン情報の保持や画像変換の待機管理を行います。 +NGROK_AUTH=8HU... -## Design +SESSION_SECRET=presetprivatekey # 暗に暗号化へ使う任意の頑強な文字列 -bushitsuchan-PC 全体のフロー +SLACK_CLIENT_ID=179... +SLACK_CLIENT_SECRET=38b... +WORKSTATION_ID=I6B... -> [Sequence 図](/docs/sequence.md) +SLACK_BOT_ACCESS_TOKEN=xoxb-3814... +SLACK_SIGNING_SECRET=fb36... +CONTACT_CHANNEL=BN3... +NOTIFICATION_CHANNEL=O6C... +``` -## Setup +> ファイルを作成せずに [direnv](https://direnv.net/)などで環境変数にセットしても動作します ### ngrok @@ -74,7 +67,7 @@ ngrok はユーザー登録をしていると使い勝手が良くなるので #### 設定 [ngrok](https://ngrok.com/)に登録して,`Tunnel Authtoken` を取得します。 -それを後述する環境変数`NGROK_AUTH`にセットしてください。 +それを前述したように環境変数`NGROK_AUTH`にセットしてください。 ### AWS API Gateway @@ -88,7 +81,7 @@ API Gateway を利用するためには AWS アカウントと AWS へアクセ [AWS アクセスキーの作成方法](https://aws.amazon.com/jp/premiumsupport/knowledge-center/create-access-key/)に従い 新たにユーザー作成し,`アクセスキー ID`と`シークレットアクセスキー`を作成してください。 -それを後述する環境変数`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`にセットしてください。 +それをを前述したように環境変数`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`にセットしてください。 そのユーザーにはポリシー`AmazonAPIGatewayAdministrator`をアクセス権にアタッチしてください。 @@ -101,7 +94,7 @@ API Gateway を利用するためには AWS アカウントと AWS へアクセ Slack と連携し特定の Workspace に属する場合のみ LIVE Streaming 視聴を許可するように設定します。 その際,Slack App という枠組みを利用しています。新たに Slack App を作成し,それに対応するいくつかの ID やキーが必要です。 -また,Slash Commands やメッセージへのアクションを受け取るためには[slack 設定](slack/README.md)に従う必要があります。 +また,Slash Commands やメッセージへのアクションを受け取るために追加で[slack 追加設定](/docs/slack_appendix.md)に従う必要があります。 #### 設定 @@ -111,7 +104,8 @@ Bot User メニューにて Redirect URLs は `https://[RESOURCE_ID].execute-api.[REGION].amazonaws.com/prod/oauth-redirect`のみに設定し, Scopes に`identity.basic`を追加してください。 -作成した Slack App から以下の環境変数を設定してください。詳細は後述します。 +作成した Slack App から以下の環境変数を設定してください。 + どの部分から得るのかの対応を書いておきます。 - `SLACK_CLIENT_ID`: Basic Information > App Credentials > Client ID @@ -131,36 +125,7 @@ bushitsuchan-PC では slack で特定のワークスペースに属する場合 まず,そのワークスペースのサイトをブラウザで開きます。 URL が`https://app.slack.com/client/VYS39C27C/UC7CHE35J`のようになっているはずです。 この URL の`VYS39C27C`部分が必要な ID です。 -後述する環境変数`WORKSTATION_ID`にセットしてください。 - -### 環境変数 - -#### 説明 - -環境変数は独立したアプリケーション間で共通の値を参照できるもので,通常は不変な ID やパスワードを設定します。 - -#### 設定 - -`.env`ファイルに以下の様に書き保存してください。 - -```text -AWS_REST_API_ID=j3i... # 二回目以降に必要 -AWS_ACCESS_KEY_ID=FUB... -AWS_SECRET_ACCESS_KEY=vKw... - -NGROK_AUTH=8HU... - -SESSION_SECRET=presetprivatekey # 暗に暗号化へ使う任意の頑強な文字列 - -SLACK_CLIENT_ID=179... -SLACK_CLIENT_SECRET=38b... -WORKSTATION_ID=VOW38CP2D - -SLACK_BOT_ACCESS_TOKEN=xoxb-3814... -SLACK_SIGNING_SECRET=fb36... -``` - -> ファイルを作成せずに [direnv](https://direnv.net/)などで環境変数に代入しても動作します +これを前述したように環境変数`WORKSTATION_ID`にセットしてください。 ## Requirement @@ -194,6 +159,23 @@ Forwarding https://[AWS_REST_API_ID].execute-api.[AWS_REGION].amazonaws.com/pro すると,初回実行時(過去に Slack で認証をしていなければ) Slack の認証ページへリダイレクトされます。 Sign in すると自動的に配信再生ページへ移動します。 -## for Developer +### slack + +設定した Workspace 内で`/bushitsu-photo`コマンドを任意の場所で送信すると,現在の現在の部室の様子が投稿されます。 +また,環境変数`NOTIFICATION_CHANNEL`にセットしたチャンネルに部室を物体検出した結果が随時投稿されます。 + +## For Developer + +[developer](docs/developer.md)に詳細が記されています。 + +## Support + +以下の OS をサポートします。 + +- Ubuntu 18.04 +- macOS 10.14 (Debug mode のみ) -[developer](docs/developer.md)を参照してください。 +Debug mode 下では挙動に以下の差異があります。 + +- ストリーミング映像がカメラからではなく任意の動画ファイルから取得される +- Time zone の設定がされず時刻がずれる diff --git a/docs/container.md b/docs/container.md new file mode 100644 index 0000000..6865a81 --- /dev/null +++ b/docs/container.md @@ -0,0 +1,35 @@ +# Container + +bushitsuchan-PC における container の一覧と用途を記します。 + +## streaming-server + +同時に複数のプロセスがカメラにアクセスすることができないためこの container で映像を管理し,複数のプロセスへとカメラ画像を受け渡します。 + +## streamer + +**streaming-server** へと実際にカメラ画像をストリーミングします。遅延を減らすための圧縮や codec の変換も行います。 + +## media + +各 container が必要とするカメラ画像や映像を **streaming-server** から代理で取り出します。また取り出す際のさらなる変換も行います。 + +## reverse-proxy + +外部からのアクセスを URL 毎に **web** または **slack** へ振り分ける処理を行います。 + +## tunnel + +外部へ **reverse-proxy** サーバを公開する際の初期設定などの処理を行います。 + +## web + +ブラウザでウェブサイトへアクセスされた際の処理を行います。ログイン処理なども担います。 + +## slack + +Slack 上での slash command や action への応答を処理しています。 + +## redis + +データベースとして機能し,ログイン情報の保持や画像変換の待機管理を行います。 diff --git a/docs/slack_appendix.md b/docs/slack_appendix.md new file mode 100644 index 0000000..ce959c2 --- /dev/null +++ b/docs/slack_appendix.md @@ -0,0 +1,36 @@ +# slack + +## Slack bot + +### Setup + +[Slash Commands](https://api.slack.com/slash-commands)に従い Slack API ページにて以下のコマンドを追加してください。 + +Command: `/bushitsu-photo` +Request URL: `https://[AWS_REST_API_ID].execute-api.[AWS_REGION].amazonaws.com/prod/slack/bushitsu-photo` + +その際,Escape channels, users, and links sent to your app は有効に設定してください。 + +## Slack interactive message + +### Setup + +[Making messages interactive](https://api.slack.com/interactive-messages) に従い Request URL に`https://[AWS_REST_API_ID].execute-api.[AWS_REGION].amazonaws.com/prod/slack/actions/`を設定してください。 + +## Slack Message Channel + +[Slack Workspace](../README.md#Slack\ Workspace)で行った設定に似ています。 +いくつかの Channel ID の設定が必要です。 + +### Setup + +以下の環境変数をセットしてください。 +ここで挙げる環境変数には Channel ID をセットしてください。 + +- `CONTACT_CHANNEL`: bushitsuchan-PC に関する管理を行うチャンネル +- `NOTIFICATION_CHANNEL`: 物体検出の結果を投稿するチャンネル + +また,Channel ID は以下の手順で取得できます。 +まず,Slack の ID を知りたい Slack チャンネルをブラウザで開きます。 +URL が`https://app.slack.com/client/VYS39C27C/UC7CHE35J`のようになっているはずです。 +この URL の`UC7CHE35J`部分が Channel ID です。 diff --git a/slack/README.md b/slack/README.md deleted file mode 100644 index b483a67..0000000 --- a/slack/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# slack - -## Slack bot - -### Setup - -[Slash Commands](https://api.slack.com/slash-commands)に従い Slack API ページにて以下のコマンドを追加してください。 - -Command: `/bushitsu-photo` -Request URL: `https://[AWS_REST_API_ID].execute-api.[AWS_REGION].amazonaws.com/prod/slack/bushitsu-photo` - -その際,Escape channels, users, and links sent to your app は有効に設定してください。 - -## Slack interactive message - -### Setup - -[Making messages interactive](https://api.slack.com/interactive-messages) に従い Request URL に`https://[AWS_REST_API_ID].execute-api.[AWS_REGION].amazonaws.com/prod/slack/actions/`を設定してください。 From a908879bff5c2ee34bc0f78d8e27aa3884dbc9ca Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 5 Nov 2019 00:45:06 +0900 Subject: [PATCH 52/60] Tweak & format --- README.md | 6 +++--- docs/developer.md | 2 +- docs/sequence.md | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2a3b4b6..f843a99 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ bushitsuchan-PC は単一の Ubuntu PC 上で動作します。 bushitsuchan-PC では[Docker](https://www.docker.com/)というソフトフェアを活用しています。 Docker はコンテナ技術を体現したシステムの一つで,独立したサービス単位で環境それぞれを Container という形で OS レベルに分離させることができます。必要最低な構成を独立して扱うため再利用性が高まり,また分離しているため取り回しも良くなります。 -各 Container の説明は[ここ](/docs/container.md)に置かれています。 +各 Container の説明は[ここ](docs/container.md)に置かれています。 ### Design @@ -94,7 +94,7 @@ API Gateway を利用するためには AWS アカウントと AWS へアクセ Slack と連携し特定の Workspace に属する場合のみ LIVE Streaming 視聴を許可するように設定します。 その際,Slack App という枠組みを利用しています。新たに Slack App を作成し,それに対応するいくつかの ID やキーが必要です。 -また,Slash Commands やメッセージへのアクションを受け取るために追加で[slack 追加設定](/docs/slack_appendix.md)に従う必要があります。 +また,Slash Commands やメッセージへのアクションを受け取るために追加で[Slack 追加設定](/docs/slack_appendix.md)に従う必要があります。 #### 設定 @@ -166,7 +166,7 @@ Sign in すると自動的に配信再生ページへ移動します。 ## For Developer -[developer](docs/developer.md)に詳細が記されています。 +[ここ](docs/developer.md)に詳細が記されています。 ## Support diff --git a/docs/developer.md b/docs/developer.md index bd57b82..bc40959 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -1,4 +1,4 @@ -# bushitsuchan-PC +# bushitsuchan-PC for developer Developer 向けの情報を書き置きます。 diff --git a/docs/sequence.md b/docs/sequence.md index 6d209cf..e945149 100644 --- a/docs/sequence.md +++ b/docs/sequence.md @@ -1,4 +1,6 @@ -# シーケンス +# シーケンス図 + +水色の背景で囲われた部分は Docker 内であり,各 container がどのように通信して連携しているのかを図にしています。 ## Startup From 58ec739272ffb80b2c5d8306bad7407567235550 Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 5 Nov 2019 00:45:40 +0900 Subject: [PATCH 53/60] Update Sequence diagram --- docs/sequence.md | 22 ++++++++++------ docs/sequence/object-detecion.pu | 38 ++++++++++++++++++++++++++++ docs/sequence/slack_button.pu | 26 +------------------ docs/sequence/slack_slash_command.pu | 18 ++++++------- docs/sequence/startup.pu | 16 ++++++++---- docs/sequence/web.pu | 16 +++++++++--- 6 files changed, 85 insertions(+), 51 deletions(-) create mode 100644 docs/sequence/object-detecion.pu diff --git a/docs/sequence.md b/docs/sequence.md index e945149..518086b 100644 --- a/docs/sequence.md +++ b/docs/sequence.md @@ -4,9 +4,9 @@ ## Startup -![Startup image](http://www.plantuml.com/plantuml/png/SoWkIImgAStDKGW6Cmgual8h55BoaxDJYnIKVJBJCqgSSafJkGg0afd9cGM9UIKAkQafcOae8ah59KMfYRcPUUcwnQb5PQb5IYZI4DdK8XJ1ajAylDGShjIy50MWbLnSEVdv1LoSCAKAkdPOJBLIUDoqyt5pn-FcLO-Rzpnkdl-uUVFZfWqlMtkVx5y8CWfc3DY9sCrGm678q_xfG4DUB6jyjh69YnEBFbsWSH1phHI2KeiByejJuHOXP1utJttSjF1nqvB7pQkVJvd_h6C2n5qGxu9KvgKNvMS3LRvOiVRfkbbSO2xOS8WIe8o_Dx9wn_1WX6eW1qEj0z02O0no0G00) +![Startup image](http://www.plantuml.com/plantuml/png/VP71IiCm7CRF-pz5c5Vx0ZkCwLN1mmwUkovkjMbIqbIyha6SWY3eBYACmP2fE1HFYhA7oTREjp0nZ5aidjf_lj_tvUk_ZLYuN2GXGSsVbmXQx1YrcHTWZZPs_KvNR9C4GwH5t_CZbmhK9N5XhiQ2OpVqQSU9CJ_2l5gGhOfvyP2uNb1COQr3x0cdZOL--8mMKqH2AIQ0QHlfXW24iGWggspar4jgrD3NoSLyDZAkbKENBuTH3QdqJSc-aWzAVYWvLF9LfSysOddNorvIg9Ju7ATkLlA_trwy9kL0fIELZfLypA-7MV_IThHVQJZQuIpGv7Boj9ZUW1tDLHRHojxERtvhlxccpV271OuF4DELIrQzQNz83ULdz_FFgsnykpXzLxrfqvncvuDyCWDew8f9IE0R) -[作成ページ](http://www.plantuml.com/plantuml/uml/SoWkIImgAStDuKhAhr18oK_EJYrIKFR9JCyeSSefJUKg0Cfc9cSM9EQLAEIcfcGceeWe5PSKfIRcPkQbwnQd5fMb5YcXI4DaKujG14jAy_9ISxXIyr8KW5PoSUNavnTmSSAKAkZQOJ7LIk5nqyx7pHsFcrSzRjxpk7d-u-RDZvisl6pjVR9_8SWec35W9s8tGm678K_xfmCDUR6iyTd69YvEBFfqWSP1pBLI24ejBiWlJeLRX91vt3prSTF2nqrB7ZUlVZvb_hEE2H1tGRmBKfcNNfIV3LJvOiNQf-jcSO6vOCCXIe0o_jx8wXt3Wn6gWHmCjGv02u0n1m00?switch) +[作成ページ](http://www.plantuml.com/plantuml/uml/VP71IiCm7CRF-pz5c5Vx0ZkCwLN1mmwUkovkjMbIqbIyha6SWY3eBYACmP2fE1HFYhA7oTREjp0nZ5aidjf_lj_tvUk_ZLYuN2GXGSsVbmXQx1YrcHTWZZPs_KvNR9C4GwH5t_CZbmhK9N5XhiQ2OpVqQSU9CJ_2l5gGhOfvyP2uNb1COQr3x0cdZOL--8mMKqH2AIQ0QHlfXW24iGWggspar4jgrD3NoSLyDZAkbKENBuTH3QdqJSc-aWzAVYWvLF9LfSysOddNorvIg9Ju7ATkLlA_trwy9kL0fIELZfLypA-7MV_IThHVQJZQuIpGv7Boj9ZUW1tDLHRHojxERtvhlxccpV271OuF4DELIrQzQNz83ULdz_FFgsnykpXzLxrfqvncvuDyCWDew8f9IE0R) ## WEB @@ -18,20 +18,26 @@ ### general -![image](http://www.plantuml.com/plantuml/png/RP7HIZf15CQlFKznu7_xzmNc8iIGRhggeElH7MfndHLtf6v7Au8C8xGI2YEYD33ejgGUPXhNtgBZpWOkTRNmdVDzvxVV52B56wfP2t2xL0GeX_leXPMgQE2_TNzdLnM3fW2FArxcaS26yFm8wkJmAtwTIuKrKdX6sHDb4D93YeBCO3FWbMf6MGry8HM0-s9-PM56XckbBG0UA9m_dSv7qrdxqDw-6DsntNkZ3o17MxJiQ1Ygi2gaxLxOzql8oL0HveASfV56Ftv-tDZ9bT5zq-eO_K0PHWzDQsBQKzCwjyVZk3S2o2Lvc7SO33T4L0zb97xkkHzWE1kDlmPdyTqhqP4hKVzmKGS0pkbQOcXF-d7lxJ_Qeq5yFJJwEQLEnajx6VbtiaibEUrjQLIWg_IOy0q0) +![image](http://www.plantuml.com/plantuml/png/RL91Im9163tx_OeFk-OVs4E88LqwLT1vT0TTN7TbTwIkenL1XX5Q2OKHKHeOT2sf7pEDQ_-YJzSLL_OqxFVU-zvxCvlr1VD4lMhZOJu7K72FqNIB5UxXngvLAekSNUTWCi4ApEVeSTFoeKOAgsZLc2EmRCU_qrQLbNZ65wv7Ppg67V42SCT4Ce4Oi6-pOYKssROjxWY0yCJCraoC1kxa3m2OBN3wTZaTZ2VDK_tueMHBjv-LF84KiOWSvZHGk1NkwFQD_hw5bECAAZ3hP2pMA_dw-_EWHtTATbMZfUGBxL2ohneZrHohnhK-7mQT0K1glWypOGm3zxXVSnsVHtvX0GCdW-5Vxofu-gHqf9fF4rHq1s69eFEbc-reo_hT6QWlkaJPH7tM2-xxIhv7NTQOoU9aRb8Us-SBhsKMUjV8VyMNfaimDalk23IROujdNC6pHA2_3lu1) -[作成ページ](http://www.plantuml.com/plantuml/uml/RP7HIZf15CQlFKznu7_xzmNc8iIGRhggeElH7MfndHLtf6v7Au8C8xGI2YEYD33ejgGUPXhNtgBZpWOkTRNmdVDzvxVV52B56wfP2t2xL0GeX_leXPMgQE2_TNzdLnM3fW2FArxcaS26yFm8wkJmAtwTIuKrKdX6sHDb4D93YeBCO3FWbMf6MGry8HM0-s9-PM56XckbBG0UA9m_dSv7qrdxqDw-6DsntNkZ3o17MxJiQ1Ygi2gaxLxOzql8oL0HveASfV56Ftv-tDZ9bT5zq-eO_K0PHWzDQsBQKzCwjyVZk3S2o2Lvc7SO33T4L0zb97xkkHzWE1kDlmPdyTqhqP4hKVzmKGS0pkbQOcXF-d7lxJ_Qeq5yFJJwEQLEnajx6VbtiaibEUrjQLIWg_IOy0q0) +[作成ページ](http://www.plantuml.com/plantuml/uml/RL91Im9163tx_OeFk-OVs4E88LqwLT1vT0TTN7TbTwIkenL1XX5Q2OKHKHeOT2sf7pEDQ_-YJzSLL_OqxFVU-zvxCvlr1VD4lMhZOJu7K72FqNIB5UxXngvLAekSNUTWCi4ApEVeSTFoeKOAgsZLc2EmRCU_qrQLbNZ65wv7Ppg67V42SCT4Ce4Oi6-pOYKssROjxWY0yCJCraoC1kxa3m2OBN3wTZaTZ2VDK_tueMHBjv-LF84KiOWSvZHGk1NkwFQD_hw5bECAAZ3hP2pMA_dw-_EWHtTATbMZfUGBxL2ohneZrHohnhK-7mQT0K1glWypOGm3zxXVSnsVHtvX0GCdW-5Vxofu-gHqf9fF4rHq1s69eFEbc-reo_hT6QWlkaJPH7tM2-xxIhv7NTQOoU9aRb8Us-SBhsKMUjV8VyMNfaimDalk23IROujdNC6pHA2_3lu1) ## Slack ### slash command -![image](http://www.plantuml.com/plantuml/png/TL51I_D05BplhtZqE_SF15BAfoAYK36zbvWiRMYoATbKFDe4HBq4HAsYKYf5YY0edhHYVimsJVqNfcwoDCIU7hnvRsQOgL9NTTokPO9YgbgxGKsLjXgQRLagqT6-VGYwhRMn0_zsZ6RB_MzsCUea7uPcT5JYGecw3bOjWpJB53i7s2dbO0lhXfhRq8KCmaI7X1mjGzn1RhDc6fYu2F49vGg_0ManQGiodtoRm3I5TsjA7I7ArqjlUvXsR48nKWIKSaimdpny7_N4LuMRbo2-c4H-48rEPy7j_B4tU_NGBmBbJ32xsLfdthcGo7WKVZ8xkup7eH0MhxLjbF5L_eXJ0kQzC_-4-K_C_sJ-WFblp7k9Wluq7APsYb-9WF0l3AKg0eYER-AxmJIyZvwl4P9bc0_7yUY3UI7pHa89PBbGW9IUSlr2c4kQ2MqQpYfomIqIsToehoWX5t-XeU0g-keNkyaLii9c5HEzQvde1m00) +![image](http://www.plantuml.com/plantuml/png/L8xFoi903CJlUOhGxzmN-0uYUXKKwxt4RMYNxf-oISN7TyjMQKy3yyjavYXAIMVli75anbOSoT2Qw3s53fxnZLqq8oVykzX-q9ER6QQSiCPE51GhqSJaRUXhuVJYLEsnzTHpBHfJrZsJfH0uT9XhO8lAbfrpTfQ30XJ5-b1ky7zH6V2xkBWPouflr-O18CNUnEuiKmp2qFpG-lipAuKNknUzR6Y4wx93zuQLmlCfkvyszpzTqlciV_QBPOtFDZPneQbHq8Kv0gRQq-LnqoIOjN2pWo5AddLDVRvYFymn2At-tboO9jjX2NOhXSTDEnytTpnkNlMuUS_ZvlcFcpS_Rjhmj7_wa_qBeKx4rAMWYyrtS4TYseof-6dRpETpvZ_PF_VfsXbSNBQs2YyMhdY-PDVZflsFcvR0tQ5WQuiHULPGfH3NOKG4mXqWOw61YCjmcDc8a7Dt3I4OWTYZ3b-CzqzxkcywlhX6H31kxpW04pqmot410000) -[作成ページ](http://www.plantuml.com/plantuml/uml/TL51I_D05BplhtZqE_SF15BAfoAYK36zbvWiRMYoATbKFDe4HBq4HAsYKYf5YY0edhHYVimsJVqNfcwoDCIU7hnvRsQOgL9NTTokPO9YgbgxGKsLjXgQRLagqT6-VGYwhRMn0_zsZ6RB_MzsCUea7uPcT5JYGecw3bOjWpJB53i7s2dbO0lhXfhRq8KCmaI7X1mjGzn1RhDc6fYu2F49vGg_0ManQGiodtoRm3I5TsjA7I7ArqjlUvXsR48nKWIKSaimdpny7_N4LuMRbo2-c4H-48rEPy7j_B4tU_NGBmBbJ32xsLfdthcGo7WKVZ8xkup7eH0MhxLjbF5L_eXJ0kQzC_-4-K_C_sJ-WFblp7k9Wluq7APsYb-9WF0l3AKg0eYER-AxmJIyZvwl4P9bc0_7yUY3UI7pHa89PBbGW9IUSlr2c4kQ2MqQpYfomIqIsToehoWX5t-XeU0g-keNkyaLii9c5HEzQvde1m00) +[作成ページ](http://www.plantuml.com/plantuml/uml/L8xFoi903CJlUOhGxzmN-0uYUXKKwxt4RMYNxf-oISN7TyjMQKy3yyjavYXAIMVli75anbOSoT2Qw3s53fxnZLqq8oVykzX-q9ER6QQSiCPE51GhqSJaRUXhuVJYLEsnzTHpBHfJrZsJfH0uT9XhO8lAbfrpTfQ30XJ5-b1ky7zH6V2xkBWPouflr-O18CNUnEuiKmp2qFpG-lipAuKNknUzR6Y4wx93zuQLmlCfkvyszpzTqlciV_QBPOtFDZPneQbHq8Kv0gRQq-LnqoIOjN2pWo5AddLDVRvYFymn2At-tboO9jjX2NOhXSTDEnytTpnkNlMuUS_ZvlcFcpS_Rjhmj7_wa_qBeKx4rAMWYyrtS4TYseof-6dRpETpvZ_PF_VfsXbSNBQs2YyMhdY-PDVZflsFcvR0tQ5WQuiHULPGfH3NOKG4mXqWOw61YCjmcDc8a7Dt3I4OWTYZ3b-CzqzxkcywlhX6H31kxpW04pqmot410000) ### button action -![image](http://www.plantuml.com/plantuml/png/TL7TQXD15BxEUOf3lSuBBAIKgeWeL4plPPCCSSd-X9s9UDcT5Mch497M6bH29TIe28fNsc8UvdIpwLiukpCT4hQv6ZZdpFVpVLjSkB4O13usVRVTUz8Q2165q8gUOoTgzrYCjnvwtQTYsnymwAjJh-trtL3W1XSnSmClxDOvYv-nU6Db7R2EvwvCU84FBEoW0eVbbQPUcTpsFHOA0FrYVLFVEBXTwYFvTdvuGSa8od6nvth_QAUv2y3rzFeRElYOyNuKSWPDkpBO3YxEFr_j9G2kBp0_Ei_IeSBFtdmdkHSmpjqkA_cEy-bCKP9y1JLkQBLFntpB9WVpuOV5MJB_9Q4MHe9XN8Jd62vAlbpEFcK_tbDoJF8r9MUKlA1aBA8U2mlE_Q_vqHG04JKmrgqpGt7_ZhgpPg1cpZPlwCD1adyetQVq6wKNb8uf_KtoPpOykPoTNekiVbESrfOYYhmMPykAx39xESe_ZhMXebSRkorBPnR5sS7XrMXYexUMTXu0D1guE9tcaxyaPoGdLYOs6jNwpQaMNwbogMK5Qm9R1swnhPfxTtVXvbuDNpchbZvyb_qxWKfVLWjVBtDBnJO8VFWF) +![image](http://www.plantuml.com/plantuml/png/SoWkIImgAStDKGZEIKpEZaygBId9p-DAogzGICbFpaujKb3soKpFA77AAKtbAW0gpKpEB4ZCAr5GAYufIatCpSnBrorEBIfBBL92aIu6cSQLcfUY03IA2raAOX6AY7DEPcfU2HSNX5RGjOEeiL9m0hlcSTEaPrrx7ZVEv08BW-IB8V81_i4XN5p5456ODWKhXQ3KueBylE9Khc2O5DGEeDoBtOjUDZJ2T27iUjhPzNBc4fWEX1t-tbmEG7y0WuWB0000) -[作成ページ](http://www.plantuml.com/plantuml/uml/TL7TQXD15BxEUOf3lSuBBAIKgeWeL4plPPCCSSd-X9s9UDcT5Mch497M6bH29TIe28fNsc8UvdIpwLiukpCT4hQv6ZZdpFVpVLjSkB4O13usVRVTUz8Q2165q8gUOoTgzrYCjnvwtQTYsnymwAjJh-trtL3W1XSnSmClxDOvYv-nU6Db7R2EvwvCU84FBEoW0eVbbQPUcTpsFHOA0FrYVLFVEBXTwYFvTdvuGSa8od6nvth_QAUv2y3rzFeRElYOyNuKSWPDkpBO3YxEFr_j9G2kBp0_Ei_IeSBFtdmdkHSmpjqkA_cEy-bCKP9y1JLkQBLFntpB9WVpuOV5MJB_9Q4MHe9XN8Jd62vAlbpEFcK_tbDoJF8r9MUKlA1aBA8U2mlE_Q_vqHG04JKmrgqpGt7_ZhgpPg1cpZPlwCD1adyetQVq6wKNb8uf_KtoPpOykPoTNekiVbESrfOYYhmMPykAx39xESe_ZhMXebSRkorBPnR5sS7XrMXYexUMTXu0D1guE9tcaxyaPoGdLYOs6jNwpQaMNwbogMK5Qm9R1swnhPfxTtVXvbuDNpchbZvyb_qxWKfVLWjVBtDBnJO8VFWF) +[作成ページ](http://www.plantuml.com/plantuml/uml/SoWkIImgAStDKGZEIKpEZaygBId9p-DAogzGICbFpaujKb3soKpFA77AAKtbAW0gpKpEB4ZCAr5GAYufIatCpSnBrorEBIfBBL92aIu6cSQLcfUY03IA2raAOX6AY7DEPcfU2HSNX5RGjOEeiL9m0hlcSTEaPrrx7ZVEv08BW-IB8V81_i4XN5p5456ODWKhXQ3KueBylE9Khc2O5DGEeDoBtOjUDZJ2T27iUjhPzNBc4fWEX1t-tbmEG7y0WuWB0000) + +### Object-detection + +![image](http://www.plantuml.com/plantuml/png/P8v13W8n203ll8Aiv_x1wDMR3p3TBbbnkz1GQdo-rLkLooGC2NEi7itRdl6QOzfkStDNWLbVk6ZQoF1muVNkfzm8IZ_bn2MAurJTAEuiQwXaJx9fr3e_A7bOo3jOvKVp7bSArTKwHrS_8K2oOA-0GNqRXyqvCua3PDK2sEV_COPt9UMJqZ0GXV7zd68ke0SOYBWH5ougfbVemeqLuW6S6KGhICG_Tc5H0a6hWYWYQAlcCAypQMzXXXSdCEa4kyxt_TxxldbanPr76Sqlnah68CwcTro_2kDrL6XqOnelY4-GHo0VGNw1l0Nv1k9bTd0ooPAADi-wL5-b6JTlBQJKOzfC_4cbFHrV0-zlTQBTxaxKyLVZ8VKU9j_dEXsemz7_QoryxwVwPl2tn_DcAsml487HreP_6Xu6PJGqXxctlDq5VWyo0Ib1Z4rtucEspylMKEtl2YUXoi334ku0zV5bFioCr2WGY2Pac3ib90ZeD1dcwGX41YArZqY3W10yKJk3bTBoKYegwXYrRsQmMAKNNh4ZPA-ljOdDL7yUfE5avsk3GSLNwgTVDzYnrSwHFyvgKLNneo6_) + +[作成ページ](http://www.plantuml.com/plantuml/uml/P8v13W8n203ll8Aiv_x1wDMR3p3TBbbnkz1GQdo-rLkLooGC2NEi7itRdl6QOzfkStDNWLbVk6ZQoF1muVNkfzm8IZ_bn2MAurJTAEuiQwXaJx9fr3e_A7bOo3jOvKVp7bSArTKwHrS_8K2oOA-0GNqRXyqvCua3PDK2sEV_COPt9UMJqZ0GXV7zd68ke0SOYBWH5ougfbVemeqLuW6S6KGhICG_Tc5H0a6hWYWYQAlcCAypQMzXXXSdCEa4kyxt_TxxldbanPr76Sqlnah68CwcTro_2kDrL6XqOnelY4-GHo0VGNw1l0Nv1k9bTd0ooPAADi-wL5-b6JTlBQJKOzfC_4cbFHrV0-zlTQBTxaxKyLVZ8VKU9j_dEXsemz7_QoryxwVwPl2tn_DcAsml487HreP_6Xu6PJGqXxctlDq5VWyo0Ib1Z4rtucEspylMKEtl2YUXoi334ku0zV5bFioCr2WGY2Pac3ib90ZeD1dcwGX41YArZqY3W10yKJk3bTBoKYegwXYrRsQmMAKNNh4ZPA-ljOdDL7yUfE5avsk3GSLNwgTVDzYnrSwHFyvgKLNneo6_) diff --git a/docs/sequence/object-detecion.pu b/docs/sequence/object-detecion.pu new file mode 100644 index 0000000..80ba6a3 --- /dev/null +++ b/docs/sequence/object-detecion.pu @@ -0,0 +1,38 @@ +@startuml Slack_button +box docker #LightBlue +participant "streaming-server" +participant "object-detection" +participant "image-storage" +participant slack +end box + +participant Slack +participant Client + +loop + "object-detection" -> "image-storage" : 画像を要求 + "image-storage" -> "streaming-server" : ストリーミング配信要求 + "streaming-server" --> "image-storage" : ストリーミング配信 + "image-storage" --> "object-detection" : 画像に変換しResponse + "object-detection" -> "object-detection" : 物体検出 + "object-detection" -> "image-storage": 結果画像のPOST + "image-storage" --> "object-detection": OK + "object-detection" -> slack : Socket.ioでメッセージ送信 + slack --> "object-detection" : OK + slack -> Slack : メッセージ投稿 + Slack --> slack : OK + +end + +== 表示タイミング == + +Client -> Slack: 表示要求 +Slack --> Client: Response + +== 画像表示タイミング == +Client -> slack: GET +slack -> "image-storage": 画像要求 +"image-storage" -> "image-storage": 画像取得 +"image-storage" --> slack: Response +slack --> Client: Response +@enduml diff --git a/docs/sequence/slack_button.pu b/docs/sequence/slack_button.pu index 00bc834..9c7be27 100644 --- a/docs/sequence/slack_button.pu +++ b/docs/sequence/slack_button.pu @@ -1,7 +1,6 @@ @startuml Slack_button box docker #LightBlue participant "streaming-server" -participant media participant slack end box @@ -14,29 +13,6 @@ Slack -> slack: POST slack --> Slack : Response Slack --> Client : 転送 -alt 画像を含むmessageを投稿する - slack -> media: 画像変換要求 - note right: Clientで保存されていたtokenを利用 - - media --> slack: 画像IDをResponse - - media -> "streaming-server": ストリーミング受信要求 - "streaming-server" --> media: Resoibse - media -> media: 写真保存 -end - -slack -> Slack: 投稿or削除 +slack -> Slack: 削除 Slack --> slack: OK - -== 表示タイミング == - -Client -> Slack: 表示要求 -Slack --> Client: Response - -== 画像表示タイミング == -Client -> slack: GET -slack -> media: 画像要求 -media -> media: 画像取得 -media --> slack: Response -slack --> Client: Response @enduml diff --git a/docs/sequence/slack_slash_command.pu b/docs/sequence/slack_slash_command.pu index 5473225..2243650 100644 --- a/docs/sequence/slack_slash_command.pu +++ b/docs/sequence/slack_slash_command.pu @@ -1,7 +1,7 @@ @startuml Slack_slash_command box docker #LightBlue participant "streaming-server" -participant media +participant "image-storage" participant slack end box @@ -14,14 +14,14 @@ Slack -> slack : POST slack --> Slack : Response Slack --> Client : 転送 -slack -> media: 画像変換要求 -media --> slack: 画像IDをResponse +slack -> "image-storage": 画像変換要求 +"image-storage" --> slack: 画像IDをResponse slack ->Slack: 投稿 Slack --> slack: OK -media -> "streaming-server": ストリーミング受信要求 -"streaming-server" --> media: Response -media -> media: 写真保存 +"image-storage" -> "streaming-server": ストリーミング受信要求 +"streaming-server" --> "image-storage": Response +"image-storage" -> "image-storage": 写真保存 == 表示タイミング == @@ -30,8 +30,8 @@ Slack --> Client: Response == 画像表示タイミング == Client -> slack: GET -slack -> media: 画像要求 -media -> media: 画像取得 -media --> slack: Response +slack -> "image-storage": 画像要求 +"image-storage" -> "image-storage": 画像取得 +"image-storage" --> slack: Response slack --> Client: Response @enduml diff --git a/docs/sequence/startup.pu b/docs/sequence/startup.pu index 6404649..67857c9 100644 --- a/docs/sequence/startup.pu +++ b/docs/sequence/startup.pu @@ -1,19 +1,21 @@ @startuml Startup box docker #LightBlue -participant media +participant hls participant "streaming-server" participant streamer +participant slack +participant "object-detection" participant tunnel end box loop - streamer -> "streaming-server": ストリーミング配信 + streamer -> "streaming-server": 配信 end loop - media -> "streaming-server" : ストリーミング受信要求 - "streaming-server" --> media : Respose - media -> media : ファイル生成 + hls -> "streaming-server" : ストリーミング配信要求 + "streaming-server" --> hls : ストリーミング配信 + hls -> hls : ファイル生成 end tunnel -> ngrok : 設定 @@ -21,4 +23,8 @@ ngrok --> tunnel : OK tunnel -> AWS : 設定 AWS --> tunnel : OK + + +ref over "object-detection", slack: 物体検出のSlack投稿 + @enduml diff --git a/docs/sequence/web.pu b/docs/sequence/web.pu index f9b6a41..2e21106 100644 --- a/docs/sequence/web.pu +++ b/docs/sequence/web.pu @@ -2,7 +2,8 @@ box docker #LightBlue database redis -participant media +participant hls +participant "image-storage" participant web end box @@ -21,9 +22,16 @@ alt 認証情報が古い Slack --> web: Response end -web -> media: 動画, 写真の取得 -media -> media: 取得 -media --> web: Response +alt 画像 + web -> "image-storage": 動画, 写真の取得 + "image-storage" -> "image-storage": 取得 + "image-storage" --> web: Response +else 動画 + web -> hls: 動画の取得 + hls -> hls: 取得 + hls --> web: Response +end + web --> Client : Response @enduml From 5177a86a882aeddfdee3490460af97caa6dc85b1 Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 5 Nov 2019 01:00:33 +0900 Subject: [PATCH 54/60] Remove unnecessary args --- docker-compose.debug.yml | 1 - docker-compose.prod.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/docker-compose.debug.yml b/docker-compose.debug.yml index f41bbe8..8e5e972 100644 --- a/docker-compose.debug.yml +++ b/docker-compose.debug.yml @@ -110,7 +110,6 @@ services: - CONTACT_CHANNEL=${CONTACT_CHANNEL} - SESSION_SECRET=${SESSION_SECRET} - NOTIFICATION_CHANNEL=${NOTIFICATION_CHANNEL} - - NOTIFICATION_INTERVAL=${NOTIFICATION_INTERVAL} volumes: - ./slack/src:/app ports: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 626fb08..0c39fa7 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -108,7 +108,6 @@ services: - CONTACT_CHANNEL=${CONTACT_CHANNEL} - SESSION_SECRET=${SESSION_SECRET} - NOTIFICATION_CHANNEL=${NOTIFICATION_CHANNEL} - - NOTIFICATION_INTERVAL=${NOTIFICATION_INTERVAL} volumes: - ./slack/src:/app - /etc/localtime:/etc/localtime:ro From 2ba756a019367689c902efd58f03c41629806d3e Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 5 Nov 2019 01:34:07 +0900 Subject: [PATCH 55/60] Format --- image-storage/src/main.js | 50 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/image-storage/src/main.js b/image-storage/src/main.js index bac660c..b6abbb6 100644 --- a/image-storage/src/main.js +++ b/image-storage/src/main.js @@ -48,31 +48,31 @@ app.get('/temporary', async (req, res) => { app.post('/temporary', upload.single('file'), (req, res) => { - const retentionTime = Number(req.body.retention_time); - const { buffer, mimetype } = req.file; - if (retentionTime === undefined || buffer === undefined || !(retentionTime > 0)) { - res.sendStatus(400); - return; - } - const id = Date.now(); - imageBuffers[id] = { - mimetype, - buffer, - }; - wait(retentionTime).then(() => { delete imageBuffers[id]; }); - res.status(201).json({ id }); - }); - - - app.get('/temporary/:id', (req, res) => { - const { id } = req.params; - if (!(id in imageBuffers)) { - res.sendStatus(404); - return; - } - const { mimetype, buffer } = imageBuffers[id]; - res.contentType(mimetype).end(buffer); - }); + const retentionTime = Number(req.body.retention_time); + const { buffer, mimetype } = req.file; + if (retentionTime === undefined || buffer === undefined || !(retentionTime > 0)) { + res.sendStatus(400); + return; + } + const id = Date.now(); + imageBuffers[id] = { + mimetype, + buffer, + }; + wait(retentionTime).then(() => { delete imageBuffers[id]; }); + res.status(201).json({ id }); +}); + + +app.get('/temporary/:id', (req, res) => { + const { id } = req.params; + if (!(id in imageBuffers)) { + res.sendStatus(404); + return; + } + const { mimetype, buffer } = imageBuffers[id]; + res.contentType(mimetype).end(buffer); +}); app.get('/permament', async (req, res) => { const { directory } = req.query; From 38235b212354eb7113361217d1dd5ce0218ac380 Mon Sep 17 00:00:00 2001 From: ilim Date: Tue, 5 Nov 2019 02:02:52 +0900 Subject: [PATCH 56/60] Install only necessary OpenVINO components --- object-detection/Dockerfile | 1 + object-detection/src/get_model.sh | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/object-detection/Dockerfile b/object-detection/Dockerfile index 2f13824..8fb74d1 100644 --- a/object-detection/Dockerfile +++ b/object-detection/Dockerfile @@ -16,6 +16,7 @@ RUN mkdir -p $TEMP_DIR && \ wget -c $DOWNLOAD_LINK && \ tar xf l_openvino_toolkit*.tgz && \ cd l_openvino_toolkit* && \ + sed -i 's/COMPONENTS=DEFAULTS/COMPONENTS=intel-openvino-ie-sdk-ubuntu-bionic__x86_64;intel-openvino-ie-rt-cpu-ubuntu-bionic__x86_64;intel-openvino-ie-rt-vpu-ubuntu-bionic__x86_64;intel-openvino-model-optimizer__x86_64/g' silent.cfg && \ sed -i 's/decline/accept/g' silent.cfg && \ sed -i 's/#INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/INTEL_SW_IMPROVEMENT_PROGRAM_CONSENT=no/g' silent.cfg && \ ./install.sh -s silent.cfg && \ diff --git a/object-detection/src/get_model.sh b/object-detection/src/get_model.sh index defbdaf..c28d425 100644 --- a/object-detection/src/get_model.sh +++ b/object-detection/src/get_model.sh @@ -1,9 +1,9 @@ -python /opt/intel/openvino/deployment_tools/tools/model_downloader/downloader.py \ +python /opt/intel/openvino/deployment_tools/open_model_zoo/tools/downloader/downloader.py \ --name $1 \ --cache_dir ./.cache \ --output_dir ./models -python /opt/intel/openvino/deployment_tools/tools/model_downloader/converter.py \ +python /opt/intel/openvino/deployment_tools/open_model_zoo/tools/downloader/converter.py \ --name $1 \ --precisions=FP16 \ --mo /opt/intel/openvino/deployment_tools/model_optimizer/mo.py \ From 949692f7b2ef3683974f7c5a2fc8d1dbf59ca358 Mon Sep 17 00:00:00 2001 From: ilim Date: Thu, 7 Nov 2019 14:47:23 +0900 Subject: [PATCH 57/60] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f843a99..9517347 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ bushitsuchan-PC を動作させるための設定を各部分ごとに説明し 最終的に`.env`ファイルに以下の様に書き保存してください。 各変数へと何をセットすれば良いのかはこれから説明します。 -```text +```text= AWS_REST_API_ID=j3i... # 二回目以降に必要 AWS_ACCESS_KEY_ID=FUB... AWS_SECRET_ACCESS_KEY=vKw... From bcf211cedadf86d72a23d4b5cc56520c479dbb19 Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 13 Nov 2019 12:33:12 +0900 Subject: [PATCH 58/60] Add missing classes --- object-detection/src/labels.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/object-detection/src/labels.json b/object-detection/src/labels.json index 41bf507..4067c0a 100644 --- a/object-detection/src/labels.json +++ b/object-detection/src/labels.json @@ -88,5 +88,7 @@ "vase", "scissors", "teddy bear", - "hair drier" + "hair drier", + "toothbrush", + "hair brush" ] From f606afaa70d88f6ad294cfef885d16c90da5048f Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 13 Nov 2019 12:35:35 +0900 Subject: [PATCH 59/60] Typo --- image-storage/src/main.js | 4 ++-- slack/src/main.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/image-storage/src/main.js b/image-storage/src/main.js index b6abbb6..5149120 100644 --- a/image-storage/src/main.js +++ b/image-storage/src/main.js @@ -74,7 +74,7 @@ app.get('/temporary/:id', (req, res) => { res.contentType(mimetype).end(buffer); }); -app.get('/permament', async (req, res) => { +app.get('/permanent', async (req, res) => { const { directory } = req.query; if (directory === undefined) { res.sendStatus(400); @@ -102,7 +102,7 @@ app.get('/permament', async (req, res) => { res.json({ filename }); }); -app.get('/permament/:directory(\\w+)/:file', async (req, res) => { +app.get('/permanent/:directory(\\w+)/:file', async (req, res) => { const { directory, file } = req.params; const path = `${directory}/${file}`; diff --git a/slack/src/main.js b/slack/src/main.js index ab24337..1306a8c 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -70,7 +70,7 @@ slackInteractions.action({ type: 'button' }, (payload, respond) => { // Slash command app.post('/bushitsu-photo', async (req, res) => { - const { filename } = await axios.get('http://image-storage/permament', { params: { directory: 'slack' } }).then((result) => result.data); + const { filename } = await axios.get('http://image-storage/permanent', { params: { directory: 'slack' } }).then((result) => result.data); res.status(200).end(); const key = crypto .createHash('md5') @@ -117,7 +117,7 @@ app.get(['/photo/:filename', '/detected-photo/:filename'], async (req, res, next }); app.get('/photo/:filename', async (req, res) => { - const img = await axios.get(`http://image-storage/permament/slack/${req.params.filename}`, { + const img = await axios.get(`http://image-storage/permanent/slack/${req.params.filename}`, { responseType: 'arraybuffer', headers: { 'Content-Type': 'image/jpg' }, }); From cccfa42e16a84071b1e10f2fa559aecc8104bce3 Mon Sep 17 00:00:00 2001 From: ilim Date: Wed, 13 Nov 2019 12:55:11 +0900 Subject: [PATCH 60/60] Update catch clause --- slack/src/main.js | 26 ++++++++++++++++-------- slack/src/object_detection.js | 7 +++++-- web/src/main.js | 38 +++++++++++++++++++---------------- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/slack/src/main.js b/slack/src/main.js index 1306a8c..412d51d 100644 --- a/slack/src/main.js +++ b/slack/src/main.js @@ -70,14 +70,19 @@ slackInteractions.action({ type: 'button' }, (payload, respond) => { // Slash command app.post('/bushitsu-photo', async (req, res) => { - const { filename } = await axios.get('http://image-storage/permanent', { params: { directory: 'slack' } }).then((result) => result.data); + const { filename } = await axios.get('http://image-storage/permanent', { params: { directory: 'slack' } }) + .then((result) => result.data) + .catch((err) => console.error('Failed to permanent image acquisition request for image-storage.:\n', err)); res.status(200).end(); const key = crypto .createHash('md5') .update(`${filename}-${process.env.SESSION_SECRET}`, 'utf8') .digest('Base64'); - const { awsUrl } = await axios.get('http://tunnel').then((result) => result.data); + const { awsUrl } = await axios.get('http://tunnel') + .then((result) => result.data) + .catch((err) => console.error('Failed to fetch AWS URL from tunnel.:\n', err)); + const blocks = object( JSON.parse(fs.readFileSync('./block_template.json', 'utf8')), { @@ -117,18 +122,23 @@ app.get(['/photo/:filename', '/detected-photo/:filename'], async (req, res, next }); app.get('/photo/:filename', async (req, res) => { - const img = await axios.get(`http://image-storage/permanent/slack/${req.params.filename}`, { + const image = await axios.get(`http://image-storage/permanent/slack/${req.params.filename}`, { responseType: 'arraybuffer', headers: { 'Content-Type': 'image/jpg' }, - }); - res.type('image/jpg').send(img.data).end(); + }) + .then((result) => result.data) + .catch((err) => console.error('Failed to get permanent image from image-storage.:\n', err)); + + res.type('image/jpg').send(image).end(); }); app.get('/detected-photo/:filename', async (req, res) => { - const img = await axios.get(`http://image-storage/temporary/${req.params.filename}`, { + const image = await axios.get(`http://image-storage/temporary/${req.params.filename}`, { responseType: 'arraybuffer', headers: { 'Content-Type': 'image/jpg' }, - }); - res.type('image/jpg').send(img.data).end(); + }) + .then((result) => result.data) + .catch((err) => console.error('Failed to get temporary image from image-storage.:\n', err)); + res.type('image/jpg').send(image).end(); }); diff --git a/slack/src/object_detection.js b/slack/src/object_detection.js index dca931a..30960ad 100644 --- a/slack/src/object_detection.js +++ b/slack/src/object_detection.js @@ -18,7 +18,7 @@ const web = new WebClient(process.env.SLACK_BOT_ACCESS_TOKEN); const rtm = new RTMClient(process.env.SLACK_BOT_ACCESS_TOKEN); rtm.start() .then('start rtmp client') - .catch(console.error); + .catch((err) => console.error('Failed to start RTMP client.:\n', err)); rtm.on('message', (event) => { if (event.subtype === undefined) { @@ -85,7 +85,10 @@ module.exports = (path = '/socket.io') => { }); io.on('connection', async (socket) => { - const { awsUrl } = await axios.get('http://tunnel').then((result) => result.data); + const { awsUrl } = await axios.get('http://tunnel') + .then((result) => result.data) + .catch((err) => console.error('Failed to fetch AWS URL from tunnel.:\n', err)); + socket.on('prediction', (prediction) => { objectsNotification(prediction, awsUrl); }); diff --git a/web/src/main.js b/web/src/main.js index 3c5b19b..66997d2 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -111,14 +111,16 @@ app.get('/oauth-redirect', (req, res) => { .then((token) => { req.session.token = token; req.session.lastAuthedTime = Date.now(); - authorize(token, process.env.WORKSTATION_ID).then((name) => { - req.session.isAuth = true; - req.session.name = name; - res.redirect(state || 'viewer'); - }).catch((err) => { - console.error('Certification failed:\n', err); - res.sendStatus(403); - }); + authorize(token, process.env.WORKSTATION_ID) + .then((name) => { + req.session.isAuth = true; + req.session.name = name; + res.redirect(state || 'viewer'); + }) + .catch((err) => { + console.error('Certification failed:\n', err); + res.sendStatus(403); + }); }) .catch((err) => { console.error('Failed to fetch token:\n', err); @@ -157,15 +159,17 @@ app.use(['/viewer', '/photo-viewer', '/photo', '/hls'], (req, res, next) => { return; } req.session.lastAuthedTime = Date.now(); - authorize(token, process.env.WORKSTATION_ID).then((name) => { - req.session.isAuth = true; - req.session.name = name; - req.session.authPendding = false; - next(); - }).catch((err) => { - console.error('Certification failed:\n', err); - res.sendStatus(403); - }); + authorize(token, process.env.WORKSTATION_ID) + .then((name) => { + req.session.isAuth = true; + req.session.name = name; + req.session.authPendding = false; + next(); + }) + .catch((err) => { + console.error('Certification failed:\n', err); + res.sendStatus(403); + }); }); app.get(['/viewer', '/photo-viewer'], (req, res) => {