Refactor to remove pandas dependency (#177)

* Use regular dicts for sleep pattern (WIP)

* Remove dataframes code from sleep pattern graph

* Reimplement UTC offset change handling

* Move label formatting in to a function

* Remove pandas!

* Fix linting issue

* Add dev requirements to generated requirements.txt

* Stop committing Pipfile.lock

Pipenv is designed to pin to a specific version of Python. Including the lock
file can lead to failed builds or broken package configurations on different
system architectures and/or Python versions.
This commit is contained in:
Christopher Charbonneau Wells 2020-12-02 20:15:22 -08:00 committed by GitHub
parent 6d601abf30
commit 3f1a7d9a9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 100 additions and 670 deletions

6
.gitignore vendored
View File

@ -25,3 +25,9 @@ docker-compose.yml
# Django media root directory. # Django media root directory.
/media /media
# Pipfile.lock.
# Committing this file makes it difficult to support multiple Python versions as
# requirements can different between versions, but the Pipfile only supports
# locking to one version.
Pipfile.lock

View File

@ -3,7 +3,6 @@ ENV PYTHONUNBUFFERED 1
RUN pip install --upgrade pipenv gunicorn RUN pip install --upgrade pipenv gunicorn
WORKDIR /app WORKDIR /app
COPY Pipfile /app/ COPY Pipfile /app/
COPY Pipfile.lock /app/
RUN pipenv install --deploy --system RUN pipenv install --deploy --system
ADD manage.py /app/ ADD manage.py /app/
ADD api /app/api ADD api /app/api

View File

@ -8,7 +8,6 @@ djangorestframework = "*"
django-filter = "*" django-filter = "*"
django-widget-tweaks = "*" django-widget-tweaks = "*"
plotly = "*" plotly = "*"
pandas = "*"
faker = "*" faker = "*"
dj-database-url = "*" dj-database-url = "*"
gunicorn = "*" gunicorn = "*"

571
Pipfile.lock generated
View File

@ -1,571 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "b4b3273cf82cabd1475cec47c4b7b5139e28e054527f5ce00e70635560f8bb4c"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
},
"default": {
"asgiref": {
"hashes": [
"sha256:7e51911ee147dd685c3c8b805c0ad0cb58d360987b56953878f8c06d2d1c6f1a",
"sha256:9fc6fb5d39b8af147ba40765234fa822b39818b12cc80b35ad9b0cef3a476aed"
],
"markers": "python_version >= '3.5'",
"version": "==3.2.10"
},
"boto3": {
"hashes": [
"sha256:60c78f96c690974cd388270e4c82e4807f5034c5544f8a26ec3c3844df726cff",
"sha256:8611d07488bb36b509d9a79a4ab593cf1c96f9c0d177733007568cbfa1079914"
],
"version": "==1.16.4"
},
"botocore": {
"hashes": [
"sha256:c78fe2fb4790e9f06dc40a28402893f12088c4aa88b739475827d9674972f1c4",
"sha256:cd5d2fceef451ee28b149a0c7de848710daab52d8273330e092ccc316d42b2c7"
],
"version": "==1.19.4"
},
"defusedxml": {
"hashes": [
"sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93",
"sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==0.6.0"
},
"diff-match-patch": {
"hashes": [
"sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34",
"sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18"
],
"markers": "python_version >= '2.7'",
"version": "==20200713"
},
"dj-database-url": {
"hashes": [
"sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163",
"sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9"
],
"version": "==0.5.0"
},
"django": {
"hashes": [
"sha256:a2127ad0150ec6966655bedf15dbbff9697cc86d61653db2da1afa506c0b04cc",
"sha256:c93c28ccf1d094cbd00d860e83128a39e45d2c571d3b54361713aaaf9a94cac4"
],
"version": "==3.1.2"
},
"django-filter": {
"hashes": [
"sha256:84e9d5bb93f237e451db814ed422a3a625751cbc9968b484ecc74964a8696b06",
"sha256:e00d32cebdb3d54273c48f4f878f898dced8d5dfaad009438fe61ebdf535ace1"
],
"version": "==2.4.0"
},
"django-import-export": {
"hashes": [
"sha256:401d76eca0a5c6cf43bffed16c06e509b9044ce8f6bcff264b776e3952830f1a",
"sha256:7610f6efff797d65f56c03ba34444507c0b0ccdffe9346c168b9894fc349c55e"
],
"version": "==2.4.0"
},
"django-storages": {
"hashes": [
"sha256:12de8fb2605b9b57bfaf54b075280d7cbb3b3ee1ca4bc9b9add147af87fe3a2c",
"sha256:652275ab7844538c462b62810276c0244866f345878256a9e0e86f5b1283ae18"
],
"version": "==1.10.1"
},
"django-widget-tweaks": {
"hashes": [
"sha256:9f91ca4217199b7671971d3c1f323a2bec71a0c27dec6260b3c006fa541bc489",
"sha256:f80bff4a8a59b278bb277a405a76a8b9a884e4bae7a6c70e78a39c626cd1c836"
],
"version": "==1.4.8"
},
"djangorestframework": {
"hashes": [
"sha256:5c5071fcbad6dce16f566d492015c829ddb0df42965d488b878594aabc3aed21",
"sha256:d54452aedebb4b650254ca092f9f4f5df947cb1de6ab245d817b08b4f4156249"
],
"version": "==3.12.1"
},
"easy-thumbnails": {
"hashes": [
"sha256:e4e7a0dd4001f56bfd4058428f2c91eafe27d33ef3b8b33ac4e013b159b9ff91"
],
"version": "==2.7"
},
"et-xmlfile": {
"hashes": [
"sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b"
],
"version": "==1.0.1"
},
"faker": {
"hashes": [
"sha256:30afa8f564350770373f299d2d267bff42aaba699a7ae0a3b6f378b2a8170569",
"sha256:a7a36c3c657f06bd1e3e3821b9480f2a92017d8a26e150e464ab6b97743cbc92"
],
"version": "==4.14.0"
},
"gunicorn": {
"hashes": [
"sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626",
"sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"
],
"version": "==20.0.4"
},
"jdcal": {
"hashes": [
"sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba",
"sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8"
],
"version": "==1.4.1"
},
"jmespath": {
"hashes": [
"sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9",
"sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'",
"version": "==0.10.0"
},
"markuppy": {
"hashes": [
"sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f"
],
"version": "==1.14"
},
"numpy": {
"hashes": [
"sha256:04c7d4ebc5ff93d9822075ddb1751ff392a4375e5885299445fcebf877f179d5",
"sha256:0bfd85053d1e9f60234f28f63d4a5147ada7f432943c113a11afcf3e65d9d4c8",
"sha256:0c66da1d202c52051625e55a249da35b31f65a81cb56e4c69af0dfb8fb0125bf",
"sha256:0d310730e1e793527065ad7dde736197b705d0e4c9999775f212b03c44a8484c",
"sha256:1669ec8e42f169ff715a904c9b2105b6640f3f2a4c4c2cb4920ae8b2785dac65",
"sha256:2117536e968abb7357d34d754e3733b0d7113d4c9f1d921f21a3d96dec5ff716",
"sha256:3733640466733441295b0d6d3dcbf8e1ffa7e897d4d82903169529fd3386919a",
"sha256:4339741994c775396e1a274dba3609c69ab0f16056c1077f18979bec2a2c2e6e",
"sha256:51ee93e1fac3fe08ef54ff1c7f329db64d8a9c5557e6c8e908be9497ac76374b",
"sha256:54045b198aebf41bf6bf4088012777c1d11703bf74461d70cd350c0af2182e45",
"sha256:58d66a6b3b55178a1f8a5fe98df26ace76260a70de694d99577ddeab7eaa9a9d",
"sha256:59f3d687faea7a4f7f93bd9665e5b102f32f3fa28514f15b126f099b7997203d",
"sha256:62139af94728d22350a571b7c82795b9d59be77fc162414ada6c8b6a10ef5d02",
"sha256:7118f0a9f2f617f921ec7d278d981244ba83c85eea197be7c5a4f84af80a9c3c",
"sha256:7c6646314291d8f5ea900a7ea9c4261f834b5b62159ba2abe3836f4fa6705526",
"sha256:967c92435f0b3ba37a4257c48b8715b76741410467e2bdb1097e8391fccfae15",
"sha256:9a3001248b9231ed73894c773142658bab914645261275f675d86c290c37f66d",
"sha256:aba1d5daf1144b956bc87ffb87966791f5e9f3e1f6fab3d7f581db1f5b598f7a",
"sha256:addaa551b298052c16885fc70408d3848d4e2e7352de4e7a1e13e691abc734c1",
"sha256:b594f76771bc7fc8a044c5ba303427ee67c17a09b36e1fa32bde82f5c419d17a",
"sha256:c35a01777f81e7333bcf276b605f39c872e28295441c265cd0c860f4b40148c1",
"sha256:cebd4f4e64cfe87f2039e4725781f6326a61f095bc77b3716502bed812b385a9",
"sha256:d526fa58ae4aead839161535d59ea9565863bb0b0bdb3cc63214613fb16aced4",
"sha256:d7ac33585e1f09e7345aa902c281bd777fdb792432d27fca857f39b70e5dd31c",
"sha256:e6ddbdc5113628f15de7e4911c02aed74a4ccff531842c583e5032f6e5a179bd",
"sha256:eb25c381d168daf351147713f49c626030dcff7a393d5caa62515d415a6071d8"
],
"markers": "python_version >= '3.6'",
"version": "==1.19.2"
},
"odfpy": {
"hashes": [
"sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec",
"sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0"
],
"version": "==1.4.1"
},
"openpyxl": {
"hashes": [
"sha256:18e11f9a650128a12580a58e3daba14e00a11d9e907c554a17ea016bf1a2c71b",
"sha256:f7d666b569f729257082cf7ddc56262431878f602dcc2bc3980775c59439cdab"
],
"version": "==3.0.5"
},
"pandas": {
"hashes": [
"sha256:206d7c3e5356dcadf082e64dc25c24bc8541718045826074f96346e9d6d05a20",
"sha256:24f61f40febe47edac271eda45d683e42838b7db2bd0f82574d9800259d2b182",
"sha256:3a038cd5da602b955d335aa80cbaa0e5774f68501ff47b9c21509906981478da",
"sha256:427be9938b2f79ab298de84f87693914cda238a27cf10580da96caf3dff64115",
"sha256:54f5f564058b0280d588c3758abde82e280702c440db5faf0c686b80336096f9",
"sha256:5a8a84b75ca3a29bb4263b35d5ed9fcaae2b062f014feed8c5daa897339c7d85",
"sha256:84a4ffe668df357e31f98c829536e3a7142c3036c82f996e639f644c5d32eda1",
"sha256:882012763668af54b48f1412bab95c5cc0a7ccce5a2a8221cfc3839a6e3394ef",
"sha256:920d30fdff65a079f071db635d282b4f583c2b26f2b58d5dca218aac7c59974d",
"sha256:a605054fbca71ed1d08bb2aef6f73c84a579bbac956bfe8f9718d5e84cb41248",
"sha256:b11b496c317dbe007898de699fd59eaf687d0fe8c1b7dad109db6010155d28ae",
"sha256:babbeda2f83b0686c9ad38d93b10516e68cdcd5771007eb80a763e98aaf44613",
"sha256:c22e40f1b4d162ca18eb6b2c572e63eef220dbc9cc3de0241cefb77972621bb7",
"sha256:ca31ac8578d48da354cf66a473d4d5ff99277ca71d321dc7ea4e6fad3c6bb0fd",
"sha256:ca71a5aa9eeb3ef5b31feca7d9b6369d6b3d0b2e9c85d7a89abe3ecb013f1e86",
"sha256:d6b1f9d506dc23da2915bcae5c5968990049c9cec44108bd9855d2c7c89d91dc",
"sha256:d89dbc58aec1544722a8d5046f880b597c497ef8a82c5fe695b4b2effafac5ec",
"sha256:df43ea0e9fd9f9672b0de9cac26d01255ad50481994bf3cb4687c21eec2d7bbc",
"sha256:fd6f05b6101d0e76f3e5c26a47be5be7be96ed84ef3981dc1852e76898e73594"
],
"version": "==1.1.3"
},
"pillow": {
"hashes": [
"sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a",
"sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae",
"sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce",
"sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e",
"sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140",
"sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb",
"sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021",
"sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6",
"sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302",
"sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c",
"sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271",
"sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09",
"sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3",
"sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015",
"sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3",
"sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544",
"sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8",
"sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792",
"sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0",
"sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3",
"sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8",
"sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11",
"sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7",
"sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11",
"sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e",
"sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039",
"sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5",
"sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"
],
"markers": "python_version >= '3.6'",
"version": "==8.0.1"
},
"plotly": {
"hashes": [
"sha256:9ec2c9f4cceac7c595ebb77c98cbeb6566a97bef777508584d9bb7d9bcb8854c",
"sha256:c50babbb4f8ad12e2a4f004df5d80c1dbf10c38e9325b5ffb1146b383687ef52"
],
"version": "==4.12.0"
},
"psycopg2-binary": {
"hashes": [
"sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c",
"sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67",
"sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0",
"sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db",
"sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94",
"sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52",
"sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b",
"sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd",
"sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550",
"sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679",
"sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83",
"sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77",
"sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2",
"sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77",
"sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2",
"sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd",
"sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859",
"sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1",
"sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25",
"sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152",
"sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf",
"sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f",
"sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729",
"sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71",
"sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66",
"sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4",
"sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449",
"sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da",
"sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a",
"sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c",
"sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb",
"sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4",
"sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5"
],
"version": "==2.8.6"
},
"python-dateutil": {
"hashes": [
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.8.1"
},
"python-dotenv": {
"hashes": [
"sha256:8c10c99a1b25d9a68058a1ad6f90381a62ba68230ca93966882a4dbc3bc9c33d",
"sha256:c10863aee750ad720f4f43436565e4c1698798d763b63234fb5021b6c616e423"
],
"version": "==0.14.0"
},
"pytz": {
"hashes": [
"sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed",
"sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"
],
"version": "==2020.1"
},
"pyyaml": {
"hashes": [
"sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97",
"sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76",
"sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2",
"sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648",
"sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf",
"sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f",
"sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2",
"sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee",
"sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d",
"sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c",
"sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"
],
"version": "==5.3.1"
},
"retrying": {
"hashes": [
"sha256:08c039560a6da2fe4f2c426d0766e284d3b736e355f8dd24b37367b0bb41973b"
],
"version": "==1.3.3"
},
"s3transfer": {
"hashes": [
"sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13",
"sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db"
],
"version": "==0.3.3"
},
"six": {
"hashes": [
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==1.15.0"
},
"sqlparse": {
"hashes": [
"sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0",
"sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"
],
"markers": "python_version >= '3.5'",
"version": "==0.4.1"
},
"tablib": {
"extras": [
"html",
"ods",
"xls",
"xlsx",
"yaml"
],
"hashes": [
"sha256:8cc2fa10bc37219ac5e76850eb7fbd50de313c7a1a7895c44af2a8dd206b7be7",
"sha256:c5a77c96ad306d5b380def1309d521ad5e98b4f83726f84857ad87e142d13279"
],
"markers": "python_version >= '3.5'",
"version": "==2.0.0"
},
"text-unidecode": {
"hashes": [
"sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8",
"sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"
],
"version": "==1.3"
},
"uritemplate": {
"hashes": [
"sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f",
"sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"
],
"version": "==3.0.1"
},
"urllib3": {
"hashes": [
"sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2",
"sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"
],
"markers": "python_version != '3.4'",
"version": "==1.25.11"
},
"whitenoise": {
"hashes": [
"sha256:05ce0be39ad85740a78750c86a93485c40f08ad8c62a6006de0233765996e5c7",
"sha256:05d00198c777028d72d8b0bbd234db605ef6d60e9410125124002518a48e515d"
],
"version": "==5.2.0"
},
"xlrd": {
"hashes": [
"sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2",
"sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"
],
"version": "==1.2.0"
},
"xlwt": {
"hashes": [
"sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e",
"sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88"
],
"version": "==1.3.0"
}
},
"develop": {
"certifi": {
"hashes": [
"sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3",
"sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"
],
"version": "==2020.6.20"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"coverage": {
"hashes": [
"sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516",
"sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259",
"sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9",
"sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097",
"sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0",
"sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f",
"sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7",
"sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c",
"sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5",
"sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7",
"sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729",
"sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978",
"sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9",
"sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f",
"sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9",
"sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822",
"sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418",
"sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82",
"sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f",
"sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d",
"sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221",
"sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4",
"sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21",
"sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709",
"sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54",
"sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d",
"sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270",
"sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24",
"sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751",
"sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a",
"sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237",
"sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7",
"sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636",
"sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
"version": "==5.3"
},
"coveralls": {
"hashes": [
"sha256:4430b862baabb3cf090d36d84d331966615e4288d8a8c5957e0fd456d0dd8bd6",
"sha256:b3b60c17b03a0dee61952a91aed6f131e0b2ac8bd5da909389c53137811409e1"
],
"version": "==2.1.2"
},
"docopt": {
"hashes": [
"sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"
],
"version": "==0.6.2"
},
"flake8": {
"hashes": [
"sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839",
"sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"
],
"version": "==3.8.4"
},
"idna": {
"hashes": [
"sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
"sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.10"
},
"importlib-metadata": {
"hashes": [
"sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da",
"sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"
],
"markers": "python_version < '3.8'",
"version": "==2.0.0"
},
"ipaddress": {
"hashes": [
"sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc",
"sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2"
],
"version": "==1.0.23"
},
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"pycodestyle": {
"hashes": [
"sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367",
"sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.6.0"
},
"pyflakes": {
"hashes": [
"sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
"sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.2.0"
},
"requests": {
"hashes": [
"sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b",
"sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.24.0"
},
"urllib3": {
"hashes": [
"sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2",
"sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e"
],
"markers": "python_version != '3.4'",
"version": "==1.25.11"
},
"zipp": {
"hashes": [
"sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108",
"sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"
],
"markers": "python_version >= '3.6'",
"version": "==3.4.0"
}
}
}

View File

@ -190,12 +190,6 @@ Python 3.6+, nginx, uwsgi and sqlite and should be sufficient for a few users
pipenv install --three pipenv install --three
pipenv shell pipenv shell
**Note:** Python dependencies are locked on x86-64 architecture. Installs
on other architectures (like Raspberry Pi's ARM) may result in a
``THESE PACKAGES DO NOT MATCH THE HASHES FROM Pipfile.lock!`` error. Add
the ``--skip-lock`` flag to the above command to suppress this error
(i.e.: ``pipenv install --three --dev --skip-lock``).
1. Create a production settings file and set the ``SECRET_KEY`` and ``ALLOWED_HOSTS`` values 1. Create a production settings file and set the ``SECRET_KEY`` and ``ALLOWED_HOSTS`` values

View File

@ -6,4 +6,4 @@ set -euo pipefail
# Prevent heroku-buildpack-python from using pipenv instead of pip and requirements.txt. # Prevent heroku-buildpack-python from using pipenv instead of pip and requirements.txt.
# https://github.com/heroku/heroku-buildpack-python/issues/704 # https://github.com/heroku/heroku-buildpack-python/issues/704
rm Pipfile Pipfile.lock rm Pipfile

View File

@ -4,7 +4,6 @@ from collections import OrderedDict
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import pandas as pd
import plotly.offline as plotly import plotly.offline as plotly
import plotly.graph_objs as go import plotly.graph_objs as go
@ -19,36 +18,35 @@ def sleep_pattern(instances):
:param instances: a QuerySet of Sleep instances. :param instances: a QuerySet of Sleep instances.
:returns: a tuple of the the graph's html and javascript. :returns: a tuple of the the graph's html and javascript.
""" """
# TODO: Simplify this using the bar charts "base" property. times = {}
y_df = pd.DataFrame() labels = {}
text_df = pd.DataFrame()
last_end_time = None last_end_time = None
adjustment = None adjustment = None
df_index = 0
for instance in instances: for instance in instances:
start_time = timezone.localtime(instance.start) start_time = timezone.localtime(instance.start)
end_time = timezone.localtime(instance.end) end_time = timezone.localtime(instance.end)
start_date = start_time.date().isoformat() start_date = start_time.date().isoformat()
duration = instance.duration duration = instance.duration
if start_date not in times:
times[start_date] = []
if start_date not in labels:
labels[start_date] = []
# Check if the previous entry crossed midnight (see below). # Check if the previous entry crossed midnight (see below).
if adjustment: if adjustment:
# Fake (0) entry to keep the color switching logic working. # Fake (0) entry to keep the color switching logic working.
df_index = _add_sleep_entry( times[adjustment['column']].append(0)
y_df, text_df, 0, adjustment['column'], 0) labels[adjustment['column']].append(0)
# Real adjustment entry. # Real adjustment entry.
df_index = _add_sleep_entry( times[adjustment['column']].append(
y_df, adjustment['duration'].seconds/60)
text_df, labels[adjustment['column']].append(_format_label(
df_index, adjustment['duration'],
adjustment['column'], adjustment['start_time'],
adjustment['duration'].seconds/60, adjustment['end_time']))
'Asleep {} ({} to {})'.format(
duration_string(adjustment['duration']),
adjustment['start_time'].strftime('%I:%M %p'),
adjustment['end_time'].strftime('%I:%M %p')
)
)
last_end_time = timezone.localtime(adjustment['end_time']) last_end_time = timezone.localtime(adjustment['end_time'])
adjustment = None adjustment = None
@ -68,49 +66,53 @@ def sleep_pattern(instances):
day=start_time.day, hour=23, minute=59, second=0) day=start_time.day, hour=23, minute=59, second=0)
duration = end_time - start_time duration = end_time - start_time
if start_date not in y_df: if not last_end_time:
last_end_time = start_time.replace(hour=0, minute=0, second=0) last_end_time = start_time.replace(hour=0, minute=0, second=0)
# Awake time. # Awake time.
df_index = _add_sleep_entry( times[start_date].append((start_time - last_end_time).seconds/60)
y_df, labels[start_date].append(None)
text_df,
df_index,
start_date,
(start_time - last_end_time).seconds/60
)
# Asleep time. # Asleep time.
df_index = _add_sleep_entry( times[start_date].append(duration.seconds/60)
y_df, labels[start_date].append(_format_label(duration, start_time,
text_df, end_time))
df_index,
start_date,
duration.seconds/60,
'Asleep {} ({} to {})'.format(
duration_string(duration),
start_time.strftime('%I:%M %p'),
end_time.strftime('%I:%M %p')
)
)
# Update the previous entry duration if an offset change occurred. # Update the previous entry duration if an offset change occurred.
# This can happen when an entry crosses a daylight savings time change. # This can happen when an entry crosses a daylight savings time change.
if start_time.utcoffset() != end_time.utcoffset(): if start_time.utcoffset() != end_time.utcoffset():
diff = start_time.utcoffset() - end_time.utcoffset() diff = start_time.utcoffset() - end_time.utcoffset()
duration -= timezone.timedelta(seconds=diff.seconds) duration -= timezone.timedelta(seconds=diff.seconds)
y_df.at[df_index - 1, start_date] = duration.seconds/60 times[len(times) - 1] = duration.seconds/60
labels[len(labels) - 1] = _format_label(duration, start_time,
end_time)
last_end_time = end_time last_end_time = end_time
dates = list(y_df) dates = list(times.keys())
traces = [] traces = []
color = 'rgba(255, 255, 255, 0)' color = 'rgba(255, 255, 255, 0)'
for index, row in y_df.iterrows():
# Set iterator and determine maximum iteration for dates.
i = 0
max_i = 0
for date_times in times.values():
max_i = max(len(date_times), max_i)
while i < max_i:
y = {}
text = {}
for date in times.keys():
try:
y[date] = times[date][i]
text[date] = labels[date][i]
except IndexError:
y[date] = None
text[date] = None
i += 1
traces.append(go.Bar( traces.append(go.Bar(
x=dates, x=dates,
y=row, y=list(y.values()),
text=text_df.iloc[index], text=list(text.values()),
hoverinfo='text', hoverinfo='text',
marker={'color': color}, marker={'color': color},
marker_line_width=0, marker_line_width=0,
@ -155,23 +157,15 @@ def sleep_pattern(instances):
return utils.split_graph_output(output) return utils.split_graph_output(output)
def _add_sleep_entry(y_df, text_df, index, column, duration, text=''): def _format_label(duration, start_time, end_time):
""" """
Create a duration and text description entry in a DataFrame and return Formats a time block label.
the next index on success. :param duration: Duration.
:param y_df: the y values DataFrame. :param start_time: Start time.
:param text_df: the text values DataFrame. :param end_time: End time.
:param index: the index to target in both y_df and text_df. :return: Formatted string with duration, start, and end time.
:param column: the column (date) to make the entry in.
:param duration: the duration of the entry.
:param text: text to go with the entry (displays on graph hover).
:return: the next index of the DataFrames.
""" """
if column not in y_df: return 'Asleep {} ({} to {})'.format(
y_df.assign(**{column: 0 in range(0, len(y_df.index))}) duration_string(duration),
text_df.assign(**{column: 0 in range(0, len(text_df.index))}) start_time.strftime('%I:%M %p'),
index = 0 end_time.strftime('%I:%M %p'))
y_df.at[index, column] = duration
text_df.at[index, column] = text
return index + 1

View File

@ -1,43 +1,52 @@
-i https://pypi.python.org/simple -i https://pypi.python.org/simple
asgiref==3.2.10 asgiref==3.3.1; python_version >= '3.5'
boto3==1.14.25 boto3==1.16.28
botocore==1.17.25 botocore==1.19.28
defusedxml==0.6.0 certifi==2020.11.8
diff-match-patch==20200713 chardet==3.0.4
coverage==5.3; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'
coveralls==2.2.0
defusedxml==0.6.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
diff-match-patch==20200713; python_version >= '2.7'
dj-database-url==0.5.0 dj-database-url==0.5.0
django-filter==2.3.0 django-filter==2.4.0
django-import-export==2.3.0 django-import-export==2.4.0
django-storages==1.9.1 django-storages==1.10.1
django-widget-tweaks==1.4.8 django-widget-tweaks==1.4.8
django==3.0.8 django==3.1.4
djangorestframework==3.11.0 djangorestframework==3.12.2
docutils==0.15.2 docopt==0.6.2
easy-thumbnails==2.7 easy-thumbnails==2.7.1
et-xmlfile==1.0.1 et-xmlfile==1.0.1
faker==4.1.1 faker==4.18.0
flake8==3.8.4
gunicorn==20.0.4 gunicorn==20.0.4
idna==2.10; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
ipaddress==1.0.23
jdcal==1.4.1 jdcal==1.4.1
jmespath==0.10.0 jmespath==0.10.0; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'
markuppy==1.14 markuppy==1.14
numpy==1.19.1 mccabe==0.6.1
odfpy==1.4.1 odfpy==1.4.1
openpyxl==3.0.4 openpyxl==3.0.5
pandas==1.0.5 pillow==8.0.1; python_version >= '3.6'
pillow==7.2.0 plotly==4.13.0
plotly==4.9.0 psycopg2-binary==2.8.6
psycopg2-binary==2.8.5 pycodestyle==2.6.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
python-dateutil==2.8.1 pyflakes==2.2.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
python-dotenv==0.14.0 python-dateutil==2.8.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'
pytz==2020.1 python-dotenv==0.15.0
pytz==2020.4
pyyaml==5.3.1 pyyaml==5.3.1
requests==2.25.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
retrying==1.3.3 retrying==1.3.3
s3transfer==0.3.3 s3transfer==0.3.3
six==1.15.0 six==1.15.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'
sqlparse==0.3.1 sqlparse==0.4.1; python_version >= '3.5'
tablib[html,ods,xls,xlsx,yaml]==2.0.0 tablib[html,ods,xls,xlsx,yaml]==2.0.0; python_version >= '3.5'
text-unidecode==1.3 text-unidecode==1.3
uritemplate==3.0.1 uritemplate==3.0.1
urllib3==1.25.9 ; python_version != '3.4' urllib3==1.26.2; python_version != '3.4'
whitenoise==5.1.0 whitenoise==5.2.0
xlrd==1.2.0 xlrd==1.2.0
xlwt==1.3.0 xlwt==1.3.0