Skip to content
Open
4 changes: 2 additions & 2 deletions articles/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from collections import defaultdict
from datetime import timedelta
from typing import Counter, List, Optional
from urllib.parse import quote_plus, unquote
from urllib.parse import quote, quote_plus, unquote

from django.contrib.contenttypes.models import ContentType
from django.core.paginator import Paginator
Expand Down Expand Up @@ -168,7 +168,7 @@ def create_article(
f"New article submitted in {community.name}"
f" by {request.auth.username}"
),
link=f"/community/{community.name}/submissions",
link=f"/community/{quote(community.name, safe='')}/submissions",
content=article.title,
)
except Exception:
Expand Down
21 changes: 19 additions & 2 deletions communities/api_join.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import logging
from typing import List, Literal
from urllib.parse import quote

from django.utils import timezone
from ninja import Router
from ninja.responses import codes_4xx, codes_5xx

from communities.models import Community, JoinRequest
from communities.schemas import JoinRequestSchema, Message
from myapp.services.send_emails import send_join_decision_email, send_join_request_email
from users.auth import JWTAuth
from users.models import Notification

Expand Down Expand Up @@ -124,13 +126,18 @@ def join_community(request, community_id: int):
community=community,
notification_type="join_request_received",
message=f"New join request from {user.username}",
link=f"/community/{community.name}/requests",
link=f"/community/{quote(community.name, safe='')}/requests",
)
except Exception as e:
logger.error(f"Error creating notification: {e}")
# Continue even if notification fails
pass

try:
send_join_request_email(user, community)
except Exception as e:
logger.error(f"Error sending join request email: {e}")

return 200, {"message": "Your request to join the community has been sent."}
except Exception as e:
logger.error(f"Error processing join request: {e}")
Expand Down Expand Up @@ -204,13 +211,18 @@ def manage_join_request(
community=community,
notification_type="join_request_approved",
message=f"Your join request to {community.name} has been approved.",
link=f"/community/{community.name}",
link=f"/community/{quote(community.name, safe='')}",
)
except Exception as e:
logger.error(f"Error creating notification: {e}")
# Continue even if notification fails
pass

try:
send_join_decision_email(join_request.user, community, "approve")
except Exception as e:
logger.error(f"Error sending join decision email: {e}")

return 200, {
"message": f"Join request approved. \
{join_request.user.username} is now a member of the community."
Expand All @@ -227,6 +239,11 @@ def manage_join_request(
"message": "Error updating join request status. Please try again."
}

try:
send_join_decision_email(join_request.user, community, "reject")
except Exception as e:
logger.error(f"Error sending join decision email: {e}")

return 200, {
"message": "You have rejected the join request successfully."
}
Expand Down
3 changes: 2 additions & 1 deletion communities/articles_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from typing import List, Literal, Optional
from urllib.parse import quote

from django.core.paginator import Paginator
from django.db import transaction
Expand Down Expand Up @@ -119,7 +120,7 @@ def submit_article(request, community_name: str, article_slug: str):
message=(
f"New article submitted in {community.name} by {request.auth.username}"
),
link=f"/community/{community.name}/submissions",
link=f"/community/{quote(community.name, safe='')}/submissions",
content=article.title,
)
except Exception as e:
Expand Down
81 changes: 81 additions & 0 deletions myapp/services/send_emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,87 @@ def send_review_notification_email(article, review, community):
logger.error(f"Error sending review notification email: {e}")


def send_join_request_email(user, community):
admin = community.admins.first()
if not admin or not admin.email:
logger.warning(
f"Cannot send join request email: community {community.id} has no admin with email"
)
return

if not is_email_notifications_enabled(admin.id):
logger.debug(
f"Email notifications disabled for admin {admin.id}, skipping join request email"
)
return

domain = get_frontend_domain()
link = f"{domain}/community/{quote(community.name, safe='')}/requests"

context = {
"recipient_name": admin.first_name or admin.username,
"notification_type": "New Join Request",
"message_text": mark_safe(
f"<b>{user.username}</b> has requested to join the <b>{community.name}</b> community."
),
"content_preview": None,
"article_link": link,
}

send_email_task.delay(
subject=f"New Join Request for {community.name}",
html_template_name="review_comment_notification.html",
context=context,
recipient_list=[admin.email],
from_email=settings.DEFAULT_FROM_EMAIL,
)


def send_join_decision_email(user, community, action):
if not user or not user.email:
logger.warning(
f"Cannot send join decision email: user has no email for community {community.id}"
)
return

if not is_email_notifications_enabled(user.id):
logger.debug(
f"Email notifications disabled for user {user.id}, skipping join decision email"
)
return

domain = get_frontend_domain()

if action == "approve":
notification_type = "Join Request Approved"
message_text = mark_safe(
f"Your request to join <b>{community.name}</b> has been approved. Welcome!"
)
link = f"{domain}/community/{quote(community.name, safe='')}"
else:
notification_type = "Join Request Rejected"
message_text = mark_safe(
f"Your request to join <b>{community.name}</b> has been rejected."
)
link = f"{domain}/communities"

context = {
"recipient_name": user.first_name or user.username,
"notification_type": notification_type,
"message_text": message_text,
"content_preview": None,
"article_link": link,
}

send_email_task.delay(
subject=f"Community Join Request {action.capitalize()}d: {community.name}",
html_template_name="review_comment_notification.html",
context=context,
recipient_list=[user.email],
from_email=settings.DEFAULT_FROM_EMAIL,
)


def send_comment_notification_email(comment, review, article, community):
"""
Send email notification when a new comment/reply is added to a review.
Expand Down
4 changes: 2 additions & 2 deletions myapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@
"formatters": {
"detailed": {
"format": LOG_FORMAT,
"datefmt": "%Y-%m-%d %H:%M:%S,%f",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
"handlers": {
Expand Down Expand Up @@ -377,7 +377,7 @@
"formatters": {
"detailed": {
"format": LOG_FORMAT,
"datefmt": "%Y-%m-%d %H:%M:%S,%f",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
"handlers": {
Expand Down