def search_courses(): """Search courses from various criteria. Accepts the following query parameters: keywords: Keywords to search on sort_mode: Name of a sort mode. See Course.SORT_MODES. If this is 'friends_taken', a user must be authenticated, otherwise, will default to the 'popular' sort mode. direction: 1 for ascending, -1 for descending count: Max items to return (aka. limit) offset: Index of first search result to return (aka. skip) exclude_taken_courses: "yes" to exclude courses current user has taken. If a user is authenticated, additional user-specific info will be returned, such as terms user took each course and ratings and reviews (if any). """ current_user = view_helpers.get_current_user() courses, has_more = m.Course.search(flask.request.values, current_user) course_dicts, user_course_dicts, _ = ( m.Course.get_course_and_user_course_dicts(courses, current_user)) return api_util.jsonify({ 'courses': course_dicts, 'user_courses': user_course_dicts, 'has_more': has_more, })
def render_template(*args, **kwargs): redis = view_helpers.get_redis_instance() current_user = view_helpers.get_current_user() should_renew_fb_token = False if (current_user and current_user.fbid and not current_user.is_demo_account and not hasattr(flask.request, 'as_user_override')): should_renew_fb_token = current_user.should_renew_fb_token kwargs.update({ 'env': app.config['ENV'], 'VERSION': VERSION, 'NUM_KITTENS': len(KITTEN_DATA), 'js_dir': app.config['JS_DIR'], 'ga_property_id': app.config['GA_PROPERTY_ID'], 'total_points': int(redis.get('total_points') or 0), 'current_user': current_user, 'should_renew_fb_token': should_renew_fb_token, 'current_term_id': util.get_current_term_id(), 'user_agent': flask.request.headers['User-Agent'] if 'User-Agent' in flask.request.headers else 'No Info', }) return flask_render_template(*args, **kwargs)
def _get_user_require_auth(user_id=None): """Return the requested user only if authenticated and authorized. Defaults to the current user if no user_id given. Guaranteed to return a user object. """ current_user = view_helpers.get_current_user() if not current_user: raise api_util.ApiBadRequestError('Must authenticate as a user.') if not user_id: return current_user try: user_id_bson = bson.ObjectId(user_id) except bson.errors.InvalidId: raise api_util.ApiBadRequestError( 'User ID %s is not a valid BSON ObjectId.' % user_id) # Does the the current user have permission to get info about this user? if (user_id_bson == current_user.id or user_id_bson in current_user.friend_ids): user = m.User.objects.with_id(user_id_bson) if user: return user raise api_util.ApiForbiddenError( 'Not authorized to get info about this user.')
def search_courses(): current_user = view_helpers.get_current_user() courses, has_more = m.Course.search(flask.request.values, current_user) course_dict_list, user_course_dict_list, user_course_list = ( m.Course.get_course_and_user_course_dicts(courses, current_user, include_friends=True, full_user_courses=False, include_sections=True)) professor_dict_list = m.Professor.get_reduced_professors_for_courses( courses) user_dict_list = [] if current_user: user_ids = [ uc['user_id'] for uc in user_course_dict_list if uc['user_id'] != current_user.id ] users = m.User.objects(id__in=user_ids).only(*m.User.CORE_FIELDS) user_dict_list = [u.to_dict() for u in users] return util.json_dumps({ 'user_objs': user_dict_list, 'course_objs': course_dict_list, 'professor_objs': professor_dict_list, 'user_course_objs': user_course_dict_list, 'has_more': has_more, })
def onboarding(): current_user = view_helpers.get_current_user() current_user.last_show_onboarding = datetime.now() current_user.save() rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_ONBOARDING, current_user.id, ) friends = m.User.objects(id__in=current_user.friend_ids).only( *(m.User.CORE_FIELDS + ['course_history'])) user_objs = [] for user in [current_user] + list(friends): user_objs.append(user.to_dict()) return flask.render_template( 'onboarding_page.html', page_script='onboarding_page.js', current_user_id=current_user.id, user_objs=user_objs, )
def onboarding(): current_user = view_helpers.get_current_user() current_user.last_show_onboarding = datetime.now() current_user.save() rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_ONBOARDING, current_user.id, ) friends = m.User.objects( id__in=current_user.friend_ids ).only(*(m.User.CORE_FIELDS + ['course_history'])) user_objs = [] for user in [current_user] + list(friends): user_objs.append(user.to_dict()) return flask.render_template('onboarding_page.html', page_script='onboarding_page.js', current_user_id=current_user.id, user_objs=user_objs, )
def user_course_share(): user_course_id = flask.request.form['user_course_id'] review_type = flask.request.form['review_type'] current_user = view_helpers.get_current_user() review = None points_gained = 0 user_course = m.UserCourse.objects.get( id=user_course_id, user_id=current_user.id) if review_type == 'course': review = user_course.course_review points_gained = m.PointSource.SHARE_COURSE_REVIEW elif review_type == 'professor': review = user_course.professor_review points_gained = m.PointSource.SHARE_PROFESSOR_REVIEW # Only award points on the first share if not review.share_date: redis = view_helpers.get_redis_instance() current_user.award_points(points_gained, redis) else: points_gained = 0 review.share_date = datetime.now() user_course.save() current_user.save() return util.json_dumps({ 'points_gained': points_gained, })
def index(): # Redirect logged-in users to profile # TODO(Sandy): If we request extra permissions from FB, we'll need to show # them the landing page to let them to Connect again and accept the new # permissions. Alternatively, we could use other means of requesting for # new perms request = flask.request logout = bool(request.values.get('logout')) referrer_id = request.values.get('meow') or request.values.get('referrer') if logout: view_helpers.logout_current_user() if not logout and not referrer_id and view_helpers.get_current_user(): return flask.make_response(flask.redirect('profile')) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_LANDING, ) return flask.render_template( 'index_page.html', page_script='index_page.js', )
def remove_course(): current_user = view_helpers.get_current_user() rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_REMOVE_COURSE, { 'request_form': flask.request.form, 'user_id': current_user.id, }, ) user_course = m.UserCourse.objects( user_id=current_user.id, course_id=flask.request.form.get('course_id'), term_id=flask.request.form.get('term_id'), ).first() if not user_course: logging.warn("No UserCourse found matching request values %s" % flask.request.values) # TODO(david): Use api.py:not_found in my onboarding-v2 branch return '' current_user.update(pull__course_history=user_course.id) user_course.delete() return ''
def user_course_share(): user_course_id = flask.request.form['user_course_id'] review_type = flask.request.form['review_type'] current_user = view_helpers.get_current_user() review = None points_gained = 0 user_course = m.UserCourse.objects.get(id=user_course_id, user_id=current_user.id) if review_type == 'course': review = user_course.course_review points_gained = m.PointSource.SHARE_COURSE_REVIEW elif review_type == 'professor': review = user_course.professor_review points_gained = m.PointSource.SHARE_PROFESSOR_REVIEW # Only award points on the first share if not review.share_date: redis = view_helpers.get_redis_instance() current_user.award_points(points_gained, redis) else: points_gained = 0 review.share_date = datetime.now() user_course.save() current_user.save() return util.json_dumps({ 'points_gained': points_gained, })
def schedule_screenshot_url(): user = view_helpers.get_current_user() return util.json_dumps({ # Note that this may be None "url": schedule_screenshot.get_screenshot_url(user) })
def search_courses(): current_user = view_helpers.get_current_user() courses, has_more = m.Course.search(flask.request.values, current_user) course_dict_list, user_course_dict_list, user_course_list = ( m.Course.get_course_and_user_course_dicts( courses, current_user, include_friends=True, full_user_courses=False, include_sections=True)) professor_dict_list = m.Professor.get_reduced_professors_for_courses( courses) user_dict_list = [] if current_user: user_ids = [uc['user_id'] for uc in user_course_dict_list if uc['user_id'] != current_user.id] users = m.User.objects(id__in=user_ids).only(*m.User.CORE_FIELDS) user_dict_list = [u.to_dict() for u in users] return util.json_dumps({ 'user_objs': user_dict_list, 'course_objs': course_dict_list, 'professor_objs': professor_dict_list, 'user_course_objs': user_course_dict_list, 'has_more': has_more, })
def signup_email(): """Create a new account using data encoded in the POST body. Expects the following form data: first_name: E.g. 'Taylor' last_name: E.g. 'Swift' email: E.g. '*****@*****.**' password: E.g. 'iknewyouweretrouble' Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ # Prevent a CSRF attack from replacing a logged-in user's account with # a new account with known credentials current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) params = flask.request.form.copy() # Don't log the password password = params.pop('password', None) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_SIGNUP, { 'params': params, 'type': rmclogger.LOGIN_TYPE_STRING_EMAIL, }, ) first_name = params.get('first_name') last_name = params.get('last_name') email = params.get('email') if not first_name: raise api_util.ApiBadRequestError('Must provide first name.') if not last_name: raise api_util.ApiBadRequestError('Must provide last name.') if not email: raise api_util.ApiBadRequestError('Must provide email.') if not password: raise api_util.ApiBadRequestError('Must provide password.') try: user = m.User.create_new_user_from_email(first_name, last_name, email, password) except m.User.UserCreationError as e: raise api_util.ApiBadRequestError(e.message) view_helpers.login_as_user(user) return api_util.jsonify( {'message': 'Created and logged in user %s' % user.name})
def signup_email(): """Create a new account using data encoded in the POST body. Expects the following form data: first_name: E.g. 'Taylor' last_name: E.g. 'Swift' email: E.g. '*****@*****.**' password: E.g. 'iknewyouweretrouble' Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ # Prevent a CSRF attack from replacing a logged-in user's account with # a new account with known credentials current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) params = flask.request.form.copy() # Don't log the password password = params.pop('password', None) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_SIGNUP, { 'params': params, 'type': rmclogger.LOGIN_TYPE_STRING_EMAIL, }, ) first_name = params.get('first_name') last_name = params.get('last_name') email = params.get('email') if not first_name: raise api_util.ApiBadRequestError('Must provide first name.') if not last_name: raise api_util.ApiBadRequestError('Must provide last name.') if not email: raise api_util.ApiBadRequestError('Must provide email.') if not password: raise api_util.ApiBadRequestError('Must provide password.') try: user = m.User.create_new_user_from_email( first_name, last_name, email, password) except m.User.UserCreationError as e: raise api_util.ApiBadRequestError(e.message) view_helpers.login_as_user(user) return api_util.jsonify({ 'message': 'Created and logged in user %s' % user.name })
def next_course_to_review(): current_user = view_helpers.get_current_user() uc = current_user.next_course_to_review() if current_user else None if not uc: return util.json_dumps({}) uc.select_for_review(current_user) return util.json_dumps(uc.to_dict())
def course_page(course_id): course = m.Course.objects.with_id(course_id) if not course: # TODO(david): 404 page flask.abort(404) current_user = view_helpers.get_current_user() course_dict_list, user_course_dict_list, user_course_list = ( m.Course.get_course_and_user_course_dicts( [course], current_user, include_all_users=True, include_friends=True, full_user_courses=True, include_sections=True)) professor_dict_list = m.Professor.get_full_professors_for_course( course, current_user) user_dicts = {} if current_user: # TODO(Sandy): This is poorly named because its not only friends... friend_ids = ({uc_dict['user_id'] for uc_dict in user_course_dict_list} - set([current_user.id])) friends = m.User.objects(id__in=friend_ids).only(*m.User.CORE_FIELDS) for friend in friends: user_dicts[friend.id] = friend.to_dict() user_dicts[current_user.id] = current_user.to_dict( include_course_ids=True) tip_dict_list = course.get_reviews(current_user, user_course_list) rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_SINGLE_COURSE, { 'current_user': current_user.id if current_user else None, 'course_id': course_id, }, ) exam_objs = m.Exam.objects(course_id=course_id) exam_dict_list = [e.to_dict() for e in exam_objs] exam_updated_date = None if exam_objs: exam_updated_date = exam_objs[0].id.generation_time return flask.render_template('course_page.html', page_script='course_page.js', course_obj=course_dict_list[0], professor_objs=professor_dict_list, tip_objs=tip_dict_list, user_course_objs=user_course_dict_list, user_objs=user_dicts.values(), exam_objs=exam_dict_list, exam_updated_date=exam_updated_date, current_user_id=current_user.id if current_user else None, )
def get_count(): course_id = flask.request.args.get('course_id') if not course_id: return flask.abort(400) current_user = view_helpers.get_current_user() comments = m.CourseComment.get_course_comments(course_id, current_user.friend_ids, 0, 10000) return util.json_dumps(len(comments))
def login_facebook(): """Attempt to login a user with FB credentials encoded in the POST body. Expects the following form data: fb_access_token: Facebook user access token. This is used to verify that the user did authenticate with Facebook and is authenticated to our app. The user's FB ID is also obtained from this token. Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. Also returns the CSRF token, which must be sent as the value of the "X-CSRF-Token" header for all non-GET requests. """ # Prevent a CSRF attack from replacing a logged-in user's account with the # attacker's. current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_SIGNUP, { 'type': rmclogger.LOGIN_TYPE_STRING_FACEBOOK, }, ) req = flask.request fb_access_token = req.form.get('fb_access_token') # We perform a check to confirm the fb_access_token is indeed the person # identified by fbid, and that it was our app that generated the token. token_info = facebook.get_access_token_info(fb_access_token) if not token_info['is_valid'] or not token_info.get('user_id'): raise api_util.ApiForbiddenError( 'The given FB credentials are invalid.') fbid = str(token_info['user_id']) user = m.User.objects(fbid=fbid).first() if not user: raise api_util.ApiForbiddenError('No user with fbid %s exists. ' 'Create an account at uwflow.com.' % fbid) view_helpers.login_as_user(user) # TODO(sandy): We don't need to do this anymore, just use the endpoint csrf_token = view_helpers.generate_csrf_token() return api_util.jsonify({ 'message': 'Logged in user %s' % user.name, 'csrf_token': csrf_token, })
def search_unified(): """Returns an array of course objects and an array of friend objects which power the unified search bar. """ result_types = flask.request.args.get('result_types').split(',') # TODO(david): Cache this. course_dicts = [] if 'courses' in result_types: courses = sorted(list(m.Course.objects().only('id', 'name', '_keywords', 'department_id', 'number')), key=lambda c: c.id) course_dicts = [{ 'label': c.id, 'name': c.name, 'type': 'course', 'tokens': c._keywords, 'department_id': c.department_id, 'number': c.number } for c in courses] friend_dicts = [] if 'friends' in result_types: user = view_helpers.get_current_user() if user: friends = user.get_friends() friend_dicts = [{ 'label': f.name, 'program': f.short_program_name, 'type': 'friend', 'id': f.id, 'pic': f.profile_pic_urls['square'], 'tokens': [f.first_name, f.last_name] } for f in friends] prof_dicts = [] if 'professors' in result_types: professors = m.Professor.objects().only('id', 'first_name', 'last_name', 'departments_taught') prof_dicts = [{ 'label': p.name, 'departments_taught': p.departments_taught, 'type': 'prof', 'prof_id': p.id, 'name': p.name, 'tokens': [p.first_name, p.last_name, 'professor'] } for p in professors] return api_util.jsonify({ 'friends': friend_dicts, 'courses': course_dicts, 'professors': prof_dicts })
def get_course_professors(course_id): course = m.Course.objects.with_id(course_id) if not course: raise api_util.ApiNotFoundError('Course %s not found. :(' % course_id) current_user = view_helpers.get_current_user() professors = m.Professor.get_full_professors_for_course( course, current_user) return api_util.jsonify({'professors': professors})
def about_page(): # current_user CAN be None, but that's okay for logging current_user = view_helpers.get_current_user() user_id = current_user.id if current_user else None rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_ABOUT, user_id, ) return flask.render_template('about_page.html')
def privacy(): # current_user CAN be None, but that's okay for logging current_user = view_helpers.get_current_user() user_id = current_user.id if current_user else None rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_PRIVACY_POLICY, user_id, ) return flask.render_template('privacy_page.html')
def get_course(course_id): course = m.Course.objects.with_id(course_id) if not course: raise api_util.ApiNotFoundError('Course %s not found. :(' % course_id) current_user = view_helpers.get_current_user() course_reviews = course.get_reviews(current_user) # TODO(david): Implement HATEOAS (URLs of other course info endpoints). return api_util.jsonify(dict(course.to_dict(), **{ 'reviews': course_reviews, }))
def get_course_professors(course_id): course = m.Course.objects.with_id(course_id) if not course: raise api_util.ApiNotFoundError('Course %s not found. :(' % course_id) current_user = view_helpers.get_current_user() professors = m.Professor.get_full_professors_for_course( course, current_user) return api_util.jsonify({ 'professors': professors })
def invite_friend(): current_user = view_helpers.get_current_user() orig_points = current_user.num_points current_user.invite_friend(view_helpers.get_redis_instance()) current_user.save() points_gained = current_user.num_points - orig_points return util.json_dumps({ 'num_invites': current_user.num_invites, 'points_gained': points_gained, })
def search_courses(): current_user = view_helpers.get_current_user() courses, has_more = m.Course.search(flask.request.values, current_user) course_dict_list, user_course_dict_list, user_course_list = ( m.Course.get_course_and_user_course_dicts( courses, current_user, include_friends=True, full_user_courses=False, include_sections=True)) return util.json_dumps({ 'course_objs': course_dict_list, 'has_more': has_more, })
def upload_transcript(): req = flask.request user = view_helpers.get_current_user() user_id = user.id rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_TRANSCRIPT, { 'user_id': user_id, 'requset_form': req.form, }, ) def get_term_id(term_name): season, year = term_name.split() return m.Term.get_id_from_year_season(year, season) transcript_data = util.json_loads(req.form['transcriptData']) courses_by_term = transcript_data['coursesByTerm'] # TODO(Sandy): Batch request fetch to mongo instead of fetch while looping for term in courses_by_term: term_id = get_term_id(term['name']) program_year_id = term['programYearId'] for course_id in term['courseIds']: # TODO(Sandy): Fill in course weight and grade info here user.add_course(course_id.lower(), term_id, program_year_id) if courses_by_term: last_term = courses_by_term[0] term_id = get_term_id(last_term['name']) user.last_term_id = term_id user.last_program_year_id = last_term['programYearId'] user.program_name = transcript_data['programName'] student_id = transcript_data.get('studentId') if student_id: user.student_id = str(student_id) user.cache_mutual_course_ids(view_helpers.get_redis_instance()) user.transcripts_imported += 1 user.save() rmclogger.log_event( rmclogger.LOG_CATEGORY_TRANSCRIPT, rmclogger.LOG_EVENT_UPLOAD, user_id ) return ''
def renew_fb(): '''Renew the current user's Facebook access token. The client should make this call periodically (once every couple months, see User.should_renew_fb_token) to keep the access token up to date. Takes a Facebook signed request object from the post params in the form of: { 'fb_signed_request': obj } ''' req = flask.request current_user = view_helpers.get_current_user() rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_RENEW_FB, { 'user_id': current_user.id, 'request_form': req.form, } ) fbsr = req.form.get('fb_signed_request') if fbsr is None: logging.warn('No fbsr set') raise exceptions.ImATeapot('No fbsr set') fb_data = facebook.get_fb_data(fbsr, app.config) access_token = fb_data['access_token'] expires_on = fb_data['expires_on'] is_invalid = fb_data['is_invalid'] if not is_invalid: current_user.fb_access_token_expiry_date = expires_on current_user.fb_access_token = access_token current_user.fb_access_token_invalid = is_invalid # Update the user's fb friend list, since it's likely outdated by now try: current_user.update_fb_friends( facebook.get_friend_list(access_token)) except: # Not sure why this would happen. Usually it's due to invalid # access_token, but we JUST got the token, so it should be valid logging.warn( "/api/renew-fb: get_friend_list failed with token (%s)" % access_token) current_user.save() return ''
def add_course_to_shortlist(): current_user = view_helpers.get_current_user() user_course = m.UserCourse( user_id=current_user.id, course_id=flask.request.form.get('course_id'), term_id=m.Term.SHORTLIST_TERM_ID, ) user_course.save() current_user.update(add_to_set__course_history=user_course.id) return util.json_dumps({ 'user_course': user_course.to_dict(), })
def update_prof_comment(prof_id): course_prof_comment = m.CourseProfessorComment.objects(id=prof_id).first() comment = util.json_loads(flask.request.data) current_user = view_helpers.get_current_user() if not current_user or comment[ 'user_id'] != current_user.id or course_prof_comment is None: return flask.abort(400) if 'course_id' not in comment or 'professor_id' not in comment: return flask.abort(400) course_prof_comment.update_by_dict(comment) course_prof_comment.save() return util.json_dumps({})
def last_schedule_paste(): user_id = flask.request.values.get('user_id') if not user_id: user_id = view_helpers.get_current_user().id else: user_id = bson.ObjectId(user_id) user = m.User.objects.with_id(user_id) last_schedule_paste = user.last_schedule_paste return util.json_dumps({ 'last_schedule_paste': last_schedule_paste, })
def remove_transcript(): current_user = view_helpers.get_current_user() current_user.course_history = [] current_user.save() # Remove cached mutual courses current_user.remove_mutual_course_ids(view_helpers.get_redis_instance()) # Remove term_id from user_courses # TODO(mack): Display message notifying users how many reviews they will # lose by removing their transcript. m.UserCourse.objects(user_id=current_user.id).delete() rmclogger.log_event(rmclogger.LOG_CATEGORY_TRANSCRIPT, rmclogger.LOG_EVENT_REMOVE, current_user.id) return ''
def login_email(): """Attempt to log in a user with the credentials encoded in the POST body. Expects the following form data: email: E.g. '*****@*****.**' password: E.g. 'iknewyouweretrouble' Responds with the session cookie via the `set-cookie` header on success. Send the associated cookie for all subsequent API requests that accept user authentication. """ # Prevent a CSRF attack from replacing a logged-in user's account with the # attacker's. current_user = view_helpers.get_current_user() if current_user: return api_util.jsonify({'message': 'A user is already logged in.'}) params = flask.request.form.copy() # Don't log the password password = params.pop('password', None) rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_LOGIN, { 'params': params, 'type': rmclogger.LOGIN_TYPE_STRING_EMAIL, }, ) email = params.get('email') if not email: raise api_util.ApiBadRequestError('Must provide email.') if not password: raise api_util.ApiBadRequestError('Must provide password.') user = m.User.auth_user(email, password) if not user: raise api_util.ApiNotFoundError('Incorrect email or password.') view_helpers.login_as_user(user) return api_util.jsonify({'message': 'Logged in user %s' % user.name})
def transcript_log(): user = view_helpers.get_current_user() file_name = '%d.txt' % int(time.time()) file_path = os.path.join(get_transcript_dir(), file_name) with open(file_path, 'w') as f: f.write(flask.request.form['transcript'].encode('utf-8')) rmclogger.log_event( rmclogger.LOG_CATEGORY_TRANSCRIPT, rmclogger.LOG_EVENT_PARSE_FAILED, { 'user_id': user.id, 'file_path': file_path, }, ) return ''
def unsubscribe_page(): current_user = view_helpers.get_current_user() req = flask.request unsubscribe_user_id = req.args.get('pasta') rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_UNSUBSCRIBE, { 'current_user': current_user.id if current_user else None, 'unsubscribe_user': unsubscribe_user_id, 'request_args': req.args, }, ) return flask.render_template('unsubscribe_page.html', page_script='unsubscribe_page.js', unsubscribe_user=unsubscribe_user_id, )
def remove_transcript(): current_user = view_helpers.get_current_user() current_user.course_history = [] current_user.save() # Remove cached mutual courses current_user.remove_mutual_course_ids(view_helpers.get_redis_instance()) # Remove term_id from user_courses # TODO(mack): Display message notifying users how many reviews they will # lose by removing their transcript. m.UserCourse.objects(user_id=current_user.id).delete() rmclogger.log_event( rmclogger.LOG_CATEGORY_TRANSCRIPT, rmclogger.LOG_EVENT_REMOVE, current_user.id ) return ''
def unsubscribe_user(): current_user = view_helpers.get_current_user() req = flask.request unsubscribe_user_id = req.form.get('pasta') if not unsubscribe_user_id: logging.warn('Missing user_id (%s)' % unsubscribe_user_id) return flask.redirect('/') try: unsubscribe_user_id = bson.ObjectId(unsubscribe_user_id) except: logging.warn('Invalid user_id (%s)' % unsubscribe_user_id) return flask.redirect('/') user = m.User.objects.with_id(unsubscribe_user_id) if user: user.email_unsubscribed = True user.save() # TODO(Sandy): Temporary until we enforce logged in unsub's or just # generate and send out a hash next time notes = "Legit unsub" if current_user: if current_user.id != unsubscribe_user_id: notes = "Suspicious: Non-matching logged in user_id/unsub_id" else: notes = "Suspicious: No logged in user_id" rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_UNSUBSCRIBE_USER, { 'current_user': current_user.id if current_user else None, 'unsubscribe_user': unsubscribe_user_id, 'request_form': req.form, 'notes': notes, }, ) else: logging.warn('User object (%s) not found' % unsubscribe_user_id) return flask.redirect('/') return flask.redirect('/')
def prof_page(prof_id): prof = m.Professor.objects.with_id(prof_id) if not prof: flask.abort(404) current_user = view_helpers.get_current_user() courses_taught = prof.get_courses_taught() courses = m.Course.objects(id__in=courses_taught) full_course_info = [c.to_dict() for c in courses] return flask.render_template('prof_page.html', page_script='prof_page.js', prof_name=prof.name, prof_ratings=prof.get_ratings_for_career(), prof_courses=courses_taught, prof_courses_full=full_course_info, prof_departments_list=prof.get_departments_taught(), tip_objs_by_course=prof.get_reviews_for_all_courses(current_user) )
def courses(): # TODO(mack): move into COURSES_SORT_MODES def clean_sort_modes(sort_mode): return { 'name': sort_mode['name'], 'direction': sort_mode['direction'], } sort_modes = map(clean_sort_modes, COURSES_SORT_MODES) current_user = view_helpers.get_current_user() return flask.render_template( 'search_page.html', page_script='search_page.js', sort_modes=sort_modes, current_user_id=current_user.id if current_user else None, user_objs=[current_user.to_dict( include_course_ids=True)] if current_user else [], )
def schedule_log(): user = view_helpers.get_current_user() file_name = '%d.txt' % int(time.time()) file_path = os.path.join(get_schedule_dir(), file_name) with open(file_path, 'w') as f: f.write(flask.request.form['schedule'].encode('utf-8')) rmclogger.log_event( rmclogger.LOG_CATEGORY_SCHEDULE, rmclogger.LOG_EVENT_PARSE_FAILED, { 'user_id': user.id, 'file_path': file_path, }, ) user.last_bad_schedule_paste = flask.request.form.get('schedule') user.last_bad_schedule_paste_date = datetime.now() user.save() return ''
def render_schedule_page(profile_user): profile_dict = profile_user.to_dict() profile_dict.update({ 'last_program_year_id': profile_user.get_latest_program_year_id(), }) # TODO(david): Show exam slots here as well (see render_profile_page) schedule_item_dicts = profile_user.get_schedule_item_dicts() course_ids = [si['course_id'] for si in schedule_item_dicts] courses = m.Course.objects(id__in=course_ids) course_dicts = [c.to_dict() for c in courses] current_user = view_helpers.get_current_user() current_user_id = None if current_user: current_user_id = current_user.id rmclogger.log_event( rmclogger.LOG_CATEGORY_IMPRESSION, rmclogger.LOG_EVENT_SCHEDULE_VIEW, { 'current_user': current_user_id, 'profile_user': profile_user.id, }, ) user_dicts = [profile_dict] if current_user and current_user_id != profile_user.id: user_dicts.append(current_user.to_dict()) return flask.render_template('schedule_page.html', page_script='schedule_page.js', profile_obj=profile_dict, user_objs=user_dicts, profile_user_id=profile_user.id, current_user_id=current_user_id, schedule_item_objs=schedule_item_dicts, course_objs=course_dicts, show_printable=flask.request.values.get('print'), )