Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Track Professor/Course visits #73

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
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
22 changes: 21 additions & 1 deletion core/daos/courses.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from .utils import to_where, fetchone_as_dict, fetchone, fetchall
from .utils import to_where, fetchone_as_dict, fetchone, fetchall, insert


def course_select_summary(dept, course_number):
query = "SELECT * from courses where department=%s and course_number=%s"
return fetchone_as_dict(query, dept, course_number)


def course_insert_view(dept, course_number):
insert("courses_visits", {"course_number": course_number, "department": dept})


def course_select_paginated_reviews(dept, course_number, limit, page, tags=[]):
query = """
SELECT r.*, u.name AS reviewer_name, u.username AS reviewer_username, p.id AS professor_id, p.name AS professor_name, p.email AS professor_email
Expand Down Expand Up @@ -251,3 +255,19 @@ def course_search_by_similarity_count(
full_query,
*([query, *list(filter(lambda x: x is not None, args.values()))] * 2),
)


def course_select_most_visited(limit: int, start_time: str):
"""
Select the most visited courses that were visited after
start_time
"""
query = f"""
SELECT course_number, department, COUNT(*) AS visits FROM courses_visits
WHERE created_at > %s
GROUP BY (course_number, department)
ORDER BY COUNT(*) DESC
LIMIT %s
"""

return fetchall(query, start_time, limit)
22 changes: 21 additions & 1 deletion core/daos/professors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .utils import fetchone, fetchone_as_dict, fetchall
from .utils import fetchone, fetchone_as_dict, fetchall, insert


# SUMMARY
Expand All @@ -7,6 +7,10 @@ def professor_select_summary(professor_id):
return fetchone_as_dict(query, professor_id)


def professor_insert_view(professor_id):
insert("professor_visits", {"professor_id": professor_id})


# STATS
def professor_select_average_grade(professor_id):
query = "SELECT get_professor_average_grade(%s)"
Expand Down Expand Up @@ -122,3 +126,19 @@ def professor_search_by_last_name_count(last_name_start: str):
name ~ ' {last_name_start}[^\\s]*$'
"""
return fetchone(sql_query)[0]


def professor_select_most_visited(limit: int, start_time: str):
"""
Select the most visited professors that were visited after
start_time
"""
query = f"""
SELECT professor_id, COUNT(*) AS visits FROM professor_visits
WHERE created_at > %s
GROUP BY (professor_id)
ORDER BY COUNT(*) DESC
LIMIT %s
"""

return fetchall(query, start_time, limit)
31 changes: 31 additions & 0 deletions core/services/courses.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime, timedelta
from core.daos import (
course_select_average_rating,
course_select_average_quality,
Expand All @@ -13,9 +14,39 @@
course_search_by_filters_count,
course_search_by_similarity,
course_search_by_similarity_count,
course_select_summary,
course_insert_view,
course_select_most_visited,
)


def get_course_most_visited():
last_month = datetime.now() - timedelta(weeks=4)
most_visited = course_select_most_visited(
3, last_month.isoformat(sep=" ", timespec="seconds")
)
if len(most_visited) == 0:
# no one visited our site in the past month...
# so just return the most visited overall (starting from epoch)
most_visited = course_select_most_visited(3, "1970-01-01 00:00:00")
return {
"most_visited": [
get_course_reviews_stats(el["department"], el["course_number"])
| course_select_summary(el["department"], el["course_number"])
| {"visits": el["visits"]}
for el in most_visited
]
}


def get_course_summary(dept, course_number):
"""
Inserts a visit into courses_visits and returns the summary
"""
course_insert_view(dept, course_number)
return course_select_summary(dept, course_number)


