From 2c28ec668e4fa3e64a5a26b84785884abe7df98a Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Thu, 26 Dec 2024 12:41:17 -0500 Subject: [PATCH 1/7] Added pep8-naming package. --- evergreen/poetry.lock | 18 ++++++++++++++++-- evergreen/pyproject.toml | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/evergreen/poetry.lock b/evergreen/poetry.lock index 2e29624..ff45a6d 100644 --- a/evergreen/poetry.lock +++ b/evergreen/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "asgiref" @@ -603,6 +603,20 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +[[package]] +name = "pep8-naming" +version = "0.14.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pep8-naming-0.14.1.tar.gz", hash = "sha256:1ef228ae80875557eb6c1549deafed4dabbf3261cfcafa12f773fe0db9be8a36"}, + {file = "pep8_naming-0.14.1-py3-none-any.whl", hash = "sha256:63f514fc777d715f935faf185dedd679ab99526a7f2f503abb61587877f7b1c5"}, +] + +[package.dependencies] +flake8 = ">=5.0.0" + [[package]] name = "pillow" version = "11.0.0" @@ -1107,4 +1121,4 @@ testing = ["coverage[toml]", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "9197387bd99d06c03cfc2705a593dacdea28ad62b9593e8dfc0754dd94741a21" +content-hash = "feb5c7b50940d40fadb2e735144268800e085c42fe4d8016a0bfad75da72baeb" diff --git a/evergreen/pyproject.toml b/evergreen/pyproject.toml index f8da298..23ca6cf 100644 --- a/evergreen/pyproject.toml +++ b/evergreen/pyproject.toml @@ -29,6 +29,7 @@ channels = "^4.2.0" daphne = "^4.1.2" uuid = "^1.30" what = "^0.5.0" +pep8-naming = "^0.14.1" [build-system] From 731df853f157f63a70411717f5e0164980cad61a Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Thu, 26 Dec 2024 12:55:45 -0500 Subject: [PATCH 2/7] Fixed pep8 namings. --- evergreen/eg_app/consumers.py | 34 ++++++++++-------- evergreen/eg_app/models.py | 4 +-- evergreen/eg_app/views.py | 66 ++++++++++++++++++----------------- evergreen/evergreen/urls.py | 10 +++--- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/evergreen/eg_app/consumers.py b/evergreen/eg_app/consumers.py index 3137a81..de49f7a 100644 --- a/evergreen/eg_app/consumers.py +++ b/evergreen/eg_app/consumers.py @@ -9,9 +9,11 @@ from channels.generic.websocket import AsyncWebsocketConsumer # from channels.layers import get_channel_layer -from django.apps import apps +# from django.apps import apps from django.core.files.base import ContentFile +from eg_app.models import Post + class FeedConsumer(AsyncWebsocketConsumer): MAX_FRAME_SIZE = 8000000 @@ -130,7 +132,7 @@ async def receive(self, text_data=None, bytes_data=None): @database_sync_to_async def get_all_posts(self): - Post = apps.get_model("eg_app", "Post") + # Post = apps.get_model("eg_app", "Post") posts = Post.objects.all().order_by("-timestamp") @@ -147,7 +149,9 @@ def get_all_posts(self): user_has_liked = False if current_user.is_authenticated: - user_has_liked = post.userLikes.filter(id=current_user.id).exists() + user_has_liked = post.users_who_liked.filter( + id=current_user.id + ).exists() post_data = { "id": str(post.id), # type: ignore @@ -168,7 +172,7 @@ def get_all_posts(self): @database_sync_to_async def handle_post_upload(self, data): - Post = apps.get_model("eg_app", "Post") + # Post = apps.get_model("eg_app", "Post") try: user = self.scope["user"] @@ -177,9 +181,9 @@ def handle_post_upload(self, data): return None caption = data.get("caption", "") - MAX_CHAR_LENGTH = 280 + max_char_length = 280 - if len(caption) > MAX_CHAR_LENGTH: + if len(caption) > max_char_length: return None post_data = { @@ -197,9 +201,9 @@ def handle_post_upload(self, data): format, imgstr = data["image"].split(";base64,") image_bytes = base64.b64decode(imgstr) - MAX_IMAGE_SIZE = 8000000 + max_image_size = 8000000 - if len(image_bytes) > MAX_IMAGE_SIZE: + if len(image_bytes) > max_image_size: return None # check the magic bytes! @@ -224,13 +228,13 @@ def handle_post_upload(self, data): @database_sync_to_async def get_post_data(self, post_id): - Post = apps.get_model("eg_app", "Post") + # Post = apps.get_model("eg_app", "Post") try: post = Post.objects.get(pk=post_id) user = self.scope["user"] has_liked = ( str(user.username) != "AnonymousUser" - and post.userLikes.filter(id=user.id).exists() # type: ignore + and post.users_who_liked.filter(id=user.id).exists() # type: ignore ) return { @@ -264,25 +268,25 @@ async def like_update(self, event): @database_sync_to_async def get_post(self, post_id): - Post = apps.get_model("eg_app", "Post") + # Post = apps.get_model("eg_app", "Post") return Post.objects.get(pk=post_id) @database_sync_to_async def update_like(self, post_id, user): - Post = apps.get_model("eg_app", "Post") + # Post = apps.get_model("eg_app", "Post") try: post = Post.objects.get(pk=post_id) if str(user.username) != "AnonymousUser": - if not post.userLikes.contains(user): # type: ignore + if not post.users_who_liked.contains(user): # type: ignore post.likes += 1 # type: ignore - post.userLikes.add(user) # type: ignore + post.users_who_liked.add(user) # type: ignore else: post.likes -= 1 # type: ignore - post.userLikes.remove(user) # type: ignore + post.users_who_liked.remove(user) # type: ignore post.save() diff --git a/evergreen/eg_app/models.py b/evergreen/eg_app/models.py index a8503f8..ff78a66 100644 --- a/evergreen/eg_app/models.py +++ b/evergreen/eg_app/models.py @@ -10,7 +10,7 @@ class Post(models.Model): image = models.ImageField(upload_to="image_upload", blank=True, null=True) caption = models.TextField(blank=True) timestamp = models.DateTimeField(auto_now_add=True) - userLikes = models.ManyToManyField(User, blank=True) + users_who_liked = models.ManyToManyField(User, blank=True) likes = models.PositiveIntegerField(default=0) def __str__(self): @@ -18,7 +18,7 @@ def __str__(self): def get_likers_display(self): - likers = self.userLikes.all() + likers = self.users_who_liked.all() number_of_likes = likers.count() diff --git a/evergreen/eg_app/views.py b/evergreen/eg_app/views.py index 93027a0..e314970 100644 --- a/evergreen/eg_app/views.py +++ b/evergreen/eg_app/views.py @@ -37,20 +37,20 @@ def index(request): return render(request, "index.html", {"hidden1": "hidden"}) -def getFileType(filePath: str) -> tuple[str | None, str | None]: +def get_file_type(file_path: str) -> tuple[str | None, str | None]: # returns tuple {type, encoding} - contentType = mimetypes.guess_type(filePath) - return contentType + content_type = mimetypes.guess_type(file_path) + return content_type -def fileHandler(request: HttpRequest, fileName: str) -> HttpResponse: +def file_handler(request: HttpRequest, filename: str) -> HttpResponse: # can handle img and text # get the absolute path - sanitizedFileName = quote(fileName) - path = Path(settings.STATIC_ROOT) / sanitizedFileName + sanitized_filename = quote(filename) + path = Path(settings.STATIC_ROOT) / sanitized_filename - allowedType: set[str] = { + allowed_types: set[str] = { ".css", ".html", ".js", @@ -66,16 +66,16 @@ def fileHandler(request: HttpRequest, fileName: str) -> HttpResponse: ".ico", } # can add more - if not str(path.suffix.lower()) in allowedType: # to deal with user uploads + if not str(path.suffix.lower()) in allowed_types: # to deal with user uploads return HttpResponseNotFound("404 - File type not allowed") # deal with /../ attacks - rootPath = Path(settings.STATIC_ROOT).resolve() - if not path.resolve().is_relative_to(rootPath): + root_path = Path(settings.STATIC_ROOT).resolve() + if not path.resolve().is_relative_to(root_path): return HttpResponseNotFound("404 Not Found") if path.exists() and path.is_file(): # make sure it's not a directory - contentType, encoding = getFileType(str(path)) + content_type, encoding = get_file_type(str(path)) try: with open(path, "rb") as file: @@ -84,8 +84,8 @@ def fileHandler(request: HttpRequest, fileName: str) -> HttpResponse: return HttpResponseNotFound("404 Not Found") # return render(request, '404.html', status=404) when making 404 pages - if contentType: - response = HttpResponse(content, content_type=contentType) + if content_type: + response = HttpResponse(content, content_type=content_type) else: response = HttpResponse(content) @@ -101,10 +101,10 @@ def fileHandler(request: HttpRequest, fileName: str) -> HttpResponse: return HttpResponseNotFound("404 Not Found") -def addCookies(response: HttpResponse, cookies: dict[str, str]) -> HttpResponse: +def add_cookies(response: HttpResponse, cookies: dict[str, str]) -> HttpResponse: """add all cookies from the give dic to the response""" - for cookieName, cookieValue in cookies.items(): - response.set_cookie(cookieName, cookieValue) + for cookie_name, cookie_value in cookies.items(): + response.set_cookie(cookie_name, cookie_value) return response @@ -148,7 +148,7 @@ def register(request: HttpRequest) -> HttpResponse: return HttpResponseRedirect(ROOT_PATH) -def deletePost(request, pk): +def delete_post(request, pk): post = Post.objects.get(pk=pk) if post.user == request.user: @@ -156,31 +156,31 @@ def deletePost(request, pk): return redirect("/") -def dislikePost(request, pk): +def dislike_post(request, pk): post = Post.objects.get(pk=pk) - if post.userLikes.contains(request.user): + if post.users_who_liked.contains(request.user): post.likes -= 1 - post.userLikes.remove(request.user) + post.users_who_liked.remove(request.user) post.save() return redirect("/") -def addComment(request, postId): - post = Post.objects.get(id=postId) +def add_comment(request, post_id): + post = Post.objects.get(id=post_id) # user = request.user.email user = "guest@buffalo.edu" comment = request.POST["comment"] comment = html.escape(comment) - postComment = Comments.objects.create(post=post, user=user, comment=comment) - postComment.save() + post_comment = Comments.objects.create(post=post, user=user, comment=comment) + post_comment.save() return redirect("/") -def deleteComment(request, commentId): - comment = Comments.objects.get(commentId) +def delete_comment(request, comment_id): + comment = Comments.objects.get(comment_id) if comment.user == request.user: comment.delete() @@ -218,7 +218,7 @@ def login_view(request: HttpRequest): return HttpResponseBadRequest() -def updateFeed(request) -> JsonResponse: +def update_feed(request) -> JsonResponse: posts = Post.objects.all().order_by("-timestamp") posts_data = [] @@ -232,7 +232,7 @@ def updateFeed(request) -> JsonResponse: "likes": post.likes, "likers_display": post.get_likers_display(), "has_liked": current_user.is_authenticated - and post.userLikes.filter(id=current_user.id).exists(), + and post.users_who_liked.filter(id=current_user.id).exists(), "comments": [], } posts_data.append(post_dict) @@ -240,7 +240,7 @@ def updateFeed(request) -> JsonResponse: return JsonResponse({"posts": posts_data}) -def likePost(request, pk) -> JsonResponse: +def like_post(request, pk) -> JsonResponse: user_who_is_liking = request.user if request.method == "POST": @@ -249,12 +249,14 @@ def likePost(request, pk) -> JsonResponse: if str( user_who_is_liking.username - ) != "AnonymousUser" and not post.userLikes.contains(user_who_is_liking): + ) != "AnonymousUser" and not post.users_who_liked.contains( + user_who_is_liking + ): post.likes += 1 - post.userLikes.add(user_who_is_liking) + post.users_who_liked.add(user_who_is_liking) elif str(user_who_is_liking.username) != "AnonymousUser": post.likes -= 1 - post.userLikes.remove(user_who_is_liking) + post.users_who_liked.remove(user_who_is_liking) post.save() return JsonResponse({"status": "success", "likes": post.likes}) diff --git a/evergreen/evergreen/urls.py b/evergreen/evergreen/urls.py index 197af0b..ee6b8f8 100644 --- a/evergreen/evergreen/urls.py +++ b/evergreen/evergreen/urls.py @@ -28,11 +28,11 @@ path("admin/", admin.site.urls), path("", views.index, name="index"), path("validate", views.validate, name="validate"), - path("updateFeed", views.updateFeed, name="updateFeed"), - path("deletePost", views.deletePost, name="deletePost"), - path("likePost/", views.likePost, name="likePost"), - path("addComment", views.addComment, name="addComment"), - path("deleteComment", views.deleteComment, name="deleteComment"), + path("updateFeed", views.update_feed, name="updateFeed"), + path("deletePost", views.delete_post, name="deletePost"), + path("likePost/", views.like_post, name="likePost"), + path("addComment", views.add_comment, name="addComment"), + path("deleteComment", views.delete_comment, name="deleteComment"), path("register", views.register, name="register"), path("login", views.login_view, name="login"), path("logout", views.logout_view, name="logout"), From 7a0dba1521435927fe269c1bc53455f2b47f4f84 Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Thu, 26 Dec 2024 19:00:39 -0500 Subject: [PATCH 3/7] Fixed the order of imports in the asgi.py to fix an issue where django container would conitnue to fail and restart due to not being able to find settings. --- evergreen/evergreen/asgi.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/evergreen/evergreen/asgi.py b/evergreen/evergreen/asgi.py index b5f1d16..e272db7 100644 --- a/evergreen/evergreen/asgi.py +++ b/evergreen/evergreen/asgi.py @@ -7,20 +7,21 @@ https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ """ +# CAUTION: Do not put any custom imports until after the application has been gotten with django_asgi_app = get_asgi_application() +# source: https://channels.readthedocs.io/en/latest/deploying.html#configuring-the-asgi-application import os - -# import django from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from channels.security.websocket import AllowedHostsOriginValidator from django.core.asgi import get_asgi_application -from eg_app.routing import websocket_urlpatterns - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "evergreen.settings") - django_asgi_app = get_asgi_application() +# Define your custom imports from here... +from eg_app.routing import websocket_urlpatterns + + application = ProtocolTypeRouter( { "http": django_asgi_app, From e38f98166a973f38d9cb138b134155fe88a07f3b Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Thu, 26 Dec 2024 19:05:47 -0500 Subject: [PATCH 4/7] linter. --- evergreen/evergreen/asgi.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/evergreen/evergreen/asgi.py b/evergreen/evergreen/asgi.py index e272db7..f8f118f 100644 --- a/evergreen/evergreen/asgi.py +++ b/evergreen/evergreen/asgi.py @@ -7,9 +7,12 @@ https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ """ -# CAUTION: Do not put any custom imports until after the application has been gotten with django_asgi_app = get_asgi_application() -# source: https://channels.readthedocs.io/en/latest/deploying.html#configuring-the-asgi-application +# CAUTION: Do not put any custom imports until after the application has been gotten +# with django_asgi_app = get_asgi_application() +# source: +# https://channels.readthedocs.io/en/latest/deploying.html#configuring-the-asgi-application import os + from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from channels.security.websocket import AllowedHostsOriginValidator @@ -19,8 +22,7 @@ django_asgi_app = get_asgi_application() # Define your custom imports from here... -from eg_app.routing import websocket_urlpatterns - +from eg_app.routing import websocket_urlpatterns # noqa: E402 application = ProtocolTypeRouter( { From bd099d5925ce5789e19347c62a9d7a559e643f10 Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Sat, 28 Dec 2024 19:05:00 -0500 Subject: [PATCH 5/7] constants to screaming snake --- evergreen/eg_app/consumers.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/evergreen/eg_app/consumers.py b/evergreen/eg_app/consumers.py index de49f7a..805ea58 100644 --- a/evergreen/eg_app/consumers.py +++ b/evergreen/eg_app/consumers.py @@ -16,7 +16,9 @@ class FeedConsumer(AsyncWebsocketConsumer): - MAX_FRAME_SIZE = 8000000 + MAX_FRAME_SIZE = 8_000_000 + MAX_IMAGE_SIZE_BYTES = 8_000_000 + MAX_CHARACTERS_IN_MESSAGE = 280 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -181,9 +183,8 @@ def handle_post_upload(self, data): return None caption = data.get("caption", "") - max_char_length = 280 - if len(caption) > max_char_length: + if len(caption) > self.MAX_CHARACTERS_IN_MESSAGE: return None post_data = { @@ -201,9 +202,7 @@ def handle_post_upload(self, data): format, imgstr = data["image"].split(";base64,") image_bytes = base64.b64decode(imgstr) - max_image_size = 8000000 - - if len(image_bytes) > max_image_size: + if len(image_bytes) > self.MAX_IMAGE_SIZE_BYTES: return None # check the magic bytes! From 55b69a40250a0841f9d13b706079250fd8e1d306 Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Sat, 28 Dec 2024 21:31:44 -0500 Subject: [PATCH 6/7] Removed old commented out code and imports related to the app model get hack. --- evergreen/eg_app/consumers.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/evergreen/eg_app/consumers.py b/evergreen/eg_app/consumers.py index 805ea58..dd0f52d 100644 --- a/evergreen/eg_app/consumers.py +++ b/evergreen/eg_app/consumers.py @@ -4,12 +4,9 @@ import uuid from imghdr import what -# from asgiref.sync import async_to_sync from channels.db import database_sync_to_async from channels.generic.websocket import AsyncWebsocketConsumer -# from channels.layers import get_channel_layer -# from django.apps import apps from django.core.files.base import ContentFile from eg_app.models import Post @@ -134,8 +131,6 @@ async def receive(self, text_data=None, bytes_data=None): @database_sync_to_async def get_all_posts(self): - # Post = apps.get_model("eg_app", "Post") - posts = Post.objects.all().order_by("-timestamp") all_posts_data = [] @@ -174,7 +169,6 @@ def get_all_posts(self): @database_sync_to_async def handle_post_upload(self, data): - # Post = apps.get_model("eg_app", "Post") try: user = self.scope["user"] @@ -227,7 +221,6 @@ def handle_post_upload(self, data): @database_sync_to_async def get_post_data(self, post_id): - # Post = apps.get_model("eg_app", "Post") try: post = Post.objects.get(pk=post_id) user = self.scope["user"] @@ -267,12 +260,10 @@ async def like_update(self, event): @database_sync_to_async def get_post(self, post_id): - # Post = apps.get_model("eg_app", "Post") return Post.objects.get(pk=post_id) @database_sync_to_async def update_like(self, post_id, user): - # Post = apps.get_model("eg_app", "Post") try: post = Post.objects.get(pk=post_id) From eddaed697717a1fd6566d0a5bfcdc374b9526dc2 Mon Sep 17 00:00:00 2001 From: Eric-Butcher Date: Sat, 28 Dec 2024 22:44:26 -0500 Subject: [PATCH 7/7] linting. --- evergreen/eg_app/consumers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/evergreen/eg_app/consumers.py b/evergreen/eg_app/consumers.py index dd0f52d..eebe77d 100644 --- a/evergreen/eg_app/consumers.py +++ b/evergreen/eg_app/consumers.py @@ -6,7 +6,6 @@ from channels.db import database_sync_to_async from channels.generic.websocket import AsyncWebsocketConsumer - from django.core.files.base import ContentFile from eg_app.models import Post