From bb5c96ec8060661732a2e0deb8cc945d501dfdb3 Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 18:58:30 +0200 Subject: [PATCH 01/15] :package: update Pillow --- Pipfile.lock | 236 ++++++++++++++++++++------------------------------- 1 file changed, 93 insertions(+), 143 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 8140415d..d9ae0d4c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -40,18 +40,18 @@ }, "boto3": { "hashes": [ - "sha256:970bd7b332e73d7b51077ed36772c634811b38c81b0cc6ed0f910e50d7ebadf8", - "sha256:cdd79a3a7bbe1f33a365f0acfcc75c4405b482b3eb9ce3f4e6b16c418e201ac3" + "sha256:91b34fac764c908f2e9553607fb0f2c56adc6b9df76e1f313dc190af512849c8", + "sha256:fc8511eda662d7b4b10bce55153cf65b89c41d86b65162bc0d15b89547d3d837" ], "index": "pypi", - "version": "==1.12.39" + "version": "==1.13.2" }, "botocore": { "hashes": [ - "sha256:94232b44e1540b7e043e220bd43f855400d0a243e926b26b3fb72994e971d518", - "sha256:e20ba56476b1031ce5ac8e22b59dabc75bd0e03231f124ed6b9ff99fe0b0c96b" + "sha256:102534a1d98a70bf6ecacf51c3cef2ef09587039aef064ad076bd2e36dd4c441", + "sha256:8ef5b178b76920f6f11169ad69ff30e297044aab4c34d1e92f26221faaa033ed" ], - "version": "==1.15.39" + "version": "==1.16.2" }, "certifi": { "hashes": [ @@ -69,10 +69,10 @@ }, "click": { "hashes": [ - "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", - "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "version": "==7.1.1" + "version": "==7.1.2" }, "colorama": { "hashes": [ @@ -152,12 +152,6 @@ ], "version": "==4.4.2" }, - "distlib": { - "hashes": [ - "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21" - ], - "version": "==0.3.0" - }, "django": { "hashes": [ "sha256:69897097095f336d5aeef45b4103dceae51c00afa6d3ae198a2a18e519791b7a", @@ -319,10 +313,10 @@ }, "dparse": { "hashes": [ - "sha256:14fed5efc5e98c0a81dfe100c4c2ea0a4c189104e9a9d18b5cfd342a163f97be", - "sha256:db349e53f6d03c8ee80606c49b35f515ed2ab287a8e1579e2b4bdf52b12b1530" + "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367", + "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994" ], - "version": "==0.5.0" + "version": "==0.5.1" }, "faker": { "hashes": [ @@ -339,13 +333,6 @@ "index": "pypi", "version": "==0.2.2" }, - "filelock": { - "hashes": [ - "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", - "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" - ], - "version": "==3.0.12" - }, "funcy": { "hashes": [ "sha256:75ee84c3b446f92e68a857c2267b15a1b49c631c9d5a87a5f063cd2d6761a5c4" @@ -354,17 +341,17 @@ }, "gitdb": { "hashes": [ - "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5", - "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a" + "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", + "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "version": "==4.0.4" + "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74", - "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d" + "sha256:864a47472548f3ba716ca202e034c1900f197c0fb3a08f641c20c3cafd15ed94", + "sha256:da3b2cf819974789da34f95ac218ef99f515a928685db141327c09b73dd69c09" ], - "version": "==3.1.1" + "version": "==3.1.2" }, "halo": { "hashes": [ @@ -381,14 +368,6 @@ ], "version": "==2.9" }, - "importlib-metadata": { - "hashes": [ - "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", - "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" - ], - "markers": "python_version < '3.8'", - "version": "==1.6.0" - }, "jmespath": { "hashes": [ "sha256:695cb76fa78a10663425d5b73ddc5714eb711157e52704d69be03b1a02ba4fec", @@ -454,29 +433,29 @@ }, "numpy": { "hashes": [ - "sha256:1598a6de323508cfeed6b7cd6c4efb43324f4692e20d1f76e1feec7f59013448", - "sha256:1b0ece94018ae21163d1f651b527156e1f03943b986188dd81bc7e066eae9d1c", - "sha256:2e40be731ad618cb4974d5ba60d373cdf4f1b8dcbf1dcf4d9dff5e212baf69c5", - "sha256:4ba59db1fcc27ea31368af524dcf874d9277f21fd2e1f7f1e2e0c75ee61419ed", - "sha256:59ca9c6592da581a03d42cc4e270732552243dc45e87248aa8d636d53812f6a5", - "sha256:5e0feb76849ca3e83dd396254e47c7dba65b3fa9ed3df67c2556293ae3e16de3", - "sha256:6d205249a0293e62bbb3898c4c2e1ff8a22f98375a34775a259a0523111a8f6c", - "sha256:6fcc5a3990e269f86d388f165a089259893851437b904f422d301cdce4ff25c8", - "sha256:82847f2765835c8e5308f136bc34018d09b49037ec23ecc42b246424c767056b", - "sha256:87902e5c03355335fc5992a74ba0247a70d937f326d852fc613b7f53516c0963", - "sha256:9ab21d1cb156a620d3999dd92f7d1c86824c622873841d6b080ca5495fa10fef", - "sha256:a1baa1dc8ecd88fb2d2a651671a84b9938461e8a8eed13e2f0a812a94084d1fa", - "sha256:a244f7af80dacf21054386539699ce29bcc64796ed9850c99a34b41305630286", - "sha256:a35af656a7ba1d3decdd4fae5322b87277de8ac98b7d9da657d9e212ece76a61", - "sha256:b1fe1a6f3a6f355f6c29789b5927f8bd4f134a4bd9a781099a7c4f66af8850f5", - "sha256:b5ad0adb51b2dee7d0ee75a69e9871e2ddfb061c73ea8bc439376298141f77f5", - "sha256:ba3c7a2814ec8a176bb71f91478293d633c08582119e713a0c5351c0f77698da", - "sha256:cd77d58fb2acf57c1d1ee2835567cd70e6f1835e32090538f17f8a3a99e5e34b", - "sha256:cdb3a70285e8220875e4d2bc394e49b4988bdb1298ffa4e0bd81b2f613be397c", - "sha256:deb529c40c3f1e38d53d5ae6cd077c21f1d49e13afc7936f7f868455e16b64a0", - "sha256:e7894793e6e8540dbeac77c87b489e331947813511108ae097f1715c018b8f3d" - ], - "version": "==1.18.2" + "sha256:00d7b54c025601e28f468953d065b9b121ddca7fff30bed7be082d3656dd798d", + "sha256:02ec9582808c4e48be4e93cd629c855e644882faf704bc2bd6bbf58c08a2a897", + "sha256:0e6f72f7bb08f2f350ed4408bb7acdc0daba637e73bce9f5ea2b207039f3af88", + "sha256:1be2e96314a66f5f1ce7764274327fd4fb9da58584eaff00b5a5221edefee7d6", + "sha256:2466fbcf23711ebc5daa61d28ced319a6159b260a18839993d871096d66b93f7", + "sha256:2b573fcf6f9863ce746e4ad00ac18a948978bb3781cffa4305134d31801f3e26", + "sha256:3f0dae97e1126f529ebb66f3c63514a0f72a177b90d56e4bce8a0b5def34627a", + "sha256:50fb72bcbc2cf11e066579cb53c4ca8ac0227abb512b6cbc1faa02d1595a2a5d", + "sha256:57aea170fb23b1fd54fa537359d90d383d9bf5937ee54ae8045a723caa5e0961", + "sha256:709c2999b6bd36cdaf85cf888d8512da7433529f14a3689d6e37ab5242e7add5", + "sha256:7d59f21e43bbfd9a10953a7e26b35b6849d888fc5a331fa84a2d9c37bd9fe2a2", + "sha256:904b513ab8fbcbdb062bed1ce2f794ab20208a1b01ce9bd90776c6c7e7257032", + "sha256:96dd36f5cdde152fd6977d1bbc0f0561bccffecfde63cd397c8e6033eb66baba", + "sha256:9933b81fecbe935e6a7dc89cbd2b99fea1bf362f2790daf9422a7bb1dc3c3085", + "sha256:bbcc85aaf4cd84ba057decaead058f43191cc0e30d6bc5d44fe336dc3d3f4509", + "sha256:dccd380d8e025c867ddcb2f84b439722cf1f23f3a319381eac45fd077dee7170", + "sha256:e22cd0f72fc931d6abc69dc7764484ee20c6a60b0d0fee9ce0426029b1c1bdae", + "sha256:ed722aefb0ebffd10b32e67f48e8ac4c5c4cf5d3a785024fdf0e9eb17529cd9d", + "sha256:efb7ac5572c9a57159cf92c508aad9f856f1cb8e8302d7fdb99061dbe52d712c", + "sha256:efdba339fffb0e80fcc19524e4fdbda2e2b5772ea46720c44eaac28096d60720", + "sha256:f22273dd6a403ed870207b853a856ff6327d5cbce7a835dfa0645b3fc00273ec" + ], + "version": "==1.18.4" }, "onesignal-sdk": { "hashes": [ @@ -514,31 +493,31 @@ }, "pillow": { "hashes": [ - "sha256:04a10558320eba9137d6a78ca6fc8f4a5801f1b971152938851dc4629d903579", - "sha256:0f89ddc77cf421b8cd34ae852309501458942bf370831b4a9b406156b599a14e", - "sha256:251e5618125ec12ac800265d7048f5857a8f8f1979db9ea3e11382e159d17f68", - "sha256:291bad7097b06d648222b769bbfcd61e40d0abdfe10df686d20ede36eb8162b6", - "sha256:2f0b52a08d175f10c8ea36685115681a484c55d24d0933f9fd911e4111c04144", - "sha256:3713386d1e9e79cea1c5e6aaac042841d7eef838cc577a3ca153c8bedf570287", - "sha256:433bbc2469a2351bea53666d97bb1eb30f0d56461735be02ea6b27654569f80f", - "sha256:4510c6b33277970b1af83c987277f9a08ec2b02cc20ac0f9234e4026136bb137", - "sha256:50a10b048f4dd81c092adad99fa5f7ba941edaf2f9590510109ac2a15e706695", - "sha256:670e58d3643971f4afd79191abd21623761c2ebe61db1c2cb4797d817c4ba1a7", - "sha256:6c1924ed7dbc6ad0636907693bbbdd3fdae1d73072963e71f5644b864bb10b4d", - "sha256:721c04d3c77c38086f1f95d1cd8df87f2f9a505a780acf8575912b3206479da1", - "sha256:8d5799243050c2833c2662b824dfb16aa98e408d2092805edea4300a408490e7", - "sha256:90cd441a1638ae176eab4d8b6b94ab4ec24b212ed4c3fbee2a6e74672481d4f8", - "sha256:a5dc9f28c0239ec2742d4273bd85b2aa84655be2564db7ad1eb8f64b1efcdc4c", - "sha256:b2f3e8cc52ecd259b94ca880fea0d15f4ebc6da2cd3db515389bb878d800270f", - "sha256:b7453750cf911785009423789d2e4e5393aae9cbb8b3f471dab854b85a26cb89", - "sha256:b99b2607b6cd58396f363b448cbe71d3c35e28f03e442ab00806463439629c2c", - "sha256:cd47793f7bc9285a88c2b5551d3f16a2ddd005789614a34c5f4a598c2a162383", - "sha256:d6bf085f6f9ec6a1724c187083b37b58a8048f86036d42d21802ed5d1fae4853", - "sha256:da737ab273f4d60ae552f82ad83f7cbd0e173ca30ca20b160f708c92742ee212", - "sha256:eb84e7e5b07ff3725ab05977ac56d5eeb0c510795aeb48e8b691491be3c5745b" - ], - "index": "pypi", - "version": "==7.1.1" + "sha256:04766c4930c174b46fd72d450674612ab44cca977ebbcc2dde722c6933290107", + "sha256:0e2a3bceb0fd4e0cb17192ae506d5f082b309ffe5fc370a5667959c9b2f85fa3", + "sha256:0f01e63c34f0e1e2580cc0b24e86a5ccbbfa8830909a52ee17624c4193224cd9", + "sha256:12e4bad6bddd8546a2f9771485c7e3d2b546b458ae8ff79621214119ac244523", + "sha256:1f694e28c169655c50bb89a3fa07f3b854d71eb47f50783621de813979ba87f3", + "sha256:3d25dd8d688f7318dca6d8cd4f962a360ee40346c15893ae3b95c061cdbc4079", + "sha256:4b02b9c27fad2054932e89f39703646d0c543f21d3cc5b8e05434215121c28cd", + "sha256:9744350687459234867cbebfe9df8f35ef9e1538f3e729adbd8fde0761adb705", + "sha256:a0b49960110bc6ff5fead46013bcb8825d101026d466f3a4de3476defe0fb0dd", + "sha256:ae2b270f9a0b8822b98655cb3a59cdb1bd54a34807c6c56b76dd2e786c3b7db3", + "sha256:b37bb3bd35edf53125b0ff257822afa6962649995cbdfde2791ddb62b239f891", + "sha256:b532bcc2f008e96fd9241177ec580829dee817b090532f43e54074ecffdcd97f", + "sha256:b67a6c47ed963c709ed24566daa3f95a18f07d3831334da570c71da53d97d088", + "sha256:b943e71c2065ade6fef223358e56c167fc6ce31c50bc7a02dd5c17ee4338e8ac", + "sha256:ccc9ad2460eb5bee5642eaf75a0438d7f8887d484490d5117b98edd7f33118b7", + "sha256:d23e2aa9b969cf9c26edfb4b56307792b8b374202810bd949effd1c6e11ebd6d", + "sha256:eaa83729eab9c60884f362ada982d3a06beaa6cc8b084cf9f76cae7739481dfa", + "sha256:ee94fce8d003ac9fd206496f2707efe9eadcb278d94c271f129ab36aa7181344", + "sha256:f455efb7a98557412dc6f8e463c1faf1f1911ec2432059fa3e582b6000fc90e2", + "sha256:f46e0e024346e1474083c729d50de909974237c72daca05393ee32389dabe457", + "sha256:f54be399340aa602066adb63a86a6a5d4f395adfdd9da2b9a0162ea808c7b276", + "sha256:f784aad988f12c80aacfa5b381ec21fd3f38f851720f652b9f33facc5101cf4d" + ], + "index": "pypi", + "version": "==7.1.2" }, "pinocchio": { "hashes": [ @@ -547,14 +526,6 @@ "index": "pypi", "version": "==0.4.2" }, - "pipenv": { - "hashes": [ - "sha256:56ad5f5cb48f1e58878e14525a6e3129d4306049cb76d2f6a3e95df0d5fc6330", - "sha256:7df8e33a2387de6f537836f48ac6fcd94eda6ed9ba3d5e3fd52e35b5bc7ff49e", - "sha256:a673e606e8452185e9817a987572b55360f4d28b50831ef3b42ac3cab3fee846" - ], - "version": "==2018.11.26" - }, "pyjwt": { "hashes": [ "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", @@ -579,11 +550,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:81822227f771e0cab235a2939f0f265954ac4763cafd806d845801c863bf372f", - "sha256:92b3123fb2d58a284f76cc92bfe4ee6c502c32ded73e8b051c4f6afc8b6751ed" + "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", + "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" ], "index": "pypi", - "version": "==0.12.0" + "version": "==0.13.0" }, "python-magic": { "hashes": [ @@ -595,10 +566,10 @@ }, "pytz": { "hashes": [ - "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", - "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", + "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" ], - "version": "==2019.3" + "version": "==2020.1" }, "pyyaml": { "hashes": [ @@ -619,11 +590,11 @@ }, "redis": { "hashes": [ - "sha256:0dcfb335921b88a850d461dc255ff4708294943322bd55de6cfd68972490ca1f", - "sha256:b205cffd05ebfd0a468db74f0eedbff8df1a7bfc47521516ade4692991bb0833" + "sha256:174101a3ce04560d716616290bb40e0a2af45d5844c8bd474c23fc5c52e7a46a", + "sha256:7378105cd8ea20c4edc49f028581e830c01ad5f00be851def0f4bc616a83cd89" ], "index": "pypi", - "version": "==3.4.1" + "version": "==3.5.0" }, "requests": { "hashes": [ @@ -634,10 +605,10 @@ }, "requests-file": { "hashes": [ - "sha256:75c175eed739270aec3c5279ffd74e6527dada275c5c0d76b5817e9c86bb7dea", - "sha256:8f04aa6201bacda0567e7ac7f677f1499b0fc76b22140c54bc06edf1ba92e2fa" + "sha256:07d74208d3389d01c38ab89ef403af0cfec63957d53a0081d8eca738d0247d8e", + "sha256:dfe5dae75c12481f68ba353183c53a65e6044c923e64c24b2209f6c7570ca953" ], - "version": "==1.4.3" + "version": "==1.5.1" }, "rest-framework-generic-relations": { "git": "https://github.com/Ian-Foote/rest-framework-generic-relations.git", @@ -652,10 +623,10 @@ }, "rq-scheduler": { "hashes": [ - "sha256:06038a42d33d653f89d534ba3bb95694b9d82b39fdd17c6ac6d9bf77d1acdefb", - "sha256:9f9f68d0a4749c83f023d903e148b81da2191229e25ac644a9ff9d6eac31bff4" + "sha256:de2e2754a05549dadbe7422d2d1fa5ad0c1d556280515af9c3b9c1eba0db5ddb", + "sha256:f19486671473eba42095163f2ae829d5dcb046dde01628233871ee830c1c3c2e" ], - "version": "==0.9.1" + "version": "==0.10.0" }, "s3transfer": { "hashes": [ @@ -666,11 +637,11 @@ }, "safety": { "hashes": [ - "sha256:05f77773bbab834502328b29ed013677aa53ed0c22b6e330aef7d2a7e1dfd838", - "sha256:3016631e0dd17193d6cf12e8ed1af92df399585e8ee0e4b1300d9e7e32b54903" + "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9", + "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087" ], "index": "pypi", - "version": "==1.8.7" + "version": "==1.9.0" }, "sentry-sdk": { "hashes": [ @@ -696,10 +667,10 @@ }, "smmap": { "hashes": [ - "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1", - "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911" + "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", + "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "version": "==3.0.2" + "version": "==3.0.4" }, "soupsieve": { "hashes": [ @@ -781,25 +752,11 @@ }, "urllib3": { "hashes": [ - "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", - "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" + "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", + "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" ], "markers": "python_version != '3.4'", - "version": "==1.25.8" - }, - "virtualenv": { - "hashes": [ - "sha256:00cfe8605fb97f5a59d52baab78e6070e72c12ca64f51151695407cc0eb8a431", - "sha256:c8364ec469084046c779c9a11ae6340094e8a0bf1d844330fc55c1cefe67c172" - ], - "version": "==20.0.17" - }, - "virtualenv-clone": { - "hashes": [ - "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", - "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" - ], - "version": "==0.5.4" + "version": "==1.25.9" }, "watchdog": { "hashes": [ @@ -814,13 +771,6 @@ ], "index": "pypi", "version": "==1.6.0" - }, - "zipp": { - "hashes": [ - "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", - "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" - ], - "version": "==3.1.0" } }, "develop": { @@ -842,10 +792,10 @@ }, "pytz": { "hashes": [ - "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", - "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", + "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" ], - "version": "==2019.3" + "version": "==2020.1" } } } From 135e3f78f1b02536a64bb90f56e5931349ad0ed2 Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 19:35:49 +0200 Subject: [PATCH 02/15] Revert ":package: update Pillow" This reverts commit bb5c96ec8060661732a2e0deb8cc945d501dfdb3. --- Pipfile.lock | 236 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 143 insertions(+), 93 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index d9ae0d4c..8140415d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -40,18 +40,18 @@ }, "boto3": { "hashes": [ - "sha256:91b34fac764c908f2e9553607fb0f2c56adc6b9df76e1f313dc190af512849c8", - "sha256:fc8511eda662d7b4b10bce55153cf65b89c41d86b65162bc0d15b89547d3d837" + "sha256:970bd7b332e73d7b51077ed36772c634811b38c81b0cc6ed0f910e50d7ebadf8", + "sha256:cdd79a3a7bbe1f33a365f0acfcc75c4405b482b3eb9ce3f4e6b16c418e201ac3" ], "index": "pypi", - "version": "==1.13.2" + "version": "==1.12.39" }, "botocore": { "hashes": [ - "sha256:102534a1d98a70bf6ecacf51c3cef2ef09587039aef064ad076bd2e36dd4c441", - "sha256:8ef5b178b76920f6f11169ad69ff30e297044aab4c34d1e92f26221faaa033ed" + "sha256:94232b44e1540b7e043e220bd43f855400d0a243e926b26b3fb72994e971d518", + "sha256:e20ba56476b1031ce5ac8e22b59dabc75bd0e03231f124ed6b9ff99fe0b0c96b" ], - "version": "==1.16.2" + "version": "==1.15.39" }, "certifi": { "hashes": [ @@ -69,10 +69,10 @@ }, "click": { "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" + "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", + "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" ], - "version": "==7.1.2" + "version": "==7.1.1" }, "colorama": { "hashes": [ @@ -152,6 +152,12 @@ ], "version": "==4.4.2" }, + "distlib": { + "hashes": [ + "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21" + ], + "version": "==0.3.0" + }, "django": { "hashes": [ "sha256:69897097095f336d5aeef45b4103dceae51c00afa6d3ae198a2a18e519791b7a", @@ -313,10 +319,10 @@ }, "dparse": { "hashes": [ - "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367", - "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994" + "sha256:14fed5efc5e98c0a81dfe100c4c2ea0a4c189104e9a9d18b5cfd342a163f97be", + "sha256:db349e53f6d03c8ee80606c49b35f515ed2ab287a8e1579e2b4bdf52b12b1530" ], - "version": "==0.5.1" + "version": "==0.5.0" }, "faker": { "hashes": [ @@ -333,6 +339,13 @@ "index": "pypi", "version": "==0.2.2" }, + "filelock": { + "hashes": [ + "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", + "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" + ], + "version": "==3.0.12" + }, "funcy": { "hashes": [ "sha256:75ee84c3b446f92e68a857c2267b15a1b49c631c9d5a87a5f063cd2d6761a5c4" @@ -341,17 +354,17 @@ }, "gitdb": { "hashes": [ - "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", - "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" + "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5", + "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a" ], - "version": "==4.0.5" + "version": "==4.0.4" }, "gitpython": { "hashes": [ - "sha256:864a47472548f3ba716ca202e034c1900f197c0fb3a08f641c20c3cafd15ed94", - "sha256:da3b2cf819974789da34f95ac218ef99f515a928685db141327c09b73dd69c09" + "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74", + "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d" ], - "version": "==3.1.2" + "version": "==3.1.1" }, "halo": { "hashes": [ @@ -368,6 +381,14 @@ ], "version": "==2.9" }, + "importlib-metadata": { + "hashes": [ + "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", + "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" + ], + "markers": "python_version < '3.8'", + "version": "==1.6.0" + }, "jmespath": { "hashes": [ "sha256:695cb76fa78a10663425d5b73ddc5714eb711157e52704d69be03b1a02ba4fec", @@ -433,29 +454,29 @@ }, "numpy": { "hashes": [ - "sha256:00d7b54c025601e28f468953d065b9b121ddca7fff30bed7be082d3656dd798d", - "sha256:02ec9582808c4e48be4e93cd629c855e644882faf704bc2bd6bbf58c08a2a897", - "sha256:0e6f72f7bb08f2f350ed4408bb7acdc0daba637e73bce9f5ea2b207039f3af88", - "sha256:1be2e96314a66f5f1ce7764274327fd4fb9da58584eaff00b5a5221edefee7d6", - "sha256:2466fbcf23711ebc5daa61d28ced319a6159b260a18839993d871096d66b93f7", - "sha256:2b573fcf6f9863ce746e4ad00ac18a948978bb3781cffa4305134d31801f3e26", - "sha256:3f0dae97e1126f529ebb66f3c63514a0f72a177b90d56e4bce8a0b5def34627a", - "sha256:50fb72bcbc2cf11e066579cb53c4ca8ac0227abb512b6cbc1faa02d1595a2a5d", - "sha256:57aea170fb23b1fd54fa537359d90d383d9bf5937ee54ae8045a723caa5e0961", - "sha256:709c2999b6bd36cdaf85cf888d8512da7433529f14a3689d6e37ab5242e7add5", - "sha256:7d59f21e43bbfd9a10953a7e26b35b6849d888fc5a331fa84a2d9c37bd9fe2a2", - "sha256:904b513ab8fbcbdb062bed1ce2f794ab20208a1b01ce9bd90776c6c7e7257032", - "sha256:96dd36f5cdde152fd6977d1bbc0f0561bccffecfde63cd397c8e6033eb66baba", - "sha256:9933b81fecbe935e6a7dc89cbd2b99fea1bf362f2790daf9422a7bb1dc3c3085", - "sha256:bbcc85aaf4cd84ba057decaead058f43191cc0e30d6bc5d44fe336dc3d3f4509", - "sha256:dccd380d8e025c867ddcb2f84b439722cf1f23f3a319381eac45fd077dee7170", - "sha256:e22cd0f72fc931d6abc69dc7764484ee20c6a60b0d0fee9ce0426029b1c1bdae", - "sha256:ed722aefb0ebffd10b32e67f48e8ac4c5c4cf5d3a785024fdf0e9eb17529cd9d", - "sha256:efb7ac5572c9a57159cf92c508aad9f856f1cb8e8302d7fdb99061dbe52d712c", - "sha256:efdba339fffb0e80fcc19524e4fdbda2e2b5772ea46720c44eaac28096d60720", - "sha256:f22273dd6a403ed870207b853a856ff6327d5cbce7a835dfa0645b3fc00273ec" - ], - "version": "==1.18.4" + "sha256:1598a6de323508cfeed6b7cd6c4efb43324f4692e20d1f76e1feec7f59013448", + "sha256:1b0ece94018ae21163d1f651b527156e1f03943b986188dd81bc7e066eae9d1c", + "sha256:2e40be731ad618cb4974d5ba60d373cdf4f1b8dcbf1dcf4d9dff5e212baf69c5", + "sha256:4ba59db1fcc27ea31368af524dcf874d9277f21fd2e1f7f1e2e0c75ee61419ed", + "sha256:59ca9c6592da581a03d42cc4e270732552243dc45e87248aa8d636d53812f6a5", + "sha256:5e0feb76849ca3e83dd396254e47c7dba65b3fa9ed3df67c2556293ae3e16de3", + "sha256:6d205249a0293e62bbb3898c4c2e1ff8a22f98375a34775a259a0523111a8f6c", + "sha256:6fcc5a3990e269f86d388f165a089259893851437b904f422d301cdce4ff25c8", + "sha256:82847f2765835c8e5308f136bc34018d09b49037ec23ecc42b246424c767056b", + "sha256:87902e5c03355335fc5992a74ba0247a70d937f326d852fc613b7f53516c0963", + "sha256:9ab21d1cb156a620d3999dd92f7d1c86824c622873841d6b080ca5495fa10fef", + "sha256:a1baa1dc8ecd88fb2d2a651671a84b9938461e8a8eed13e2f0a812a94084d1fa", + "sha256:a244f7af80dacf21054386539699ce29bcc64796ed9850c99a34b41305630286", + "sha256:a35af656a7ba1d3decdd4fae5322b87277de8ac98b7d9da657d9e212ece76a61", + "sha256:b1fe1a6f3a6f355f6c29789b5927f8bd4f134a4bd9a781099a7c4f66af8850f5", + "sha256:b5ad0adb51b2dee7d0ee75a69e9871e2ddfb061c73ea8bc439376298141f77f5", + "sha256:ba3c7a2814ec8a176bb71f91478293d633c08582119e713a0c5351c0f77698da", + "sha256:cd77d58fb2acf57c1d1ee2835567cd70e6f1835e32090538f17f8a3a99e5e34b", + "sha256:cdb3a70285e8220875e4d2bc394e49b4988bdb1298ffa4e0bd81b2f613be397c", + "sha256:deb529c40c3f1e38d53d5ae6cd077c21f1d49e13afc7936f7f868455e16b64a0", + "sha256:e7894793e6e8540dbeac77c87b489e331947813511108ae097f1715c018b8f3d" + ], + "version": "==1.18.2" }, "onesignal-sdk": { "hashes": [ @@ -493,31 +514,31 @@ }, "pillow": { "hashes": [ - "sha256:04766c4930c174b46fd72d450674612ab44cca977ebbcc2dde722c6933290107", - "sha256:0e2a3bceb0fd4e0cb17192ae506d5f082b309ffe5fc370a5667959c9b2f85fa3", - "sha256:0f01e63c34f0e1e2580cc0b24e86a5ccbbfa8830909a52ee17624c4193224cd9", - "sha256:12e4bad6bddd8546a2f9771485c7e3d2b546b458ae8ff79621214119ac244523", - "sha256:1f694e28c169655c50bb89a3fa07f3b854d71eb47f50783621de813979ba87f3", - "sha256:3d25dd8d688f7318dca6d8cd4f962a360ee40346c15893ae3b95c061cdbc4079", - "sha256:4b02b9c27fad2054932e89f39703646d0c543f21d3cc5b8e05434215121c28cd", - "sha256:9744350687459234867cbebfe9df8f35ef9e1538f3e729adbd8fde0761adb705", - "sha256:a0b49960110bc6ff5fead46013bcb8825d101026d466f3a4de3476defe0fb0dd", - "sha256:ae2b270f9a0b8822b98655cb3a59cdb1bd54a34807c6c56b76dd2e786c3b7db3", - "sha256:b37bb3bd35edf53125b0ff257822afa6962649995cbdfde2791ddb62b239f891", - "sha256:b532bcc2f008e96fd9241177ec580829dee817b090532f43e54074ecffdcd97f", - "sha256:b67a6c47ed963c709ed24566daa3f95a18f07d3831334da570c71da53d97d088", - "sha256:b943e71c2065ade6fef223358e56c167fc6ce31c50bc7a02dd5c17ee4338e8ac", - "sha256:ccc9ad2460eb5bee5642eaf75a0438d7f8887d484490d5117b98edd7f33118b7", - "sha256:d23e2aa9b969cf9c26edfb4b56307792b8b374202810bd949effd1c6e11ebd6d", - "sha256:eaa83729eab9c60884f362ada982d3a06beaa6cc8b084cf9f76cae7739481dfa", - "sha256:ee94fce8d003ac9fd206496f2707efe9eadcb278d94c271f129ab36aa7181344", - "sha256:f455efb7a98557412dc6f8e463c1faf1f1911ec2432059fa3e582b6000fc90e2", - "sha256:f46e0e024346e1474083c729d50de909974237c72daca05393ee32389dabe457", - "sha256:f54be399340aa602066adb63a86a6a5d4f395adfdd9da2b9a0162ea808c7b276", - "sha256:f784aad988f12c80aacfa5b381ec21fd3f38f851720f652b9f33facc5101cf4d" - ], - "index": "pypi", - "version": "==7.1.2" + "sha256:04a10558320eba9137d6a78ca6fc8f4a5801f1b971152938851dc4629d903579", + "sha256:0f89ddc77cf421b8cd34ae852309501458942bf370831b4a9b406156b599a14e", + "sha256:251e5618125ec12ac800265d7048f5857a8f8f1979db9ea3e11382e159d17f68", + "sha256:291bad7097b06d648222b769bbfcd61e40d0abdfe10df686d20ede36eb8162b6", + "sha256:2f0b52a08d175f10c8ea36685115681a484c55d24d0933f9fd911e4111c04144", + "sha256:3713386d1e9e79cea1c5e6aaac042841d7eef838cc577a3ca153c8bedf570287", + "sha256:433bbc2469a2351bea53666d97bb1eb30f0d56461735be02ea6b27654569f80f", + "sha256:4510c6b33277970b1af83c987277f9a08ec2b02cc20ac0f9234e4026136bb137", + "sha256:50a10b048f4dd81c092adad99fa5f7ba941edaf2f9590510109ac2a15e706695", + "sha256:670e58d3643971f4afd79191abd21623761c2ebe61db1c2cb4797d817c4ba1a7", + "sha256:6c1924ed7dbc6ad0636907693bbbdd3fdae1d73072963e71f5644b864bb10b4d", + "sha256:721c04d3c77c38086f1f95d1cd8df87f2f9a505a780acf8575912b3206479da1", + "sha256:8d5799243050c2833c2662b824dfb16aa98e408d2092805edea4300a408490e7", + "sha256:90cd441a1638ae176eab4d8b6b94ab4ec24b212ed4c3fbee2a6e74672481d4f8", + "sha256:a5dc9f28c0239ec2742d4273bd85b2aa84655be2564db7ad1eb8f64b1efcdc4c", + "sha256:b2f3e8cc52ecd259b94ca880fea0d15f4ebc6da2cd3db515389bb878d800270f", + "sha256:b7453750cf911785009423789d2e4e5393aae9cbb8b3f471dab854b85a26cb89", + "sha256:b99b2607b6cd58396f363b448cbe71d3c35e28f03e442ab00806463439629c2c", + "sha256:cd47793f7bc9285a88c2b5551d3f16a2ddd005789614a34c5f4a598c2a162383", + "sha256:d6bf085f6f9ec6a1724c187083b37b58a8048f86036d42d21802ed5d1fae4853", + "sha256:da737ab273f4d60ae552f82ad83f7cbd0e173ca30ca20b160f708c92742ee212", + "sha256:eb84e7e5b07ff3725ab05977ac56d5eeb0c510795aeb48e8b691491be3c5745b" + ], + "index": "pypi", + "version": "==7.1.1" }, "pinocchio": { "hashes": [ @@ -526,6 +547,14 @@ "index": "pypi", "version": "==0.4.2" }, + "pipenv": { + "hashes": [ + "sha256:56ad5f5cb48f1e58878e14525a6e3129d4306049cb76d2f6a3e95df0d5fc6330", + "sha256:7df8e33a2387de6f537836f48ac6fcd94eda6ed9ba3d5e3fd52e35b5bc7ff49e", + "sha256:a673e606e8452185e9817a987572b55360f4d28b50831ef3b42ac3cab3fee846" + ], + "version": "==2018.11.26" + }, "pyjwt": { "hashes": [ "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", @@ -550,11 +579,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", - "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" + "sha256:81822227f771e0cab235a2939f0f265954ac4763cafd806d845801c863bf372f", + "sha256:92b3123fb2d58a284f76cc92bfe4ee6c502c32ded73e8b051c4f6afc8b6751ed" ], "index": "pypi", - "version": "==0.13.0" + "version": "==0.12.0" }, "python-magic": { "hashes": [ @@ -566,10 +595,10 @@ }, "pytz": { "hashes": [ - "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", - "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" + "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", + "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" ], - "version": "==2020.1" + "version": "==2019.3" }, "pyyaml": { "hashes": [ @@ -590,11 +619,11 @@ }, "redis": { "hashes": [ - "sha256:174101a3ce04560d716616290bb40e0a2af45d5844c8bd474c23fc5c52e7a46a", - "sha256:7378105cd8ea20c4edc49f028581e830c01ad5f00be851def0f4bc616a83cd89" + "sha256:0dcfb335921b88a850d461dc255ff4708294943322bd55de6cfd68972490ca1f", + "sha256:b205cffd05ebfd0a468db74f0eedbff8df1a7bfc47521516ade4692991bb0833" ], "index": "pypi", - "version": "==3.5.0" + "version": "==3.4.1" }, "requests": { "hashes": [ @@ -605,10 +634,10 @@ }, "requests-file": { "hashes": [ - "sha256:07d74208d3389d01c38ab89ef403af0cfec63957d53a0081d8eca738d0247d8e", - "sha256:dfe5dae75c12481f68ba353183c53a65e6044c923e64c24b2209f6c7570ca953" + "sha256:75c175eed739270aec3c5279ffd74e6527dada275c5c0d76b5817e9c86bb7dea", + "sha256:8f04aa6201bacda0567e7ac7f677f1499b0fc76b22140c54bc06edf1ba92e2fa" ], - "version": "==1.5.1" + "version": "==1.4.3" }, "rest-framework-generic-relations": { "git": "https://github.com/Ian-Foote/rest-framework-generic-relations.git", @@ -623,10 +652,10 @@ }, "rq-scheduler": { "hashes": [ - "sha256:de2e2754a05549dadbe7422d2d1fa5ad0c1d556280515af9c3b9c1eba0db5ddb", - "sha256:f19486671473eba42095163f2ae829d5dcb046dde01628233871ee830c1c3c2e" + "sha256:06038a42d33d653f89d534ba3bb95694b9d82b39fdd17c6ac6d9bf77d1acdefb", + "sha256:9f9f68d0a4749c83f023d903e148b81da2191229e25ac644a9ff9d6eac31bff4" ], - "version": "==0.10.0" + "version": "==0.9.1" }, "s3transfer": { "hashes": [ @@ -637,11 +666,11 @@ }, "safety": { "hashes": [ - "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9", - "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087" + "sha256:05f77773bbab834502328b29ed013677aa53ed0c22b6e330aef7d2a7e1dfd838", + "sha256:3016631e0dd17193d6cf12e8ed1af92df399585e8ee0e4b1300d9e7e32b54903" ], "index": "pypi", - "version": "==1.9.0" + "version": "==1.8.7" }, "sentry-sdk": { "hashes": [ @@ -667,10 +696,10 @@ }, "smmap": { "hashes": [ - "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", - "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" + "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1", + "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911" ], - "version": "==3.0.4" + "version": "==3.0.2" }, "soupsieve": { "hashes": [ @@ -752,11 +781,25 @@ }, "urllib3": { "hashes": [ - "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", - "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" + "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", + "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" ], "markers": "python_version != '3.4'", - "version": "==1.25.9" + "version": "==1.25.8" + }, + "virtualenv": { + "hashes": [ + "sha256:00cfe8605fb97f5a59d52baab78e6070e72c12ca64f51151695407cc0eb8a431", + "sha256:c8364ec469084046c779c9a11ae6340094e8a0bf1d844330fc55c1cefe67c172" + ], + "version": "==20.0.17" + }, + "virtualenv-clone": { + "hashes": [ + "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", + "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" + ], + "version": "==0.5.4" }, "watchdog": { "hashes": [ @@ -771,6 +814,13 @@ ], "index": "pypi", "version": "==1.6.0" + }, + "zipp": { + "hashes": [ + "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", + "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" + ], + "version": "==3.1.0" } }, "develop": { @@ -792,10 +842,10 @@ }, "pytz": { "hashes": [ - "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", - "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" + "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", + "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" ], - "version": "==2020.1" + "version": "==2019.3" } } } From 03495fa8301d622c431fb2c90aa1cab60c7c69fe Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 20:33:54 +0200 Subject: [PATCH 03/15] :bug: jesus christ --- .ebextensions/ffmpeg.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ebextensions/ffmpeg.config b/.ebextensions/ffmpeg.config index f5cde3ad..714c7d9c 100644 --- a/.ebextensions/ffmpeg.config +++ b/.ebextensions/ffmpeg.config @@ -10,8 +10,8 @@ commands: 03-tar: command: "tar xvf /tmp/ffmpeg.tar.xz -C /opt/ffmpeg" 04-ln: - command: "if [[ ! -f /usr/bin/ffmpeg ]] ; then ln -sf /opt/ffmpeg/ffmpeg-4.2.1-amd64-static/ffmpeg /usr/bin/ffmpeg; fi" + command: "if [[ ! -f /usr/bin/ffmpeg ]] ; then ln -sf /opt/ffmpeg/ffmpeg-4.2.2-amd64-static/ffmpeg /usr/bin/ffmpeg; fi" 05-ln: - command: "if [[ ! -f /usr/bin/ffprobe ]] ; then ln -sf /opt/ffmpeg/ffmpeg-4.2.1-amd64-static/ffprobe /usr/bin/ffprobe; fi" + command: "if [[ ! -f /usr/bin/ffprobe ]] ; then ln -sf /opt/ffmpeg/ffmpeg-4.2.2-amd64-static/ffprobe /usr/bin/ffprobe; fi" 06-pecl: command: "if [ `pecl list | grep imagick` ] ; then pecl install -f imagick; fi" \ No newline at end of file From a1af80494c575a0b10474bfa87d42c4590e1d46b Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 21:12:26 +0200 Subject: [PATCH 04/15] :bug: revert django storages upgrade --- Pipfile | 2 +- Pipfile.lock | 244 +++++++++++++++++++---------------------------- requirements.txt | 2 +- 3 files changed, 99 insertions(+), 149 deletions(-) diff --git a/Pipfile b/Pipfile index 11e346dd..f9600075 100644 --- a/Pipfile +++ b/Pipfile @@ -22,7 +22,7 @@ nose-exclude = "*" mixer = "*" faker = "*" "boto3" = "*" -django-storages = "*" +django-storages = "==1.8" django-amazon-ses = "*" django-media-fixtures = "==0.0.3" django-modeltranslation = {git = "https://github.com/lifenautjoe/django-modeltranslation.git",ref = "551af9905961038badad9d9a16b2f47996f7685b"} diff --git a/Pipfile.lock b/Pipfile.lock index 8140415d..46849da5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "08e9aa637a9494fc6250c92d330dff771826b4a1783a2b8f483f9d548a23ae4c" + "sha256": "5fd3f2910644f657607e5fa06c14bbe11fa76414d18b8b43434a8f09b3b7ae7b" }, "pipfile-spec": 6, "requires": {}, @@ -40,18 +40,18 @@ }, "boto3": { "hashes": [ - "sha256:970bd7b332e73d7b51077ed36772c634811b38c81b0cc6ed0f910e50d7ebadf8", - "sha256:cdd79a3a7bbe1f33a365f0acfcc75c4405b482b3eb9ce3f4e6b16c418e201ac3" + "sha256:91b34fac764c908f2e9553607fb0f2c56adc6b9df76e1f313dc190af512849c8", + "sha256:fc8511eda662d7b4b10bce55153cf65b89c41d86b65162bc0d15b89547d3d837" ], "index": "pypi", - "version": "==1.12.39" + "version": "==1.13.2" }, "botocore": { "hashes": [ - "sha256:94232b44e1540b7e043e220bd43f855400d0a243e926b26b3fb72994e971d518", - "sha256:e20ba56476b1031ce5ac8e22b59dabc75bd0e03231f124ed6b9ff99fe0b0c96b" + "sha256:102534a1d98a70bf6ecacf51c3cef2ef09587039aef064ad076bd2e36dd4c441", + "sha256:8ef5b178b76920f6f11169ad69ff30e297044aab4c34d1e92f26221faaa033ed" ], - "version": "==1.15.39" + "version": "==1.16.2" }, "certifi": { "hashes": [ @@ -69,10 +69,10 @@ }, "click": { "hashes": [ - "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", - "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "version": "==7.1.1" + "version": "==7.1.2" }, "colorama": { "hashes": [ @@ -152,12 +152,6 @@ ], "version": "==4.4.2" }, - "distlib": { - "hashes": [ - "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21" - ], - "version": "==0.3.0" - }, "django": { "hashes": [ "sha256:69897097095f336d5aeef45b4103dceae51c00afa6d3ae198a2a18e519791b7a", @@ -295,11 +289,11 @@ }, "django-storages": { "hashes": [ - "sha256:3103991c2ee8cef8a2ff096709973ffe7106183d211a79f22cf855f33533d924", - "sha256:a59e9923cbce7068792f75344ed7727021ee4ac20f227cf17297d0d03d141e91" + "sha256:0a9b7e620e969fb0797523695329ed223bf540bbfdf6cd163b061fc11dab2d1c", + "sha256:9322ab74ba6371e2e0fccc350c741686ade829e43085597b26b07ae8955a0a00" ], "index": "pypi", - "version": "==1.9.1" + "version": "==1.8" }, "djangorestframework": { "hashes": [ @@ -319,10 +313,10 @@ }, "dparse": { "hashes": [ - "sha256:14fed5efc5e98c0a81dfe100c4c2ea0a4c189104e9a9d18b5cfd342a163f97be", - "sha256:db349e53f6d03c8ee80606c49b35f515ed2ab287a8e1579e2b4bdf52b12b1530" + "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367", + "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994" ], - "version": "==0.5.0" + "version": "==0.5.1" }, "faker": { "hashes": [ @@ -339,13 +333,6 @@ "index": "pypi", "version": "==0.2.2" }, - "filelock": { - "hashes": [ - "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", - "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836" - ], - "version": "==3.0.12" - }, "funcy": { "hashes": [ "sha256:75ee84c3b446f92e68a857c2267b15a1b49c631c9d5a87a5f063cd2d6761a5c4" @@ -354,17 +341,17 @@ }, "gitdb": { "hashes": [ - "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5", - "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a" + "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac", + "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9" ], - "version": "==4.0.4" + "version": "==4.0.5" }, "gitpython": { "hashes": [ - "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74", - "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d" + "sha256:864a47472548f3ba716ca202e034c1900f197c0fb3a08f641c20c3cafd15ed94", + "sha256:da3b2cf819974789da34f95ac218ef99f515a928685db141327c09b73dd69c09" ], - "version": "==3.1.1" + "version": "==3.1.2" }, "halo": { "hashes": [ @@ -381,14 +368,6 @@ ], "version": "==2.9" }, - "importlib-metadata": { - "hashes": [ - "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", - "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" - ], - "markers": "python_version < '3.8'", - "version": "==1.6.0" - }, "jmespath": { "hashes": [ "sha256:695cb76fa78a10663425d5b73ddc5714eb711157e52704d69be03b1a02ba4fec", @@ -454,29 +433,29 @@ }, "numpy": { "hashes": [ - "sha256:1598a6de323508cfeed6b7cd6c4efb43324f4692e20d1f76e1feec7f59013448", - "sha256:1b0ece94018ae21163d1f651b527156e1f03943b986188dd81bc7e066eae9d1c", - "sha256:2e40be731ad618cb4974d5ba60d373cdf4f1b8dcbf1dcf4d9dff5e212baf69c5", - "sha256:4ba59db1fcc27ea31368af524dcf874d9277f21fd2e1f7f1e2e0c75ee61419ed", - "sha256:59ca9c6592da581a03d42cc4e270732552243dc45e87248aa8d636d53812f6a5", - "sha256:5e0feb76849ca3e83dd396254e47c7dba65b3fa9ed3df67c2556293ae3e16de3", - "sha256:6d205249a0293e62bbb3898c4c2e1ff8a22f98375a34775a259a0523111a8f6c", - "sha256:6fcc5a3990e269f86d388f165a089259893851437b904f422d301cdce4ff25c8", - "sha256:82847f2765835c8e5308f136bc34018d09b49037ec23ecc42b246424c767056b", - "sha256:87902e5c03355335fc5992a74ba0247a70d937f326d852fc613b7f53516c0963", - "sha256:9ab21d1cb156a620d3999dd92f7d1c86824c622873841d6b080ca5495fa10fef", - "sha256:a1baa1dc8ecd88fb2d2a651671a84b9938461e8a8eed13e2f0a812a94084d1fa", - "sha256:a244f7af80dacf21054386539699ce29bcc64796ed9850c99a34b41305630286", - "sha256:a35af656a7ba1d3decdd4fae5322b87277de8ac98b7d9da657d9e212ece76a61", - "sha256:b1fe1a6f3a6f355f6c29789b5927f8bd4f134a4bd9a781099a7c4f66af8850f5", - "sha256:b5ad0adb51b2dee7d0ee75a69e9871e2ddfb061c73ea8bc439376298141f77f5", - "sha256:ba3c7a2814ec8a176bb71f91478293d633c08582119e713a0c5351c0f77698da", - "sha256:cd77d58fb2acf57c1d1ee2835567cd70e6f1835e32090538f17f8a3a99e5e34b", - "sha256:cdb3a70285e8220875e4d2bc394e49b4988bdb1298ffa4e0bd81b2f613be397c", - "sha256:deb529c40c3f1e38d53d5ae6cd077c21f1d49e13afc7936f7f868455e16b64a0", - "sha256:e7894793e6e8540dbeac77c87b489e331947813511108ae097f1715c018b8f3d" - ], - "version": "==1.18.2" + "sha256:00d7b54c025601e28f468953d065b9b121ddca7fff30bed7be082d3656dd798d", + "sha256:02ec9582808c4e48be4e93cd629c855e644882faf704bc2bd6bbf58c08a2a897", + "sha256:0e6f72f7bb08f2f350ed4408bb7acdc0daba637e73bce9f5ea2b207039f3af88", + "sha256:1be2e96314a66f5f1ce7764274327fd4fb9da58584eaff00b5a5221edefee7d6", + "sha256:2466fbcf23711ebc5daa61d28ced319a6159b260a18839993d871096d66b93f7", + "sha256:2b573fcf6f9863ce746e4ad00ac18a948978bb3781cffa4305134d31801f3e26", + "sha256:3f0dae97e1126f529ebb66f3c63514a0f72a177b90d56e4bce8a0b5def34627a", + "sha256:50fb72bcbc2cf11e066579cb53c4ca8ac0227abb512b6cbc1faa02d1595a2a5d", + "sha256:57aea170fb23b1fd54fa537359d90d383d9bf5937ee54ae8045a723caa5e0961", + "sha256:709c2999b6bd36cdaf85cf888d8512da7433529f14a3689d6e37ab5242e7add5", + "sha256:7d59f21e43bbfd9a10953a7e26b35b6849d888fc5a331fa84a2d9c37bd9fe2a2", + "sha256:904b513ab8fbcbdb062bed1ce2f794ab20208a1b01ce9bd90776c6c7e7257032", + "sha256:96dd36f5cdde152fd6977d1bbc0f0561bccffecfde63cd397c8e6033eb66baba", + "sha256:9933b81fecbe935e6a7dc89cbd2b99fea1bf362f2790daf9422a7bb1dc3c3085", + "sha256:bbcc85aaf4cd84ba057decaead058f43191cc0e30d6bc5d44fe336dc3d3f4509", + "sha256:dccd380d8e025c867ddcb2f84b439722cf1f23f3a319381eac45fd077dee7170", + "sha256:e22cd0f72fc931d6abc69dc7764484ee20c6a60b0d0fee9ce0426029b1c1bdae", + "sha256:ed722aefb0ebffd10b32e67f48e8ac4c5c4cf5d3a785024fdf0e9eb17529cd9d", + "sha256:efb7ac5572c9a57159cf92c508aad9f856f1cb8e8302d7fdb99061dbe52d712c", + "sha256:efdba339fffb0e80fcc19524e4fdbda2e2b5772ea46720c44eaac28096d60720", + "sha256:f22273dd6a403ed870207b853a856ff6327d5cbce7a835dfa0645b3fc00273ec" + ], + "version": "==1.18.4" }, "onesignal-sdk": { "hashes": [ @@ -514,31 +493,31 @@ }, "pillow": { "hashes": [ - "sha256:04a10558320eba9137d6a78ca6fc8f4a5801f1b971152938851dc4629d903579", - "sha256:0f89ddc77cf421b8cd34ae852309501458942bf370831b4a9b406156b599a14e", - "sha256:251e5618125ec12ac800265d7048f5857a8f8f1979db9ea3e11382e159d17f68", - "sha256:291bad7097b06d648222b769bbfcd61e40d0abdfe10df686d20ede36eb8162b6", - "sha256:2f0b52a08d175f10c8ea36685115681a484c55d24d0933f9fd911e4111c04144", - "sha256:3713386d1e9e79cea1c5e6aaac042841d7eef838cc577a3ca153c8bedf570287", - "sha256:433bbc2469a2351bea53666d97bb1eb30f0d56461735be02ea6b27654569f80f", - "sha256:4510c6b33277970b1af83c987277f9a08ec2b02cc20ac0f9234e4026136bb137", - "sha256:50a10b048f4dd81c092adad99fa5f7ba941edaf2f9590510109ac2a15e706695", - "sha256:670e58d3643971f4afd79191abd21623761c2ebe61db1c2cb4797d817c4ba1a7", - "sha256:6c1924ed7dbc6ad0636907693bbbdd3fdae1d73072963e71f5644b864bb10b4d", - "sha256:721c04d3c77c38086f1f95d1cd8df87f2f9a505a780acf8575912b3206479da1", - "sha256:8d5799243050c2833c2662b824dfb16aa98e408d2092805edea4300a408490e7", - "sha256:90cd441a1638ae176eab4d8b6b94ab4ec24b212ed4c3fbee2a6e74672481d4f8", - "sha256:a5dc9f28c0239ec2742d4273bd85b2aa84655be2564db7ad1eb8f64b1efcdc4c", - "sha256:b2f3e8cc52ecd259b94ca880fea0d15f4ebc6da2cd3db515389bb878d800270f", - "sha256:b7453750cf911785009423789d2e4e5393aae9cbb8b3f471dab854b85a26cb89", - "sha256:b99b2607b6cd58396f363b448cbe71d3c35e28f03e442ab00806463439629c2c", - "sha256:cd47793f7bc9285a88c2b5551d3f16a2ddd005789614a34c5f4a598c2a162383", - "sha256:d6bf085f6f9ec6a1724c187083b37b58a8048f86036d42d21802ed5d1fae4853", - "sha256:da737ab273f4d60ae552f82ad83f7cbd0e173ca30ca20b160f708c92742ee212", - "sha256:eb84e7e5b07ff3725ab05977ac56d5eeb0c510795aeb48e8b691491be3c5745b" - ], - "index": "pypi", - "version": "==7.1.1" + "sha256:04766c4930c174b46fd72d450674612ab44cca977ebbcc2dde722c6933290107", + "sha256:0e2a3bceb0fd4e0cb17192ae506d5f082b309ffe5fc370a5667959c9b2f85fa3", + "sha256:0f01e63c34f0e1e2580cc0b24e86a5ccbbfa8830909a52ee17624c4193224cd9", + "sha256:12e4bad6bddd8546a2f9771485c7e3d2b546b458ae8ff79621214119ac244523", + "sha256:1f694e28c169655c50bb89a3fa07f3b854d71eb47f50783621de813979ba87f3", + "sha256:3d25dd8d688f7318dca6d8cd4f962a360ee40346c15893ae3b95c061cdbc4079", + "sha256:4b02b9c27fad2054932e89f39703646d0c543f21d3cc5b8e05434215121c28cd", + "sha256:9744350687459234867cbebfe9df8f35ef9e1538f3e729adbd8fde0761adb705", + "sha256:a0b49960110bc6ff5fead46013bcb8825d101026d466f3a4de3476defe0fb0dd", + "sha256:ae2b270f9a0b8822b98655cb3a59cdb1bd54a34807c6c56b76dd2e786c3b7db3", + "sha256:b37bb3bd35edf53125b0ff257822afa6962649995cbdfde2791ddb62b239f891", + "sha256:b532bcc2f008e96fd9241177ec580829dee817b090532f43e54074ecffdcd97f", + "sha256:b67a6c47ed963c709ed24566daa3f95a18f07d3831334da570c71da53d97d088", + "sha256:b943e71c2065ade6fef223358e56c167fc6ce31c50bc7a02dd5c17ee4338e8ac", + "sha256:ccc9ad2460eb5bee5642eaf75a0438d7f8887d484490d5117b98edd7f33118b7", + "sha256:d23e2aa9b969cf9c26edfb4b56307792b8b374202810bd949effd1c6e11ebd6d", + "sha256:eaa83729eab9c60884f362ada982d3a06beaa6cc8b084cf9f76cae7739481dfa", + "sha256:ee94fce8d003ac9fd206496f2707efe9eadcb278d94c271f129ab36aa7181344", + "sha256:f455efb7a98557412dc6f8e463c1faf1f1911ec2432059fa3e582b6000fc90e2", + "sha256:f46e0e024346e1474083c729d50de909974237c72daca05393ee32389dabe457", + "sha256:f54be399340aa602066adb63a86a6a5d4f395adfdd9da2b9a0162ea808c7b276", + "sha256:f784aad988f12c80aacfa5b381ec21fd3f38f851720f652b9f33facc5101cf4d" + ], + "index": "pypi", + "version": "==7.1.2" }, "pinocchio": { "hashes": [ @@ -547,14 +526,6 @@ "index": "pypi", "version": "==0.4.2" }, - "pipenv": { - "hashes": [ - "sha256:56ad5f5cb48f1e58878e14525a6e3129d4306049cb76d2f6a3e95df0d5fc6330", - "sha256:7df8e33a2387de6f537836f48ac6fcd94eda6ed9ba3d5e3fd52e35b5bc7ff49e", - "sha256:a673e606e8452185e9817a987572b55360f4d28b50831ef3b42ac3cab3fee846" - ], - "version": "==2018.11.26" - }, "pyjwt": { "hashes": [ "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", @@ -579,11 +550,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:81822227f771e0cab235a2939f0f265954ac4763cafd806d845801c863bf372f", - "sha256:92b3123fb2d58a284f76cc92bfe4ee6c502c32ded73e8b051c4f6afc8b6751ed" + "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", + "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" ], "index": "pypi", - "version": "==0.12.0" + "version": "==0.13.0" }, "python-magic": { "hashes": [ @@ -595,10 +566,10 @@ }, "pytz": { "hashes": [ - "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", - "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", + "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" ], - "version": "==2019.3" + "version": "==2020.1" }, "pyyaml": { "hashes": [ @@ -619,11 +590,11 @@ }, "redis": { "hashes": [ - "sha256:0dcfb335921b88a850d461dc255ff4708294943322bd55de6cfd68972490ca1f", - "sha256:b205cffd05ebfd0a468db74f0eedbff8df1a7bfc47521516ade4692991bb0833" + "sha256:174101a3ce04560d716616290bb40e0a2af45d5844c8bd474c23fc5c52e7a46a", + "sha256:7378105cd8ea20c4edc49f028581e830c01ad5f00be851def0f4bc616a83cd89" ], "index": "pypi", - "version": "==3.4.1" + "version": "==3.5.0" }, "requests": { "hashes": [ @@ -634,10 +605,10 @@ }, "requests-file": { "hashes": [ - "sha256:75c175eed739270aec3c5279ffd74e6527dada275c5c0d76b5817e9c86bb7dea", - "sha256:8f04aa6201bacda0567e7ac7f677f1499b0fc76b22140c54bc06edf1ba92e2fa" + "sha256:07d74208d3389d01c38ab89ef403af0cfec63957d53a0081d8eca738d0247d8e", + "sha256:dfe5dae75c12481f68ba353183c53a65e6044c923e64c24b2209f6c7570ca953" ], - "version": "==1.4.3" + "version": "==1.5.1" }, "rest-framework-generic-relations": { "git": "https://github.com/Ian-Foote/rest-framework-generic-relations.git", @@ -652,10 +623,10 @@ }, "rq-scheduler": { "hashes": [ - "sha256:06038a42d33d653f89d534ba3bb95694b9d82b39fdd17c6ac6d9bf77d1acdefb", - "sha256:9f9f68d0a4749c83f023d903e148b81da2191229e25ac644a9ff9d6eac31bff4" + "sha256:de2e2754a05549dadbe7422d2d1fa5ad0c1d556280515af9c3b9c1eba0db5ddb", + "sha256:f19486671473eba42095163f2ae829d5dcb046dde01628233871ee830c1c3c2e" ], - "version": "==0.9.1" + "version": "==0.10.0" }, "s3transfer": { "hashes": [ @@ -666,11 +637,11 @@ }, "safety": { "hashes": [ - "sha256:05f77773bbab834502328b29ed013677aa53ed0c22b6e330aef7d2a7e1dfd838", - "sha256:3016631e0dd17193d6cf12e8ed1af92df399585e8ee0e4b1300d9e7e32b54903" + "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9", + "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087" ], "index": "pypi", - "version": "==1.8.7" + "version": "==1.9.0" }, "sentry-sdk": { "hashes": [ @@ -696,10 +667,10 @@ }, "smmap": { "hashes": [ - "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1", - "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911" + "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", + "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" ], - "version": "==3.0.2" + "version": "==3.0.4" }, "soupsieve": { "hashes": [ @@ -781,25 +752,11 @@ }, "urllib3": { "hashes": [ - "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", - "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" + "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", + "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" ], "markers": "python_version != '3.4'", - "version": "==1.25.8" - }, - "virtualenv": { - "hashes": [ - "sha256:00cfe8605fb97f5a59d52baab78e6070e72c12ca64f51151695407cc0eb8a431", - "sha256:c8364ec469084046c779c9a11ae6340094e8a0bf1d844330fc55c1cefe67c172" - ], - "version": "==20.0.17" - }, - "virtualenv-clone": { - "hashes": [ - "sha256:07e74418b7cc64f4fda987bf5bc71ebd59af27a7bc9e8a8ee9fd54b1f2390a27", - "sha256:665e48dd54c84b98b71a657acb49104c54e7652bce9c1c4f6c6976ed4c827a29" - ], - "version": "==0.5.4" + "version": "==1.25.9" }, "watchdog": { "hashes": [ @@ -814,13 +771,6 @@ ], "index": "pypi", "version": "==1.6.0" - }, - "zipp": { - "hashes": [ - "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", - "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" - ], - "version": "==3.1.0" } }, "develop": { @@ -842,10 +792,10 @@ }, "pytz": { "hashes": [ - "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", - "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", + "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" ], - "version": "==2019.3" + "version": "==2020.1" } } } diff --git a/requirements.txt b/requirements.txt index 671addaf..54811864 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,7 +30,7 @@ django-redis==4.11.0 django-replicated==2.7 django-rq-scheduler==1.1.3 django-rq==2.3.1 -django-storages==1.9.1 +django-storages==1.8 django==2.2.12 djangorestframework==3.11.0 docutils==0.15.2 From 6e33a4e54155b536e169a4dc392670c7e9fba138 Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 22:26:00 +0200 Subject: [PATCH 05/15] :bug: remove django-rq routes --- openbook/urls.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openbook/urls.py b/openbook/urls.py index d0c8936f..a7cd3364 100644 --- a/openbook/urls.py +++ b/openbook/urls.py @@ -450,7 +450,6 @@ urlpatterns = [ path('api/', include(api_patterns)), url('admin/', admin.site.urls), - path('django-rq/', include('django_rq.urls')), url('health/', Health.as_view(), name='health'), ] From e8a002eca6dfafab09d4b063c2ba55be36b2c535 Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 22:31:10 +0200 Subject: [PATCH 06/15] :bug: add missing worker for activity score --- .ebextensions/supervisord.config | 36 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/.ebextensions/supervisord.config b/.ebextensions/supervisord.config index f961b95c..427d4d2f 100644 --- a/.ebextensions/supervisord.config +++ b/.ebextensions/supervisord.config @@ -8,7 +8,7 @@ files: file=/opt/python/run/supervisor.sock ; (the path to the socket file) ;chmod=0700 ; socket file mode (default 0700) ;chown=nobody:nogroup ; socket file uid:gid owner - + [supervisord] logfile=/opt/python/log/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=10MB ; (max main logfile bytes b4 rotation;default 50MB) @@ -19,13 +19,13 @@ files: minprocs=200 ; (min. avail process descriptors;default 200) directory=/opt/python/current/app ; (default is not to cd during start) ;nocleanup=true ; (don not clean up tempfiles at start;default false) - + [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface - + [supervisorctl] serverurl=unix:///opt/python/run/supervisor.sock - + [program:httpd] command=/opt/python/bin/httpdlaunch stdout_logfile=/opt/python/log/django_stdout.log @@ -39,8 +39,8 @@ files: exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) killasgroup=false ; SIGKILL the UNIX process group (def false) redirect_stderr=false - - + + [program:rqworkerdefault] command=/bin/bash -c 'source /opt/python/current/env && source /opt/python/run/venv/bin/activate && python manage.py rqworker default' stdout_logfile=/opt/python/log/rqworkerdefault_stdout.log @@ -61,7 +61,7 @@ files: stopasgroup=true stopsignal=QUIT redirect_stderr=false - + [program:rqworkerhigh] command=/bin/bash -c 'source /opt/python/current/env && source /opt/python/run/venv/bin/activate && python manage.py rqworker high' stdout_logfile=/opt/python/log/rqworkerhigh_stdout.log @@ -81,7 +81,7 @@ files: stopasgroup=true stopsignal=QUIT redirect_stderr=false - + [program:rqworkerlow] command=/bin/bash -c 'source /opt/python/current/env && source /opt/python/run/venv/bin/activate && python manage.py rqworker low' stdout_logfile=/opt/python/log/rqworkerlow_stdout.log @@ -101,3 +101,23 @@ files: stopasgroup=true stopsignal=QUIT redirect_stderr=false + + [program:rqworkeractivityscore] + command=/bin/bash -c 'source /opt/python/current/env && source /opt/python/run/venv/bin/activate && python manage.py rqworker process-activity-score' + stdout_logfile=/opt/python/log/rqworkerlow_stdout.log + stderr_logfile=/opt/python/log/rqworkerlow_stderr.log + pidfile=/opt/python/run/rqworker_low + loglevel=info ; (log level;default info; others: debug,warn,trace) + user=nobody + group=nobody + numprocs=1 + directory=/opt/python/current/app + autostart=true + autorestart=unexpected + startsecs=1 ; number of secs prog must stay running (def. 1) + startretries=3 ; max # of serial start failures (default 3) + exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) + killasgroup=true ; SIGKILL the UNIX process group (def false) + stopasgroup=true + stopsignal=QUIT + redirect_stderr=false From 74bf84da250f6ee9e4a4376f9f88d56e6e0550f2 Mon Sep 17 00:00:00 2001 From: Joel Hernandez Date: Tue, 5 May 2020 22:32:31 +0200 Subject: [PATCH 07/15] :bug: add missing config on docker for activity scores --- .docker/scheduler/supervisord.conf | 14 ++++++++++++++ .docker/worker/supervisord.conf | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/.docker/scheduler/supervisord.conf b/.docker/scheduler/supervisord.conf index a7057d12..a3011aec 100644 --- a/.docker/scheduler/supervisord.conf +++ b/.docker/scheduler/supervisord.conf @@ -49,4 +49,18 @@ startretries = 3 ; max # of serial start failures (default 3) exitcodes = 0, 2 ; 'expected' exit codes for process (default 0, 2) killasgroup = true ; SIGKILL the UNIX process group (def false) stopasgroup = true +stopsignal = QUIT + +[program: rqscheduleractivityscore] +command = python manage.py rqscheduler --queue=process-activity-score +loglevel = info ; (log level;default info; others: debug, warn, trace) +numprocs = 1 +directory = /opt/okuna-api +autostart = true +autorestart = unexpected +startsecs = 1 ; number of secs prog must stay running (def. 1) +startretries = 3 ; max # of serial start failures (default 3) +exitcodes = 0, 2 ; 'expected' exit codes for process (default 0, 2) +killasgroup = true ; SIGKILL the UNIX process group (def false) +stopasgroup = true stopsignal = QUIT \ No newline at end of file diff --git a/.docker/worker/supervisord.conf b/.docker/worker/supervisord.conf index 6b5be544..46b26fd4 100644 --- a/.docker/worker/supervisord.conf +++ b/.docker/worker/supervisord.conf @@ -49,4 +49,18 @@ startretries = 3 ; max # of serial start failures (default 3) exitcodes = 0, 2 ; 'expected' exit codes for process (default 0, 2) killasgroup = true ; SIGKILL the UNIX process group (def false) stopasgroup = true +stopsignal = QUIT + +[program: rqworkeractivityscore] +command = python manage.py rqworker process-activity-score +loglevel = info ; (log level;default info; others: debug, warn, trace) +numprocs = 1 +directory = /opt/okuna-api +autostart = true +autorestart = unexpected +startsecs = 1 ; number of secs prog must stay running (def. 1) +startretries = 3 ; max # of serial start failures (default 3) +exitcodes = 0, 2 ; 'expected' exit codes for process (default 0, 2) +killasgroup = true ; SIGKILL the UNIX process group (def false) +stopasgroup = true stopsignal = QUIT \ No newline at end of file From c45313513cef191e7d34afec9a041383b31f2ed5 Mon Sep 17 00:00:00 2001 From: Shantanu Date: Thu, 14 May 2020 18:01:01 +0200 Subject: [PATCH 08/15] :wrench: change docker to 3.6 image to reflect aws --- .docker/api/Dockerfile | 2 +- .docker/scheduler/Dockerfile | 4 +-- .docker/worker/Dockerfile | 4 +-- Pipfile.lock | 63 ++++++++++++++++++------------------ 4 files changed, 36 insertions(+), 37 deletions(-) diff --git a/.docker/api/Dockerfile b/.docker/api/Dockerfile index e3d1b7df..5369afdf 100644 --- a/.docker/api/Dockerfile +++ b/.docker/api/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.7.3 +FROM python:3.6 RUN apt-get -y update && apt-get -y upgrade && apt-get install -y ffmpeg diff --git a/.docker/scheduler/Dockerfile b/.docker/scheduler/Dockerfile index 3647a89a..b5e84ad6 100644 --- a/.docker/scheduler/Dockerfile +++ b/.docker/scheduler/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.7.3 +FROM python:3.6 RUN apt-get -y update && apt-get -y upgrade && apt-get install -y ffmpeg && apt-get install -y supervisor @@ -21,4 +21,4 @@ RUN pip install -r requirements.txt VOLUME ["/opt/okuna-api"] -CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] \ No newline at end of file +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] diff --git a/.docker/worker/Dockerfile b/.docker/worker/Dockerfile index 86a5e0a2..2e6e50f5 100644 --- a/.docker/worker/Dockerfile +++ b/.docker/worker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.7.3 +FROM python:3.6 RUN apt-get -y update && apt-get -y upgrade && apt-get install -y ffmpeg && apt-get install -y supervisor @@ -21,4 +21,4 @@ RUN pip install -r /requirements.txt VOLUME ["/opt/okuna-api"] -CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] \ No newline at end of file +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] diff --git a/Pipfile.lock b/Pipfile.lock index 46849da5..fe22ec4e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -16,10 +16,10 @@ "default": { "appdirs": { "hashes": [ - "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", - "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", + "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" ], - "version": "==1.4.3" + "version": "==1.4.4" }, "bandit": { "hashes": [ @@ -40,18 +40,17 @@ }, "boto3": { "hashes": [ - "sha256:91b34fac764c908f2e9553607fb0f2c56adc6b9df76e1f313dc190af512849c8", - "sha256:fc8511eda662d7b4b10bce55153cf65b89c41d86b65162bc0d15b89547d3d837" + "sha256:06dd5d0f2ed3570f60eab04b9f04d229ff980b55102447481992756efe268639" ], "index": "pypi", - "version": "==1.13.2" + "version": "==1.13.9" }, "botocore": { "hashes": [ - "sha256:102534a1d98a70bf6ecacf51c3cef2ef09587039aef064ad076bd2e36dd4c441", - "sha256:8ef5b178b76920f6f11169ad69ff30e297044aab4c34d1e92f26221faaa033ed" + "sha256:8743cd10500b6c4c4d9423d3aa2905ed886fea2bd4bb7c8eff6e6c08283c9ab9", + "sha256:d82f34844f9fc64d51b46046eed1f98fc367897832e5c4734ce58c0e17e7188f" ], - "version": "==1.16.2" + "version": "==1.16.9" }, "certifi": { "hashes": [ @@ -235,11 +234,11 @@ }, "django-ordered-model": { "hashes": [ - "sha256:0931f498008f91a00a32c4e0ae08a662ef608a1092bf6e6ec9af9b1a83f08acf", - "sha256:abf0d963f7e607a994baf6bc300e50af647b3d243c3e592c6cc8f8b924b6d427" + "sha256:29af6624cf3505daaf0df00e2df1d0726dd777b95e08f304d5ad0264092aa934", + "sha256:d867166ed4dd12501139e119cbbc5b4d19798a3e72740aef0af4879ba97102cf" ], "index": "pypi", - "version": "==3.3.0" + "version": "==3.4.1" }, "django-positions": { "hashes": [ @@ -273,11 +272,11 @@ }, "django-rq": { "hashes": [ - "sha256:060bece17912c4188fc3166e79c8244dc0608fbacc68e1069a47ceb91759ffcf", - "sha256:70e4e4a6566c0c1449a2f08ad74865a2045d74659da63aeea66681015ae1bbdb" + "sha256:ee9aefba814ae00b6d6a566ed0cd2a0a090e0e42d90bb9c4f1c70d3cacb47a52", + "sha256:f0bd7ac3b8b4b4abb161646e80a8751c81664beaa810e92fdbcf9fb3e7d72727" ], "index": "pypi", - "version": "==2.3.1" + "version": "==2.3.2" }, "django-rq-scheduler": { "hashes": [ @@ -328,10 +327,10 @@ }, "ffmpy": { "hashes": [ - "sha256:65abdddfa2561bb86b6c9ecfced53c7a15ea5080db4ddad08da7de5a348929f1" + "sha256:c52a86f530f1caefddc15b50193f86d1bfe009855893b06e683d8a9445af99fb" ], "index": "pypi", - "version": "==0.2.2" + "version": "==0.2.3" }, "funcy": { "hashes": [ @@ -370,10 +369,10 @@ }, "jmespath": { "hashes": [ - "sha256:695cb76fa78a10663425d5b73ddc5714eb711157e52704d69be03b1a02ba4fec", - "sha256:cca55c8d153173e21baa59983015ad0daf603f9cb799904ff057bfb8ff8dc2d9" + "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9", + "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f" ], - "version": "==0.9.5" + "version": "==0.10.0" }, "langdetect": { "hashes": [ @@ -558,11 +557,11 @@ }, "python-magic": { "hashes": [ - "sha256:f2674dcfad52ae6c49d4803fa027809540b130db1dec928cfbb9240316831375", - "sha256:f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5" + "sha256:356efa93c8899047d1eb7d3eb91e871ba2f5b1376edbaf4cc305e3c872207355", + "sha256:b757db2a5289ea3f1ced9e60f072965243ea43a2221430048fd8cacab17be0ce" ], "index": "pypi", - "version": "==0.4.15" + "version": "==0.4.18" }, "pytz": { "hashes": [ @@ -590,11 +589,11 @@ }, "redis": { "hashes": [ - "sha256:174101a3ce04560d716616290bb40e0a2af45d5844c8bd474c23fc5c52e7a46a", - "sha256:7378105cd8ea20c4edc49f028581e830c01ad5f00be851def0f4bc616a83cd89" + "sha256:6e9d2722a95d10ddf854596e66516d316d99c6a483e5db3b35c34e1158b2bfa1", + "sha256:a5b0e25890d216d8189636742c50ab992e42eea699bcc1b08cc2d6bf3adff52a" ], "index": "pypi", - "version": "==3.5.0" + "version": "==3.5.1" }, "requests": { "hashes": [ @@ -616,10 +615,10 @@ }, "rq": { "hashes": [ - "sha256:49c9149fa9301f98d918f3042f36bed4252d37193d222a1ce8b0e25886442377", - "sha256:c3e65a8ba5e59287308f23679f7fe729b9380531e4f6cdabb2dee99b82834811" + "sha256:c88623cd7528fad8620ee7a2d793493b85b63855f74a2da28c14671bab34a161", + "sha256:efabd10f27ef45414fc3e5f592110f699811b3ab9993ac40d78e87656423288a" ], - "version": "==1.3.0" + "version": "==1.4.0" }, "rq-scheduler": { "hashes": [ @@ -730,10 +729,10 @@ }, "toml": { "hashes": [ - "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", - "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", + "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" ], - "version": "==0.10.0" + "version": "==0.10.1" }, "uritools": { "hashes": [ From a80de8f3efed08041e88310883cae959c775d7fa Mon Sep 17 00:00:00 2001 From: Shantanu Date: Thu, 14 May 2020 18:01:32 +0200 Subject: [PATCH 09/15] :recycle: remove logging and extra db refresh in job --- openbook_posts/jobs.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/openbook_posts/jobs.py b/openbook_posts/jobs.py index bd665cc5..82dec3f1 100644 --- a/openbook_posts/jobs.py +++ b/openbook_posts/jobs.py @@ -87,12 +87,6 @@ def _process_community_activity_score_reaction_deleted(community, post_reaction_ community.activity_score = F('activity_score') - settings.ACTIVITY_UNIQUE_REACTION_WEIGHT community.save() - community.refresh_from_db() - if community.activity_score < Decimal(0.0): - logger.info('Community activity score for community with id {0} ' - 'went below zero while processing delete reaction with id {1}'.format( - community.pk, post_reaction_id)) - def process_activity_score_post_reaction(post_id, post_reaction_id): """ @@ -136,11 +130,6 @@ def process_activity_score_post_reaction(post_id, post_reaction_id): post.activity_score = F('activity_score') + settings.ACTIVITY_UNIQUE_REACTION_WEIGHT post.save() - post.refresh_from_db() - - if post.activity_score < Decimal(0.0): - logger.info('Post activity score for post with id {0} ' - 'went below zero while processing reaction with id {1}'.format(post_id, post_reaction_id)) logger.info('Processed activity score for reaction of post with id: %d' % post_id) @@ -188,12 +177,6 @@ def _process_community_activity_score_comment_deleted(community, default_scheduler.cancel(unique_comment_job_id) community.save() - community.refresh_from_db() - if community.activity_score < Decimal(0.0): - logger.info('Community activity score for community with id {0} ' - 'went below zero while processing delete comment with id {1}'.format( - community.pk, post_comment_id)) - def _process_community_activity_score_comment_added(community, post_id, @@ -280,10 +263,6 @@ def process_activity_score_post_comment(post_id, post_comment_id, post_commenter _process_post_activity_score_comment_added(post, commenter_comments_count) post.save() - post.refresh_from_db() - if post.activity_score < Decimal(0.0): - logger.info('Post activity score for post with id {0} ' - 'went below zero while processing comment with id {1}'.format(post_id, post_comment_id)) logger.info('Processed activity score for comment with id: %d' % post_comment_id) @@ -338,12 +317,6 @@ def _process_community_activity_score_post_deleted(post_id, post_creator_id, default_scheduler.cancel(unique_post_job_id) community.save() - community.refresh_from_db() - if community.activity_score < Decimal(0.0): - logger.info('Community activity score for community with id {0} ' - 'went below zero while processing delete post with id {1}'.format( - community.pk, post_id)) - def process_community_activity_score_post(post_id, post_creator_id, post_community_id): """ From 3996ec5410f9dd0b653814fd0cdc2e40b705b591 Mon Sep 17 00:00:00 2001 From: Shantanu Date: Fri, 15 May 2020 12:38:00 +0200 Subject: [PATCH 10/15] :bug: fix chunked queryset import --- openbook_common/utils/helpers.py | 23 +++++++++++++++++++++++ openbook_posts/jobs.py | 24 ------------------------ 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/openbook_common/utils/helpers.py b/openbook_common/utils/helpers.py index 19478b46..ad6bd1be 100644 --- a/openbook_common/utils/helpers.py +++ b/openbook_common/utils/helpers.py @@ -143,3 +143,26 @@ def write_in_memory_file_to_disk(in_memory_file): tmp_file.seek(0) tmp_file.close() return tmp_file + + +def chunked_queryset_iterator(queryset, size, *, ordering=('id',)): + """ + Split a queryset into chunks. + This can be used instead of `queryset.iterator()`, + so `.prefetch_related()` also works + Note:: + The ordering must uniquely identify the object, + and be in the same order (ASC/DESC). See https://github.com/photocrowd/django-cursor-pagination + """ + pager = CursorPaginator(queryset, ordering) + after = None + while True: + page = pager.page(after=after, first=size) + if page: + yield from page.items + else: + return + if not page.has_next: + break + # take last item, next page starts after this. + after = pager.cursor(instance=page[-1]) diff --git a/openbook_posts/jobs.py b/openbook_posts/jobs.py index 82dec3f1..812a1d27 100644 --- a/openbook_posts/jobs.py +++ b/openbook_posts/jobs.py @@ -1,5 +1,4 @@ from django.utils import timezone -from decimal import Decimal from django_rq import job, get_scheduler, get_queue from openbook_common.utils.helpers import chunked_queryset_iterator @@ -639,26 +638,3 @@ def clean_trending_posts(): # delete posts TrendingPost.objects.filter(id__in=direct_removable_delete_ids).delete() - - -def _chunked_queryset_iterator(queryset, size, *, ordering=('id',)): - """ - Split a queryset into chunks. - This can be used instead of `queryset.iterator()`, - so `.prefetch_related()` also works - Note:: - The ordering must uniquely identify the object, - and be in the same order (ASC/DESC). See https://github.com/photocrowd/django-cursor-pagination - """ - pager = CursorPaginator(queryset, ordering) - after = None - while True: - page = pager.page(after=after, first=size) - if page: - yield from page.items - else: - return - if not page.has_next: - break - # take last item, next page starts after this. - after = pager.cursor(instance=page[-1]) From 51bd225bb018db281a86168c9b39ba4fba863f29 Mon Sep 17 00:00:00 2001 From: Shantanu Date: Fri, 15 May 2020 13:04:39 +0200 Subject: [PATCH 11/15] :bug: fix incorrect merge --- openbook/settings.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/openbook/settings.py b/openbook/settings.py index ea1626d7..c2db8308 100644 --- a/openbook/settings.py +++ b/openbook/settings.py @@ -19,6 +19,7 @@ from dotenv import load_dotenv, find_dotenv from sentry_sdk.integrations.django import DjangoIntegration from django_replicated.settings import * +from decimal import Decimal, getcontext # Logging config from sentry_sdk.integrations.rq import RqIntegration @@ -177,6 +178,8 @@ REDIS_RQ_DEFAULT_JOBS_CACHE_LOCATION = '%(redis_location)s/%(db)d' % {'redis_location': REDIS_LOCATION, 'db': 1} REDIS_RQ_HIGH_JOBS_CACHE_LOCATION = '%(redis_location)s/%(db)d' % {'redis_location': REDIS_LOCATION, 'db': 2} REDIS_RQ_LOW_JOBS_CACHE_LOCATION = '%(redis_location)s/%(db)d' % {'redis_location': REDIS_LOCATION, 'db': 3} +REDIS_ACTIVITY_SCORES_JOBS_CACHE_LOCATION = '%(redis_location)s/%(db)d' % { + 'redis_location': REDIS_LOCATION, 'db': 4} CACHES = { 'default': { @@ -211,6 +214,14 @@ }, "KEY_PREFIX": "ob-api-rq-low-job-" }, + 'activity-score-jobs': { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": REDIS_ACTIVITY_SCORES_JOBS_CACHE_LOCATION, + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient" + }, + "KEY_PREFIX": "ob-api-actvty-score-job-" + }, } CACHEOPS_REDIS_DB = int(os.environ.get('CACHEOPS_REDIS_DB', '1')) @@ -236,6 +247,9 @@ 'low': { 'USE_REDIS_CACHE': 'rq-low-jobs', }, + 'process-activity-score': { + 'USE_REDIS_CACHE': 'activity-score-jobs', + }, } if IS_BUILD: @@ -527,7 +541,26 @@ MIN_UNIQUE_TOP_POST_REACTIONS_COUNT = int(os.environ.get('MIN_UNIQUE_TOP_POST_REACTIONS_COUNT', '5')) MIN_UNIQUE_TOP_POST_COMMENTS_COUNT = int(os.environ.get('MIN_UNIQUE_TOP_POST_COMMENTS_COUNT', '5')) -MIN_UNIQUE_TRENDING_POST_REACTIONS_COUNT = int(os.environ.get('MIN_UNIQUE_TRENDING_POST_REACTIONS_COUNT', '5')) + +# for activity score, set decimal precision to 10 +getcontext().prec = 10 + +MIN_ACTIVITY_SCORE_FOR_POST_TRENDING = Decimal((os.environ.get('MIN_ACTIVITY_SCORE_FOR_POST_TRENDING', 0.002))) +MIN_ACTIVITY_SCORE_FOR_COMMUNITY_TRENDING = Decimal((os.environ.get('MIN_ACTIVITY_SCORE_FOR_COMMUNITY_TRENDING', 0.002))) +ACTIVITY_ATOMIC_WEIGHT = Decimal((os.environ.get('ACTIVITY_ATOMIC_WEIGHT', 0.001))) + +ACTIVITY_UNIQUE_REACTION_MULTIPLIER = int(os.environ.get('ACTIVITY_UNIQUE_REACTION_MULTIPLIER', 1)) +ACTIVITY_UNIQUE_COMMENT_MULTIPLIER = int(os.environ.get('ACTIVITY_UNIQUE_COMMENT_MULTIPLIER', 1)) +ACTIVITY_COUNT_COMMENTS_MULTIPLIER = int(os.environ.get('ACTIVITY_COUNT_COMMENTS_MULTIPLIER', 1)) +ACTIVITY_UNIQUE_POST_MULTIPLIER = int(os.environ.get('ACTIVITY_UNIQUE_POST_MULTIPLIER', 1)) +ACTIVITY_COUNT_POSTS_MULTIPLIER = int(os.environ.get('ACTIVITY_COUNT_POSTS_MULTIPLIER', 1)) + +ACTIVITY_UNIQUE_REACTION_WEIGHT = Decimal((ACTIVITY_ATOMIC_WEIGHT * ACTIVITY_UNIQUE_REACTION_MULTIPLIER)) +ACTIVITY_UNIQUE_COMMENT_WEIGHT = Decimal((ACTIVITY_ATOMIC_WEIGHT * ACTIVITY_UNIQUE_COMMENT_MULTIPLIER)) +ACTIVITY_COUNT_COMMENTS_WEIGHT = Decimal((ACTIVITY_ATOMIC_WEIGHT * ACTIVITY_COUNT_COMMENTS_MULTIPLIER)) +ACTIVITY_UNIQUE_POST_WEIGHT = Decimal((ACTIVITY_ATOMIC_WEIGHT * ACTIVITY_UNIQUE_POST_MULTIPLIER)) +ACTIVITY_COUNT_POSTS_WEIGHT = Decimal((ACTIVITY_ATOMIC_WEIGHT * ACTIVITY_COUNT_POSTS_MULTIPLIER)) +ACTIVITY_SCORE_EXPIRY_IN_HOURS = int(os.environ.get('ACTIVITY_SCORE_EXPIRY_IN_HOURS', 12)) # Email Config @@ -550,7 +583,7 @@ OS_TRANSLATION_STRATEGY_NAME = 'testing' MIN_UNIQUE_TOP_POST_REACTIONS_COUNT = 1 MIN_UNIQUE_TOP_POST_COMMENTS_COUNT = 1 - MIN_UNIQUE_TRENDING_POST_REACTIONS_COUNT = 1 + MIN_ACTIVITY_SCORE_FOR_POST_TRENDING = 0.001 if IS_PRODUCTION: AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID') From f067e4c65068252798ea9b7464b7bb235398c334 Mon Sep 17 00:00:00 2001 From: Shantanu Date: Fri, 15 May 2020 15:31:08 +0200 Subject: [PATCH 12/15] Revert "Revert "Merge pull request #692 from OkunaOrg/feature/257-trending-communities-n-posts-rehaul"" This reverts commit 05ae2a40b393301df7b83ee696bdffdc1050a446. --- CHANGELOG.md | 7 + openbook/urls.py | 4 +- openbook_auth/models.py | 11 +- .../tests/views/test_authenticated_user.py | 2 - openbook_common/tests/models.py | 11 +- .../migrations/0034_trendingcommunity.py | 22 ++ .../0035_community_activity_score.py | 18 ++ .../0036_delete_trendingcommunity.py | 16 ++ .../migrations/0037_auto_20200222_1344.py | 17 ++ .../migrations/0038_auto_20200224_1615.py | 18 ++ openbook_communities/models.py | 39 ++- .../tests/views/communities/test_views.py | 159 +++++++++++- .../tests/views/community/posts/test_views.py | 74 +++++- .../views/communities/serializers.py | 11 + .../views/communities/views.py | 33 ++- openbook_moderation/tests/views/checks.py | 2 - .../migrations/0068_post_activity_score.py | 18 ++ .../migrations/0069_auto_20200130_1529.py | 17 ++ .../migrations/0070_merge_20200222_1342.py | 14 ++ .../migrations/0071_auto_20200224_1615.py | 18 ++ .../migrations/0073_merge_20200505_1647.py | 14 ++ openbook_posts/models.py | 140 ++++++++--- openbook_posts/tests/views/test_post.py | 91 ++++++- .../tests/views/test_post_comment.py | 110 ++++++++- .../tests/views/test_post_comments.py | 8 +- .../tests/views/test_post_reaction.py | 84 ++++++- .../tests/views/test_post_reactions.py | 79 +++++- openbook_posts/tests/views/test_posts.py | 232 +++++++++++------- openbook_posts/views/posts/views.py | 17 +- 29 files changed, 1119 insertions(+), 167 deletions(-) create mode 100644 openbook_communities/migrations/0034_trendingcommunity.py create mode 100644 openbook_communities/migrations/0035_community_activity_score.py create mode 100644 openbook_communities/migrations/0036_delete_trendingcommunity.py create mode 100644 openbook_communities/migrations/0037_auto_20200222_1344.py create mode 100644 openbook_communities/migrations/0038_auto_20200224_1615.py create mode 100644 openbook_posts/migrations/0068_post_activity_score.py create mode 100644 openbook_posts/migrations/0069_auto_20200130_1529.py create mode 100644 openbook_posts/migrations/0070_merge_20200222_1342.py create mode 100644 openbook_posts/migrations/0071_auto_20200224_1615.py create mode 100644 openbook_posts/migrations/0073_merge_20200505_1647.py diff --git a/CHANGELOG.md b/CHANGELOG.md index bcd2da1d..6ef91d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,17 @@ The change log for the API server for Okuna. ## Table of contents +- [Release 0.0.66](#release-0.0.66) - [Release 0.0.63](#release-0.0.63) - [Release 0.0.59](#release-0.0.59) +## Release 0.0.66 + +- Introduce activity score in posts and communities, add jobs for the same +- Refactor trending posts and trending communities to use activity score + + ## Release 0.0.63 - Improve performance for linked users API diff --git a/openbook/urls.py b/openbook/urls.py index 53c9520b..b93e8e8f 100644 --- a/openbook/urls.py +++ b/openbook/urls.py @@ -83,7 +83,7 @@ from openbook_posts.views.post_media.views import PostMedia from openbook_posts.views.post_reaction.views import PostReactionItem from openbook_posts.views.post_reactions.views import PostReactions, PostReactionsEmojiCount, PostReactionEmojiGroups -from openbook_posts.views.posts.views import Posts, TrendingPosts, TopPosts, TrendingPostsNew, \ +from openbook_posts.views.posts.views import Posts, TrendingPosts, TopPosts, TrendingPostsLegacy, \ ProfilePostsExcludedCommunities, SearchProfilePostsExcludedCommunities, TopPostsExcludedCommunities, \ SearchTopPostsExcludedCommunities, ProfilePostsExcludedCommunity, TopPostsExcludedCommunity from openbook_importer.views import ImportItem @@ -233,7 +233,7 @@ path('/', include(post_patterns)), path('', Posts.as_view(), name='posts'), path('trending/', TrendingPosts.as_view(), name='trending-posts'), - path('trending/new/', TrendingPostsNew.as_view(), name='trending-posts-new'), + path('trending/new/', TrendingPostsLegacy.as_view(), name='trending-posts-new'), path('emojis/groups/', PostReactionEmojiGroups.as_view(), name='posts-emoji-groups'), path('profile/', include(posts_profile_patterns)), path('top/', include(posts_top_patterns)), diff --git a/openbook_auth/models.py b/openbook_auth/models.py index 0941cbf6..f7efc209 100644 --- a/openbook_auth/models.py +++ b/openbook_auth/models.py @@ -1991,13 +1991,18 @@ def get_trending_posts(self, max_id=None, min_id=None): Post = get_post_model() return Post.get_trending_posts_for_user_with_id(user_id=self.pk, max_id=max_id, min_id=min_id) - def get_trending_posts_old(self): + def get_trending_posts_legacy(self): Post = get_post_model() - return Post.get_trending_posts_old_for_user_with_id(user_id=self.pk) + return Post.get_trending_posts_for_user_with_id_legacy(user_id=self.pk) def get_trending_communities(self, category_name=None): Community = get_community_model() - return Community.get_trending_communities_for_user_with_id(user_id=self.pk, category_name=category_name) + return Community.get_trending_communities_for_user_with_id(user_id=self.pk, + category_name=category_name) + + def get_trending_communities_by_members(self, category_name=None): + Community = get_community_model() + return Community.get_trending_communities_by_members_for_user_with_id(user_id=self.pk, category_name=category_name) def search_communities_with_query(self, query, excluded_from_profile_posts): Community = get_community_model() diff --git a/openbook_auth/tests/views/test_authenticated_user.py b/openbook_auth/tests/views/test_authenticated_user.py index aba7dab8..3f8ff4e5 100644 --- a/openbook_auth/tests/views/test_authenticated_user.py +++ b/openbook_auth/tests/views/test_authenticated_user.py @@ -846,8 +846,6 @@ def test_cannot_set_invalid_language(self): 'language_id': 99999 }, **headers) - print(response) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) user.refresh_from_db() self.assertTrue(user.language.id, language.id) diff --git a/openbook_common/tests/models.py b/openbook_common/tests/models.py index f9e46bff..ea6809f1 100644 --- a/openbook_common/tests/models.py +++ b/openbook_common/tests/models.py @@ -1,6 +1,6 @@ from unittest.mock import patch -from rest_framework.test import APITestCase +from rest_framework.test import APITestCase, APITransactionTestCase class OpenbookAPITestCase(APITestCase): @@ -10,3 +10,12 @@ def setUp(self): def tearDown(self): self.patcher.stop() + + +class OpenbookAPITransactionTestCase(APITransactionTestCase): + def setUp(self): + self.patcher = patch('openbook_notifications.helpers._send_notification_to_user') + self.mock_foo = self.patcher.start() + + def tearDown(self): + self.patcher.stop() diff --git a/openbook_communities/migrations/0034_trendingcommunity.py b/openbook_communities/migrations/0034_trendingcommunity.py new file mode 100644 index 00000000..4a3fe5d0 --- /dev/null +++ b/openbook_communities/migrations/0034_trendingcommunity.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2.5 on 2020-02-03 14:10 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_communities', '0033_auto_20191209_1337'), + ] + + operations = [ + migrations.CreateModel( + name='TrendingCommunity', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(db_index=True, editable=False)), + ('community', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='trending_community', to='openbook_communities.Community')), + ], + ), + ] diff --git a/openbook_communities/migrations/0035_community_activity_score.py b/openbook_communities/migrations/0035_community_activity_score.py new file mode 100644 index 00000000..4596d9a2 --- /dev/null +++ b/openbook_communities/migrations/0035_community_activity_score.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.5 on 2020-02-10 12:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_communities', '0034_trendingcommunity'), + ] + + operations = [ + migrations.AddField( + model_name='community', + name='activity_score', + field=models.FloatField(default=0.0), + ), + ] diff --git a/openbook_communities/migrations/0036_delete_trendingcommunity.py b/openbook_communities/migrations/0036_delete_trendingcommunity.py new file mode 100644 index 00000000..86376e58 --- /dev/null +++ b/openbook_communities/migrations/0036_delete_trendingcommunity.py @@ -0,0 +1,16 @@ +# Generated by Django 2.2.5 on 2020-02-22 11:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_communities', '0035_community_activity_score'), + ] + + operations = [ + migrations.DeleteModel( + name='TrendingCommunity', + ), + ] diff --git a/openbook_communities/migrations/0037_auto_20200222_1344.py b/openbook_communities/migrations/0037_auto_20200222_1344.py new file mode 100644 index 00000000..f56d8566 --- /dev/null +++ b/openbook_communities/migrations/0037_auto_20200222_1344.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.5 on 2020-02-22 12:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_communities', '0036_delete_trendingcommunity'), + ] + + operations = [ + migrations.AddIndex( + model_name='community', + index=models.Index(fields=['activity_score'], name='openbook_co_activit_07d4ba_idx'), + ), + ] diff --git a/openbook_communities/migrations/0038_auto_20200224_1615.py b/openbook_communities/migrations/0038_auto_20200224_1615.py new file mode 100644 index 00000000..252eeb03 --- /dev/null +++ b/openbook_communities/migrations/0038_auto_20200224_1615.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.5 on 2020-02-24 15:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_communities', '0037_auto_20200222_1344'), + ] + + operations = [ + migrations.AlterField( + model_name='community', + name='activity_score', + field=models.DecimalField(decimal_places=10, default=0.0, max_digits=10), + ), + ] diff --git a/openbook_communities/models.py b/openbook_communities/models.py index 38cf3e86..54df2b8e 100644 --- a/openbook_communities/models.py +++ b/openbook_communities/models.py @@ -66,9 +66,13 @@ class Community(models.Model): _('is deleted'), default=False, ) + activity_score = models.DecimalField(default=0.0, decimal_places=10, max_digits=10) class Meta: verbose_name_plural = 'communities' + indexes = [ + models.Index(fields=['activity_score']), + ] @classmethod def is_user_with_username_invited_to_community_with_name(cls, username, community_name): @@ -147,7 +151,12 @@ def get_new_user_suggested_communities(cls): def get_trending_communities_for_user_with_id(cls, user_id, category_name=None): trending_communities_query = cls._make_trending_communities_query(category_name=category_name) trending_communities_query.add(~Q(banned_users__id=user_id), Q.AND) - return cls._get_trending_communities_with_query(query=trending_communities_query) + + trending_communities = cls._get_trending_communities_with_query(query=trending_communities_query) + if trending_communities.count() == 0: + return cls.get_trending_communities_by_members_for_user_with_id(user_id, category_name=category_name) + + return trending_communities @classmethod def get_trending_communities(cls, category_name=None): @@ -156,11 +165,37 @@ def get_trending_communities(cls, category_name=None): @classmethod def _get_trending_communities_with_query(cls, query): + return cls.objects.filter(query).order_by('-activity_score') + + @classmethod + def _make_trending_communities_query(cls, category_name=None): + trending_communities_query = Q(type=Community.COMMUNITY_TYPE_PUBLIC, is_deleted=False) + trending_communities_query.add(Q(activity_score__gte=settings.MIN_ACTIVITY_SCORE_FOR_COMMUNITY_TRENDING), Q.AND) + trending_communities_query.add(~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED), Q.AND) + + if category_name: + trending_communities_query.add(Q(categories__name=category_name), Q.AND) + + return trending_communities_query + + @classmethod + def get_trending_communities_by_members_for_user_with_id(cls, user_id, category_name=None): + trending_communities_query = cls._make_trending_communities_by_members_query(category_name=category_name) + trending_communities_query.add(~Q(banned_users__id=user_id), Q.AND) + return cls._get_trending_communities_by_members_with_query(query=trending_communities_query) + + @classmethod + def get_trending_communities_by_members(cls, category_name=None): + trending_communities_query = cls._make_trending_communities_by_members_query(category_name=category_name) + return cls._get_trending_communities_by_members_with_query(query=trending_communities_query) + + @classmethod + def _get_trending_communities_by_members_with_query(cls, query): return cls.objects.annotate(Count('memberships')).filter(query).order_by( '-memberships__count', '-created') @classmethod - def _make_trending_communities_query(cls, category_name=None): + def _make_trending_communities_by_members_query(cls, category_name=None): trending_communities_query = Q(type=cls.COMMUNITY_TYPE_PUBLIC, is_deleted=False) if category_name: diff --git a/openbook_communities/tests/views/communities/test_views.py b/openbook_communities/tests/views/communities/test_views.py index 685e0580..38f63a3e 100644 --- a/openbook_communities/tests/views/communities/test_views.py +++ b/openbook_communities/tests/views/communities/test_views.py @@ -5,7 +5,10 @@ from django.conf import settings from faker import Faker from rest_framework import status -from openbook_common.tests.models import OpenbookAPITestCase +from django_rq import get_worker, get_scheduler +from rq import SimpleWorker + +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase from mixer.backend.django import mixer import logging @@ -13,7 +16,7 @@ from openbook_common.tests.helpers import make_user, make_authentication_headers_for_user, \ make_community_avatar, make_community_cover, make_category, make_community_users_adjective, \ - make_community_user_adjective, make_community + make_community_user_adjective, make_community, make_fake_post_text from openbook_common.utils.model_loaders import get_community_model from openbook_communities.models import Community @@ -1548,6 +1551,158 @@ def _get_url(self): return reverse('trending-communities') +class TrendingCommunitiesTransactionAPITests(OpenbookAPITransactionTestCase): + """ + TrendingCommunitiesTransactionAPITests + """ + + fixtures = [ + 'openbook_circles/fixtures/circles.json' + ] + + def test_displays_public_communities(self): + """ + should display public communities and return 200 + """ + user = make_user() + + amount_of_communities = 5 + communities_ids = [] + + for i in range(0, amount_of_communities): + community_owner = make_user() + community = make_community(creator=community_owner) + communities_ids.append(community.pk) + post = community_owner.create_community_post(text=make_fake_post_text(), community_name=community.name) + + # update activity scores + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + + url = self._get_url() + response = self.client.get(url, **headers, format='multipart') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_communities = json.loads(response.content) + + self.assertEqual(len(response_communities), len(communities_ids)) + self._clear_jobs_in_scheduler() + for response_community in response_communities: + response_community_id = response_community.get('id') + self.assertIn(response_community_id, communities_ids) + + def test_displays_only_public_communities_with_min_activity_score(self): + """ + should display only public communities with minimum activity score and return 200 + """ + user = make_user() + + amount_of_communities = 5 + communities_ids = [] + + for i in range(0, amount_of_communities): + community_owner = make_user() + community = make_community(creator=community_owner) + if i % 2 == 0: + communities_ids.append(community.pk) + post = community_owner.create_community_post(text=make_fake_post_text(), community_name=community.name) + + # update activity scores + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + + url = self._get_url() + response = self.client.get(url, **headers, format='multipart') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_communities = json.loads(response.content) + + self.assertEqual(len(response_communities), len(communities_ids)) + self._clear_jobs_in_scheduler() + for response_community in response_communities: + response_community_id = response_community.get('id') + self.assertIn(response_community_id, communities_ids) + + def test_not_displays_private_communities(self): + """ + should not display private communities and return 200 + """ + user = make_user() + + amount_of_communities = 5 + + Community = get_community_model() + + for i in range(0, amount_of_communities): + community_owner = make_user() + community = make_community(creator=community_owner, type=Community.COMMUNITY_TYPE_PRIVATE) + post = community_owner.create_community_post(text=make_fake_post_text(), community_name=community.name) + + # update activity scores + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + + url = self._get_url() + + response = self.client.get(url, **headers, format='multipart') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_communities = json.loads(response.content) + + self._clear_jobs_in_scheduler() + self.assertEqual(len(response_communities), 0) + + def test_does_not_display_community_banned_from(self): + """ + should not display a community banned from and return 200 + """ + user = make_user() + community_owner = make_user() + + community = make_community(creator=community_owner) + post = community_owner.create_community_post(text=make_fake_post_text(), community_name=community.name) + user.join_community_with_name(community_name=community.name) + + community_owner.ban_user_with_username_from_community_with_name(username=user.username, community_name=community.name) + + # update activity scores + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + + url = self._get_url() + + response = self.client.get(url, **headers, format='multipart') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_communities = json.loads(response.content) + self._clear_jobs_in_scheduler() + self.assertEqual(0, len(response_communities)) + + def _clear_jobs_in_scheduler(self): + default_scheduler = get_scheduler('process-activity-score') + for job in default_scheduler.get_jobs(): + default_scheduler.cancel(job.get_id()) + + def _add_version_header(self, headers): + headers['HTTP_ACCEPT'] = 'application/json; version=2.0' + return headers + + def _get_url(self): + return reverse('trending-communities') + + class TopPostsExcludedCommunitiesAPITests(OpenbookAPITestCase): """ TopPostsExcludedCommunitiesAPI diff --git a/openbook_communities/tests/views/community/posts/test_views.py b/openbook_communities/tests/views/community/posts/test_views.py index 4dc5c626..767c96dd 100644 --- a/openbook_communities/tests/views/community/posts/test_views.py +++ b/openbook_communities/tests/views/community/posts/test_views.py @@ -1,6 +1,10 @@ from django.urls import reverse +from django_rq import get_worker, get_scheduler +from django.conf import settings from faker import Faker -from openbook_common.tests.models import OpenbookAPITestCase +from rq import SimpleWorker + +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase from rest_framework import status import logging @@ -855,6 +859,74 @@ def _get_url(self, community_name): }) +class CommunityPostsTransactionAPITests(OpenbookAPITransactionTestCase): + """ + CommunityPostsTransactionAPI + """ + + def test_create_community_post_updates_community_activity_score(self): + """ + should update community activity score when creating community post + """ + user = make_user() + + headers = make_authentication_headers_for_user(user=user) + community = make_community(creator=user) + + data = { + 'text': make_fake_post_text(), + } + + url = self._get_url(community_name=community.name) + response = self.client.put(url, data, **headers, format='multipart') + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + community.refresh_from_db() + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + expected_weight = settings.ACTIVITY_UNIQUE_POST_WEIGHT + settings.ACTIVITY_COUNT_POSTS_WEIGHT + + self._clear_jobs_in_scheduler() + self.assertEqual(community.activity_score, expected_weight) + + def test_create_second_community_post_updates_community_activity_score_appropriately(self): + """ + should update community activity score by only count weight when creating a second community post by same user + """ + user = make_user() + + headers = make_authentication_headers_for_user(user=user) + community = make_community(creator=user) + + data = { + 'text': make_fake_post_text(), + } + + url = self._get_url(community_name=community.name) + response = self.client.put(url, data, **headers, format='multipart') + + # create one more post + response = self.client.put(url, data, **headers, format='multipart') + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + expected_weight = settings.ACTIVITY_UNIQUE_POST_WEIGHT + (2 * settings.ACTIVITY_COUNT_POSTS_WEIGHT) + + self._clear_jobs_in_scheduler() + self.assertEqual(community.activity_score, expected_weight) + + def _clear_jobs_in_scheduler(self): + default_scheduler = get_scheduler('process-activity-score') + for job in default_scheduler.get_jobs(): + default_scheduler.cancel(job.get_id()) + + def _get_url(self, community_name): + return reverse('community-posts', kwargs={ + 'community_name': community_name + }) + + class CommunityClosedPostsAPITest(OpenbookAPITestCase): def test_can_retrieve_closed_posts_from_community_if_administrator(self): diff --git a/openbook_communities/views/communities/serializers.py b/openbook_communities/views/communities/serializers.py index 36efb74b..2ffcb795 100644 --- a/openbook_communities/views/communities/serializers.py +++ b/openbook_communities/views/communities/serializers.py @@ -89,11 +89,22 @@ class GetFavoriteCommunitiesSerializer(serializers.Serializer): ) +class TrendingCommunitiesSerializerLegacy(serializers.Serializer): + category = serializers.CharField(max_length=settings.CATEGORY_NAME_MAX_LENGTH, + allow_blank=True, + required=False, + validators=[category_name_exists]) + + class TrendingCommunitiesSerializer(serializers.Serializer): category = serializers.CharField(max_length=settings.CATEGORY_NAME_MAX_LENGTH, allow_blank=True, required=False, validators=[category_name_exists]) + count = serializers.IntegerField( + required=False, + max_value=20 + ) class GetCommunitiesCommunityCategorySerializer(serializers.ModelSerializer): diff --git a/openbook_communities/views/communities/views.py b/openbook_communities/views/communities/views.py index 962bf567..9133584f 100644 --- a/openbook_communities/views/communities/views.py +++ b/openbook_communities/views/communities/views.py @@ -13,7 +13,8 @@ from openbook_communities.views.communities.serializers import CreateCommunitySerializer, \ CommunitiesCommunitySerializer, CommunityNameCheckSerializer, \ GetFavoriteCommunitiesSerializer, GetJoinedCommunitiesSerializer, TrendingCommunitiesSerializer, \ - GetModeratedCommunitiesSerializer, GetAdministratedCommunitiesSerializer, SuggestedCommunitiesCommunitySerializer + GetModeratedCommunitiesSerializer, GetAdministratedCommunitiesSerializer, SuggestedCommunitiesCommunitySerializer, \ + TrendingCommunitiesSerializerLegacy class Communities(APIView): @@ -233,11 +234,20 @@ def get(self, request): class TrendingCommunities(APIView): permission_classes = (IsAuthenticated, IsNotSuspended) + serializer_class_legacy = TrendingCommunitiesSerializerLegacy serializer_class = TrendingCommunitiesSerializer def get(self, request): + version = request.version + + if version == '2.0': + return self.get_trending_communities(request) + else: + return self.get_trending_communities_legacy(request) + + def get_trending_communities_legacy(self, request): query_params = request.query_params.dict() - serializer = self.serializer_class(data=query_params) + serializer = self.serializer_class_legacy(data=query_params) serializer.is_valid(raise_exception=True) data = serializer.data @@ -245,12 +255,29 @@ def get(self, request): user = request.user - communities = user.get_trending_communities(category_name=category_name)[:30] + communities = user.get_trending_communities_by_members(category_name=category_name)[:30] posts_serializer = CommonSearchCommunitiesCommunitySerializer(communities, many=True, context={"request": request}) return Response(posts_serializer.data, status=status.HTTP_200_OK) + def get_trending_communities(self, request): + query_params = request.query_params.dict() + serializer = self.serializer_class(data=query_params) + serializer.is_valid(raise_exception=True) + + data = serializer.data + category_name = data.get('category') + count = data.get('count', 10) + user = request.user + + trending_communities = user.get_trending_communities(category_name=category_name)[:count] + + trending_communities_serializer = CommonSearchCommunitiesCommunitySerializer( + trending_communities, many=True, context={"request": request}) + + return Response(trending_communities_serializer.data, status=status.HTTP_200_OK) + class FavoriteCommunities(APIView): permission_classes = (IsAuthenticated, IsNotSuspended) diff --git a/openbook_moderation/tests/views/checks.py b/openbook_moderation/tests/views/checks.py index 67e59b89..3c604560 100644 --- a/openbook_moderation/tests/views/checks.py +++ b/openbook_moderation/tests/views/checks.py @@ -41,8 +41,6 @@ def test_suspension_penalties_prevent_access(self): headers = make_authentication_headers_for_user(user) response = self.client.get(url, **headers) - print(response.content) - self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) def test_expired_suspension_penalty_does_not_prevent_access(self): diff --git a/openbook_posts/migrations/0068_post_activity_score.py b/openbook_posts/migrations/0068_post_activity_score.py new file mode 100644 index 00000000..f8d3fa90 --- /dev/null +++ b/openbook_posts/migrations/0068_post_activity_score.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.5 on 2020-01-28 12:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_posts', '0067_merge_20191202_1731'), + ] + + operations = [ + migrations.AddField( + model_name='post', + name='activity_score', + field=models.FloatField(default=0.0), + ), + ] diff --git a/openbook_posts/migrations/0069_auto_20200130_1529.py b/openbook_posts/migrations/0069_auto_20200130_1529.py new file mode 100644 index 00000000..35a02660 --- /dev/null +++ b/openbook_posts/migrations/0069_auto_20200130_1529.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.5 on 2020-01-30 14:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_posts', '0068_post_activity_score'), + ] + + operations = [ + migrations.AddIndex( + model_name='post', + index=models.Index(fields=['activity_score'], name='openbook_po_activit_4b4ca7_idx'), + ), + ] diff --git a/openbook_posts/migrations/0070_merge_20200222_1342.py b/openbook_posts/migrations/0070_merge_20200222_1342.py new file mode 100644 index 00000000..70b0496e --- /dev/null +++ b/openbook_posts/migrations/0070_merge_20200222_1342.py @@ -0,0 +1,14 @@ +# Generated by Django 2.2.5 on 2020-02-22 12:42 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_posts', '0069_auto_20200130_1529'), + ('openbook_posts', '0068_profilepostscommunityexclusion'), + ] + + operations = [ + ] diff --git a/openbook_posts/migrations/0071_auto_20200224_1615.py b/openbook_posts/migrations/0071_auto_20200224_1615.py new file mode 100644 index 00000000..87c9e909 --- /dev/null +++ b/openbook_posts/migrations/0071_auto_20200224_1615.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.5 on 2020-02-24 15:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_posts', '0070_merge_20200222_1342'), + ] + + operations = [ + migrations.AlterField( + model_name='post', + name='activity_score', + field=models.DecimalField(decimal_places=10, default=0.0, max_digits=10), + ), + ] diff --git a/openbook_posts/migrations/0073_merge_20200505_1647.py b/openbook_posts/migrations/0073_merge_20200505_1647.py new file mode 100644 index 00000000..53762b20 --- /dev/null +++ b/openbook_posts/migrations/0073_merge_20200505_1647.py @@ -0,0 +1,14 @@ +# Generated by Django 2.2.5 on 2020-05-05 14:47 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('openbook_posts', '0071_auto_20200224_1615'), + ('openbook_posts', '0072_auto_20200414_1852'), + ] + + operations = [ + ] diff --git a/openbook_posts/models.py b/openbook_posts/models.py index 7918e090..6326bc02 100644 --- a/openbook_posts/models.py +++ b/openbook_posts/models.py @@ -14,6 +14,8 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.db.models import Count +from django.db import transaction +import django_rq import ffmpy # Create your views here. @@ -52,7 +54,8 @@ check_mimetype_is_supported_media_mimetypes from openbook_posts.helpers import upload_to_post_image_directory, upload_to_post_video_directory, \ upload_to_post_directory -from openbook_posts.jobs import process_post_media +from openbook_posts.jobs import process_post_media, process_activity_score_post_reaction, \ + process_activity_score_post_comment, process_community_activity_score_post magic = get_magic() from openbook_common.helpers import get_language_for_text @@ -92,11 +95,15 @@ class Post(models.Model): upload_to=upload_to_post_directory, blank=False, null=True, format='JPEG', options={'quality': 30}, processors=[ResizeToFit(width=512, upscale=False)]) + activity_score = models.DecimalField(default=0.0, decimal_places=10, max_digits=10) class Meta: index_together = [ ('creator', 'community'), ] + indexes = [ + models.Index(fields=['activity_score']), + ] @classmethod def get_post_id_for_post_with_uuid(cls, post_uuid): @@ -206,42 +213,6 @@ def get_trending_posts_for_user_with_id(cls, user_id, max_id=None, min_id=None): return trending_community_posts_queryset - @classmethod - def get_trending_posts_old_for_user_with_id(cls, user_id): - """ - For backwards compatibility reasons - """ - trending_posts_query = cls._get_trending_posts_old_query() - trending_posts_query.add(~Q(community__banned_users__id=user_id), Q.AND) - - trending_posts_query.add(~Q(Q(creator__blocked_by_users__blocker_id=user_id) | Q( - creator__user_blocks__blocked_user_id=user_id)), Q.AND) - - trending_posts_query.add(~Q(moderated_object__reports__reporter_id=user_id), Q.AND) - - trending_posts_query.add(~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED), Q.AND) - - return cls._get_trending_posts_old_with_query(query=trending_posts_query) - - @classmethod - def _get_trending_posts_old_with_query(cls, query): - return cls.objects.filter(query).annotate(Count('reactions')).order_by( - '-reactions__count', '-created') - - @classmethod - def _get_trending_posts_old_query(cls): - trending_posts_query = Q(created__gte=timezone.now() - timedelta( - hours=12)) - - Community = get_community_model() - - trending_posts_sources_query = Q(community__type=Community.COMMUNITY_TYPE_PUBLIC, status=cls.STATUS_PUBLISHED, - is_closed=False, is_deleted=False) - - trending_posts_query.add(trending_posts_sources_query, Q.AND) - - return trending_posts_query - @classmethod def get_post_comment_notification_target_users(cls, post, post_commenter): """ @@ -528,6 +499,7 @@ def _publish(self): self.status = Post.STATUS_PUBLISHED self.created = timezone.now() self._process_post_subscribers() + self._enqueue_process_activity_score_add_community_post() self.save() def is_draft(self): @@ -555,6 +527,7 @@ def save(self, *args, **kwargs): def delete(self, *args, **kwargs): self.delete_media() + self._enqueue_process_activity_score_delete_community_post() super(Post, self).delete(*args, **kwargs) def delete_media(self): @@ -563,6 +536,7 @@ def delete_media(self): def soft_delete(self): self.delete_notifications() + self._enqueue_process_activity_score_delete_community_post() for comment in self.comments.all().iterator(): comment.soft_delete() self.is_deleted = True @@ -789,6 +763,37 @@ def _process_post_subscribers(self): user_notifications_subscription_id=subscription.pk) send_user_new_post_push_notification(user_notifications_subscription=subscription, post=self) + def _enqueue_process_activity_score_add_community_post(self): + if self.community is None: + return + + add_post_job_id = 'process_add_community_post_community_{0}_pid_{1}_uid_{2}'.format(self.community.pk, + self.pk, + self.creator.pk) + queue = django_rq.get_queue('process-activity-score') + transaction.on_commit(lambda: queue.enqueue(process_community_activity_score_post, + post_id=self.pk, + post_creator_id=self.creator.pk, + post_community_id=self.community.pk, + job_id=add_post_job_id)) + + def _enqueue_process_activity_score_delete_community_post(self): + if self.community is None: + return + + delete_post_job_id = 'process_delete_community_post_community_{0}_pid_{1}_uid_{2}'.format(self.community.pk, + self.pk, + self.creator.pk) + queue = django_rq.get_queue('process-activity-score') + post_id = self.pk + post_creator_id = self.creator.pk + post_community_id = self.community.pk + transaction.on_commit(lambda: queue.enqueue(process_community_activity_score_post, + post_id=post_id, + post_creator_id=post_creator_id, + post_community_id=post_community_id, + job_id=delete_post_job_id)) + class TopPost(models.Model): post = models.OneToOneField(Post, on_delete=models.CASCADE, related_name='top_post') @@ -975,8 +980,12 @@ def create_comment(cls, text, commenter, post, parent_comment=None): post_comment = PostComment.objects.create(text=text, commenter=commenter, post=post, parent_comment=parent_comment) post_comment.language = get_language_for_text(text) + add_comment_job_id = 'process_add_comment_pid_{0}_cid_{1}'.format(post.pk, post_comment.pk) + transaction.on_commit(lambda: PostComment.enqueue_process_activity_score_job(post_id=post.pk, + post_comment_id=post_comment.pk, + post_commenter_id=commenter.pk, + job_id=add_comment_job_id)) post_comment.save() - return post_comment @classmethod @@ -990,6 +999,15 @@ def get_emoji_counts_for_post_comment_with_id(cls, post_comment_id, emoji_id=Non return Emoji.get_emoji_counts_for_post_comment_with_id(post_comment_id=post_comment_id, emoji_id=emoji_id, reactor_id=reactor_id) + @classmethod + def enqueue_process_activity_score_job(cls, post_id, post_comment_id, post_commenter_id, job_id): + queue = django_rq.get_queue('process-activity-score') + queue.enqueue(process_activity_score_post_comment, + post_id=post_id, + post_comment_id=post_comment_id, + post_commenter_id=post_commenter_id, + job_id=job_id) + def count_replies(self): return self.replies.count() @@ -1128,6 +1146,25 @@ def soft_delete(self): self.is_deleted = True self.delete_notifications() self.save() + delete_comment_job_id = 'process_delete_comment_pid_{0}_cid_{1}'.format(self.post.pk, self.pk) + transaction.on_commit(lambda: PostComment.enqueue_process_activity_score_job(post_id=self.post.pk, + post_comment_id=self.pk, + post_commenter_id=self.commenter.pk, + job_id=delete_comment_job_id)) + + def delete(self, *args, **kwargs): + if not self.is_deleted: + post_id = self.post.pk + post_comment_id = self.pk + post_commenter_id = self.commenter.pk + delete_comment_job_id = 'process_delete_comment_pid_{0}_cid_{1}'.format(post_id, post_comment_id) + transaction.on_commit(lambda: + PostComment.enqueue_process_activity_score_job(post_id=post_id, + post_comment_id=post_comment_id, + post_commenter_id=post_commenter_id, + job_id=delete_comment_job_id)) + + super(PostComment, self).delete(*args, **kwargs) def unsoft_delete(self): self.is_deleted = False @@ -1194,9 +1231,23 @@ class PostReaction(models.Model): class Meta: unique_together = ('reactor', 'post',) + @classmethod + def enqueue_process_activity_score_job(cls, post_id, post_reaction_id, job_id): + queue = django_rq.get_queue('process-activity-score') + queue.enqueue(process_activity_score_post_reaction, + post_id=post_id, + post_reaction_id=post_reaction_id, + job_id=job_id) + @classmethod def create_reaction(cls, reactor, emoji_id, post): - return PostReaction.objects.create(reactor=reactor, emoji_id=emoji_id, post=post) + post_reaction = PostReaction.objects.create(reactor=reactor, emoji_id=emoji_id, post=post) + job_id = 'process_add_unique_reaction_pid_{0}_rid_{1}'.format(post.pk, post_reaction.pk) + transaction.on_commit(lambda: PostReaction.enqueue_process_activity_score_job(post_id=post.pk, + post_reaction_id=post_reaction.pk, + job_id=job_id)) + + return post_reaction @classmethod def count_reactions_for_post_with_id(cls, post_id, reactor_id=None): @@ -1207,6 +1258,17 @@ def count_reactions_for_post_with_id(cls, post_id, reactor_id=None): return cls.objects.filter(count_query).count() + def delete(self, *args, **kwargs): + reaction_id = self.pk + post_id = self.post.pk + job_id = 'process_remove_unique_reaction_pid_{0}_rid_{1}'.format(post_id, reaction_id) + transaction.on_commit(lambda: PostReaction.enqueue_process_activity_score_job( + post_id=post_id, + post_reaction_id=reaction_id, + job_id=job_id)) + + super(PostReaction, self).delete(*args, **kwargs) + def save(self, *args, **kwargs): ''' On save, update timestamps ''' if not self.id: diff --git a/openbook_posts/tests/views/test_post.py b/openbook_posts/tests/views/test_post.py index 1aebf7d8..b7b1fa42 100644 --- a/openbook_posts/tests/views/test_post.py +++ b/openbook_posts/tests/views/test_post.py @@ -5,34 +5,33 @@ from PIL import Image from django.urls import reverse -from django_rq import get_worker -from django_rq.queues import get_queues +from django_rq import get_worker, get_scheduler from faker import Faker +from django.db import transaction from rest_framework import status -from openbook_common.tests.models import OpenbookAPITestCase +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase from django.core.files.images import ImageFile from django.core.files import File -from django.core.cache import cache from django.conf import settings from unittest import mock import logging -from rq import SimpleWorker, Worker +from rq import SimpleWorker from openbook_common.tests.helpers import make_authentication_headers_for_user, make_fake_post_text, \ make_fake_post_comment_text, make_user, make_circle, make_community, make_moderation_category, \ - get_test_videos, get_test_image, make_proxy_blacklisted_domain, make_hashtag, make_hashtag_name, \ + get_test_videos, get_test_image, make_hashtag, make_hashtag_name, \ make_reactions_emoji_group, make_emoji -from openbook_common.utils.model_loaders import get_language_model, get_community_new_post_notification_model, \ +from openbook_common.utils.model_loaders import get_community_new_post_notification_model, \ get_post_comment_notification_model, get_post_comment_user_mention_notification_model, \ get_post_user_mention_notification_model, get_post_comment_reaction_notification_model, \ get_post_comment_reply_notification_model +from openbook_common.utils.model_loaders import get_language_model from openbook_communities.models import Community from openbook_hashtags.models import Hashtag from openbook_notifications.models import PostUserMentionNotification, Notification from openbook_posts.models import Post, PostUserMention, PostMedia -from openbook_common.models import ProxyBlacklistedDomain logger = logging.getLogger(__name__) fake = Faker() @@ -1304,6 +1303,82 @@ def _get_url(self, post): }) +class PostItemTransactionAPITests(OpenbookAPITransactionTestCase): + + def test_reduces_community_activity_score_on_delete_post(self): + """ + should reduce community activity score on delete post and return 200 + """ + self._clear_jobs_in_scheduler() + user = make_user() + headers = make_authentication_headers_for_user(user) + community = make_community(creator=user) + with transaction.atomic(): + post = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + activity_score_before_delete = community.activity_score + + url = self._get_url(post) + response = self.client.delete(url, **headers) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + expected_weight = activity_score_before_delete - \ + settings.ACTIVITY_UNIQUE_POST_WEIGHT - \ + settings.ACTIVITY_COUNT_POSTS_WEIGHT + + self._clear_jobs_in_scheduler() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(community.activity_score, expected_weight) + + def test_reduces_community_activity_score_appropriately_on_delete_two_posts_by_same_creator(self): + """ + should reduce community activity score correctly on delete two posts by same creator + """ + user = make_user() + headers = make_authentication_headers_for_user(user) + community = make_community(creator=user) + with transaction.atomic(): + post_1 = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + post_2 = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + activity_score_before_delete = community.activity_score + + url_1 = self._get_url(post_1) + response_1 = self.client.delete(url_1, **headers) + url_2 = self._get_url(post_2) + response_2 = self.client.delete(url_2, **headers) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + expected_weight = activity_score_before_delete - \ + settings.ACTIVITY_UNIQUE_POST_WEIGHT - \ + (2 * settings.ACTIVITY_COUNT_POSTS_WEIGHT) + + self._clear_jobs_in_scheduler() + self.assertEqual(response_1.status_code, status.HTTP_200_OK) + self.assertEqual(response_2.status_code, status.HTTP_200_OK) + self.assertEqual(community.activity_score, expected_weight) + + def _clear_jobs_in_scheduler(self): + default_scheduler = get_scheduler('process-activity-score') + for job in default_scheduler.get_jobs(): + default_scheduler.cancel(job.get_id()) + + def _get_url(self, post): + return reverse('post', kwargs={ + 'post_uuid': post.uuid + }) + + class MutePostAPITests(OpenbookAPITestCase): """ MutePostAPI diff --git a/openbook_posts/tests/views/test_post_comment.py b/openbook_posts/tests/views/test_post_comment.py index da433e01..63fd67a7 100644 --- a/openbook_posts/tests/views/test_post_comment.py +++ b/openbook_posts/tests/views/test_post_comment.py @@ -1,7 +1,11 @@ from django.urls import reverse +from django_rq import get_worker, get_scheduler +from django.conf import settings from faker import Faker from rest_framework import status -from openbook_common.tests.models import OpenbookAPITestCase +from rq import SimpleWorker + +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase from unittest import mock import json @@ -2163,6 +2167,110 @@ def _get_url(self, post, post_comment): }) +class PostCommentItemTransactionAPITests(OpenbookAPITransactionTestCase): + + fixtures = [ + 'openbook_circles/fixtures/circles.json' + ] + + def test_delete_comment_in_post_reduces_post_activity_score(self): + """ + should reduce post activity score on delete comment in post and return 200 + """ + user = make_user() + commenter = make_user() + + post = user.create_public_post(text=make_fake_post_text()) + post_comment = commenter.comment_post_with_id(post.pk, text=make_fake_post_comment_text()) + + url = self._get_url(post_comment=post_comment, post=post) + + headers = make_authentication_headers_for_user(user) + response = self.client.delete(url, **headers) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + post.refresh_from_db() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._clear_jobs_in_scheduler() + self.assertEqual(post.activity_score, 0.0) + + def test_delete_comment_in_community_post_reduces_community_activity_score(self): + """ + should reduce community activity score on delete comment in community post and return 200 + """ + user = make_user() + community = make_community(creator=user) + post = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + activity_score_before_delete = community.activity_score + + post_comment = user.comment_post_with_id(post.pk, text=make_fake_post_comment_text()) + + url = self._get_url(post_comment=post_comment, post=post) + + headers = make_authentication_headers_for_user(user) + response = self.client.delete(url, **headers) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + self._clear_jobs_in_scheduler() + self.assertEqual(community.activity_score, activity_score_before_delete) + + def test_delete_comment_in_community_post_one_by_one_reduces_community_activity_score_correctly(self): + """ + should reduce community activity score correctly on sequential job runs of delete comment in community post and return 200 + """ + user = make_user() + community = make_community(creator=user) + post = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + + post_comment_1 = user.comment_post_with_id(post.pk, text=make_fake_post_comment_text()) + post_comment_2 = user.comment_post_with_id(post.pk, text=make_fake_post_comment_text()) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + activity_score_before_delete = community.activity_score + + # delete comment one + url = self._get_url(post_comment=post_comment_1, post=post) + headers = make_authentication_headers_for_user(user) + response = self.client.delete(url, **headers) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + expected_activity_score_1 = activity_score_before_delete - settings.ACTIVITY_COUNT_COMMENTS_WEIGHT + self.assertEqual(community.activity_score, expected_activity_score_1) + + # delete comment two + url_2 = self._get_url(post_comment=post_comment_2, post=post) + headers = make_authentication_headers_for_user(user) + response = self.client.delete(url_2, **headers) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + expected_activity_score_2 = expected_activity_score_1 - \ + settings.ACTIVITY_COUNT_COMMENTS_WEIGHT - \ + settings.ACTIVITY_UNIQUE_COMMENT_WEIGHT + + self._clear_jobs_in_scheduler() + self.assertEqual(community.activity_score, expected_activity_score_2) + + def _clear_jobs_in_scheduler(self): + default_scheduler = get_scheduler('process-activity-score') + for job in default_scheduler.get_jobs(): + default_scheduler.cancel(job.get_id()) + + def _get_url(self, post, post_comment): + return reverse('post-comment', kwargs={ + 'post_uuid': post.uuid, + 'post_comment_id': post_comment.pk + }) + + class MutePostCommentAPITests(OpenbookAPITestCase): """ MutePostCommentAPI diff --git a/openbook_posts/tests/views/test_post_comments.py b/openbook_posts/tests/views/test_post_comments.py index c1405298..89ebdb98 100644 --- a/openbook_posts/tests/views/test_post_comments.py +++ b/openbook_posts/tests/views/test_post_comments.py @@ -1,11 +1,17 @@ # Create your tests here. import json from django.urls import reverse +from django_rq import get_worker, get_scheduler +from django.conf import settings from faker import Faker from rest_framework import status from unittest import mock from unittest.mock import ANY -from openbook_common.tests.models import OpenbookAPITestCase + +from rq import SimpleWorker + +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase +from unittest.mock import call import logging import random diff --git a/openbook_posts/tests/views/test_post_reaction.py b/openbook_posts/tests/views/test_post_reaction.py index 798bcea7..c87aaab7 100644 --- a/openbook_posts/tests/views/test_post_reaction.py +++ b/openbook_posts/tests/views/test_post_reaction.py @@ -1,8 +1,13 @@ # Create your tests here. from django.urls import reverse +from django.db import transaction +from django.conf import settings +from django_rq import get_worker from faker import Faker from rest_framework import status -from openbook_common.tests.models import OpenbookAPITestCase +from rq import SimpleWorker + +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase import logging @@ -437,3 +442,80 @@ def _get_url(self, post, post_reaction): 'post_uuid': post.uuid, 'post_reaction_id': post_reaction.pk }) + + +class PostReactionItemTransactionAPITests(OpenbookAPITransactionTestCase): + """ + PostReactionItemTransactionsAPI + """ + + fixtures = [ + 'openbook_circles/fixtures/circles.json' + ] + + def test_delete_own_reaction_reduces_post_activity_score(self): + """ + should reduce activity score on delete own reaction in public post and return 200 + """ + user = make_user() + + foreign_user = make_user() + + post = foreign_user.create_public_post(text=make_fake_post_text()) + + emoji_group = make_reactions_emoji_group() + + post_reaction_emoji_id = make_emoji(group=emoji_group).pk + + with transaction.atomic(): + post_reaction = user.react_to_post_with_id(post.pk, emoji_id=post_reaction_emoji_id) + + url = self._get_url(post_reaction=post_reaction, post=post) + headers = make_authentication_headers_for_user(user) + response = self.client.delete(url, **headers) + + # run job to reduce activity score + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + post.refresh_from_db() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(post.activity_score, 0.0) + + def test_delete_own_post_reaction_reduces_community_activity_score(self): + """ + should reduce community activity score on delete own reaction in community post and return 200 + """ + user = make_user() + + community = make_community(creator=user) + post = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + + emoji_group = make_reactions_emoji_group() + + post_reaction_emoji_id = make_emoji(group=emoji_group).pk + + with transaction.atomic(): + post_reaction = user.react_to_post_with_id(post.pk, emoji_id=post_reaction_emoji_id) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + activity_score_before_delete = community.activity_score + + url = self._get_url(post_reaction=post_reaction, post=post) + headers = make_authentication_headers_for_user(user) + response = self.client.delete(url, **headers) + + # run job to reduce activity score + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(community.activity_score, + activity_score_before_delete - settings.ACTIVITY_UNIQUE_REACTION_WEIGHT) + + def _get_url(self, post, post_reaction): + return reverse('post-reaction', kwargs={ + 'post_uuid': post.uuid, + 'post_reaction_id': post_reaction.pk + }) diff --git a/openbook_posts/tests/views/test_post_reactions.py b/openbook_posts/tests/views/test_post_reactions.py index a78d167c..7598f88b 100644 --- a/openbook_posts/tests/views/test_post_reactions.py +++ b/openbook_posts/tests/views/test_post_reactions.py @@ -1,16 +1,20 @@ # Create your tests here. import json from django.urls import reverse +from django.conf import settings +from django_rq import get_worker from faker import Faker from rest_framework import status -from openbook_common.tests.models import OpenbookAPITestCase +from rq import SimpleWorker + +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase import logging from openbook_common.tests.helpers import make_authentication_headers_for_user, make_fake_post_text, \ make_fake_post_comment_text, make_user, make_circle, make_emoji, make_emoji_group, make_reactions_emoji_group, \ make_community from openbook_notifications.models import PostReactionNotification -from openbook_posts.models import PostReaction +from openbook_posts.models import PostReaction, Post logger = logging.getLogger(__name__) fake = Faker() @@ -594,6 +598,77 @@ def _get_url(self, post): }) +class PostReactionsTransactionAPITests(OpenbookAPITransactionTestCase): + """ + PostReactionsTransactionAPI + """ + + fixtures = [ + 'openbook_circles/fixtures/circles.json' + ] + + def test_creating_post_reaction_updates_post_activity_score(self): + """ + should update activity score in post after successful reaction + """ + user = make_user() + headers = make_authentication_headers_for_user(user) + post = user.create_public_post(text=make_fake_post_text()) + + emoji_group = make_reactions_emoji_group() + + post_reaction_emoji_id = make_emoji(group=emoji_group).pk + + data = self._get_create_post_reaction_request_data(post_reaction_emoji_id, emoji_group.pk) + + url = self._get_url(post) + response = self.client.put(url, data, **headers) + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + post.refresh_from_db() + self.assertEqual(post.activity_score, settings.ACTIVITY_UNIQUE_REACTION_WEIGHT) + + def test_creating_post_reaction_updates_community_activity_score(self): + """ + should update activity score in community after successful community post reaction + """ + user = make_user() + headers = make_authentication_headers_for_user(user) + community = make_community(creator=user) + post = user.create_community_post(text=make_fake_post_text(), community_name=community.name) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + community.refresh_from_db() + + activity_score_before_reaction = community.activity_score + + emoji_group = make_reactions_emoji_group() + + post_reaction_emoji_id = make_emoji(group=emoji_group).pk + + data = self._get_create_post_reaction_request_data(post_reaction_emoji_id, emoji_group.pk) + + url = self._get_url(post) + response = self.client.put(url, data, **headers) + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + community.refresh_from_db() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(community.activity_score, activity_score_before_reaction + settings.ACTIVITY_UNIQUE_REACTION_WEIGHT) + + def _get_create_post_reaction_request_data(self, emoji_id, emoji_group_id): + return { + 'emoji_id': emoji_id, + 'group_id': emoji_group_id + } + + def _get_url(self, post): + return reverse('post-reactions', kwargs={ + 'post_uuid': post.uuid + }) + + class PostReactionsEmojiCountAPITests(OpenbookAPITestCase): """ PostReactionsEmojiCountAPI diff --git a/openbook_posts/tests/views/test_posts.py b/openbook_posts/tests/views/test_posts.py index 6d5b4bc7..48c9f6a8 100644 --- a/openbook_posts/tests/views/test_posts.py +++ b/openbook_posts/tests/views/test_posts.py @@ -8,11 +8,12 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.urls import reverse from django_rq import get_worker +from django.db import transaction from faker import Faker from rest_framework import status from rq import SimpleWorker -from openbook_common.tests.models import OpenbookAPITestCase +from openbook_common.tests.models import OpenbookAPITestCase, OpenbookAPITransactionTestCase from mixer.backend.django import mixer from openbook.settings import POST_MAX_LENGTH @@ -3784,41 +3785,6 @@ class TrendingPostsAPITests(OpenbookAPITestCase): 'openbook_circles/fixtures/circles.json' ] - def test_displays_community_posts_only(self): - """ - should display community posts only and return 200 - """ - user = make_user() - community = make_community(creator=user) - - user.create_public_post(text=make_fake_post_text()) - post = user.create_community_post(community_name=community.name, text=make_fake_post_text()) - - headers = make_authentication_headers_for_user(user) - - emoji_group = make_reactions_emoji_group() - emoji = make_emoji(group=emoji_group) - - # react once, min required while testing - user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) - - curate_trending_posts() - - url = self._get_url() - - response = self.client.get(url, **headers, format='multipart') - - self.assertEqual(response.status_code, status.HTTP_200_OK) - - response_posts = json.loads(response.content) - - self.assertEqual(1, len(response_posts)) - - response_post = response_posts[0] - - self.assertEqual(response_post['post']['id'], post.pk) - self.assertTrue(TrendingPost.objects.filter(post__id=post.pk).exists()) - def test_does_not_curate_community_posts_with_less_than_min_reactions(self): """ should not curate community posts with less than minimum reactions and return 200 @@ -3830,6 +3796,7 @@ def test_does_not_curate_community_posts_with_less_than_min_reactions(self): post = user.create_community_post(community_name=community.name, text=make_fake_post_text()) headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) curate_trending_posts() @@ -3844,46 +3811,6 @@ def test_does_not_curate_community_posts_with_less_than_min_reactions(self): self.assertEqual(0, len(response_posts)) self.assertFalse(TrendingPost.objects.filter(post__id=post.pk).exists()) - def test_does_not_display_closed_community_posts(self): - """ - should not display community posts that are closed - """ - user = make_user() - community = make_community(creator=user) - - user.create_public_post(text=make_fake_post_text()) - post = user.create_community_post(community_name=community.name, text=make_fake_post_text()) - post_two = user.create_community_post(community_name=community.name, text=make_fake_post_text()) - post_two.is_closed = True - post_two.save() - - headers = make_authentication_headers_for_user(user) - - emoji_group = make_reactions_emoji_group() - emoji = make_emoji(group=emoji_group) - - # react once, min required while testing - user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) - user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) - - curate_trending_posts() - - url = self._get_url() - - response = self.client.get(url, **headers, format='multipart') - - self.assertEqual(response.status_code, status.HTTP_200_OK) - - response_posts = json.loads(response.content) - - self.assertEqual(1, len(response_posts)) - - response_post = response_posts[0] - - self.assertEqual(response_post['post']['id'], post.pk) - self.assertFalse(TrendingPost.objects.filter(post__id=post_two.pk).exists()) - self.assertTrue(TrendingPost.objects.filter(post__id=post.pk).exists()) - def test_does_not_display_post_from_community_banned_from(self): """ should not display posts from a community banned from and return 200 @@ -3906,6 +3833,7 @@ def test_does_not_display_post_from_community_banned_from(self): community_name=community.name) headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) curate_trending_posts() @@ -3943,6 +3871,7 @@ def test_cant_retrieve_post_of_blocked_user(self): url = self._get_url() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) response = self.client.get(url, **headers) @@ -3976,6 +3905,7 @@ def test_cant_retrieve_post_of_blocking_user(self): url = self._get_url() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) response = self.client.get(url, **headers) @@ -4010,6 +3940,7 @@ def test_cant_retrieve_post_of_blocked_community_staff_member(self): url = self._get_url() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) response = self.client.get(url, **headers) @@ -4044,6 +3975,7 @@ def test_does_not_curate_encircled_posts(self): curate_trending_posts() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) url = self._get_url() @@ -4077,6 +4009,7 @@ def test_does_not_curate_private_community_posts(self): curate_trending_posts() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) url = self._get_url() @@ -4091,28 +4024,83 @@ def test_does_not_curate_private_community_posts(self): self.assertEqual(0, len(trending_posts)) self.assertFalse(TrendingPost.objects.filter(post__id=post.pk).exists()) - def test_does_not_return_recently_turned_private_community_posts(self): + def _add_version_header(self, headers): + headers['HTTP_ACCEPT'] = 'application/json; version=2.0' + return headers + + def _get_url(self): + return reverse('trending-posts') + + +class TrendingPostsTransactionAPITests(OpenbookAPITransactionTestCase): + fixtures = [ + 'openbook_circles/fixtures/circles.json' + ] + + def test_displays_community_posts_only(self): """ - should not return recently turned private community posts in trending posts + should display community posts only and return 200 """ user = make_user() + community = make_community(creator=user) - community = make_community(creator=user, type=Community.COMMUNITY_TYPE_PUBLIC) + user.create_public_post(text=make_fake_post_text()) post = user.create_community_post(community_name=community.name, text=make_fake_post_text()) + headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + emoji_group = make_reactions_emoji_group() emoji = make_emoji(group=emoji_group) # react once, min required while testing - user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) + with transaction.atomic(): + user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) - # curate trending posts + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) curate_trending_posts() - community.type = Community.COMMUNITY_TYPE_PRIVATE - community.save() + url = self._get_url() + + response = self.client.get(url, **headers, format='multipart') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_posts = json.loads(response.content) + + self.assertEqual(1, len(response_posts)) + + response_post = response_posts[0] + + self.assertEqual(response_post['post']['id'], post.pk) + self.assertTrue(TrendingPost.objects.filter(post__id=post.pk).exists()) + + def test_does_not_display_closed_community_posts(self): + """ + should not display community posts that are closed + """ + user = make_user() + community = make_community(creator=user) + + user.create_public_post(text=make_fake_post_text()) + post = user.create_community_post(community_name=community.name, text=make_fake_post_text()) + post_two = user.create_community_post(community_name=community.name, text=make_fake_post_text()) + post_two.is_closed = True + post_two.save() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + + emoji_group = make_reactions_emoji_group() + emoji = make_emoji(group=emoji_group) + + # react once, min required while testing + with transaction.atomic(): + user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) + user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + curate_trending_posts() url = self._get_url() @@ -4121,10 +4109,13 @@ def test_does_not_return_recently_turned_private_community_posts(self): self.assertEqual(response.status_code, status.HTTP_200_OK) response_posts = json.loads(response.content) - self.assertEqual(0, len(response_posts)) - trending_posts = TrendingPost.objects.all() - self.assertEqual(1, len(trending_posts)) + self.assertEqual(1, len(response_posts)) + + response_post = response_posts[0] + + self.assertEqual(response_post['post']['id'], post.pk) + self.assertFalse(TrendingPost.objects.filter(post__id=post_two.pk).exists()) self.assertTrue(TrendingPost.objects.filter(post__id=post.pk).exists()) def test_does_not_display_curated_closed_community_posts(self): @@ -4142,9 +4133,11 @@ def test_does_not_display_curated_closed_community_posts(self): emoji = make_emoji(group=emoji_group) # react once, min required while testing - user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) - user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + with transaction.atomic(): + user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) + user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) # curate trending posts curate_trending_posts() @@ -4152,6 +4145,7 @@ def test_does_not_display_curated_closed_community_posts(self): post_two.save() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) url = self._get_url() @@ -4188,13 +4182,17 @@ def test_does_not_display_reported_community_posts_that_are_approved(self): emoji = make_emoji(group=emoji_group) # react once, min required while testing - user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) - user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + with transaction.atomic(): + user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) + user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) # curate trending posts curate_trending_posts() headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) url = self._get_url() @@ -4234,8 +4232,11 @@ def test_does_not_display_reported_community_posts_that_are_approved_after_curat emoji = make_emoji(group=emoji_group) # react once, min required while testing - user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) - user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + with transaction.atomic(): + user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) + user.react_to_post_with_id(post_id=post_two.pk, emoji_id=emoji.pk) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) # curate trending posts curate_trending_posts() @@ -4243,6 +4244,7 @@ def test_does_not_display_reported_community_posts_that_are_approved_after_curat user.approve_moderated_object(moderated_object=moderated_object) headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) url = self._get_url() @@ -4254,8 +4256,52 @@ def test_does_not_display_reported_community_posts_that_are_approved_after_curat response_post = response_posts[0] self.assertEqual(response_post['post']['id'], post_two.pk) + def test_does_not_return_recently_turned_private_community_posts(self): + """ + should not return recently turned private community posts in trending posts + """ + user = make_user() + + community = make_community(creator=user, type=Community.COMMUNITY_TYPE_PUBLIC) + post = user.create_community_post(community_name=community.name, text=make_fake_post_text()) + + emoji_group = make_reactions_emoji_group() + emoji = make_emoji(group=emoji_group) + + # react once, min required while testing + with transaction.atomic(): + user.react_to_post_with_id(post_id=post.pk, emoji_id=emoji.pk) + + get_worker('process-activity-score', worker_class=SimpleWorker).work(burst=True) + + # curate trending posts + curate_trending_posts() + + community.type = Community.COMMUNITY_TYPE_PRIVATE + community.save() + + headers = make_authentication_headers_for_user(user) + headers = self._add_version_header(headers) + + url = self._get_url() + + response = self.client.get(url, **headers, format='multipart') + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response_posts = json.loads(response.content) + self.assertEqual(0, len(response_posts)) + + trending_posts = TrendingPost.objects.all() + self.assertEqual(1, len(trending_posts)) + self.assertTrue(TrendingPost.objects.filter(post__id=post.pk).exists()) + + def _add_version_header(self, headers): + headers['HTTP_ACCEPT'] = 'application/json; version=2.0' + return headers + def _get_url(self): - return reverse('trending-posts-new') + return reverse('trending-posts') class TopPostsAPITests(OpenbookAPITestCase): diff --git a/openbook_posts/views/posts/views.py b/openbook_posts/views/posts/views.py index cae49189..89fdd7e5 100644 --- a/openbook_posts/views/posts/views.py +++ b/openbook_posts/views/posts/views.py @@ -114,18 +114,27 @@ def get_posts_for_unauthenticated_user(self, request): return Response(post_serializer.data, status=status.HTTP_200_OK) -class TrendingPosts(APIView): +class TrendingPostsLegacy(APIView): permission_classes = (IsAuthenticated, IsNotSuspended) def get(self, request): + query_params = request.query_params.dict() + + serializer = GetTrendingPostsSerializer(data=query_params) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + max_id = data.get('max_id') + min_id = data.get('min_id') + count = data.get('count', 30) user = request.user - posts = user.get_trending_posts_old()[:30] - posts_serializer = AuthenticatedUserPostSerializer(posts, many=True, context={"request": request}) + trending_posts = user.get_trending_posts(max_id=max_id, min_id=min_id).order_by('-id')[:count] + posts_serializer = AuthenticatedUserTrendingPostSerializer(trending_posts, many=True, context={"request": request}) return Response(posts_serializer.data, status=status.HTTP_200_OK) -class TrendingPostsNew(APIView): +class TrendingPosts(APIView): permission_classes = (IsAuthenticated, IsNotSuspended) def get(self, request): From 1bc360c5cbd9efc7d43ce39cdfe371c3c11dab79 Mon Sep 17 00:00:00 2001 From: Shantanu Date: Fri, 15 May 2020 15:43:47 +0200 Subject: [PATCH 13/15] :card_file_box: remove migration not needed --- .../migrations/0073_merge_20200505_1647.py | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 openbook_posts/migrations/0073_merge_20200505_1647.py diff --git a/openbook_posts/migrations/0073_merge_20200505_1647.py b/openbook_posts/migrations/0073_merge_20200505_1647.py deleted file mode 100644 index 53762b20..00000000 --- a/openbook_posts/migrations/0073_merge_20200505_1647.py +++ /dev/null @@ -1,14 +0,0 @@ -# Generated by Django 2.2.5 on 2020-05-05 14:47 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('openbook_posts', '0071_auto_20200224_1615'), - ('openbook_posts', '0072_auto_20200414_1852'), - ] - - operations = [ - ] From c043e4bb5912e57d1c71a0a2b56be060e9928c30 Mon Sep 17 00:00:00 2001 From: Shantanu Date: Fri, 15 May 2020 16:00:22 +0200 Subject: [PATCH 14/15] :recycle: add missing import --- openbook_common/utils/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openbook_common/utils/helpers.py b/openbook_common/utils/helpers.py index ad6bd1be..467a2f42 100644 --- a/openbook_common/utils/helpers.py +++ b/openbook_common/utils/helpers.py @@ -7,6 +7,7 @@ import magic import spectra +from cursor_pagination import CursorPaginator from django.http import QueryDict from imagekit.utils import get_cache from imagekit.models import ProcessedImageField From 847cfd715f615baf9cbafeee5bd20c2e17fda87c Mon Sep 17 00:00:00 2001 From: Shantanu Date: Thu, 21 May 2020 18:03:06 +0200 Subject: [PATCH 15/15] :arrow_up: add missing pkg --- Pipfile | 1 + Pipfile.lock | 116 +++++++++++++++++++++++++-------------------------- 2 files changed, 58 insertions(+), 59 deletions(-) diff --git a/Pipfile b/Pipfile index 27ea21c6..c0589632 100644 --- a/Pipfile +++ b/Pipfile @@ -55,6 +55,7 @@ shutilwhich = "*" halo = "*" watchdog = "*" spectra = "*" +colorlog = "*" [pipenv] allow_prereleases = true diff --git a/Pipfile.lock b/Pipfile.lock index fe22ec4e..17a8b8aa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "5fd3f2910644f657607e5fa06c14bbe11fa76414d18b8b43434a8f09b3b7ae7b" + "sha256": "28fdd02c898eb2875dac892a5d7500b02d9856a85f09461de9e6830fcbfdf001" }, "pipfile-spec": 6, "requires": {}, @@ -31,26 +31,27 @@ }, "beautifulsoup4": { "hashes": [ - "sha256:594ca51a10d2b3443cbac41214e12dbb2a1cd57e1a7344659849e2e20ba6a8d8", - "sha256:a4bbe77fd30670455c5296242967a123ec28c37e9702a8a81bd2f20a4baf0368", - "sha256:d4e96ac9b0c3a6d3f0caae2e4124e6055c5dcafde8e2f831ff194c104f0775a0" + "sha256:73cc4d115b96f79c7d77c1c7f7a0a8d4c57860d1041df407dd1aae7f07a77fd7", + "sha256:a6237df3c32ccfaee4fd201c8f5f9d9df619b93121d01353a64a73ce8c6ef9a8", + "sha256:e718f2342e2e099b640a34ab782407b7b676f47ee272d6739e60b8ea23829f2c" ], "index": "pypi", - "version": "==4.9.0" + "version": "==4.9.1" }, "boto3": { "hashes": [ - "sha256:06dd5d0f2ed3570f60eab04b9f04d229ff980b55102447481992756efe268639" + "sha256:703157e8f16c57133fde0082a2d8b99ca6d36120ca4479df1464df80dd148a87", + "sha256:74d78ca0fd706f447a5f787d88214b298b213b1eddf2e8197051a0844df45146" ], "index": "pypi", - "version": "==1.13.9" + "version": "==1.13.14" }, "botocore": { "hashes": [ - "sha256:8743cd10500b6c4c4d9423d3aa2905ed886fea2bd4bb7c8eff6e6c08283c9ab9", - "sha256:d82f34844f9fc64d51b46046eed1f98fc367897832e5c4734ce58c0e17e7188f" + "sha256:a8e4cb8ed5a7e59fce935c9a550ccf616e9d5a053d02c374832610c2e377ca92", + "sha256:c8a5647069f978ae664987ebdeffaef0eb2910e88a52fcc8d52c9eb014fed8cc" ], - "version": "==1.16.9" + "version": "==1.16.14" }, "certifi": { "hashes": [ @@ -176,11 +177,11 @@ }, "django-cacheops": { "hashes": [ - "sha256:56ea95ad4eb1b61b6c014b7b23f3203ef8816611c9e8a097a7e99628810e9f16", - "sha256:a94418c8ba816c7c65d8cc2dd265313e042f4339c3b62a3682ebec89d75ff222" + "sha256:0f3e28c16d172b513980f604e026e356db559a4e511d2a12d06f3d34d5c9ca58", + "sha256:f7f657fd8c5a79a2739e781d25f06492725aa1fce0032c25fa7b06e057d8be49" ], "index": "pypi", - "version": "==4.2" + "version": "==5.0" }, "django-cursor-pagination": { "hashes": [ @@ -432,29 +433,34 @@ }, "numpy": { "hashes": [ - "sha256:00d7b54c025601e28f468953d065b9b121ddca7fff30bed7be082d3656dd798d", - "sha256:02ec9582808c4e48be4e93cd629c855e644882faf704bc2bd6bbf58c08a2a897", - "sha256:0e6f72f7bb08f2f350ed4408bb7acdc0daba637e73bce9f5ea2b207039f3af88", - "sha256:1be2e96314a66f5f1ce7764274327fd4fb9da58584eaff00b5a5221edefee7d6", - "sha256:2466fbcf23711ebc5daa61d28ced319a6159b260a18839993d871096d66b93f7", - "sha256:2b573fcf6f9863ce746e4ad00ac18a948978bb3781cffa4305134d31801f3e26", - "sha256:3f0dae97e1126f529ebb66f3c63514a0f72a177b90d56e4bce8a0b5def34627a", - "sha256:50fb72bcbc2cf11e066579cb53c4ca8ac0227abb512b6cbc1faa02d1595a2a5d", - "sha256:57aea170fb23b1fd54fa537359d90d383d9bf5937ee54ae8045a723caa5e0961", - "sha256:709c2999b6bd36cdaf85cf888d8512da7433529f14a3689d6e37ab5242e7add5", - "sha256:7d59f21e43bbfd9a10953a7e26b35b6849d888fc5a331fa84a2d9c37bd9fe2a2", - "sha256:904b513ab8fbcbdb062bed1ce2f794ab20208a1b01ce9bd90776c6c7e7257032", - "sha256:96dd36f5cdde152fd6977d1bbc0f0561bccffecfde63cd397c8e6033eb66baba", - "sha256:9933b81fecbe935e6a7dc89cbd2b99fea1bf362f2790daf9422a7bb1dc3c3085", - "sha256:bbcc85aaf4cd84ba057decaead058f43191cc0e30d6bc5d44fe336dc3d3f4509", - "sha256:dccd380d8e025c867ddcb2f84b439722cf1f23f3a319381eac45fd077dee7170", - "sha256:e22cd0f72fc931d6abc69dc7764484ee20c6a60b0d0fee9ce0426029b1c1bdae", - "sha256:ed722aefb0ebffd10b32e67f48e8ac4c5c4cf5d3a785024fdf0e9eb17529cd9d", - "sha256:efb7ac5572c9a57159cf92c508aad9f856f1cb8e8302d7fdb99061dbe52d712c", - "sha256:efdba339fffb0e80fcc19524e4fdbda2e2b5772ea46720c44eaac28096d60720", - "sha256:f22273dd6a403ed870207b853a856ff6327d5cbce7a835dfa0645b3fc00273ec" - ], - "version": "==1.18.4" + "sha256:0028da01578ddb0d7372ccd168d7e7e3b04f25881db7f520bff6c50456aa7b02", + "sha256:09e0e60d6ed6417516a08f9767665ae459507dd1df63942e0c0bb69d93f05c0e", + "sha256:0bffe7f20aa96e3b16a99c5a38a6e3ebeeff9203c8000723f040c72746808c5b", + "sha256:1041dd124664263f1b9cde98028dd2d0f164a94b13a06183f27a7b7dd14767ad", + "sha256:164d8d2a0de07c3aba089e7db0873930ac05252d985c8825f247bd79ddf3bd9d", + "sha256:1ae657a2390cbc1553df60cb2a5f69742761d0ad5957b0113c9c00bb06276a78", + "sha256:1ae709f648755ce757ef896fb110c52cbc76bc787a1243ad9b1262be3cc01e64", + "sha256:1d84d42be12fc7d3e9afc2e381136e6a4a0aa509183166b99079fd87afb8a6a6", + "sha256:361c84cdf8e10a27d1ce7bb0404284eed2f704fb10ebbdb714fe5a51ef4f2765", + "sha256:59b4ace51c26d6f6698ebaee442a37d2f34415ad2d9c683e18bb462f50768697", + "sha256:5c1db3b05428c6c8397c2457063b16a03688f1d0531dac96afa46a0362a5f237", + "sha256:705551bb2fb68a3ee1c5868a24d9e57670324a2c25530e3846b58f111ca3bada", + "sha256:72a8744aa28d2f85629810aa13fe45b13992ca9566eade5fecb0e916d7df6c80", + "sha256:82a905f8d920aa1dc2d642a1e76ed54f2baa3eb23e2216bc6cd41ae2b274dded", + "sha256:876a0d72f16e60c34678ff52535d0ccdfb5718ed0ebac4ed50187bd6e06c1bac", + "sha256:8ac99d78e3ebc41b0dccf024a8dd36057abfa4dfcf3875259abf09da28e89fd2", + "sha256:8c4be83b9f253701ff865b6a9de26bbb67a3104486123347a3629101d3268a43", + "sha256:96578b9000e8ca35b83e96237d617345c4ac7bf8816cb950ddf76235b3b7306c", + "sha256:c39e84169f93899a15dbb7cbd3e68bd6bb31f56800658d966f89a2186eb4f929", + "sha256:c58eedde4999735da1d95a4af266a43ba1c32fbc2021941bb5149ad58da1312d", + "sha256:c995c832ddf4ce88b6383ce8c9160e86d614141412c0c874b6df87f680783528", + "sha256:d5833cb9cce627e960c87b75eb1878498cdf430155062f9423cee5617032284f", + "sha256:de874f2537e4e604c1db5905c4728b6b715c66a85bc71b5bc1b236973dc7610a", + "sha256:f45938abfa864e342f6719f05150f6458e018e22793a6fdf60e0ea4d4d15f53c", + "sha256:f6fe5dd6526fa6c0083fb5218a903dc9d9ea02df66996cd3be8c44c3b97894d5", + "sha256:fbd9dbb96fa22ee2f2cfad5311563a9df4528d3ac70f7635a9da0c7424ba4459" + ], + "version": "==1.19.0rc1" }, "onesignal-sdk": { "hashes": [ @@ -466,10 +472,10 @@ }, "packaging": { "hashes": [ - "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3", - "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752" + "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", + "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" ], - "version": "==20.3" + "version": "==20.4" }, "pathtools": { "hashes": [ @@ -589,11 +595,11 @@ }, "redis": { "hashes": [ - "sha256:6e9d2722a95d10ddf854596e66516d316d99c6a483e5db3b35c34e1158b2bfa1", - "sha256:a5b0e25890d216d8189636742c50ab992e42eea699bcc1b08cc2d6bf3adff52a" + "sha256:2ef11f489003f151777c064c5dbc6653dfb9f3eade159bcadc524619fddc2242", + "sha256:6d65e84bc58091140081ee9d9c187aab0480097750fac44239307a3bdf0b1251" ], "index": "pypi", - "version": "==3.5.1" + "version": "==3.5.2" }, "requests": { "hashes": [ @@ -615,10 +621,10 @@ }, "rq": { "hashes": [ - "sha256:c88623cd7528fad8620ee7a2d793493b85b63855f74a2da28c14671bab34a161", - "sha256:efabd10f27ef45414fc3e5f592110f699811b3ab9993ac40d78e87656423288a" + "sha256:318017229145a40d34c20bc21ecdcd8c217a326eb08c9bee249e8c9e09846e36", + "sha256:e6d82156eb43a8fffe451099a716114f5f163ec7603b6e8c8dab16a1b31f4547" ], - "version": "==1.4.0" + "version": "==1.4.1" }, "rq-scheduler": { "hashes": [ @@ -659,10 +665,10 @@ }, "six": { "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "version": "==1.14.0" + "version": "==1.15.0" }, "smmap": { "hashes": [ @@ -673,10 +679,10 @@ }, "soupsieve": { "hashes": [ - "sha256:e914534802d7ffd233242b785229d5ba0766a7f487385e3f714446a07bf540ae", - "sha256:fcd71e08c0aee99aca1b73f45478549ee7e7fc006d51b37bec9e9def7dc22b69" + "sha256:1634eea42ab371d3d346309b93df7870a88610f0725d47528be902a0d95ecc55", + "sha256:a59dc181727e95d25f781f0eb4fd1825ff45590ec8ff49eadfd7f1a537cc0232" ], - "version": "==2.0" + "version": "==2.0.1" }, "spectra": { "hashes": [ @@ -773,14 +779,6 @@ } }, "develop": { - "colorlog": { - "hashes": [ - "sha256:30aaef5ab2a1873dec5da38fd6ba568fa761c9fa10b40241027fa3edea47f3d2", - "sha256:732c191ebbe9a353ec160d043d02c64ddef9028de8caae4cfa8bd49b6afed53e" - ], - "index": "pypi", - "version": "==4.1.0" - }, "polib": { "hashes": [ "sha256:93b730477c16380c9a96726c54016822ff81acfa553977fdd131f2b90ba858d7",