Skip to content

Commit d5571bd

Browse files
authored
Merge pull request #127 from Zohair-coder/dev
Dev
2 parents fda5c15 + b09e201 commit d5571bd

File tree

4 files changed

+141
-17
lines changed

4 files changed

+141
-17
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,23 @@ python src/main.py
4444

4545
The scraper will output a JSON file called `data.json` in the same directory as the scraper.
4646

47-
You can modify the scraper to scrape other terms by changing the `year`, `quarter`, and `college_code` variables in `src/config.py`.
47+
#### Automatic Quarter Detection
48+
49+
The scraper now automatically detects the current Drexel quarter based on the current date. You no longer need to manually update the `year` and `quarter` values in `src/config.py`. The system uses the following schedule:
50+
51+
- **Fall Quarter (15)**: July 1 - September 27
52+
- **Winter Quarter (25)**: September 28 - January 15
53+
- **Spring Quarter (35)**: January 16 - April 14
54+
- **Summer Quarter (45)**: April 15 - June 30
55+
56+
If you need to override the automatic detection (e.g., for testing or scraping a specific past/future quarter), you can set the `DREXEL_YEAR` and `DREXEL_QUARTER` environment variables:
57+
58+
```bash
59+
export DREXEL_YEAR=2024
60+
export DREXEL_QUARTER=35 # Spring quarter
61+
```
62+
63+
You can still modify the `college_code` variable in `src/config.py` to scrape a specific college.
4864

4965
To view all the options that the scraper supports, run `python3 src/main.py --help` on Mac/Linux, or `python src/main.py --help` on Windows.
5066

src/config.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
import os
22
import sys
33

4-
# in format YYYY (e.g. 2022)
5-
# example value: 2022
6-
year = "2024"
7-
# 15 for Fall, 25 for Winter, 35 for Spring, 45 for Summer
8-
# example value: 45
9-
quarter = "45"
10-
# check college code by going to the tms website and selecting your college from the left sidebar
4+
from quarter_utils import get_current_quarter_and_year, get_quarter_name
5+
6+
# Automatically determine the current quarter and year
7+
# Can be overridden with DREXEL_YEAR and DREXEL_QUARTER environment variables
8+
if "DREXEL_YEAR" in os.environ and "DREXEL_QUARTER" in os.environ:
9+
year = os.environ["DREXEL_YEAR"]
10+
quarter = os.environ["DREXEL_QUARTER"]
11+
print(
12+
f"Using manually configured {get_quarter_name(quarter)} {year} "
13+
f"quarter (code: {quarter})"
14+
)
15+
else:
16+
year, quarter = get_current_quarter_and_year()
17+
print(
18+
f"Using auto-detected {get_quarter_name(quarter)} {year} "
19+
f"quarter (code: {quarter})"
20+
)
21+
22+
# Note: These values are now automatically determined based on the current date
23+
# Fall (15): July 1 - September 27
24+
# Winter (25): September 28 - January 15
25+
# Spring (35): January 16 - April 14
26+
# Summer (45): April 15 - June 30
27+
# check college code by going to the tms website and selecting your college
28+
# from the left sidebar
1129
# the URL bar should update and it should end with something like collCode=CI
1230
# the characters after the = sign is your college code
1331
# e.g. in this URL the college code is CI
@@ -27,7 +45,9 @@ def get_environ(key: str, required: bool = True) -> str:
2745
return os.environ[key]
2846
elif required:
2947
print(
30-
f"{key} is missing from your environment variables and is required to run this script. See {environ_help_url} for more information and help."
48+
f"{key} is missing from your environment variables and is required "
49+
f"to run this script. See {environ_help_url} for more information "
50+
f"and help."
3151
)
3252
sys.exit(1)
3353
else:
@@ -37,7 +57,8 @@ def get_environ(key: str, required: bool = True) -> str:
3757
# Drexel Connect Credentials
3858
drexel_email = get_environ("DREXEL_EMAIL")
3959
drexel_password = get_environ("DREXEL_PASSWORD")
40-
# This is not required if the user is using a separate authenticator app and will manually approve the login attempt
60+
# This is not required if the user is using a separate authenticator app
61+
# and will manually approve the login attempt
4162
drexel_mfa_secret_key = get_environ("DREXEL_MFA_SECRET_KEY", False) or None
4263

