Improved db migrations, & fixes
This commit is contained in:
167
Pipfile.lock
generated
167
Pipfile.lock
generated
@@ -18,17 +18,17 @@
|
|||||||
"default": {
|
"default": {
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3",
|
"sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
|
||||||
"sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"
|
"sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
|
||||||
],
|
],
|
||||||
"version": "==2020.6.20"
|
"version": "==2020.12.5"
|
||||||
},
|
},
|
||||||
"chardet": {
|
"chardet": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
"sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa",
|
||||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
"sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"
|
||||||
],
|
],
|
||||||
"version": "==3.0.4"
|
"version": "==4.0.0"
|
||||||
},
|
},
|
||||||
"idna": {
|
"idna": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -39,11 +39,11 @@
|
|||||||
},
|
},
|
||||||
"praw": {
|
"praw": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:6b93ad1e53385c68753203ec87f4d0053b2425b09fc8813847800a542efdfe6c",
|
"sha256:068a01c19834e1f748a8c220c6aa62ae9f0f8e211504ab8ef19883d09bed3430",
|
||||||
"sha256:fb55e46203a771342da7cbe144fbcd8c61d825719ce1025bdd72112194a0228f"
|
"sha256:87166a77ec31a1d9686ccdac97b5b72ba277ce436976eb3baf467c593f15bb26"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==7.1.0"
|
"version": "==7.1.4"
|
||||||
},
|
},
|
||||||
"prawcore": {
|
"prawcore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -54,10 +54,10 @@
|
|||||||
},
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b",
|
"sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804",
|
||||||
"sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"
|
"sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"
|
||||||
],
|
],
|
||||||
"version": "==2.24.0"
|
"version": "==2.25.1"
|
||||||
},
|
},
|
||||||
"six": {
|
"six": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -68,11 +68,11 @@
|
|||||||
},
|
},
|
||||||
"toml": {
|
"toml": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f",
|
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
|
||||||
"sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"
|
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.10.1"
|
"version": "==0.10.2"
|
||||||
},
|
},
|
||||||
"update-checker": {
|
"update-checker": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -83,10 +83,10 @@
|
|||||||
},
|
},
|
||||||
"urllib3": {
|
"urllib3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a",
|
"sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80",
|
||||||
"sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"
|
"sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"
|
||||||
],
|
],
|
||||||
"version": "==1.25.10"
|
"version": "==1.26.3"
|
||||||
},
|
},
|
||||||
"websocket-client": {
|
"websocket-client": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -99,51 +99,54 @@
|
|||||||
"develop": {
|
"develop": {
|
||||||
"astroid": {
|
"astroid": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703",
|
"sha256:87ae7f2398b8a0ae5638ddecf9987f081b756e0e9fc071aeebdca525671fc4dc",
|
||||||
"sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386"
|
"sha256:b31c92f545517dcc452f284bc9c044050862fbe6d93d2b3de4a215a6b384bf0d"
|
||||||
],
|
],
|
||||||
"version": "==2.4.2"
|
"version": "==2.5"
|
||||||
},
|
},
|
||||||
"colorama": {
|
"colorama": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff",
|
"sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b",
|
||||||
"sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"
|
"sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"
|
||||||
],
|
],
|
||||||
"markers": "sys_platform == 'win32'",
|
"markers": "sys_platform == 'win32'",
|
||||||
"version": "==0.4.3"
|
"version": "==0.4.4"
|
||||||
},
|
},
|
||||||
"isort": {
|
"isort": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:60a1b97e33f61243d12647aaaa3e6cc6778f5eb9f42997650f1cc975b6008750",
|
"sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e",
|
||||||
"sha256:d488ba1c5a2db721669cc180180d5acf84ebdc5af7827f7aaeaa75f73cf0e2b8"
|
"sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc"
|
||||||
],
|
],
|
||||||
"version": "==5.4.2"
|
"version": "==5.7.0"
|
||||||
},
|
},
|
||||||
"lazy-object-proxy": {
|
"lazy-object-proxy": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d",
|
"sha256:1d33d6f789697f401b75ce08e73b1de567b947740f768376631079290118ad39",
|
||||||
"sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449",
|
"sha256:2f2de8f8ac0be3e40d17730e0600619d35c78c13a099ea91ef7fb4ad944ce694",
|
||||||
"sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08",
|
"sha256:3782931963dc89e0e9a0ae4348b44762e868ea280e4f8c233b537852a8996ab9",
|
||||||
"sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a",
|
"sha256:37d9c34b96cca6787fe014aeb651217944a967a5b165e2cacb6b858d2997ab84",
|
||||||
"sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50",
|
"sha256:38c3865bd220bd983fcaa9aa11462619e84a71233bafd9c880f7b1cb753ca7fa",
|
||||||
"sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd",
|
"sha256:429c4d1862f3fc37cd56304d880f2eae5bd0da83bdef889f3bd66458aac49128",
|
||||||
"sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239",
|
"sha256:522b7c94b524389f4a4094c4bf04c2b02228454ddd17c1a9b2801fac1d754871",
|
||||||
"sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb",
|
"sha256:57fb5c5504ddd45ed420b5b6461a78f58cbb0c1b0cbd9cd5a43ad30a4a3ee4d0",
|
||||||
"sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea",
|
"sha256:5944a9b95e97de1980c65f03b79b356f30a43de48682b8bdd90aa5089f0ec1f4",
|
||||||
"sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e",
|
"sha256:6f4e5e68b7af950ed7fdb594b3f19a0014a3ace0fedb86acb896e140ffb24302",
|
||||||
"sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156",
|
"sha256:71a1ef23f22fa8437974b2d60fedb947c99a957ad625f83f43fd3de70f77f458",
|
||||||
"sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142",
|
"sha256:8a44e9901c0555f95ac401377032f6e6af66d8fc1fbfad77a7a8b1a826e0b93c",
|
||||||
"sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442",
|
"sha256:b6577f15d5516d7d209c1a8cde23062c0f10625f19e8dc9fb59268859778d7d7",
|
||||||
"sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62",
|
"sha256:c8fe2d6ff0ff583784039d0255ea7da076efd08507f2be6f68583b0da32e3afb",
|
||||||
"sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db",
|
"sha256:cadfa2c2cf54d35d13dc8d231253b7985b97d629ab9ca6e7d672c35539d38163",
|
||||||
"sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531",
|
"sha256:cd1bdace1a8762534e9a36c073cd54e97d517a17d69a17985961265be6d22847",
|
||||||
"sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383",
|
"sha256:ddbdcd10eb999d7ab292677f588b658372aadb9a52790f82484a37127a390108",
|
||||||
"sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a",
|
"sha256:e7273c64bccfd9310e9601b8f4511d84730239516bada26a0c9846c9697617ef",
|
||||||
"sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357",
|
"sha256:e7428977763150b4cf83255625a80a23dfdc94d43be7791ce90799d446b4e26f",
|
||||||
"sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4",
|
"sha256:e960e8be509e8d6d618300a6c189555c24efde63e85acaf0b14b2cd1ac743315",
|
||||||
"sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"
|
"sha256:ecb5dd5990cec6e7f5c9c1124a37cb2c710c6d69b0c1a5c4aa4b35eba0ada068",
|
||||||
|
"sha256:ef3f5e288aa57b73b034ce9c1f1ac753d968f9069cd0742d1d69c698a0167166",
|
||||||
|
"sha256:fa5b2dee0e231fa4ad117be114251bdfe6afe39213bd629d43deb117b6a6c40a",
|
||||||
|
"sha256:fa7fb7973c622b9e725bee1db569d2c2ee64d2f9a089201c5e8185d482c7352d"
|
||||||
],
|
],
|
||||||
"version": "==1.4.3"
|
"version": "==1.5.2"
|
||||||
},
|
},
|
||||||
"mccabe": {
|
"mccabe": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -160,47 +163,49 @@
|
|||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.6.0"
|
"version": "==2.6.0"
|
||||||
},
|
},
|
||||||
"six": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
|
|
||||||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
|
|
||||||
],
|
|
||||||
"version": "==1.15.0"
|
|
||||||
},
|
|
||||||
"toml": {
|
"toml": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f",
|
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
|
||||||
"sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"
|
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.10.1"
|
"version": "==0.10.2"
|
||||||
},
|
},
|
||||||
"typed-ast": {
|
"typed-ast": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
|
"sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1",
|
||||||
"sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
|
"sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d",
|
||||||
"sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
|
"sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6",
|
||||||
"sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
|
"sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd",
|
||||||
"sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
|
"sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37",
|
||||||
"sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
|
"sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151",
|
||||||
"sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
|
"sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07",
|
||||||
"sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
|
"sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440",
|
||||||
"sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
|
"sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70",
|
||||||
"sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
|
"sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496",
|
||||||
"sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
|
"sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea",
|
||||||
"sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
|
"sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400",
|
||||||
"sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
|
"sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc",
|
||||||
"sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
|
"sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606",
|
||||||
"sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
|
"sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc",
|
||||||
"sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
|
"sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581",
|
||||||
"sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
|
"sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412",
|
||||||
"sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
|
"sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a",
|
||||||
"sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
|
"sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2",
|
||||||
"sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
|
"sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787",
|
||||||
"sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
|
"sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f",
|
||||||
|
"sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937",
|
||||||
|
"sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64",
|
||||||
|
"sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487",
|
||||||
|
"sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b",
|
||||||
|
"sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41",
|
||||||
|
"sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a",
|
||||||
|
"sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3",
|
||||||
|
"sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166",
|
||||||
|
"sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10"
|
||||||
],
|
],
|
||||||
"markers": "implementation_name == 'cpython' and python_version < '3.8'",
|
"markers": "implementation_name == 'cpython' and python_version < '3.8'",
|
||||||
"version": "==1.4.1"
|
"version": "==1.4.2"
|
||||||
},
|
},
|
||||||
"wrapt": {
|
"wrapt": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
"""Entry point used for either runnning or freezing the bot."""
|
"""Entry point used for either runnning or freezing the bot."""
|
||||||
import pointsbot
|
import pointsbot
|
||||||
|
|
||||||
|
try:
|
||||||
pointsbot.run()
|
pointsbot.run()
|
||||||
|
except KeyboardInterrupt as e:
|
||||||
|
print('\nShutting down...\n')
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ def is_valid_tag(solved_comment, valid_tags):
|
|||||||
|
|
||||||
|
|
||||||
# def find_solver(solved_comment):
|
# def find_solver(solved_comment):
|
||||||
def find_solver_and_comment(solved_comment)
|
def find_solver_and_comment(solved_comment):
|
||||||
"""Determine the redditor responsible for solving the question."""
|
"""Determine the redditor responsible for solving the question."""
|
||||||
# TODO plz make this better someday
|
# TODO plz make this better someday
|
||||||
# return solved_comment.parent().author
|
# return solved_comment.parent().author
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
|
import logging
|
||||||
import os.path
|
import os.path
|
||||||
|
import re
|
||||||
import sqlite3 as sqlite
|
import sqlite3 as sqlite
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
### Decorators ###
|
### Decorators ###
|
||||||
|
|
||||||
|
|
||||||
def transaction(func):
|
def transaction(func):
|
||||||
"""Use this decorator on any methods that needs to query the database to
|
"""Use this decorator on any methods that needs to query the database to
|
||||||
ensure that connections are properly opened and closed.
|
ensure that connections are properly opened and closed, without being
|
||||||
|
left open unnecessarily.
|
||||||
"""
|
"""
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def newfunc(self, *args, **kwargs):
|
def newfunc(self, *args, **kwargs):
|
||||||
@@ -20,7 +22,16 @@ def transaction(func):
|
|||||||
self.cursor = self.conn.cursor()
|
self.cursor = self.conn.cursor()
|
||||||
created_conn = True
|
created_conn = True
|
||||||
|
|
||||||
ret = func(self, *args, **kwargs)
|
try:
|
||||||
|
return_value = func(self, *args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
if self.conn.in_transaction:
|
||||||
|
self.conn.rollback()
|
||||||
|
if created_conn:
|
||||||
|
self.cursor.close()
|
||||||
|
self.conn.close()
|
||||||
|
self.cursor = self.conn = None
|
||||||
|
raise e
|
||||||
|
|
||||||
if self.conn.in_transaction:
|
if self.conn.in_transaction:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
@@ -30,61 +41,98 @@ def transaction(func):
|
|||||||
self.conn.close()
|
self.conn.close()
|
||||||
self.cursor = self.conn = None
|
self.cursor = self.conn = None
|
||||||
|
|
||||||
return ret
|
return return_value
|
||||||
|
|
||||||
return newfunc
|
return newfunc
|
||||||
|
|
||||||
|
|
||||||
### Classes ###
|
### Classes ###
|
||||||
|
|
||||||
DatabaseVersion = namedtuple('DatabaseVersion', 'major minor patch pre_release_name pre_release_number')
|
class DatabaseVersion:
|
||||||
|
|
||||||
|
PRE_RELEASE_NAME_ORDER_NUMBER = {
|
||||||
|
None: None,
|
||||||
|
'alpha': 0,
|
||||||
|
'beta': 1,
|
||||||
|
'rc': 2
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, major, minor, patch, pre_release_name=None, pre_release_number=None):
|
||||||
|
self.major = major
|
||||||
|
self.minor = minor
|
||||||
|
self.patch = patch
|
||||||
|
self.pre_release_name = pre_release_name
|
||||||
|
self.pre_release_number = pre_release_number
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
self_tuple = (self.major, self.minor, self.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[self.pre_release_name], self.pre_release_number)
|
||||||
|
other_tuple = (other.major, other.minor, other.patch, self.PRE_RELEASE_NAME_ORDER_NUMBER[other.pre_release_name], other.pre_release_number)
|
||||||
|
return self_tuple < other_tuple
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
version_string = f'{self.major}.{self.minor}.{self.patch}'
|
||||||
|
if self.pre_release_name is not None:
|
||||||
|
version_string += f'-{self.pre_release_name}'
|
||||||
|
if self.pre_release_number is not None:
|
||||||
|
version_string += f'.{self.pre_release_number}'
|
||||||
|
return version_string
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_string(cls, version_string):
|
||||||
|
match = re.match(r'(\d+).(\d+).(\d+)(?:-([:alpha:]+)(?:.(\d+))?)?', version_string)
|
||||||
|
if not match:
|
||||||
|
return None
|
||||||
|
groups = match.groups()
|
||||||
|
return cls(int(groups[0]), int(groups[1]), int(groups[2]), groups[3], int(groups[4]))
|
||||||
|
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
|
|
||||||
VERSION = DatabaseVersion(0, 2, 0, None, None)
|
# LATEST_VERSION = DatabaseVersion(0, 2, 0, None, None)
|
||||||
|
LATEST_VERSION = DatabaseVersion(0, 2, 0)
|
||||||
SCHEMA = '''
|
|
||||||
---------------------------
|
|
||||||
-- Schema version: 0.1.0 --
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
|
SCHEMA_VERSION_STATEMENTS = {
|
||||||
|
DatabaseVersion(0, 1, 0): [
|
||||||
|
'''
|
||||||
CREATE TABLE IF NOT EXISTS redditor_points (
|
CREATE TABLE IF NOT EXISTS redditor_points (
|
||||||
id TEXT UNIQUE NOT NULL,
|
id TEXT UNIQUE NOT NULL,
|
||||||
name TEXT UNIQUE NOT NULL,
|
name TEXT UNIQUE NOT NULL,
|
||||||
points INTEGER DEFAULT 0
|
points INTEGER DEFAULT 0
|
||||||
);
|
)
|
||||||
|
'''
|
||||||
---------------------------
|
],
|
||||||
-- Schema version: 0.2.0 --
|
DatabaseVersion(0, 2, 0): [
|
||||||
---------------------------
|
'''
|
||||||
|
|
||||||
-- Tracking bot/db version for potential future use in migrations et al.
|
|
||||||
CREATE TABLE IF NOT EXISTS bot_version (
|
CREATE TABLE IF NOT EXISTS bot_version (
|
||||||
major INTEGER NOT NULL,
|
major INTEGER NOT NULL,
|
||||||
minor INTEGER NOT NULL,
|
minor INTEGER NOT NULL,
|
||||||
patch INTEGER NOT NULL,
|
patch INTEGER NOT NULL,
|
||||||
pre_release_name TEXT,
|
pre_release_name TEXT,
|
||||||
pre_release_number INTEGER
|
pre_release_number INTEGER
|
||||||
);
|
)
|
||||||
INSERT OR IGNORE INTO bot_version (major, minor, patch) VALUES (0, 2, 0);
|
''',
|
||||||
|
'''
|
||||||
ALTER TABLE redditor_points RENAME TO redditor;
|
INSERT OR IGNORE INTO bot_version (major, minor, patch) VALUES (0, 2, 0)
|
||||||
-- TODO rename "id" columns to "reddit_id" for consistency/clarity?
|
''',
|
||||||
-- ALTER TABLE redditor RENAME COLUMN id TO reddit_id;
|
'''
|
||||||
|
ALTER TABLE redditor_points RENAME TO redditor
|
||||||
|
''',
|
||||||
|
'''
|
||||||
CREATE TABLE IF NOT EXISTS submission (
|
CREATE TABLE IF NOT EXISTS submission (
|
||||||
id TEXT UNIQUE NOT NULL,
|
id TEXT UNIQUE NOT NULL,
|
||||||
author_id TEXT UNIQUE NOT NULL
|
author_id TEXT UNIQUE NOT NULL
|
||||||
);
|
)
|
||||||
|
''',
|
||||||
|
'''
|
||||||
CREATE TABLE IF NOT EXISTS comment (
|
CREATE TABLE IF NOT EXISTS comment (
|
||||||
id TEXT UNIQUE NOT NULL,
|
id TEXT UNIQUE NOT NULL,
|
||||||
author_id TEXT NOT NULL,
|
author_id TEXT NOT NULL,
|
||||||
author_rowid INTEGER, -- May be NULL **for now**
|
author_rowid INTEGER, -- May be NULL **for now**
|
||||||
created_at_datetime TEXT NOT NULL,
|
created_at_datetime TEXT NOT NULL,
|
||||||
FOREIGN KEY (author_rowid) REFERENCES redditor (rowid) ON DELETE CASCADE
|
FOREIGN KEY (author_rowid) REFERENCES redditor (rowid) ON DELETE CASCADE
|
||||||
);
|
)
|
||||||
|
''',
|
||||||
|
'''
|
||||||
CREATE TABLE IF NOT EXISTS solution (
|
CREATE TABLE IF NOT EXISTS solution (
|
||||||
submission_rowid INTEGER NOT NULL,
|
submission_rowid INTEGER NOT NULL,
|
||||||
author_rowid INTEGER NOT NULL,
|
author_rowid INTEGER NOT NULL,
|
||||||
@@ -96,9 +144,11 @@ class Database:
|
|||||||
FOREIGN KEY (comment_rowid) REFERENCES comment (rowid) ON DELETE CASCADE,
|
FOREIGN KEY (comment_rowid) REFERENCES comment (rowid) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (chosen_by_comment_rowid) REFERENCES comment (rowid) ON DELETE SET NULL,
|
FOREIGN KEY (chosen_by_comment_rowid) REFERENCES comment (rowid) ON DELETE SET NULL,
|
||||||
FOREIGN KEY (removed_by_comment_rowid) REFERENCES comment (rowid) ON DELETE SET NULL,
|
FOREIGN KEY (removed_by_comment_rowid) REFERENCES comment (rowid) ON DELETE SET NULL,
|
||||||
PRIMARY KEY (submission_rowid, author_rowid) ON DELETE CASCADE
|
PRIMARY KEY (submission_rowid, author_rowid)
|
||||||
);
|
)
|
||||||
'''
|
'''
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, dbpath):
|
def __init__(self, dbpath):
|
||||||
self.path = dbpath
|
self.path = dbpath
|
||||||
@@ -106,28 +156,41 @@ class Database:
|
|||||||
self.cursor = None
|
self.cursor = None
|
||||||
|
|
||||||
if not os.path.exists(self.path):
|
if not os.path.exists(self.path):
|
||||||
self._create()
|
logging.info('No database found; creating...')
|
||||||
|
self._run_migrations()
|
||||||
|
logging.info('Successfully created database')
|
||||||
else:
|
else:
|
||||||
self._migrate_if_necessary()
|
current_version = self._get_current_version()
|
||||||
|
if current_version != self.LATEST_VERSION:
|
||||||
|
logging.info('Newer database version exists; migrating...')
|
||||||
|
self._run_migrations(current_version)
|
||||||
|
logging.info('Successfully completed all migrations')
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def _create(self):
|
def _run_migrations(self, current_version=None):
|
||||||
self.cursor.execute(self.SCHEMA)
|
if not current_version:
|
||||||
|
current_version = DatabaseVersion(0, 0, 0)
|
||||||
|
logging.info(f'Current database version: {current_version}')
|
||||||
|
versions = sorted(v for v in self.SCHEMA_VERSION_STATEMENTS if current_version < v)
|
||||||
|
for v in versions:
|
||||||
|
logging.info(f'Beginning migration to version: {v}...')
|
||||||
|
for sql_stmt in self.SCHEMA_VERSION_STATEMENTS[v]:
|
||||||
|
self.cursor.execute(sql_stmt)
|
||||||
|
logging.info(f'Successfully completed migration')
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def _migrate_if_necessary(self):
|
def _get_current_version(self):
|
||||||
self.cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'bot_version'")
|
self.cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'bot_version'")
|
||||||
has_version_table = (self.cursor.rowcount == 1)
|
has_version_table = (self.cursor.rowcount == 1)
|
||||||
has_outdated_version = False
|
if not has_version_table:
|
||||||
if has_version_table:
|
current_version = DatabaseVersion(0, 1, 0)
|
||||||
|
else:
|
||||||
self.cursor.execute('SELECT major, minor, patch, pre_release_name, pre_release_number FROM bot_version')
|
self.cursor.execute('SELECT major, minor, patch, pre_release_name, pre_release_number FROM bot_version')
|
||||||
row = self.cursor.fetchone()
|
row = self.cursor.fetchone()
|
||||||
pre_release_number = int(row['pre_release_number']) if row['pre_release_number'] else None
|
pre_release_number = int(row['pre_release_number']) if row['pre_release_number'] else None
|
||||||
current_version = DatabaseVersion(int(row['major']), int(row['minor']), int(row['patch']), row['pre_release_name'], pre_release_number)
|
current_version = DatabaseVersion(int(row['major']), int(row['minor']), int(row['patch']), row['pre_release_name'], pre_release_number)
|
||||||
has_outdated_version = (current_version == self.VERSION)
|
|
||||||
|
|
||||||
if not has_version_table or has_outdated_version:
|
return current_version
|
||||||
self.cursor.execute(self.SCHEMA)
|
|
||||||
|
|
||||||
### Public Methods ###
|
### Public Methods ###
|
||||||
|
|
||||||
@@ -151,18 +214,14 @@ class Database:
|
|||||||
return self.cursor.rowcount
|
return self.cursor.rowcount
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
# def has_already_solved_once(self, solver, submission):
|
|
||||||
def has_already_solved_once(self, submission, solver):
|
def has_already_solved_once(self, submission, solver):
|
||||||
# author_id = self._get_rowid_from_reddit_id('redditor', solver)
|
|
||||||
select_stmt = '''
|
select_stmt = '''
|
||||||
SELECT count(solution.rowid) AS num_solutions
|
SELECT count(solution.rowid) AS num_solutions
|
||||||
FROM solution
|
FROM solution
|
||||||
JOIN submission ON (solution.submission_rowid = submission.rowid)
|
JOIN submission ON (solution.submission_rowid = submission.rowid)
|
||||||
JOIN redditor ON (solution.author_rowid = redditor.rowid)
|
JOIN redditor ON (solution.author_rowid = redditor.rowid)
|
||||||
-- JOIN comment ON (solution.comment_rowid = comment.rowid)
|
|
||||||
WHERE submission.id = :submission_id
|
WHERE submission.id = :submission_id
|
||||||
AND redditor.id = :author_id
|
AND redditor.id = :author_id
|
||||||
-- AND comment.author_id = :author_id
|
|
||||||
'''
|
'''
|
||||||
self.cursor.execute(select_stmt, {'submission_id': submission.id, 'author_id': solver.id})
|
self.cursor.execute(select_stmt, {'submission_id': submission.id, 'author_id': solver.id})
|
||||||
row = self.cursor.fetchone()
|
row = self.cursor.fetchone()
|
||||||
@@ -174,32 +233,24 @@ class Database:
|
|||||||
self._add_comment(chosen_by_comment, chooser)
|
self._add_comment(chosen_by_comment, chooser)
|
||||||
|
|
||||||
self._update_points(solver, 1)
|
self._update_points(solver, 1)
|
||||||
# rowcount = self._add_solution(submission, solution_comment, chosen_by_comment)
|
|
||||||
rowcount = self._add_solution(submission, solver, solution_comment, chosen_by_comment)
|
rowcount = self._add_solution(submission, solver, solution_comment, chosen_by_comment)
|
||||||
if rowcount == 0:
|
if rowcount == 0:
|
||||||
# Was not able to add solution, probably because user has already solved this submission
|
# Was not able to add solution, probably because user has already solved this submission
|
||||||
self._update_points(solver, -1)
|
self._update_points(solver, -1)
|
||||||
# if rowcount > 0:
|
# if rowcount > 0:
|
||||||
# rowcount = self._update_points(solver, 1)
|
|
||||||
# # TODO update author_rowid for comment?
|
# # TODO update author_rowid for comment?
|
||||||
return rowcount
|
return rowcount
|
||||||
|
|
||||||
# def remove_point_for_solution(self, submission, solver, solution_comment, remover, removed_by_comment):
|
|
||||||
# def remove_point_for_solution(self, submission, solver, remover, removed_by_comment):
|
|
||||||
def soft_remove_point_for_solution(self, submission, solver, remover, removed_by_comment):
|
def soft_remove_point_for_solution(self, submission, solver, remover, removed_by_comment):
|
||||||
# submission = removed_by_comment.submission
|
|
||||||
self._add_comment(removed_by_comment, remover)
|
self._add_comment(removed_by_comment, remover)
|
||||||
# rowcount = self._soft_remove_solution(submission, solution_comment, removed_by_comment)
|
|
||||||
rowcount = self._soft_remove_solution(submission, solver, removed_by_comment)
|
rowcount = self._soft_remove_solution(submission, solver, removed_by_comment)
|
||||||
if rowcount > 0:
|
if rowcount > 0:
|
||||||
rowcount = self._update_points(solver, -1)
|
rowcount = self._update_points(solver, -1)
|
||||||
# TODO move "remove redditor" logic here since it doesn't need to be considered when adding points?
|
|
||||||
return rowcount
|
return rowcount
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def add_back_point_for_solution(self, submission, solver):
|
def add_back_point_for_solution(self, submission, solver):
|
||||||
self._update_points(solver, 1)
|
self._update_points(solver, 1)
|
||||||
# submission_rowid = self._get_submission_rowid(submission)
|
|
||||||
submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
|
submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
|
||||||
author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
|
author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
|
||||||
params = {'submission_rowid': submission_rowid, 'author_rowid': author_rowid}
|
params = {'submission_rowid': submission_rowid, 'author_rowid': author_rowid}
|
||||||
@@ -266,12 +317,6 @@ class Database:
|
|||||||
self.cursor.execute(insert_stmt, params)
|
self.cursor.execute(insert_stmt, params)
|
||||||
return self.cursor.rowcount
|
return self.cursor.rowcount
|
||||||
|
|
||||||
# @transaction
|
|
||||||
# def _get_comment_rowid(self, comment):
|
|
||||||
# self.cursor.execute('SELECT rowid FROM comment WHERE id = :id', {'id': comment.id})
|
|
||||||
# row = self.cursor.fetchone()
|
|
||||||
# return row['rowid'] if row else None
|
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def _add_submission(self, submission):
|
def _add_submission(self, submission):
|
||||||
insert_stmt = '''
|
insert_stmt = '''
|
||||||
@@ -281,17 +326,8 @@ class Database:
|
|||||||
self.cursor.execute(insert_stmt, {'id': submission.id, 'author_id': submission.author.id})
|
self.cursor.execute(insert_stmt, {'id': submission.id, 'author_id': submission.author.id})
|
||||||
return self.cursor.rowcount
|
return self.cursor.rowcount
|
||||||
|
|
||||||
# @transaction
|
|
||||||
# def _get_submission_rowid(self, submission):
|
|
||||||
# self.cursor.execute('SELECT rowid FROM submission WHERE id = :id', {'id': submission.id})
|
|
||||||
# row = self.cursor.fetchone()
|
|
||||||
# return row['rowid'] if row else None
|
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def _add_solution(self, submission, solver, comment, chosen_by_comment):
|
def _add_solution(self, submission, solver, comment, chosen_by_comment):
|
||||||
# submission_rowid = self._get_submission_rowid(submission)
|
|
||||||
# comment_rowid = self._get_comment_rowid(comment)
|
|
||||||
# chosen_by_comment_rowid = self._get_comment_rowid(chosen_by_comment)
|
|
||||||
submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
|
submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
|
||||||
author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
|
author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
|
||||||
comment_rowid = self._get_rowid_from_reddit_id('comment', comment)
|
comment_rowid = self._get_rowid_from_reddit_id('comment', comment)
|
||||||
@@ -310,18 +346,12 @@ class Database:
|
|||||||
return self.cursor.rowcount
|
return self.cursor.rowcount
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
# def _soft_remove_solution(self, submission, comment, removed_by_comment):
|
|
||||||
def _soft_remove_solution(self, submission, solver, removed_by_comment):
|
def _soft_remove_solution(self, submission, solver, removed_by_comment):
|
||||||
# submission_rowid = self._get_submission_rowid(submission)
|
|
||||||
# comment_rowid = self._get_comment_rowid(comment)
|
|
||||||
# removed_by_comment_rowid = self._get_comment_rowid(removed_by_comment)
|
|
||||||
submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
|
submission_rowid = self._get_rowid_from_reddit_id('submission', submission)
|
||||||
author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
|
author_rowid = self._get_rowid_from_reddit_id('redditor', solver)
|
||||||
# comment_rowid = self._get_rowid_from_reddit_id('comment', comment)
|
|
||||||
removed_by_comment_rowid = self._get_rowid_from_reddit_id('comment', removed_by_comment)
|
removed_by_comment_rowid = self._get_rowid_from_reddit_id('comment', removed_by_comment)
|
||||||
params = {
|
params = {
|
||||||
'submission_rowid': submission_rowid,
|
'submission_rowid': submission_rowid,
|
||||||
# 'comment_rowid': comment_rowid,
|
|
||||||
'author_rowid': author_rowid,
|
'author_rowid': author_rowid,
|
||||||
'removed_by_comment_rowid': removed_by_comment_rowid,
|
'removed_by_comment_rowid': removed_by_comment_rowid,
|
||||||
}
|
}
|
||||||
@@ -333,12 +363,6 @@ class Database:
|
|||||||
self.cursor.execute(update_stmt, params)
|
self.cursor.execute(update_stmt, params)
|
||||||
return self.cursor.rowcount
|
return self.cursor.rowcount
|
||||||
|
|
||||||
# @transaction
|
|
||||||
# def _get_redditor_rowid(self, redditor):
|
|
||||||
# self.cursor.execute('SELECT rowid FROM redditor WHERE id = :id', {'id': redditor.id})
|
|
||||||
# row = self.cursor.fetchone()
|
|
||||||
# return row['rowid'] if row else None
|
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def _update_points(self, redditor, points_modifier):
|
def _update_points(self, redditor, points_modifier):
|
||||||
"""points_modifier is positive to add points, negative to subtract."""
|
"""points_modifier is positive to add points, negative to subtract."""
|
||||||
|
|||||||
Reference in New Issue
Block a user