From c63147c3e3d4be13d2da90237bc6d781288623fd Mon Sep 17 00:00:00 2001 From: Simo-C3 Date: Wed, 16 Mar 2022 01:08:02 +0900 Subject: [PATCH] =?UTF-8?q?[add]=20DB=E3=81=AE=E9=80=A3=E6=90=BA=E3=80=81?= =?UTF-8?q?=E3=83=87=E3=83=97=E3=83=AD=E3=82=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pipfile | 4 +- Pipfile.lock | 266 +++++++++++++++++++++++++++++++++++++++++++++++ bot.py | 51 +++++++-- cruds/bot.py | 96 +++++++++++++++-- exception.py | 19 ++++ requirements.txt | 54 ++++++++++ schemas/bot.py | 10 ++ 7 files changed, 478 insertions(+), 22 deletions(-) create mode 100644 exception.py create mode 100644 schemas/bot.py diff --git a/Pipfile b/Pipfile index 5d61406..75ff5b8 100644 --- a/Pipfile +++ b/Pipfile @@ -18,12 +18,14 @@ sqlalchemy-utils = "*" python-dotenv = "*" pyjwt = "*" cerberus = "*" -line-bot-sdk = "*" flask = "*" pyzbar = "*" pillow = "*" python-dateutil = "*" fastapi-pagination = "*" +aiofiles = "*" +line-bot-sdk = "*" +opencensus-ext-azure = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 8ad03ec..18ff216 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -16,6 +16,14 @@ ] }, "default": { + "aiofiles": { + "hashes": [ + "sha256:7a973fc22b29e9962d0897805ace5856e6a566ab1f0c8e5c91ff6c866519c937", + "sha256:8334f23235248a3b2e83b2c3a78a22674f39969b96397126cc93664d9a901e59" + ], + "index": "pypi", + "version": "==0.8.0" + }, "aiohttp": { "hashes": [ "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3", @@ -134,6 +142,22 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==21.4.0" }, + "azure-core": { + "hashes": [ + "sha256:23c1389a115c328878c4eface3ca3899c2468313ea6f883f2347d6924cd887b2", + "sha256:a56a6f720d0948d3f3e4a25a5fe46df2f1b7f865c358d74e2ce47dbb49262608" + ], + "markers": "python_version >= '3.6'", + "version": "==1.23.0" + }, + "azure-identity": { + "hashes": [ + "sha256:020ff0e47157852e4aac8a3adb06841827147f27a94cbe74a904425d8e62d93c", + "sha256:8d87aff09b8dabe3c99bb934798dcdeb2f2d49614ecc4f0425cc888faafd64ae" + ], + "markers": "python_version >= '3.6'", + "version": "==1.8.0" + }, "bcrypt": { "hashes": [ "sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d", @@ -150,6 +174,14 @@ "index": "pypi", "version": "==3.2.0" }, + "cachetools": { + "hashes": [ + "sha256:486471dfa8799eb7ec503a8059e263db000cdda20075ce5e48903087f79d5fd6", + "sha256:8fecd4203a38af17928be7b90689d8083603073622229ca7077b72d8e5a976e4" + ], + "markers": "python_version ~= '3.7'", + "version": "==5.0.0" + }, "cerberus": { "hashes": [ "sha256:d1b21b3954b2498d9a79edf16b3170a3ac1021df88d197dc2ce5928ba519237c" @@ -235,6 +267,40 @@ "markers": "python_version >= '3.6'", "version": "==8.0.4" }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.4" + }, + "cryptography": { + "hashes": [ + "sha256:0a817b961b46894c5ca8a66b599c745b9a3d9f822725221f0e0fe49dc043a3a3", + "sha256:2d87cdcb378d3cfed944dac30596da1968f88fb96d7fc34fdae30a99054b2e31", + "sha256:30ee1eb3ebe1644d1c3f183d115a8c04e4e603ed6ce8e394ed39eea4a98469ac", + "sha256:391432971a66cfaf94b21c24ab465a4cc3e8bf4a939c1ca5c3e3a6e0abebdbcf", + "sha256:39bdf8e70eee6b1c7b289ec6e5d84d49a6bfa11f8b8646b5b3dfe41219153316", + "sha256:4caa4b893d8fad33cf1964d3e51842cd78ba87401ab1d2e44556826df849a8ca", + "sha256:53e5c1dc3d7a953de055d77bef2ff607ceef7a2aac0353b5d630ab67f7423638", + "sha256:596f3cd67e1b950bc372c33f1a28a0692080625592ea6392987dba7f09f17a94", + "sha256:5d59a9d55027a8b88fd9fd2826c4392bd487d74bf628bb9d39beecc62a644c12", + "sha256:6c0c021f35b421ebf5976abf2daacc47e235f8b6082d3396a2fe3ccd537ab173", + "sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b", + "sha256:74d6c7e80609c0f4c2434b97b80c7f8fdfaa072ca4baab7e239a15d6d70ed73a", + "sha256:7be0eec337359c155df191d6ae00a5e8bbb63933883f4f5dffc439dac5348c3f", + "sha256:94ae132f0e40fe48f310bba63f477f14a43116f05ddb69d6fa31e93f05848ae2", + "sha256:bb5829d027ff82aa872d76158919045a7c1e91fbf241aec32cb07956e9ebd3c9", + "sha256:ca238ceb7ba0bdf6ce88c1b74a87bffcee5afbfa1e41e173b1ceb095b39add46", + "sha256:ca28641954f767f9822c24e927ad894d45d5a1e501767599647259cbf030b903", + "sha256:e0344c14c9cb89e76eb6a060e67980c9e35b3f36691e15e1b7a9e58a0a6c6dc3", + "sha256:ebc15b1c22e55c4d5566e3ca4db8689470a0ca2babef8e3a9ee057a8b82ce4b1", + "sha256:ec63da4e7e4a5f924b90af42eddf20b698a70e58d86a72d943857c4c6045b3ee" + ], + "markers": "python_version >= '3.6'", + "version": "==36.0.1" + }, "dnspython": { "hashes": [ "sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e", @@ -354,6 +420,30 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.18.2" }, + "google-api-core": { + "hashes": [ + "sha256:6be1fc59e2a7ba9f66808bbc22f976f81e4c3e7ab20fa0620ce42686288787d0", + "sha256:b0fa577e512f0c8e063386b974718b8614586a798c5894ed34bedf256d9dae24" + ], + "markers": "python_version >= '3.6'", + "version": "==2.7.1" + }, + "google-auth": { + "hashes": [ + "sha256:218ca03d7744ca0c8b6697b6083334be7df49b7bf76a69d555962fd1a7657b5f", + "sha256:ad160fc1ea8f19e331a16a14a79f3d643d813a69534ba9611d2c80dc10439dad" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==2.6.0" + }, + "googleapis-common-protos": { + "hashes": [ + "sha256:183bb0356bd614c4330ad5158bc1c1bcf9bcf7f5e7f911317559fe209496eeee", + "sha256:53eb313064738f45d5ac634155ae208e121c963659627b90dfcb61ef514c03e1" + ], + "markers": "python_version >= '3.6'", + "version": "==1.55.0" + }, "greenlet": { "hashes": [ "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3", @@ -515,6 +605,20 @@ ], "version": "==0.6.1" }, + "msal": { + "hashes": [ + "sha256:04e3cb7bb75c51f56d290381f23056207df1f3eb594ed03d38551f3b16d2a36e", + "sha256:5a52d78e70d2c451e267c1e8c2342e4c06f495c75c859aeafd9260d3974f09fe" + ], + "version": "==1.17.0" + }, + "msal-extensions": { + "hashes": [ + "sha256:89df9c0237e1adf16938fa58575db59c2bb9de04a83ffb0452c8dfc79031f717", + "sha256:d9029af70f2cbdc5ad7ecfed61cb432ebe900484843ccf72825445dbfe62d311" + ], + "version": "==0.3.1" + }, "multidict": { "hashes": [ "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60", @@ -580,6 +684,28 @@ "markers": "python_version >= '3.7'", "version": "==6.0.2" }, + "opencensus": { + "hashes": [ + "sha256:476d99fb82f3807acf566e6c232049dc13e825102be104e6231784abcc1b1a5e", + "sha256:7a60bdbceb370a379bccad9ea9d1d56fcce650cf12a6d2b129e6880d2632eeab" + ], + "version": "==0.8.0" + }, + "opencensus-context": { + "hashes": [ + "sha256:8bfb461d18f1dd243420224603c71544d7ac888bb236cf0d0a58545942561478", + "sha256:8cf64ce901e6b35f491bd1521e6541676e034c52d00c95500e9364600f835c06" + ], + "version": "==0.1.2" + }, + "opencensus-ext-azure": { + "hashes": [ + "sha256:70ad2601ef24e655d1fd5e6e53f57599f919ca2b943c5371c8a794da379a5fe8", + "sha256:fba89a747dfee7ddc1a23875ba0b7e77f5ae73540336079901ffcd7d6141d5dc" + ], + "index": "pypi", + "version": "==1.1.3" + }, "packaging": { "hashes": [ "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", @@ -637,6 +763,84 @@ "markers": "python_version >= '3.6'", "version": "==1.0.0" }, + "portalocker": { + "hashes": [ + "sha256:a648ad761b8ea27370cb5915350122cd807b820d2193ed5c9cc28f163df637f4", + "sha256:b092f48e1e30a234ab3dd1cfd44f2f235e8a41f4e310e463fc8d6798d1c3c235" + ], + "markers": "python_version >= '3.5' and platform_system == 'Windows'", + "version": "==2.4.0" + }, + "protobuf": { + "hashes": [ + "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c", + "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb", + "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9", + "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4", + "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca", + "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58", + "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b", + "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909", + "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2", + "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368", + "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2", + "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13", + "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0", + "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e", + "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee", + "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a", + "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616", + "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e", + "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a", + "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26", + "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7", + "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934", + "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f", + "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f", + "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07", + "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37" + ], + "markers": "python_version >= '3.5'", + "version": "==3.19.4" + }, + "psutil": { + "hashes": [ + "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5", + "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a", + "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4", + "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841", + "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d", + "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d", + "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0", + "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845", + "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf", + "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b", + "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07", + "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618", + "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2", + "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd", + "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666", + "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce", + "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3", + "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d", + "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25", + "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492", + "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b", + "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d", + "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2", + "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203", + "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2", + "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94", + "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9", + "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64", + "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56", + "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3", + "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c", + "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==5.9.0" + }, "psycopg2": { "hashes": [ "sha256:06f32425949bd5fe8f625c49f17ebb9784e1e4fe928b7cce72edc36fb68e4c0c", @@ -662,6 +866,42 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.11.0" }, + "pyasn1": { + "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" + }, + "pyasn1-modules": { + "hashes": [ + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", + "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" + ], + "version": "==0.2.8" + }, "pycodestyle": { "hashes": [ "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", @@ -776,6 +1016,24 @@ "index": "pypi", "version": "==0.0.5" }, + "pywin32": { + "hashes": [ + "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559", + "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51", + "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b", + "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb", + "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba", + "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34", + "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352", + "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9", + "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e", + "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca", + "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee", + "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439" + ], + "markers": "platform_system == 'Windows'", + "version": "==303" + }, "pyzbar": { "hashes": [ "sha256:0e204b904e093e5e75aa85e0203bb0e02888105732a509b51f31cff400f34265", @@ -793,6 +1051,14 @@ "index": "pypi", "version": "==2.27.1" }, + "rsa": { + "hashes": [ + "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17", + "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb" + ], + "markers": "python_version >= '3.6'", + "version": "==4.8" + }, "setuptools": { "hashes": [ "sha256:2347b2b432c891a863acadca2da9ac101eae6169b1d3dfee2ec605ecd50dbfe5", diff --git a/bot.py b/bot.py index ae54e4c..4b778c8 100644 --- a/bot.py +++ b/bot.py @@ -2,7 +2,11 @@ from dotenv import load_dotenv from pathlib import Path import os -from cruds.bot import save_img, get_isbn_by_bar_code, get_book_info_by_isbn +from db.main import get_db +from sqlalchemy.orm import Session +from schemas.bot import User +from cruds.bot import save_img, book_register, create_user +from exception import GetIsbnException, GetBookInfoException, RegisterBookException, SaveImageException from linebot import ( LineBotApi, WebhookHandler @@ -11,13 +15,15 @@ InvalidSignatureError ) from linebot.models import ( - MessageEvent, TextMessage, TextSendMessage, ImageMessage + MessageEvent, TextSendMessage, ImageMessage ) load_dotenv() YOUR_CHANNEL_ACCESS_TOKEN=os.environ.get('YOUR_CHANNEL_ACCESS_TOKEN') YOUR_CHANNEL_SECRET=os.environ.get('YOUR_CHANNEL_SECRET') +db: Session = next(get_db()) + SAVE_DIR=os.environ.get('SAVE_DIR') SRC_IMG_PATH = SAVE_DIR + "/{}.jpg" @@ -47,24 +53,47 @@ def callback(): return 'OK' +# @handler.add(MessageEvent, message=TextMessage) +# def handle_message(event): +# line_bot_api.reply_message( +# event.reply_token, +# TextSendMessage(text=event.message.text)) #ここでオウム返しのメッセージを返します。 + # 画像を受け取った際の処理 @handler.add(MessageEvent, message=ImageMessage) def handle_image(event): + profile = line_bot_api.get_profile(event.source.user_id) + user = create_user(db, profile.user_id, profile.display_name) message_id = event.message.id src_img_path = SRC_IMG_PATH.format(message_id) # 保存する画像のパス - - save_img(message_id, src_img_path) # 画像を一時保存する - isbn = get_isbn_by_bar_code(src_img_path) # ISBNの取得 - book_info = get_book_info_by_isbn(isbn) - print(book_info) + + try: + save_img(message_id, src_img_path) # 画像を一時保存する + book_info = book_register(db, src_img_path, user) + print(book_info) + except GetIsbnException as e: + resText = "バーコードの読み込みに失敗しました。もう一度、全体がきれいに写るように写真を撮影してください。" + print(e) + except GetBookInfoException as e: + resText = "書籍情報の取得が取得できませんでした。" + print(e) + except RegisterBookException as e: + resText = "書籍の登録に失敗しました。" + print(e) + except SaveImageException as e: + resText = "エラーが発生しました" + print(e) + else: + resText = f"タイトル:{book_info.title}\n著者:{book_info.author}サムネ:{book_info.thumbnail_url}" + finally: + # 一時保存していた画像を削除 + Path(SRC_IMG_PATH.format(message_id)).absolute().unlink() # 書籍情報を返す line_bot_api.reply_message( event.reply_token, - TextSendMessage(text=f"タイトル:{book_info['items'][0]['volumeInfo']['title']}\n著者:{book_info['items'][0]['volumeInfo']['authors'][0]}") + TextSendMessage(text=resText) ) - # 一時保存していた画像を削除 - Path(SRC_IMG_PATH.format(message_id)).absolute().unlink() if __name__ == "__main__": - app.run() + app.run(debug=True) diff --git a/cruds/bot.py b/cruds/bot.py index a9c4f42..be99f04 100644 --- a/cruds/bot.py +++ b/cruds/bot.py @@ -4,12 +4,17 @@ from pyzbar.pyzbar import decode from PIL import Image import requests +from db import models +from sqlalchemy.orm.session import Session +from schemas.api import Book +from schemas.bot import User +from exception import GetIsbnException, GetBookInfoException, SaveImageException, RegisterBookException, LeadAlreadyExistsException from linebot import ( LineBotApi ) -load_dotenv() +load_dotenv("localhost.env") YOUR_CHANNEL_ACCESS_TOKEN=os.environ.get('YOUR_CHANNEL_ACCESS_TOKEN') GOOGLE_API=os.environ.get('GOOGLE_API') @@ -17,16 +22,18 @@ line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN) # 写真の保存 -def save_img(message_id, src_img_path): +def save_img(message_id: str, src_img_path: str): # message_idから画像のバイナリデータを取得 message_content = line_bot_api.get_message_content(message_id) - with open(src_img_path, "wb") as f: - # バイナリを1024バイトずつ書き込む - for chunk in message_content.iter_content(): - f.write(chunk) - + try: + with open(src_img_path, "wb") as f: + # バイナリを1024バイトずつ書き込む + for chunk in message_content.iter_content(): + f.write(chunk) + except Exception as e: + raise SaveImageException("画像の保存に失敗しました", e) # 画像内のバーコードからISBNの抽出 -def get_isbn_by_bar_code(src_img_path): +def get_isbn_by_bar_code(db: Session, src_img_path: str) -> str: # 画像ファイルの指定 img_path = Path(rf"{src_img_path}") # バーコードの読取 @@ -35,9 +42,78 @@ def get_isbn_by_bar_code(src_img_path): return data[1][0].decode('utf-8', 'ignore') # ISBNから書籍情報を検索・取得 -def get_book_info_by_isbn(isbn): +def get_book_info_by_isbn(db: Session, isbn: str) -> object: # 検索リクエストURL req_url = GOOGLE_API + isbn # リクエスト response = requests.get(req_url) - return response.json() \ No newline at end of file + return response.json() + +def create_user(db: Session, user_id: str, user_name: str) -> User: + user_orm = db.query(models.User).filter(models.User.user_id == user_id).first() + if user_orm is None: + user_orm = models.User( + user_id = user_id, + name = user_name + ) + + db.add(user_orm) + db.commit() + db.refresh(user_orm) + user = User.from_orm(user_orm) + + else: + user = User.from_orm(user_orm) + + return user + +def book_register(db: Session, src_img_path: str, user: User) -> object: + isbn = get_isbn_by_bar_code(db, src_img_path) # ISBNの取得 + if isbn is None: + raise GetIsbnException('ISBNの取得に失敗しました', 404) + + book_orm = db.query(models.Book).filter(models.Book.isbn == isbn).first() + + if book_orm is None: + book_info = get_book_info_by_isbn(db, isbn) + print(book_info) + if book_info is None: + raise GetBookInfoException('書籍の情報取得に失敗しました', 404) + + book_orm = models.Book( + isbn = isbn, + title = book_info['items'][0]['volumeInfo']['title'], + author = book_info['items'][0]['volumeInfo']['authors'][0], + thumbnail_url = book_info['items'][0]['volumeInfo']['imageLinks']['smallThumbnail'], + published_date = book_info['items'][0]['volumeInfo']['publishedDate'] + ) + + db.add(book_orm) + db.commit() + db.refresh(book_orm) + book = Book.from_orm(book_orm) + + + try: + book_user_intermediate_table_register(db, user.user_id, isbn) + except LeadAlreadyExistsException as e: + db.delete(book_orm) + db.commit() + raise RegisterBookException('書籍の登録に失敗しました', e) + else: + return book + +def book_user_intermediate_table_register(db: Session, user_id: str, isbn: str): + read_orm = db.query(models.Read).filter(models.Read.user_id == user_id, models.Read.isbn == isbn).first() + + if read_orm is not None: + raise LeadAlreadyExistsException('Readにデータがすでに存在しています', 400) + else: + read_orm = models.Read( + user_id = user_id, + isbn = isbn + ) + + db.add(read_orm) + db.commit() + db.refresh(read_orm) diff --git a/exception.py b/exception.py new file mode 100644 index 0000000..553b959 --- /dev/null +++ b/exception.py @@ -0,0 +1,19 @@ +class GetIsbnException(Exception): + """ISBNの取得中にエラーが発生したことを知らせる例外クラス""" + pass + +class GetBookInfoException(Exception): + """書籍の情報取得中にエラーが発生したことを知らせる例外クラス""" + pass + +class LeadAlreadyExistsException(Exception): + """Readにすでにデータが存在していることを知らせる例外クラス""" + pass + +class RegisterBookException(Exception): + """書籍の登録中にエラーが発生したことを知らせる例外クラス""" + pass + +class SaveImageException(Exception): + """画像の保存中にエラーが発生したことを知らせる例外クラス""" + pass diff --git a/requirements.txt b/requirements.txt index 2922866..b1700c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,6 +48,49 @@ pydantic[email]==1.9.0 pyflakes==2.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' pyjwt==2.3.0 pyparsing==3.0.7; python_version >= '3.6' +aiofiles==0.8.0 +aiohttp==3.8.1 +aiosignal==1.2.0 +anyio==3.5.0 +asgiref==3.5.0 +async-timeout==4.0.2 +atomicwrites==1.4.0 +attrs==21.4.0 +bcrypt==3.2.0 +Cerberus==1.3.4 +certifi==2021.10.8 +cffi==1.15.0 +charset-normalizer==2.0.12 +click==8.0.4 +colorama==0.4.4 +dnspython==2.2.1 +email-validator==1.1.3 +fastapi==0.75.0 +flake8==4.0.1 +Flask==2.0.3 +frozenlist==1.3.0 +future==0.18.2 +greenlet==1.1.2 +h11==0.13.0 +idna==3.3 +iniconfig==1.1.1 +itsdangerous==2.1.1 +Jinja2==3.0.3 +line-bot-sdk==2.1.0 +MarkupSafe==2.1.0 +mccabe==0.6.1 +multidict==6.0.2 +packaging==21.3 +Pillow==9.0.1 +pluggy==1.0.0 +psycopg2==2.9.3 +py==1.11.0 +pycodestyle==2.8.0 +pycparser==2.21 +pydantic==1.9.0 +pyflakes==2.4.0 +PyJWT==2.3.0 +pyparsing==3.0.7 pytest==7.1.0 python-dotenv==0.19.2 python-multipart==0.0.5 @@ -65,3 +108,14 @@ urllib3==1.26.8; python_version >= '2.7' and python_version not in '3.0, 3.1, 3. uvicorn==0.17.6 werkzeug==2.0.3; python_version >= '3.6' yarl==1.7.2; python_version >= '3.6' +six==1.16.0 +sniffio==1.2.0 +SQLAlchemy==1.4.32 +SQLAlchemy-Utils==0.38.2 +starlette==0.17.1 +tomli==2.0.1 +typing_extensions==4.1.1 +urllib3==1.26.8 +uvicorn==0.17.6 +Werkzeug==2.0.3 +yarl==1.7.2 diff --git a/schemas/bot.py b/schemas/bot.py new file mode 100644 index 0000000..d366468 --- /dev/null +++ b/schemas/bot.py @@ -0,0 +1,10 @@ +from pydantic import BaseModel + +from db import models + +class User(BaseModel): + user_id: str + name: str + + class Config: + orm_mode = True \ No newline at end of file