4364
# URL's

src/db.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from datetime import datetime
1717
from pytz import timezone
1818
from typing import Any
19+
import config
20+
from quarter_utils import get_quarter_name
1921

2022

2123
def populate_db(data: dict[str, dict[str, Any]]) -> None:
@@ -212,14 +214,27 @@ def create_tables(cur: cursor) -> None:
212214
def update_metadata(cur: cursor) -> None:
213215
tz = timezone("US/Eastern")
214216
current_datetime = datetime.now(tz).strftime("%m/%d/%y %I:%M %p")
215-
cur.execute(
217+
218+
# Get current quarter information
219+
quarter_name = get_quarter_name(config.quarter)
220+
221+
# Update multiple metadata values
222+
metadata_updates = [
223+
("last_updated", current_datetime),
224+
("current_year", config.year),
225+
("current_quarter", config.quarter),
226+
("current_quarter_name", quarter_name),
227+
("current_term", f"{quarter_name} {config.year}"),
228+
]
229+
230+
cur.executemany(
216231
"""
217-
INSERT INTO metadata (key, value)
218-
VALUES ('last_updated', %s)
219-
ON CONFLICT (key)
220-
DO UPDATE SET value = EXCLUDED.value;
221-
""",
222-
(current_datetime,),
232+
INSERT INTO metadata (key, value)
233+
VALUES (%s, %s)
234+
ON CONFLICT (key)
235+
DO UPDATE SET value = EXCLUDED.value;
236+
""",
237+
metadata_updates,
223238
)
224239

225240

src/quarter_utils.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""Utilities for determining the current Drexel quarter based on date."""
2+
3+
from datetime import datetime
4+
5+
6+
def get_current_quarter_and_year() -> tuple[str, str]:
7+
"""
8+
Determine the current Drexel quarter and year based on the current date.
9+
10+
Drexel quarters:
11+
- Fall (15): July 1 - September 27
12+
- Winter (25): September 28 - January 15
13+
- Spring (35): January 16 - April 14
14+
- Summer (45): April 15 - June 30
15+
16+
Returns:
17+
Tuple of (year, quarter_code) as strings
18+
"""
19+
now = datetime.now()
20+
month = now.month
21+
day = now.day
22+
year = now.year
23+
24+
# Determine quarter based on month and day
25+
if month == 7 or month == 8 or (month == 9 and day <= 27):
26+
# Fall quarter
27+
quarter = "15"
28+
elif (
29+
(month == 9 and day >= 28)
30+
or month == 10
31+
or month == 11
32+
or month == 12
33+
or (month == 1 and day <= 15)
34+
):
35+
# Winter quarter
36+
quarter = "25"
37+
elif (
38+
(month == 1 and day >= 16)
39+
or month == 2
40+
or month == 3
41+
or (month == 4 and day <= 14)
42+
):
43+
# Spring quarter
44+
quarter = "35"
45+
else:
46+
# Summer quarter (April 15 - June 30)
47+
quarter = "45"
48+
49+
# For Winter quarter spanning two calendar years (Sept 28 - Jan 15),
50+
# if we're in January, it belongs to the previous year's academic year
51+
if quarter == "25" and month == 1:
52+
year = year - 1
53+
54+
return str(year), quarter
55+
56+
57+
def get_quarter_name(quarter_code: str) -> str:
58+
"""Get the human-readable name for a quarter code."""
59+
quarter_names = {
60+
"15": "Fall",
61+
"25": "Winter",
62+
"35": "Spring",
63+
"45": "Summer",
64+
}
65+
return quarter_names.get(quarter_code, "Unknown")
66+
67+
68+
if __name__ == "__main__":
69+
# Test the function
70+
year, quarter = get_current_quarter_and_year()
71+
quarter_name = get_quarter_name(quarter)
72+
print(f"Current quarter: {quarter_name} {year} (code: {quarter})")

0 commit comments

Comments
 (0)