コード例 #1
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def subject_test(user, subject_key):
    """
    Send test concepts
    """
    subject_key = Utils.urlsafe_to_key(subject_key)

    session_data = user.getSession()

    if session_data['views'] < 5:
        return Respond.error("Not enough views left", error_code=400)

    # Find revised concepts
    concepts = UserConcept.query(UserConcept.subject == subject_key,
                                 ancestor=user.key).fetch()

    # select 5 randomly

    if len(concepts) < 5:
        return Respond.error("Less than 5 concepts read", error_code=400)

    # Unique indices
    random_nums = random.sample(range(1, len(concepts)), 5)

    test_concepts = []

    for i in random_nums:
        test_concepts.append(concepts[i].concept.get().to_dict())

    user.subtractSessionViews(5)

    return Respond.success({
        "concepts": test_concepts,
        "session_data": user.getSession()
    })
コード例 #2
0
def admin_login():
    """
	Login a user
	:return:
	"""
    # Pass the post details
    post = Utils.parse_json(request)

    # Check if email and password in the post
    if 'email' not in post or 'password' not in post:
        return Respond.error("Email password not found", error_code=422)

    # Find the user with that email
    user = User.query(User.email == post['email']).get()

    # If user not found
    if user is None:
        return Respond.error("User not found with the provided email",
                             error_code=404)

    if user.type != "Admin" and user.type != "Creator":
        return Respond.error("Login with password not allowed", error_code=422)

    # If password not correct
    if not user.verify_password(post['password']):
        return Respond.error("Password incorrect")

    # Make token
    token = user.make_token()

    # Respond with user and token
    return Respond.success({"token": token, "user": user.as_dict()})
コード例 #3
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def activate_pro(user):
    """
    Activate pro usage for the user
    :param user:
    :return: Response
    """

    # Perform checks

    if user.getPoints() < PRO_COST:
        return Respond.error('Low balance', error_code=420)

    if user.pro:
        return Respond.error('User already a pro', error_code=410)

    post = Utils.parse_json(request)

    users_with_device = User.query(User.device == post['device']).fetch()

    if len(users_with_device) > 0:
        return Respond.error('Device already registered by another user')

    # Activate Pro for user on this device

    user.subtractPoints(PRO_COST, 'Activated Pro')

    user.pro = True
    user.device = post['device']

    user.put()

    return Respond.success('Activated pro for user')
コード例 #4
0
    def wrapper_func(*args, **kwargs):
        token = request.headers.get('Authorization')
        if token is None:
            return Respond.error('Auth Required', 401)

        user = User.from_token(token)

        if user is None:
            return Respond.error('User not found', 400)
        else:
            return original_function(user, *args, **kwargs)
コード例 #5
0
def social_login():
    """
	Login via google
	With the id token get user details, if the user does not 
	exist then create it. If the user is coming back then just save the id token 
	Then make a token and send it to the client
	"""
    post = Utils.parse_json(request)
    id_token = post['id_token']

    url = 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=%s' % id_token

    try:
        result = urlfetch.fetch(url)
        if result.status_code == 200:
            result = json.loads(result.content)
            name = result['name']
            email = result['email']
            picture = result['picture']
        else:
            error = 'Status code: {} , Response: {}'.format(
                result.status_code, result.content)
            logging.error(error)
            return Respond.error('Error getting user info from google.')
    except urlfetch.Error:
        logging.exception('Caught exception fetching url')
        return Respond.error('Error getting user info from google.')

    users = User.query(User.email == email).fetch()

    if len(users) > 1:
        return Respond.error("There was an error", error_code=422)

    elif len(users) == 1:
        # User already exists. Just make a token and return
        user = users[0]

        # Make token
        token = user.make_token()

        # Respond with user and token
        return Respond.success({"token": token, "user": user.as_dict()})
    else:
        # New User. Create and send token
        user = User(name=name, email=email, picture_uri=picture)
        user.put()

        # Make token
        token = user.make_token()

        # Respond with user and token
        return Respond.success({"token": token, "user": user.as_dict()})
コード例 #6
0
    def wrapper_func(*args, **kwargs):
        token = request.headers.get('Authorization')

        if token is None:
            return Respond.error('Auth Required', 401)

        user = User.from_token(token)
        if user is None:
            return Respond.error('User not found', 400)
        elif (user.type != 'Admin' and user.type != 'Creator'):
            return Respond.error("Permission Denied", 422)
        else:
            return original_function(user, *args, **kwargs)
