Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 14 additions & 21 deletions evergreen/eg_app/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
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


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)
Expand Down Expand Up @@ -130,8 +130,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 = []
Expand All @@ -147,7 +145,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
Expand All @@ -168,7 +168,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"]
Expand All @@ -177,9 +176,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 = {
Expand All @@ -197,9 +195,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!
Expand All @@ -224,13 +220,12 @@ 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"]
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 {
Expand Down Expand Up @@ -264,25 +259,23 @@ 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)

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()

Expand Down
4 changes: 2 additions & 2 deletions evergreen/eg_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ 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):
return f"{self.user}: {self.caption}"

def get_likers_display(self):

likers = self.userLikes.all()
likers = self.users_who_liked.all()

number_of_likes = likers.count()

Expand Down
66 changes: 34 additions & 32 deletions evergreen/eg_app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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:
Expand All @@ -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)

Expand All @@ -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


Expand Down Expand Up @@ -148,39 +148,39 @@ 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:
post.delete()
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()
Expand Down Expand Up @@ -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 = []
Expand All @@ -232,15 +232,15 @@ 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)

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":
Expand All @@ -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})

Expand Down
11 changes: 7 additions & 4 deletions evergreen/evergreen/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@
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 # noqa: E402

application = ProtocolTypeRouter(
{
"http": django_asgi_app,
Expand Down
10 changes: 5 additions & 5 deletions evergreen/evergreen/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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/<uuid:pk>", 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/<uuid:pk>", 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"),
Expand Down
18 changes: 16 additions & 2 deletions evergreen/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions evergreen/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Loading