This commit is contained in:
syuilo 2019-05-10 11:55:07 +09:00
parent 37ef9094a8
commit 7c4ac882ef
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
8 changed files with 703 additions and 1 deletions

173
package-lock.json generated
View file

@ -3,6 +3,11 @@
"requires": true, "requires": true,
"lockfileVersion": 1, "lockfileVersion": 1,
"dependencies": { "dependencies": {
"@types/caseless": {
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w=="
},
"@types/chalk": { "@types/chalk": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz",
@ -16,6 +21,14 @@
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA=="
}, },
"@types/form-data": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
"integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==",
"requires": {
"@types/node": "*"
}
},
"@types/lokijs": { "@types/lokijs": {
"version": "1.5.2", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/@types/lokijs/-/lokijs-1.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/lokijs/-/lokijs-1.5.2.tgz",
@ -34,6 +47,30 @@
"@types/retry": "*" "@types/retry": "*"
} }
}, },
"@types/random-seed": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@types/random-seed/-/random-seed-0.3.3.tgz",
"integrity": "sha512-kHsCbIRHNXJo6EN5W8EA5b4i1hdT6jaZke5crBPLUcLqaLdZ0QBq8QVMbafHzhjFF83Cl9qlee2dChD18d/kPg=="
},
"@types/request": {
"version": "2.48.1",
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz",
"integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==",
"requires": {
"@types/caseless": "*",
"@types/form-data": "*",
"@types/node": "*",
"@types/tough-cookie": "*"
}
},
"@types/request-promise-native": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/@types/request-promise-native/-/request-promise-native-1.0.16.tgz",
"integrity": "sha512-gbLf6cg1XGBU8BObOgs5VkCQo5JFz2GstgZjyE4FRbig/jiCEdiynu2fCzJlw3qYPuoj59spKnvuRLN4PsMvhA==",
"requires": {
"@types/request": "*"
}
},
"@types/retry": { "@types/retry": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
@ -44,6 +81,16 @@
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.28.tgz", "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.28.tgz",
"integrity": "sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA==" "integrity": "sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA=="
}, },
"@types/tmp": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.1.0.tgz",
"integrity": "sha512-6IwZ9HzWbCq6XoQWhxLpDjuADodH/MKXRUIDFudvgjcVdjFknvmR+DNsoUeer4XPrEnrZs04Jj+kfV9pFsrhmA=="
},
"@types/tough-cookie": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz",
"integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg=="
},
"@types/uuid": { "@types/uuid": {
"version": "3.4.4", "version": "3.4.4",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz",
@ -138,6 +185,11 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
}, },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"bcrypt-pbkdf": { "bcrypt-pbkdf": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@ -146,6 +198,15 @@
"tweetnacl": "^0.14.3" "tweetnacl": "^0.14.3"
} }
}, },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"buffer-from": { "buffer-from": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@ -187,6 +248,11 @@
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
} }
}, },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@ -264,6 +330,11 @@
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
} }
}, },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"getpass": { "getpass": {
"version": "0.1.7", "version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@ -272,6 +343,19 @@
"assert-plus": "^1.0.0" "assert-plus": "^1.0.0"
} }
}, },
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"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"
}
},
"har-schema": { "har-schema": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
@ -301,6 +385,20 @@
"sshpk": "^1.7.0" "sshpk": "^1.7.0"
} }
}, },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"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="
},
"is-typedarray": { "is-typedarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@ -311,6 +409,11 @@
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
}, },
"jpeg-js": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.5.tgz",
"integrity": "sha512-hvaExqwmQDS8O9qnZAVDXGWU43Tbu1V0wMZmjROjT11jloSgGICZpscG+P6Nyi1BVAvyu2ARRx8qmEW30sxgdQ=="
},
"jsbn": { "jsbn": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@ -383,6 +486,14 @@
"mime-db": "~1.38.0" "mime-db": "~1.38.0"
} }
}, },
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"misskey-reversi": { "misskey-reversi": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/misskey-reversi/-/misskey-reversi-0.0.5.tgz", "resolved": "https://registry.npmjs.org/misskey-reversi/-/misskey-reversi-0.0.5.tgz",
@ -393,11 +504,34 @@
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
}, },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"opentype.js": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.4.11.tgz",
"integrity": "sha1-KBojkGOcwVkxyVXY1jwUp8d3K0E="
},
"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="
},
"performance-now": { "performance-now": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
}, },
"pngjs": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
},
"promise-retry": { "promise-retry": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz",
@ -417,11 +551,29 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
}, },
"pureimage": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/pureimage/-/pureimage-0.1.6.tgz",
"integrity": "sha512-t74leLaXyD3VGmMbcFZNWZoHqPQNX805gHYNBCrNEVRjUkDfdlopLJnDJI9QYdhWXwtNiD02coq+NB7+CryAwg==",
"requires": {
"jpeg-js": "^0.3.3",
"opentype.js": "^0.4.3",
"pngjs": "^3.3.1"
}
},
"qs": { "qs": {
"version": "6.5.2", "version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
}, },
"random-seed": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/random-seed/-/random-seed-0.3.0.tgz",
"integrity": "sha1-2UXy4fOPSejViRNDG4v2u5N1Vs0=",
"requires": {
"json-stringify-safe": "^5.0.1"
}
},
"reconnecting-websocket": { "reconnecting-websocket": {
"version": "4.1.10", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.1.10.tgz", "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.1.10.tgz",
@ -477,6 +629,14 @@
"resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
}, },
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"requires": {
"glob": "^7.1.3"
}
},
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@ -551,6 +711,14 @@
"resolved": "https://registry.npmjs.org/timeout-as-promise/-/timeout-as-promise-1.0.0.tgz", "resolved": "https://registry.npmjs.org/timeout-as-promise/-/timeout-as-promise-1.0.0.tgz",
"integrity": "sha1-c2foEfyZKs/Nzaq/LlDfr4shV28=" "integrity": "sha1-c2foEfyZKs/Nzaq/LlDfr4shV28="
}, },
"tmp": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz",
"integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==",
"requires": {
"rimraf": "^2.6.3"
}
},
"tough-cookie": { "tough-cookie": {
"version": "2.4.3", "version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@ -620,6 +788,11 @@
"extsprintf": "^1.2.0" "extsprintf": "^1.2.0"
} }
}, },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"ws": { "ws": {
"version": "6.2.1", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",

View file

@ -10,7 +10,10 @@
"@types/lokijs": "1.5.2", "@types/lokijs": "1.5.2",
"@types/node": "10.0.5", "@types/node": "10.0.5",
"@types/promise-retry": "1.1.3", "@types/promise-retry": "1.1.3",
"@types/random-seed": "0.3.3",
"@types/request-promise-native": "1.0.16",
"@types/seedrandom": "2.4.28", "@types/seedrandom": "2.4.28",
"@types/tmp": "0.1.0",
"@types/uuid": "3.4.4", "@types/uuid": "3.4.4",
"@types/ws": "6.0.1", "@types/ws": "6.0.1",
"autobind-decorator": "2.4.0", "autobind-decorator": "2.4.0",
@ -19,11 +22,14 @@
"mecab-async": "0.1.2", "mecab-async": "0.1.2",
"misskey-reversi": "0.0.5", "misskey-reversi": "0.0.5",
"promise-retry": "1.1.1", "promise-retry": "1.1.1",
"pureimage": "0.1.6",
"random-seed": "0.3.0",
"reconnecting-websocket": "4.1.10", "reconnecting-websocket": "4.1.10",
"request": "2.88.0", "request": "2.88.0",
"request-promise-native": "1.0.7", "request-promise-native": "1.0.7",
"seedrandom": "2.4.3", "seedrandom": "2.4.3",
"timeout-as-promise": "1.0.0", "timeout-as-promise": "1.0.0",
"tmp": "0.1.0",
"ts-node": "8.0.3", "ts-node": "8.0.3",
"typescript": "2.8.3", "typescript": "2.8.3",
"uuid": "3.3.2", "uuid": "3.3.2",

View file

@ -1,5 +1,6 @@
// AI CORE // AI CORE
import * as fs from 'fs';
import autobind from 'autobind-decorator'; import autobind from 'autobind-decorator';
import * as loki from 'lokijs'; import * as loki from 'lokijs';
import * as request from 'request-promise-native'; import * as request from 'request-promise-native';
@ -59,6 +60,7 @@ export default class 藍 {
}>; }>;
public friends: loki.Collection<FriendDoc>; public friends: loki.Collection<FriendDoc>;
public moduleData: loki.Collection<any>;
/** /**
* *
@ -105,6 +107,10 @@ export default class 藍 {
this.friends = this.getCollection('friends', { this.friends = this.getCollection('friends', {
indices: ['userId'] indices: ['userId']
}); });
this.moduleData = this.getCollection('moduleData', {
indices: ['module']
});
//#endregion //#endregion
// Init stream // Init stream
@ -281,6 +287,22 @@ export default class 藍 {
return friend; return friend;
} }
/**
*
*/
@autobind
public async upload(readStream: fs.ReadStream) {
const res = await request.post({
url: `${config.apiUrl}/drive/files/create`,
formData: {
i: config.i,
file: readStream
},
json: true
});
return res;
}
/** /**
* 稿 * 稿
*/ */

View file

@ -19,6 +19,7 @@ import DiceModule from './modules/dice';
import ServerModule from './modules/server'; import ServerModule from './modules/server';
import FollowModule from './modules/follow'; import FollowModule from './modules/follow';
import ValentineModule from './modules/valentine'; import ValentineModule from './modules/valentine';
import MazeModule from './modules/maze';
import chalk from 'chalk'; import chalk from 'chalk';
import * as request from 'request-promise-native'; import * as request from 'request-promise-native';
@ -69,6 +70,7 @@ promiseRetry(retry => {
new BirthdayModule(), new BirthdayModule(),
new ValentineModule(), new ValentineModule(),
new KeywordModule(), new KeywordModule(),
new MazeModule(),
]); ]);
}).catch(e => { }).catch(e => {
log(chalk.red('Failed to fetch the account')); log(chalk.red('Failed to fetch the account'));

View file

@ -5,9 +5,21 @@ export default abstract class Module {
public abstract readonly name: string; public abstract readonly name: string;
protected ai: ; protected ai: ;
private doc: any;
public init(ai: ) { public init(ai: ) {
this.ai = ai; this.ai = ai;
this.doc = this.ai.moduleData.findOne({
module: this.name
});
if (this.doc == null) {
this.doc = this.ai.moduleData.insertOne({
module: this.name,
data: {}
});
}
} }
public abstract install(): InstallerResult; public abstract install(): InstallerResult;
@ -48,4 +60,15 @@ export default abstract class Module {
public setTimeoutWithPersistence(delay: number, data?: any) { public setTimeoutWithPersistence(delay: number, data?: any) {
this.ai.setTimeoutWithPersistence(this, delay, data); this.ai.setTimeoutWithPersistence(this, delay, data);
} }
@autobind
protected getData() {
return this.doc.data;
}
@autobind
protected setData(data: any) {
this.doc.data = data;
this.ai.moduleData.update(this.doc);
}
} }

View file

@ -35,7 +35,7 @@ export const itemPrefixes = [
'Microsoft製', 'Microsoft製',
'Apple製', 'Apple製',
'人類の技術を結集して作った', '人類の技術を結集して作った',
'2018年製', '2018年製', // TODO ランダム
'500kgくらいある', '500kgくらいある',
'高級', '高級',
'腐った', '腐った',

472
src/modules/maze/index.ts Normal file
View file

@ -0,0 +1,472 @@
/**
* Random avatar generator
*/
const p = require('pureimage');
import * as gen from 'random-seed';
import * as fs from 'fs';
import autobind from 'autobind-decorator';
import Module from '../../module';
import serifs from '../../serifs';
import * as tmp from 'tmp';
type CellType = 'empty' | 'left' | 'right' | 'top' | 'bottom' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom' | 'leftRightTop' | 'leftRightBottom' | 'leftTopBottom' | 'rightTopBottom' | 'leftRight' | 'topBottom' | 'cross';
type Dir = 'left' | 'right' | 'top' | 'bottom';
const cellVariants = {
empty: {
digg: { left: 'left', right: 'right', top: 'top', bottom: 'bottom' },
cross: { left: false, right: false, top: false, bottom: false },
},
left: {
digg: { left: null, right: 'leftRight', top: 'leftTop', bottom: 'leftBottom' },
cross: { left: false, right: false, top: false, bottom: false },
},
right: {
digg: { left: 'leftRight', right: null, top: 'rightTop', bottom: 'rightBottom' },
cross: { left: false, right: false, top: false, bottom: false },
},
top: {
digg: { left: 'leftTop', right: 'rightTop', top: null, bottom: 'topBottom' },
cross: { left: false, right: false, top: false, bottom: false },
},
bottom: {
digg: { left: 'leftBottom', right: 'rightBottom', top: 'topBottom', bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
leftTop: {
digg: { left: null, right: 'leftRightTop', top: null, bottom: 'leftTopBottom' },
cross: { left: false, right: false, top: false, bottom: false },
},
leftBottom: {
digg: { left: null, right: 'leftRightBottom', top: 'leftTopBottom', bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
rightTop: {
digg: { left: 'leftRightTop', right: null, top: null, bottom: 'rightTopBottom' },
cross: { left: false, right: false, top: false, bottom: false },
},
rightBottom: {
digg: { left: 'leftRightBottom', right: null, top: 'rightTopBottom', bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
leftRightTop: {
digg: { left: null, right: null, top: null, bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
leftRightBottom: {
digg: { left: null, right: null, top: null, bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
leftTopBottom: {
digg: { left: null, right: null, top: null, bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
rightTopBottom: {
digg: { left: null, right: null, top: null, bottom: null },
cross: { left: false, right: false, top: false, bottom: false },
},
leftRight: {
digg: { left: null, right: null, top: 'leftRightTop', bottom: 'leftRightBottom' },
cross: { left: false, right: false, top: true, bottom: true },
},
topBottom: {
digg: { left: 'leftTopBottom', right: 'rightTopBottom', top: null, bottom: null },
cross: { left: true, right: true, top: false, bottom: false },
},
cross: {
digg: { left: 'cross', right: 'cross', top: 'cross', bottom: 'cross' },
cross: { left: false, right: false, top: false, bottom: false },
},
} as { [k in CellType]: {
digg: { left: CellType | null; right: CellType | null; top: CellType | null; bottom: CellType | null; };
cross: { left: boolean; right: boolean; top: boolean; bottom: boolean; };
} };
const imageSize = 2048; // px
const margin = 256;
const mazeAreaSize = imageSize - (margin * 2);
const themes = [{
bg1: '#C1D9CE',
bg2: '#F2EDD5',
wall: '#0F8AA6',
road: '#C1D9CE',
marker: '#84BFBF',
}, {
bg1: '#17275B',
bg2: '#1F2E67',
wall: '#17275B',
road: '#6A77A4',
marker: '#E6E5E3',
}, {
bg1: '#194035',
bg2: '#417334',
wall: '#594020',
road: '#A67926',
marker: '#2E4D59',
}];
export default class extends Module {
public readonly name = 'maze';
@autobind
public install() {
this.post();
setInterval(this.post, 1000 * 60 * 3);
return {};
}
@autobind
private async post() {
const now = new Date();
if (now.getHours() !== 11) return;
const date = `${now.getFullYear()}-${now.getMonth()}-${now.getDate()}`;
const data = this.getData();
if (data.lastPosted == date) return;
data.lastPosted = date;
this.setData(data);
const seed = date;
this.log('Maze generating...');
const maze = this.genMize(seed);
this.log('Maze rendering...');
const [temp] = await this.createTemp();
await this.renderMaze(seed, maze, fs.createWriteStream(temp));
this.log('Image uploading...');
const file = await this.ai.upload(fs.createReadStream(temp));
this.log('Posting...');
this.ai.post({
text: serifs.maze.post,
fileIds: [file.id]
});
}
@autobind
private createTemp(): Promise<[string, any]> {
return new Promise<[string, any]>((res, rej) => {
tmp.file((e, path, fd, cleanup) => {
if (e) return rej(e);
res([path, cleanup]);
});
});
}
@autobind
private genMize(seed) {
const rand = gen.create(seed);
const mazeSize = 10 + rand(21);
// maze (filled by 'empty')
const maze: CellType[][] = new Array(mazeSize);
for (let i = 0; i < mazeSize; i++) {
maze[i] = new Array(mazeSize).fill('empty');
}
const origin = {
x: rand(mazeSize),
y: rand(mazeSize),
};
function checkDiggable(x: number, y: number, dir: Dir) {
if (cellVariants[maze[x][y]].digg[dir] === null) return false;
const newPos =
dir === 'top' ? { x: x, y: y - 1 } :
dir === 'bottom' ? { x: x, y: y + 1 } :
dir === 'left' ? { x: x - 1, y: y } :
dir === 'right' ? { x: x + 1, y: y } :
{ x, y };
if (newPos.x < 0 || newPos.y < 0 || newPos.x >= mazeSize || newPos.y >= mazeSize) return false;
const cell = maze[newPos.x][newPos.y];
if (cell === 'empty') return true;
if (cellVariants[cell].cross[dir] && checkDiggable(newPos.x, newPos.y, dir)) return true;
return false;
}
function diggFrom(x: number, y: number) {
const isUpDiggable = checkDiggable(x, y, 'top');
const isRightDiggable = checkDiggable(x, y, 'right');
const isDownDiggable = checkDiggable(x, y, 'bottom');
const isLeftDiggable = checkDiggable(x, y, 'left');
if (!isUpDiggable && !isRightDiggable && !isDownDiggable && !isLeftDiggable) return;
const dirs: Dir[] = [];
if (isUpDiggable) dirs.push('top');
if (isRightDiggable) dirs.push('right');
if (isDownDiggable) dirs.push('bottom');
if (isLeftDiggable) dirs.push('left');
const dir = dirs[rand(dirs.length)];
maze[x][y] = cellVariants[maze[x][y]].digg[dir];
if (dir === 'top') {
maze[x][y - 1] = maze[x][y - 1] === 'empty' ? 'bottom' : 'cross';
diggFrom(x, y - 1);
return;
}
if (dir === 'right') {
maze[x + 1][y] = maze[x + 1][y] === 'empty' ? 'left' : 'cross';
diggFrom(x + 1, y);
return;
}
if (dir === 'bottom') {
maze[x][y + 1] = maze[x][y + 1] === 'empty' ? 'top' : 'cross';
diggFrom(x, y + 1);
return;
}
if (dir === 'left') {
maze[x - 1][y] = maze[x - 1][y] === 'empty' ? 'right' : 'cross';
diggFrom(x - 1, y);
return;
}
}
diggFrom(origin.x, origin.y);
let hasEmptyCell = true;
while (hasEmptyCell) {
const nonEmptyCells = [];
for (let y = 0; y < mazeSize; y++) {
for (let x = 0; x < mazeSize; x++) {
const cell = maze[x][y];
if (cell !== 'empty' && cell !== 'cross') nonEmptyCells.push([x, y]);
}
}
const pos = nonEmptyCells[rand(nonEmptyCells.length)];
diggFrom(pos[0], pos[1]);
hasEmptyCell = false;
for (let y = 0; y < mazeSize; y++) {
for (let x = 0; x < mazeSize; x++) {
if (maze[x][y] === 'empty') hasEmptyCell = true;
}
}
}
return maze;
}
@autobind
private renderMaze(seed, maze: CellType[][], stream: fs.WriteStream): Promise<void> {
const rand = gen.create(seed);
const mazeSize = maze.length;
const colors = themes[rand(themes.length)];
const canvas = p.make(imageSize, imageSize);
const ctx = canvas.getContext('2d');
ctx.fillStyle = colors.bg1;
ctx.beginPath();
ctx.fillRect(0, 0, imageSize, imageSize);
ctx.fillStyle = colors.bg2;
ctx.beginPath();
ctx.fillRect(margin / 2, margin / 2, imageSize - ((margin / 2) * 2), imageSize - ((margin / 2) * 2));
// Draw
function drawCell(ctx, x, y, size, left, right, top, bottom, mark) {
const wallThickness = size / 8;
const wallMargin = size / 4;
const markerMargin = size / 3;
ctx.fillStyle = colors.road;
if (left) {
ctx.beginPath();
ctx.fillRect(x, y + wallMargin, size - wallMargin, size - (wallMargin * 2));
}
if (right) {
ctx.beginPath();
ctx.fillRect(x + wallMargin, y + wallMargin, size - wallMargin, size - (wallMargin * 2));
}
if (top) {
ctx.beginPath();
ctx.fillRect(x + wallMargin, y, size - (wallMargin * 2), size - wallMargin);
}
if (bottom) {
ctx.beginPath();
ctx.fillRect(x + wallMargin, y + wallMargin, size - (wallMargin * 2), size - wallMargin);
}
if (mark) {
ctx.fillStyle = colors.marker;
ctx.beginPath();
ctx.fillRect(x + markerMargin, y + markerMargin, size - (markerMargin * 2), size - (markerMargin * 2));
}
const wallLeftTopX = x + wallMargin - (wallThickness / 2);
const wallLeftTopY = y + wallMargin - (wallThickness / 2);
const wallRightTopX = x + size - wallMargin - (wallThickness / 2);
const wallRightTopY = y + wallMargin - (wallThickness / 2);
const wallLeftBottomX = x + wallMargin - (wallThickness / 2);
const wallLeftBottomY = y + size - wallMargin - (wallThickness / 2);
const wallRightBottomX = x + size - wallMargin - (wallThickness / 2);
const wallRightBottomY = y + size - wallMargin - (wallThickness / 2);
ctx.fillStyle = colors.wall;
if (left && right && top && bottom) {
ctx.beginPath();
if (rand(2) === 0) {
ctx.fillRect(x + wallMargin - (wallThickness / 2), y, wallThickness, size);
ctx.fillRect(x + size - wallMargin - (wallThickness / 2), y, wallThickness, size);
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), wallMargin, wallThickness);
ctx.fillRect(x + size - wallMargin, y + wallMargin - (wallThickness / 2), wallMargin, wallThickness);
ctx.fillRect(x, y + size - wallMargin - (wallThickness / 2), wallMargin, wallThickness);
ctx.fillRect(x + size - wallMargin, y + size - wallMargin - (wallThickness / 2), wallMargin, wallThickness);
} else {
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), size, wallThickness);
ctx.fillRect(x, y + size - wallMargin - (wallThickness / 2), size, wallThickness);
ctx.fillRect(wallLeftTopX, y, wallThickness, wallMargin - (wallThickness / 2));
ctx.fillRect(wallRightTopX, y, wallThickness, wallMargin - (wallThickness / 2));
ctx.fillRect(wallLeftTopX, wallLeftBottomY, wallThickness, wallMargin + (wallThickness / 2));
ctx.fillRect(wallRightTopX, wallRightBottomY, wallThickness, wallMargin + (wallThickness / 2));
}
return;
}
if (!left && right && !top && bottom) {
ctx.beginPath();
ctx.fillRect(wallLeftTopX, wallLeftTopY, size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallLeftTopX, wallLeftTopY, wallThickness, size - wallMargin + (wallThickness / 2));
}
if (right && bottom) {
ctx.fillRect(wallRightBottomX, wallRightBottomY, wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallRightBottomX, wallRightBottomY, wallThickness, wallMargin + (wallThickness / 2));
}
if (left && !right && !top && bottom) {
ctx.beginPath();
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallRightTopX, y + wallMargin - (wallThickness / 2), wallThickness, size - wallMargin + (wallThickness / 2));
}
if (left && bottom) {
ctx.fillRect(x, wallLeftBottomY, wallMargin - (wallThickness / 2), wallThickness);
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, wallThickness, wallMargin + (wallThickness / 2));
}
if (!left && right && top && !bottom) {
ctx.beginPath();
ctx.fillRect(wallLeftBottomX, y, wallThickness, size - wallMargin + (wallThickness / 2));
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, size - wallMargin + (wallThickness / 2), wallThickness);
}
if (right && top) {
ctx.fillRect(wallRightTopX, y, wallThickness, wallMargin - (wallThickness / 2));
ctx.fillRect(wallRightTopX, wallRightTopY, size - wallMargin - (wallThickness * 2), wallThickness);
}
if (left && !right && top && !bottom) {
ctx.beginPath();
ctx.fillRect(x, wallLeftBottomY, size - wallMargin - (wallThickness / 2), wallThickness);
ctx.fillRect(wallRightTopX, y, wallThickness, size - wallMargin + (wallThickness / 2));
}
if (left && top) {
ctx.fillRect(wallLeftTopX, y, wallThickness, wallMargin + (wallThickness / 2));
ctx.fillRect(x, wallLeftTopY, wallMargin - (wallThickness / 2), wallThickness);
}
if (!left && right && !top && !bottom) {
ctx.beginPath();
ctx.fillRect(wallLeftTopX, wallLeftTopY, size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallLeftTopX, wallLeftTopY, wallThickness, size - wallMargin - (wallThickness * 2));
return;
}
if (left && !right && !top && !bottom) {
ctx.beginPath();
ctx.fillRect(x, wallLeftTopY, size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(x, wallLeftBottomY, size - wallMargin + (wallThickness / 2), wallThickness);
ctx.fillRect(wallRightTopX, wallRightTopY, wallThickness, size - wallMargin - (wallThickness * 2));
return;
}
if (!left && !right && !top && bottom) {
ctx.beginPath();
ctx.fillRect(wallLeftTopX, wallLeftTopY, wallThickness, size - wallMargin + (wallThickness / 2));
ctx.fillRect(wallRightTopX, wallRightTopY, wallThickness, size - wallMargin + (wallThickness / 2));
ctx.fillRect(wallLeftTopX, wallLeftTopY, size - wallMargin - (wallThickness * 2), wallThickness);
return;
}
if (!left && !right && top && !bottom) {
ctx.beginPath();
ctx.fillRect(wallLeftTopX, y, wallThickness, size - wallMargin + (wallThickness / 2));
ctx.fillRect(wallRightTopX, y, wallThickness, size - wallMargin + (wallThickness / 2));
ctx.fillRect(wallLeftBottomX, wallLeftBottomY, size - wallMargin - (wallThickness * 2), wallThickness);
return;
}
if (top && bottom) {
if (!left) {
ctx.beginPath();
ctx.fillRect(x + wallMargin - (wallThickness / 2), y, wallThickness, size);
}
if (!right) {
ctx.beginPath();
ctx.fillRect(x + size - wallMargin - (wallThickness / 2), y, wallThickness, size);
}
}
if (left && right) {
if (!top) {
ctx.beginPath();
ctx.fillRect(x, y + wallMargin - (wallThickness / 2), size, wallThickness);
}
if (!bottom) {
ctx.beginPath();
ctx.fillRect(x, y + size - wallMargin - (wallThickness / 2), size, wallThickness);
}
}
}
const cellSize = mazeAreaSize / mazeSize;
for (let x = 0; x < mazeSize; x++) {
for (let y = 0; y < mazeSize; y++) {
const actualX = margin + (cellSize * x);
const actualY = margin + (cellSize * y);
const cell = maze[x][y];
const mark = (x === 0 && y === 0) || (x === mazeSize - 1 && y === mazeSize - 1);
if (cell === 'left') drawCell(ctx, actualX, actualY, cellSize, true, false, false, false, mark);
if (cell === 'right') drawCell(ctx, actualX, actualY, cellSize, false, true, false, false, mark);
if (cell === 'top') drawCell(ctx, actualX, actualY, cellSize, false, false, true, false, mark);
if (cell === 'bottom') drawCell(ctx, actualX, actualY, cellSize, false, false, false, true, mark);
if (cell === 'leftTop') drawCell(ctx, actualX, actualY, cellSize, true, false, true, false, mark);
if (cell === 'leftBottom') drawCell(ctx, actualX, actualY, cellSize, true, false, false, true, mark);
if (cell === 'rightTop') drawCell(ctx, actualX, actualY, cellSize, false, true, true, false, mark);
if (cell === 'rightBottom') drawCell(ctx, actualX, actualY, cellSize, false, true, false, true, mark);
if (cell === 'leftRightTop') drawCell(ctx, actualX, actualY, cellSize, true, true, true, false, mark);
if (cell === 'leftRightBottom') drawCell(ctx, actualX, actualY, cellSize, true, true, false, true, mark);
if (cell === 'leftTopBottom') drawCell(ctx, actualX, actualY, cellSize, true, false, true, true, mark);
if (cell === 'rightTopBottom') drawCell(ctx, actualX, actualY, cellSize, false, true, true, true, mark);
if (cell === 'leftRight') drawCell(ctx, actualX, actualY, cellSize, true, true, false, false, mark);
if (cell === 'topBottom') drawCell(ctx, actualX, actualY, cellSize, false, false, true, true, mark);
if (cell === 'cross') drawCell(ctx, actualX, actualY, cellSize, true, true, true, true, mark);
}
}
return p.encodePNGToStream(canvas, stream);
}
}

View file

@ -311,6 +311,10 @@ export default {
server: { server: {
cpu: 'サーバーの負荷が高そうです。大丈夫でしょうか...' cpu: 'サーバーの負荷が高そうです。大丈夫でしょうか...'
}, },
maze: {
post: 'この回路、解読してみてください! #AiMaze'
},
}; };
export function getSerif(variant: string | string[]): string { export function getSerif(variant: string | string[]): string {