コード例 #7
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def mark_concept_important(user, concept_key):
    """
    Mark a concept as important
    """

    concept = Utils.urlsafe_to_key(concept_key).get()

    # Get the user data for the concept
    user_data = UserConcept.query(UserConcept.concept == concept.key,
                                  ancestor=user.key).get()

    if not user_data:

        subject = concept.key.parent().parent()

        user_data = UserConcept(subject=subject,
                                concept=concept.key,
                                important=True,
                                parent=user.key)

        user_data.put()

    else:
        if user_data.important:
            return Respond.error('Concept already marked important')

        user_data.important = True
        user_data.put()

    return Respond.success('Concept marked important')
コード例 #8
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def subject_revise(user, subject_key):
    """
    Send revision concepts
    """

    # Find not read concepts
    # Fetch the first 5 from them
    # Send concepts

    subject = Utils.urlsafe_to_key(subject_key).get()

    session_data = user.getSession()

    if session_data['views'] < 5:
        return Respond.error("Not enough views left", error_code=420)

    user_concepts = UserConcept.query(UserConcept.subject == subject.key,
                                      ancestor=user.key).fetch()

    chapters = Chapter.query(ancestor=subject.key).order(Chapter.srno)

    revision_concepts = []

    for chapter in chapters:

        concepts = Concept.query(ancestor=chapter.key).order(
            Concept.srno).fetch()

        for concept in concepts:
            if len(revision_concepts) < 5:
                if any(x.concept == concept.key for x in user_concepts):
                    pass
                else:
                    revision_concepts.append(concept.to_dict())
            else:
                break

    if len(revision_concepts) is 0:
        return Respond.error("No concepts left to revise", error_code=400)

    user.subtractSessionViews(len(revision_concepts))

    return Respond.success({
        "concepts": revision_concepts,
        "session_data": user.getSession()
    })
コード例 #9
0
def get(user):
    course = user.course.get()
    if not course:
        return Respond.error("User not subscribed to a course", error_code=400)

    subjects = map(Subject.dict_for_list,
                   Subject.query(ancestor=course.key).fetch())

    return Respond.success({"subjects": subjects})
コード例 #10
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def read_concept(user, concept_key):
    """
    Send the concept to the user
    """

    if not user_has_views(user, 1):
        return Respond.error('Not enough views left', error_code=420)

    concept = Utils.urlsafe_to_key(concept_key).get()

    return Respond.success({"concept": concept.to_dict()})
コード例 #11
0
def admin_register(user):
    """
	Get the post variables and register the user
	:return: User token
	"""
    # parse the json request
    post = Utils.parse_json(request)

    # Check if basic account info is in the post
    if 'name' not in post or 'email' not in post or 'password' not in post:
        return Respond.error("Validation Error", error_code=422)

    # Check if email has not registered before
    if User.query(User.email == post['email']).count() > 0:
        return Respond.error("User account with this email already registered",
                             401)

    # Create a user model
    user = User(name=post['name'],
                email=post['email'],
                password=User.hash_password(post['password']),
                type=post['type'])

    # Add other properties of the user if sent
    if 'year' in post:
        user.year = post['year']
    if 'course' in post:
        user.course = post['course']
    if 'college' in post:
        user.college = post['college']
    if 'picture_uri' in post:
        user.picture_uri = post['picture_uri']

    # Save the user
    user.put()

    # Make a token for the user
    token = user.make_token()

    # Respond with the token
    return Respond.success({"token": token, "user": user.as_dict()})
コード例 #12
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def reset_session(user):
    if user.getPoints() < RESET_COST:
        return Respond.error('User does not have enough points',
                             error_code=400)

    user.subtractPoints(RESET_COST, "Skipped cooldown")

    session = UserSession(views=PER_SESSION_VIEWS, parent=user.key)

    session.put()

    return Respond.success({
        "session": session.as_dict(),
        "balance": user.getPoints()
    })
コード例 #13
0
def done_concept(user, concept_key):
    """
	Mark a concept as done
	"""
    # get the concept data entity
    concept_data = UserConceptData.query(
        UserConceptData.concept == Utils.urlsafe_to_key(concept_key),
        ancestor=user.key).get()
    if not concept_data:
        return Respond.error(error="No data of user for this concept")
    # mark it as understood
    concept_data.done = True
    concept_data.put()
    # return
    return Respond.success("Marked done")
コード例 #14
0
def wrong_concept(user, concept_key):
    """
	Mark a concept as wrong
	"""
    # get the concept data entity
    concept_data = UserConceptData.query(
        UserConceptData.concept == Utils.urlsafe_to_key(concept_key),
        ancestor=user.key).get()
    if not concept_data:
        return Respond.error(error="No data of user for this concept")
    # mark done as false
    concept_data.done = False
    concept_data.put()
    # return
    return Respond.success("Marked wrong")
