Skip to content

Commit

Permalink
run precommit
Browse files Browse the repository at this point in the history
  • Loading branch information
pinwheeeel committed Jan 28, 2025
1 parent 2b1eb82 commit acd4f5e
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 66 deletions.
12 changes: 7 additions & 5 deletions core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
UserAdminForm,
UserCreationAdminForm,
LateStartEventForm,
DailyAnnouncementAdminForm
DailyAnnouncementAdminForm,
)
from .models import Comment, StaffMember
from .utils.actions import (
Expand Down Expand Up @@ -198,16 +198,18 @@ def formfield_for_manytomany(self, db_field, request, **kwargs):
kwargs["queryset"] = models.Tag.objects.all()
return super().formfield_for_manytomany(db_field, request, **kwargs)


class DailyAnnouncementAdmin(admin.ModelAdmin):
list_display = ['organization', 'start_date', 'end_date']
list_filter = ['organization', 'start_date', 'end_date']
ordering = ['start_date']
list_display = ["organization", "start_date", "end_date"]
list_filter = ["organization", "start_date", "end_date"]
ordering = ["start_date"]

def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs["form"] = DailyAnnouncementAdminForm
return super().get_form(request, obj, **kwargs)


class PostAdmin(admin.ModelAdmin):
readonly_fields = ["like_count", "save_count", "comments"]
fields = ["like_count", "save_count", "comments"]
Expand Down
8 changes: 5 additions & 3 deletions core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,16 @@ class Meta:


class DailyAnnouncementAdminForm(forms.ModelForm):

def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get("start_date")
end_date = cleaned_data.get("end_date")

if start_date != None and end_date != None and start_date > end_date:
raise forms.ValidationError({"start_date": "Start date cannot be after end date"})
if start_date is not None and end_date is not None and start_date > end_date:
raise forms.ValidationError(
{"start_date": "Start date cannot be after end date"}
)


class AnnouncementAdminForm(forms.ModelForm):
status = forms.ChoiceField(
Expand Down
26 changes: 11 additions & 15 deletions core/management/commands/auth_google.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,41 @@
from django.conf import settings
from core.tasks import load_client
from pathlib import Path
import gspread
import gspread


class Command(BaseCommand):
help = "Authenticates Google Account"

def handle(self, *args, **options):

SECRETS_PATH = settings.SECRETS_PATH

CLIENT_PATH = SECRETS_PATH + "/client_secret.json"
AUTHORIZED_PATH = SECRETS_PATH + "/authorized_user.json"

client, error_msg, client_path_exists = load_client()

if client is None:
if not client_path_exists:
raise CommandError(error_msg)
elif Path(AUTHORIZED_PATH).is_file():
user = input(f"Delete authorized_user.json located at {AUTHORIZED_PATH}? [Y/n] ")
user = input(
f"Delete authorized_user.json located at {AUTHORIZED_PATH}? [Y/n] "
)
if user.strip().lower() not in ["yes", "y", ""]:
raise CommandError("Failed to authenticate")

Path(AUTHORIZED_PATH).unlink()

try:
scopes = gspread.auth.READONLY_SCOPES

gspread.oauth(
credentials_filename=CLIENT_PATH,
authorized_user_filename=AUTHORIZED_PATH,
scopes=scopes,
)
except Exception as e:
except Exception:
raise CommandError("Failed to authenticate")

self.stdout.write(
self.style.SUCCESS("Successfully authenticated")
)




self.stdout.write(self.style.SUCCESS("Successfully authenticated"))
8 changes: 6 additions & 2 deletions core/models/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ class Meta:
]
permissions = (("view_flagged", "View flagged comments"),)


class DailyAnnouncement(models.Model):
organization = models.CharField(max_length=100)
content = models.TextField()
Expand All @@ -206,8 +207,11 @@ def __str__(self) -> str:
return self.content[:75]

@classmethod
def get_todays_announcements(cls) -> QuerySet[Self]:
return cls.objects.filter(start_date__lte=timezone.now(), end_date__gte=timezone.now())
def get_todays_announcements(cls) -> QuerySet:
return cls.objects.filter(
start_date__lte=timezone.now(), end_date__gte=timezone.now()
)


class Post(models.Model):
author = models.ForeignKey(
Expand Down
90 changes: 51 additions & 39 deletions core/tasks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import datetime as dt
import functools
from pathlib import Path
Expand All @@ -22,7 +21,7 @@
from oauth2_provider.models import clear_expired
from requests.exceptions import ConnectionError, HTTPError

import gspread
import gspread
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request

Expand Down Expand Up @@ -63,7 +62,9 @@ def setup_periodic_tasks(sender, **kwargs):
crontab(hour=1, minute=0), clear_expired
) # Delete expired oauth2 tokens from db everyday at 1am

sender.add_periodic_task(crontab(hour=8, minute=0, day_of_week="mon-fri"), fetch_announcements)
sender.add_periodic_task(
crontab(hour=8, minute=0, day_of_week="mon-fri"), fetch_announcements
)


@app.task
Expand Down Expand Up @@ -246,56 +247,56 @@ def notif_single(self, recipient_id: int, msg_kwargs):

def load_client() -> tuple[gspread.Client | None, str | None, bool]:
"""
Returns a client from authorized_user.json file
Returns a client from authorized_user.json file
:returns: Tuple with the client, error message and
whether the client secret file exists
:returns: Tuple with the client, error message and
whether the client secret file exists
"""
CLIENT_PATH = settings.SECRETS_PATH + "/client_secret.json"
AUTHORIZED_PATH = settings.SECRETS_PATH + "/authorized_user.json"

if not Path(settings.SECRETS_PATH).is_dir():
return (None, f"{settings.SECRETS_PATH} directory does not exist", False)

if not Path(CLIENT_PATH).is_file():
return (None, f"{CLIENT_PATH} does not exist", False)
client = None

client = None
scopes = gspread.auth.READONLY_SCOPES

if Path(AUTHORIZED_PATH).is_file():
creds = None
creds = None

try:
creds = Credentials.from_authorized_user_file(AUTHORIZED_PATH, scopes)
except Exception as e:
return (None, "Failed to load credentials", True)
except Exception:
return (None, "Failed to load credentials", True)

if not creds.valid and creds.expired and creds.refresh_token:

try:
creds.refresh(Request())
except Exception as e:
except Exception:
return (None, "Failed to refresh credentials", True)

with open(AUTHORIZED_PATH, "w") as f:
f.write(creds.to_json())

try:
client = gspread.authorize(creds)
except Exception as e:
except Exception:
return (None, "Failed to authorize credentials", True)

return (client, None, True)
return (client, None, True)

else:
return (None, "No file to load client from", True)
return (None, "No file to load client from", True)


@app.task
def fetch_announcements():
if settings.GOOGLE_SHEET_KEY == "" or settings.GOOGLE_SHEET_KEY is None:
logger.warning(f"Fetch Announcements: GOOGLE_SHEET_KEY is empty")
return
logger.warning("Fetch Announcements: GOOGLE_SHEET_KEY is empty")
return

client, error_msg, client_path_exists = load_client()

Expand All @@ -304,30 +305,39 @@ def fetch_announcements():
logger.warning(f"Fetch Announcements: {error_msg} - Run auth_google to fix")
else:
logger.warning(f"Fetch Announcements: {error_msg}")
return
worksheet = None

return

worksheet = None

try:
worksheet = client.open_by_key(settings.GOOGLE_SHEET_KEY).sheet1
except Exception as e:
worksheet = client.open_by_key(settings.GOOGLE_SHEET_KEY).sheet1
except Exception:
logger.warning("Fetch Announcements: Failed to open google sheet")
return

row_counter = 1
row_counter = 1
while True:

data = []
data = []

try:
data = [value.strip() for value in worksheet.row_values(row_counter)]
except:
except Exception:
logger.warning(f"Fetch Announcements: Failed to read row {row_counter}")
break
break

if row_counter == 1:
if data != ['Timestamp', 'Email Address', "Today's Date", 'Student Name (First and Last Name), if applicable.', 'Staff Advisor', 'Club', 'Start Date announcement is to be read (max. 3 consecutive school days).', 'End Date announcement is to be read', 'Announcement to be read (max 75 words)']:
if data != [
"Timestamp",
"Email Address",
"Today's Date",
"Student Name (First and Last Name), if applicable.",
"Staff Advisor",
"Club",
"Start Date announcement is to be read (max. 3 consecutive school days).",
"End Date announcement is to be read",
"Announcement to be read (max 75 words)",
]:
logger.warning("Fetch Announcements: Header row does not match")
break
else:
Expand All @@ -336,14 +346,16 @@ def fetch_announcements():
else:
try:
parsed_data = {
"organization": data[5],
"start_date": dt.datetime.strptime(data[6],'%m/%d/%Y'),
"end_date": dt.datetime.strptime(data[7],'%m/%d/%Y'),
"content": data[8]
}
"organization": data[5],
"start_date": dt.datetime.strptime(data[6], "%m/%d/%Y"),
"end_date": dt.datetime.strptime(data[7], "%m/%d/%Y"),
"content": data[8],
}

DailyAnnouncement.objects.get_or_create(**parsed_data)
except:
logger.warning(f"Fetch Announcements: Failed to parse or create object for row {row_counter}")
except Exception:
logger.warning(
f"Fetch Announcements: Failed to parse or create object for row {row_counter}"
)

row_counter += 1
row_counter += 1
2 changes: 1 addition & 1 deletion metropolis/local_settings_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import sentry_sdk

# Daily Announcements
# Daily Announcements

GOOGLE_SHEET_ID = ""
SECRETS_PATH = ""
Expand Down
2 changes: 1 addition & 1 deletion metropolis/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,4 +600,4 @@ def set_maintenance():
THEME_LOGO = THEMES[CURRENT_THEME]["logo"]
THEME_CSS = THEMES[CURRENT_THEME]["theme"]

SPECTACULAR_SETTINGS.update(SWAGGER_UI_FAVICON_HREF=THEME_LOGO)
SPECTACULAR_SETTINGS.update(SWAGGER_UI_FAVICON_HREF=THEME_LOGO)

0 comments on commit acd4f5e

Please sign in to comment.