def get_course_reviews_stats(dept, course_number):
return {
"department": dept,
Expand Down
29 changes: 29 additions & 0 deletions core/services/professors.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import datetime, timedelta

from core.daos import (
professor_select_average_rating,
professor_select_average_quality,
Expand All @@ -17,9 +19,36 @@
professor_search_by_similarity_tags,
professor_search_by_last_name,
professor_search_by_last_name_count,
professor_insert_view,
professor_select_summary,
professor_select_most_visited,
)


def get_professor_most_visited():
last_month = datetime.now() - timedelta(weeks=4)
most_visited = professor_select_most_visited(
3, last_month.isoformat(sep=" ", timespec="seconds")
)
if len(most_visited) == 0:
# no one visited our site in the past month...
# so just return the most visited overall (starting from epoch)
most_visited = professor_select_most_visited(3, "1970-01-01 00:00:00")
return {
"most_visited": [
get_professor_reviews_stats(el["professor_id"])
| professor_select_summary(el["professor_id"])
| {"visits": el["visits"]}
for el in most_visited
]
}


def get_professor_summary(professor_id: str):
professor_insert_view(professor_id)
return professor_select_summary(professor_id)


def get_professor_reviews_stats(professor_id: str):
return {
"avg_rating": professor_select_average_rating(professor_id),
Expand Down
2 changes: 2 additions & 0 deletions core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"courses/<str:department>-<str:course_number>/reviews",
views.course_reviews_view,
),
path("courses/most_visited", views.course_most_visited_view),
# path('courses/<str:course>/reviews/comments', views.review_comments),
# ############### professor paths ###################
path("professors/<str:professor_id>/summary", views.professor_summary_view),
Expand All @@ -32,6 +33,7 @@
),
path("professors/<str:professor_id>/reviews", views.professor_reviews_view),
path("professors/search", views.professor_search_view),
path("professors/most_visited", views.professor_most_visited_view),
# ############## schedule search ####################
path("schedules/search", views.schedule_search_view),
# ############## departments paths ####################
Expand Down
13 changes: 10 additions & 3 deletions core/views/courses.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from django.http.response import JsonResponse
from rest_framework.decorators import api_view

from core.daos import course_select_summary
from core.services import (
get_paginated_reviews_by_course,
get_paginated_schedules_by_course,
get_course_reviews_stats,
get_course_search_results,
get_course_summary,
get_course_most_visited,
)
from .utils import validate_user, validate_page_limit, try_response


@api_view(["GET"])
@try_response
def course_summary_view(request, department: str, course_number: str):
json_data = course_select_summary(department.upper(), course_number)
json_data = get_course_summary(department.upper(), course_number)

return JsonResponse(json_data)

Expand Down Expand Up @@ -47,7 +48,7 @@ def course_reviews_view(request, department: str, course_number: str):
course_number,
**validate_page_limit(request),
tags=request.GET.getlist("tags"),
user_id=validate_user(request)
user_id=validate_user(request),
)

return JsonResponse(json_data)
Expand All @@ -65,3 +66,9 @@ def course_search_view(request):
)

return JsonResponse(json_data)


@api_view(["GET"])
@try_response
def course_most_visited_view(request):
return JsonResponse(get_course_most_visited())
13 changes: 10 additions & 3 deletions core/views/professors.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from django.http.response import JsonResponse
from rest_framework.decorators import api_view

from core.daos import professor_select_summary
from core.services import (
get_paginated_schedules_by_professor,
get_professor_reviews_stats,
get_paginated_reviews_by_professor,
get_professor_search_results,
get_professor_summary,
get_professor_most_visited,
)
from .utils import validate_user, validate_page_limit, try_response

Expand All @@ -25,7 +26,7 @@ def professor_schedules_view(request, professor_id):
@api_view(["GET"])
@try_response
def professor_summary_view(request, professor_id):
json_data = professor_select_summary(professor_id=professor_id)
json_data = get_professor_summary(professor_id=professor_id)
return JsonResponse(json_data)


Expand All @@ -43,7 +44,7 @@ def professor_reviews_view(request, professor_id):
professor_id=professor_id,
**validate_page_limit(request),
tags=request.GET.getlist("tags"),
user_id = validate_user(request)
user_id=validate_user(request),
)

return JsonResponse(json_data)
Expand All @@ -59,3 +60,9 @@ def professor_search_view(request):
)

return JsonResponse(json_data)


@api_view(["GET"])
@try_response
def professor_most_visited_view(request):
return JsonResponse(get_professor_most_visited())