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

Pub/Sub integration #38

Merged
merged 12 commits into from
Nov 9, 2020
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ node_modules

# node version compabilities
.nvmrc
master-service-account.json
21 changes: 21 additions & 0 deletions apps/web/migrations/0023_student_unauth_session_ids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-11-09 21:02
from __future__ import unicode_literals

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('web', '0022_increase_period_length'),
]

operations = [
migrations.AddField(
model_name='student',
name='unauth_session_ids',
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=32, unique=True), default=[], size=None),
),
]
3 changes: 3 additions & 0 deletions apps/web/models/student.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import unicode_literals
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.auth.models import User
from django.conf import settings
from django.core.mail import send_mail
Expand Down Expand Up @@ -35,6 +36,8 @@ class Student(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

unauth_session_ids = ArrayField(base_field=models.CharField(max_length=32, unique=True), default=list())

def send_confirmation_link(self, request):
full_link = request.build_absolute_uri(
reverse('confirmation')) + '?link=' + self.confirmation_link
Expand Down
57 changes: 51 additions & 6 deletions apps/web/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import os
import sys
import datetime
import dateutil.parser
from django.shortcuts import render, redirect
from django.conf import settings
from django.views.decorators.http import require_safe, require_POST
Expand Down Expand Up @@ -34,18 +37,44 @@
from lib.departments import get_department_name
from lib import constants

import uuid
from google.cloud import pubsub_v1

pub_sub_publisher = pubsub_v1.PublisherClient()
topic_paths = {
'course-views': pub_sub_publisher.topic_path(os.environ['GCLOUD_PROJECT_ID'], 'course-views')
}

LIMITS = {
"courses": 20,
"reviews": 5,
"unauthenticated_review_search": 3,
'courses': 20,
'reviews': 5,
'unauthenticated_review_search': 3,
}

def get_session_id(request):
if 'user_id' not in request.session:
if not request.user.is_authenticated():
request.session['user_id'] = uuid.uuid4().hex
else:
request.session['user_id'] = request.user.username
return request.session['user_id']


def get_prior_course_id(request, current_course_id):
prior_course_id = None
if 'prior_course_id' in request.session and 'prior_course_timestamp' in request.session:
prior_course_timestamp = request.session['prior_course_timestamp']
if dateutil.parser.parse(prior_course_timestamp) + datetime.timedelta(seconds=15) >= datetime.datetime.now():
prior_course_id = request.session['prior_course_id']
request.session['prior_course_id'] = current_course_id
request.session['prior_course_timestamp'] = datetime.datetime.now().isoformat()
return prior_course_id

@require_safe
def landing(request):
return render(request, 'landing.html', {
'page_javascript': 'LayupList.Web.Landing()',
'review_count': Review.objects.count(),
'review_count': Review.objects.count()
})


Expand All @@ -56,10 +85,10 @@ def signup(request):
form.save_and_send_confirmation(request)
return render(request, 'instructions.html')
else:
return render(request, 'signup.html', {"form": form})
return render(request, 'signup.html', {'form': form})

else:
return render(request, 'signup.html', {"form": SignupForm()})
return render(request, 'signup.html', {'form': SignupForm()})


def auth_login(request):
Expand All @@ -72,6 +101,12 @@ def auth_login(request):
if user is not None:
if user.is_active:
login(request, user)
if 'user_id' in request.session:
student = Student.objects.get(user=user)
student.unauth_session_ids.append(request.session['user_id'])
student.save()
request.session['user_id'] = user.username

return redirect(next_url)
else:
return render(request, 'login.html', {
Expand All @@ -92,6 +127,7 @@ def auth_login(request):
@login_required
def auth_logout(request):
logout(request)
request.session['userID'] = uuid.uuid4().hex
return render(request, 'logout.html')


Expand Down Expand Up @@ -179,6 +215,15 @@ def current_term(request, sort):
def course_detail(request, course_id):
try:
course = Course.objects.get(pk=course_id)
prior_course_id = get_prior_course_id(request, course_id)
if prior_course_id is not None:
result = pub_sub_publisher.publish(topic_paths['course-views'], b'', courseID=course_id, priorCourseID=prior_course_id, userID=get_session_id(request), timestamp=datetime.datetime.utcnow().isoformat())
else:
result = pub_sub_publisher.publish(topic_paths['course-views'], b'', courseID=course_id, userID=get_session_id(request), timestamp=datetime.datetime.utcnow().isoformat())
try:
result.result()
except:
print('Error publishing view activity for ', course_id)
except Course.DoesNotExist:
return HttpResponseNotFound('<h1>Page not found</h1>')

Expand Down
1 change: 1 addition & 0 deletions auth.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export GOOGLE_APPLICATION_CREDENTIALS="master-service-account.json"
1 change: 1 addition & 0 deletions build.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
echo 'yes' | python manage.py collectstatic
2 changes: 2 additions & 0 deletions init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
source ./scripts/dev/environment.sh
source ./scripts/dev/virtualize.sh
29 changes: 27 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
amqp==2.1.3
appnope==0.1.0
astroid==1.6.6
backports.functools-lru-cache==1.6.1
backports.shutil-get-terminal-size==1.0.0
beautifulsoup4==4.5.1
billiard==3.5.0.2
cachetools==3.1.1
celery==4.0.1
certifi==2020.6.20
chardet==3.0.4
configparser==4.0.2
decorator==4.0.10
dj-database-url==0.4.1
Django==1.11.29
Expand All @@ -19,34 +25,53 @@ django-postgrespool==0.3.0
enum34==1.1.6
factory-boy==2.7.0
fake-factory==0.7.2
futures==3.0.5
futures==3.3.0
google-api-core==1.23.0
google-auth==1.23.0
google-cloud-pubsub==1.7.0
googleapis-common-protos==1.52.0
grpc-google-iam-v1==0.12.3
grpcio==1.33.2
gunicorn==19.6.0
idna==2.10
ipaddress==1.0.17
ipdb==0.10.1
ipython==5.1.0
ipython-genutils==0.1.0
isort==4.3.21
kombu==4.0.1
lazy-object-proxy==1.5.1
MarkupSafe==0.23
mccabe==0.6.1
numpy==1.11.2
pathlib2==2.1.0
pexpect==4.2.1
pickleshare==0.7.4
prompt-toolkit==1.0.9
protobuf==3.13.0
psycopg2==2.8.5
ptyprocess==0.5.1
pyasn1==0.4.8
pyasn1-modules==0.2.8
PyExecJS==1.4.0
Pygments==2.1.3
pylint==1.9.5
PyReact==0.6.0
python-dateutil==2.6.0
pytz==2016.10
redis==2.10.5
requests==2.24.0
rsa==4.5
scikit-learn==0.18.1
scipy==0.18.1
simplegeneric==0.8.1
six==1.10.0
singledispatch==3.4.0.3
six==1.15.0
SQLAlchemy==1.1.4
sqlparse==0.2.2
traitlets==4.3.1
urllib3==1.25.11
vine==1.1.3
wcwidth==0.1.7
whitenoise==3.2.2
wrapt==1.12.1
1 change: 1 addition & 0 deletions run.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
forego start
1 change: 1 addition & 0 deletions shell.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python manage.py shell