'registered' by importing them. The sub controllers need to import the base blue-print from this file in order to be registered. """ __author__ = "Harshvardhan Gupta" from datetime import datetime from flask_login import current_user, login_required from Sugar import JSONifiedNestableBlueprint from extensions import db from models import Error, Role, UserRoles from .Misc import admin_misc_controller admin_base_blueprint = JSONifiedNestableBlueprint('admin_api', __name__) admin_base_blueprint.register_blueprint(admin_misc_controller) # admin_base_blueprint.register_blueprint(admin_tests_controller) @admin_base_blueprint.before_request @login_required def verify_admin(): """ Checks if the current user has an admin role. It also means that the user must be logged in. This function will be applied to all endpoints that use admin blueprint. :return:
from flask import current_app, request from flask_login import current_user, login_required from Externals import Discourse from Sugar import JSONifiedNestableBlueprint from models import Error discourse_blueprint = JSONifiedNestableBlueprint('Discourse', __name__) @discourse_blueprint.route("/discourse_sso", methods=['POST']) @login_required def discourse_login(): try: payload = request.args.get('sso') signature = request.args.get('sig') decoded = Discourse.parse_payload(payload, signature) query_string = Discourse.build_return_payload(decoded, current_user.id) url = f"{current_app.config['DISCOURSE_URL']}?{query_string}" except: return Error("Invalid query parameters provided", 403)() return {"url": url}
from flask import Response from flask_login import current_user, login_required from sqlalchemy import and_ from sqlalchemy.orm import contains_eager, load_only, eagerload, undefer from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint, requires_roles from Util import Pinger from extensions import db from models import Choice, Error, Question, QuestionAttempt, Section, \ SectionAttempt, Test, TestAttempt, AuditLog __author__ = "Harshvardhan Gupta" test_attempt_controller = JSONifiedNestableBlueprint("TestAttempt", __name__) @test_attempt_controller.route('/tests/<test_id>/attempts/start', methods=['Post']) @login_required def start_test(test_id): """ Start a test. If an existing test_attempt that is not complete exists, it is returned. If not, if the user has access to the test, a new test attempt and section attempt(s) is created and returned. :param testID: :return: the id of the test attempt
from flask import request from flask_login import current_user, login_required from sqlalchemy import exc from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint, requires_roles, \ requires_validation from extensions import db from models import Error, PromoCode from .req_val import PromoCodeInputs promo_codes_controller = JSONifiedNestableBlueprint("PromoCodes", __name__) @promo_codes_controller.route('/promo_codes/', methods=['GET']) @requires_roles('admin') def get_promo_codes(): """ Returns all available Promo Codes in database :return: [promo.todict()] """ try: promo_codes = PromoCode.query.all() return promo_codes except NoResultFound: return Error('Invalid Promo Code', 400)() @promo_codes_controller.route('/promo_codes/<code>', methods=['GET']) @requires_roles('admin') def get_promo_code(code):
from flask import Flask, url_for, render_template, make_response, request from Sugar import JSONifiedNestableBlueprint from flask import url_for, render_template, make_response, jsonify from models import TestAttempt, Test, Section, QuestionSection, Order, OrderTest, Question from sqlalchemy import func, select, case from Sugar import JSONifiedNestableBlueprint from flask import request from flask_login import current_user, login_required from sqlalchemy import and_ from sqlalchemy.orm import contains_eager, load_only from flask import jsonify import requests __author__ = "Harshvardhan Gupta" base_blueprint = JSONifiedNestableBlueprint("UIBASE", __name__) @base_blueprint.route('/', methods=['Get']) def status_page(): """ Just a function to echo current time. May be useful for testing if servers are up. :return: current date """ r = make_response(render_template("UI/Pages/landing_page.html")) return r @base_blueprint.route('/test', methods=['GET', 'POST']) def test_listing():
from flask import Response from flask_login import current_user, login_required from sqlalchemy import and_ from sqlalchemy.orm import contains_eager, load_only from sqlalchemy.orm.exc import NoResultFound from extensions import db from Sugar import JSONifiedNestableBlueprint from Util import Pinger from models import (Choice, Error, Question, Section, Test, TestAttempt, SectionAttempt) __author__ = "Harshvardhan Gupta" section_attmpt_ctrl = JSONifiedNestableBlueprint('section_attempt_controller', __name__) @section_attmpt_ctrl.route( '/tests/<testID>/sections/<sectionID>/attempts/finish', methods=["Post"]) @login_required def finish_section(testID, sectionID): try: test_id, section_id, jumps_allowed, _, _ = Pinger.split_pinger_string() except: return Error("No Pinger", 403)() try: test_attempt = (TestAttempt.query.filter( TestAttempt.test_id == test_id).filter(
from flask import request from sqlalchemy import and_ from sqlalchemy.orm import contains_eager, load_only from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint, requires_validation from controllers.rex import CookieHelper from controllers.rex.CookieHelper import requires_corporate_cookies from controllers.rex.TestAttempts.req_val import ApplicationStatusTypes, \ UpdateApplicants, UpdateScore from extensions import db from models import Corporate, CorporateApplicants, Error, QuestionAttempt, \ SectionAttempt, TestAttempt, TestAttemptReport, SixteenPReport rex_testattempts_controller = JSONifiedNestableBlueprint('RexTestAttempt', __name__) @rex_testattempts_controller.route('/test/<test_id>/attempts/<date>', methods=['Get']) @requires_corporate_cookies() def get_overview(test_id, date): if not Corporate.can_access_test(CookieHelper.get_corporate_id(), test_id): return Error("No access", 403)() return (Corporate.get_test_performance(CookieHelper.get_corporate_id(), test_id, date)) @rex_testattempts_controller.route(
from flask_login import current_user from sqlalchemy import and_ from sqlalchemy.orm import contains_eager from Sugar import JSONifiedNestableBlueprint from models import Course, Order, OrderCourse courses_controller = JSONifiedNestableBlueprint("Courses", __name__) @courses_controller.route('/courses', methods=['Get']) def get_courses(): """ List all courses in the system. If user has purchased some, the courses will have 'is_purchased' key to true, else it will be false. If user has access to those courses by being in a college, the same thing applies. It also passes the query parameters received from the client as is , to the db queries. Useful for filtering """ current_user_id = current_user.id if not current_user.is_anonymous else None # left outer join on course -> orders -> ordercourse. if user has a # paid order it will be accessible by course.order. courses = (Course.query .outerjoin(OrderCourse, OrderCourse.course_id == Course.id)
from flask_login import current_user, login_required from sqlalchemy import and_ from Sugar import cachify from Sugar import JSONifiedNestableBlueprint from models import Error, Section, Test, TestAttempt from .Questions import questions_controller from .SectionAttempts import section_attmpt_ctrl __author__ = "Harshvardhan Gupta" sections_controller = JSONifiedNestableBlueprint('Sections_controller', __name__) sections_controller.register_blueprint(questions_controller) sections_controller.register_blueprint(section_attmpt_ctrl) @sections_controller.route('/tests/<test_id>/sections', methods=['Get']) @cachify(1800) @login_required def get_sections(test_id): """ Get list of sections for a particular test. This requires the test attempt for the user to exist for the test :param test_id: :return: """ sections = (Section.query.join(Test).join( TestAttempt, and_(TestAttempt.test_id == Test.id,
from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint from models import Corporate, Error corporates_controller = JSONifiedNestableBlueprint("Corporates", __name__) @corporates_controller.route('/corporates/<path:corporate_slug>', methods=['GET']) def get_corporate(corporate_slug): try: corporate = Corporate.query \ .filter(Corporate.slug == corporate_slug) \ .one() return corporate except NoResultFound: return Error("Invalid Corporate Slug", 400)()
from flask_login import current_user, login_required from sqlalchemy import and_ from sqlalchemy.orm import contains_eager, load_only from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint, cachify from extensions import cache from models import Choice, CodingCase, CodingLanguage, Error, Question, \ TestAttempt from .QuestionAttempts import qstn_attmpt_ctrl __author__ = "Harshvardhan Gupta" questions_controller = JSONifiedNestableBlueprint( 'Questions_controller', __name__) questions_controller.register_blueprint(qstn_attmpt_ctrl) @cache.cached(timeout=6000) def fetch_question(question_id): question = (Question.query .outerjoin(Question.choices) .outerjoin(CodingCase, and_(Question.id == CodingCase.question_id, CodingCase.viewable_with_question == True)) .outerjoin(Question.allowed_languages) .options( load_only(Question.html, Question.rc_passage, Question.coding_cases, Question.type))
from flask import Response from json2html import json2html from sqlalchemy.orm import contains_eager from Sugar import JSONifiedNestableBlueprint, requires_roles from models import (Order, PromoCode, User) admin_misc_controller = JSONifiedNestableBlueprint("Admin MISC", __name__) @admin_misc_controller.route('/misc/promo_metrics', methods=['GET']) def get_admin_promo_metrics(): """ Get promocode->orders->users as a table. This takes in a complex json object and uses json2html to make it a readable table. :return: the json in table format as *HTML* format """ query = (PromoCode.query.outerjoin(PromoCode.orders).outerjoin( Order.user).options( contains_eager(PromoCode.orders).load_only( Order.user_id, Order.status).contains_eager( Order.user).load_only(User.email)).all()) result = [promo.todict() for promo in query] for promo in result: cancelled_count = 0
from flask import request from Mail import CONTACT_US, Mail from Sugar import JSONifiedNestableBlueprint, requires_validation from .req_val import ContactUsInputs misc_controller = JSONifiedNestableBlueprint('Misc', __name__) @misc_controller.route("/misc/contact_us", methods=['Post']) @requires_validation(ContactUsInputs) def contact_us(): """ Receives query message and sends it to the email in the request, and also "*****@*****.**" """ req = request.json del req['captcha_token'] email = req['email'] Mail([email, '*****@*****.**', '*****@*****.**'], req, req, req, CONTACT_US).send()
from Sugar import JSONifiedNestableBlueprint from .Users import rex_user_controller from .TestAttempts import rex_testattempts_controller base_blueprint = JSONifiedNestableBlueprint("REXBASE", __name__) base_blueprint.register_blueprint(rex_user_controller) base_blueprint.register_blueprint(rex_testattempts_controller) @base_blueprint.route('', methods=['Post', 'Get']) def echo_time(): pass
from flask import request from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint, requires_validation from extensions import db from models import Choice, Error, Question from .req_val import QuestionInputs __author__ = "Harshvardhan Gupta" # All endpoints will have sectionID in them, so it is prepended # to the nestable controller admin_sections_controller = JSONifiedNestableBlueprint("Admin Sections", __name__) @admin_sections_controller.route('/<sectionId>/questions', methods=['GET']) def get_admin_section_questions(sectionId): """ List Questions of a Section for Admin based on the Section ID :param sectionId: :return: questions """ try: questions = Question.query \ .filter(Question.section_id == sectionId)\ .all() return questions except NoResultFound: # section id is incorrect return Error('Invalid Section ID', 400)()
from flask import request from flask_login import current_user, login_required from sqlalchemy.orm import contains_eager, load_only from sqlalchemy.orm.exc import NoResultFound from Externals import Discourse from Externals.Razorpay import Razorpay from Sugar import JSONifiedNestableBlueprint, requires_validation from extensions import db from models import (Error, Order, OrderCourse, OrderTest, PromoCode, Test) from models.Order import OrderStatusTypes from .req_val import OrderCreateInputs __author__ = "Harshvardhan Gupta" orders_controller = JSONifiedNestableBlueprint("Orders", __name__) @orders_controller.route('/orders', methods=['GET']) @login_required def get_orders(): """ List Orders for a User. Currently it lists test ids associated with the Order. If more items are added, all those will also need to be sent over. :return: [orders.todict()] """ orders = (Order.query.filter_by( **request.args).outerjoin(OrderTest).outerjoin(Test).options( contains_eager(Order.tests).load_only(
from controllers.apiv01.Corporates.Corporates import corporates_controller from extensions import celery from models import TestAttempt from models.SixteenPReport import SixteenPReport from .Colleges import colleges_controller from .Courses import courses_controller from .Discourse import discourse_blueprint from .Misc import misc_controller from .Orders import orders_controller from .PromoCodes import promo_codes_controller from .Tests import tests_controller from .Users import user_controller __author__ = "Harshvardhan Gupta" base_blueprint = JSONifiedNestableBlueprint("BASE", __name__) # base_blueprint.register_blueprint(admin_base_blueprint, url_prefix='/admin') base_blueprint.register_blueprint(user_controller) base_blueprint.register_blueprint(tests_controller) base_blueprint.register_blueprint(promo_codes_controller) base_blueprint.register_blueprint(colleges_controller) base_blueprint.register_blueprint(orders_controller) base_blueprint.register_blueprint(courses_controller) base_blueprint.register_blueprint(discourse_blueprint) base_blueprint.register_blueprint(misc_controller) base_blueprint.register_blueprint(corporates_controller) from flask import request, url_for
from flask import current_app as app, redirect, request, session, url_for from flask_login import current_user, login_required, login_user, logout_user from itsdangerous import BadSignature, URLSafeSerializer from sqlalchemy.orm import contains_eager, load_only from sqlalchemy.orm.exc import NoResultFound from Mail import FORGOT_PASSWORD, Mail, SIGNUP_ACTIVATION, WELCOME_MAIL from Sugar import JSONifiedNestableBlueprint, requires_validation from controllers.rex import CookieHelper from extensions import bcrypt, celery, db, mautic from models import Corporate, Error, User from .req_val import ChangePasswordInputs, ForgotPasswordInputs, LoginInputs, \ ResendActivationInputs, ResetPasswordInputs, SignupInputs user_controller = JSONifiedNestableBlueprint('User', __name__) @user_controller.route('/user', methods=['GET']) @login_required def get_user(): """ Current User is determined by Flask Login based on the Session Cookie :return: """ # print(session) fields = [c.name for c in User.__table__.c] # get all fields except fields = filter(lambda x: x not in ['password', 'is_active', 'type'],
from flask import Response from flask_login import current_user from sqlalchemy import and_ from sqlalchemy.orm import contains_eager from sqlalchemy.orm.exc import NoResultFound from extensions import db from Sugar import JSONifiedNestableBlueprint from Util import Pinger from models import (Section, Test, SectionAttempt, TestAttempt, Error, QuestionAttempt) from datetime import datetime PingController = JSONifiedNestableBlueprint("Ping Controller", __name__) @PingController.route( "/tests/<testID>/sections/<int:sectionID>/questions/<int:questionID>/attempts/ping", methods=["Post"]) def ping(testID, sectionID, questionID): """ Perform 1 ping. The time spent on each section will be reduced by the Pinger's duration value. (Read how the logic works for sectional jumps vs non sectional jumps in the comments below). If all the requests succeed, then the pinger gets a new cookie with an updated time. If not, this operation will not happen, making future requests impossible.
from Sugar import JSONifiedNestableBlueprint from models import Test from .Sections import admin_sections_controller admin_tests_controller = JSONifiedNestableBlueprint("Admin Tests", __name__) admin_tests_controller.register_blueprint(admin_sections_controller, url_prefix='/sections') @admin_tests_controller.route('/tests', methods=['GET']) def get_admin_tests(): """ List of existing Tests :return: """ return Test.query.all()
from flask import request from flask_login import current_user, login_required from sqlalchemy import and_ from sqlalchemy.orm import contains_eager, load_only from sqlalchemy.orm.exc import NoResultFound from Sugar import JSONifiedNestableBlueprint, cachify from models import Error, Order, OrderTest, Test, TestAttempt, Section, \ Question from .Sections import sections_controller from .TestAttempts import test_attempt_controller from .Pinger import PingController tests_controller = JSONifiedNestableBlueprint("Tests", __name__) tests_controller.register_blueprint(test_attempt_controller) tests_controller.register_blueprint(sections_controller) tests_controller.register_blueprint(PingController) @tests_controller.route('/tests', methods=['Get']) def get_tests(): """ List all tests in the system. If user has purchased some, the tests will have 'is_purchased' key to true, else it will be false. If user has access to those tests by being in a college, the same thing