From 9f60274453b3f86364c2416608cd2901114757d7 Mon Sep 17 00:00:00 2001 From: GitLukeW <102833183+GitLukeW@users.noreply.github.com> Date: Sat, 14 Oct 2023 12:46:20 -0400 Subject: [PATCH 01/18] Update staging (#163) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Deploy 10/02/2023 (#150) * Deploy 09182023 (#143) (#144) * updated cors with staging (#136) (#138) (#139) * Sessionserializer (#141) * updated cors with staging (#136) (#138) * added mentor to session serializer --------- * fix(availability): fix overlapping error (#142) --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews * Forgot password (#148) * Hotfix build celery code * Updated settings file to enable djoser password reset * chore(precommit): setup precommit (#149) * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): update readme * Create SECURITY.md --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> * Deploy 10142023 (#162) * Deploy 09182023 (#143) (#144) * updated cors with staging (#136) (#138) (#139) * Sessionserializer (#141) * updated cors with staging (#136) (#138) * added mentor to session serializer --------- * fix(availability): fix overlapping error (#142) --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews * Forgot password (#148) * Hotfix build celery code * Updated settings file to enable djoser password reset * chore(precommit): setup precommit (#149) * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): update readme * Create SECURITY.md * feat(mentor): add team number to mentor model (#153) * Bump urllib3 from 1.26.16 to 1.26.17 (#151) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.16 to 1.26.17. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.16...1.26.17) --- updated-dependencies: - dependency-name: urllib3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> * Documentation update (#157) * Deploy 10/02/2023 (#150) * Deploy 09182023 (#143) (#144) * updated cors with staging (#136) (#138) (#139) * Sessionserializer (#141) * updated cors with staging (#136) (#138) * added mentor to session serializer --------- * fix(availability): fix overlapping error (#142) --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews * Forgot password (#148) * Hotfix build celery code * Updated settings file to enable djoser password reset * chore(precommit): setup precommit (#149) * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): update readme * Create SECURITY.md --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> * corrected markdown error with Sessions endpoint; added note to Create User endpoint about username being saved as lowercase; formatted JSON code blocks to have proper syntax highlighting * forgot about Logout correction --------- Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> * Dockerizing (#158) * Deploy 10/02/2023 (#150) * Deploy 09182023 (#143) (#144) * updated cors with staging (#136) (#138) (#139) * Sessionserializer (#141) * updated cors with staging (#136) (#138) * added mentor to session serializer --------- * fix(availability): fix overlapping error (#142) --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews * Forgot password (#148) * Hotfix build celery code * Updated settings file to enable djoser password reset * chore(precommit): setup precommit (#149) * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): update readme * Create SECURITY.md --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> * added drf-spectacular to pipfile and generated schema.yml * nitpicking styling * adjusted schema example in models.py * updated SessionSerialiazer example and added AvailabilitySerializer examples * added more serializer examples * updated Pipfile.lock * added requirements.txt from Pipfile * tried dockerizing backend; error while installing cffi * requirements are installed correctly when image is built; build now fails on useradd command * updated pipfile and requirements.txt * changed Dockerfile * added docker-compose file and compose dir to hold Dockerfile and start scripts; build fails during celery worker * docker-compose now builds * removed unecessary script checking that db is set up * django container now runs with docker compose and connects to db container * updated README to match changes made to database connection in settings.py * docker compose yaml now makes api container accessible on 8000 port * celery containers now run properly * added documentation for running project locally with docker containers * added hyperlink to documentation * added more documentation on how to connect to database; updated host port for db container * removed unused package * removed createsuperuser command --------- Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> * Password reset email url (#159) * Hotfix build celery code * Added DOMAIN and SITE_NAME to settings to get correct url for reset password email * Django container creates superuser if none exists and doesn't exit if… (#161) * Django container creates superuser if none exists and doesn't exit if an error is thrown * added documentation note about accessing admin UI --------- Signed-off-by: dependabot[bot] Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Andrews --------- Signed-off-by: dependabot[bot] Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Andrews From 73f919ed0a9e1f95c54829504147393f0ebf86d9 Mon Sep 17 00:00:00 2001 From: GitLukeW <102833183+GitLukeW@users.noreply.github.com> Date: Sat, 14 Oct 2023 16:47:26 -0400 Subject: [PATCH 02/18] fix(deploy): fixing deploy (#165) --- Pipfile.lock | 326 +++++++++++++++++++++++++-------------------------- 1 file changed, 158 insertions(+), 168 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index f0e2aad..a0c520f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -50,20 +50,19 @@ }, "boto3": { "hashes": [ - "sha256:5ddf24cf52c7fb6aaa332eaa08ae8c2afc8f2d1e8860680728533dd573904e32", - "sha256:e2d2824ba6459b330d097e94039a9c4f96ae3f4bcdc731d620589ad79dcd16d3" + "sha256:65d052ec13197460586ee385aa2d6bba0e7378d2d2c7f3e93c044c43ae1ca782", + "sha256:94218aba2feb5b404b665b8d76c172dc654f79b4c5fa0e9e92459c098da87bf4" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.28.57" + "version": "==1.28.63" }, "botocore": { "hashes": [ - "sha256:002f8bdca8efde50ae7267f342bc1d03a71d76024ce3949e4ffdd1151581c53e", - "sha256:83a3ca4d9247fdbde76c654137e6ab648bd976f652ce2354def1715c838af505" + "sha256:6e582c811ea74f25bdb490ac372b2645de4a60286b42ddd8c69f3b6df82b6b12", + "sha256:cb9db5db5af865b1fc2e1405b967db5d78dd0f4d84e5dc1974e082733c1034b7" ], "markers": "python_version >= '3.7'", - "version": "==1.31.58" + "version": "==1.31.63" }, "celery": { "hashes": [ @@ -71,7 +70,6 @@ "sha256:9023df6a8962da79eb30c0c84d5f4863d9793a466354cc931d7f72423996de28" ], "index": "pypi", - "markers": "python_version >= '3.8'", "version": "==5.3.4" }, "certifi": { @@ -241,7 +239,7 @@ "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e", "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==3.3.0" }, "click": { @@ -257,7 +255,7 @@ "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" ], - "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", + "markers": "python_version < '4.0' and python_full_version >= '3.6.2'", "version": "==0.3.0" }, "click-plugins": { @@ -277,62 +275,61 @@ }, "coverage": { "hashes": [ - "sha256:025ded371f1ca280c035d91b43252adbb04d2aea4c7105252d3cbc227f03b375", - "sha256:04312b036580ec505f2b77cbbdfb15137d5efdfade09156961f5277149f5e344", - "sha256:0575c37e207bb9b98b6cf72fdaaa18ac909fb3d153083400c2d48e2e6d28bd8e", - "sha256:07d156269718670d00a3b06db2288b48527fc5f36859425ff7cec07c6b367745", - "sha256:1f111a7d85658ea52ffad7084088277135ec5f368457275fc57f11cebb15607f", - "sha256:220eb51f5fb38dfdb7e5d54284ca4d0cd70ddac047d750111a68ab1798945194", - "sha256:229c0dd2ccf956bf5aeede7e3131ca48b65beacde2029f0361b54bf93d36f45a", - "sha256:245c5a99254e83875c7fed8b8b2536f040997a9b76ac4c1da5bff398c06e860f", - "sha256:2829c65c8faaf55b868ed7af3c7477b76b1c6ebeee99a28f59a2cb5907a45760", - "sha256:4aba512a15a3e1e4fdbfed2f5392ec221434a614cc68100ca99dcad7af29f3f8", - "sha256:4c96dd7798d83b960afc6c1feb9e5af537fc4908852ef025600374ff1a017392", - "sha256:50dd1e2dd13dbbd856ffef69196781edff26c800a74f070d3b3e3389cab2600d", - "sha256:5289490dd1c3bb86de4730a92261ae66ea8d44b79ed3cc26464f4c2cde581fbc", - "sha256:53669b79f3d599da95a0afbef039ac0fadbb236532feb042c534fbb81b1a4e40", - "sha256:553d7094cb27db58ea91332e8b5681bac107e7242c23f7629ab1316ee73c4981", - "sha256:586649ada7cf139445da386ab6f8ef00e6172f11a939fc3b2b7e7c9082052fa0", - "sha256:5ae4c6da8b3d123500f9525b50bf0168023313963e0e2e814badf9000dd6ef92", - "sha256:5b4ee7080878077af0afa7238df1b967f00dc10763f6e1b66f5cced4abebb0a3", - "sha256:5d991e13ad2ed3aced177f524e4d670f304c8233edad3210e02c465351f785a0", - "sha256:614f1f98b84eb256e4f35e726bfe5ca82349f8dfa576faabf8a49ca09e630086", - "sha256:636a8ac0b044cfeccae76a36f3b18264edcc810a76a49884b96dd744613ec0b7", - "sha256:6407424621f40205bbe6325686417e5e552f6b2dba3535dd1f90afc88a61d465", - "sha256:6bc6f3f4692d806831c136c5acad5ccedd0262aa44c087c46b7101c77e139140", - "sha256:6cb7fe1581deb67b782c153136541e20901aa312ceedaf1467dcb35255787952", - "sha256:74bb470399dc1989b535cb41f5ca7ab2af561e40def22d7e188e0a445e7639e3", - "sha256:75c8f0df9dfd8ff745bccff75867d63ef336e57cc22b2908ee725cc552689ec8", - "sha256:770f143980cc16eb601ccfd571846e89a5fe4c03b4193f2e485268f224ab602f", - "sha256:7eb0b188f30e41ddd659a529e385470aa6782f3b412f860ce22b2491c89b8593", - "sha256:7eb3cd48d54b9bd0e73026dedce44773214064be93611deab0b6a43158c3d5a0", - "sha256:87d38444efffd5b056fcc026c1e8d862191881143c3aa80bb11fcf9dca9ae204", - "sha256:8a07b692129b8a14ad7a37941a3029c291254feb7a4237f245cfae2de78de037", - "sha256:966f10df9b2b2115da87f50f6a248e313c72a668248be1b9060ce935c871f276", - "sha256:a6191b3a6ad3e09b6cfd75b45c6aeeffe7e3b0ad46b268345d159b8df8d835f9", - "sha256:aab8e9464c00da5cb9c536150b7fbcd8850d376d1151741dd0d16dfe1ba4fd26", - "sha256:ac3c5b7e75acac31e490b7851595212ed951889918d398b7afa12736c85e13ce", - "sha256:ac9ad38204887349853d7c313f53a7b1c210ce138c73859e925bc4e5d8fc18e7", - "sha256:b9c0c19f70d30219113b18fe07e372b244fb2a773d4afde29d5a2f7930765136", - "sha256:c397c70cd20f6df7d2a52283857af622d5f23300c4ca8e5bd8c7a543825baa5a", - "sha256:c6601a60318f9c3945be6ea0f2a80571f4299b6801716f8a6e4846892737ebe4", - "sha256:c6f55d38818ca9596dc9019eae19a47410d5322408140d9a0076001a3dcb938c", - "sha256:ca70466ca3a17460e8fc9cea7123c8cbef5ada4be3140a1ef8f7b63f2f37108f", - "sha256:ca833941ec701fda15414be400c3259479bfde7ae6d806b69e63b3dc423b1832", - "sha256:cd0f7429ecfd1ff597389907045ff209c8fdb5b013d38cfa7c60728cb484b6e3", - "sha256:cd694e19c031733e446c8024dedd12a00cda87e1c10bd7b8539a87963685e969", - "sha256:cdd088c00c39a27cfa5329349cc763a48761fdc785879220d54eb785c8a38520", - "sha256:de30c1aa80f30af0f6b2058a91505ea6e36d6535d437520067f525f7df123887", - "sha256:defbbb51121189722420a208957e26e49809feafca6afeef325df66c39c4fdb3", - "sha256:f09195dda68d94a53123883de75bb97b0e35f5f6f9f3aa5bf6e496da718f0cb6", - "sha256:f12d8b11a54f32688b165fd1a788c408f927b0960984b899be7e4c190ae758f1", - "sha256:f1a317fdf5c122ad642db8a97964733ab7c3cf6009e1a8ae8821089993f175ff", - "sha256:f2781fd3cabc28278dc982a352f50c81c09a1a500cc2086dc4249853ea96b981", - "sha256:f4f456590eefb6e1b3c9ea6328c1e9fa0f1006e7481179d749b3376fc793478e" + "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", + "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", + "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", + "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", + "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", + "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", + "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", + "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", + "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", + "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", + "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", + "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", + "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", + "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", + "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", + "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", + "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", + "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", + "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", + "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", + "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", + "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", + "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", + "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", + "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", + "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", + "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", + "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", + "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", + "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", + "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", + "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", + "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", + "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", + "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", + "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", + "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", + "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", + "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", + "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", + "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", + "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", + "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", + "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", + "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", + "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", + "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", + "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", + "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", + "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", + "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", + "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==7.3.1" + "version": "==7.3.2" }, "cron-descriptor": { "hashes": [ @@ -386,12 +383,11 @@ }, "django": { "hashes": [ - "sha256:5e5c1c9548ffb7796b4a8a4782e9a2e5a3df3615259fc1bfd3ebc73b646146c1", - "sha256:b6b2b5cae821077f137dc4dade696a1c2aa292f892eca28fa8d7bfdf2608ddd4" + "sha256:08f41f468b63335aea0d904c5729e0250300f6a1907bf293a65499496cdbc68f", + "sha256:a64d2487cdb00ad7461434320ccc38e60af9c404773a2f95ab0093b4453a3215" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==4.2.5" + "version": "==4.2.6" }, "django-appconf": { "hashes": [ @@ -415,8 +411,7 @@ "sha256:bd36c7aea0d070e462f3383f0dc9ef717e5fdc2b10a99c98c285f16da84ffba2" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==4.2.0" + "version": "==4.3.0" }, "django-environ": { "hashes": [ @@ -424,7 +419,6 @@ "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be" ], "index": "pypi", - "markers": "python_version >= '3.6' and python_version < '4'", "version": "==0.11.2" }, "django-extensions": { @@ -433,7 +427,6 @@ "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==3.2.3" }, "django-imagekit": { @@ -458,17 +451,15 @@ "sha256:20c7c5c449e33eed5fd45ef8d3dc668faabaeff3277eddd1892b262d686ba381" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.1.0" + "version": "==7.2.0" }, "django-storages": { "hashes": [ - "sha256:18cb6c305fbb2f114c11b5b7b647b6271aa251972dcd4a5651b9cee2b0bd3a8a", - "sha256:a2c327d67792eec04c7f5f5bb2900b21f426de8a3a811cea85fac7904bdccf36" + "sha256:1db759346b52ada6c2efd9f23d8241ecf518813eb31db9e2589207174f58f6ad", + "sha256:51b36af28cc5813b98d5f3dfe7459af638d84428c8df4a03990c7d74d1bea4e5" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.14.1" + "version": "==1.14.2" }, "django-templated-mail": { "hashes": [ @@ -491,7 +482,6 @@ "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==3.14.0" }, "djangorestframework-simplejwt": { @@ -508,7 +498,6 @@ "sha256:7b24718cdc51b4294b0abcf6bf0ead11aa3ca83652e351dfb04b7b8b15afa3b0" ], "index": "pypi", - "markers": "python_version >= '3.8' and python_version < '4.0'", "version": "==2.2.0" }, "filelock": { @@ -525,7 +514,6 @@ "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5" ], "index": "pypi", - "markers": "python_full_version >= '3.8.1'", "version": "==6.1.0" }, "gunicorn": { @@ -534,7 +522,6 @@ "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033" ], "index": "pypi", - "markers": "python_version >= '3.5'", "version": "==21.2.0" }, "identify": { @@ -674,7 +661,6 @@ "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1" ], "index": "pypi", - "markers": "python_version >= '3.8'", "version": "==10.0.1" }, "platformdirs": { @@ -687,95 +673,102 @@ }, "pre-commit": { "hashes": [ - "sha256:6bbd5129a64cad4c0dfaeeb12cd8f7ea7e15b77028d985341478c8af3c759522", - "sha256:96d529a951f8b677f730a7212442027e8ba53f9b04d217c4c67dc56c393ad945" + "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32", + "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==3.4.0" + "version": "==3.5.0" }, "prompt-toolkit": { "hashes": [ "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==3.0.39" }, "psycopg2-binary": { "hashes": [ - "sha256:01f9731761f711e42459f87bd2ad5d744b9773b5dd05446f3b579a0f077e78e3", - "sha256:0e3071c947bda6afc6fe2e7b64ebd64fb2cad1bc0e705a3594cb499291f2dfec", - "sha256:14f85ff2d5d826a7ce9e6c31e803281ed5a096789f47f52cb728c88f488de01b", - "sha256:15458c81b0d199ab55825007115f697722831656e6477a427783fe75c201c82b", - "sha256:19d40993701e39c49b50e75cd690a6af796d7e7210941ee0fe49cf12b25840e5", - "sha256:1d669887df169a9b0c09e0f5b46891511850a9ddfcde3593408af9d9774c5c3a", - "sha256:1dbad789ebd1e61201256a19dc2e90fed4706bc966ccad4f374648e5336b1ab4", - "sha256:1f279ba74f0d6b374526e5976c626d2ac3b8333b6a7b08755c513f4d380d3add", - "sha256:205cecdd81ff4f1ddd687ce7d06879b9b80cccc428d8d6ebf36fcba08bb6d361", - "sha256:278ebd63ced5a5f3af5394cb75a9a067243eee21f42f0126c6f1cf85eaeb90f9", - "sha256:3723c3f009e2b2771f2491b330edb7091846f1aad0c08fbbd9a1383d6a0c0841", - "sha256:395c217156723fe21809dfe8f7a433c5bf8e9bce229944668e4ec709c37c5442", - "sha256:3ae22a0fa5c516b84ddb189157fabfa3f12eded5d630e1ce260a18e1771f8707", - "sha256:3b6928a502af71ca2ac9aad535e78c8309892ed3bfa7933182d4c760580c8af4", - "sha256:3b6c607ecb6a9c245ebe162d63ccd9222d38efa3c858bbe38d32810b08b8f87e", - "sha256:3fd44b52bc9c74c1512662e8da113a1c55127adeeacebaf460babe766517b049", - "sha256:4336afc0e81726350bd5863e3c3116d8c12aa7f457d3d0b3b3dc36137fec6feb", - "sha256:4879ee1d07a6b2c232ae6a74570f4788cd7a29b3cd38bc39bf60225b1d075c78", - "sha256:4960c881471ca710b81a67ef148c33ee121c1f8e47a639cf7e06537fe9fee337", - "sha256:4b8b2cdf3bce4dd91dc035fbff4eb812f5607dda91364dc216b0920b97b521c7", - "sha256:4bfabbd7e70785af726cc0209e8e64b926abf91741eca80678b221aad9e72135", - "sha256:4d6b592ecc8667e608b9e7344259fbfb428cc053df0062ec3ac75d8270cd5a9f", - "sha256:5262713988d97a9d4cd54b682dec4a413b87b76790e5b16f480450550d11a8f7", - "sha256:54bf5c27bd5867a5fa5341fad29f0d5838e2fed617ef5346884baf8b8b16dd82", - "sha256:565edaf9f691b17a7fdbabd368b5b3e67d0fdc8f7f6b52177c1d3289f4e763fd", - "sha256:59421806c1a0803ea7de9ed061d656c041a84db0da7e73266b98db4c7ba263da", - "sha256:59f45cca0765aabb52a5822c72d5ff2ec46a28b1c1702de90dc0d306ec5c2001", - "sha256:5a0a6e4004697ec98035ff3b8dfc4dba8daa477b23ee891d831cd3cd65ace6be", - "sha256:5aa0c99c12075c593dcdccbb8a7aaa714b716560cc99ef9206f9e75b77520801", - "sha256:5aef3296d44d05805e634dbbd2972aa8eb7497926dd86047f5e39a79c3ecc086", - "sha256:5cbe1e19f59950afd66764e3c905ecee9f2aee9f8df2ef35af6f7948ad93f620", - "sha256:5debcb23a052f3fb4c165789ea513b562b2fac0f0f4f53eaf3cf4dc648907ff8", - "sha256:5f955fe6301b84b6fd13970a05f3640fbb62ca3a0d19342356585006c830e038", - "sha256:6369f4bd4d27944498094dccced1ae7ca43376a59dbfe4c8b6a16e9e3dc3ccce", - "sha256:63ce1dccfd08d9c5341ac82d62aa04345bc4bf41b5e5b7b2c6c172a28e0eda27", - "sha256:65403113ac3a4813a1409fb6a1e43c658b459cc8ed8afcc5f4baf02ec8be4334", - "sha256:673eafbdaa4ed9f5164c90e191c3895cc5f866b9b379fdb59f3a2294e914d9bd", - "sha256:693a4e7641556f0b421a7d6c6a74058aead407d860ac1cb9d0bf25be0ca73de8", - "sha256:6e1bb4eb0d9925d65dabaaabcbb279fab444ba66d73f86d4c07dfd11f0139c06", - "sha256:6f5e70e40dae47a4dc7f8eb390753bb599b0f4ede314580e6faa3b7383695d19", - "sha256:80451e6b6b7c486828d5c7ed50769532bbb04ec3a411f1e833539d5c10eb691c", - "sha256:8c84ff9682bc4520504c474e189b3de7c4a4029e529c8b775e39c95c33073767", - "sha256:91719f53ed2a95ebecefac48d855d811cba9d9fe300acc162993bdfde9bc1c3b", - "sha256:9a971086db0069aef2fd22ccffb670baac427f4ee2174c4f5c7206254f1e6794", - "sha256:aeb09db95f38e75ae04e947d283e07be34d03c4c2ace4f0b73dbb9143d506e67", - "sha256:c68a2e1afb4f2a5bb4b7bb8f90298d21196ac1c66418523e549430b8c4b7cb1e", - "sha256:c7ff2b6a79a92b1b169b03bb91b41806843f0cdf6055256554495bffed1d496d", - "sha256:ccaa2ae03990cedde1f618ff11ec89fefa84622da73091a67b44553ca8be6711", - "sha256:cf60c599c40c266a01c458e9c71db7132b11760f98f08233f19b3e0a2153cbf1", - "sha256:d29efab3c5d6d978115855a0f2643e0ee8c6450dc536d5b4afec6f52ab99e99e", - "sha256:d4a19a3332f2ac6d093e60a6f1c589f97eb9f9de7e27ea80d67f188384e31572", - "sha256:dc145a241e1f6381efb924bcf3e3462d6020b8a147363f9111eb0a9c89331ad7", - "sha256:de85105c568dc5f0f0efe793209ba83e4675d53d00faffc7a7c7a8bea9e0e19a", - "sha256:e11373d8e4f1f46cf3065bf613f0df9854803dc95aa4a35354ffac19f8c52127", - "sha256:e271ad6692d50d70ca75db3bd461bfc26316de78de8fe1f504ef16dcea8f2312", - "sha256:e3142c7e51b92855cff300580de949e36a94ab3bfa8f353b27fe26535e9b3542", - "sha256:e46b0f4683539965ce849f2c13fc53e323bb08d84d4ba2e4b3d976f364c84210", - "sha256:e6ef615d48fa60361e57f998327046bd89679c25d06eee9e78156be5a7a76e03", - "sha256:e7bdc94217ae20ad03b375a991e107a31814053bee900ad8c967bf82ef3ff02e", - "sha256:fc37de7e3a87f5966965fc874d33c9b68d638e6c3718fdf32a5083de563428b0" + "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9", + "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77", + "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e", + "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84", + "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3", + "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2", + "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67", + "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876", + "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152", + "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f", + "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a", + "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6", + "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503", + "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f", + "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493", + "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996", + "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f", + "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e", + "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59", + "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94", + "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7", + "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682", + "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420", + "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae", + "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291", + "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe", + "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980", + "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692", + "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119", + "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716", + "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472", + "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b", + "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2", + "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc", + "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c", + "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5", + "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984", + "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9", + "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf", + "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0", + "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f", + "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212", + "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb", + "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be", + "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90", + "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041", + "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7", + "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860", + "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245", + "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27", + "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417", + "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359", + "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202", + "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0", + "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7", + "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba", + "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1", + "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd", + "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07", + "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98", + "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55", + "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d", + "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972", + "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f", + "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e", + "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26", + "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957", + "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53", + "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==2.9.8" + "version": "==2.9.9" }, "pycodestyle": { "hashes": [ - "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0", - "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], "markers": "python_version >= '3.8'", - "version": "==2.11.0" + "version": "==2.11.1" }, "pycparser": { "hashes": [ @@ -892,7 +885,6 @@ "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==5.0.1" }, "requests": { @@ -924,10 +916,11 @@ "django" ], "hashes": [ - "sha256:64a7141005fb775b9db298a30de93e3b83e0ddd1232dc6f36eb38aebc1553291", - "sha256:6de2e88304873484207fed836388e422aeff000609b104c802749fd89d56ba5b" + "sha256:935e8fbd7787a3702457393b74b13d89a5afb67185bc0af85c00cb27cbd42e7c", + "sha256:eeb0b3550536f3bbc05bb1c7e0feb3a78d74acb43b607159a606ed2ec0a33a4d" ], - "version": "==1.31.0" + "index": "pypi", + "version": "==1.32.0" }, "setuptools": { "hashes": [ @@ -987,12 +980,11 @@ }, "urllib3": { "hashes": [ - "sha256:24d6a242c28d29af46c3fae832c36db3bbebcc533dd1bb549172cd739c82df21", - "sha256:94a757d178c9be92ef5539b8840d48dc9cf1b2709c9d6b588232a055c524458b" + "sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2", + "sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564" ], - "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.17" + "markers": "python_version >= '3.6'", + "version": "==2.0.6" }, "vine": { "hashes": [ @@ -1023,8 +1015,7 @@ "sha256:b1f9db9bf67dc183484d760b99f4080185633136a273a03f6436034a41064146" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==6.5.0" + "version": "==6.6.0" } }, "develop": { @@ -1034,16 +1025,15 @@ "sha256:2913064abd97b3419d1cc83ea71f042cb821f87e45b9c88cad5ad3c4ea87fe0c" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==2.0.4" }, "pycodestyle": { "hashes": [ - "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0", - "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8" + "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", + "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" ], "markers": "python_version >= '3.8'", - "version": "==2.11.0" + "version": "==2.11.1" }, "tomli": { "hashes": [ From 2999ba4ef9c5f95867b15302e0c60f45bd245273 Mon Sep 17 00:00:00 2001 From: GitLukeW <102833183+GitLukeW@users.noreply.github.com> Date: Sat, 14 Oct 2023 17:04:43 -0400 Subject: [PATCH 03/18] Chore/issue 1/deploy (#166) * fix(deploy): fixing deploy * fix(deploy): fixing deploy --- config/settings.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/config/settings.py b/config/settings.py index 5d816ea..663694b 100644 --- a/config/settings.py +++ b/config/settings.py @@ -101,14 +101,7 @@ # https://docs.djangoproject.com/en/4.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': env("DATABASE_NAME"), - 'USER': env("DATABASE_USER"), - 'PASSWORD': env("DATABASE_PASSWORD"), - 'HOST': env("DATABASE_HOST"), - 'PORT': env("DATABASE_PORT"), - }, + 'default': env.db() } From 5402a9a010bb4c47da1ed1cc8eb70b377f93f763 Mon Sep 17 00:00:00 2001 From: James Andrews Date: Sat, 21 Oct 2023 16:25:14 -0400 Subject: [PATCH 04/18] Docker containers now use DATABASE_URL env variable (#168) --- docker-compose.yaml | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index a2f7833..5784d89 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -16,11 +16,7 @@ services: env_file: - ./config/.env environment: - - DATABASE_NAME=mentors - - DATABASE_USER=mentors - - DATABASE_PASSWORD=mentors - - DATABASE_HOST=db - - DATABASE_PORT=5432 + - DATABASE_URL=postgres://mentors:mentors@db:5432/mentors depends_on: - redis - db @@ -49,11 +45,7 @@ services: environment: - CELERY_BROKER_URL=redis://redis:6379 - CELERY_RESULT_BACKEND=redis://redis:6379 - - DATABASE_NAME=mentors - - DATABASE_USER=mentors - - DATABASE_PASSWORD=mentors - - DATABASE_HOST=db - - DATABASE_PORT=5432 + - DATABASE_URL=postgres://mentors:mentors@db:5432/mentors volumes: - .:/app depends_on: @@ -70,11 +62,7 @@ services: environment: - CELERY_BROKER_URL=redis://redis:6379 - CELERY_RESULT_BACKEND=redis://redis:6379 - - DATABASE_NAME=mentors - - DATABASE_USER=mentors - - DATABASE_PASSWORD=mentors - - DATABASE_HOST=db - - DATABASE_PORT=5432 + - DATABASE_URL=postgres://mentors:mentors@db:5432/mentors volumes: - .:/app depends_on: From 0a0bf59dc29be010892f5477c3272cf7e603bffa Mon Sep 17 00:00:00 2001 From: James Andrews Date: Sat, 21 Oct 2023 16:26:58 -0400 Subject: [PATCH 05/18] updating Mentor info docs updated; added new note about changing files in Docker docs (#164) Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> --- README.md | 88 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 719e458..19dfdf3 100644 --- a/README.md +++ b/README.md @@ -136,20 +136,27 @@ If you want to connect to the container database via an app like Postico 2, the - User: mentors - Password: mentors +While running, the Django server will automatically detect changes made and +reload, just as if it was running in your local environment. +Certain file changes, such as to a model, won't trigger this behavior. +In these cases, stop then restart the containers. + To stop running the containers, hit Ctrl+C, then spin down the containers: ```bash docker compose down ``` -The database is persistant. If you want to reset it, follow these 2 steps once the containers are no longer running: +The database is persistant. If you make changes to a model, run makemigrations +before resetting the the database. +Follow these 2 steps once the containers are no longer running: - Remove the persistant volume: ```bash docker volume rm team_production_system_be_postgres_data ``` -- Rebuild the docker images: +- Rebuild the docker images without the cached data: ```bash -docker compose build +docker compose build --no-cache ``` The next time you spin up the docker containers, the database will be empty again. @@ -597,10 +604,18 @@ Host: https://team-production-system.onrender.com POST - https://team-production-system.onrender.com/mentorinfo/ ``` -| Body | Type | Description | -| :--------- | :------- | :------------------------- | -| `about_me` | `string` | Information about the user | -| `skills` | `string` | Skills the user has | +| Body | Type | Description | +| :------------ | :------- | :------------------------- | +| `pk` | `int` | The mentor pk | +| `about_me` | `string` | Information about the user | +| `skills` | `array` | Skills the user has | +| `team_number` | `int` | Mentor's team number | + +**Nested Information:** + +| Body | Type | Description | +| :--------------- | :------ | :---------------------------- | +| `availabilities` | `array` | Availabilities the mentor has | #### Request Sample: @@ -612,7 +627,8 @@ Host: https://team-production-system.onrender.com { "about_me": "Hi, I am so and so and do such and such", - "skills": "CSS" + "skills": ["CSS"], + "team_number": 10, } ``` @@ -621,8 +637,13 @@ Host: https://team-production-system.onrender.com ```JSON { + "pk": 1, "about_me": "Hi, I am so and so and do such and such", - "skills": "CSS" + "skills": [ + "CSS" + ], + "availabilities": [], + "team_number": 10 } ``` @@ -637,10 +658,12 @@ Host: https://team-production-system.onrender.com GET - https://team-production-system.onrender.com/mentorinfo/ ``` -| Body | Type | Description | -| :--------- | :------- | :------------------------- | -| `about_me` | `string` | Information about the user | -| `skills` | `string` | Skills the user has | +| Body | Type | Description | +| :------------ | :------- | :------------------------- | +| `pk` | `int` | The mentor pk | +| `about_me` | `string` | Information about the user | +| `skills` | `string` | Skills the user has | +| `team_number` | `int` | Mentor's team number | **Nested Information:** @@ -666,8 +689,11 @@ Host: https://team-production-system.onrender.com ```JSON { + "pk": 1, "about_me": "Hi, I am so and so and do such and such", - "skills": "CSS" + "skills": [ + "CSS" + ], "availabilities": [ { "pk": 1, @@ -675,8 +701,8 @@ Host: https://team-production-system.onrender.com "start_time": "2023-04-12T14:30:00Z", "end_time": "2023-04-12T15:30:00Z" } - ] - + ], + "team_number": 10 } ``` @@ -691,10 +717,18 @@ Host: https://team-production-system.onrender.com PATCH - https://team-production-system.onrender.com/mentorinfoupdate/ ``` -| Body | Type | Description | -| :--------- | :------- | :------------------------- | -| `about_me` | `string` | Information about the user | -| `skills` | `string` | Skills the user has | +| Body | Type | Description | +| :------------ | :------- | :------------------------- | +| `pk` | `int` | The mentor pk | +| `about_me` | `string` | Information about the user | +| `skills` | `array` | Skills the user has | +| `team_number` | `int` | Mentor's team number | + +**Nested Information:** + +| Body | Type | Description | +| :--------------- | :------ | :---------------------------- | +| `availabilities` | `array` | Availabilities the mentor has | #### Request Sample: @@ -714,8 +748,20 @@ Host: https://team-production-system.onrender.com ```JSON { + "pk": 1, "about_me": "Hi, I am so and so and do such and such", - "skills": "Python" + "skills": [ + "Python" + ], + "availabilities": [ + { + "pk": 1, + "mentor": 2, + "start_time": "2023-04-12T14:30:00Z", + "end_time": "2023-04-12T15:30:00Z" + } + ], + "team_number": 10 } ``` From a95f9c55cdbcba802342458ef033019c6bb915a6 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Thu, 26 Oct 2023 12:14:16 -0400 Subject: [PATCH 06/18] docs(linting): adds instructions for flake8 (#170) * docs(linting): adds instructions for flake8 * docs(linting): wrap flake8 in bash --- README.md | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 19dfdf3..003ad18 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Team Production System is an app for mentees to schedule one-on-one sessions wit - [Run Locally via Docker Containers](#run-locally-via-docker-containers) - [Environment Variables](#environment-variables) - [Testing](#testing) +- [Linting](#linting) - [Submitting Code](#submitting-code) - [API Reference](#api-reference) @@ -103,22 +104,26 @@ celery -A config.celery beat -l debug You will also need to have your .env file set up. Update `requirements.txt` with any newly added installs: + ```bash pipenv requirements > requirements.txt ``` **Note:** If this step deletes everything in the requirements.txt file, your pipenv is out of date. You can update it with the following command: + ```bash pip install --user --upgrade pipenv ``` Build docker images: + ```bash docker compose build ``` Spin up docker containers: + ```bash docker compose up ``` @@ -130,11 +135,11 @@ Use the DJANGO_SUPERUSER credentials you set in the .env file. If you want to connect to the container database via an app like Postico 2, the settings needed are: - - Host: localhost - - Port: 5433 - - Database: mentors - - User: mentors - - Password: mentors + - Host: localhost + - Port: 5433 + - Database: mentors + - User: mentors + - Password: mentors While running, the Django server will automatically detect changes made and reload, just as if it was running in your local environment. @@ -142,6 +147,7 @@ Certain file changes, such as to a model, won't trigger this behavior. In these cases, stop then restart the containers. To stop running the containers, hit Ctrl+C, then spin down the containers: + ```bash docker compose down ``` @@ -151,13 +157,18 @@ before resetting the the database. Follow these 2 steps once the containers are no longer running: - Remove the persistant volume: + ```bash docker volume rm team_production_system_be_postgres_data -``` +``` + +- Rebuild the docker images: + +```` - Rebuild the docker images without the cached data: ```bash docker compose build --no-cache -``` +```` The next time you spin up the docker containers, the database will be empty again. @@ -225,6 +236,16 @@ Then in the `htmlcov` folder of the project, open the file `index.html` in a bro Here is some helpful information on testing in Django and Django REST Framework: https://www.rootstrap.com/blog/testing-in-django-django-rest-basics-useful-tools-good-practices +# Linting + +To keep our code easy to read and use please make sure it passes flake8 linting before submitting your code. To run in terminal: + +```bash +flake8 +``` + +Each error will show the file name and line to find the error. The command can be run over and over again until errors are cleared. + # Submitting Code We use a pre-commit to check branch names and commit messages. Please follow the the following schema for branch names and commit messages: @@ -604,7 +625,7 @@ Host: https://team-production-system.onrender.com POST - https://team-production-system.onrender.com/mentorinfo/ ``` -| Body | Type | Description | +| Body | Type | Description | | :------------ | :------- | :------------------------- | | `pk` | `int` | The mentor pk | | `about_me` | `string` | Information about the user | @@ -661,8 +682,8 @@ GET - https://team-production-system.onrender.com/mentorinfo/ | Body | Type | Description | | :------------ | :------- | :------------------------- | | `pk` | `int` | The mentor pk | -| `about_me` | `string` | Information about the user | -| `skills` | `string` | Skills the user has | +| `about_me` | `string` | Information about the user | +| `skills` | `string` | Skills the user has | | `team_number` | `int` | Mentor's team number | **Nested Information:** @@ -717,7 +738,7 @@ Host: https://team-production-system.onrender.com PATCH - https://team-production-system.onrender.com/mentorinfoupdate/ ``` -| Body | Type | Description | +| Body | Type | Description | | :------------ | :------- | :------------------------- | | `pk` | `int` | The mentor pk | | `about_me` | `string` | Information about the user | From 5f87e768ec5a7e5c600aee5cbddac3b0eb859036 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Thu, 26 Oct 2023 21:16:34 -0400 Subject: [PATCH 07/18] feat(availability): saves in 30 min chunks (#152) * Deploy 10/02/2023 (#150) * Deploy 09182023 (#143) (#144) * updated cors with staging (#136) (#138) (#139) * Sessionserializer (#141) * updated cors with staging (#136) (#138) * added mentor to session serializer --------- * fix(availability): fix overlapping error (#142) --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews * Forgot password (#148) * Hotfix build celery code * Updated settings file to enable djoser password reset * chore(precommit): setup precommit (#149) * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): setup precommit * chore(precommit): update readme * Create SECURITY.md --------- Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> * feat(availability): adds status field to model * feat(availability): unique constraint error message clearer * refactor(availability): breaks up 30 mins chunks in serializer * refactor(availability): restores original serializer renames new serializer * refactor(availability): restores original endpoint * chore(urls): updates availability-v2 url for clarity * test(serializer): coverage for availability v2 * test(view): coverage for availability v2 * test(view): coverage for availability delete * chore(linting): clean ups errors * chore(model): availability status updated to confirmed * test(serializer): availability test clean up * chore(urls): clean up spacing * chore(migrations): updating migrations with merge * docs(availability): add new create availability endpoint * docs(availability): updates response to current functionality * docs(user login): update with lowercase username instructions * chore(availability): add note to update to namespace * feat(models): adds modified_at and created_at fields to availability and sessions * chore: add new serializer and view to inits * feat(admin): adds readonly fields of created_at and modified_at * refactor(availability): rework serializer to bulk_create * refactor(availabilities): rework views to create 30 min chunks * chore(linting): cleans up code * chore: remove comment * feat: adds helper functions file * feat: availabilities validating and saving correctly * chore: realign urls * tests: update tests * test(availabilitiy): adds test coverage for serializers. * chore: cleans up linting * refractor(availability): uses header versioning best practices * docs(availability): updates for v2 * chore: cleans up comments * chore: removes v1 versioning comment * test(availability): rework tests to pass * refactor(availabilities): changes from code review * chore: removes parentheses * chore: adds todo * chore(availabilities): remove else statement * feat(availabilities): only returns 30 min chunks in time range * test(helpers): adds coverage to 100% * fix(availability): updates error handling to return consistent error messaging * test(errors): updates tests with new error handling --------- Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> Co-authored-by: Laura Andrews <125932649+Laura-D-Andrews@users.noreply.github.com> Co-authored-by: Laura-D-Andrews Co-authored-by: Nathan Zeager <108411172+nzeager@users.noreply.github.com> --- README.md | 167 ++++++++++++++++-- config/settings.py | 3 + requirements.txt | 59 +++---- team_production_system/admin.py | 9 + team_production_system/helpers.py | 60 +++++++ ...bility_availability_constraint_and_more.py | 38 ++++ ...ed_at_availability_modified_at_and_more.py | 38 ++++ team_production_system/models/availability.py | 21 ++- team_production_system/models/session.py | 3 +- .../serializers/__init__.py | 5 +- .../serializers/availability.py | 46 ++++- .../tests/unit_tests/serializers/__init__.py | 0 .../test_availability_serializer.py | 154 ++++++++++++++++ .../test_availability_create_list_view.py | 109 ++++++++++-- .../views/test_availability_delete_view.py | 32 ++++ team_production_system/urls.py | 23 +-- .../views/availability_list_create.py | 77 +++++++- 17 files changed, 761 insertions(+), 83 deletions(-) create mode 100644 team_production_system/helpers.py create mode 100644 team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py create mode 100644 team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py create mode 100644 team_production_system/tests/unit_tests/serializers/__init__.py create mode 100644 team_production_system/tests/unit_tests/serializers/test_availability_serializer.py create mode 100644 team_production_system/tests/unit_tests/views/test_availability_delete_view.py diff --git a/README.md b/README.md index 003ad18..27c44f5 100644 --- a/README.md +++ b/README.md @@ -160,12 +160,11 @@ Follow these 2 steps once the containers are no longer running: ```bash docker volume rm team_production_system_be_postgres_data -``` -- Rebuild the docker images: +``` -```` - Rebuild the docker images without the cached data: + ```bash docker compose build --no-cache ```` @@ -298,12 +297,14 @@ API URL - https://team-production-system.onrender.com ## Quck Links: -- [User Endpoints](#user-create) -- [Mentor Endpoints](#view-mentors-list-user-authentication-required) -- [Mentee Endpoints](#view-mentee-list-user-authentication-required) -- [Availability Endpoints](#mentors-availabilty-user-authentication-required) -- [Session Endpoints](#sessions-user-authentication-required) -- [Notification Endpoints](#update-notification-settings-user-authentication-required) +- [User Endpoints](#user-endpoints) +- [Mentor Endpoints](#mentor-endpoints) +- [Mentee Endpoints](#mentee-endpoints) +- [Availability Endpoints](#availability-endpoints) +- [Session Endpoints](#session-endpoints) +- [Notification Endpoints](#notification-endpoints) + +## User Endpoints ## User Create @@ -353,6 +354,7 @@ Host: https://team-production-system.onrender.com ## Token Authentication / User Login - Create a user token. +- Username must be lowercase ```http POST - https://team-production-system.onrender.com/auth/token/login/ @@ -360,7 +362,7 @@ POST - https://team-production-system.onrender.com/auth/token/login/ | Body | Type | Description | | :--------- | :------- | :---------------------- | -| `username` | `string` | Username | +| `username` | `string` | Username (lowercase) | | `password` | `string` | User generated password | #### Request Sample: @@ -545,6 +547,8 @@ Host: https://team-production-system.onrender.com --- +## Mentor Endpoints + ## View Mentors List (User Authentication **Required**) - View a list of all user with the mentors flag (Expired availabilties are filtered out) @@ -884,6 +888,8 @@ Host: https://team-production-system.onrender.com --- +## Mentee Endpoints + ## View Mentee List (User Authentication **Required**) - View a list of all user with the mentee flag set to true @@ -1094,7 +1100,9 @@ No body returned to response --- -## Mentors Availabilty (User Authentication **Required**) +## Availability Endpoints + +## V1 | Get Mentors Availabilty (User Authentication **Required**) - Get mentor availabilty - This endpoint filters out any expired availabilty. Only shows availabilty that is in the future. @@ -1157,9 +1165,79 @@ Host: https://team-production-system.onrender.com --- -## Add Mentor Availabilty (User Authentication **Required**) +## V2 | View Mentor Availabilty List (User Authentication **Required**, Version Header **Required**) -- Add mentor availabilty (This endpoint filters out any expired availabilty. Only shows availabilty that is in the future.) +- Get mentor availabilty +- This endpoint filters out any expired availabilty +- Only shows availabilty with end_time in future. +- Availability reponse ordered from present to future +- Must pass version number in headers. + +```http +GET - https://team-production-system.onrender.com/availabilty/ +``` + +| Body | Type | Description | +| :----------- | :---------- | :----------------------------------------------- | +| `pk` | `int` | The pk of the availabilty | +| `mentor` | `int` | The pk of the mentor attached to the availabilty | +| `start_time` | `date-time` | Start time of the availabilty | +| `end_time` | `date-time` | Start time of the availabilty | +| `status` | `string` | Status of the availability | + +#### Request Sample: + +```JSON +GET /availabilty/ +Content-Type: json +Accept: version=v2 +Authorization: Required +Host: https://team-production-system.onrender.com + +{ + "" +} + +``` + +#### Response Example (200 OK) + +```JSON +[ + { + "pk": 19, + "mentor": 4, + "start_time": "1999-12-31T14:30:00Z", + "end_time": "1999-12-31T15:30:00Z" + }, + { + "pk": 20, + "mentor": 5, + "start_time": "1999-12-31T15:30:00Z", + "end_time": "1999-12-31T16:30:00Z" + }, + { + "pk": 21, + "mentor": 4, + "start_time": "1999-12-31T16:30:00Z", + "end_time": "1999-12-31T18:30:00Z" + }, + { + "pk": 22, + "mentor": 7, + "start_time": "1999-12-31T18:30:00Z", + "end_time": "1999-12-31T19:30:00Z" + } +] +``` + +--- + +## V1 | Add Mentor Availabilty (User Authentication **Required**) + +- Add mentor availabilty +- Start time must be in the future +- End time must be after start time ```http POST - https://team-production-system.onrender.com/availabilty/ @@ -1200,6 +1278,65 @@ Host: https://team-production-system.onrender.com --- +## V2 | Add Mentor Availabilty (User Authentication **Required**, Version Header **Required**) + +- Add mentor availabilty +- Availability saves to database in 30 min chunks +- Status defaults to 'Open' +- Must pass version number in headers. + +```http +POST - https://team-production-system.onrender.com/v2/availabilty/ +``` + +| Body | Type | Description | +| :----------- | :---------- | :----------------------------------------------- | +| `pk` | `int` | The pk of the availabilty | +| `mentor` | `int` | The pk of the mentor attached to the availabilty | +| `start_time` | `date-time` | Start time of the availabilty | +| `end_time` | `date-time` | Start time of the availabilty | +| `status` | `string` | Status of the availability | + +#### Request Sample: + +``` +POST /v2/availabilty/ +Content-Type: json +Accept: version=v2 +Authorization: Required +Host: https://team-production-system.onrender.com + +{ + "start_time": "1999-12-31T14:30:00Z", + "end_time": "1999-12-31T15:30:00Z" +} + +``` + +#### Response Example (201 Created) + +``` +[ + { + "pk": 23, + "mentor": 1, + "start_time": "1999-12-31T14:30:00Z", + "end_time": "1999-12-31T15:00:00Z", + "status": "Open" + }, + { + "pk": 24, + "mentor": 1, + "start_time": "1999-12-31T15:00:00Z", + "end_time": "1999-12-31T15:30:00Z", + "status": "Open" + }, + +] +``` + +--- + ## Delete Mentor Availabilty (User Authentication **Required**) - Delete a mentor availabilty @@ -1234,6 +1371,8 @@ No body returned to response --- +## Session Endpoints + ## Sessions (User Authentication **Required**) - Get a list of all sessions @@ -1492,6 +1631,8 @@ Host: https://team-production-system.onrender.com --- +## Notification Endpoints + ## Update Notification Settings (User Authentication **Required**) - Update user's notification settings diff --git a/config/settings.py b/config/settings.py index 663694b..2538074 100644 --- a/config/settings.py +++ b/config/settings.py @@ -197,6 +197,9 @@ 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', ), + 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning', + 'DEFAULT_VERSION': 'v1', + 'ALLOWED_VERSIONS': ['v1', 'v2'], } DOMAIN = 'momentors.dev' diff --git a/requirements.txt b/requirements.txt index 54dda35..abbc59e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,48 +2,44 @@ amqp==5.1.1; python_version >= '3.6' asgiref==3.7.2; python_version >= '3.7' async-timeout==4.0.3; python_full_version <= '3.11.2' -attrs==23.1.0; python_version >= '3.7' billiard==4.1.0; python_version >= '3.7' -boto3==1.28.57; python_version >= '3.7' -botocore==1.31.57; python_version >= '3.7' -celery==5.3.4; python_version >= '3.8' +boto3==1.28.63 +botocore==1.31.63; python_version >= '3.7' +celery==5.3.4 certifi==2023.7.22; python_version >= '3.6' cffi==1.16.0; python_version >= '3.8' cfgv==3.4.0; python_version >= '3.8' -charset-normalizer==3.3.0; python_full_version >= '3.7.0' +charset-normalizer==3.3.0; python_version >= '3.7' click==8.1.7; python_version >= '3.7' -click-didyoumean==0.3.0; python_full_version >= '3.6.2' and python_full_version < '4.0.0' +click-didyoumean==0.3.0; python_version < '4.0' and python_full_version >= '3.6.2' click-plugins==1.1.1 click-repl==0.3.0; python_version >= '3.6' -coverage==7.3.1; python_version >= '3.8' +coverage==7.3.2 cron-descriptor==1.4.0 cryptography==41.0.4; python_version >= '3.7' defusedxml==0.8.0rc2; python_version >= '3.6' distlib==0.3.7 -django==4.2.5; python_version >= '3.8' +django==4.2.6 django-appconf==1.0.5; python_version >= '3.6' django-celery-beat==2.5.0 -django-cors-headers==4.2.0; python_version >= '3.8' -django-environ==0.11.2; python_version >= '3.6' and python_version < '4' -django-extensions==3.2.3; python_version >= '3.6' +django-cors-headers==4.3.0 +django-environ==0.11.2 +django-extensions==3.2.3 django-imagekit==5.0.0 django-multiselectfield==0.1.12 -django-phonenumber-field==7.1.0; python_version >= '3.7' -django-storages==1.14.1; python_version >= '3.7' +django-phonenumber-field==7.2.0 +django-storages==1.14.2 django-templated-mail==1.1.1 django-timezone-field==6.0.1; python_version >= '3.8' and python_version < '4.0' -djangorestframework==3.14.0; python_version >= '3.6' +djangorestframework==3.14.0 djangorestframework-simplejwt==5.3.0; python_version >= '3.7' -djoser==2.2.0; python_version >= '3.8' and python_version < '4.0' +djoser==2.2.0 filelock==3.12.4; python_version >= '3.8' -flake8==6.1.0; python_full_version >= '3.8.1' -gunicorn==21.2.0; python_version >= '3.5' +flake8==6.1.0 +gunicorn==21.2.0 identify==2.5.30; python_version >= '3.8' idna==3.4; python_version >= '3.5' -inflection==0.5.1; python_version >= '3.5' jmespath==1.0.1; python_version >= '3.7' -jsonschema==4.19.1; python_version >= '3.8' -jsonschema-specifications==2023.7.1; python_version >= '3.8' kombu==5.3.2; python_version >= '3.8' mccabe==0.7.0; python_version >= '3.6' nodeenv==1.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' @@ -51,12 +47,12 @@ oauthlib==3.2.2; python_version >= '3.6' packaging==23.2; python_version >= '3.7' phonenumbers==8.13.22 pilkit==3.0 -pillow==10.0.1; python_version >= '3.8' -platformdirs==3.10.0; python_version >= '3.7' -pre-commit==3.4.0; python_version >= '3.8' -prompt-toolkit==3.0.39; python_full_version >= '3.7.0' -psycopg2-binary==2.9.8; python_version >= '3.6' -pycodestyle==2.11.0; python_version >= '3.8' +pillow==10.0.1 +platformdirs==3.11.0; python_version >= '3.7' +pre-commit==3.5.0 +prompt-toolkit==3.0.39; python_version >= '3.7' +psycopg2-binary==2.9.9 +pycodestyle==2.11.1; python_version >= '3.8' pycparser==2.21 pyflakes==3.1.0; python_version >= '3.8' pyjwt==2.8.0; python_version >= '3.7' @@ -65,13 +61,11 @@ python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, python3-openid==3.2.0 pytz==2023.3.post1 pyyaml==6.0.1; python_version >= '3.6' -redis==5.0.1; python_version >= '3.7' -referencing==0.30.2; python_version >= '3.8' +redis==5.0.1 requests==2.31.0; python_version >= '3.7' requests-oauthlib==1.3.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -rpds-py==0.10.3; python_version >= '3.8' s3transfer==0.7.0; python_version >= '3.7' -sentry-sdk[django]==1.31.0 +sentry-sdk[django]==1.32.0 setuptools==68.2.2; python_version >= '3.8' six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' social-auth-app-django==5.3.0; python_version >= '3.7' @@ -79,9 +73,8 @@ social-auth-core==4.4.2; python_version >= '3.6' sqlparse==0.4.4; python_version >= '3.5' typing-extensions==4.8.0; python_version < '3.11' tzdata==2023.3; python_version >= '2' -uritemplate==4.1.1; python_version >= '3.6' -urllib3==1.26.17; python_version >= '3.6' +urllib3==2.0.6; python_version >= '3.6' vine==5.0.0; python_version >= '3.6' virtualenv==20.24.5; python_version >= '3.7' wcwidth==0.2.8 -whitenoise==6.5.0; python_version >= '3.7' +whitenoise==6.6.0 diff --git a/team_production_system/admin.py b/team_production_system/admin.py index d03f8ea..178c051 100644 --- a/team_production_system/admin.py +++ b/team_production_system/admin.py @@ -8,6 +8,15 @@ NotificationSettings ) + +class AvailabilityAdmin(admin.ModelAdmin): + readonly_fields = ("created_at", "modified_at") + + +class SessionAdmin(admin.ModelAdmin): + readonly_fields = ("created_at", "modified_at") + + # admin.site.register(UserAdmin) admin.site.register(CustomUser) admin.site.register(Mentor) diff --git a/team_production_system/helpers.py b/team_production_system/helpers.py new file mode 100644 index 0000000..080068b --- /dev/null +++ b/team_production_system/helpers.py @@ -0,0 +1,60 @@ +# helper.py +# Purpose: Helper functions for the team_production_system app. + +from datetime import timedelta +from django.utils import timezone +from team_production_system.models import Availability +from django.utils.dateparse import parse_datetime + + +# Create a list of Availability objects in 30 mins chunks for a time range +def create_30_min_availabilities(start_time_str, end_time_str, mentor): + chunk_size = timedelta(minutes=30) + start_time = parse_datetime(start_time_str) + end_time = parse_datetime(end_time_str) + + availabilities = [] + while start_time < end_time: + end_time_new = start_time + chunk_size + if end_time_new > end_time: + break + availability = { + 'start_time': start_time, + 'end_time': end_time_new, + 'mentor': mentor.user.pk, + 'status': 'Open' + } + availabilities.append(availability) + start_time += chunk_size + return availabilities + + +# Check if the mentor has any overlapping availabilities +def is_overlapping_availabilities(mentor, data): + """ + Check if there is any overlap with existing availabilities. + """ + start_time = data['start_time'] + end_time = data['end_time'] + overlapping_availabilities = Availability.objects.filter( + mentor=mentor, + start_time__lt=end_time, + end_time__gt=start_time + ) + return overlapping_availabilities.exists() + + +# Check if the start_time is in the future +def is_valid_start_time(start_time): + """ + Check that the start_time is in the future. + """ + return start_time > timezone.now() + + +# Check if the end_time is after the start_time +def is_valid_end_time(start_time, end_time): + """ + Check that the end_time is after the start_time. + """ + return end_time > start_time diff --git a/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py b/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py new file mode 100644 index 0000000..eafa3f1 --- /dev/null +++ b/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.5 on 2023-10-10 20:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("team_production_system", "0011_mentor_team_number"), + ] + + operations = [ + migrations.RemoveConstraint( + model_name="availability", + name="availability_constraint", + ), + migrations.AddField( + model_name="availability", + name="status", + field=models.CharField( + choices=[ + ("Open", "Open"), + ("Requested", "Requested"), + ("Confirmed", "Confirmed"), + ], + default="Open", + max_length=10, + ), + ), + migrations.AddConstraint( + model_name="availability", + constraint=models.UniqueConstraint( + fields=("mentor", "start_time"), + name="availability_constraint", + violation_error_message="Availability already exists.", + ), + ), + ] diff --git a/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py b/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py new file mode 100644 index 0000000..1521c07 --- /dev/null +++ b/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.6 on 2023-10-11 04:24 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "team_production_system", + "0012_remove_availability_availability_constraint_and_more", + ), + ] + + operations = [ + migrations.AddField( + model_name="availability", + name="created_at", + field=models.DateTimeField( + auto_now_add=True, + default=datetime.datetime( + 2023, 10, 11, 4, 24, 26, 645977, tzinfo=datetime.timezone.utc + ), + ), + preserve_default=False, + ), + migrations.AddField( + model_name="availability", + name="modified_at", + field=models.DateTimeField(auto_now=True), + ), + migrations.AddField( + model_name="session", + name="modified_at", + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/team_production_system/models/availability.py b/team_production_system/models/availability.py index f6a3a3d..f17a72f 100644 --- a/team_production_system/models/availability.py +++ b/team_production_system/models/availability.py @@ -5,16 +5,33 @@ # Allow mentors to set their avaliabiltiy class Availability(models.Model): + + STATUS_CHOICES = [ + ('Open', 'Open'), + ('Requested', 'Requested'), + ('Confirmed', 'Confirmed'), + ] + mentor = models.ForeignKey( - Mentor, on_delete=models.CASCADE, related_name='mentor_availability') + Mentor, on_delete=models.CASCADE, related_name='mentor_availability' + ) start_time = models.DateTimeField() end_time = models.DateTimeField() + status = models.CharField( + max_length=10, + choices=STATUS_CHOICES, + default='Open' + ) + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) class Meta: constraints = [ UniqueConstraint( fields=['mentor', 'start_time'], - name='availability_constraint') + name='availability_constraint', + violation_error_message='Availability already exists.' + ) ] def __str__(self): diff --git a/team_production_system/models/session.py b/team_production_system/models/session.py index 6118243..1253cbd 100644 --- a/team_production_system/models/session.py +++ b/team_production_system/models/session.py @@ -22,7 +22,6 @@ class Session(models.Model): project = models.CharField(max_length=500) help_text = models.TextField(max_length=500) git_link = models.URLField(max_length=200) - created_at = models.DateTimeField(auto_now_add=True) confirmed = models.BooleanField(default=False) status_choices = [ ('Pending', 'Pending'), @@ -39,6 +38,8 @@ class Session(models.Model): ] session_length = models.IntegerField( choices=session_length_choices, default=30) + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) def end_time(self): return self.start_time + timedelta(minutes=self.session_length) diff --git a/team_production_system/serializers/__init__.py b/team_production_system/serializers/__init__.py index 0b810bd..70ec0d3 100644 --- a/team_production_system/serializers/__init__.py +++ b/team_production_system/serializers/__init__.py @@ -1,6 +1,9 @@ # flake8: noqa -from .availability import AvailabilitySerializer +from .availability import ( + AvailabilitySerializer, + AvailabilitySerializerV2 +) from .custom_user import CustomUserSerializer from .mentor_profile import MentorProfileSerializer from .mentor_list import MentorListSerializer diff --git a/team_production_system/serializers/availability.py b/team_production_system/serializers/availability.py index edfb406..d78af79 100644 --- a/team_production_system/serializers/availability.py +++ b/team_production_system/serializers/availability.py @@ -4,15 +4,21 @@ Mentor, Availability, ) +from team_production_system.helpers import ( + is_overlapping_availabilities, + is_valid_start_time, + is_valid_end_time +) +# V1 API # # The mentor availability serializer class AvailabilitySerializer(serializers.ModelSerializer): class Meta: model = Availability - fields = ('pk', 'mentor', 'start_time', 'end_time',) - read_only_fields = ('mentor', 'pk',) + fields = ['pk', 'mentor', 'start_time', 'end_time'] + read_only_fields = ('mentor', 'pk') def create(self, validated_data): mentor = Mentor.objects.select_related('user').get( @@ -79,4 +85,38 @@ def validate_end_time(self, value): ) return value - # TODO: Add validation for start times + +# V2 API # +# The mentor availability serializer +class AvailabilitySerializerV2(serializers.ModelSerializer): + + class Meta: + model = Availability + fields = [ + 'pk', + 'mentor', + 'start_time', + 'end_time', + 'status' + ] + read_only_fields = ('pk',) + + def validate(self, data): + mentor = Mentor.objects.select_related('user').get( + user=self.context['request'].user) + start_time = data.get('start_time') + end_time = data.get('end_time') + + if not is_valid_start_time(start_time): + raise serializers.ValidationError( + 'Start time must be in the future.') + + if not is_valid_end_time(start_time, end_time): + raise serializers.ValidationError( + 'End time must be after start time.') + + if is_overlapping_availabilities(mentor, data): + raise serializers.ValidationError( + 'Availability overlaps with existing availability.') + + return data diff --git a/team_production_system/tests/unit_tests/serializers/__init__.py b/team_production_system/tests/unit_tests/serializers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py b/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py new file mode 100644 index 0000000..4bb8681 --- /dev/null +++ b/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py @@ -0,0 +1,154 @@ +from datetime import datetime +from django.http import HttpRequest +from django.test import TestCase +from django.utils import timezone +from rest_framework import serializers +from ....serializers import AvailabilitySerializer, AvailabilitySerializerV2 +from ....models import Mentor, CustomUser, Availability + + +class AvailabilitySerializerTestCase(TestCase): + def setUp(self): + self.user = CustomUser.objects.create_user( + username='testuser', password='testpass') + self.mentor = Mentor.objects.create(user=self.user) + self.availability_attributes = { + 'mentor': self.mentor, + 'start_time': datetime.now( + timezone.utc) + timezone.timedelta(hours=4), + 'end_time': datetime.now( + timezone.utc) + timezone.timedelta(hours=5), + } + self.serializer_data = { + 'mentor': self.mentor.pk, + 'start_time': self.availability_attributes['start_time'], + 'end_time': self.availability_attributes['end_time'], + } + self.availability = Availability.objects.create( + **self.availability_attributes) + self.request = HttpRequest() + self.request.user = self.user + self.serializer = AvailabilitySerializer( + instance=self.availability, + context={'request': self.request}) + + def test_contains_expected_fields(self): + data = self.serializer.data + expected_keys = ['pk', 'mentor', 'start_time', 'end_time'] + self.assertCountEqual(data.keys(), expected_keys) + + def test_mentor_field_content(self): + data = self.serializer.data + self.assertEqual(data['mentor'], self.mentor.pk) + + def test_start_time_field_content(self): + data = self.serializer.data + self.assertEqual( + data['start_time'], + self.serializer_data[ + 'start_time'].strftime('%Y-%m-%dT%H:%M:%S.%fZ') + ) + + def test_end_time_field_content(self): + data = self.serializer.data + self.assertEqual( + data['end_time'], + self.serializer_data[ + 'end_time'].strftime('%Y-%m-%dT%H:%M:%S.%fZ') + ) + + def test_create(self): + start_time = datetime.now(timezone.utc) + timezone.timedelta(hours=5) + end_time = datetime.now(timezone.utc) + timezone.timedelta(hours=6) + serializer_data = { + 'mentor': self.mentor.pk, + 'start_time': start_time, + 'end_time': end_time, + } + serializer = AvailabilitySerializer( + data=serializer_data, + context={'request': self.request} + ) + self.assertTrue(serializer.is_valid()) + availability = serializer.save() + self.assertEqual(availability.mentor, self.mentor) + self.assertEqual(availability.start_time, start_time) + self.assertEqual(availability.end_time, end_time) + + +# Test class for AvailabilitySerializerV2 +class AvailabilitySerializerV2TestCase(TestCase): + def setUp(self): + self.user = CustomUser.objects.create_user( + username='testuser', password='testpass') + self.mentor = Mentor.objects.create(user=self.user) + self.request = HttpRequest() + self.request.user = self.user + self.availability_attributes = { + 'mentor': self.mentor, + 'start_time': timezone.now() + timezone.timedelta(hours=3), + 'end_time': timezone.now() + timezone.timedelta(hours=4), + } + self.serializer_data = { + 'mentor': self.mentor.pk, + 'start_time': self.availability_attributes['start_time'], + 'end_time': self.availability_attributes['end_time'], + } + self.availability = Availability.objects.create( + **self.availability_attributes) + self.serializer = AvailabilitySerializerV2( + instance=self.availability, + context={'request': self.request}) + + # Test that the serializer contains the expected fields + def test_contains_expected_fields(self): + data = self.serializer.data + self.assertEqual(set(data.keys()), set( + ['pk', 'mentor', 'start_time', 'end_time', 'status'])) + + def test_create(self): + pass + + # Test validate method + def test_validate(self): + serializer = AvailabilitySerializerV2( + context={'request': self.request}) + start_time = datetime.now( + timezone.utc) + timezone.timedelta(hours=1) + end_time = timezone.now() + timezone.timedelta(hours=2) + data = { + 'start_time': start_time, + 'end_time': end_time + } + + # Test valid input data + validated_data = serializer.validate(data) + self.assertEqual(validated_data, data) + + # Test invalid start_time + start_time = timezone.now() - timezone.timedelta(hours=1) + end_time = timezone.now() + timezone.timedelta(hours=2) + data = { + 'start_time': start_time, + 'end_time': end_time, + } + with self.assertRaises(serializers.ValidationError) as context: + serializer.validate(data) + self.assertEqual( + str(context.exception.detail[0]), + 'Start time must be in the future.' + ) + + # Test invalid end_time + start_time = timezone.now() + timezone.timedelta(hours=2) + end_time = timezone.now() + timezone.timedelta(hours=1) + data = { + 'start_time': start_time, + 'end_time': end_time, + } + with self.assertRaises(serializers.ValidationError) as context: + serializer.validate(data) + self.assertEqual( + str(context.exception.detail[0]), + 'End time must be after start time.' + ) diff --git a/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py b/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py index 976a213..279eb2a 100644 --- a/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py +++ b/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py @@ -1,10 +1,14 @@ from django.urls import reverse from django.utils import timezone +from datetime import timedelta from rest_framework import status from rest_framework.test import APIClient from django.test import TestCase from ....models import Mentor, Availability, CustomUser -from ....serializers import AvailabilitySerializer +from ....serializers import ( + AvailabilitySerializer, + AvailabilitySerializerV2 +) from unittest.mock import patch @@ -23,6 +27,7 @@ def setUp(self): start_time=timezone.now() + timezone.timedelta(hours=1), end_time=timezone.now() + timezone.timedelta(hours=2) ) + self.url = reverse('availability') @patch('django.utils.timezone') def test_get_availability_list(self, mock_timezone): @@ -38,10 +43,8 @@ def test_get_availability_list(self, mock_timezone): # Set up the mock timezone to return a fixed datetime mock_timezone.now.return_value = timezone.datetime(2022, 1, 1, tzinfo=timezone.utc) - # Make a GET request to the AvailabilityList view response = self.client.get('/availability/', format='json') - # Check that the response status code is 200 OK self.assertEqual(response.status_code, 200) @@ -49,9 +52,9 @@ def test_get_availability_list(self, mock_timezone): self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['start_time'], self.availability.start_time.isoformat().replace( - '+00:00', 'Z')) + '+00:00', 'Z')) - def test_create_availability(self): + def test_create_availability_v1(self): """ Test that a POST request to create a new Availability returns a status code of 201 CREATED and the new Availability. @@ -67,8 +70,7 @@ def test_create_availability(self): 'end_time': timezone.now() + timezone.timedelta(hours=4) } - url = reverse('availability') - response = client.post(url, data, format='json') + response = client.post(self.url, data, format='json') # Check that the response has a status code of 201 CREATED self.assertEqual(response.status_code, status.HTTP_201_CREATED) @@ -79,7 +81,7 @@ def test_create_availability(self): self.assertEqual(response.data['start_time'], serializer.data['start_time']) - def test_create_availability_with_invalid_data(self): + def test_create_availability_v1_with_invalid_data(self): """ Test that a POST request to create a new Availability with invalid data returns a status code of 400 BAD REQUEST and an error message. @@ -94,12 +96,97 @@ def test_create_availability_with_invalid_data(self): 'start_time': timezone.now() + timezone.timedelta(hours=2), 'end_time': timezone.now() + timezone.timedelta(hours=1) } - url = reverse('availability') - response = client.post(url, data, format='json') + + response = client.post(self.url, data, format='json') # Check that the response has a status code of 400 BAD REQUEST self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Check that the response data contains an error message - self.assertEqual(response.data['non_field_errors'][0], + self.assertEqual(str(response.data[0]), 'End time must be after start time.') + + def test_create_availability_v2(self): + self.client = APIClient() + self.client.force_authenticate(user=self.user) + + start_time = timezone.now() + timedelta(hours=5) + end_time = start_time + timedelta(hours=1) + data = { + 'start_time': start_time, + 'end_time': end_time, + } + headers = {'HTTP_ACCEPT': 'application/json; version=v2'} + response = self.client.post(self.url, data, format='json', **headers) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Availability.objects.count(), 3) + availability = Availability.objects.last() + self.assertEqual( + availability.start_time, end_time - timedelta(minutes=30)) + self.assertEqual(availability.end_time, end_time) + self.assertEqual(availability.mentor, self.mentor) + + def test_create_availability_v2_with_overlap(self): + self.client = APIClient() + self.client.force_authenticate(user=self.user) + + start_time = timezone.now() + timedelta(hours=7) + end_time = start_time + timedelta(hours=8) + Availability.objects.create( + mentor=self.mentor, start_time=start_time, end_time=end_time) + data = { + 'start_time': start_time, + 'end_time': end_time, + } + headers = {'HTTP_ACCEPT': 'application/json; version=v2'} + response = self.client.post(self.url, data, format='json', **headers) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual(Availability.objects.count(), 2) + + def test_create_availability_v2_with_past_end_time(self): + self.client = APIClient() + self.client.force_authenticate(user=self.user) + + start_time = timezone.now() + timedelta(hours=1) + end_time = timezone.now() - timedelta(hours=1) + data = { + 'start_time': start_time, + 'end_time': end_time, + } + + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual(Availability.objects.count(), 1) + + def test_create_availability_v2_with_time_not_divisible_by_30(self): + self.client = APIClient() + self.client.force_authenticate(user=self.user) + + start_time = timezone.now() + timedelta(hours=2) + end_time = timezone.now() + timedelta(hours=3, minutes=15) + data = { + 'start_time': start_time, + 'end_time': end_time, + } + headers = {'HTTP_ACCEPT': 'application/json; version=v2'} + response = self.client.post(self.url, data, format='json', **headers) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(len(response.data), 2) + availability_1 = Availability.objects.get(pk=response.data[0]['pk']) + availability_2 = Availability.objects.get(pk=response.data[1]['pk']) + self.assertEqual(availability_1.end_time, + start_time + timedelta(minutes=30)) + self.assertNotEqual(availability_2.end_time, end_time) + self.assertEqual(availability_1.mentor, self.mentor) + + def test_list_availabilities_v2(self): + self.client = APIClient() + self.client.force_authenticate(user=self.user) + + headers = {'HTTP_ACCEPT': 'application/json; version=v2'} + response = self.client.get(self.url, format='json', **headers) + self.assertEqual(response.status_code, status.HTTP_200_OK) + availabilities = Availability.objects.filter(mentor=self.mentor) + serializer = AvailabilitySerializerV2(availabilities, many=True) + self.assertEqual(response.data, serializer.data) diff --git a/team_production_system/tests/unit_tests/views/test_availability_delete_view.py b/team_production_system/tests/unit_tests/views/test_availability_delete_view.py new file mode 100644 index 0000000..470c307 --- /dev/null +++ b/team_production_system/tests/unit_tests/views/test_availability_delete_view.py @@ -0,0 +1,32 @@ +from django.test import TestCase +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APIClient +from ....models import Availability, Mentor, CustomUser + + +class AvailabilityDeleteViewTestCase(TestCase): + def setUp(self): + self.client = APIClient() + self.user = CustomUser.objects.create_user( + username='testuser', password='testpass') + self.mentor = Mentor.objects.create(user=self.user) + self.client.force_authenticate(user=self.user) + + def test_get_object(self): + # Create an Availability instance for the logged-in user + availability = Availability.objects.create( + mentor=self.mentor, + start_time='2022-01-01T00:00:00Z', + end_time='2022-01-01T01:00:00Z' + ) + + # Test that get_object returns the correct Availability instance + url = reverse('availability-delete', args=[availability.id]) + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # Test that get_object raises Http404 for non-existent Availability + url = reverse('availability-delete', args=[availability.id + 1]) + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) diff --git a/team_production_system/urls.py b/team_production_system/urls.py index 0bb5129..7a99301 100644 --- a/team_production_system/urls.py +++ b/team_production_system/urls.py @@ -3,10 +3,11 @@ urlpatterns = [ - # User information end points + + # User endpoints path('myprofile/', views.UserProfile.as_view(), name='my-profile'), - # List of mentor end points + # Mentor end points path('mentor/', views.MentorList.as_view(), name='mentor-list'), path('mentorinfo/', views.MentorInfoView.as_view(), name='mentor-info'), path('mentor//', views.MentorFilteredList.as_view(), @@ -14,22 +15,22 @@ path('mentorinfoupdate/', views.MentorInfoUpdateView.as_view(), name='mentor-info-update'), - - # List of mentee end points + # Mentee endpoints path('mentee/', views.MenteeList.as_view(), name='mentee-list'), path('menteeinfo/', views.MenteeInfoView.as_view(), name='mentee-info'), path('menteeinfoupdate/', views.MenteeInfoUpdateView.as_view(), name='mentee-info-update'), - # End points related to sessions + # Availability endpoints path( 'availability/', views.AvailabilityListCreateView.as_view(), name='availability' ), - # Delete availability path('availability//', views.AvailabilityDeleteView.as_view(), name='availability-delete'), + + # Session endpoints path('session/', views.SessionView.as_view(), name='session'), path('archivesession/', views.ArchiveSessionView.as_view(), name='archive-session'), @@ -39,9 +40,11 @@ name='session-detail'), path('sessionsignuplist/', views.SessionSignupListView.as_view(), name='session-signup-list'), + + # Notification endpoints path( - 'notificationsettings//', - views.NotificationSettingsView.as_view(), - name='notification-settings' + 'notificationsettings//', + views.NotificationSettingsView.as_view(), + name='notification-settings' ), -] + ] diff --git a/team_production_system/views/availability_list_create.py b/team_production_system/views/availability_list_create.py index 2b73a0a..fb929b5 100644 --- a/team_production_system/views/availability_list_create.py +++ b/team_production_system/views/availability_list_create.py @@ -1,8 +1,13 @@ -from rest_framework import generics +from rest_framework import generics, status from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response from django.utils import timezone -from team_production_system.serializers import AvailabilitySerializer +from team_production_system.serializers import ( + AvailabilitySerializer, + AvailabilitySerializerV2 +) from team_production_system.models import Mentor, Availability +from team_production_system.helpers import create_30_min_availabilities # Create and view all availabilities @@ -10,11 +15,65 @@ class AvailabilityListCreateView(generics.ListCreateAPIView): serializer_class = AvailabilitySerializer permission_classes = [IsAuthenticated] + def handle_exception(self, exc): + response = super().handle_exception(exc) + + if isinstance(response.data, dict) and 'non_field_errors' in response.data: + response.data = response.data['non_field_errors'] + + return response + def get_queryset(self): - # Get the Mentor instance for the logged in user - mentor = Mentor.objects.get(user=self.request.user) - # Exclude any availability that has an end time in the past - # and filter availabilities belonging to the logged in user's mentor - return Availability.objects.filter(mentor=mentor, - end_time__gte=timezone.now() - ).select_related('mentor__user') + if self.request.version == 'v2': + # Get the Mentor instance for the logged in user + mentor = Mentor.objects.select_related('user').get( + user=self.request.user) + return Availability.objects.filter( + mentor=mentor, + end_time__gte=timezone.now() + ).select_related('mentor__user').order_by('start_time') + else: + # Get the Mentor instance for the logged in user + mentor = Mentor.objects.get(user=self.request.user) + # Exclude any availability that has an end time in the past + # and filter availabilities belonging to the logged in mentor + return Availability.objects.filter( + mentor=mentor, end_time__gte=timezone.now() + ).select_related('mentor__user') + + def create(self, request, *args, **kwargs): + if request.version == 'v2': + # Validate data before creating 30 min availabilities + request.data.update(mentor=request.user.mentor) + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + # Create 30 min availabilities + availabilities = create_30_min_availabilities( + request.data['start_time'], + request.data['end_time'], + request.user.mentor + ) + # Serialize and save 30 min availabilities + serializer = self.get_serializer(data=availabilities, many=True) + serializer.is_valid(raise_exception=True) + self.perform_create(serializer) + + headers = self.get_success_headers(serializer.data) + return Response( + serializer.data, + status=status.HTTP_201_CREATED, + headers=headers) + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + self.perform_create(serializer) + headers = self.get_success_headers(serializer.data) + return Response( + serializer.data, + status=status.HTTP_201_CREATED, + headers=headers) + + def get_serializer_class(self): + if self.request.version == 'v2': + return AvailabilitySerializerV2 + else: + return AvailabilitySerializer From 43a27d16421e6c9bee5bb2a5a94fc021758be684 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Sat, 28 Oct 2023 21:01:39 -0400 Subject: [PATCH 08/18] feat(media): media files upload locally when debug is true (#173) Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> --- .gitignore | 2 +- config/settings.py | 16 ++++++++++++++-- media/random_photo/1.jpg | Bin 0 -> 197840 bytes media/random_photo/2.jpg | Bin 0 -> 25880 bytes media/random_photo/3.jpg | Bin 0 -> 184852 bytes 5 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 media/random_photo/1.jpg create mode 100644 media/random_photo/2.jpg create mode 100644 media/random_photo/3.jpg diff --git a/.gitignore b/.gitignore index e972286..04320a1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ __pycache__/ local_settings.py db.sqlite3 db.sqlite3-journal -media +media/profile_photo/* # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ # in your Git repository. Update and uncomment the following line accordingly. diff --git a/config/settings.py b/config/settings.py index 2538074..c19ac8e 100644 --- a/config/settings.py +++ b/config/settings.py @@ -170,8 +170,20 @@ 'CacheControl': 'max-age=86400', } - -DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' +if env("DEBUG") == False: + DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" + +if env("DEBUG") == True: + DEFAULT_FILE_STORAGE = "django.core.files.storage.FileSystemStorage" + +# STORAGES = { +# "default": { +# "BACKEND": "django.core.files.storage.FileSystemStorage", +# }, +# "staticfiles": { +# "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", +# }, +# } AUTH_USER_MODEL = 'team_production_system.CustomUser' diff --git a/media/random_photo/1.jpg b/media/random_photo/1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..caf611ee75e0255b47efe3334235a0dd2415045d GIT binary patch literal 197840 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Π<)_QUxUPNp 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

WLqEvs}OYuQV$IkOvh( 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 literal 0 HcmV?d00001 diff --git a/media/random_photo/2.jpg b/media/random_photo/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d21d8abea43f17728ee89d78d0f05cc3f03aaf08 GIT binary patch literal 25880 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 I8{MD(*~M|pDF6Tf literal 0 HcmV?d00001 diff --git a/media/random_photo/3.jpg b/media/random_photo/3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b4ede8a22aee9b310cad3ee6b9c3cc661173ba1e GIT binary patch literal 184852 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 literal 0 HcmV?d00001 From c0fac674759b8fc8f90a42ce0091a1cb4ffb1750 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Mon, 30 Oct 2023 20:49:35 -0400 Subject: [PATCH 09/18] fix(gitignore): removes requirements.txt file from project (#174) * fix(requirements): cleans up ignored files * docs(requirements): clarifies instructional language --- .gitignore | 2 ++ README.md | 2 +- requirements.txt | 80 ------------------------------------------------ 3 files changed, 3 insertions(+), 81 deletions(-) delete mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 04320a1..0f5b560 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ __pycache__/ local_settings.py db.sqlite3 db.sqlite3-journal +media +requirements.txt media/profile_photo/* # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ diff --git a/README.md b/README.md index 27c44f5..2977285 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ celery -A config.celery beat -l debug **Note:** Docker and Docker Desktop are required to be installed on your machine for this method. You will also need to have your .env file set up. -Update `requirements.txt` with any newly added installs: +Create or update `requirements.txt` with any new plugins from Pipfile: ```bash pipenv requirements > requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index abbc59e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,80 +0,0 @@ --i https://pypi.org/simple -amqp==5.1.1; python_version >= '3.6' -asgiref==3.7.2; python_version >= '3.7' -async-timeout==4.0.3; python_full_version <= '3.11.2' -billiard==4.1.0; python_version >= '3.7' -boto3==1.28.63 -botocore==1.31.63; python_version >= '3.7' -celery==5.3.4 -certifi==2023.7.22; python_version >= '3.6' -cffi==1.16.0; python_version >= '3.8' -cfgv==3.4.0; python_version >= '3.8' -charset-normalizer==3.3.0; python_version >= '3.7' -click==8.1.7; python_version >= '3.7' -click-didyoumean==0.3.0; python_version < '4.0' and python_full_version >= '3.6.2' -click-plugins==1.1.1 -click-repl==0.3.0; python_version >= '3.6' -coverage==7.3.2 -cron-descriptor==1.4.0 -cryptography==41.0.4; python_version >= '3.7' -defusedxml==0.8.0rc2; python_version >= '3.6' -distlib==0.3.7 -django==4.2.6 -django-appconf==1.0.5; python_version >= '3.6' -django-celery-beat==2.5.0 -django-cors-headers==4.3.0 -django-environ==0.11.2 -django-extensions==3.2.3 -django-imagekit==5.0.0 -django-multiselectfield==0.1.12 -django-phonenumber-field==7.2.0 -django-storages==1.14.2 -django-templated-mail==1.1.1 -django-timezone-field==6.0.1; python_version >= '3.8' and python_version < '4.0' -djangorestframework==3.14.0 -djangorestframework-simplejwt==5.3.0; python_version >= '3.7' -djoser==2.2.0 -filelock==3.12.4; python_version >= '3.8' -flake8==6.1.0 -gunicorn==21.2.0 -identify==2.5.30; python_version >= '3.8' -idna==3.4; python_version >= '3.5' -jmespath==1.0.1; python_version >= '3.7' -kombu==5.3.2; python_version >= '3.8' -mccabe==0.7.0; python_version >= '3.6' -nodeenv==1.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -oauthlib==3.2.2; python_version >= '3.6' -packaging==23.2; python_version >= '3.7' -phonenumbers==8.13.22 -pilkit==3.0 -pillow==10.0.1 -platformdirs==3.11.0; python_version >= '3.7' -pre-commit==3.5.0 -prompt-toolkit==3.0.39; python_version >= '3.7' -psycopg2-binary==2.9.9 -pycodestyle==2.11.1; python_version >= '3.8' -pycparser==2.21 -pyflakes==3.1.0; python_version >= '3.8' -pyjwt==2.8.0; python_version >= '3.7' -python-crontab==3.0.0 -python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -python3-openid==3.2.0 -pytz==2023.3.post1 -pyyaml==6.0.1; python_version >= '3.6' -redis==5.0.1 -requests==2.31.0; python_version >= '3.7' -requests-oauthlib==1.3.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -s3transfer==0.7.0; python_version >= '3.7' -sentry-sdk[django]==1.32.0 -setuptools==68.2.2; python_version >= '3.8' -six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -social-auth-app-django==5.3.0; python_version >= '3.7' -social-auth-core==4.4.2; python_version >= '3.6' -sqlparse==0.4.4; python_version >= '3.5' -typing-extensions==4.8.0; python_version < '3.11' -tzdata==2023.3; python_version >= '2' -urllib3==2.0.6; python_version >= '3.6' -vine==5.0.0; python_version >= '3.6' -virtualenv==20.24.5; python_version >= '3.7' -wcwidth==0.2.8 -whitenoise==6.6.0 From 89a893d43f0a15ffbe5c511195229e73cb53d420 Mon Sep 17 00:00:00 2001 From: James Andrews Date: Tue, 31 Oct 2023 11:39:46 -0400 Subject: [PATCH 10/18] docs(fix): updated documentation to fix inconsistencies (#175) * docs(fix): updated documentation to fix inconsistencies * docs(pr): addressing PR comments --------- Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> --- README.md | 182 +++++++++++++++++++++++++++++++++++++++------------- example.env | 12 +++- 2 files changed, 145 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 2977285..4cd0232 100644 --- a/README.md +++ b/README.md @@ -25,107 +25,132 @@ Please adhere to this project's [code of conduct](https://github.com/TeamProduct ## Features - Users can setup profiles as a mentor or mentee. -- Mentors can set their skill set and avalibilty. -- Mentees can schedule sessions with the menots, filtered by skills and avalibilty +- Mentors can set their skill set and availabilty. +- Mentees can schedule sessions with the mentors, filtered by skills and availabilty - Mentors can confirm sessions - Both mentor and mentee can cancel a session prior to session start time. -# Run Locally +# Running Locally + +## Local Setup Clone the project: ```bash -git clone https://github.com/TeamProductionSystem/Team_Production_System_BE.git +$ git clone https://github.com/TeamProductionSystem/Team_Production_System_BE.git ``` Navigate to the project directory: ```bash -cd Team_Production_System_BE +$ cd Team_Production_System_BE ``` Set up a virtual environment for the project using pipenv. If you don't have pipenv installed, you can install it using pip: ```bash -pip install pipenv +$ pip install pipenv ``` Then, activate the virtual environment by running: ```bash -pipenv shell +$ pipenv shell ``` Install the project dependencies: ```bash -pipenv install +$ pipenv install ``` +## Running without Containers + Set up the database by running the migrations: ```bash -python manage.py migrate +$ python manage.py migrate ``` +đź’ˇ**Note:** If this command throws an error, you might not have +[setup your database](#setting-up-a-postgresql-database), +or [configured your DATABASE_URL env variable properly](#environment-variables). + Start the development server: ```bash -python manage.py runserver +$ python manage.py runserver ``` The app should now be running at http://localhost:8000/ -## Run Celery and Redis locally +### Run Celery and Redis locally -Only needed if you want 15/60 minute reminders of scheduled sessions. +These servers are only needed if you want 15/60 minute reminders of scheduled sessions. +Run each of the following commands in its own terminal window at the project root. Start the Redis server: ```bash -redis-server +$ redis-server ``` Start the Celery server: ```bash -celery -A config.celery worker --loglevel=info +$ celery -A config.celery worker --loglevel=info ``` Start the Celery Beat server: ```bash -celery -A config.celery beat -l debug +$ celery -A config.celery beat -l debug ``` ## Run Locally via Docker Containers -**Note:** Docker and Docker Desktop are required to be installed on your machine for this method. -You will also need to have your .env file set up. +### Setup + +Install Docker Desktop. This will also install the Docker engine and the Docker CLI. +You can find installation instructions on the Docker website for +[Mac](https://docs.docker.com/desktop/install/mac-install/) and +[Windows](https://docs.docker.com/desktop/install/windows-install/). + +Setup your Environment Variables. You can find instructions [here](#environment-variables). Create or update `requirements.txt` with any new plugins from Pipfile: ```bash -pipenv requirements > requirements.txt +$ pipenv requirements > requirements.txt ``` -**Note:** If this step deletes everything in the requirements.txt file, your pipenv is out of date. +đź’ˇ**Note:** If this step deletes everything in the requirements.txt file, your pipenv is out of date. You can update it with the following command: ```bash -pip install --user --upgrade pipenv +$ pip install --user --upgrade pipenv ``` -Build docker images: +### Building Docker Image + +Run the following command: ```bash -docker compose build +$ docker compose build ``` -Spin up docker containers: +If you haven't built the container before, this can take over a minute. +After that, Docker will use the cached image layers as reference for future builds. +You can expect the build to only take seconds. + +If you want to build the image from scratch, add the flag `--no-cache` to the above command. + +### Running Docker Containers + +Run the following command: ```bash -docker compose up +$ docker compose up ``` The app should now be running at http://localhost:8000/ @@ -146,10 +171,15 @@ reload, just as if it was running in your local environment. Certain file changes, such as to a model, won't trigger this behavior. In these cases, stop then restart the containers. -To stop running the containers, hit Ctrl+C, then spin down the containers: +### Stopping Docker Containers + +To stop running the containers, hit `Ctrl+C`. The container instances will not be deleted. +If you spin them up again, those same instances will be running. + +If you want to delete the container instances, run the following command: ```bash -docker compose down +$ docker compose down ``` The database is persistant. If you make changes to a model, run makemigrations @@ -159,15 +189,14 @@ Follow these 2 steps once the containers are no longer running: - Remove the persistant volume: ```bash -docker volume rm team_production_system_be_postgres_data - -``` +$ docker volume rm team_production_system_be_postgres_data +``` - Rebuild the docker images without the cached data: ```bash -docker compose build --no-cache -```` +$ docker compose build --no-cache +``` The next time you spin up the docker containers, the database will be empty again. @@ -180,21 +209,30 @@ The next time you spin up the docker containers, the database will be empty agai For example: ``` -DATABASE_PASSWORD=mentors -DATABASE_NAME=mentors -DATABASE_USER=mentors -DATABASE_HOST=localhost -DATABASE_PORT=5432 +DATABASE_URL=postgres://mentors:mentors@localhost:5432/mentors + SECRET_KEY=my_secret_key DEBUG=True + DJANGO_SUPERUSER_USERNAME=admin DJANGO_SUPERUSER_PASSWORD=admin_password DJANGO_SUPERUSER_EMAIL=admin@example.com -CELERY_BROKER_URL = local_redis_url -CELERY_RESULT_BACKEND = local_redis_url + +CELERY_BROKER_URL=local_redis_url +CELERY_RESULT_BACKEND=local_redis_url + +AWS_ACCESS_KEY_ID=from-your-aws-account +AWS_SECRET_ACCESS_KEY=also_from-your-aws-account +AWS_STORAGE_BUCKET_NAME=your-aws-s3-bucket + +EMAIL_HOST=usually-gmail +EMAIL_HOST_USER=example@fake.com +EMAIL_HOST_PASSWORD=do-not-share + +SENTRY_DSN=not-necessary-for-running-locally ``` -- DATABASE_URL: This should be set to the URL of your database. Depending on your database type, this may include a username, password, host, and port. +- DATABASE_URL: This should be set to the URL of your database. Depending on your database type, this may include a username, password, host, and port. When using a local PostgreSQL database, it should take the form `postgres://:@localhost:5432/` - SECRET_KEY: This should be set to a secret key that is used for cryptographic signing in Django. It is important that this value is kept secret and is not shared publicly. @@ -210,6 +248,20 @@ CELERY_RESULT_BACKEND = local_redis_url - CELERY_RESULT_BACKEND: This should be set to your local redis url. +- AWS_ACCESS_KEY: This should be set to your AWS account. + +- AWS_SECRET_ACCESS_KEY: This should be set to your AWS account. + +- AWS_STORAGE_BUCKET_NAME: This should be set to your AWS S3 instance. + +- EMAIL_HOST: This should be set to the email account you want to use. + +- EMAIL_HOST_USER: This should be set to the email account you want to use. + +- EMAIL_HOST_PASSWORD: This should be set to the email account you want to use. + +- SENTRY_DSN: This should be set to your Sentry account. + 3. Save the .env file. # Testing @@ -217,19 +269,31 @@ CELERY_RESULT_BACKEND = local_redis_url For testing this app, we are using [Django Test Case](https://docs.djangoproject.com/en/4.2/topics/testing/overview/) and [Django REST Framework API Test Case](https://www.django-rest-framework.org/api-guide/testing/#api-test-cases) along with [coverage.py](https://coverage.readthedocs.io/en/7.2.7/index.html) for test coverage reporting. To run tests: -`python manage.py test` -To skip a test that isn't finished, add the following before the test class: +```bash +$ python manage.py test +``` + +đź’ˇ**Note:** To skip a test that isn't finished, add the following before the test class: `@unittest.skip("Test file is not ready yet")` To run coverage for test: -`coverage run manage.py test` + +```bash +$ coverage run manage.py test +``` After you run tests you can get the report in command-line by running: -`coverage report` + +```bash +$ coverage report +``` For an interactive html report, run: -`coverage html` + +```bash +$ coverage html +``` Then in the `htmlcov` folder of the project, open the file `index.html` in a browser. Here you can see an indepth analysis of coverage and what lines need testing. Click available links to view specific file coverage data. @@ -291,6 +355,32 @@ Commit messages should be in the following format: **Description:** A concise description of the changes. Start with a lowercase verb indicating what was done (e.g., add, update, remove, fix). +## Setting Up a PostgreSQL Database + +đź’ˇ**Note:** This guide assumes you are using a macOS. If you are using a different +operating system, only the installation step should be different. Here are guides +for [Windows](https://www.postgresqltutorial.com/postgresql-getting-started/install-postgresql/) +and [Linux](https://www.postgresqltutorial.com/postgresql-getting-started/install-postgresql-linux/). + +Install PostgreSQL on your machine, then run it as a background service: + +```bash +$ brew install postgresql@15 +$ brew services start postgresql@15 +``` + +Next, create a user: + +```bash +$ createuser -d +``` + +Then, create a database: + +```bash +$ createdb -U +``` + # API Reference API URL - https://team-production-system.onrender.com @@ -309,7 +399,7 @@ API URL - https://team-production-system.onrender.com ## User Create - Create a new user -- **Note: the username will automatically be converted to all lowercase letters** +- đź’ˇ**Note: the username will automatically be converted to all lowercase letters** ```http POST https://team-production-system.onrender.com/auth/users/ @@ -485,7 +575,7 @@ Host: https://team-production-system.onrender.com ## Edit User Profile (User Authentication **Required**) - Update the users profile information. -- **Note: This endpoint has multipart/form-data content type.** +- đź’ˇ**Note: This endpoint has multipart/form-data content type.** ```http PATCH - https://team-production-system.onrender.com/myprofile/ diff --git a/example.env b/example.env index 1088bba..c41e3bd 100644 --- a/example.env +++ b/example.env @@ -1,19 +1,25 @@ DATABASE_URL=Local Database + SECRET_KEY=Your Secret Key DEBUG=True or False + DJANGO_SUPERUSER_USERNAME=Example DJANGO_SUPERUSER_PASSWORD=Example DJANGO_SUPERUSER_EMAIL=Example + +CELERY_BROKER_URL=Example +CELERY_RESULT_BACKEND=Example + AWS_ACCESS_KEY_ID=Your AWS Key ID AWS_SECRET_ACCESS_KEY=Your AWS Secret key AWS_STORAGE_BUCKET_NAME=Your AWS storage bucket + EMAIL_HOST=Your email host EMAIL_HOST_USER=Example EMAIL_HOST_PASSWORD=Example + SENTRY_DSN=Example -CELERY_BROKER_URL=Example -CELERY_RESULT_BACKEND=Example (If you do not plan to create an Email server, AWS S3 bucket, and/or a sentry account, you will need to comment out lines 202 - 226 -while testing and uncomment them when creating a PR.) \ No newline at end of file +of config/settings.py while testing and uncomment them when creating a PR.) \ No newline at end of file From e23271ca12398167d4ed1ddca8044ea647e4eddc Mon Sep 17 00:00:00 2001 From: Amy Gori Date: Wed, 1 Nov 2023 15:20:13 -0400 Subject: [PATCH 11/18] Update S3 config to get media and static files working (#147) * Change storages config for Django >= 4.2 compatibility This commit updates the storages setting to use the new default backend. It also sets the default public ACL on S3 to true to allow for public access of images. More info about configuring django-storages: https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#configuration-settings About the STORAGES setting in Django: https://docs.djangoproject.com/en/4.2/ref/settings/#storages * Add UserAdmin class for better user password management in admin The big benefit is that passwords are properly hashed when users are added via the admin. More about customizing the UserAdmin class here: https://docs.djangoproject.com/en/4.2/topics/auth/customizing/#custom-users-and-django-contrib-admin * Use Django's file storage API instead of boto3 so this will work in dev as well * Add tests for user profile photo existence and storage --------- Co-authored-by: GitLukeW <102833183+GitLukeW@users.noreply.github.com> --- config/settings.py | 54 ++++++---------- team_production_system/admin.py | 3 +- .../test_user_profile_patch_upload.py | 64 +++++++++++++++++++ team_production_system/views/user_profile.py | 8 +-- 4 files changed, 88 insertions(+), 41 deletions(-) create mode 100644 team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py diff --git a/config/settings.py b/config/settings.py index c19ac8e..94c25c9 100644 --- a/config/settings.py +++ b/config/settings.py @@ -43,6 +43,8 @@ ALLOWED_HOSTS = [] +if DEBUG: + ALLOWED_HOSTS.append('127.0.0.1') INSTALLED_APPS = [ 'django.contrib.admin', @@ -67,8 +69,8 @@ MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', @@ -148,42 +150,33 @@ MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media" -if not DEBUG: - STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" - # Default primary key field type # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -if env("RENDER"): - ALLOWED_HOSTS.append(env("RENDER_EXTERNAL_HOSTNAME")) - DJANGO_SUPERUSER_USERNAME = env("DJANGO_SUPERUSER_USERNAME") +if env('RENDER'): + ALLOWED_HOSTS.append(env('RENDER_EXTERNAL_HOSTNAME')) + DJANGO_SUPERUSER_USERNAME = env('DJANGO_SUPERUSER_USERNAME') DJANGO_SUPERUSER_PASSWORD = env( - "DJANGO_SUPERUSER_PASSWORD") - DJANGO_SUPERUSER_EMAIL = env("DJANGO_SUPERUSER_EMAIL") - AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID") - AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY") - AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME") + 'DJANGO_SUPERUSER_PASSWORD') + DJANGO_SUPERUSER_EMAIL = env('DJANGO_SUPERUSER_EMAIL') + AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID') + AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY') + AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME') AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com' AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', } - -if env("DEBUG") == False: - DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" - -if env("DEBUG") == True: - DEFAULT_FILE_STORAGE = "django.core.files.storage.FileSystemStorage" - -# STORAGES = { -# "default": { -# "BACKEND": "django.core.files.storage.FileSystemStorage", -# }, -# "staticfiles": { -# "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", -# }, -# } + AWS_DEFAULT_ACL = 'public-read' + AWS_QUERYSTRING_AUTH = False + AWS_S3_FILE_OVERWRITE = False + STORAGES = { + 'default': {'BACKEND': 'storages.backends.s3.S3Storage'}, + 'staticfiles': { + 'BACKEND': 'storages.backends.s3boto3.S3StaticStorage', + }, + } AUTH_USER_MODEL = 'team_production_system.CustomUser' @@ -224,13 +217,6 @@ 'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': True, } -AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID') -AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY') -AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME') -AWS_QUERYSTRING_AUTH = False -AWS_S3_FILE_OVERWRITE = False - - EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = env('EMAIL_HOST') EMAIL_HOST_USER = env('EMAIL_HOST_USER') diff --git a/team_production_system/admin.py b/team_production_system/admin.py index 178c051..3ffcefb 100644 --- a/team_production_system/admin.py +++ b/team_production_system/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin +from django.contrib.auth.admin import UserAdmin from .models import ( Mentor, Mentee, @@ -18,7 +19,7 @@ class SessionAdmin(admin.ModelAdmin): # admin.site.register(UserAdmin) -admin.site.register(CustomUser) +admin.site.register(CustomUser, UserAdmin) admin.site.register(Mentor) admin.site.register(Mentee) admin.site.register(Session) diff --git a/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py b/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py new file mode 100644 index 0000000..c612378 --- /dev/null +++ b/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py @@ -0,0 +1,64 @@ +from django.core.files.uploadedfile import SimpleUploadedFile +from django.test import TestCase +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APIClient +from team_production_system.models import CustomUser + + +class UserProfilePatchTestCase(TestCase): + def setUp(self): + self.client = APIClient() + self.user = CustomUser.objects.create( + username="baby_yoda", + email="grogu@mandalor.edu", + password="badpassword" + ) + + def test_new_user_gets_random_photo_assigned(self): + # Check that the user has a profile photo + self.assertIsNotNone(self.user.profile_photo) + + def test_profile_photo_uploaded_first_time(self): + # mock photo file + photo = SimpleUploadedFile( + "photo.jpg", + b"this is a photo", + content_type="image/jpeg" + ) + # Make a PATCH request to update the user profile with the new photo + url = reverse("my-profile") + self.client.force_authenticate(user=self.user) + response = self.client.patch(url, {"profile_photo": photo}) + + # Check that the response status code is 200 OK + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Check that the profile photo was saved to the UserProfile object + self.user.refresh_from_db() + self.assertIsNotNone(self.user.profile_photo) + + def test_previous_file_deleted_when_new_photo_saved(self): + # get name of existing profile photo file + old_photo_name = self.user.profile_photo.name + # Create a new profile photo file + new_photo = SimpleUploadedFile( + "new_photo.jpg", + b"this is a new photo", + content_type="image/jpeg" + ) + + # Make a PATCH request to update the user profile with the new photo + url = reverse("my-profile") + self.client.force_authenticate(user=self.user) + response = self.client.patch(url, {"profile_photo": new_photo}) + + # Check that the response status code is 200 OK + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Check that the new profile photo was saved + self.user.refresh_from_db() + self.assertNotEqual(self.user.profile_photo.name, old_photo_name) + + # Check that the previous profile photo file was deleted from storage + self.assertFalse(self.user.profile_photo.storage.exists(old_photo_name)) diff --git a/team_production_system/views/user_profile.py b/team_production_system/views/user_profile.py index 2a855af..5e6b195 100644 --- a/team_production_system/views/user_profile.py +++ b/team_production_system/views/user_profile.py @@ -3,7 +3,6 @@ from rest_framework.parsers import MultiPartParser from rest_framework.permissions import IsAuthenticated from django.conf import settings -import boto3 from team_production_system.serializers import CustomUserSerializer from team_production_system.models import CustomUser @@ -42,11 +41,8 @@ def patch(self, request, *args, **kwargs): if 'profile_photo' in request.FILES: if user.profile_photo: - s3 = boto3.client('s3') - s3.delete_object( - Bucket=settings.AWS_STORAGE_BUCKET_NAME, - Key=user.profile_photo.name) - + # remove the file from storage + user.profile_photo.storage.delete(user.profile_photo.name) user.profile_photo = request.FILES['profile_photo'] user.save() From 23a5f62d7911d25ec2628d6fb65d0928afa6f4b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:53:12 -0400 Subject: [PATCH 12/18] chore(deps): bump urllib3 from 2.0.6 to 2.0.7 (#179) Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.6 to 2.0.7. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.0.6...2.0.7) --- updated-dependencies: - dependency-name: urllib3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Pipfile.lock | 316 +++++++++++++++++++++++++++------------------------ 1 file changed, 169 insertions(+), 147 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index a0c520f..9b6bc03 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -54,15 +54,16 @@ "sha256:94218aba2feb5b404b665b8d76c172dc654f79b4c5fa0e9e92459c098da87bf4" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.28.63" }, "botocore": { "hashes": [ - "sha256:6e582c811ea74f25bdb490ac372b2645de4a60286b42ddd8c69f3b6df82b6b12", - "sha256:cb9db5db5af865b1fc2e1405b967db5d78dd0f4d84e5dc1974e082733c1034b7" + "sha256:479abb5a1ee03eb00faa1ea176bc595b2f46f7494777807681a9df45ed99ea18", + "sha256:74e0a4515d61b2860b24dc208ca89a68d79dc00147125d531746d3ba808822ad" ], "markers": "python_version >= '3.7'", - "version": "==1.31.63" + "version": "==1.31.76" }, "celery": { "hashes": [ @@ -70,6 +71,7 @@ "sha256:9023df6a8962da79eb30c0c84d5f4863d9793a466354cc931d7f72423996de28" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==5.3.4" }, "certifi": { @@ -148,99 +150,99 @@ }, "charset-normalizer": { "hashes": [ - "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843", - "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786", - "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e", - "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8", - "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4", - "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa", - "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d", - "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82", - "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7", - "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895", - "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d", - "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a", - "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382", - "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678", - "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b", - "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e", - "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741", - "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4", - "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596", - "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9", - "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69", - "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c", - "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77", - "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13", - "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459", - "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e", - "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7", - "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908", - "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a", - "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f", - "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8", - "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482", - "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d", - "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d", - "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545", - "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34", - "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86", - "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6", - "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe", - "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e", - "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc", - "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7", - "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd", - "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c", - "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557", - "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a", - "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89", - "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078", - "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e", - "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4", - "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403", - "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0", - "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89", - "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115", - "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9", - "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05", - "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a", - "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec", - "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56", - "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38", - "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479", - "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c", - "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e", - "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd", - "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186", - "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455", - "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c", - "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65", - "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78", - "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287", - "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df", - "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43", - "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1", - "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7", - "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989", - "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a", - "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63", - "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884", - "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649", - "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810", - "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828", - "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4", - "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2", - "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd", - "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5", - "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe", - "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293", - "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e", - "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e", - "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8" - ], - "markers": "python_version >= '3.7'", - "version": "==3.3.0" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" }, "click": { "hashes": [ @@ -255,7 +257,7 @@ "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.2'", + "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", "version": "==0.3.0" }, "click-plugins": { @@ -329,6 +331,7 @@ "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==7.3.2" }, "cron-descriptor": { @@ -339,32 +342,32 @@ }, "cryptography": { "hashes": [ - "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67", - "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311", - "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8", - "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13", - "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143", - "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f", - "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829", - "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd", - "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397", - "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac", - "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d", - "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a", - "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839", - "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e", - "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6", - "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9", - "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860", - "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca", - "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91", - "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d", - "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714", - "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb", - "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f" + "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf", + "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84", + "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e", + "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8", + "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7", + "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1", + "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88", + "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86", + "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179", + "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81", + "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20", + "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548", + "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d", + "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d", + "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5", + "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1", + "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147", + "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936", + "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797", + "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696", + "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72", + "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da", + "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723" ], "markers": "python_version >= '3.7'", - "version": "==41.0.4" + "version": "==41.0.5" }, "defusedxml": { "hashes": [ @@ -387,6 +390,7 @@ "sha256:a64d2487cdb00ad7461434320ccc38e60af9c404773a2f95ab0093b4453a3215" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==4.2.6" }, "django-appconf": { @@ -411,6 +415,7 @@ "sha256:bd36c7aea0d070e462f3383f0dc9ef717e5fdc2b10a99c98c285f16da84ffba2" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==4.3.0" }, "django-environ": { @@ -419,6 +424,7 @@ "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be" ], "index": "pypi", + "markers": "python_version >= '3.6' and python_version < '4'", "version": "==0.11.2" }, "django-extensions": { @@ -427,6 +433,7 @@ "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.2.3" }, "django-imagekit": { @@ -451,6 +458,7 @@ "sha256:20c7c5c449e33eed5fd45ef8d3dc668faabaeff3277eddd1892b262d686ba381" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==7.2.0" }, "django-storages": { @@ -459,6 +467,7 @@ "sha256:51b36af28cc5813b98d5f3dfe7459af638d84428c8df4a03990c7d74d1bea4e5" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.14.2" }, "django-templated-mail": { @@ -482,6 +491,7 @@ "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.14.0" }, "djangorestframework-simplejwt": { @@ -498,15 +508,16 @@ "sha256:7b24718cdc51b4294b0abcf6bf0ead11aa3ca83652e351dfb04b7b8b15afa3b0" ], "index": "pypi", + "markers": "python_version >= '3.8' and python_version < '4.0'", "version": "==2.2.0" }, "filelock": { "hashes": [ - "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4", - "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd" + "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", + "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c" ], "markers": "python_version >= '3.8'", - "version": "==3.12.4" + "version": "==3.13.1" }, "flake8": { "hashes": [ @@ -514,6 +525,7 @@ "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5" ], "index": "pypi", + "markers": "python_full_version >= '3.8.1'", "version": "==6.1.0" }, "gunicorn": { @@ -522,15 +534,16 @@ "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==21.2.0" }, "identify": { "hashes": [ - "sha256:afe67f26ae29bab007ec21b03d4114f41316ab9dd15aa8736a167481e108da54", - "sha256:f302a4256a15c849b91cfcdcec052a8ce914634b2f77ae87dad29cd749f2d88d" + "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75", + "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d" ], "markers": "python_version >= '3.8'", - "version": "==2.5.30" + "version": "==2.5.31" }, "idna": { "hashes": [ @@ -661,6 +674,7 @@ "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==10.0.1" }, "platformdirs": { @@ -677,6 +691,7 @@ "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==3.5.0" }, "prompt-toolkit": { @@ -684,7 +699,7 @@ "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.0.39" }, "psycopg2-binary": { @@ -716,6 +731,7 @@ "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291", "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe", "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980", + "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93", "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692", "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119", "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716", @@ -725,6 +741,7 @@ "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc", "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c", "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5", + "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab", "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984", "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9", "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf", @@ -737,6 +754,7 @@ "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041", "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7", "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860", + "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d", "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245", "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27", "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417", @@ -760,6 +778,7 @@ "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.9.9" }, "pycodestyle": { @@ -885,6 +904,7 @@ "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==5.0.1" }, "requests": { @@ -919,7 +939,6 @@ "sha256:935e8fbd7787a3702457393b74b13d89a5afb67185bc0af85c00cb27cbd42e7c", "sha256:eeb0b3550536f3bbc05bb1c7e0feb3a78d74acb43b607159a606ed2ec0a33a4d" ], - "index": "pypi", "version": "==1.32.0" }, "setuptools": { @@ -940,19 +959,19 @@ }, "social-auth-app-django": { "hashes": [ - "sha256:2e71234656ddebe0c5b5ad450d42ee49f52a3f2d1708687fccf2a2c92d31a624", - "sha256:8719d57d01d80dcc9629a46e6806889aa9714fe4b658d2ebe3c120450591031d" + "sha256:09ac02a063cb313eed5e9ef2f9ac4477c8bf5bbd685925ff3aba43f9072f1bbb", + "sha256:28c65b2e2092f30cdb3cf912eeaa6988b49fdf4001b29bd89e683673d700a38e" ], - "markers": "python_version >= '3.7'", - "version": "==5.3.0" + "markers": "python_version >= '3.8'", + "version": "==5.4.0" }, "social-auth-core": { "hashes": [ - "sha256:9791d7c7aee2ac8517fe7a2ea2f942a8a5492b3a4ccb44a9b0dacc87d182f2aa", - "sha256:ea7a19c46b791b767e95f467881b53c5fd0d1efb40048d9ed3dbc46daa05c954" + "sha256:3d4154f45c0bacffe54ccf4361bce7e66cf5f5cd1bb0ebb7507ad09a1b07d9d9", + "sha256:f4ae5d8e503a401f319498bcad59fd1f6c473517eeae89c22299250f63c33365" ], - "markers": "python_version >= '3.6'", - "version": "==4.4.2" + "markers": "python_version >= '3.8'", + "version": "==4.5.0" }, "sqlparse": { "hashes": [ @@ -980,11 +999,12 @@ }, "urllib3": { "hashes": [ - "sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2", - "sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564" + "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", + "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" ], - "markers": "python_version >= '3.6'", - "version": "==2.0.6" + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==2.0.7" }, "vine": { "hashes": [ @@ -996,18 +1016,18 @@ }, "virtualenv": { "hashes": [ - "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b", - "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752" + "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af", + "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381" ], "markers": "python_version >= '3.7'", - "version": "==20.24.5" + "version": "==20.24.6" }, "wcwidth": { "hashes": [ - "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704", - "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4" + "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223", + "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8" ], - "version": "==0.2.8" + "version": "==0.2.9" }, "whitenoise": { "hashes": [ @@ -1015,6 +1035,7 @@ "sha256:b1f9db9bf67dc183484d760b99f4080185633136a273a03f6436034a41064146" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==6.6.0" } }, @@ -1025,6 +1046,7 @@ "sha256:2913064abd97b3419d1cc83ea71f042cb821f87e45b9c88cad5ad3c4ea87fe0c" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2.0.4" }, "pycodestyle": { From 6fbf4429b00f2277783894282e22e2938bee0872 Mon Sep 17 00:00:00 2001 From: James Andrews Date: Thu, 2 Nov 2023 12:52:52 -0400 Subject: [PATCH 13/18] Feat/issue 154/configuring linting (#172) * added several flake8 plugins and black * removed flake8-isort; celery app is instantiated based on new ENVIRONMENT env variable * fixed docs on running celery server locally; added error handling for incorrect ENVIRONMENT value * removed commented out code * fixing linting errors * added flake8-clean-block and fixed errors * added flake8-multiline-containers plugin and fixed errors * fixed multiline container in archive_session_list * fixed indentation * added and configured isort to project; fixed imports on other files * added and configured isort; isort and black configs are now in pyproject.toml; fixed imports; added isort, black, and flake8 to pre-commit * re-added black to pre-commit * corrected Environment Variables section in README; added flake8 plugins as dependencies in pre-commit config * added flake8-quotes plugin; fixed linting errors * fix(precommit): isort, black, flake8, and Branch Name Lint now only run during pre-commit hook * fix(readme): minor formatting JSONs in README * ci(linting): added flake8-isort plugin * docs(hooks): updating the Submitting Code section * docs(linting): added docs on what flake8 errors look like and each plugin's error code prefix * fix: commit-msg-linter no longer requires scope; removed autopep8 * docs: adding $ to shell commands * fix: Branch Name Lint should only run on push * docs: added example to branch name schema * docs: instructions on dealing with pre-commit during rebase * refactor: moved flake8 from packages to dev-packages in Pipfile; locked Pipfile; updated requirements.txt * chore: addressing PR comments * docs: auto-formatted and linted after rebase * chore: reverting sentry-sdk installation * fix: commit script should now handle scope conditionally * fix(commit): testing commit script with scope * docs(commits): added optional scope back to documentation about how we lint the commit message * added several flake8 plugins and black removed flake8-isort; celery app is instantiated based on new ENVIRONMENT env variable fixed docs on running celery server locally; added error handling for incorrect ENVIRONMENT value removed commented out code fixing linting errors added and configured isort; isort and black configs are now in pyproject.toml; fixed imports; added isort, black, and flake8 to pre-commit corrected Environment Variables section in README; added flake8 plugins as dependencies in pre-commit config fix(precommit): isort, black, flake8, and Branch Name Lint now only run during pre-commit hook docs(hooks): updating the Submitting Code section docs(linting): added docs on what flake8 errors look like and each plugin's error code prefix docs: added example to branch name schema chore: addressing PR comments docs: auto-formatted and linted after rebase fix: commit script should now handle scope conditionally docs(commits): added optional scope back to documentation about how we lint the commit message chore(gitignore): removing requirements.txt from cache fix(testing): test set created with set literal instead of set() constructor; added breakpoint to whitelist chore(hooks): switching run tests to pre-push hook chore(docs): updating Submitting Code section in README to include pre-push git hook fix(rebasing): moved branch name linter to pre-push to prevent issues with rebasing * chore: removed 'production' code from celery_settings * fix: deleted Pipfile.lock and reinstalled * fix(docker): added 'localhost' to ALLOWED_HOSTS if DEBUG is true; fixes trying to call on locally-running container API * fix: removed deleted code that made it through merge/rebase * fix: removed $ from shell commands --------- Co-authored-by: Em Sparr --- .flake8 | 7 +- .pre-commit-config.yaml | 43 +- Pipfile | 14 +- Pipfile.lock | 375 +++++++++++++----- README.md | 152 +++++-- config/__init__.py | 1 + config/celery_settings.py | 14 +- config/settings.py | 35 +- config/urls.py | 3 +- manage.py | 7 +- pyproject.toml | 9 + scripts/commit-msg-lint.sh | 9 +- team_production_system/admin.py | 12 +- team_production_system/helpers.py | 14 +- .../management/commands/add_superuser.py | 32 +- .../migrations/0001_initial.py | 228 +++++++++-- ...m_number_alter_mentor_about_me_and_more.py | 17 +- .../0003_alter_customuser_phone_number.py | 17 +- .../0004_alter_customuser_phone_number.py | 12 +- .../0005_alter_customuser_phone_number.py | 12 +- .../migrations/0006_alter_mentor_skills.py | 27 +- ...otificationsettings_delete_notification.py | 22 +- .../migrations/0008_alter_mentor_skills.py | 27 +- ...09_availability_availability_constraint.py | 5 +- .../migrations/0010_alter_mentor_skills.py | 33 +- .../migrations/0011_mentor_team_number.py | 1 - ...bility_availability_constraint_and_more.py | 1 - ...ed_at_availability_modified_at_and_more.py | 2 +- team_production_system/models/__init__.py | 2 +- team_production_system/models/availability.py | 25 +- team_production_system/models/custom_user.py | 14 +- team_production_system/models/mentee.py | 4 +- team_production_system/models/mentor.py | 12 +- .../models/notification_settings.py | 5 +- team_production_system/models/session.py | 44 +- .../serializers/__init__.py | 13 +- .../serializers/availability.py | 94 ++--- .../serializers/custom_user.py | 1 + .../serializers/mentee_list.py | 15 +- .../serializers/mentee_profile.py | 1 + .../serializers/mentor_list.py | 31 +- .../serializers/mentor_profile.py | 9 +- .../serializers/notification_settings.py | 14 +- team_production_system/serializers/session.py | 53 ++- team_production_system/tasks.py | 23 +- .../test_availability_list_create.py | 69 ++-- .../tests/test_availability.py | 24 +- .../models/test_availability_model.py | 22 +- .../unit_tests/models/test_mentor_model.py | 23 +- .../test_availability_serializer.py | 64 ++- .../tests/unit_tests/tasks/test_tasks.py | 6 +- .../test_availability_create_list_view.py | 54 ++- .../views/test_availability_delete_view.py | 8 +- team_production_system/urls.py | 100 ++--- team_production_system/views/__init__.py | 2 +- .../views/archive_session_list.py | 14 +- .../views/availability_delete.py | 14 +- .../views/availability_list_create.py | 34 +- .../views/mentee_info_list_create.py | 3 +- .../views/mentee_info_update.py | 1 + team_production_system/views/mentee_list.py | 21 +- .../views/mentor_filtered_list.py | 10 +- .../views/mentor_info_list_create.py | 3 +- .../views/mentor_info_update.py | 1 + team_production_system/views/mentor_list.py | 21 +- .../views/notification_settings.py | 7 +- team_production_system/views/session_list.py | 15 +- .../views/session_request_detail.py | 15 +- .../views/session_request_list_create.py | 129 ++++-- .../views/session_signup_list.py | 16 +- team_production_system/views/user_profile.py | 37 +- whitelist.txt | 15 + 72 files changed, 1456 insertions(+), 763 deletions(-) create mode 100644 pyproject.toml create mode 100644 whitelist.txt diff --git a/.flake8 b/.flake8 index e15622d..68faef7 100644 --- a/.flake8 +++ b/.flake8 @@ -4,4 +4,9 @@ exclude = *migrations* ./config/settings.py ./team_production_system/management/commands/add_superuser.py - +dictionaries = en_US,python,technical,django +; The bugbear plugin allows for a 10% safety net, so max-line-length is effectively 88 +; This is due to ignoring E501 and adding B950 +max-line-length = 80 +extend-ignore = E501 +extend-select = B950 \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 941e6c3..46e572c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,47 @@ repos: +- repo: https://github.com/PyCQA/isort + rev: "5.12.0" + hooks: + - id: isort + stages: [pre-commit] +- repo: https://github.com/psf/black + rev: "23.10.1" + hooks: + - id: black + stages: [pre-commit] +- repo: https://github.com/PyCQA/flake8 + rev: "6.1.0" + hooks: + - id: flake8 + stages: [pre-commit] + additional_dependencies: + - "flake8-bugbear" + - "pep8-naming" + - "flake8-spellcheck" + - "flake8-eradicate" + - "flake8-multiline-containers" + - "flake8-clean-block" + - "flake8-secure-coding-standard" + - "flake8-comprehensions" + - "flake8-quotes" - repo: local hooks: + - id: commit-msg-lint + name: 'Commit Message Lint' + entry: ./scripts/commit-msg-lint.sh + language: script + stages: [commit-msg] - id: branch-name-lint name: 'Branch Name Lint' entry: ./scripts/branch-name-lint.sh language: script always_run: true pass_filenames: false - - id: commit-msg-lint - name: 'Commit Message Lint' - entry: ./scripts/commit-msg-lint.sh - language: script - stages: [commit-msg] \ No newline at end of file + stages: [pre-push] + - id: django-test + name: 'Checking Tests' + entry: python manage.py test + always_run: true + pass_filenames: false + language: system + stages: [pre-push] diff --git a/Pipfile b/Pipfile index 32541f9..cd8b73b 100644 --- a/Pipfile +++ b/Pipfile @@ -22,7 +22,6 @@ django-multiselectfield = "*" boto3 = "*" sentry-sdk = {extras = ["django"], version = "*"} pytz = "*" -flake8 = "*" redis = "*" coverage = "*" celery = "*" @@ -30,7 +29,18 @@ django-celery-beat = "*" pre-commit = "*" [dev-packages] -autopep8 = "*" +flake8 = "*" +flake8-bugbear = "*" +pep8-naming = "*" +flake8-spellcheck = "*" +flake8-eradicate = "*" +black = "*" +flake8-multiline-containers = "*" +flake8-clean-block = "*" +flake8-secure-coding-standard = "*" +isort = "*" +flake8-comprehensions = "*" +flake8-quotes = "*" [requires] python_version = "3.10" diff --git a/Pipfile.lock b/Pipfile.lock index 9b6bc03..ebc02ea 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "db5550df8f89bfd52f3e07ec791eb1e004f3821342dcbf6ca0a9b9652184a25a" + "sha256": "9ef67d98faa54fd0a9a5cdb93981e091ca450e69a0d3bbfe6edaf50a9fad482b" }, "pipfile-spec": 6, "requires": { @@ -50,12 +50,12 @@ }, "boto3": { "hashes": [ - "sha256:65d052ec13197460586ee385aa2d6bba0e7378d2d2c7f3e93c044c43ae1ca782", - "sha256:94218aba2feb5b404b665b8d76c172dc654f79b4c5fa0e9e92459c098da87bf4" + "sha256:85e2fa361ad3210d30800bad311688261f2673a9b301e0edab56463d89609761", + "sha256:d18688bc5d688decf3cc404430a3ac3ec317be653cdcfbc51104c01f38a66434" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.28.63" + "version": "==1.28.76" }, "botocore": { "hashes": [ @@ -386,12 +386,12 @@ }, "django": { "hashes": [ - "sha256:08f41f468b63335aea0d904c5729e0250300f6a1907bf293a65499496cdbc68f", - "sha256:a64d2487cdb00ad7461434320ccc38e60af9c404773a2f95ab0093b4453a3215" + "sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41", + "sha256:e1d37c51ad26186de355cbcec16613ebdabfa9689bbade9c538835205a8abbe9" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.2.6" + "version": "==4.2.7" }, "django-appconf": { "hashes": [ @@ -519,15 +519,6 @@ "markers": "python_version >= '3.8'", "version": "==3.13.1" }, - "flake8": { - "hashes": [ - "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23", - "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5" - ], - "index": "pypi", - "markers": "python_full_version >= '3.8.1'", - "version": "==6.1.0" - }, "gunicorn": { "hashes": [ "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0", @@ -569,14 +560,6 @@ "markers": "python_version >= '3.8'", "version": "==5.3.2" }, - "mccabe": { - "hashes": [ - "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", - "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" - ], - "markers": "python_version >= '3.6'", - "version": "==0.7.0" - }, "nodeenv": { "hashes": [ "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2", @@ -603,11 +586,11 @@ }, "phonenumbers": { "hashes": [ - "sha256:001664c90f59b8954766c2db85adafc8dbc96177efeb49607ca4e64a7acaf569", - "sha256:85ceeba9e67984ba98182c77e8e4c70093d38c0c6a0cb2bd392e0694ddaeb1f6" + "sha256:7abc66f38d92c3b9e827d597b5d590283ca3b05288d9fadea8bc0d6c8ad73c06", + "sha256:7dd66c57da00c0f373de83074e78d66a0801381cface4d010cfe07be2fa77fe5" ], "index": "pypi", - "version": "==8.13.22" + "version": "==8.13.24" }, "pilkit": { "hashes": [ @@ -618,64 +601,64 @@ }, "pillow": { "hashes": [ - "sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff", - "sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f", - "sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21", - "sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635", - "sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a", - "sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f", - "sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1", - "sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d", - "sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db", - "sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849", - "sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7", - "sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876", - "sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3", - "sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317", - "sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91", - "sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d", - "sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b", - "sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd", - "sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed", - "sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500", - "sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7", - "sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a", - "sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a", - "sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0", - "sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf", - "sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f", - "sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1", - "sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088", - "sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971", - "sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a", - "sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205", - "sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54", - "sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08", - "sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21", - "sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d", - "sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08", - "sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e", - "sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf", - "sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b", - "sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145", - "sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2", - "sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d", - "sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d", - "sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf", - "sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad", - "sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d", - "sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1", - "sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4", - "sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2", - "sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19", - "sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37", - "sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4", - "sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68", - "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1" + "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", + "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", + "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", + "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", + "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", + "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", + "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", + "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", + "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", + "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", + "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", + "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", + "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", + "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", + "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", + "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", + "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", + "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", + "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", + "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", + "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", + "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", + "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", + "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", + "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", + "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", + "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", + "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", + "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", + "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", + "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", + "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", + "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", + "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", + "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", + "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", + "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", + "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", + "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", + "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", + "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", + "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", + "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", + "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", + "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", + "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", + "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", + "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", + "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", + "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", + "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", + "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", + "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", + "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==10.0.1" + "version": "==10.1.0" }, "platformdirs": { "hashes": [ @@ -781,14 +764,6 @@ "markers": "python_version >= '3.7'", "version": "==2.9.9" }, - "pycodestyle": { - "hashes": [ - "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", - "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" - ], - "markers": "python_version >= '3.8'", - "version": "==2.11.1" - }, "pycparser": { "hashes": [ "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", @@ -796,14 +771,6 @@ ], "version": "==2.21" }, - "pyflakes": { - "hashes": [ - "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774", - "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc" - ], - "markers": "python_version >= '3.8'", - "version": "==3.1.0" - }, "pyjwt": { "hashes": [ "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", @@ -824,7 +791,7 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.8.2" }, "python3-openid": { @@ -936,10 +903,10 @@ "django" ], "hashes": [ - "sha256:935e8fbd7787a3702457393b74b13d89a5afb67185bc0af85c00cb27cbd42e7c", - "sha256:eeb0b3550536f3bbc05bb1c7e0feb3a78d74acb43b607159a606ed2ec0a33a4d" + "sha256:1cce906dc86afda1ecd22c4716b0c846639151a3c3b59e23826711c6525c5642", + "sha256:816aeb900a54bba2d9346bad8ffac2d258c4fa09271b95a6533a714e9000f074" ], - "version": "==1.32.0" + "version": "==1.33.1" }, "setuptools": { "hashes": [ @@ -954,7 +921,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "social-auth-app-django": { @@ -1002,8 +969,7 @@ "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" ], - "index": "pypi", - "markers": "python_version >= '3.7'", + "markers": "python_version >= '3.6'", "version": "==2.0.7" }, "vine": { @@ -1040,14 +1006,189 @@ } }, "develop": { - "autopep8": { + "attrs": { + "hashes": [ + "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", + "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1.0" + }, + "black": { + "hashes": [ + "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884", + "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916", + "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258", + "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1", + "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce", + "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d", + "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982", + "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7", + "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173", + "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9", + "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb", + "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad", + "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc", + "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0", + "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a", + "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe", + "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace", + "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==23.10.1" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "eradicate": { + "hashes": [ + "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37", + "sha256:2b29b3dd27171f209e4ddd8204b70c02f0682ae95eecb353f10e8d72b149c63e" + ], + "version": "==2.3.0" + }, + "flake8": { + "hashes": [ + "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23", + "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.1'", + "version": "==6.1.0" + }, + "flake8-bugbear": { + "hashes": [ + "sha256:90cf04b19ca02a682feb5aac67cae8de742af70538590509941ab10ae8351f71", + "sha256:b182cf96ea8f7a8595b2f87321d7d9b28728f4d9c3318012d896543d19742cb5" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.1'", + "version": "==23.9.16" + }, + "flake8-clean-block": { "hashes": [ - "sha256:067959ca4a07b24dbd5345efa8325f5f58da4298dab0dde0443d5ed765de80cb", - "sha256:2913064abd97b3419d1cc83ea71f042cb821f87e45b9c88cad5ad3c4ea87fe0c" + "sha256:0a1f8a58be210a013715810a78dda029a65660373f585b7e14e36c3b85c7791d", + "sha256:9684c26a6b087e25f73966fe8f4a38f6abb3e9737a9f781140115e0e2c14a93c" ], "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.1.2" + }, + "flake8-comprehensions": { + "hashes": [ + "sha256:7b9d07d94aa88e62099a6d1931ddf16c344d4157deedf90fe0d8ee2846f30e97", + "sha256:81768c61bfc064e1a06222df08a2580d97de10cb388694becaf987c331c6c0cf" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.14.0" + }, + "flake8-eradicate": { + "hashes": [ + "sha256:18acc922ad7de623f5247c7d5595da068525ec5437dd53b22ec2259b96ce9d22", + "sha256:aee636cb9ecb5594a7cd92d67ad73eb69909e5cc7bd81710cf9d00970f3983a6" + ], + "index": "pypi", + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==1.5.0" + }, + "flake8-multiline-containers": { + "hashes": [ + "sha256:1b684da84b401f42f1ad36f0f90e24b7f49b2691458cb582911fb99d871bb0b2", + "sha256:7c47527f1a2b0a991b876e58a2758e0ecc6b2d10a5fd4ee7740d042722f2f281" + ], + "index": "pypi", + "version": "==0.0.19" + }, + "flake8-quotes": { + "hashes": [ + "sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1" + ], + "index": "pypi", + "version": "==3.3.2" + }, + "flake8-secure-coding-standard": { + "hashes": [ + "sha256:0c7222b8c92f85dc38014a53d6a1a8dab4267363b128afe480cbc2d1c29b2df0", + "sha256:a0393cd3ed5bd44a79735e15d1845e9416cda5b3fe39941984e2d9714916d779" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.4.0" + }, + "flake8-spellcheck": { + "hashes": [ + "sha256:6fb79724f27097af0b4c678c7eaf731f0d87cf4c1eae7fbd7836c1c78d67e12c", + "sha256:a0a37164b9175819b143ce0f0a8d2475457af3f0d77cd8423b0daf204662ee72" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.28.0" + }, + "isort": { + "hashes": [ + "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", + "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.0'", + "version": "==5.12.0" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], "markers": "python_version >= '3.6'", - "version": "==2.0.4" + "version": "==0.7.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, + "pathspec": { + "hashes": [ + "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", + "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + ], + "markers": "python_version >= '3.7'", + "version": "==0.11.2" + }, + "pep8-naming": { + "hashes": [ + "sha256:1705f046dfcd851378aac3be1cd1551c7c1e5ff363bacad707d43007877fa971", + "sha256:1a86b8c71a03337c97181917e2b472f0f5e4ccb06844a0d6f0a33522549e7a80" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.13.3" + }, + "platformdirs": { + "hashes": [ + "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3", + "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e" + ], + "markers": "python_version >= '3.7'", + "version": "==3.11.0" }, "pycodestyle": { "hashes": [ @@ -1057,6 +1198,14 @@ "markers": "python_version >= '3.8'", "version": "==2.11.1" }, + "pyflakes": { + "hashes": [ + "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774", + "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc" + ], + "markers": "python_version >= '3.8'", + "version": "==3.1.0" + }, "tomli": { "hashes": [ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", @@ -1064,6 +1213,14 @@ ], "markers": "python_version < '3.11'", "version": "==2.0.1" + }, + "typing-extensions": { + "hashes": [ + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + ], + "markers": "python_version < '3.11'", + "version": "==4.8.0" } } } diff --git a/README.md b/README.md index 4cd0232..b5f9769 100644 --- a/README.md +++ b/README.md @@ -37,31 +37,31 @@ Please adhere to this project's [code of conduct](https://github.com/TeamProduct Clone the project: ```bash -$ git clone https://github.com/TeamProductionSystem/Team_Production_System_BE.git +git clone https://github.com/TeamProductionSystem/Team_Production_System_BE.git ``` Navigate to the project directory: ```bash -$ cd Team_Production_System_BE +cd Team_Production_System_BE ``` Set up a virtual environment for the project using pipenv. If you don't have pipenv installed, you can install it using pip: ```bash -$ pip install pipenv +pip install pipenv ``` Then, activate the virtual environment by running: ```bash -$ pipenv shell +pipenv shell ``` Install the project dependencies: ```bash -$ pipenv install +pipenv install ``` ## Running without Containers @@ -69,7 +69,7 @@ $ pipenv install Set up the database by running the migrations: ```bash -$ python manage.py migrate +python manage.py migrate ``` đź’ˇ**Note:** If this command throws an error, you might not have @@ -79,7 +79,7 @@ or [configured your DATABASE_URL env variable properly](#environment-variables). Start the development server: ```bash -$ python manage.py runserver +python manage.py runserver ``` The app should now be running at http://localhost:8000/ @@ -92,19 +92,19 @@ Run each of the following commands in its own terminal window at the project roo Start the Redis server: ```bash -$ redis-server +redis-server ``` Start the Celery server: ```bash -$ celery -A config.celery worker --loglevel=info +celery -A config.celery_settings worker --loglevel=info ``` Start the Celery Beat server: ```bash -$ celery -A config.celery beat -l debug +celery -A config.celery_settings beat -l debug ``` ## Run Locally via Docker Containers @@ -121,14 +121,14 @@ Setup your Environment Variables. You can find instructions [here](#environment- Create or update `requirements.txt` with any new plugins from Pipfile: ```bash -$ pipenv requirements > requirements.txt +pipenv requirements > requirements.txt ``` đź’ˇ**Note:** If this step deletes everything in the requirements.txt file, your pipenv is out of date. You can update it with the following command: ```bash -$ pip install --user --upgrade pipenv +pip install --user --upgrade pipenv ``` ### Building Docker Image @@ -136,7 +136,7 @@ $ pip install --user --upgrade pipenv Run the following command: ```bash -$ docker compose build +docker compose build ``` If you haven't built the container before, this can take over a minute. @@ -150,7 +150,7 @@ If you want to build the image from scratch, add the flag `--no-cache` to the ab Run the following command: ```bash -$ docker compose up +docker compose up ``` The app should now be running at http://localhost:8000/ @@ -179,7 +179,7 @@ If you spin them up again, those same instances will be running. If you want to delete the container instances, run the following command: ```bash -$ docker compose down +docker compose down ``` The database is persistant. If you make changes to a model, run makemigrations @@ -189,13 +189,13 @@ Follow these 2 steps once the containers are no longer running: - Remove the persistant volume: ```bash -$ docker volume rm team_production_system_be_postgres_data -``` +docker volume rm team_production_system_be_postgres_data +``` - Rebuild the docker images without the cached data: ```bash -$ docker compose build --no-cache +docker compose build --no-cache ``` The next time you spin up the docker containers, the database will be empty again. @@ -209,8 +209,8 @@ The next time you spin up the docker containers, the database will be empty agai For example: ``` +ENVIRONMENT=dev DATABASE_URL=postgres://mentors:mentors@localhost:5432/mentors - SECRET_KEY=my_secret_key DEBUG=True @@ -232,6 +232,9 @@ EMAIL_HOST_PASSWORD=do-not-share SENTRY_DSN=not-necessary-for-running-locally ``` +- ENVIRONMENT: This should be either `dev` or `prod`, depending on what environment the app is running in. +As long as your are running locally, use the value `dev`. + - DATABASE_URL: This should be set to the URL of your database. Depending on your database type, this may include a username, password, host, and port. When using a local PostgreSQL database, it should take the form `postgres://:@localhost:5432/` - SECRET_KEY: This should be set to a secret key that is used for cryptographic signing in Django. It is important that this value is kept secret and is not shared publicly. @@ -271,28 +274,25 @@ For testing this app, we are using [Django Test Case](https://docs.djangoproject To run tests: ```bash -$ python manage.py test +python manage.py test ``` đź’ˇ**Note:** To skip a test that isn't finished, add the following before the test class: `@unittest.skip("Test file is not ready yet")` To run coverage for test: - ```bash -$ coverage run manage.py test +coverage run manage.py test ``` After you run tests you can get the report in command-line by running: - ```bash -$ coverage report +coverage report ``` For an interactive html report, run: - ```bash -$ coverage html +coverage html ``` Then in the `htmlcov` folder of the project, open the file `index.html` in a browser. Here you can see an indepth analysis of coverage and what lines need testing. Click available links to view specific file coverage data. @@ -311,13 +311,83 @@ Each error will show the file name and line to find the error. The command can b # Submitting Code -We use a pre-commit to check branch names and commit messages. Please follow the the following schema for branch names and commit messages: +We use several [git hooks](https://git-scm.com/docs/githooks) to ensure code quality +and consistency. These are run using the [pre-commit](https://pre-commit.com/) +Python package. + +Here are the processes we run for each hook: +- **[Pre-Commit](https://git-scm.com/docs/githooks#_pre_commit):** + - linting code with Flake8 + - autoformatting code with isort and black +- **[Commit-Msg](https://git-scm.com/docs/githooks#_commit_msg):** + - linting commit message +- **[Pre-Push](https://git-scm.com/docs/githooks#_pre_push):** + - linting branch name + - running all tests + +Below, we go over how to set up and use these hooks, the linting plugins used, +and the schemas for Branch Names and Commit Messages. + +## Pre-Commit Setup +These steps assume you have already entered a pipenv shell and installed all +dependencies. +Below are the commands and expected outputs: + +```bash +pre-commit install +pre-commit installed at .git/hooks/pre-commit + +pre-commit install --hook-type commit-msg +pre-commit installed at .git/hooks/commit-msg +``` + +To run the pre-commit checks before making a commit, run the following command. + +```bash +pre-commit run --all-files +``` + +If no files need changes, the output should look like this: + +```bash +isort....................................................................Passed +black....................................................................Passed +flake8...................................................................Passed +``` + +If isort or black catch any errors, they will automatically alter the files to fix them. +This will prevent making a commit, and you will need to stage the new changes. +flake8 errors need to be fixed manually. + +## Code Linting + +We ensure code consistancy by linting with flake8. +Errors found by flake 8 will be listed in the following format: +```bash +::: +``` +Error codes from flake8 will have a prefix of F. +The flake8 plugins used are listed below, along with their error code prefix: + + - flake8-bugbear (B): additional rules to catch bugs and design problems + - pep8-naming (N): check the PEP-8 naming conventions + - flake8-spellcheck (SC): spellcheck variables, classnames, comments, docstrings etc. + - flake8-eradicate (E): finds commented out or dead code + - flake8-clean-block (CLB): enforces a blank line after if/for/while/with/try blocks + - flake8-multiline (JS): ensures a consistent format for multiline containers + - flake8-secure-coding-standard (SCS): enforces some secure coding standards for Python + - flake8-comprehensions (C): helps you write better list/set/dict comprehensions + - flake8-quotes (Q): extension for checking quotes in Python + +đź’ˇ**Note:** If the spellcheck plugin gets caught on a name that you did not set, +add it to `whitelist.txt`. +**DO NOT ADD NAMES THAT YOU CREATE!!!** -## Branch Names +## Branch Name Schema Branch names should be in the following format: -`//` +`/issue-/` **Type:** The type of branch. This should be one of the following: @@ -331,7 +401,9 @@ Branch names should be in the following format: **Description:** A short description of the branch. This should be in lowercase and use dashes instead of spaces. -## Commit Messages +**Example:** `feat/issue-66/remove-jedi` + +## Commit Message Schema Commit messages should be in the following format: @@ -351,9 +423,12 @@ Commit messages should be in the following format: - chore - Miscellaneous changes, such as updating packages or bumping a version number - revert - Reverting a previous commit -**Scope:** This is optional but can provide additional contextual information. It describes the section or aspect of the codebase affected by the change. For example, auth for authentication-related changes or header for changes to a website's header component. +**Scope:** This is optional but can provide additional contextual information. +It describes the section or aspect of the codebase affected by the change. +For example, auth for authentication-related changes or header for changes to a website's header component. -**Description:** A concise description of the changes. Start with a lowercase verb indicating what was done (e.g., add, update, remove, fix). +**Description:** A concise description of the changes. +Start with a lowercase verb indicating what was done (e.g., add, update, remove, fix). ## Setting Up a PostgreSQL Database @@ -365,20 +440,20 @@ and [Linux](https://www.postgresqltutorial.com/postgresql-getting-started/instal Install PostgreSQL on your machine, then run it as a background service: ```bash -$ brew install postgresql@15 -$ brew services start postgresql@15 +brew install postgresql@15 +brew services start postgresql@15 ``` Next, create a user: ```bash -$ createuser -d +createuser -d ``` Then, create a database: ```bash -$ createdb -U +createdb -U ``` # API Reference @@ -423,7 +498,7 @@ Host: https://team-production-system.onrender.com "username": "TestUserLogin", "email": "testemail@fake.com", "password": "TestUserPassword", - "re_password": "TestUserPassword", + "re_password": "TestUserPassword" } ``` @@ -504,7 +579,7 @@ Host: https://team-production-system.onrender.com { "username": "testuserlogin" , - "password": "TestUserPassword", + "password": "TestUserPassword" } ``` @@ -819,7 +894,6 @@ Host: https://team-production-system.onrender.com ], "team_number": 10 } - ``` --- diff --git a/config/__init__.py b/config/__init__.py index ab2f983..bb40e99 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + from .celery_settings import app as celery_app __all__ = ('celery_app',) diff --git a/config/celery_settings.py b/config/celery_settings.py index d727e0a..1111ea4 100644 --- a/config/celery_settings.py +++ b/config/celery_settings.py @@ -1,22 +1,12 @@ from __future__ import absolute_import + import os -# import ssl + from celery import Celery from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') -# for production -# app = Celery( -# "config", -# broker_use_ssl={ -# 'ssl_cert_reqs': ssl.CERT_NONE -# }, -# redis_backend_use_ssl={ -# 'ssl_cert_reqs': ssl.CERT_NONE -# } -# ) -# for development app = Celery('config') app.conf.beat_schedule = { diff --git a/config/settings.py b/config/settings.py index 94c25c9..76df789 100644 --- a/config/settings.py +++ b/config/settings.py @@ -10,18 +10,18 @@ https://docs.djangoproject.com/en/4.1/ref/settings/ """ -import environ from pathlib import Path -from corsheaders.defaults import default_headers + +import environ import sentry_sdk +from corsheaders.defaults import default_headers from sentry_sdk.integrations.django import DjangoIntegration - env = environ.Env( # set casting, default value DEBUG=(bool, False), USE_S3=(bool, False), - RENDER=(bool, False) + RENDER=(bool, False), ) @@ -44,7 +44,7 @@ ALLOWED_HOSTS = [] if DEBUG: - ALLOWED_HOSTS.append('127.0.0.1') + ALLOWED_HOSTS.extend(['127.0.0.1', 'localhost']) INSTALLED_APPS = [ 'django.contrib.admin', @@ -102,9 +102,7 @@ # Database # https://docs.djangoproject.com/en/4.1/ref/settings/#databases -DATABASES = { - 'default': env.db() -} +DATABASES = {'default': env.db()} # Password validation @@ -155,15 +153,14 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -if env('RENDER'): - ALLOWED_HOSTS.append(env('RENDER_EXTERNAL_HOSTNAME')) - DJANGO_SUPERUSER_USERNAME = env('DJANGO_SUPERUSER_USERNAME') - DJANGO_SUPERUSER_PASSWORD = env( - 'DJANGO_SUPERUSER_PASSWORD') - DJANGO_SUPERUSER_EMAIL = env('DJANGO_SUPERUSER_EMAIL') - AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID') - AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY') - AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME') +if env("RENDER"): + ALLOWED_HOSTS.append(env("RENDER_EXTERNAL_HOSTNAME")) + DJANGO_SUPERUSER_USERNAME = env("DJANGO_SUPERUSER_USERNAME") + DJANGO_SUPERUSER_PASSWORD = env("DJANGO_SUPERUSER_PASSWORD") + DJANGO_SUPERUSER_EMAIL = env("DJANGO_SUPERUSER_EMAIL") + AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID") + AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY") + AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME") AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com' AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', @@ -189,9 +186,6 @@ "http://localhost:3000", "http://localhost:3001", "https://momentors.dev", - - - ] CORS_ALLOW_HEADERS = list(default_headers) + [ @@ -229,7 +223,6 @@ integrations=[ DjangoIntegration(), ], - # Set traces_sample_rate to 1.0 to capture 100% # of transactions for performance monitoring. # We recommend adjusting this value in production. diff --git a/config/urls.py b/config/urls.py index e1bb81c..fc0032d 100644 --- a/config/urls.py +++ b/config/urls.py @@ -14,8 +14,7 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path, include - +from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), diff --git a/manage.py b/manage.py index 8e7ac79..2125a97 100755 --- a/manage.py +++ b/manage.py @@ -11,10 +11,11 @@ def main(): from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" + 'Could not import Django. Are you sure it is installed and ' + 'available on your PYTHONPATH environment variable? Did you ' + 'forget to activate a virtual environment?' ) from exc + execute_from_command_line(sys.argv) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6b7007b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[tool.black] +line-length = 88 +skip-string-normalization = 1 +[tool.isort] +profile = "black" +multi_line_output = 3 +include_trailing_comma = true +line_length = 88 +skip = ["./team_production_system/migrations/", ".gitignore", ".dockerignore"] \ No newline at end of file diff --git a/scripts/commit-msg-lint.sh b/scripts/commit-msg-lint.sh index 4160001..da218b8 100755 --- a/scripts/commit-msg-lint.sh +++ b/scripts/commit-msg-lint.sh @@ -3,11 +3,12 @@ commit_msg_file=$1 commit_msg=$(cat $commit_msg_file) -regex="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)\([a-z]+\): .+$" +regex_without_scope="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert): .+$" +regex_with_scope="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)\([a-z]+\): .+$" -if [[ ! $commit_msg =~ $regex ]]; then +if [[ ! $commit_msg =~ $regex_with_scope ]] && [[ ! $commit_msg =~ $regex_without_scope ]]; then echo "Error: Commit message does not match the required format!" - echo "Expected Format: " + echo "Expected Format: " echo "Example: chore(test): setup test" exit 1 -fi \ No newline at end of file +fi diff --git a/team_production_system/admin.py b/team_production_system/admin.py index 3ffcefb..dd37b1b 100644 --- a/team_production_system/admin.py +++ b/team_production_system/admin.py @@ -1,21 +1,21 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import ( - Mentor, - Mentee, + Availability, CustomUser, + Mentee, + Mentor, + NotificationSettings, Session, - Availability, - NotificationSettings ) class AvailabilityAdmin(admin.ModelAdmin): - readonly_fields = ("created_at", "modified_at") + readonly_fields = ('created_at', 'modified_at') class SessionAdmin(admin.ModelAdmin): - readonly_fields = ("created_at", "modified_at") + readonly_fields = ('created_at', 'modified_at') # admin.site.register(UserAdmin) diff --git a/team_production_system/helpers.py b/team_production_system/helpers.py index 080068b..b43226a 100644 --- a/team_production_system/helpers.py +++ b/team_production_system/helpers.py @@ -2,12 +2,14 @@ # Purpose: Helper functions for the team_production_system app. from datetime import timedelta + from django.utils import timezone -from team_production_system.models import Availability from django.utils.dateparse import parse_datetime +from team_production_system.models import Availability + -# Create a list of Availability objects in 30 mins chunks for a time range +# Create a list of Availability objects in 30 minutes chunks for a time range def create_30_min_availabilities(start_time_str, end_time_str, mentor): chunk_size = timedelta(minutes=30) start_time = parse_datetime(start_time_str) @@ -18,14 +20,16 @@ def create_30_min_availabilities(start_time_str, end_time_str, mentor): end_time_new = start_time + chunk_size if end_time_new > end_time: break + availability = { 'start_time': start_time, 'end_time': end_time_new, 'mentor': mentor.user.pk, - 'status': 'Open' + 'status': 'Open', } availabilities.append(availability) start_time += chunk_size + return availabilities @@ -37,9 +41,7 @@ def is_overlapping_availabilities(mentor, data): start_time = data['start_time'] end_time = data['end_time'] overlapping_availabilities = Availability.objects.filter( - mentor=mentor, - start_time__lt=end_time, - end_time__gt=start_time + mentor=mentor, start_time__lt=end_time, end_time__gt=start_time ) return overlapping_availabilities.exists() diff --git a/team_production_system/management/commands/add_superuser.py b/team_production_system/management/commands/add_superuser.py index 2bf1753..4ce6174 100644 --- a/team_production_system/management/commands/add_superuser.py +++ b/team_production_system/management/commands/add_superuser.py @@ -1,9 +1,9 @@ - import os + from django.core.management.base import BaseCommand -from team_production_system.models import CustomUser -from config import settings +from config import settings +from team_production_system.models import CustomUser # To run this management command: @@ -13,16 +13,20 @@ class Command(BaseCommand): def handle(self, *args, **options): if os.environ.get('RENDER'): - user, created = CustomUser.objects.get_or_create( + user, created = CustomUser.objects.get_or_create( username=settings.DJANGO_SUPERUSER_USERNAME ) - if created: - user.email = settings.DJANGO_SUPERUSER_EMAIL - user.set_password(settings.DJANGO_SUPERUSER_PASSWORD) - user.is_superuser = True - user.is_staff = True - user.save() - msg = self.style.SUCCESS(f"Superuser {settings.DJANGO_SUPERUSER_USERNAME} added to database.") - else: - msg = self.style.WARNING(f"Superuser {settings.DJANGO_SUPERUSER_USERNAME} already exists.") - self.stdout.write(msg) \ No newline at end of file + if created: + user.email = settings.DJANGO_SUPERUSER_EMAIL + user.set_password(settings.DJANGO_SUPERUSER_PASSWORD) + user.is_superuser = True + user.is_staff = True + user.save() + msg = self.style.SUCCESS( + f"Superuser {settings.DJANGO_SUPERUSER_USERNAME} added to database." + ) + else: + msg = self.style.WARNING( + f"Superuser {settings.DJANGO_SUPERUSER_USERNAME} already exists." + ) + self.stdout.write(msg) diff --git a/team_production_system/migrations/0001_initial.py b/team_production_system/migrations/0001_initial.py index e8813f7..f50b1ef 100644 --- a/team_production_system/migrations/0001_initial.py +++ b/team_production_system/migrations/0001_initial.py @@ -1,17 +1,16 @@ # Generated by Django 4.1.7 on 2023-04-10 14:16 -from django.conf import settings import django.contrib.auth.models import django.contrib.auth.validators -from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import multiselectfield.db.fields import phonenumber_field.modelfields +from django.conf import settings +from django.db import migrations, models class Migration(migrations.Migration): - initial = True dependencies = [ @@ -22,23 +21,97 @@ class Migration(migrations.Migration): migrations.CreateModel( name='CustomUser', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ( + 'last_login', + models.DateTimeField( + blank=True, null=True, verbose_name='last login' + ), + ), + ( + 'is_superuser', + models.BooleanField( + default=False, + help_text='Designates that this user has all permissions without explicitly assigning them.', + verbose_name='superuser status', + ), + ), + ( + 'username', + models.CharField( + error_messages={ + 'unique': 'A user with that username already exists.' + }, + help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', + max_length=150, + unique=True, + validators=[ + django.contrib.auth.validators.UnicodeUsernameValidator() + ], + verbose_name='username', + ), + ), + ( + 'is_staff', + models.BooleanField( + default=False, + help_text='Designates whether the user can log into this admin site.', + verbose_name='staff status', + ), + ), + ( + 'date_joined', + models.DateTimeField( + default=django.utils.timezone.now, verbose_name='date joined' + ), + ), ('is_mentor', models.BooleanField(default=False)), ('is_mentee', models.BooleanField(default=False)), ('is_active', models.BooleanField(default=True)), ('first_name', models.CharField(max_length=75)), ('last_name', models.CharField(max_length=75)), ('email', models.EmailField(max_length=75, unique=True)), - ('phone_number', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, region=None, unique=True)), - ('profile_photo', models.ImageField(blank=True, null=True, upload_to='profile_photo')), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ( + 'phone_number', + phonenumber_field.modelfields.PhoneNumberField( + blank=True, max_length=128, null=True, region=None, unique=True + ), + ), + ( + 'profile_photo', + models.ImageField(blank=True, null=True, upload_to='profile_photo'), + ), + ( + 'groups', + models.ManyToManyField( + blank=True, + help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', + related_name='user_set', + related_query_name='user', + to='auth.group', + verbose_name='groups', + ), + ), + ( + 'user_permissions', + models.ManyToManyField( + blank=True, + help_text='Specific permissions for this user.', + related_name='user_set', + related_query_name='user', + to='auth.permission', + verbose_name='user permissions', + ), + ), ], options={ 'verbose_name': 'user', @@ -52,7 +125,15 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Availability', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), ('start_time', models.DateTimeField()), ('end_time', models.DateTimeField()), ], @@ -60,47 +141,142 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Mentee', fields=[ - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ( + 'user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + primary_key=True, + serialize=False, + to=settings.AUTH_USER_MODEL, + ), + ), ('team_number', models.IntegerField()), ], ), migrations.CreateModel( name='Mentor', fields=[ - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ( + 'user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + primary_key=True, + serialize=False, + to=settings.AUTH_USER_MODEL, + ), + ), ('about_me', models.TextField(max_length=1000)), - ('skills', multiselectfield.db.fields.MultiSelectField(choices=[('HTML', 'HTML'), ('CSS', 'CSS'), ('JavaScript', 'JavaScript'), ('React', 'React'), ('Python', 'Python'), ('Django', 'Django'), ('Django REST', 'Django REST')], max_length=52)), + ( + 'skills', + multiselectfield.db.fields.MultiSelectField( + choices=[ + ('HTML', 'HTML'), + ('CSS', 'CSS'), + ('JavaScript', 'JavaScript'), + ('React', 'React'), + ('Python', 'Python'), + ('Django', 'Django'), + ('Django REST', 'Django REST'), + ], + max_length=52, + ), + ), ], ), migrations.CreateModel( name='Notification', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), ('message', models.CharField(max_length=500)), ('created_at', models.DateTimeField(auto_now_add=True)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to=settings.AUTH_USER_MODEL)), + ( + 'user', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='notifications', + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.CreateModel( name='Session', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), ('start_time', models.DateTimeField()), ('project', models.CharField(max_length=500)), ('help_text', models.TextField(max_length=500)), ('git_link', models.URLField()), ('created_at', models.DateTimeField(auto_now_add=True)), ('confirmed', models.BooleanField(default=False)), - ('status', models.CharField(choices=[('Pending', 'Pending'), ('Confirmed', 'Confirmed'), ('Canceled', 'Canceled'), ('Completed', 'Completed')], default='Pending', max_length=10)), - ('session_length', models.IntegerField(choices=[(30, '30 minutes'), (60, '60 minutes')], default=30)), - ('mentor_availability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='mentor_session', to='team_production_system.availability')), - ('mentee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='mentee_session', to='team_production_system.mentee')), - ('mentor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='mentor_session', to='team_production_system.mentor')), + ( + 'status', + models.CharField( + choices=[ + ('Pending', 'Pending'), + ('Confirmed', 'Confirmed'), + ('Canceled', 'Canceled'), + ('Completed', 'Completed'), + ], + default='Pending', + max_length=10, + ), + ), + ( + 'session_length', + models.IntegerField( + choices=[(30, '30 minutes'), (60, '60 minutes')], default=30 + ), + ), + ( + 'mentor_availability', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='mentor_session', + to='team_production_system.availability', + ), + ), + ( + 'mentee', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='mentee_session', + to='team_production_system.mentee', + ), + ), + ( + 'mentor', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='mentor_session', + to='team_production_system.mentor', + ), + ), ], ), migrations.AddField( model_name='availability', name='mentor', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='mentor_availability', to='team_production_system.mentor'), + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='mentor_availability', + to='team_production_system.mentor', + ), ), ] diff --git a/team_production_system/migrations/0002_alter_mentee_team_number_alter_mentor_about_me_and_more.py b/team_production_system/migrations/0002_alter_mentee_team_number_alter_mentor_about_me_and_more.py index fd3f253..1df8181 100644 --- a/team_production_system/migrations/0002_alter_mentee_team_number_alter_mentor_about_me_and_more.py +++ b/team_production_system/migrations/0002_alter_mentee_team_number_alter_mentor_about_me_and_more.py @@ -1,11 +1,10 @@ # Generated by Django 4.1.7 on 2023-05-01 14:42 -from django.db import migrations, models import multiselectfield.db.fields +from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0001_initial'), ] @@ -24,6 +23,18 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='mentor', name='skills', - field=multiselectfield.db.fields.MultiSelectField(choices=[('HTML', 'HTML'), ('CSS', 'CSS'), ('JavaScript', 'JavaScript'), ('React', 'React'), ('Python', 'Python'), ('Django', 'Django'), ('Django REST', 'Django REST')], default='HTML', max_length=52), + field=multiselectfield.db.fields.MultiSelectField( + choices=[ + ('HTML', 'HTML'), + ('CSS', 'CSS'), + ('JavaScript', 'JavaScript'), + ('React', 'React'), + ('Python', 'Python'), + ('Django', 'Django'), + ('Django REST', 'Django REST'), + ], + default='HTML', + max_length=52, + ), ), ] diff --git a/team_production_system/migrations/0003_alter_customuser_phone_number.py b/team_production_system/migrations/0003_alter_customuser_phone_number.py index e55ccfb..321a524 100644 --- a/team_production_system/migrations/0003_alter_customuser_phone_number.py +++ b/team_production_system/migrations/0003_alter_customuser_phone_number.py @@ -1,19 +1,28 @@ # Generated by Django 4.1.7 on 2023-05-04 19:47 -from django.db import migrations import phonenumber_field.modelfields +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('team_production_system', '0002_alter_mentee_team_number_alter_mentor_about_me_and_more'), + ( + 'team_production_system', + '0002_alter_mentee_team_number_alter_mentor_about_me_and_more', + ), ] operations = [ migrations.AlterField( model_name='customuser', name='phone_number', - field=phonenumber_field.modelfields.PhoneNumberField(blank=True, default='', max_length=128, null=True, region=None, unique=True), + field=phonenumber_field.modelfields.PhoneNumberField( + blank=True, + default='', + max_length=128, + null=True, + region=None, + unique=True, + ), ), ] diff --git a/team_production_system/migrations/0004_alter_customuser_phone_number.py b/team_production_system/migrations/0004_alter_customuser_phone_number.py index 0157977..ae6816f 100644 --- a/team_production_system/migrations/0004_alter_customuser_phone_number.py +++ b/team_production_system/migrations/0004_alter_customuser_phone_number.py @@ -1,11 +1,10 @@ # Generated by Django 4.1.7 on 2023-05-04 21:00 -from django.db import migrations import phonenumber_field.modelfields +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0003_alter_customuser_phone_number'), ] @@ -14,6 +13,13 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='customuser', name='phone_number', - field=phonenumber_field.modelfields.PhoneNumberField(blank=True, default=' ', max_length=128, null=True, region=None, unique=True), + field=phonenumber_field.modelfields.PhoneNumberField( + blank=True, + default=' ', + max_length=128, + null=True, + region=None, + unique=True, + ), ), ] diff --git a/team_production_system/migrations/0005_alter_customuser_phone_number.py b/team_production_system/migrations/0005_alter_customuser_phone_number.py index f3db5cc..a0e9ecf 100644 --- a/team_production_system/migrations/0005_alter_customuser_phone_number.py +++ b/team_production_system/migrations/0005_alter_customuser_phone_number.py @@ -1,11 +1,10 @@ # Generated by Django 4.1.7 on 2023-05-05 01:05 -from django.db import migrations import phonenumber_field.modelfields +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0004_alter_customuser_phone_number'), ] @@ -14,6 +13,13 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='customuser', name='phone_number', - field=phonenumber_field.modelfields.PhoneNumberField(blank=True, default=None, max_length=128, null=True, region=None, unique=True), + field=phonenumber_field.modelfields.PhoneNumberField( + blank=True, + default=None, + max_length=128, + null=True, + region=None, + unique=True, + ), ), ] diff --git a/team_production_system/migrations/0006_alter_mentor_skills.py b/team_production_system/migrations/0006_alter_mentor_skills.py index 0bdb608..65a6232 100644 --- a/team_production_system/migrations/0006_alter_mentor_skills.py +++ b/team_production_system/migrations/0006_alter_mentor_skills.py @@ -1,11 +1,10 @@ # Generated by Django 4.2.1 on 2023-05-24 21:46 -from django.db import migrations import multiselectfield.db.fields +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0005_alter_customuser_phone_number'), ] @@ -14,6 +13,28 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='mentor', name='skills', - field=multiselectfield.db.fields.MultiSelectField(choices=[('AWS S3', 'AWS S3'), ('Bootstrap', 'Bootstrap'), ('CSS', 'CSS'), ('Django', 'Django'), ('Git', 'Git'), ('GitHub', 'GitHub'), ('HTML', 'HTML'), ('Insomnia', 'Insomnia'), ('JavaScript', 'JavaScript'), ('MUI', 'MUI'), ('Other', 'Other'), ('PostgreSQL', 'PostgreSQL'), ('Postico', 'Postico'), ('Python', 'Python'), ('React', 'React'), ('SQL', 'SQL'), ('Time Management', 'Time Management')], default='HTML', max_length=52), + field=multiselectfield.db.fields.MultiSelectField( + choices=[ + ('AWS S3', 'AWS S3'), + ('Bootstrap', 'Bootstrap'), + ('CSS', 'CSS'), + ('Django', 'Django'), + ('Git', 'Git'), + ('GitHub', 'GitHub'), + ('HTML', 'HTML'), + ('Insomnia', 'Insomnia'), + ('JavaScript', 'JavaScript'), + ('MUI', 'MUI'), + ('Other', 'Other'), + ('PostgreSQL', 'PostgreSQL'), + ('Postico', 'Postico'), + ('Python', 'Python'), + ('React', 'React'), + ('SQL', 'SQL'), + ('Time Management', 'Time Management'), + ], + default='HTML', + max_length=52, + ), ), ] diff --git a/team_production_system/migrations/0007_notificationsettings_delete_notification.py b/team_production_system/migrations/0007_notificationsettings_delete_notification.py index 6e2237c..a93f4a8 100644 --- a/team_production_system/migrations/0007_notificationsettings_delete_notification.py +++ b/team_production_system/migrations/0007_notificationsettings_delete_notification.py @@ -1,12 +1,11 @@ # Generated by Django 4.2.1 on 2023-06-01 17:13 +import django.db.models.deletion from django.conf import settings from django.db import migrations, models -import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0006_alter_mentor_skills'), ] @@ -15,13 +14,28 @@ class Migration(migrations.Migration): migrations.CreateModel( name='NotificationSettings', fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + 'id', + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name='ID', + ), + ), ('session_requested', models.BooleanField(default=False)), ('session_confirmed', models.BooleanField(default=False)), ('session_canceled', models.BooleanField(default=False)), ('fifteen_minute_alert', models.BooleanField(default=False)), ('sixty_minute_alert', models.BooleanField(default=False)), - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='notification_settings', to=settings.AUTH_USER_MODEL)), + ( + 'user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name='notification_settings', + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.DeleteModel( diff --git a/team_production_system/migrations/0008_alter_mentor_skills.py b/team_production_system/migrations/0008_alter_mentor_skills.py index 4d16683..bd4ad14 100644 --- a/team_production_system/migrations/0008_alter_mentor_skills.py +++ b/team_production_system/migrations/0008_alter_mentor_skills.py @@ -1,11 +1,10 @@ # Generated by Django 4.2.1 on 2023-06-05 19:16 -from django.db import migrations import multiselectfield.db.fields +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0007_notificationsettings_delete_notification'), ] @@ -14,6 +13,28 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='mentor', name='skills', - field=multiselectfield.db.fields.MultiSelectField(choices=[('AWS S3', 'AWS S3'), ('Bootstrap', 'Bootstrap'), ('CSS', 'CSS'), ('Django', 'Django'), ('Git', 'Git'), ('GitHub', 'GitHub'), ('HTML', 'HTML'), ('Insomnia', 'Insomnia'), ('JavaScript', 'JavaScript'), ('MUI', 'MUI'), ('Other', 'Other'), ('PostgreSQL', 'PostgreSQL'), ('Postico', 'Postico'), ('Python', 'Python'), ('React', 'React'), ('SQL', 'SQL'), ('Time Management', 'Time Management')], default='HTML', max_length=157), + field=multiselectfield.db.fields.MultiSelectField( + choices=[ + ('AWS S3', 'AWS S3'), + ('Bootstrap', 'Bootstrap'), + ('CSS', 'CSS'), + ('Django', 'Django'), + ('Git', 'Git'), + ('GitHub', 'GitHub'), + ('HTML', 'HTML'), + ('Insomnia', 'Insomnia'), + ('JavaScript', 'JavaScript'), + ('MUI', 'MUI'), + ('Other', 'Other'), + ('PostgreSQL', 'PostgreSQL'), + ('Postico', 'Postico'), + ('Python', 'Python'), + ('React', 'React'), + ('SQL', 'SQL'), + ('Time Management', 'Time Management'), + ], + default='HTML', + max_length=157, + ), ), ] diff --git a/team_production_system/migrations/0009_availability_availability_constraint.py b/team_production_system/migrations/0009_availability_availability_constraint.py index 3d1de60..2810905 100644 --- a/team_production_system/migrations/0009_availability_availability_constraint.py +++ b/team_production_system/migrations/0009_availability_availability_constraint.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0008_alter_mentor_skills'), ] @@ -12,6 +11,8 @@ class Migration(migrations.Migration): operations = [ migrations.AddConstraint( model_name='availability', - constraint=models.UniqueConstraint(fields=('mentor', 'start_time'), name='availability_constraint'), + constraint=models.UniqueConstraint( + fields=('mentor', 'start_time'), name='availability_constraint' + ), ), ] diff --git a/team_production_system/migrations/0010_alter_mentor_skills.py b/team_production_system/migrations/0010_alter_mentor_skills.py index bc144b1..5dcfdc6 100644 --- a/team_production_system/migrations/0010_alter_mentor_skills.py +++ b/team_production_system/migrations/0010_alter_mentor_skills.py @@ -1,11 +1,10 @@ # Generated by Django 4.2.4 on 2023-09-01 19:43 -from django.db import migrations import multiselectfield.db.fields +from django.db import migrations class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0009_availability_availability_constraint'), ] @@ -14,6 +13,34 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='mentor', name='skills', - field=multiselectfield.db.fields.MultiSelectField(choices=[('AI', 'AI'), ('AWS S3', 'AWS S3'), ('Bootstrap', 'Bootstrap'), ('Career Help', 'Career Help'), ('CSS', 'CSS'), ('Django', 'Django'), ('FastAPI', 'FastAPI'), ('Git', 'Git'), ('GitHub', 'GitHub'), ('HTML', 'HTML'), ('Insomnia', 'Insomnia'), ('Interview Help', 'Interview Help'), ('JavaScript', 'JavaScript'), ('MUI', 'MUI'), ('Other', 'Other'), ('PostgreSQL', 'PostgreSQL'), ('Postico', 'Postico'), ('Python', 'Python'), ('React', 'React'), ('Resume Help', 'Resume Help'), ('SQL', 'SQL'), ('Time Management', 'Time Management'), ('Vue.js', 'Vue.js')], default='HTML', max_length=157), + field=multiselectfield.db.fields.MultiSelectField( + choices=[ + ('AI', 'AI'), + ('AWS S3', 'AWS S3'), + ('Bootstrap', 'Bootstrap'), + ('Career Help', 'Career Help'), + ('CSS', 'CSS'), + ('Django', 'Django'), + ('FastAPI', 'FastAPI'), + ('Git', 'Git'), + ('GitHub', 'GitHub'), + ('HTML', 'HTML'), + ('Insomnia', 'Insomnia'), + ('Interview Help', 'Interview Help'), + ('JavaScript', 'JavaScript'), + ('MUI', 'MUI'), + ('Other', 'Other'), + ('PostgreSQL', 'PostgreSQL'), + ('Postico', 'Postico'), + ('Python', 'Python'), + ('React', 'React'), + ('Resume Help', 'Resume Help'), + ('SQL', 'SQL'), + ('Time Management', 'Time Management'), + ('Vue.js', 'Vue.js'), + ], + default='HTML', + max_length=157, + ), ), ] diff --git a/team_production_system/migrations/0011_mentor_team_number.py b/team_production_system/migrations/0011_mentor_team_number.py index 3834b2b..f146821 100644 --- a/team_production_system/migrations/0011_mentor_team_number.py +++ b/team_production_system/migrations/0011_mentor_team_number.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('team_production_system', '0010_alter_mentor_skills'), ] diff --git a/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py b/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py index eafa3f1..3c383f8 100644 --- a/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py +++ b/team_production_system/migrations/0012_remove_availability_availability_constraint_and_more.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("team_production_system", "0011_mentor_team_number"), ] diff --git a/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py b/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py index 1521c07..99b7b22 100644 --- a/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py +++ b/team_production_system/migrations/0013_availability_created_at_availability_modified_at_and_more.py @@ -1,11 +1,11 @@ # Generated by Django 4.2.6 on 2023-10-11 04:24 import datetime + from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ( "team_production_system", diff --git a/team_production_system/models/__init__.py b/team_production_system/models/__init__.py index ed72613..3be962c 100644 --- a/team_production_system/models/__init__.py +++ b/team_production_system/models/__init__.py @@ -2,8 +2,8 @@ from .availability import Availability +from .custom_user import CustomUser from .mentee import Mentee from .mentor import Mentor from .notification_settings import NotificationSettings from .session import Session -from .custom_user import CustomUser diff --git a/team_production_system/models/availability.py b/team_production_system/models/availability.py index f17a72f..f0cc69b 100644 --- a/team_production_system/models/availability.py +++ b/team_production_system/models/availability.py @@ -1,11 +1,11 @@ -from .mentor import Mentor -from django.db.models.constraints import UniqueConstraint from django.db import models +from django.db.models.constraints import UniqueConstraint +from .mentor import Mentor -# Allow mentors to set their avaliabiltiy -class Availability(models.Model): +# Allow mentors to set their availability +class Availability(models.Model): STATUS_CHOICES = [ ('Open', 'Open'), ('Requested', 'Requested'), @@ -14,14 +14,10 @@ class Availability(models.Model): mentor = models.ForeignKey( Mentor, on_delete=models.CASCADE, related_name='mentor_availability' - ) + ) start_time = models.DateTimeField() end_time = models.DateTimeField() - status = models.CharField( - max_length=10, - choices=STATUS_CHOICES, - default='Open' - ) + status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='Open') created_at = models.DateTimeField(auto_now_add=True) modified_at = models.DateTimeField(auto_now=True) @@ -30,12 +26,9 @@ class Meta: UniqueConstraint( fields=['mentor', 'start_time'], name='availability_constraint', - violation_error_message='Availability already exists.' - ) + violation_error_message='Availability already exists.', + ) ] def __str__(self): - return ( - f"{self.mentor} is available from " - f"{self.start_time} to {self.end_time}." - ) + return f'{self.mentor} is available from {self.start_time} to {self.end_time}.' diff --git a/team_production_system/models/custom_user.py b/team_production_system/models/custom_user.py index 07071eb..cf2237c 100644 --- a/team_production_system/models/custom_user.py +++ b/team_production_system/models/custom_user.py @@ -1,8 +1,10 @@ -from django.db import models +import random + from django.contrib.auth.models import AbstractUser -from phonenumber_field.modelfields import PhoneNumberField from django.core.files.storage import default_storage -import random +from django.db import models +from phonenumber_field.modelfields import PhoneNumberField + from .notification_settings import NotificationSettings @@ -14,10 +16,8 @@ class CustomUser(AbstractUser): first_name = models.CharField(max_length=75) last_name = models.CharField(max_length=75) email = models.EmailField(max_length=75, unique=True) - phone_number = PhoneNumberField( - null=True, blank=True, unique=True, default=None) - profile_photo = models.ImageField( - upload_to='profile_photo', blank=True, null=True) + phone_number = PhoneNumberField(null=True, blank=True, unique=True, default=None) + profile_photo = models.ImageField(upload_to='profile_photo', blank=True, null=True) def __str__(self): return self.username diff --git a/team_production_system/models/mentee.py b/team_production_system/models/mentee.py index 103cc1c..91e130d 100644 --- a/team_production_system/models/mentee.py +++ b/team_production_system/models/mentee.py @@ -1,11 +1,11 @@ from django.db import models + from .custom_user import CustomUser # Model for mentees to input their team class Mentee(models.Model): - user = models.OneToOneField( - CustomUser, on_delete=models.CASCADE, primary_key=True) + user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True) team_number = models.IntegerField(default=0) def __str__(self): diff --git a/team_production_system/models/mentor.py b/team_production_system/models/mentor.py index 89a4cf9..951dcd3 100644 --- a/team_production_system/models/mentor.py +++ b/team_production_system/models/mentor.py @@ -1,12 +1,12 @@ from django.db import models -from .custom_user import CustomUser from multiselectfield import MultiSelectField +from .custom_user import CustomUser + # The mentor model that allows the mentor to select skills # they know and information about them class Mentor(models.Model): - SKILLS_CHOICES = [ ('AI', 'AI'), ('AWS S3', 'AWS S3'), @@ -33,12 +33,12 @@ class Mentor(models.Model): ('Vue.js', 'Vue.js'), ] - user = models.OneToOneField( - CustomUser, on_delete=models.CASCADE, primary_key=True) + user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True) about_me = models.TextField(max_length=1000, default='') team_number = models.IntegerField(default=0) - skills = MultiSelectField(choices=SKILLS_CHOICES, - max_choices=19, max_length=157, default='HTML') + skills = MultiSelectField( + choices=SKILLS_CHOICES, max_choices=19, max_length=157, default='HTML' + ) def __str__(self): return self.user.username diff --git a/team_production_system/models/notification_settings.py b/team_production_system/models/notification_settings.py index 9a68379..26ffe07 100644 --- a/team_production_system/models/notification_settings.py +++ b/team_production_system/models/notification_settings.py @@ -5,9 +5,10 @@ # they have a session requested, confirmed, or canceled. class NotificationSettings(models.Model): user = models.OneToOneField( - "team_production_system.CustomUser", + 'team_production_system.CustomUser', on_delete=models.CASCADE, - related_name='notification_settings') + related_name='notification_settings', + ) session_requested = models.BooleanField(default=False) session_confirmed = models.BooleanField(default=False) session_canceled = models.BooleanField(default=False) diff --git a/team_production_system/models/session.py b/team_production_system/models/session.py index 1253cbd..71d5a00 100644 --- a/team_production_system/models/session.py +++ b/team_production_system/models/session.py @@ -1,23 +1,28 @@ -from django.db import models +import secrets +from datetime import timedelta + +import pytz from django.conf import settings from django.core.mail import send_mail +from django.db import models + +from .availability import Availability from .mentee import Mentee from .mentor import Mentor -from .availability import Availability -from datetime import timedelta -import secrets -import pytz # The session model allows the mentee to setup a session and # allows both mentee and mentor see their sessions they have scheduled class Session(models.Model): - mentor = models.ForeignKey(Mentor, on_delete=models.CASCADE, - related_name='mentor_session') + mentor = models.ForeignKey( + Mentor, on_delete=models.CASCADE, related_name='mentor_session' + ) mentor_availability = models.ForeignKey( - Availability, on_delete=models.CASCADE, related_name='mentor_session') + Availability, on_delete=models.CASCADE, related_name='mentor_session' + ) mentee = models.ForeignKey( - Mentee, on_delete=models.CASCADE, related_name='mentee_session') + Mentee, on_delete=models.CASCADE, related_name='mentee_session' + ) start_time = models.DateTimeField() project = models.CharField(max_length=500) help_text = models.TextField(max_length=500) @@ -27,17 +32,12 @@ class Session(models.Model): ('Pending', 'Pending'), ('Confirmed', 'Confirmed'), ('Canceled', 'Canceled'), - ('Completed', 'Completed') + ('Completed', 'Completed'), ] # The mentee will be able to schedule a 30 minute or 60 minute session. - status = models.CharField( - max_length=10, choices=status_choices, default='Pending') - session_length_choices = [ - (30, '30 minutes'), - (60, '60 minutes') - ] - session_length = models.IntegerField( - choices=session_length_choices, default=30) + status = models.CharField(max_length=10, choices=status_choices, default='Pending') + session_length_choices = [(30, '30 minutes'), (60, '60 minutes')] + session_length = models.IntegerField(choices=session_length_choices, default=30) created_at = models.DateTimeField(auto_now_add=True) modified_at = models.DateTimeField(auto_now=True) @@ -46,8 +46,8 @@ def end_time(self): def __str__(self): return ( - f"{self.mentor_availability.mentor.user.username} " - f"session with {self.mentee.user.username} is ({self.status})" + f'{self.mentor_availability.mentor.user.username} ' + f'session with {self.mentee.user.username} is ({self.status})' ) # Notify a mentor that a mentee has requested a session @@ -114,7 +114,7 @@ def mentee_confirm_notify(self, meeting_link): f'Here is the link to your session: {meeting_link}' ), from_email=settings.EMAIL_HOST_USER, - recipient_list=[self.mentee.user.email] + recipient_list=[self.mentee.user.email], ) # Notify the mentor when the requested session has been confirmed @@ -140,7 +140,7 @@ def mentor_confirm_notify(self, meeting_link): f'Here is the link to your session: {meeting_link}' ), from_email=settings.EMAIL_HOST_USER, - recipient_list=[self.mentor.user.email] + recipient_list=[self.mentor.user.email], ) # Notify a mentor that a mentee has canceled a scheduled session diff --git a/team_production_system/serializers/__init__.py b/team_production_system/serializers/__init__.py index 70ec0d3..491ba90 100644 --- a/team_production_system/serializers/__init__.py +++ b/team_production_system/serializers/__init__.py @@ -1,13 +1,10 @@ # flake8: noqa -from .availability import ( - AvailabilitySerializer, - AvailabilitySerializerV2 -) +from .availability import AvailabilitySerializer, AvailabilitySerializerV2 from .custom_user import CustomUserSerializer -from .mentor_profile import MentorProfileSerializer -from .mentor_list import MentorListSerializer -from .mentee_profile import MenteeProfileSerializer from .mentee_list import MenteeListSerializer -from .session import SessionSerializer +from .mentee_profile import MenteeProfileSerializer +from .mentor_list import MentorListSerializer +from .mentor_profile import MentorProfileSerializer from .notification_settings import NotificationSettingsSerializer +from .session import SessionSerializer diff --git a/team_production_system/serializers/availability.py b/team_production_system/serializers/availability.py index d78af79..fbffc7c 100644 --- a/team_production_system/serializers/availability.py +++ b/team_production_system/serializers/availability.py @@ -1,68 +1,68 @@ -from rest_framework import serializers from django.utils import timezone -from team_production_system.models import ( - Mentor, - Availability, -) +from rest_framework import serializers + from team_production_system.helpers import ( is_overlapping_availabilities, + is_valid_end_time, is_valid_start_time, - is_valid_end_time ) +from team_production_system.models import Availability, Mentor -# V1 API # +# V_1 API # # The mentor availability serializer class AvailabilitySerializer(serializers.ModelSerializer): - class Meta: model = Availability - fields = ['pk', 'mentor', 'start_time', 'end_time'] - read_only_fields = ('mentor', 'pk') + fields = ( + 'pk', + 'mentor', + 'start_time', + 'end_time', + ) + read_only_fields = ( + 'mentor', + 'pk', + ) def create(self, validated_data): mentor = Mentor.objects.select_related('user').get( - user=self.context['request'].user) + user=self.context['request'].user + ) start_time = validated_data['start_time'] end_time = validated_data['end_time'] # Check if start time is between a start time and end time of # an existing availability - overlapping_condition1 = Availability.objects.filter( + overlapping_condition_1 = Availability.objects.filter( mentor=mentor, start_time__lt=start_time, end_time__gt=start_time, ).exists() # Check if end time is between a start time and end time of # an existing availability - overlapping_condition2 = Availability.objects.filter( - mentor=mentor, - start_time__lt=end_time, - end_time__gt=end_time + overlapping_condition_2 = Availability.objects.filter( + mentor=mentor, start_time__lt=end_time, end_time__gt=end_time ).exists() # Check if start time is between the new start_time and new end_time - overlapping_condition3 = Availability.objects.filter( - mentor=mentor, - start_time__gte=start_time, - start_time__lt=end_time + overlapping_condition_3 = Availability.objects.filter( + mentor=mentor, start_time__gte=start_time, start_time__lt=end_time ).exists() # Check if end time is between the new start_time and new end_time - overlapping_condition4 = Availability.objects.filter( - mentor=mentor, - end_time__gt=start_time, - end_time__lte=end_time + overlapping_condition_4 = Availability.objects.filter( + mentor=mentor, end_time__gt=start_time, end_time__lte=end_time ).exists() availability_overlap = ( - overlapping_condition1 - or overlapping_condition2 - or overlapping_condition3 - or overlapping_condition4) + overlapping_condition_1 + or overlapping_condition_2 + or overlapping_condition_3 + or overlapping_condition_4 + ) if not availability_overlap: - availability = Availability.objects.create( - mentor=mentor, **validated_data) + availability = Availability.objects.create(mentor=mentor, **validated_data) return availability - raise serializers.ValidationError( - "Input overlaps with existing availability.") + + raise serializers.ValidationError('Input overlaps with existing availability.') def validate(self, data): """ @@ -71,8 +71,8 @@ def validate(self, data): start_time = data['start_time'] end_time = data['end_time'] if start_time >= end_time: - raise serializers.ValidationError( - 'End time must be after start time.') + raise serializers.ValidationError('End time must be after start time.') + return data def validate_end_time(self, value): @@ -80,43 +80,35 @@ def validate_end_time(self, value): Check that the end_time is in the future. """ if value <= timezone.now(): - raise serializers.ValidationError( - 'End time must be in the future.' - ) + raise serializers.ValidationError('End time must be in the future.') + return value # V2 API # # The mentor availability serializer class AvailabilitySerializerV2(serializers.ModelSerializer): - class Meta: model = Availability - fields = [ - 'pk', - 'mentor', - 'start_time', - 'end_time', - 'status' - ] + fields = ['pk', 'mentor', 'start_time', 'end_time', 'status'] read_only_fields = ('pk',) def validate(self, data): mentor = Mentor.objects.select_related('user').get( - user=self.context['request'].user) + user=self.context['request'].user + ) start_time = data.get('start_time') end_time = data.get('end_time') if not is_valid_start_time(start_time): - raise serializers.ValidationError( - 'Start time must be in the future.') + raise serializers.ValidationError('Start time must be in the future.') if not is_valid_end_time(start_time, end_time): - raise serializers.ValidationError( - 'End time must be after start time.') + raise serializers.ValidationError('End time must be after start time.') if is_overlapping_availabilities(mentor, data): raise serializers.ValidationError( - 'Availability overlaps with existing availability.') + 'Availability overlaps with existing availability.' + ) return data diff --git a/team_production_system/serializers/custom_user.py b/team_production_system/serializers/custom_user.py index a19d055..3e3dd6c 100644 --- a/team_production_system/serializers/custom_user.py +++ b/team_production_system/serializers/custom_user.py @@ -1,4 +1,5 @@ from rest_framework import serializers + from team_production_system.models import CustomUser diff --git a/team_production_system/serializers/mentee_list.py b/team_production_system/serializers/mentee_list.py index f856df3..153fda0 100644 --- a/team_production_system/serializers/mentee_list.py +++ b/team_production_system/serializers/mentee_list.py @@ -1,7 +1,9 @@ from rest_framework import serializers + from team_production_system.models import CustomUser -from .mentee_profile import MenteeProfileSerializer + from .custom_user import CustomUserSerializer +from .mentee_profile import MenteeProfileSerializer class MenteeListSerializer(serializers.ModelSerializer): @@ -10,5 +12,12 @@ class MenteeListSerializer(serializers.ModelSerializer): class Meta: model = CustomUser - fields = ('user', 'pk', 'username', 'first_name', - 'last_name', 'is_mentee', 'mentee_profile') + fields = ( + 'user', + 'pk', + 'username', + 'first_name', + 'last_name', + 'is_mentee', + 'mentee_profile', + ) diff --git a/team_production_system/serializers/mentee_profile.py b/team_production_system/serializers/mentee_profile.py index 1022d6b..2464cbd 100644 --- a/team_production_system/serializers/mentee_profile.py +++ b/team_production_system/serializers/mentee_profile.py @@ -1,4 +1,5 @@ from rest_framework import serializers + from team_production_system.models import Mentee diff --git a/team_production_system/serializers/mentor_list.py b/team_production_system/serializers/mentor_list.py index f805dca..d107b3c 100644 --- a/team_production_system/serializers/mentor_list.py +++ b/team_production_system/serializers/mentor_list.py @@ -1,11 +1,9 @@ -from rest_framework import serializers from django.utils import timezone +from rest_framework import serializers + +from team_production_system.models import Availability, CustomUser, Mentor + from .availability import AvailabilitySerializer -from team_production_system.models import ( - CustomUser, - Mentor, - Availability, - ) # Serializer to show a list of all users flagged as a mentor @@ -18,9 +16,18 @@ class MentorListSerializer(serializers.ModelSerializer): class Meta: model = CustomUser - fields = ('pk', 'username', 'first_name', - 'last_name', 'profile_photo', 'is_mentor', 'about_me', - 'skills', 'availabilities', 'team_number') + fields = ( + 'pk', + 'username', + 'first_name', + 'last_name', + 'profile_photo', + 'is_mentor', + 'about_me', + 'skills', + 'availabilities', + 'team_number', + ) def get_about_me(self, obj): try: @@ -39,9 +46,9 @@ def get_skills(self, obj): def get_availabilities(self, obj): try: availabilities = Availability.objects.filter( - mentor=obj.pk, end_time__gte=timezone.now()) - serializer = AvailabilitySerializer( - instance=availabilities, many=True) + mentor=obj.pk, end_time__gte=timezone.now() + ) + serializer = AvailabilitySerializer(instance=availabilities, many=True) return serializer.data except Mentor.DoesNotExist: return None diff --git a/team_production_system/serializers/mentor_profile.py b/team_production_system/serializers/mentor_profile.py index e4c53fe..dd5d91d 100644 --- a/team_production_system/serializers/mentor_profile.py +++ b/team_production_system/serializers/mentor_profile.py @@ -1,11 +1,14 @@ -from rest_framework import serializers, fields -from .availability import AvailabilitySerializer +from rest_framework import fields, serializers + from team_production_system.models import Mentor +from .availability import AvailabilitySerializer + class MentorProfileSerializer(serializers.ModelSerializer): availabilities = AvailabilitySerializer( - many=True, read_only=True, source='mentor_availability') + many=True, read_only=True, source='mentor_availability' + ) skills = fields.MultipleChoiceField(choices=Mentor.SKILLS_CHOICES) team_number = serializers.IntegerField(required=False) diff --git a/team_production_system/serializers/notification_settings.py b/team_production_system/serializers/notification_settings.py index 38f7512..ae79ab7 100644 --- a/team_production_system/serializers/notification_settings.py +++ b/team_production_system/serializers/notification_settings.py @@ -1,11 +1,17 @@ from rest_framework import serializers + from team_production_system.models import NotificationSettings class NotificationSettingsSerializer(serializers.ModelSerializer): - class Meta: model = NotificationSettings - fields = ('pk', 'user', 'session_requested', 'session_confirmed', - 'session_canceled', 'fifteen_minute_alert', - 'sixty_minute_alert',) + fields = ( + 'pk', + 'user', + 'session_requested', + 'session_confirmed', + 'session_canceled', + 'fifteen_minute_alert', + 'sixty_minute_alert', + ) diff --git a/team_production_system/serializers/session.py b/team_production_system/serializers/session.py index c43eab0..d35d56c 100644 --- a/team_production_system/serializers/session.py +++ b/team_production_system/serializers/session.py @@ -1,22 +1,47 @@ from rest_framework import serializers + from team_production_system.models import Session class SessionSerializer(serializers.ModelSerializer): - mentor_first_name = serializers.SlugField(source='mentor.user.first_name', - read_only=True) - mentor_last_name = serializers.SlugField(source='mentor.user.last_name', - read_only=True) - mentee_first_name = serializers.SlugField(source='mentee.user.first_name', - read_only=True) - mentee_last_name = serializers.SlugField(source='mentee.user.last_name', - read_only=True) + mentor_first_name = serializers.SlugField( + source='mentor.user.first_name', + read_only=True, + ) + mentor_last_name = serializers.SlugField( + source='mentor.user.last_name', + read_only=True, + ) + mentee_first_name = serializers.SlugField( + source='mentee.user.first_name', + read_only=True, + ) + mentee_last_name = serializers.SlugField( + source='mentee.user.last_name', + read_only=True, + ) class Meta: model = Session - fields = ('pk', 'mentor', 'mentor_first_name', 'mentor_last_name', - 'mentor_availability', 'mentee', 'mentee_first_name', - 'mentee_last_name', 'start_time', 'end_time', 'status', - 'session_length',) - read_only_fields = ('mentor', 'mentor_first_name', 'mentor_last_name', - 'mentee', 'mentee_first_name', 'mentee_last_name') + fields = ( + 'pk', + 'mentor', + 'mentor_first_name', + 'mentor_last_name', + 'mentor_availability', + 'mentee', + 'mentee_first_name', + 'mentee_last_name', + 'start_time', + 'end_time', + 'status', + 'session_length', + ) + read_only_fields = ( + 'mentor', + 'mentor_first_name', + 'mentor_last_name', + 'mentee', + 'mentee_first_name', + 'mentee_last_name', + ) diff --git a/team_production_system/tasks.py b/team_production_system/tasks.py index 675fd38..eb4ef36 100644 --- a/team_production_system/tasks.py +++ b/team_production_system/tasks.py @@ -1,6 +1,8 @@ -from celery import shared_task from datetime import datetime, timedelta + +from celery import shared_task from django.utils import timezone + from .models import Session @@ -8,19 +10,22 @@ # Redis will run this every 5 minutes def notify(): now = datetime.now(timezone.utc) - # session = Session.objects.get(pk=session_pk) - sessions = Session.objects.filter(status="Confirmed") + sessions = Session.objects.filter(status='Confirmed') for session in sessions: start_time = session.start_time # We check a range of times to have Redis run every 5 minutes - if start_time - timedelta(minutes=60) \ - <= now \ - <= start_time - timedelta(minutes=55): + if ( + start_time - timedelta(minutes=60) + <= now + <= start_time - timedelta(minutes=55) + ): if session.mentor.user.notification_settings.sixty_minute_alert: session.sixty_min_notify() - elif start_time - timedelta(minutes=15) \ - <= now \ - <= start_time - timedelta(minutes=10): + elif ( + start_time - timedelta(minutes=15) + <= now + <= start_time - timedelta(minutes=10) + ): if session.mentor.user.notification_settings.fifteen_minute_alert: session.fifteen_min_notify() diff --git a/team_production_system/tests/end_to_end_tests/test_availability_list_create.py b/team_production_system/tests/end_to_end_tests/test_availability_list_create.py index 573c915..065b378 100644 --- a/team_production_system/tests/end_to_end_tests/test_availability_list_create.py +++ b/team_production_system/tests/end_to_end_tests/test_availability_list_create.py @@ -1,8 +1,9 @@ from django.urls import reverse from django.utils import timezone from rest_framework import status -from rest_framework.test import APITestCase, APIClient -from ...models import Availability, Mentor, CustomUser +from rest_framework.test import APIClient, APITestCase + +from ...models import Availability, CustomUser, Mentor from ...serializers import AvailabilitySerializer @@ -10,22 +11,20 @@ class AvailabilityListCreateTestCase(APITestCase): def setUp(self): # Create a Mentor object self.user = CustomUser.objects.create_user( - username='mentor', - email='mentor@example.com', - password='password' + username='mentor', email='mentor@example.com', password='password' ) self.mentor = Mentor.objects.create(user=self.user) # Create two Availability objects associated with the Mentor - self.availability1 = Availability.objects.create( + self.availability_1 = Availability.objects.create( mentor=self.mentor, start_time=timezone.now(), - end_time=timezone.now() + timezone.timedelta(hours=1) + end_time=timezone.now() + timezone.timedelta(hours=1), ) - self.availability2 = Availability.objects.create( + self.availability_2 = Availability.objects.create( mentor=self.mentor, start_time=timezone.now() + timezone.timedelta(days=1), - end_time=timezone.now() + timezone.timedelta(days=1, hours=1) + end_time=timezone.now() + timezone.timedelta(days=1, hours=1), ) # Create a Client self.client = APIClient() @@ -60,8 +59,7 @@ def test_get_availability_list(self): # Check that the response data matches the serialized Availability obj availabilities = Availability.objects.filter( - mentor=self.mentor, - end_time__gte=timezone.now() + mentor=self.mentor, end_time__gte=timezone.now() ).select_related('mentor__user') serializer = AvailabilitySerializer(availabilities, many=True) self.assertEqual(response.data, serializer.data) @@ -80,7 +78,7 @@ def test_create_availability(self): data = { 'mentor': self.mentor.pk, 'start_time': timezone.now() + timezone.timedelta(days=2), - 'end_time': timezone.now() + timezone.timedelta(days=2, hours=1) + 'end_time': timezone.now() + timezone.timedelta(days=2, hours=1), } url = reverse('availability') response = self.client.post(url, data, format='json') @@ -103,12 +101,14 @@ def test_create_availability_with_duplicate_start_time(self): # Authenticate as the Mentor self.client.force_authenticate(user=self.user) - '''Send a POST request to create a new Availability with - a start time that has already been used''' + """ + Send a POST request to create a new Availability with + a start time that has already been used. + """ data = { 'mentor': self.mentor.pk, - 'start_time': self.availability1.start_time, - 'end_time': timezone.now() + timezone.timedelta(hours=2) + 'start_time': self.availability_1.start_time, + 'end_time': timezone.now() + timezone.timedelta(hours=2), } url = reverse('availability') response = self.client.post(url, data, format='json') @@ -117,8 +117,7 @@ def test_create_availability_with_duplicate_start_time(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Check that the response data contains an error message - self.assertEqual(response.data[0], - 'Input overlaps with existing availability.') + self.assertEqual(response.data[0], 'Input overlaps with existing availability.') def test_create_availability_with_duplicate_start_and_end_times(self): """ @@ -133,8 +132,8 @@ def test_create_availability_with_duplicate_start_and_end_times(self): # start and end times data = { 'mentor': self.mentor.pk, - 'start_time': self.availability1.start_time, - 'end_time': self.availability1.end_time + 'start_time': self.availability_1.start_time, + 'end_time': self.availability_1.end_time, } url = reverse('availability') response = self.client.post(url, data, format='json') @@ -143,8 +142,7 @@ def test_create_availability_with_duplicate_start_and_end_times(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Check that the response data contains an error message - self.assertEqual(response.data[0], - 'Input overlaps with existing availability.') + self.assertEqual(response.data[0], 'Input overlaps with existing availability.') def test_create_availability_with_end_time_before_start_time(self): """ @@ -157,13 +155,13 @@ def test_create_availability_with_end_time_before_start_time(self): availability_data = { 'start_time': '2022-01-01T14:00:00Z', 'end_time': '2022-01-01T12:00:00Z', - 'mentor': self.mentor.pk + 'mentor': self.mentor.pk, } - response = self.client.post('/availability/', - availability_data, format='json') + response = self.client.post('/availability/', availability_data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(str(response.data['end_time'][0]), - 'End time must be in the future.') + self.assertEqual( + str(response.data['end_time'][0]), 'End time must be in the future.' + ) self.assertEqual(Availability.objects.count(), 2) def test_create_availability_inside_existing_availability(self): @@ -176,15 +174,14 @@ def test_create_availability_inside_existing_availability(self): self.client.force_authenticate(user=self.user) availability_data = { - 'start_time': self.availability1.start_time + - timezone.timedelta(minutes=15), - 'end_time': self.availability1.end_time - - timezone.timedelta(minutes=15), - 'mentor': self.mentor.pk + 'start_time': self.availability_1.start_time + + timezone.timedelta(minutes=15), + 'end_time': self.availability_1.end_time - timezone.timedelta(minutes=15), + 'mentor': self.mentor.pk, } - response = self.client.post('/availability/', - availability_data, format='json') + response = self.client.post('/availability/', availability_data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(str(response.data[0]), - 'Input overlaps with existing availability.') + self.assertEqual( + str(response.data[0]), 'Input overlaps with existing availability.' + ) self.assertEqual(Availability.objects.count(), 2) diff --git a/team_production_system/tests/test_availability.py b/team_production_system/tests/test_availability.py index 6d27159..c02ffe3 100644 --- a/team_production_system/tests/test_availability.py +++ b/team_production_system/tests/test_availability.py @@ -1,10 +1,12 @@ # flake8: noqa +import unittest +from datetime import timedelta + from django.test import TestCase from django.utils import timezone -from datetime import timedelta -from ..models import CustomUser, Mentor, Availability -import unittest + +from ..models import Availability, CustomUser, Mentor @unittest.skip("Test file is not ready yet") @@ -12,19 +14,15 @@ class AvailabilityTestCase(TestCase): def setUp(self): # Set up a mentor and an availability for testing self.mentor_user = CustomUser.objects.create_user( - username='mentor_user', - email='mentor_user@example.com', - password='password' + username='mentor_user', email='mentor_user@example.com', password='password' ) self.mentor = Mentor.objects.create( - user=self.mentor_user, - about_me='I am a mentor', - skills=['Python'] + user=self.mentor_user, about_me='I am a mentor', skills=['Python'] ) self.availability = Availability.objects.create( mentor=self.mentor, start_time=timezone.now(), - end_time=timezone.now() + timedelta(hours=1) + end_time=timezone.now() + timedelta(hours=1), ) def test_is_available(self): @@ -44,9 +42,7 @@ def test_get_next_seven_days_availability(self): slot_start_time = timezone.now() + timedelta(days=2) slot_end_time = slot_start_time + timedelta(hours=1) availability = Availability.objects.create( - mentor=self.mentor, - start_time=slot_start_time, - end_time=slot_end_time + mentor=self.mentor, start_time=slot_start_time, end_time=slot_end_time ) availabilities = self.availability.get_next_seven_days_availability() self.assertEqual(len(availabilities[2][1]), 1) @@ -63,6 +59,6 @@ def test_is_slot_available(self): mentor_availability=self.availability, mentee=self.mentee, start_time=start_time, - session_length=60 + session_length=60, ) self.assertFalse(self.availability.is_slot_available(start_time, end_time)) diff --git a/team_production_system/tests/unit_tests/models/test_availability_model.py b/team_production_system/tests/unit_tests/models/test_availability_model.py index 840766f..a4c2e61 100644 --- a/team_production_system/tests/unit_tests/models/test_availability_model.py +++ b/team_production_system/tests/unit_tests/models/test_availability_model.py @@ -1,15 +1,15 @@ -from django.test import TestCase from datetime import datetime, timedelta, timezone -from ....models import Availability, Mentor, CustomUser + +from django.test import TestCase + +from ....models import Availability, CustomUser, Mentor class AvailabilityTestCase(TestCase): def setUp(self): # Create a User and Mentor object self.user = CustomUser.objects.create_user( - username='mentor', - email='mentor@example.com', - password='password' + username='mentor', email='mentor@example.com', password='password' ) self.mentor = Mentor.objects.create(user=self.user) @@ -20,9 +20,8 @@ def test_create_availability(self): # Create an Availability object availability = Availability( - mentor=self.mentor, - start_time=start_time, - end_time=end_time) + mentor=self.mentor, start_time=start_time, end_time=end_time + ) # Save an Availability object associated with the Mentor availability.save() @@ -34,6 +33,7 @@ def test_create_availability(self): self.assertEqual(saved_availability.start_time, start_time) self.assertEqual(saved_availability.end_time, end_time) self.assertEqual(saved_availability.mentor, self.mentor) - self.assertEqual(str(saved_availability), - f"{self.mentor} is available from " - f"{start_time} to {end_time}.") + self.assertEqual( + str(saved_availability), + f'{self.mentor} is available from {start_time} to {end_time}.', + ) diff --git a/team_production_system/tests/unit_tests/models/test_mentor_model.py b/team_production_system/tests/unit_tests/models/test_mentor_model.py index 8f7fd34..31a35db 100644 --- a/team_production_system/tests/unit_tests/models/test_mentor_model.py +++ b/team_production_system/tests/unit_tests/models/test_mentor_model.py @@ -1,20 +1,21 @@ from django.test import TestCase -from ....models import Mentor, CustomUser +from ....models import CustomUser, Mentor -class MentorModelTest(TestCase): +class MentorModelTest(TestCase): def setUp(self): # Assuming CustomUser has a username and password - self.user = CustomUser.objects.create(username='testuser', - password='password123') + self.user = CustomUser.objects.create( + username='testuser', password='password123' + ) def test_mentor_creation(self): mentor = Mentor.objects.create( user=self.user, about_me='This is a test about me.', team_number=5, - skills=['HTML', 'CSS', 'Django'] + skills=['HTML', 'CSS', 'Django'], ) # Assert that the mentor object was saved and has the correct @@ -28,7 +29,7 @@ def test_str_representation(self): user=self.user, about_me='This is a test about me.', team_number=5, - skills=['HTML'] + skills=['HTML'], ) # Assert that the __str__ method returns the correct representation @@ -36,20 +37,14 @@ def test_str_representation(self): def test_default_about_me(self): # Create a Mentor object without specifying an 'about_me' - mentor = Mentor.objects.create( - user=self.user, - skills=['HTML'] - ) + mentor = Mentor.objects.create(user=self.user, skills=['HTML']) # Assert that the default value for 'about_me' is set self.assertEqual(mentor.about_me, '') def test_default_team_number(self): # Create a Mentor object without specifying a 'team_number' - mentor = Mentor.objects.create( - user=self.user, - skills=['HTML'] - ) + mentor = Mentor.objects.create(user=self.user, skills=['HTML']) # Assert that the default value for 'team_number' is set self.assertEqual(mentor.team_number, 0) diff --git a/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py b/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py index 4bb8681..5c61b82 100644 --- a/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py +++ b/team_production_system/tests/unit_tests/serializers/test_availability_serializer.py @@ -1,36 +1,36 @@ from datetime import datetime + from django.http import HttpRequest from django.test import TestCase from django.utils import timezone from rest_framework import serializers + +from ....models import Availability, CustomUser, Mentor from ....serializers import AvailabilitySerializer, AvailabilitySerializerV2 -from ....models import Mentor, CustomUser, Availability class AvailabilitySerializerTestCase(TestCase): def setUp(self): self.user = CustomUser.objects.create_user( - username='testuser', password='testpass') + username='testuser', password='testpass' + ) self.mentor = Mentor.objects.create(user=self.user) self.availability_attributes = { 'mentor': self.mentor, - 'start_time': datetime.now( - timezone.utc) + timezone.timedelta(hours=4), - 'end_time': datetime.now( - timezone.utc) + timezone.timedelta(hours=5), + 'start_time': datetime.now(timezone.utc) + timezone.timedelta(hours=4), + 'end_time': datetime.now(timezone.utc) + timezone.timedelta(hours=5), } self.serializer_data = { 'mentor': self.mentor.pk, 'start_time': self.availability_attributes['start_time'], 'end_time': self.availability_attributes['end_time'], } - self.availability = Availability.objects.create( - **self.availability_attributes) + self.availability = Availability.objects.create(**self.availability_attributes) self.request = HttpRequest() self.request.user = self.user self.serializer = AvailabilitySerializer( - instance=self.availability, - context={'request': self.request}) + instance=self.availability, context={'request': self.request} + ) def test_contains_expected_fields(self): data = self.serializer.data @@ -45,16 +45,14 @@ def test_start_time_field_content(self): data = self.serializer.data self.assertEqual( data['start_time'], - self.serializer_data[ - 'start_time'].strftime('%Y-%m-%dT%H:%M:%S.%fZ') + self.serializer_data['start_time'].strftime('%Y-%m-%dT%H:%M:%S.%fZ'), ) def test_end_time_field_content(self): data = self.serializer.data self.assertEqual( data['end_time'], - self.serializer_data[ - 'end_time'].strftime('%Y-%m-%dT%H:%M:%S.%fZ') + self.serializer_data['end_time'].strftime('%Y-%m-%dT%H:%M:%S.%fZ'), ) def test_create(self): @@ -66,9 +64,8 @@ def test_create(self): 'end_time': end_time, } serializer = AvailabilitySerializer( - data=serializer_data, - context={'request': self.request} - ) + data=serializer_data, context={'request': self.request} + ) self.assertTrue(serializer.is_valid()) availability = serializer.save() self.assertEqual(availability.mentor, self.mentor) @@ -80,7 +77,8 @@ def test_create(self): class AvailabilitySerializerV2TestCase(TestCase): def setUp(self): self.user = CustomUser.objects.create_user( - username='testuser', password='testpass') + username='testuser', password='testpass' + ) self.mentor = Mentor.objects.create(user=self.user) self.request = HttpRequest() self.request.user = self.user @@ -94,32 +92,26 @@ def setUp(self): 'start_time': self.availability_attributes['start_time'], 'end_time': self.availability_attributes['end_time'], } - self.availability = Availability.objects.create( - **self.availability_attributes) + self.availability = Availability.objects.create(**self.availability_attributes) self.serializer = AvailabilitySerializerV2( - instance=self.availability, - context={'request': self.request}) + instance=self.availability, context={'request': self.request} + ) # Test that the serializer contains the expected fields def test_contains_expected_fields(self): data = self.serializer.data - self.assertEqual(set(data.keys()), set( - ['pk', 'mentor', 'start_time', 'end_time', 'status'])) + expected_keys = {'pk', 'mentor', 'start_time', 'end_time', 'status'} + self.assertEqual(set(data.keys()), expected_keys) def test_create(self): pass # Test validate method def test_validate(self): - serializer = AvailabilitySerializerV2( - context={'request': self.request}) - start_time = datetime.now( - timezone.utc) + timezone.timedelta(hours=1) + serializer = AvailabilitySerializerV2(context={'request': self.request}) + start_time = datetime.now(timezone.utc) + timezone.timedelta(hours=1) end_time = timezone.now() + timezone.timedelta(hours=2) - data = { - 'start_time': start_time, - 'end_time': end_time - } + data = {'start_time': start_time, 'end_time': end_time} # Test valid input data validated_data = serializer.validate(data) @@ -134,9 +126,9 @@ def test_validate(self): } with self.assertRaises(serializers.ValidationError) as context: serializer.validate(data) + self.assertEqual( - str(context.exception.detail[0]), - 'Start time must be in the future.' + str(context.exception.detail[0]), 'Start time must be in the future.' ) # Test invalid end_time @@ -148,7 +140,7 @@ def test_validate(self): } with self.assertRaises(serializers.ValidationError) as context: serializer.validate(data) + self.assertEqual( - str(context.exception.detail[0]), - 'End time must be after start time.' + str(context.exception.detail[0]), 'End time must be after start time.' ) diff --git a/team_production_system/tests/unit_tests/tasks/test_tasks.py b/team_production_system/tests/unit_tests/tasks/test_tasks.py index 03fa5c7..e6780c3 100644 --- a/team_production_system/tests/unit_tests/tasks/test_tasks.py +++ b/team_production_system/tests/unit_tests/tasks/test_tasks.py @@ -1,7 +1,9 @@ -from django.test import TestCase -from django.utils import timezone from datetime import timedelta from unittest.mock import MagicMock + +from django.test import TestCase +from django.utils import timezone + from ....models import Session from ....tasks import notify diff --git a/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py b/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py index 279eb2a..6653c6b 100644 --- a/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py +++ b/team_production_system/tests/unit_tests/views/test_availability_create_list_view.py @@ -1,31 +1,29 @@ +from datetime import timedelta +from unittest.mock import patch + +from django.test import TestCase from django.urls import reverse from django.utils import timezone -from datetime import timedelta from rest_framework import status from rest_framework.test import APIClient -from django.test import TestCase -from ....models import Mentor, Availability, CustomUser -from ....serializers import ( - AvailabilitySerializer, - AvailabilitySerializerV2 -) -from unittest.mock import patch + +from ....models import Availability, CustomUser, Mentor +from ....serializers import AvailabilitySerializer, AvailabilitySerializerV2 class AvailabilityListCreateViewTestCase(TestCase): def setUp(self): # Create a Mentor instance for the test self.user = CustomUser.objects.create_user( - username='testuser', - email='testuser@fake.com', - password='testpass') + username='testuser', email='testuser@fake.com', password='testpass' + ) self.mentor = Mentor.objects.create(user=self.user) # Create an Availability instance for the test self.availability = Availability.objects.create( mentor=self.mentor, start_time=timezone.now() + timezone.timedelta(hours=1), - end_time=timezone.now() + timezone.timedelta(hours=2) + end_time=timezone.now() + timezone.timedelta(hours=2), ) self.url = reverse('availability') @@ -41,8 +39,10 @@ def test_get_availability_list(self, mock_timezone): self.client.force_authenticate(user=self.user) # Set up the mock timezone to return a fixed datetime - mock_timezone.now.return_value = timezone.datetime(2022, 1, 1, - tzinfo=timezone.utc) + mock_timezone.now.return_value = timezone.datetime( + 2022, 1, 1, tzinfo=timezone.utc + ) + # Make a GET request to the AvailabilityList view response = self.client.get('/availability/', format='json') # Check that the response status code is 200 OK @@ -50,9 +50,10 @@ def test_get_availability_list(self, mock_timezone): # Check that the response data contains the expected Availability self.assertEqual(len(response.data), 1) - self.assertEqual(response.data[0]['start_time'], - self.availability.start_time.isoformat().replace( - '+00:00', 'Z')) + self.assertEqual( + response.data[0]['start_time'], + self.availability.start_time.isoformat().replace('+00:00', 'Z'), + ) def test_create_availability_v1(self): """ @@ -67,7 +68,7 @@ def test_create_availability_v1(self): data = { 'mentor': self.mentor.pk, 'start_time': timezone.now() + timezone.timedelta(hours=3), - 'end_time': timezone.now() + timezone.timedelta(hours=4) + 'end_time': timezone.now() + timezone.timedelta(hours=4), } response = client.post(self.url, data, format='json') @@ -78,8 +79,7 @@ def test_create_availability_v1(self): # Check that the response data is the new Availability availability = Availability.objects.last() serializer = AvailabilitySerializer(availability) - self.assertEqual(response.data['start_time'], - serializer.data['start_time']) + self.assertEqual(response.data['start_time'], serializer.data['start_time']) def test_create_availability_v1_with_invalid_data(self): """ @@ -94,7 +94,7 @@ def test_create_availability_v1_with_invalid_data(self): data = { 'mentor': self.mentor.pk, 'start_time': timezone.now() + timezone.timedelta(hours=2), - 'end_time': timezone.now() + timezone.timedelta(hours=1) + 'end_time': timezone.now() + timezone.timedelta(hours=1), } response = client.post(self.url, data, format='json') @@ -103,8 +103,7 @@ def test_create_availability_v1_with_invalid_data(self): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Check that the response data contains an error message - self.assertEqual(str(response.data[0]), - 'End time must be after start time.') + self.assertEqual(str(response.data[0]), 'End time must be after start time.') def test_create_availability_v2(self): self.client = APIClient() @@ -122,8 +121,7 @@ def test_create_availability_v2(self): self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Availability.objects.count(), 3) availability = Availability.objects.last() - self.assertEqual( - availability.start_time, end_time - timedelta(minutes=30)) + self.assertEqual(availability.start_time, end_time - timedelta(minutes=30)) self.assertEqual(availability.end_time, end_time) self.assertEqual(availability.mentor, self.mentor) @@ -134,7 +132,8 @@ def test_create_availability_v2_with_overlap(self): start_time = timezone.now() + timedelta(hours=7) end_time = start_time + timedelta(hours=8) Availability.objects.create( - mentor=self.mentor, start_time=start_time, end_time=end_time) + mentor=self.mentor, start_time=start_time, end_time=end_time + ) data = { 'start_time': start_time, 'end_time': end_time, @@ -175,8 +174,7 @@ def test_create_availability_v2_with_time_not_divisible_by_30(self): self.assertEqual(len(response.data), 2) availability_1 = Availability.objects.get(pk=response.data[0]['pk']) availability_2 = Availability.objects.get(pk=response.data[1]['pk']) - self.assertEqual(availability_1.end_time, - start_time + timedelta(minutes=30)) + self.assertEqual(availability_1.end_time, start_time + timedelta(minutes=30)) self.assertNotEqual(availability_2.end_time, end_time) self.assertEqual(availability_1.mentor, self.mentor) diff --git a/team_production_system/tests/unit_tests/views/test_availability_delete_view.py b/team_production_system/tests/unit_tests/views/test_availability_delete_view.py index 470c307..8483f15 100644 --- a/team_production_system/tests/unit_tests/views/test_availability_delete_view.py +++ b/team_production_system/tests/unit_tests/views/test_availability_delete_view.py @@ -2,14 +2,16 @@ from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient -from ....models import Availability, Mentor, CustomUser + +from ....models import Availability, CustomUser, Mentor class AvailabilityDeleteViewTestCase(TestCase): def setUp(self): self.client = APIClient() self.user = CustomUser.objects.create_user( - username='testuser', password='testpass') + username='testuser', password='testpass' + ) self.mentor = Mentor.objects.create(user=self.user) self.client.force_authenticate(user=self.user) @@ -18,7 +20,7 @@ def test_get_object(self): availability = Availability.objects.create( mentor=self.mentor, start_time='2022-01-01T00:00:00Z', - end_time='2022-01-01T01:00:00Z' + end_time='2022-01-01T01:00:00Z', ) # Test that get_object returns the correct Availability instance diff --git a/team_production_system/urls.py b/team_production_system/urls.py index 7a99301..87f22df 100644 --- a/team_production_system/urls.py +++ b/team_production_system/urls.py @@ -1,50 +1,58 @@ from django.urls import path -from team_production_system import views +from team_production_system import views urlpatterns = [ - - # User endpoints - path('myprofile/', views.UserProfile.as_view(), name='my-profile'), - - # Mentor end points - path('mentor/', views.MentorList.as_view(), name='mentor-list'), - path('mentorinfo/', views.MentorInfoView.as_view(), name='mentor-info'), - path('mentor//', views.MentorFilteredList.as_view(), - name='mentor-filtered-list'), - path('mentorinfoupdate/', views.MentorInfoUpdateView.as_view(), - name='mentor-info-update'), - - # Mentee endpoints - path('mentee/', views.MenteeList.as_view(), name='mentee-list'), - path('menteeinfo/', views.MenteeInfoView.as_view(), name='mentee-info'), - path('menteeinfoupdate/', views.MenteeInfoUpdateView.as_view(), - name='mentee-info-update'), - - # Availability endpoints - path( - 'availability/', - views.AvailabilityListCreateView.as_view(), - name='availability' - ), - path('availability//', views.AvailabilityDeleteView.as_view(), - name='availability-delete'), - - # Session endpoints - path('session/', views.SessionView.as_view(), name='session'), - path('archivesession/', views.ArchiveSessionView.as_view(), - name='archive-session'), - path('sessionrequest/', views.SessionRequestView.as_view(), - name='session'), - path('sessionrequest//', views.SessionRequestDetailView.as_view(), - name='session-detail'), - path('sessionsignuplist/', views.SessionSignupListView.as_view(), - name='session-signup-list'), - - # Notification endpoints - path( - 'notificationsettings//', - views.NotificationSettingsView.as_view(), - name='notification-settings' - ), - ] + # User endpoints + path('myprofile/', views.UserProfile.as_view(), name='my-profile'), + # Mentor end points + path('mentor/', views.MentorList.as_view(), name='mentor-list'), + path('mentorinfo/', views.MentorInfoView.as_view(), name='mentor-info'), + path( + 'mentor//', + views.MentorFilteredList.as_view(), + name='mentor-filtered-list', + ), + path( + 'mentorinfoupdate/', + views.MentorInfoUpdateView.as_view(), + name='mentor-info-update', + ), + # Mentee endpoints + path('mentee/', views.MenteeList.as_view(), name='mentee-list'), + path('menteeinfo/', views.MenteeInfoView.as_view(), name='mentee-info'), + path( + 'menteeinfoupdate/', + views.MenteeInfoUpdateView.as_view(), + name='mentee-info-update', + ), + # Availability endpoints + path( + 'availability/', views.AvailabilityListCreateView.as_view(), name='availability' + ), + path( + 'availability//', + views.AvailabilityDeleteView.as_view(), + name='availability-delete', + ), + # Session endpoints + path('session/', views.SessionView.as_view(), name='session'), + path('archivesession/', views.ArchiveSessionView.as_view(), name='archive-session'), + path('sessionrequest/', views.SessionRequestView.as_view(), name='session'), + path( + 'sessionrequest//', + views.SessionRequestDetailView.as_view(), + name='session-detail', + ), + path( + 'sessionsignuplist/', + views.SessionSignUpListView.as_view(), + name='session-signup-list', + ), + # Notification endpoints + path( + 'notificationsettings//', + views.NotificationSettingsView.as_view(), + name='notification-settings', + ), +] diff --git a/team_production_system/views/__init__.py b/team_production_system/views/__init__.py index 59cc71b..39472b4 100644 --- a/team_production_system/views/__init__.py +++ b/team_production_system/views/__init__.py @@ -14,5 +14,5 @@ from .session_list import SessionView from .session_request_detail import SessionRequestDetailView from .session_request_list_create import SessionRequestView -from .session_signup_list import SessionSignupListView +from .session_signup_list import SessionSignUpListView from .user_profile import UserProfile diff --git a/team_production_system/views/archive_session_list.py b/team_production_system/views/archive_session_list.py index 4fc016c..2b4de3c 100644 --- a/team_production_system/views/archive_session_list.py +++ b/team_production_system/views/archive_session_list.py @@ -1,9 +1,10 @@ +from django.db.models import Q +from django.utils import timezone from rest_framework import generics +from rest_framework.permissions import IsAuthenticated + from team_production_system.models import Session from team_production_system.serializers import SessionSerializer -from rest_framework.permissions import IsAuthenticated -from django.utils import timezone -from django.db.models import Q class ArchiveSessionView(generics.ListAPIView): @@ -13,6 +14,7 @@ class ArchiveSessionView(generics.ListAPIView): def get_queryset(self): # Get sessions for the logged in user - return Session.objects.filter(Q(mentor__user=self.request.user) | - Q(mentee__user=self.request.user), - end_time__lt=timezone.now()) + return Session.objects.filter( + Q(mentor__user=self.request.user) | Q(mentee__user=self.request.user), + end_time__lt=timezone.now(), + ) diff --git a/team_production_system/views/availability_delete.py b/team_production_system/views/availability_delete.py index 77de3e8..1fca5ce 100644 --- a/team_production_system/views/availability_delete.py +++ b/team_production_system/views/availability_delete.py @@ -1,9 +1,10 @@ +from django.http import Http404 from rest_framework import generics from rest_framework.permissions import IsAuthenticated -from django.http import Http404 -from team_production_system.serializers import AvailabilitySerializer -from team_production_system.models import Availability + from team_production_system.custom_permissions import IsOwnerOrAdmin +from team_production_system.models import Availability +from team_production_system.serializers import AvailabilitySerializer class AvailabilityDeleteView(generics.DestroyAPIView): @@ -13,9 +14,10 @@ class AvailabilityDeleteView(generics.DestroyAPIView): def get_object(self): try: # Get the Availability instance for the logged in user - availability = Availability.objects.select_related( - 'mentor__user').get(id=self.kwargs['pk']) + availability = Availability.objects.select_related('mentor__user').get( + id=self.kwargs['pk'] + ) self.check_object_permissions(self.request, availability) return availability except Availability.DoesNotExist: - raise Http404("No Availability matches the given query.") + raise Http404('No Availability matches the given query.') diff --git a/team_production_system/views/availability_list_create.py b/team_production_system/views/availability_list_create.py index fb929b5..02eab3b 100644 --- a/team_production_system/views/availability_list_create.py +++ b/team_production_system/views/availability_list_create.py @@ -1,13 +1,14 @@ +from django.utils import timezone from rest_framework import generics, status from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from django.utils import timezone + +from team_production_system.helpers import create_30_min_availabilities +from team_production_system.models import Availability, Mentor from team_production_system.serializers import ( AvailabilitySerializer, - AvailabilitySerializerV2 + AvailabilitySerializerV2, ) -from team_production_system.models import Mentor, Availability -from team_production_system.helpers import create_30_min_availabilities # Create and view all availabilities @@ -26,12 +27,12 @@ def handle_exception(self, exc): def get_queryset(self): if self.request.version == 'v2': # Get the Mentor instance for the logged in user - mentor = Mentor.objects.select_related('user').get( - user=self.request.user) - return Availability.objects.filter( - mentor=mentor, - end_time__gte=timezone.now() - ).select_related('mentor__user').order_by('start_time') + mentor = Mentor.objects.select_related('user').get(user=self.request.user) + return ( + Availability.objects.filter(mentor=mentor, end_time__gte=timezone.now()) + .select_related('mentor__user') + .order_by('start_time') + ) else: # Get the Mentor instance for the logged in user mentor = Mentor.objects.get(user=self.request.user) @@ -51,7 +52,7 @@ def create(self, request, *args, **kwargs): availabilities = create_30_min_availabilities( request.data['start_time'], request.data['end_time'], - request.user.mentor + request.user.mentor, ) # Serialize and save 30 min availabilities serializer = self.get_serializer(data=availabilities, many=True) @@ -60,17 +61,16 @@ def create(self, request, *args, **kwargs): headers = self.get_success_headers(serializer.data) return Response( - serializer.data, - status=status.HTTP_201_CREATED, - headers=headers) + serializer.data, status=status.HTTP_201_CREATED, headers=headers + ) + serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response( - serializer.data, - status=status.HTTP_201_CREATED, - headers=headers) + serializer.data, status=status.HTTP_201_CREATED, headers=headers + ) def get_serializer_class(self): if self.request.version == 'v2': diff --git a/team_production_system/views/mentee_info_list_create.py b/team_production_system/views/mentee_info_list_create.py index 570d17e..e4df351 100644 --- a/team_production_system/views/mentee_info_list_create.py +++ b/team_production_system/views/mentee_info_list_create.py @@ -1,7 +1,8 @@ from rest_framework import generics from rest_framework.permissions import IsAuthenticated -from team_production_system.serializers import MenteeProfileSerializer + from team_production_system.models import Mentee +from team_production_system.serializers import MenteeProfileSerializer # View to allow mentees to create and view the about me/skills. diff --git a/team_production_system/views/mentee_info_update.py b/team_production_system/views/mentee_info_update.py index 991d291..e23fd33 100644 --- a/team_production_system/views/mentee_info_update.py +++ b/team_production_system/views/mentee_info_update.py @@ -1,5 +1,6 @@ from rest_framework import generics from rest_framework.permissions import IsAuthenticated + from team_production_system.serializers import MenteeProfileSerializer diff --git a/team_production_system/views/mentee_list.py b/team_production_system/views/mentee_list.py index 1094c18..f23436b 100644 --- a/team_production_system/views/mentee_list.py +++ b/team_production_system/views/mentee_list.py @@ -1,8 +1,9 @@ from rest_framework import generics, status -from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated -from team_production_system.serializers import MenteeListSerializer +from rest_framework.response import Response + from team_production_system.models import CustomUser +from team_production_system.serializers import MenteeListSerializer class MenteeList(generics.ListAPIView): @@ -10,15 +11,19 @@ class MenteeList(generics.ListAPIView): def get(self, request, *args, **kwargs): try: - queryset = CustomUser.objects.filter( - is_mentee=True).select_related("mentee") + queryset = CustomUser.objects.filter(is_mentee=True).select_related( + 'mentee' + ) except Exception: - return Response({"error": "Failed to retrieve mentee list."}, - status=status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response( + {'error': 'Failed to retrieve mentee list.'}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) if not queryset.exists(): - return Response({"message": "No mentees found."}, - status=status.HTTP_404_NOT_FOUND) + return Response( + {'message': 'No mentees found.'}, status=status.HTTP_404_NOT_FOUND + ) serializer = MenteeListSerializer(queryset, many=True) response_data = serializer.data diff --git a/team_production_system/views/mentor_filtered_list.py b/team_production_system/views/mentor_filtered_list.py index 8ed016b..ac519b1 100644 --- a/team_production_system/views/mentor_filtered_list.py +++ b/team_production_system/views/mentor_filtered_list.py @@ -1,8 +1,9 @@ from rest_framework import generics, status -from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated -from team_production_system.serializers import MentorProfileSerializer +from rest_framework.response import Response + from team_production_system.models import Mentor +from team_production_system.serializers import MentorProfileSerializer class MentorFilteredList(generics.ListAPIView): @@ -15,8 +16,9 @@ def get(self, request, *args, **kwargs): queryset = queryset.filter(skills__icontains=skill) if not queryset.exists(): - return Response({"message": "No mentors found."}, - status=status.HTTP_404_NOT_FOUND) + return Response( + {'message': 'No mentors found.'}, status=status.HTTP_404_NOT_FOUND + ) serializer = MentorProfileSerializer(queryset, many=True) return Response(serializer.data) diff --git a/team_production_system/views/mentor_info_list_create.py b/team_production_system/views/mentor_info_list_create.py index 3ead109..f7ac5a1 100644 --- a/team_production_system/views/mentor_info_list_create.py +++ b/team_production_system/views/mentor_info_list_create.py @@ -1,7 +1,8 @@ from rest_framework import generics from rest_framework.permissions import IsAuthenticated -from team_production_system.serializers import MentorProfileSerializer + from team_production_system.models import Mentor +from team_production_system.serializers import MentorProfileSerializer # View to allow mentors to create and view the about me/skills. diff --git a/team_production_system/views/mentor_info_update.py b/team_production_system/views/mentor_info_update.py index 10cb82f..fa6791e 100644 --- a/team_production_system/views/mentor_info_update.py +++ b/team_production_system/views/mentor_info_update.py @@ -1,5 +1,6 @@ from rest_framework import generics from rest_framework.permissions import IsAuthenticated + from team_production_system.serializers import MentorProfileSerializer diff --git a/team_production_system/views/mentor_list.py b/team_production_system/views/mentor_list.py index 11aec69..3c61a95 100644 --- a/team_production_system/views/mentor_list.py +++ b/team_production_system/views/mentor_list.py @@ -1,28 +1,29 @@ from rest_framework import generics, status -from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated -from team_production_system.serializers import MentorListSerializer +from rest_framework.response import Response + from team_production_system.models import CustomUser +from team_production_system.serializers import MentorListSerializer # View to see a list of all users flagged as a mentor class MentorList(generics.ListAPIView): permission_classes = [IsAuthenticated] - queryset = CustomUser.objects.filter( - is_mentor=True - ).select_related( - "mentor" - ).prefetch_related( - "mentor__mentor_availability") + queryset = ( + CustomUser.objects.filter(is_mentor=True) + .select_related('mentor') + .prefetch_related('mentor__mentor_availability') + ) serializer_class = MentorListSerializer def list(self, request, *args, **kwargs): queryset = self.get_queryset() if not queryset: - return Response({"message": "No mentors found."}, - status=status.HTTP_404_NOT_FOUND) + return Response( + {'message': 'No mentors found.'}, status=status.HTTP_404_NOT_FOUND + ) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) diff --git a/team_production_system/views/notification_settings.py b/team_production_system/views/notification_settings.py index 0e1d3eb..8e41d1f 100644 --- a/team_production_system/views/notification_settings.py +++ b/team_production_system/views/notification_settings.py @@ -1,9 +1,8 @@ from rest_framework import generics -from team_production_system.custom_permissions import ( - NotificationSettingsPermission -) -from team_production_system.serializers import NotificationSettingsSerializer + +from team_production_system.custom_permissions import NotificationSettingsPermission from team_production_system.models import NotificationSettings +from team_production_system.serializers import NotificationSettingsSerializer class NotificationSettingsView(generics.RetrieveUpdateAPIView): diff --git a/team_production_system/views/session_list.py b/team_production_system/views/session_list.py index db5ec69..4606556 100644 --- a/team_production_system/views/session_list.py +++ b/team_production_system/views/session_list.py @@ -1,9 +1,10 @@ +from django.db.models import Q +from django.utils import timezone from rest_framework import generics from rest_framework.permissions import IsAuthenticated -from django.utils import timezone -from django.db.models import Q -from team_production_system.serializers import SessionSerializer + from team_production_system.models import Session +from team_production_system.serializers import SessionSerializer class SessionView(generics.ListAPIView): @@ -15,7 +16,7 @@ def get_queryset(self): # Get sessions for the logged in user # Exclude sessions that have already ended and # order by sessions that are coming up next first. - return Session.objects.filter(Q(mentor__user=self.request.user) | - Q(mentee__user=self.request.user), - start_time__gt=timezone.now() - ).order_by('start_time') + return Session.objects.filter( + Q(mentor__user=self.request.user) | Q(mentee__user=self.request.user), + start_time__gt=timezone.now(), + ).order_by('start_time') diff --git a/team_production_system/views/session_request_detail.py b/team_production_system/views/session_request_detail.py index 6241533..bc5072a 100644 --- a/team_production_system/views/session_request_detail.py +++ b/team_production_system/views/session_request_detail.py @@ -1,7 +1,8 @@ from rest_framework import generics + from team_production_system.custom_permissions import IsMentorMentee -from team_production_system.serializers import SessionSerializer from team_production_system.models import Session +from team_production_system.serializers import SessionSerializer class SessionRequestDetailView(generics.RetrieveUpdateDestroyAPIView): @@ -20,14 +21,18 @@ def perform_update(self, serializer): session.save() # If mentee cancels session, check mentor notification - if self.request.user.is_mentee and \ - session.mentor.user.notification_settings.session_canceled: + if ( + self.request.user.is_mentee + and session.mentor.user.notification_settings.session_canceled + ): session.mentor_cancel_notify() # If mentor cancels session, check mentee notification - elif self.request.user.is_mentor and \ - session.mentee.user.notification_settings.session_canceled: + elif ( + self.request.user.is_mentor + and session.mentee.user.notification_settings.session_canceled + ): session.mentee_cancel_notify() # Notify mentee when a mentor confirms session request diff --git a/team_production_system/views/session_request_list_create.py b/team_production_system/views/session_request_list_create.py index 371afa6..52e4e8a 100644 --- a/team_production_system/views/session_request_list_create.py +++ b/team_production_system/views/session_request_list_create.py @@ -1,25 +1,27 @@ -from rest_framework import generics -from rest_framework.permissions import IsAuthenticated +from datetime import datetime, timedelta + from django.core.exceptions import ValidationError from django.db.models import Q -from datetime import datetime, timedelta from django.utils import timezone +from rest_framework import generics +from rest_framework.permissions import IsAuthenticated + +from team_production_system.models import Availability, Mentee, Session from team_production_system.serializers import SessionSerializer -from team_production_system.models import (Availability, - Mentee, - Session) def time_convert(time, minutes): # Convert string from front end to datetime object - datetime_obj = datetime.strptime( - time, '%Y-%m-%dT%H:%M:%S.%fZ').replace(tzinfo=timezone.utc) + datetime_obj = datetime.strptime(time, '%Y-%m-%dT%H:%M:%S.%fZ').replace( + tzinfo=timezone.utc + ) # Change time dependent on session length minutes datetime_delta = datetime_obj - timedelta(minutes=minutes) # Convert datetime object back to string - new_start_time = datetime.strftime( - datetime_delta, '%Y-%m-%d %H:%M:%S%z')[:-2] + new_start_time = datetime.strftime(datetime_delta, '%Y-%m-%d %H:%M:%S%z')[:-2] return new_start_time + + # Time conversion helper function # During a session request, must convert start_time string to a datetime # object in order to use timedelta to check for overlapping sessions @@ -36,8 +38,7 @@ def perform_create(self, serializer): mentor_availability_id = self.request.data.get('mentor_availability') # Get the mentor availability instance - mentor_availability = Availability.objects.get( - id=mentor_availability_id) + mentor_availability = Availability.objects.get(id=mentor_availability_id) # Ensure no overlap between mentor or mentee's sessions mentor = mentor_availability.mentor @@ -51,32 +52,50 @@ def perform_create(self, serializer): new_start_time = time_convert(start_time, session_length) if Session.objects.filter( - Q(mentor=mentor, start_time=start_time, - status__in=['Pending', 'Confirmed']) | - Q(mentor=mentor, start_time=new_start_time, - session_length=60, status__in=['Pending', 'Confirmed']) + Q( + mentor=mentor, + start_time=start_time, + status__in=['Pending', 'Confirmed'], + ) + | Q( + mentor=mentor, + start_time=new_start_time, + session_length=60, + status__in=['Pending', 'Confirmed'], + ) ).exists(): raise ValidationError( 'A session with this mentor is \ - already scheduled during this time.') + already scheduled during this time.' + ) elif Session.objects.filter( - Q(mentee=mentee, start_time=start_time, - status__in=['Pending', 'Confirmed']) | - Q(mentee=mentee, start_time=new_start_time, - session_length=60, status__in=['Pending', 'Confirmed']) + Q( + mentee=mentee, + start_time=start_time, + status__in=['Pending', 'Confirmed'], + ) + | Q( + mentee=mentee, + start_time=new_start_time, + session_length=60, + status__in=['Pending', 'Confirmed'], + ) ).exists(): raise ValidationError( 'A session with this mentee is \ - already scheduled during this time.') + already scheduled during this time.' + ) # Set the mentor for the session else: - serializer.save(mentor=mentor, - mentor_availability=mentor_availability, - mentee=mentee) + serializer.save( + mentor=mentor, + mentor_availability=mentor_availability, + mentee=mentee, + ) - # Email notification to the mentor + # Email notification to the mentor session = serializer.instance if session.mentor.user.notification_settings.session_requested: session.mentor_session_notify() @@ -86,34 +105,58 @@ def perform_create(self, serializer): after_start_time = time_convert(start_time, -30) if Session.objects.filter( - Q(mentor=mentor, start_time=start_time, - status__in=['Pending', 'Confirmed']) | - Q(mentor=mentor, start_time=before_start_time, - session_length=60, status__in=['Pending', 'Confirmed']) | - Q(mentor=mentor, start_time=after_start_time, - status__in=['Pending', 'Confirmed']) + Q( + mentor=mentor, + start_time=start_time, + status__in=['Pending', 'Confirmed'], + ) + | Q( + mentor=mentor, + start_time=before_start_time, + session_length=60, + status__in=['Pending', 'Confirmed'], + ) + | Q( + mentor=mentor, + start_time=after_start_time, + status__in=['Pending', 'Confirmed'], + ) ).exists(): raise ValidationError( 'A session with this mentor is \ - already scheduled during this time.') + already scheduled during this time.' + ) elif Session.objects.filter( - Q(mentee=mentee, start_time=start_time, - status__in=['Pending', 'Confirmed']) | - Q(mentee=mentee, start_time=before_start_time, - session_length=60, status__in=['Pending', 'Confirmed']) | - Q(mentee=mentee, start_time=after_start_time, - status__in=['Pending', 'Confirmed']) + Q( + mentee=mentee, + start_time=start_time, + status__in=['Pending', 'Confirmed'], + ) + | Q( + mentee=mentee, + start_time=before_start_time, + session_length=60, + status__in=['Pending', 'Confirmed'], + ) + | Q( + mentee=mentee, + start_time=after_start_time, + status__in=['Pending', 'Confirmed'], + ) ).exists(): raise ValidationError( 'A session with this mentee is already \ - scheduled during this time.') + scheduled during this time.' + ) # Set the mentor for the session else: - serializer.save(mentor=mentor, - mentor_availability=mentor_availability, - mentee=mentee) + serializer.save( + mentor=mentor, + mentor_availability=mentor_availability, + mentee=mentee, + ) # Email notification to the mentor session = serializer.instance diff --git a/team_production_system/views/session_signup_list.py b/team_production_system/views/session_signup_list.py index 3f70db1..6fbb7c1 100644 --- a/team_production_system/views/session_signup_list.py +++ b/team_production_system/views/session_signup_list.py @@ -1,19 +1,21 @@ -from rest_framework import generics from datetime import timedelta + from django.utils import timezone +from rest_framework import generics from rest_framework.permissions import IsAuthenticated -from team_production_system.serializers import SessionSerializer + from team_production_system.models import Session +from team_production_system.serializers import SessionSerializer -# View to show mentor timeslots a mentee can sign up for -class SessionSignupListView(generics.ListAPIView): +# View to show mentor time slots a mentee can sign up for +class SessionSignUpListView(generics.ListAPIView): queryset = Session.objects.all() serializer_class = SessionSerializer permission_classes = [IsAuthenticated] def get_queryset(self): # Filter out completed sessions - return Session.objects.exclude(status='Completed', - start_time__lt=timezone.now() - - timedelta(hours=24)) + return Session.objects.exclude( + status='Completed', start_time__lt=timezone.now() - timedelta(hours=24) + ) diff --git a/team_production_system/views/user_profile.py b/team_production_system/views/user_profile.py index 5e6b195..7bd28d3 100644 --- a/team_production_system/views/user_profile.py +++ b/team_production_system/views/user_profile.py @@ -1,10 +1,10 @@ from rest_framework import generics, status -from rest_framework.response import Response from rest_framework.parsers import MultiPartParser from rest_framework.permissions import IsAuthenticated -from django.conf import settings -from team_production_system.serializers import CustomUserSerializer +from rest_framework.response import Response + from team_production_system.models import CustomUser +from team_production_system.serializers import CustomUserSerializer # View to update the user profile information @@ -17,23 +17,35 @@ class UserProfile(generics.RetrieveUpdateDestroyAPIView): def get_object(self): user = self.request.user if not user.is_authenticated: - return Response({'error': 'User is not authenticated.'}, - status=status.HTTP_401_UNAUTHORIZED) + return Response( + {'error': 'User is not authenticated.'}, + status=status.HTTP_401_UNAUTHORIZED, + ) + try: return user except CustomUser.DoesNotExist: - return Response({'error': 'User not found.'}, - status=status.HTTP_404_NOT_FOUND) + return Response( + {'error': 'User not found.'}, status=status.HTTP_404_NOT_FOUND + ) except Exception: - return Response({ - 'error': 'An unexpected error occurred.' - }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response( + {'error': 'An unexpected error occurred.'}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) def patch(self, request, *args, **kwargs): user = self.request.user - fields = ['first_name', 'last_name', 'email', - 'phone_number', 'is_mentor', 'is_mentee', 'is_active'] + fields = [ + 'first_name', + 'last_name', + 'email', + 'phone_number', + 'is_mentor', + 'is_mentee', + 'is_active', + ] for field in fields: if field in request.data: @@ -43,6 +55,7 @@ def patch(self, request, *args, **kwargs): if user.profile_photo: # remove the file from storage user.profile_photo.storage.delete(user.profile_photo.name) + user.profile_photo = request.FILES['profile_photo'] user.save() diff --git a/whitelist.txt b/whitelist.txt new file mode 100644 index 0000000..265b15c --- /dev/null +++ b/whitelist.txt @@ -0,0 +1,15 @@ +mentee +mentees +mentee's +asgi +storages +s3boto3 +phonenumber +modelfields +multiselectfield +jitsi +availabilities +V2 +V1 +dateparse +breakpoint From 4b2c6a3ad45ce74861e9d726aff3554ac99a9dc7 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Sat, 11 Nov 2023 10:55:05 -0500 Subject: [PATCH 14/18] chore(issue-110): move all dev dependencies to dev-packages (#180) * chore(linting): cleans up code * chore(devops): pre-commit and coverage added to dev-packages * docs(packages): add instructions on package installation * chore(docs): fixed link --- Pipfile | 4 +- Pipfile.lock | 378 +++++++++--------- README.md | 24 ++ team_production_system/admin.py | 2 +- .../test_user_profile_patch_upload.py | 21 +- 5 files changed, 220 insertions(+), 209 deletions(-) diff --git a/Pipfile b/Pipfile index cd8b73b..a154929 100644 --- a/Pipfile +++ b/Pipfile @@ -23,10 +23,8 @@ boto3 = "*" sentry-sdk = {extras = ["django"], version = "*"} pytz = "*" redis = "*" -coverage = "*" celery = "*" django-celery-beat = "*" -pre-commit = "*" [dev-packages] flake8 = "*" @@ -41,6 +39,8 @@ flake8-secure-coding-standard = "*" isort = "*" flake8-comprehensions = "*" flake8-quotes = "*" +pre-commit = "*" +coverage = "*" [requires] python_version = "3.10" diff --git a/Pipfile.lock b/Pipfile.lock index ebc02ea..657727e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9ef67d98faa54fd0a9a5cdb93981e091ca450e69a0d3bbfe6edaf50a9fad482b" + "sha256": "1cdd5af9b4bb6cc3add05bae0c649184807370a7e8fcadfc85a1d80eafcb4243" }, "pipfile-spec": 6, "requires": { @@ -140,14 +140,6 @@ "markers": "python_version >= '3.8'", "version": "==1.16.0" }, - "cfgv": { - "hashes": [ - "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", - "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560" - ], - "markers": "python_version >= '3.8'", - "version": "==3.4.0" - }, "charset-normalizer": { "hashes": [ "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", @@ -275,65 +267,6 @@ "markers": "python_version >= '3.6'", "version": "==0.3.0" }, - "coverage": { - "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==7.3.2" - }, "cron-descriptor": { "hashes": [ "sha256:b6ff4e3a988d7ca04a4ab150248e9f166fb7a5c828a85090e75bcc25aa93b4dd" @@ -377,13 +310,6 @@ "markers": "python_version >= '3.6'", "version": "==0.8.0rc2" }, - "distlib": { - "hashes": [ - "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057", - "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8" - ], - "version": "==0.3.7" - }, "django": { "hashes": [ "sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41", @@ -511,14 +437,6 @@ "markers": "python_version >= '3.8' and python_version < '4.0'", "version": "==2.2.0" }, - "filelock": { - "hashes": [ - "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", - "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c" - ], - "markers": "python_version >= '3.8'", - "version": "==3.13.1" - }, "gunicorn": { "hashes": [ "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0", @@ -528,14 +446,6 @@ "markers": "python_version >= '3.5'", "version": "==21.2.0" }, - "identify": { - "hashes": [ - "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75", - "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d" - ], - "markers": "python_version >= '3.8'", - "version": "==2.5.31" - }, "idna": { "hashes": [ "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", @@ -560,14 +470,6 @@ "markers": "python_version >= '3.8'", "version": "==5.3.2" }, - "nodeenv": { - "hashes": [ - "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2", - "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==1.8.0" - }, "oauthlib": { "hashes": [ "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", @@ -660,23 +562,6 @@ "markers": "python_version >= '3.8'", "version": "==10.1.0" }, - "platformdirs": { - "hashes": [ - "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3", - "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e" - ], - "markers": "python_version >= '3.7'", - "version": "==3.11.0" - }, - "pre-commit": { - "hashes": [ - "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32", - "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==3.5.0" - }, "prompt-toolkit": { "hashes": [ "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", @@ -791,7 +676,7 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.2" }, "python3-openid": { @@ -809,62 +694,6 @@ "index": "pypi", "version": "==2023.3.post1" }, - "pyyaml": { - "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", - "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", - "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", - "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", - "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", - "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", - "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", - "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", - "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", - "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", - "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", - "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", - "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", - "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", - "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", - "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", - "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", - "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", - "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", - "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", - "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", - "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", - "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", - "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", - "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", - "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", - "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", - "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", - "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", - "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", - "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", - "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", - "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", - "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", - "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", - "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", - "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", - "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", - "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", - "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0.1" - }, "redis": { "hashes": [ "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f", @@ -903,25 +732,17 @@ "django" ], "hashes": [ - "sha256:1cce906dc86afda1ecd22c4716b0c846639151a3c3b59e23826711c6525c5642", - "sha256:816aeb900a54bba2d9346bad8ffac2d258c4fa09271b95a6533a714e9000f074" + "sha256:76dd087f38062ac6c1e30ed6feb533ee0037ff9e709974802db7b5dbf2e5db21", + "sha256:e5d0d2b25931d88fa10986da59d941ac6037f742ab6ff2fce4143a27981d60c3" ], - "version": "==1.33.1" - }, - "setuptools": { - "hashes": [ - "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", - "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" - ], - "markers": "python_version >= '3.8'", - "version": "==68.2.2" + "version": "==1.34.0" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "social-auth-app-django": { @@ -980,14 +801,6 @@ "markers": "python_version >= '3.6'", "version": "==5.0.0" }, - "virtualenv": { - "hashes": [ - "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af", - "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381" - ], - "markers": "python_version >= '3.7'", - "version": "==20.24.6" - }, "wcwidth": { "hashes": [ "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223", @@ -1039,6 +852,14 @@ "markers": "python_version >= '3.8'", "version": "==23.10.1" }, + "cfgv": { + "hashes": [ + "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", + "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560" + ], + "markers": "python_version >= '3.8'", + "version": "==3.4.0" + }, "click": { "hashes": [ "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", @@ -1047,6 +868,72 @@ "markers": "python_version >= '3.7'", "version": "==8.1.7" }, + "coverage": { + "hashes": [ + "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", + "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", + "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", + "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", + "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", + "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", + "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", + "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", + "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", + "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", + "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", + "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", + "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", + "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", + "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", + "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", + "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", + "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", + "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", + "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", + "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", + "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", + "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", + "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", + "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", + "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", + "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", + "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", + "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", + "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", + "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", + "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", + "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", + "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", + "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", + "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", + "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", + "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", + "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", + "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", + "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", + "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", + "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", + "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", + "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", + "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", + "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", + "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", + "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", + "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", + "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", + "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==7.3.2" + }, + "distlib": { + "hashes": [ + "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057", + "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8" + ], + "version": "==0.3.7" + }, "eradicate": { "hashes": [ "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37", @@ -1054,6 +941,14 @@ ], "version": "==2.3.0" }, + "filelock": { + "hashes": [ + "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", + "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c" + ], + "markers": "python_version >= '3.8'", + "version": "==3.13.1" + }, "flake8": { "hashes": [ "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23", @@ -1132,6 +1027,14 @@ "markers": "python_version >= '3.8'", "version": "==0.28.0" }, + "identify": { + "hashes": [ + "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75", + "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d" + ], + "markers": "python_version >= '3.8'", + "version": "==2.5.31" + }, "isort": { "hashes": [ "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", @@ -1157,6 +1060,14 @@ "markers": "python_version >= '3.5'", "version": "==1.0.0" }, + "nodeenv": { + "hashes": [ + "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2", + "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==1.8.0" + }, "packaging": { "hashes": [ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", @@ -1190,6 +1101,15 @@ "markers": "python_version >= '3.7'", "version": "==3.11.0" }, + "pre-commit": { + "hashes": [ + "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32", + "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.5.0" + }, "pycodestyle": { "hashes": [ "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", @@ -1206,6 +1126,70 @@ "markers": "python_version >= '3.8'", "version": "==3.1.0" }, + "pyyaml": { + "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0.1" + }, + "setuptools": { + "hashes": [ + "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", + "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" + ], + "markers": "python_version >= '3.8'", + "version": "==68.2.2" + }, "tomli": { "hashes": [ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", @@ -1221,6 +1205,14 @@ ], "markers": "python_version < '3.11'", "version": "==4.8.0" + }, + "virtualenv": { + "hashes": [ + "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af", + "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381" + ], + "markers": "python_version >= '3.7'", + "version": "==20.24.6" } } } diff --git a/README.md b/README.md index b5f9769..6d1169e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Team Production System is an app for mentees to schedule one-on-one sessions wit - [Running Celery and Redis Locally](#run-celery-and-redis-locally) - [Run Locally via Docker Containers](#run-locally-via-docker-containers) - [Environment Variables](#environment-variables) +- [Adding Packages](#adding-packages) - [Testing](#testing) - [Linting](#linting) - [Submitting Code](#submitting-code) @@ -267,6 +268,29 @@ As long as your are running locally, use the value `dev`. 3. Save the .env file. + +## Adding Packages + +[Pipenv](https://pipenv.pypa.io/en/latest/) is a packaging tool for Python that solves some common problems associated with the typical development workflow using pip, virtualenv, and the requirements.txt. In addition to addressing some common issues, it consolidates and simplifies the development process to a single command line tool. + +When installing new packages, you first need to assess if they are needed for production and development or only development. + +For packages needed for both prod and dev, please run installation as follows: + +```bash +pipenv install +``` + +If the package is only needed for development, please run installation as follows: + +```bash +pipenv install --dev +``` +Providing the --dev argument will put the dependency in a special [dev-packages] location in the Pipfile. These development packages only get installed if you specify the --dev argument with pipenv install. + +If you update the Pipfile and are using Docker locally for development, please make sure to spin down your docker containers, copy over the Pipfile information to requirements.txt and then rebuild your containers. See [Run Locally via Docker Containers](#run-locally-via-docker-containers) for instructions. + + # Testing For testing this app, we are using [Django Test Case](https://docs.djangoproject.com/en/4.2/topics/testing/overview/) and [Django REST Framework API Test Case](https://www.django-rest-framework.org/api-guide/testing/#api-test-cases) along with [coverage.py](https://coverage.readthedocs.io/en/7.2.7/index.html) for test coverage reporting. diff --git a/team_production_system/admin.py b/team_production_system/admin.py index dd37b1b..0175694 100644 --- a/team_production_system/admin.py +++ b/team_production_system/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin + from .models import ( Availability, CustomUser, @@ -18,7 +19,6 @@ class SessionAdmin(admin.ModelAdmin): readonly_fields = ('created_at', 'modified_at') -# admin.site.register(UserAdmin) admin.site.register(CustomUser, UserAdmin) admin.site.register(Mentor) admin.site.register(Mentee) diff --git a/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py b/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py index c612378..2ff1b42 100644 --- a/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py +++ b/team_production_system/tests/end_to_end_tests/test_user_profile_patch_upload.py @@ -3,6 +3,7 @@ from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient + from team_production_system.models import CustomUser @@ -10,9 +11,7 @@ class UserProfilePatchTestCase(TestCase): def setUp(self): self.client = APIClient() self.user = CustomUser.objects.create( - username="baby_yoda", - email="grogu@mandalor.edu", - password="badpassword" + username='baby_yoda', email='grogu@mandalor.edu', password='badpassword' ) def test_new_user_gets_random_photo_assigned(self): @@ -22,14 +21,12 @@ def test_new_user_gets_random_photo_assigned(self): def test_profile_photo_uploaded_first_time(self): # mock photo file photo = SimpleUploadedFile( - "photo.jpg", - b"this is a photo", - content_type="image/jpeg" + 'photo.jpg', b'this is a photo', content_type='image/jpeg' ) # Make a PATCH request to update the user profile with the new photo - url = reverse("my-profile") + url = reverse('my-profile') self.client.force_authenticate(user=self.user) - response = self.client.patch(url, {"profile_photo": photo}) + response = self.client.patch(url, {'profile_photo': photo}) # Check that the response status code is 200 OK self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -43,15 +40,13 @@ def test_previous_file_deleted_when_new_photo_saved(self): old_photo_name = self.user.profile_photo.name # Create a new profile photo file new_photo = SimpleUploadedFile( - "new_photo.jpg", - b"this is a new photo", - content_type="image/jpeg" + 'new_photo.jpg', b'this is a new photo', content_type='image/jpeg' ) # Make a PATCH request to update the user profile with the new photo - url = reverse("my-profile") + url = reverse('my-profile') self.client.force_authenticate(user=self.user) - response = self.client.patch(url, {"profile_photo": new_photo}) + response = self.client.patch(url, {'profile_photo': new_photo}) # Check that the response status code is 200 OK self.assertEqual(response.status_code, status.HTTP_200_OK) From 4a3ba1e210bc0170d2f7764489605956fbcb583c Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Mon, 13 Nov 2023 14:37:50 -0500 Subject: [PATCH 15/18] fix(prepush): adjusts pre-commit to run tests in shell (#181) * docs(styling): tries possible option for code output * fix(prepush): reinstalling celery * fix(precommit): adjusting prepush test run * fix(prepush): adds shell for running tests * chore(linting): clean up * chore: remove empty file * docs: updates name of project * docs: remove renaming of app. --- .pre-commit-config.yaml | 2 +- Pipfile.lock | 23 +++++++++++++++++------ README.md | 19 ++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 46e572c..aef88e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: stages: [pre-push] - id: django-test name: 'Checking Tests' - entry: python manage.py test + entry: pipenv run python manage.py test always_run: true pass_filenames: false language: system diff --git a/Pipfile.lock b/Pipfile.lock index 657727e..ca59dfe 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -50,20 +50,20 @@ }, "boto3": { "hashes": [ - "sha256:85e2fa361ad3210d30800bad311688261f2673a9b301e0edab56463d89609761", - "sha256:d18688bc5d688decf3cc404430a3ac3ec317be653cdcfbc51104c01f38a66434" + "sha256:1a47e5b8faea527bb2a40d0cf58faf0d09b5a46cf5658e2c5729479af20c96b8", + "sha256:c0899e54df362bea0ae329da59b0a00e4be5e220e99dc764802ed83cdfc4285c" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.28.76" + "version": "==1.28.77" }, "botocore": { "hashes": [ - "sha256:479abb5a1ee03eb00faa1ea176bc595b2f46f7494777807681a9df45ed99ea18", - "sha256:74e0a4515d61b2860b24dc208ca89a68d79dc00147125d531746d3ba808822ad" + "sha256:4c5c9562b5d1fb8355314ddf37142edf3f6abd7526f4a68cc1b6cd79bdda48ec", + "sha256:509168151f8a0e1b8296031a7fc7822d59d027865d3baa86917682b311a74d26" ], "markers": "python_version >= '3.7'", - "version": "==1.31.76" + "version": "==1.31.77" }, "celery": { "hashes": [ @@ -736,6 +736,17 @@ "sha256:e5d0d2b25931d88fa10986da59d941ac6037f742ab6ff2fce4143a27981d60c3" ], "version": "==1.34.0" +<<<<<<< HEAD + }, + "setuptools": { + "hashes": [ + "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", + "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" + ], + "markers": "python_version >= '3.8'", + "version": "==68.2.2" +======= +>>>>>>> staging }, "six": { "hashes": [ diff --git a/README.md b/README.md index 6d1169e..4f482b1 100644 --- a/README.md +++ b/README.md @@ -359,11 +359,18 @@ Below are the commands and expected outputs: ```bash pre-commit install -pre-commit installed at .git/hooks/pre-commit +``` +`pre-commit installed at .git/hooks/pre-commit` +```bash pre-commit install --hook-type commit-msg -pre-commit installed at .git/hooks/commit-msg ``` +`pre-commit installed at .git/hooks/commit-msg` + +```bash +pre-commit install --hook-type pre-push +``` +`pre-commit installed at .git/hooks/pre-push` To run the pre-commit checks before making a commit, run the following command. @@ -373,11 +380,9 @@ pre-commit run --all-files If no files need changes, the output should look like this: -```bash -isort....................................................................Passed -black....................................................................Passed -flake8...................................................................Passed -``` +`isort....................................................................Passed` +`black....................................................................Passed` +`flake8...................................................................Passed` If isort or black catch any errors, they will automatically alter the files to fix them. This will prevent making a commit, and you will need to stage the new changes. From 4ef5959861c0f4f360ad59a1e5b840aca9a1947e Mon Sep 17 00:00:00 2001 From: Nathan Zeager <108411172+nzeager@users.noreply.github.com> Date: Fri, 17 Nov 2023 14:03:21 -0500 Subject: [PATCH 16/18] Fix/issue 194/filter archived sessions by start time (#202) * Hotfix build celery code * fix(views-archive-session-list): updated filter to use start_time instead of end_time --- team_production_system/views/archive_session_list.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/team_production_system/views/archive_session_list.py b/team_production_system/views/archive_session_list.py index 2b4de3c..48bdeb0 100644 --- a/team_production_system/views/archive_session_list.py +++ b/team_production_system/views/archive_session_list.py @@ -15,6 +15,7 @@ class ArchiveSessionView(generics.ListAPIView): def get_queryset(self): # Get sessions for the logged in user return Session.objects.filter( - Q(mentor__user=self.request.user) | Q(mentee__user=self.request.user), - end_time__lt=timezone.now(), + Q(mentor__user=self.request.user) | Q( + mentee__user=self.request.user), + start_time__lt=timezone.now(), ) From 3a0a438d0358554f48f01b82f6babf7673db1277 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Sat, 18 Nov 2023 10:50:55 -0500 Subject: [PATCH 17/18] fix(deploy): reinstalls piplock.file (#205) --- Pipfile.lock | 131 +++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 71 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index ca59dfe..8bbc16c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -18,11 +18,11 @@ "default": { "amqp": { "hashes": [ - "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2", - "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359" + "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637", + "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd" ], "markers": "python_version >= '3.6'", - "version": "==5.1.1" + "version": "==5.2.0" }, "asgiref": { "hashes": [ @@ -42,37 +42,37 @@ }, "billiard": { "hashes": [ - "sha256:0f50d6be051c6b2b75bfbc8bfd85af195c5739c281d3f5b86a5640c65563614a", - "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5" + "sha256:07aa978b308f334ff8282bd4a746e681b3513db5c9a514cbdd810cbbdc19714d", + "sha256:9a3c3184cb275aa17a732f93f65b20c525d3d9f253722d26a82194803ade5a2c" ], "markers": "python_version >= '3.7'", - "version": "==4.1.0" + "version": "==4.2.0" }, "boto3": { "hashes": [ - "sha256:1a47e5b8faea527bb2a40d0cf58faf0d09b5a46cf5658e2c5729479af20c96b8", - "sha256:c0899e54df362bea0ae329da59b0a00e4be5e220e99dc764802ed83cdfc4285c" + "sha256:6617ac176efb21485ebc3a058a3a97feb1300141421ae3d1809562c4cac1d5f9", + "sha256:f3024bba9ac980007ba7b5f28a9734d111fb5466e2426ac76c5edbd6dedd8db2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.28.77" + "version": "==1.29.2" }, "botocore": { "hashes": [ - "sha256:4c5c9562b5d1fb8355314ddf37142edf3f6abd7526f4a68cc1b6cd79bdda48ec", - "sha256:509168151f8a0e1b8296031a7fc7822d59d027865d3baa86917682b311a74d26" + "sha256:0e231524e9b72169fe0b8d9310f47072c245fb712778e0669f53f264f0e49536", + "sha256:a68a33193d8cd59e3b2142bff632e562afc02f9c4417e3dcc81a6e1b1f47148e" ], "markers": "python_version >= '3.7'", - "version": "==1.31.77" + "version": "==1.32.2" }, "celery": { "hashes": [ - "sha256:1e6ed40af72695464ce98ca2c201ad0ef8fd192246f6c9eac8bba343b980ad34", - "sha256:9023df6a8962da79eb30c0c84d5f4863d9793a466354cc931d7f72423996de28" + "sha256:30b75ac60fb081c2d9f8881382c148ed7c9052031a75a1e8743ff4b4b071f184", + "sha256:6b65d8dd5db499dd6190c45aa6398e171b99592f2af62c312f7391587feb5458" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.3.4" + "version": "==5.3.5" }, "certifi": { "hashes": [ @@ -337,12 +337,12 @@ }, "django-cors-headers": { "hashes": [ - "sha256:25aabc94d4837678c1edf442c7f68a5f5fd151f6767b0e0b01c61a2179d02711", - "sha256:bd36c7aea0d070e462f3383f0dc9ef717e5fdc2b10a99c98c285f16da84ffba2" + "sha256:0b1fd19297e37417fc9f835d39e45c8c642938ddba1acce0c1753d3edef04f36", + "sha256:0bf65ef45e606aff1994d35503e6b677c0b26cafff6506f8fd7187f3be840207" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.3.0" + "version": "==4.3.1" }, "django-environ": { "hashes": [ @@ -430,12 +430,12 @@ }, "djoser": { "hashes": [ - "sha256:4aa48502df870c8b5f07109ad4a749cc881c37bb5efa85cf5462ea695a0dca8c", - "sha256:7b24718cdc51b4294b0abcf6bf0ead11aa3ca83652e351dfb04b7b8b15afa3b0" + "sha256:9deb831a1c8781ceff325699e1407b4e1be8b4588e87071621d88ba31c09349f", + "sha256:efb91ad61e4d5b8d664db029b5947df9d34078289ef2680a1ab665e047144b74" ], "index": "pypi", "markers": "python_version >= '3.8' and python_version < '4.0'", - "version": "==2.2.0" + "version": "==2.2.2" }, "gunicorn": { "hashes": [ @@ -464,11 +464,11 @@ }, "kombu": { "hashes": [ - "sha256:0ba213f630a2cb2772728aef56ac6883dc3a2f13435e10048f6e97d48506dbbd", - "sha256:b753c9cfc9b1e976e637a7cbc1a65d446a22e45546cd996ea28f932082b7dc9e" + "sha256:0bb2e278644d11dea6272c17974a3dbb9688a949f3bb60aeb5b791329c44fadc", + "sha256:63bb093fc9bb80cfb3a0972336a5cec1fa7ac5f9ef7e8237c6bf8dda9469313e" ], "markers": "python_version >= '3.8'", - "version": "==5.3.2" + "version": "==5.3.4" }, "oauthlib": { "hashes": [ @@ -488,11 +488,11 @@ }, "phonenumbers": { "hashes": [ - "sha256:7abc66f38d92c3b9e827d597b5d590283ca3b05288d9fadea8bc0d6c8ad73c06", - "sha256:7dd66c57da00c0f373de83074e78d66a0801381cface4d010cfe07be2fa77fe5" + "sha256:4ae2d2e253a4752a269ae1147822b9aa500f14b2506a91f884e68b136901f128", + "sha256:7a57cceb8145d3099a0cda7a1f2581b6829936069224790be5de0adf14b39f13" ], "index": "pypi", - "version": "==8.13.24" + "version": "==8.13.25" }, "pilkit": { "hashes": [ @@ -564,11 +564,11 @@ }, "prompt-toolkit": { "hashes": [ - "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", - "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" + "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0", + "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.0.39" + "version": "==3.0.41" }, "psycopg2-binary": { "hashes": [ @@ -676,7 +676,7 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.8.2" }, "python3-openid": { @@ -732,28 +732,17 @@ "django" ], "hashes": [ - "sha256:76dd087f38062ac6c1e30ed6feb533ee0037ff9e709974802db7b5dbf2e5db21", - "sha256:e5d0d2b25931d88fa10986da59d941ac6037f742ab6ff2fce4143a27981d60c3" + "sha256:04e392db9a0d59bd49a51b9e3a92410ac5867556820465057c2ef89a38e953e9", + "sha256:a7865952701e46d38b41315c16c075367675c48d049b90a4cc2e41991ebc7efa" ], - "version": "==1.34.0" -<<<<<<< HEAD - }, - "setuptools": { - "hashes": [ - "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", - "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" - ], - "markers": "python_version >= '3.8'", - "version": "==68.2.2" -======= ->>>>>>> staging + "version": "==1.35.0" }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "social-auth-app-django": { @@ -806,18 +795,18 @@ }, "vine": { "hashes": [ - "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", - "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" + "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc", + "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0" ], "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "version": "==5.1.0" }, "wcwidth": { "hashes": [ - "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223", - "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8" + "sha256:390c7454101092a6a5e43baad8f83de615463af459201709556b6e4b1c861f97", + "sha256:aec5179002dd0f0d40c456026e74a729661c9d468e1ed64405e3a6c2176ca36f" ], - "version": "==0.2.9" + "version": "==0.2.10" }, "whitenoise": { "hashes": [ @@ -840,28 +829,28 @@ }, "black": { "hashes": [ - "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884", - "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916", - "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258", - "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1", - "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce", - "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d", - "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982", - "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7", - "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173", - "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9", - "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb", - "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad", - "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc", - "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0", - "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a", - "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe", - "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace", - "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69" + "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4", + "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b", + "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f", + "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07", + "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187", + "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6", + "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05", + "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06", + "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e", + "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5", + "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244", + "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f", + "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221", + "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055", + "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479", + "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394", + "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911", + "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==23.10.1" + "version": "==23.11.0" }, "cfgv": { "hashes": [ From 150ce56bc7b6c198554ff8ff6076d66d23350c70 Mon Sep 17 00:00:00 2001 From: Peri Sparr Date: Mon, 20 Nov 2023 07:22:25 -0500 Subject: [PATCH 18/18] docs(github): updates PR template (#207) --- .github/pull_request_template.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 97aad03..f2508c2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,10 +2,9 @@ ### **1. Targeted Issue** ### -*(The first step to a good solution is knowing the problem. Please link the issue here.)* +*(The first step to a good solution is knowing the problem. Please link the issue here. Make sure to say 'fixes' before the linked issue)* -Issue #... or -Ticket #... +This PR fixes Issue #... ### **2. Overview of Solution** ###