コード例 #15
0
def right_concept(user, concept_key):
    """
	Mark a concept as right
	"""
    # get the concept data entity
    concept_data = UserConceptData.query(
        UserConceptData.concept == Utils.urlsafe_to_key(concept_key),
        ancestor=user.key).get()
    if not concept_data:
        return Respond.error(error="No data of user for this concept")
    # increase right count
    concept_data.right = concept_data.right + 1
    concept_data.put()
    # return
    return Respond.success("Marked right")
コード例 #16
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def save_data_offline(user, subject_key):
    """
    Send a json file to download all concept data of the subject
    """

    if not user.pro:
        return Respond.error('User not a pro', error_code=410)

    subject = Utils.urlsafe_to_key(subject_key).get()

    index = []

    user_data_list = UserConcept.query(UserConcept.subject == subject.key,
                                       ancestor=user.key).fetch()

    user_data = {}
    for data in user_data_list:
        user_data[data.concept.urlsafe()] = {
            'important': data.important,
            'read': data.read
        }

    chapters = Chapter.query(ancestor=subject.key).order(Chapter.srno)

    for chapter in chapters:
        concepts = []
        concept_list = Concept.query(ancestor=chapter.key).order(Concept.srno)

        for concept in concept_list:
            concept_data = concept.to_dict()
            key = concept_data['key']

            if key in user_data:
                concept_data.update(user_data[key])

            concepts.append(concept_data)

        index.append({
            "name": chapter.name,
            "key": chapter.key.urlsafe(),
            "concepts": concepts
        })

    return Respond.success(index)
コード例 #17
0
def store(user):
    """
	Store a concept.
	:param user:
	:return:
	"""
    post = Utils.parse_json(request)

    if 'name' not in post or 'chapter_key' not in post:
        return Respond.error("Input not valid", error_code=422)

    chapter_key = ndb.Key(urlsafe=post['chapter_key'])

    srno = Concept.query(ancestor=chapter_key).count()

    concept = Concept(name=post['name'], srno=srno, parent=chapter_key)

    concept.put()

    return Respond.success({'concept': concept.to_dict()})
コード例 #18
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def get_batch_concepts(user):
    """
    Send concepts required by in the request
    :param user:
    :return:
    """

    post = Utils.parse_json(request)

    concepts = post['concepts']

    if not user_has_views(user, len(concepts)):
        return Respond.error('Not enough views left', error_code=420)

    response = []

    for concept in concepts:
        entity = Utils.urlsafe_to_key(concept).get()
        response.append(entity.to_dict())

    return Respond.success({"concepts": response})
コード例 #19
0
def request_payment(user):

    payment_request = Payment(user=user.key,
                              cost=100,
                              points=750,
                              status="Pending")

    payment_request.put()

    headers = {"X-Api-Key": API_KEY, "X-Auth-Token": AUTH_TOKEN}
    payload = {
        'purpose': "Noted coins",
        'amount': payment_request.cost,
        'buyer_name': user.name,
        'email': user.email,
        'webhook': 'https://noted-api.appspot.com/study/payments/webhook',
        'allow_repeated_payments': 'False',
    }

    response = requests.post(
        "https://www.instamojo.com/api/1.1/payment-requests/",
        data=payload,
        headers=headers)

    insta_request = response.json()

    if insta_request['success'] == False:
        return Respond.error(insta_request['message'])

    payment_request.request_url = insta_request['payment_request']['longurl']
    payment_request.request_id = insta_request['payment_request']['id']

    payment_request.put()

    return Respond.success({
        'payment_request': insta_request['payment_request'],
        'payment_key': payment_request.key.urlsafe()
    })
コード例 #20
0
ファイル: appController.py プロジェクト: hetunandu/noted-api
def code_redeem(user):
    """
    Check code for user and give points accordingly
    """

    post = Utils.parse_json(request)

    code_data = UserCodes.query(UserCodes.code == post['code'],
                                UserCodes.activated == False).get()

    if not code_data:

        promo_data = UserCodes.query(UserCodes.code == post['code'],
                                     ancestor=user.key).get()

        if not promo_data:
            return Respond.error('No code found', error_code=400)

        user.addPoints(promo_data.points, "Used code: " + promo_data.code)

        return Respond.success({
            "new_points": promo_data.points,
            "balance": user.getPoints()
        })

    code_data.activated = True
    code_data.activatedBy = user.key

    code_data.put()

    user.addPoints(code_data.points, "Used code: " + code_data.code)

    return Respond.success({
        "new_points": code_data.points,
        "balance": user.getPoints()
    })
コード例 #21
0
def page_not_found(e):
    return Respond.error("Some error occurred")