some linting, a little var renaming
This commit is contained in:
53
Pipfile
Normal file
53
Pipfile
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
[[source]]
|
||||||
|
name = "pypi"
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
appnope = "==0.1.0"
|
||||||
|
certifi = "==2017.4.17"
|
||||||
|
chardet = "==3.0.4"
|
||||||
|
click = "==6.7"
|
||||||
|
decorator = "==4.0.11"
|
||||||
|
falcon = "==1.2.0"
|
||||||
|
future = "==0.16.0"
|
||||||
|
google-api-python-client = "==1.6.2"
|
||||||
|
httplib2 = "==0.10.3"
|
||||||
|
hug = "==2.3.0"
|
||||||
|
idna = "==2.6"
|
||||||
|
ipython = "==6.1.0"
|
||||||
|
itsdangerous = "==0.24"
|
||||||
|
jedi = "==0.10.2"
|
||||||
|
oauth2client = "==4.1.1"
|
||||||
|
parsedatetime = "==2.4"
|
||||||
|
parso = "==0.1.0"
|
||||||
|
pexpect = "==4.2.1"
|
||||||
|
pickleshare = "==0.7.4"
|
||||||
|
ptyprocess = "==0.5.1"
|
||||||
|
pyasn1 = "==0.2.3"
|
||||||
|
pyasn1-modules = "==0.0.9"
|
||||||
|
python-mimeparse = "==1.6.0"
|
||||||
|
pytz = "==2017.2"
|
||||||
|
requests = "==2.18.4"
|
||||||
|
rsa = "==3.4.2"
|
||||||
|
simplegeneric = "==0.8.1"
|
||||||
|
six = "==1.10.0"
|
||||||
|
traitlets = "==4.3.2"
|
||||||
|
twilio = "==6.8.1"
|
||||||
|
uritemplate = "==3.0.0"
|
||||||
|
urllib3 = "==1.21.1"
|
||||||
|
wcwidth = "==0.1.7"
|
||||||
|
Flask = "==0.12.2"
|
||||||
|
ipython_genutils = "==0.2.0"
|
||||||
|
Jinja2 = "==2.9.6"
|
||||||
|
MarkupSafe = "==1.0"
|
||||||
|
prompt_toolkit = "==1.0.14"
|
||||||
|
Pygments = "==2.2.0"
|
||||||
|
PyJWT = "==1.5.0"
|
||||||
|
PySocks = "==1.6.7"
|
||||||
|
Werkzeug = "==0.12.2"
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.7"
|
||||||
354
Pipfile.lock
generated
Normal file
354
Pipfile.lock
generated
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"hash": {
|
||||||
|
"sha256": "3ebef50f16c7bb5fb3eca23f8217d8d093c03d7392e668b62489bd280d9977fb"
|
||||||
|
},
|
||||||
|
"pipfile-spec": 6,
|
||||||
|
"requires": {
|
||||||
|
"python_version": "3.7"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"name": "pypi",
|
||||||
|
"url": "https://pypi.org/simple",
|
||||||
|
"verify_ssl": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"appnope": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
|
||||||
|
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.1.0"
|
||||||
|
},
|
||||||
|
"certifi": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:f4318671072f030a33c7ca6acaef720ddd50ff124d1388e50c1bda4cbd6d7010",
|
||||||
|
"sha256:f7527ebf7461582ce95f7a9e03dd141ce810d40590834f4ec20cddd54234c10a"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2017.4.17"
|
||||||
|
},
|
||||||
|
"chardet": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||||
|
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==3.0.4"
|
||||||
|
},
|
||||||
|
"click": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
|
||||||
|
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==6.7"
|
||||||
|
},
|
||||||
|
"decorator": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:73cbaadb8bc4e3c65fe1100773d56331a2d756cc0f5c7b9d8d5d5223fe04f600",
|
||||||
|
"sha256:953d6bf082b100f43229cf547f4f97f97e970f5ad645ee7601d55ff87afdfe76"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==4.0.11"
|
||||||
|
},
|
||||||
|
"falcon": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:53bb5119d2513613eef6868c829ad47606615ff619590e05f7068a955867173d",
|
||||||
|
"sha256:6f125ce285a8e9124147497a8d4c202a7316ee550d3ceb003f64d2c5740a9805"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.2.0"
|
||||||
|
},
|
||||||
|
"flask": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856",
|
||||||
|
"sha256:49f44461237b69ecd901cc7ce66feea0319b9158743dd27a2899962ab214dac1"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.12.2"
|
||||||
|
},
|
||||||
|
"future": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.16.0"
|
||||||
|
},
|
||||||
|
"google-api-python-client": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:8c2f50f8057571a5f817c74820cadb754d47799c5a4ea463c1500fe8e092c1ae",
|
||||||
|
"sha256:c0f4bcf398c937a43f382eecb384ba9b3a97ef9c24b156420b1b396fcaadd0af"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.6.2"
|
||||||
|
},
|
||||||
|
"httplib2": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:e404d3b7bd86c1bc931906098e7c1305d6a3a6dcef141b8bb1059903abb3ceeb"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.10.3"
|
||||||
|
},
|
||||||
|
"hug": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:2d3b56368a9c07804a244067f08f5c194d555ca05c90ad48445c72d38fb6b7a1"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.3.0"
|
||||||
|
},
|
||||||
|
"idna": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
|
||||||
|
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.6"
|
||||||
|
},
|
||||||
|
"ipython": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:5c53e8ee4d4bec27879982b9f3b4aa2d6e3cfd7b26782d250fa117f85bb29814",
|
||||||
|
"sha256:cd44c7f5ccb2b349ffd6ede10d8e4204c9ab1ede4a8a6c40220cfeb07069171a"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==6.1.0"
|
||||||
|
},
|
||||||
|
"ipython-genutils": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8",
|
||||||
|
"sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.2.0"
|
||||||
|
},
|
||||||
|
"itsdangerous": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.24"
|
||||||
|
},
|
||||||
|
"jedi": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:7abb618cac6470ebbd142e59c23daec5e6e063bfcecc8a43a037d2ab57276f4e",
|
||||||
|
"sha256:96678411f2ffa444da3a5e7fdd4adc513b728a4a4617b30308be5c950722424b"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.10.2"
|
||||||
|
},
|
||||||
|
"jinja2": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:2231bace0dfd8d2bf1e5d7e41239c06c9e0ded46e70cc1094a0aa64b0afeb054",
|
||||||
|
"sha256:ddaa01a212cd6d641401cb01b605f4a4d9f37bfc93043d7f760ec70fb99ff9ff"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.9.6"
|
||||||
|
},
|
||||||
|
"markupsafe": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.0"
|
||||||
|
},
|
||||||
|
"oauth2client": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:ed0c670f09db32444f843d5d2f92df00733751dfec9a28b0fd3f00693ff36a04",
|
||||||
|
"sha256:fd02b705092b76f443028328eaed366135f26c0d3e52bdbf66e649a944938ca1"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==4.1.1"
|
||||||
|
},
|
||||||
|
"parsedatetime": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b",
|
||||||
|
"sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.4"
|
||||||
|
},
|
||||||
|
"parso": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:b573acb69f66a970197b5fdbbdfad3b8a417a520e383133b2b4e708f104bfc9a",
|
||||||
|
"sha256:c5279916bb417aa2bf634648ff895cf35dce371d7319744884827bfad06f8d7b"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.1.0"
|
||||||
|
},
|
||||||
|
"pexpect": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3d132465a75b57aa818341c6521392a06cc660feb3988d7f1074f39bd23c9a92",
|
||||||
|
"sha256:f853b52afaf3b064d29854771e2db509ef80392509bde2dd7a6ecf2dfc3f0018"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==4.2.1"
|
||||||
|
},
|
||||||
|
"pickleshare": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:84a9257227dfdd6fe1b4be1319096c20eb85ff1e82c7932f36efccfe1b09737b",
|
||||||
|
"sha256:c9a2541f25aeabc070f12f452e1f2a8eae2abd51e1cd19e8430402bdf4c1d8b5"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.7.4"
|
||||||
|
},
|
||||||
|
"prompt-toolkit": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:7281b5199235adaef6980942840c43753e4ab20dfe41338da634fb41c194f9d8",
|
||||||
|
"sha256:82c7f8e07d7a0411ff5367a5a8ff520f0112b9179f3e599ee8ad2ad9b943d911",
|
||||||
|
"sha256:cc66413b1b4b17021675d9f2d15d57e640b06ddfd99bb724c73484126d22622f"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.0.14"
|
||||||
|
},
|
||||||
|
"ptyprocess": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:0530ce63a9295bfae7bd06edc02b6aa935619f486f0f1dc0972f516265ee81a6",
|
||||||
|
"sha256:464cb76f7a7122743dd25507650db89cd447c51f38e4671602b3eaa2e38e05ae"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.5.1"
|
||||||
|
},
|
||||||
|
"pyasn1": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:0439b9bd518418260c2641a571f0e07fce4370cab13b68f19b5e023306c03cad",
|
||||||
|
"sha256:738c4ebd88a718e700ee35c8d129acce2286542daa80a82823a7073644f706ad"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.2.3"
|
||||||
|
},
|
||||||
|
"pyasn1-modules": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:9d5008b0c3dc5685aac7977951e7fb222736d5fd817c810fa0cfb08c5fd71630",
|
||||||
|
"sha256:be0e4157e4a53551279d6c6e366b080527f5fd068616835b4abf32c14f657f5f"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.0.9"
|
||||||
|
},
|
||||||
|
"pygments": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
|
||||||
|
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.2.0"
|
||||||
|
},
|
||||||
|
"pyjwt": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:ad60a3fb9b393667864ed4b8abc9c3b570747f80bf77a113ead2fbaf0f0cedf3",
|
||||||
|
"sha256:fd182b728d13f04c289d9b2623d09256d356c9b4a6778018001454a954d7c54b"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.5.0"
|
||||||
|
},
|
||||||
|
"pysocks": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:18842328a4e6061f084cfba70f6950d9140ecf7418b3df7cef558ebb217bac8d",
|
||||||
|
"sha256:d00329f27efa157db7efe3ca26fcd69033cd61f83822461ee3f8a353b48e33cf"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"markers": "python_version >= '3.0'",
|
||||||
|
"version": "==1.6.7"
|
||||||
|
},
|
||||||
|
"python-mimeparse": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:76e4b03d700a641fd7761d3cd4fdbbdcd787eade1ebfac43f877016328334f78",
|
||||||
|
"sha256:a295f03ff20341491bfe4717a39cd0a8cc9afad619ba44b77e86b0ab8a2b8282"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.6.0"
|
||||||
|
},
|
||||||
|
"pytz": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:d1d6729c85acea5423671382868627129432fba9a89ecbb248d8d1c7a9f01c67",
|
||||||
|
"sha256:f5c056e8f62d45ba8215e5cb8f50dfccb198b4b9fbea8500674f3443e4689589"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2017.2"
|
||||||
|
},
|
||||||
|
"requests": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
|
||||||
|
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.18.4"
|
||||||
|
},
|
||||||
|
"rsa": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:25df4e10c263fb88b5ace923dd84bf9aa7f5019687b5e55382ffcdb8bede9db5",
|
||||||
|
"sha256:43f682fea81c452c98d09fc316aae12de6d30c4b5c84226642cf8f8fd1c93abd"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==3.4.2"
|
||||||
|
},
|
||||||
|
"simplegeneric": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:dc972e06094b9af5b855b3df4a646395e43d1c9d0d39ed345b7393560d0b9173"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.8.1"
|
||||||
|
},
|
||||||
|
"six": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1",
|
||||||
|
"sha256:105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.10.0"
|
||||||
|
},
|
||||||
|
"traitlets": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835",
|
||||||
|
"sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==4.3.2"
|
||||||
|
},
|
||||||
|
"twilio": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:919a603186afb69c25746a65e9b1956e02531d4a763b311d546c4857fdf16e67",
|
||||||
|
"sha256:f146ac865bfdca3a79deb07aa3176d0a66a110a2ad55201792938e1af452d9ac"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==6.8.1"
|
||||||
|
},
|
||||||
|
"uritemplate": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd",
|
||||||
|
"sha256:1b9c467a940ce9fb9f50df819e8ddd14696f89b9a8cc87ac77952ba416e0a8fd",
|
||||||
|
"sha256:c02643cebe23fc8adb5e6becffe201185bf06c40bda5c0b4028a93f1527d011d"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==3.0.0"
|
||||||
|
},
|
||||||
|
"urllib3": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:8ed6d5c1ff9d6ba84677310060d6a3a78ca3072ce0684cb3c645023009c114b1",
|
||||||
|
"sha256:b14486978518ca0901a76ba973d7821047409d7f726f22156b24e83fd71382a5"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.21.1"
|
||||||
|
},
|
||||||
|
"wcwidth": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||||
|
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.1.7"
|
||||||
|
},
|
||||||
|
"werkzeug": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:903a7b87b74635244548b30d30db4c8947fe64c5198f58899ddcd3a13c23bb26",
|
||||||
|
"sha256:e8549c143af3ce6559699a01e26fa4174f4c591dbee0a499f3cd4c3781cdec3d"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.12.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"develop": {}
|
||||||
|
}
|
||||||
@@ -49,11 +49,13 @@ def add_sitter(body: str) -> Tuple[str, str]:
|
|||||||
|
|
||||||
assert len(num_only) == 10
|
assert len(num_only) == 10
|
||||||
|
|
||||||
sitters[lowercase_name] = f'+1{num_only}'
|
phone_number = f'+1{num_only}'
|
||||||
|
sitters[lowercase_name] = {'num': phone_number,
|
||||||
|
'name': lowercase_name}
|
||||||
|
|
||||||
return name, sitters[lowercase_name]
|
return name, phone_number
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True, port=8000)
|
app.run(debug=True, port=8000, use_reloader=False)
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ BOOKER_NUM = os.getenv('MY_TWILIO_NUM')
|
|||||||
|
|
||||||
twilio_client = TwilioClient(os.getenv('TWILIO_SID'), os.getenv('TWILIO_TOKEN'))
|
twilio_client = TwilioClient(os.getenv('TWILIO_SID'), os.getenv('TWILIO_TOKEN'))
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
app.config.from_object(__name__)
|
|
||||||
|
|
||||||
sitters = {}
|
sitters = {}
|
||||||
if os.path.exists('sitters.p'):
|
if os.path.exists('sitters.p'):
|
||||||
sitters = pickle.load(open('sitters.p', 'rb'))
|
sitters = pickle.load(open('sitters.p', 'rb'))
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config.from_object(__name__)
|
||||||
|
|
||||||
@app.route('/bot', methods=['POST'])
|
@app.route('/bot', methods=['POST'])
|
||||||
def bot():
|
def bot():
|
||||||
from_ = request.values.get('From')
|
from_ = request.values.get('From')
|
||||||
@@ -91,5 +91,5 @@ if __name__ == '__main__':
|
|||||||
sitter_list = 'Your sitters are ' + ' and '.join(
|
sitter_list = 'Your sitters are ' + ' and '.join(
|
||||||
f'{sitter_name.title()}' for sitter_name in sitters) + '.'
|
f'{sitter_name.title()}' for sitter_name in sitters) + '.'
|
||||||
twilio_client.api.account.messages.create(to=MY_CELL, from_=BOOKER_NUM, body=sitter_list)
|
twilio_client.api.account.messages.create(to=MY_CELL, from_=BOOKER_NUM, body=sitter_list)
|
||||||
app.run(debug=True, port=8000)
|
print(sitter_list)
|
||||||
|
app.run(debug=True, port=8000, use_reloader=False)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from twilio.twiml.messaging_response import MessagingResponse
|
|||||||
twilio_client = TwilioClient(os.getenv('TWILIO_SID'), os.getenv('TWILIO_TOKEN'))
|
twilio_client = TwilioClient(os.getenv('TWILIO_SID'), os.getenv('TWILIO_TOKEN'))
|
||||||
|
|
||||||
MY_CELL = os.getenv('MY_CELL')
|
MY_CELL = os.getenv('MY_CELL')
|
||||||
BOOKER_NUM = os.getenv('MY_TWILIO_NUM')
|
BOT_NUM = os.getenv('MY_TWILIO_NUM')
|
||||||
COUNTRY_CODE = f'+{os.getenv("TWILIO_COUNTRY_CODE")}'
|
COUNTRY_CODE = f'+{os.getenv("TWILIO_COUNTRY_CODE")}'
|
||||||
TIMEOUT_MINUTES = 120
|
TIMEOUT_MINUTES = 120
|
||||||
|
|
||||||
@@ -70,11 +70,11 @@ def bot() -> str:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
start_time, end_time = request_booking(body)
|
start_datetime, end_time = request_booking(body)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
response = 'Please specify an end time (e.g. "tomorrow 5pm to 10pm").'
|
response = 'Please specify an end time (e.g. "tomorrow 5pm to 10pm").'
|
||||||
else:
|
else:
|
||||||
booking_string = make_booking_string(start_time, end_time)
|
booking_string = make_booking_string(start_datetime, end_time)
|
||||||
response = f'Okay, I will reach out to the sitters about sitting on {booking_string}.'
|
response = f'Okay, I will reach out to the sitters about sitting on {booking_string}.'
|
||||||
|
|
||||||
if response is None:
|
if response is None:
|
||||||
@@ -165,8 +165,8 @@ def accept_or_decline(sitter_name: str, body: str) -> str:
|
|||||||
return f'Okay, no problem, {sitter_name.title()}! Next time.'
|
return f'Okay, no problem, {sitter_name.title()}! Next time.'
|
||||||
|
|
||||||
|
|
||||||
def make_booking_string(start_time: datetime.datetime, end_time: datetime.time) -> str:
|
def make_booking_string(start_datetime: datetime.datetime, end_time: datetime.time) -> str:
|
||||||
start_time_and_date_string = start_time.strftime('%-m/%-d from %-I:%M%p')
|
start_time_and_date_string = start_datetime.strftime('%-m/%-d from %-I:%M%p')
|
||||||
end_time_string = end_time.strftime('%-I:%M%p')
|
end_time_string = end_time.strftime('%-I:%M%p')
|
||||||
return f'{start_time_and_date_string} to {end_time_string}'
|
return f'{start_time_and_date_string} to {end_time_string}'
|
||||||
|
|
||||||
@@ -236,12 +236,12 @@ def book_forever():
|
|||||||
def offer_booking(sitter_dict: dict, booking_string: str) -> None:
|
def offer_booking(sitter_dict: dict, booking_string: str) -> None:
|
||||||
message = f'{sitter_dict["name"].title()}, are you available to babysit on {booking_string}?'
|
message = f'{sitter_dict["name"].title()}, are you available to babysit on {booking_string}?'
|
||||||
twilio_client.api.account.messages.create(to=sitter_dict['num'],
|
twilio_client.api.account.messages.create(to=sitter_dict['num'],
|
||||||
from_=BOOKER_NUM,
|
from_=BOT_NUM,
|
||||||
body=message)
|
body=message)
|
||||||
|
|
||||||
|
|
||||||
def update_client(string: str) -> None:
|
def update_client(string: str) -> None:
|
||||||
twilio_client.api.account.messages.create(to=MY_CELL, from_=BOOKER_NUM, body=string)
|
twilio_client.api.account.messages.create(to=MY_CELL, from_=BOT_NUM, body=string)
|
||||||
|
|
||||||
|
|
||||||
def has_phone_num(string):
|
def has_phone_num(string):
|
||||||
@@ -249,19 +249,19 @@ def has_phone_num(string):
|
|||||||
|
|
||||||
|
|
||||||
def request_booking(body: str) -> Tuple[datetime.datetime, datetime.time]:
|
def request_booking(body: str) -> Tuple[datetime.datetime, datetime.time]:
|
||||||
session_start, session_end = parse_booking_request(body)
|
session_start_datetime, session_end_time = parse_booking_request(body)
|
||||||
global bookings
|
global bookings
|
||||||
bookings = load_from_pickle('bookings')
|
bookings = load_from_pickle('bookings')
|
||||||
bookings[(session_start, session_end)] = {'offered': dict()}
|
bookings[(session_start_datetime, session_end_time)] = {'offered': dict()}
|
||||||
persist_bookings()
|
persist_bookings()
|
||||||
return session_start, session_end
|
return session_start_datetime, session_end_time
|
||||||
|
|
||||||
|
|
||||||
def parse_booking_request(body: str) -> Tuple[datetime.datetime, datetime.time]:
|
def parse_booking_request(body: str) -> Tuple[datetime.datetime, datetime.time]:
|
||||||
start_string, end_string = body.split(' to ')
|
start_string, end_string = body.split(' to ')
|
||||||
session_start = cal.parseDT(start_string)[0]
|
session_start_datetime = cal.parseDT(start_string)[0]
|
||||||
session_end_time = datetime.time(cal.parse(end_string)[0].tm_hour)
|
session_end_time = datetime.time(cal.parse(end_string)[0].tm_hour)
|
||||||
return session_start, session_end_time
|
return session_start_datetime, session_end_time
|
||||||
|
|
||||||
|
|
||||||
def add_sitter(body: str) -> Tuple[str, str]:
|
def add_sitter(body: str) -> Tuple[str, str]:
|
||||||
@@ -306,5 +306,5 @@ if __name__ == '__main__':
|
|||||||
'I\'ll try to book one of our sitters!')
|
'I\'ll try to book one of our sitters!')
|
||||||
p = Process(target=book_forever)
|
p = Process(target=book_forever)
|
||||||
p.start()
|
p.start()
|
||||||
app.run(debug=True, port=8000)
|
app.run(debug=True, port=8000, use_reloader=False)
|
||||||
p.join()
|
p.join()
|
||||||
|
|||||||
263
sitter_bot_book_forever_simple.py
Normal file
263
sitter_bot_book_forever_simple.py
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
import datetime
|
||||||
|
from multiprocessing import Process
|
||||||
|
import os
|
||||||
|
from pprint import pprint
|
||||||
|
import time
|
||||||
|
from typing import Tuple, Dict
|
||||||
|
|
||||||
|
import parsedatetime as pdt
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
from flask import request, Flask
|
||||||
|
from twilio.rest import Client as TwilioClient
|
||||||
|
from twilio.twiml.messaging_response import MessagingResponse
|
||||||
|
|
||||||
|
twilio_client = TwilioClient(os.getenv('TWILIO_SID'), os.getenv('TWILIO_TOKEN'))
|
||||||
|
|
||||||
|
MY_CELL = os.getenv('MY_CELL')
|
||||||
|
BOT_NUM = os.getenv('MY_TWILIO_NUM')
|
||||||
|
COUNTRY_CODE = f'+{os.getenv("TWILIO_COUNTRY_CODE")}'
|
||||||
|
TIMEOUT_MINUTES = 120
|
||||||
|
|
||||||
|
help_add = 'You can add a sitter by giving me their first name and 10-digit phone number'
|
||||||
|
help_text = help_add + ', or book a sitter by ' \
|
||||||
|
'specifying a date and time. You can also remove a sitter from the list ' \
|
||||||
|
'with "delete" or "remove" and then their first name.'
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config.from_object(__name__)
|
||||||
|
|
||||||
|
cal = pdt.Calendar()
|
||||||
|
|
||||||
|
|
||||||
|
class TheresAlreadyAnActiveBooking(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def load_from_pickle(var_name: str) -> dict:
|
||||||
|
payload = {}
|
||||||
|
if os.path.exists(f'{var_name}.p'):
|
||||||
|
payload = pickle.load(open(f'{var_name}.p', 'rb'))
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
sitters, bookings = load_from_pickle('sitters'), load_from_pickle('bookings')
|
||||||
|
sitters_num_name_lookup = {v['num']: k for k, v in sitters.items()}
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/bot', methods=['POST'])
|
||||||
|
def bot() -> str:
|
||||||
|
from_ = request.values.get('From')
|
||||||
|
body = request.values.get('Body').lower()
|
||||||
|
|
||||||
|
resp = MessagingResponse()
|
||||||
|
response = ''
|
||||||
|
|
||||||
|
if from_ == MY_CELL:
|
||||||
|
|
||||||
|
if has_phone_num(body):
|
||||||
|
|
||||||
|
try:
|
||||||
|
sitter_name, sitter_num = add_sitter(body)
|
||||||
|
except (AssertionError, ValueError):
|
||||||
|
response = 'Sorry, did you mean to add a sitter? Please try again.'
|
||||||
|
else:
|
||||||
|
response = f'Okay, I added {sitter_name.title()} to sitters, with phone # {sitter_num}. '
|
||||||
|
|
||||||
|
elif any(remove_word in body for remove_word in ['remove', 'delete']):
|
||||||
|
|
||||||
|
try:
|
||||||
|
sitter_name = remove_sitter(body)
|
||||||
|
except KeyError:
|
||||||
|
response = 'No such sitter. Please write "delete [sitter\'s first name]."'
|
||||||
|
else:
|
||||||
|
response = f'Okay, I removed {sitter_name.title()} from the sitters.'
|
||||||
|
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
start_datetime, end_time = request_booking(body)
|
||||||
|
except ValueError:
|
||||||
|
response = 'Please specify an end time (e.g. "tomorrow 5pm to 10pm").'
|
||||||
|
except TheresAlreadyAnActiveBooking:
|
||||||
|
response = 'Please wait until the current booking is either booked or expires.'
|
||||||
|
else:
|
||||||
|
booking_string = make_booking_string(start_datetime, end_time)
|
||||||
|
response = f'Okay, I will reach out to the sitters about sitting on {booking_string}.'
|
||||||
|
|
||||||
|
if response is None:
|
||||||
|
response = 'I wasn\'t sure what to do with your input. ' + help_text
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
sitter_name = sitters_num_name_lookup.get(from_)
|
||||||
|
if sitter_name is not None:
|
||||||
|
response = accept_or_decline(sitter_name, body)
|
||||||
|
|
||||||
|
resp.message(response)
|
||||||
|
|
||||||
|
return str(resp)
|
||||||
|
|
||||||
|
|
||||||
|
def accept_or_decline(sitter_name: str, body: str) -> str:
|
||||||
|
body = body.strip()
|
||||||
|
|
||||||
|
global bookings
|
||||||
|
global sitters
|
||||||
|
|
||||||
|
bookings, sitters = load_from_pickle('bookings'), load_from_pickle('sitters')
|
||||||
|
sitter = sitters[sitter_name]
|
||||||
|
|
||||||
|
sitter_offers = [k for k, v in bookings.items()
|
||||||
|
if sitter_name in v['offered']
|
||||||
|
if v['offered'][sitter_name] not in ['yes', 'no']]
|
||||||
|
|
||||||
|
if len(sitter_offers) == 0:
|
||||||
|
update_client(f'there\'s more than one booking on offer, so I\'m confused!')
|
||||||
|
return f'Sorry, {sitter_name.title()}, there are no pending gigs.'
|
||||||
|
|
||||||
|
elif len(sitter_offers) > 1:
|
||||||
|
return f'I\'m not sure which offer you\'re responding to!'
|
||||||
|
|
||||||
|
offer = sitter_offers[0]
|
||||||
|
booking = bookings[offer]
|
||||||
|
|
||||||
|
if body not in ['yes', 'no', 'n', 'y']:
|
||||||
|
return f'Hm, I\'m not sure what you meant, {sitter_name.title()}. Please write "yes" or "no".'
|
||||||
|
|
||||||
|
if body in ['yes', 'y']:
|
||||||
|
|
||||||
|
booking_string = make_booking_string(*offer)
|
||||||
|
|
||||||
|
if any(booking['offered'][sitter_] == 'yes'
|
||||||
|
for sitter_ in booking['offered'].keys()):
|
||||||
|
return f'Sorry, {sitter_name.title()}, it looks like {booking_string} is already booked.'
|
||||||
|
|
||||||
|
booking['offered'][sitter_name] = 'yes'
|
||||||
|
persist_bookings()
|
||||||
|
update_client(f'{sitter_name.title()} agreed to babysit on {booking_string}!')
|
||||||
|
return f'Awesome, {sitter_name.title()}! See you on {booking_string}.'
|
||||||
|
|
||||||
|
booking['offered'][sitter_name] = 'no'
|
||||||
|
persist_bookings()
|
||||||
|
return f'Okay, no problem, {sitter_name.title()}! Next time.'
|
||||||
|
|
||||||
|
|
||||||
|
def make_booking_string(start_datetime: datetime.datetime, end_time: datetime.time) -> str:
|
||||||
|
start_time_and_date_string = start_datetime.strftime('%-m/%-d from %-I:%M%p')
|
||||||
|
end_time_string = end_time.strftime('%-I:%M%p')
|
||||||
|
return f'{start_time_and_date_string} to {end_time_string}'
|
||||||
|
|
||||||
|
|
||||||
|
def book_forever():
|
||||||
|
while True:
|
||||||
|
|
||||||
|
sitters_, bookings_ = load_from_pickle('sitters'), load_from_pickle('bookings')
|
||||||
|
|
||||||
|
if sitters_ and bookings_:
|
||||||
|
|
||||||
|
for booking_start_and_end, offered_dict in bookings_.items():
|
||||||
|
|
||||||
|
booking = bookings_[booking_start_and_end]
|
||||||
|
offers = booking['offered']
|
||||||
|
|
||||||
|
if any(v == 'yes' for k, v in offers.items()):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if len(sitters_) == len(offers):
|
||||||
|
continue
|
||||||
|
|
||||||
|
booking_string = make_booking_string(*booking_start_and_end)
|
||||||
|
|
||||||
|
for sitter_name, sitter_dict in sitters_.items():
|
||||||
|
if sitter_name not in offers:
|
||||||
|
offer_booking(sitter_dict, booking_string)
|
||||||
|
offers[sitter_name] = datetime.datetime.now()
|
||||||
|
update_client(
|
||||||
|
f'Okay, I offered {booking_string} to {sitter_name.title()}.')
|
||||||
|
|
||||||
|
pprint(bookings_)
|
||||||
|
|
||||||
|
persist_bookings(bookings_)
|
||||||
|
|
||||||
|
# time.sleep(60)
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
|
def offer_booking(sitter_dict: dict, booking_string: str) -> None:
|
||||||
|
message = f'{sitter_dict["name"].title()}, are you available to babysit on {booking_string}?'
|
||||||
|
twilio_client.api.account.messages.create(to=sitter_dict['num'],
|
||||||
|
from_=BOT_NUM,
|
||||||
|
body=message)
|
||||||
|
|
||||||
|
def update_client(string: str) -> None:
|
||||||
|
twilio_client.api.account.messages.create(to=MY_CELL, from_=BOT_NUM, body=string)
|
||||||
|
|
||||||
|
|
||||||
|
def has_phone_num(string):
|
||||||
|
return len([char for char in string if char.isnumeric()]) == 10
|
||||||
|
|
||||||
|
|
||||||
|
def request_booking(body: str) -> Tuple[datetime.datetime, datetime.time]:
|
||||||
|
session_start_datetime, session_end_time = parse_booking_request(body)
|
||||||
|
global bookings
|
||||||
|
bookings = load_from_pickle('bookings')
|
||||||
|
if bookings:
|
||||||
|
raise TheresAlreadyAnActiveBooking
|
||||||
|
bookings[(session_start_datetime, session_end_time)] = {'offered': dict()}
|
||||||
|
persist_bookings()
|
||||||
|
return session_start_datetime, session_end_time
|
||||||
|
|
||||||
|
|
||||||
|
def parse_booking_request(body: str) -> Tuple[datetime.datetime, datetime.time]:
|
||||||
|
start_string, end_string = body.split(' to ')
|
||||||
|
session_start_datetime = cal.parseDT(start_string)[0]
|
||||||
|
session_end_time = datetime.time(cal.parse(end_string)[0].tm_hour)
|
||||||
|
return session_start_datetime, session_end_time
|
||||||
|
|
||||||
|
|
||||||
|
def add_sitter(body: str) -> Tuple[str, str]:
|
||||||
|
name, *num_parts = body.split(' ')
|
||||||
|
|
||||||
|
num_only = ''.join(char
|
||||||
|
for num in num_parts
|
||||||
|
for char in num if char.isnumeric())
|
||||||
|
|
||||||
|
lowercase_name = name.lower()
|
||||||
|
|
||||||
|
assert len(num_only) == 10
|
||||||
|
|
||||||
|
phone_number = f'{COUNTRY_CODE}{num_only}'
|
||||||
|
sitters[lowercase_name] = {'num': phone_number,
|
||||||
|
'name': lowercase_name}
|
||||||
|
|
||||||
|
persist_sitters()
|
||||||
|
return name, phone_number
|
||||||
|
|
||||||
|
|
||||||
|
def remove_sitter(body: str) -> str:
|
||||||
|
sitter_first_name = body.split(' ')[1]
|
||||||
|
sitter = sitters.get(sitter_first_name)
|
||||||
|
if sitter is None:
|
||||||
|
raise KeyError
|
||||||
|
del sitters[sitter_first_name]
|
||||||
|
persist_sitters()
|
||||||
|
return sitter_first_name
|
||||||
|
|
||||||
|
|
||||||
|
def persist_sitters():
|
||||||
|
pickle.dump(sitters, open('sitters.p', 'wb'))
|
||||||
|
|
||||||
|
|
||||||
|
def persist_bookings(bookings_: dict = None):
|
||||||
|
pickle.dump(bookings_ if bookings_ is not None else bookings, open('bookings.p', 'wb'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
update_client('Hi, this is Babysitter Bot, on the job! Send me a date with time range and '
|
||||||
|
'I\'ll try to book one of our sitters!')
|
||||||
|
if not sitters:
|
||||||
|
update_client('Please add at least one babysitter.')
|
||||||
|
p = Process(target=book_forever)
|
||||||
|
p.start()
|
||||||
|
app.run(debug=True, port=8000, use_reloader=False)
|
||||||
|
p.join()
|
||||||
@@ -4,19 +4,19 @@ from flask import Flask, request
|
|||||||
from twilio.rest import Client as TwilioClient
|
from twilio.rest import Client as TwilioClient
|
||||||
from twilio.twiml.messaging_response import MessagingResponse
|
from twilio.twiml.messaging_response import MessagingResponse
|
||||||
|
|
||||||
twilio_client = TwilioClient(os.getenv('TWILIO_SID'), os.getenv('TWILIO_TOKEN'))
|
twilio_client = TwilioClient(os.getenv("TWILIO_SID"), os.getenv("TWILIO_TOKEN"))
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(__name__)
|
app.config.from_object(__name__)
|
||||||
|
|
||||||
@app.route('/bot', methods=['POST'])
|
|
||||||
|
@app.route("/bot", methods=["POST"])
|
||||||
def bot():
|
def bot():
|
||||||
from_ = request.values.get('From')
|
body = request.values.get("Body").lower()
|
||||||
body = request.values.get('Body').lower()
|
|
||||||
resp = MessagingResponse()
|
resp = MessagingResponse()
|
||||||
resp.message(f'ok, you said {body}.')
|
resp.message(f"ok, you said {body}.")
|
||||||
return str(resp)
|
return str(resp)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app.run(debug=True, port=8000)
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(debug=True, port=8000)
|
||||||
|
|||||||
Reference in New Issue
Block a user