Пример #1
0
def goal_completed(mission_id):
    """Endpoint to add/remove business from a mission's goals_completed."""

    if not g.user:
        return Unauthorized()

    user_mission = UserMission.query.filter_by(
        user_id=g.user.id, mission_id=mission_id).one()

    goals_completed = user_mission.goals_completed.copy()

    data = request.json

    if data['business_id'] in goals_completed:
        goals_completed.remove(data['business_id'])
        out = {'success': 'Goal Open!'}
    else:
        goals_completed.append(data['business_id'])
        out = {'success': 'Goal Completed!'}

    user_mission.goals_completed = goals_completed

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error!'})

    return jsonify(out)
Пример #2
0
def remove_from_mission(mission_id):
    """Endpoint to remove business from mission ."""

    mission = Mission.query.get_or_404(mission_id)

    if not g.user and g.user.id == mission.editor:
        return Unauthorized()

    data = request.json

    business = Business.query.get_or_404(data['business_id'])

    if business not in mission.businesses:
        return jsonify({'success': 'Business not in mission.'})

    mission.businesses.remove(business)
    # don't allow sharing when mission has no businesses.
    if len(mission.businesses) == 0:
        mission.is_public = False

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error!'})

    return jsonify({'success': 'Business Removed from Mission!'})
Пример #3
0
def delete_report(report_id):
    """Delete report view."""

    report = Report.query.get_or_404(report_id)

    if not report.user_id == g.user.id:
        return Unauthorized()

    old_file = report.photo_file if report.photo_file else None

    db.session.delete(report)

    try:
        db.session.commit()
        if old_file:
            H.s3_delete(old_file)
        flash("Report Deleted!", 'success')

    except Exception as e:
        db.session.rollback()
        flash("Error Deleting Report!", 'danger')
        H.error_logging(e)

    return redirect(url_for('user_views.user_detail',
                            username=g.user.username))
Пример #4
0
def add_to_mission(mission_id):
    """Add business to mission endpoint."""

    if not g.user:
        return Unauthorized()

    mission = Mission.query.get_or_404(mission_id)

    data = request.json

    business = Business.query.get(data['id'])

    if business:
        if business in mission.businesses:
            return jsonify({'success': 'Already Added.', 'color': 'warning'})
    else:
        # Index page adds new businesses to DB.
        business = Business.create(
            id=data['id'], name=data['name'], city=data['city'],
            state=data['state'], country=data['country'],
            longitude=float(data['longitude'] or 0),
            latitude=float(data['latitude'] or 0))

    mission.businesses.append(business)

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error!'})

    return jsonify({'success': 'Added!', 'color': 'green'})
Пример #5
0
def add_business():
    """Add business to database if it is not present."""

    data = request.json

    business = Business.query.get(data['id'])

    if business:
        return jsonify({'success': 'business already in database'})

    business = Business.create(id=data['id'],
                               name=data['name'],
                               city=data['city'],
                               state=data['state'],
                               country=data['country'],
                               longitude=float(data['longitude'] or 0),
                               latitude=float(data['latitude'] or 0))

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error!'})

    return jsonify({'success': 'Added!'})
Пример #6
0
def submit_feedback():
    """Endpoint for user to submit feedback to be emailed to developer."""

    data = request.json
    feedback = data['feedback']
    email = data.get('email', '')

    user = g.user.username if g.user else 'Anonymous'

    receiver = "*****@*****.**"
    body = f"<h5>Feedback:</h5>{feedback}<p>From: {user} --Email: {email}</p>"

    try:
        requests.post(f"https://api.mailgun.net/v3/{MAILGUN_DOMAIN}/messages",
                      auth=("api", MAILGUN_API_KEY),
                      data={
                          "from": f"Feedback <mailgun@{MAILGUN_DOMAIN}>",
                          "to": [receiver],
                          "subject": "Feedback",
                          "html": body
                      })
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error sending message', 'color': 'warning'})

    return jsonify({'success': 'Feedback Received!', 'color': 'green'})
Пример #7
0
def set_prefrences():
    """Endpoint to change user preferences. This is called by two different
       forms by two different event handlers. The Boolean form has checkbox
       data and updates preferences on onChange events. The preferences-text
       form updates when user selects official address."""

    if not g.user:
        return Unauthorized()

    data = request.json

    preferences = g.user.preferences.__dict__.copy()

    # If onChange update of Boolean preferences
    if data.get('Boolean'):
        # set each setting to true if data is present else False
        for key in BOOLEAN_PREFERENCES:
            preferences[key] = bool(data.get(key, False))
    else:
        preferences['home_address'] = data.get('home_address_official')
        if data.get('home_coords'):
            preferences['home_coords'] = [
                float(x) for x in data['home_coords'].split(',')
            ]

    g.user.preferences = SimpleNamespace(**preferences)

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'feedback': 'Error!'})

    return jsonify({'feedback': 'Updated'})
Пример #8
0
def update_mission():
    """Endpoint to update a mission."""

    note = {}

    data = request.json
    mission = Mission.query.get_or_404(data['id'])

    if not g.user.id == mission.editor:
        return Unauthorized()

    if data.get('is_public'):
        if len(mission.businesses):
            mission.share()
        else:
            note['note'] = 'You cannot share a mission without goals.'

        del data['is_public']
    else:
        data['is_public'] = False

    mission.update(**data)

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': repr(e)})

    return jsonify({
        'success': 'updated',
        'mission': mission.serialize(),
        **note
    })
Пример #9
0
def like_mission(mission_id):
    """Endpoint to like and un-like missions."""

    if not g.user:
        return Unauthorized()

    mission = Mission.query.get_or_404(mission_id)

    likes = mission.likes.copy()

    if g.user.id in likes:
        likes.remove(g.user.id)
        success = 'removed'
    else:
        likes.add(g.user.id)
        success = 'added'

    mission.likes = likes

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'feedback': 'Error!'})

    return jsonify({'success': success, 'likes': len(mission.likes)})
Пример #10
0
def delete_mission(mission_id):
    """Endpoint to delete a mission."""

    if not g.user:
        return Unauthorized()

    mission = Mission.query.get_or_404(mission_id)
    g.user.missions.remove(mission)

    db.session.commit()

    # if mission was shared and is in use or a report was written don't delete.
    if (mission.date_shared and mission.user_missions) or mission.reports:
        mission.is_public = False
        mission.editor = 2
        db.session.commit()
        return jsonify({'success': 'Mission Deleted!'})

    try:
        db.session.delete(mission)
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': repr(e)})

    return jsonify({'success': 'Mission Deleted!'})
Пример #11
0
def check_google_token():
    """Endpoint to check validity of google user token and sign user in,
       or create new account for user. Return success message for successful
       user creation or sign-in."""

    data = request.json

    user_token = data['idtoken']

    try:
        idinfo = id_token.verify_oauth2_token(user_token,
                                              requests_google.Request(),
                                              GOOGLE_O_AUTH_CLIENT_ID)

    except ValueError as e:
        H.error_logging(e)
        return jsonify({'error': f'Autorization error: {e}'})

    # ID token is valid. Get the user's Google Account ID.
    google_id = idinfo['sub']

    user = User.query.filter_by(password=google_id).first()

    # If not user with this google id try to create one.
    if not user:
        email = idinfo['email']
        username = idinfo['name']
        image_url = idinfo['picture']

        # If email already in use user should sign in using email and password.
        if User.query.filter_by(email=email).first():
            return jsonify({
                'error':
                'Email already in use. Please log in using email and password.'  # noqa e501
            })

        # If username taken add nonce until valid username is formed.
        if User.query.filter_by(username=username).first():
            nonce = 1
            username = f'{username}{nonce}'
            while User.query.filter_by(username=username).first():
                nonce += 1
                username = f'{username}{nonce}'

        try:
            user = User(email=email,
                        username=username,
                        password=google_id,
                        avatar_url=image_url)
            db.session.add(user)
            db.session.commit()
            user.add_bookmarks()
        except Exception as e:
            H.error_logging(e)
            return jsonify({'error': f'Error creating new user: {e}'})

    session['user_id'] = user.id
    flash(f"Welcome {user.username}!", "success")
    return jsonify({'success': 'User logged in.'})
Пример #12
0
def search_yelp():
    """API endpoint to relay search to Yelp search."""

    headers = {'Authorization': f'Bearer {YELP_API_KEY}'}
    params = parse_query_params(request.args)

    try:
        res = requests.get(f'{YELP_URL}/businesses/search',
                           params=params,
                           headers=headers)
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': {'message': repr(e)}})

    return res.json()
Пример #13
0
def login():
    """Login view."""

    if g.user:
        return redirect(url_for('.user_detail', username=g.user.username))

    form = LoginForm()

    if form.validate_on_submit():
        email = form.email.data
        password = form.password.data

        user = User.authenticate(email, password)

        if user is None:
            form.email.errors.append("Email not found.")
        elif user is False:
            form.password.errors.append("Password incorrect.")
        else:
            session['user_id'] = user.id
            session.permanent = True
            flash(f"Welcome {user.username}!", 'success')

            return H.next_page_logic(request)

    if request.method == 'POST':
        flash("Please fix all form errors.", "warning")

    # Create URL for signin button that passes all URL data.
    signup_url = request.full_path.replace('login', 'signup')
    return render_template('user_views/login.html',
                           form=form,
                           signup_url=signup_url)
Пример #14
0
def create_mission():
    """Endpoint to create a mission."""

    if not g.user:
        return Unauthorized()

    try:
        mission = Mission.create(editor=g.user.id, **request.json)
        db.session.commit()
        g.user.missions.append(mission)
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': repr(e)})

    return jsonify({'success': 'Mission Created!',
                    'mission': mission.serialize()})
Пример #15
0
def business_details(business_id):
    """API endpoint to get Yelp business details, Yelp business reviews,
       Foursquare venue id, and Foursquare business details."""

    headers = {'Authorization': f'Bearer {YELP_API_KEY}'}

    try:
        # Get business details
        res = requests.get(f'{YELP_URL}/businesses/{business_id}',
                           headers=headers)
        res.raise_for_status()
        # Get reviews for business
        res2 = requests.get(f'{YELP_URL}/businesses/{business_id}/reviews',
                            headers=headers)
        res2.raise_for_status()
        # Get Foursquare venue id
        params_venue = foursq_venue_params(request)
        res3 = requests.get(f'{FOURSQUARE_URL}/venues/search',
                            params=params_venue)
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': repr(e)})

    if res3.ok:
        # Try to get premium request.
        try:
            venue_id = res3.json()['response']['venues'][0]['id']
            # Get Foursquare business details
            res4 = requests.get(f'{FOURSQUARE_URL}/venues/{venue_id}',
                                params=foursq_params())
        # If over limit our data response won't contain foursquare data.
        except Exception as e:
            H.error_logging(e)

    data = res.json()
    data['reviews'] = res2.json()['reviews']
    # Add gastronaut reports for this business if any.
    data = add_reports_data(business_id, data)
    # Add foursquare data if any.
    if res3.ok and res4.ok:
        data = add_foursquare_data(data, res4.json())

    return data
Пример #16
0
def add_mission(mission_id):
    """Endpoint to add mission to user's missions."""

    if not g.user:
        return Unauthorized()

    mission = Mission.query.get_or_404(mission_id)

    if mission in g.user.missions:
        return jsonify({'success': 'Mission Already Added.'})

    g.user.missions.append(mission)

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error!'})

    return jsonify({'success': 'Mission Added!'})
Пример #17
0
def remove_mission(mission_id):
    """Endpoint to remove mission from user's missions."""

    if not g.user:
        return Unauthorized()

    mission = Mission.query.get_or_404(mission_id)

    if mission not in g.user.missions:
        return jsonify({'success': 'Mission Already Removed.'})

    g.user.missions.remove(mission)

    try:
        db.session.commit()
    except Exception as e:
        H.error_logging(e)
        return jsonify({'error': 'Error!'})

    return jsonify({'success': 'Mission Removed!'})
Пример #18
0
def index():
    """Home view."""

    search_term = request.args.get('q')

    lat, lng = H.get_coords_from_IP_address(request)

    return render_template('main_views/index.html',
                           YELP_CATEGORIES=get_yelp_categories(),
                           first_letters=first_letters,
                           lat=lat,
                           lng=lng,
                           search_term=search_term)
Пример #19
0
def user_edit():
    """User edit profile view."""

    form = EditUserForm(obj=g.user)

    if form.validate_on_submit():

        form.populate_obj(g.user)

        try:
            db.session.commit()
            flash("Profile Updated!", "success")
            return redirect(url_for('.user_detail', username=g.user.username))

        except Exception as e:
            db.session.rollback()
            flash("Error Updating User Profile", 'danger')
            H.error_logging(e)

    if request.method == 'POST':
        flash("Please fix all form errors.", "warning")

    return render_template('user_views/edit_user.html', form=form)
Пример #20
0
def signup():
    """Sign up view."""

    if g.user:
        return redirect(url_for('.user_detail', username=g.user.username))

    form = AddUserForm()

    if form.validate_on_submit():
        password = form.password.data
        # Collect relevant form data items to a dictionary.
        relevant_data = {
            k: v
            for k, v in form.data.items() if k in User.set_get()
        }

        try:
            new_user = User.register(password=password, **relevant_data)
            session['user_id'] = new_user.id
            session.permanent = True
            flash(f"Welcome {new_user.username}!", "success")

            return H.next_page_logic(request)

        except Exception as e:
            db.session.rollback()
            flash("Error Creating User", 'danger')
            H.error_logging(e)

    if request.method == 'POST':
        flash("Please fix all form errors.", "warning")

    # Create URL for login button that passes all URL data.
    login_url = request.full_path.replace("/signup", "/login")
    return render_template('user_views/signup.html',
                           form=form,
                           login_url=login_url)
Пример #21
0
def navbar_search():
    """View to route navbar searches. If normal term search on index page.
       If @username check for user and route to user detail if found.
       If username not found return to page user searched from."""

    search_term = request.args.get('q')

    if search_term and search_term.startswith('@'):
        search_user = User.query.filter_by(username=search_term[1:]).first()
        if not search_user:
            search_user = User.query.filter(
                User.username.ilike(f'%{search_term[1:]}%')).first()
        if search_user:
            return redirect(
                url_for('user_views.user_detail',
                        username=search_user.username))

        flash(f'Gastronaut {search_term} not found', 'warning')

        return H.next_page_logic(request)

    return redirect(url_for('.index', q=search_term))
Пример #22
0
def edit_report(report_id):
    """Report edit view."""

    report = Report.query.get_or_404(report_id)
    form = EditReportForm(obj=report)

    # Check if file was cleared and remove from form to pass validation.
    old_file = H.check_for_clear_file(form)

    if form.validate_on_submit():
        # File upload handling logic.
        form, f, path, old_file = H.check_file_upload_logic_w_clear(
            form, old_file)

        form.populate_obj(report)

        try:
            db.session.commit()
            if f:
                S3_CLIENT.upload_fileobj(f, S3_BUCKET_NAME, path)
            if old_file:
                H.s3_delete(old_file)
            flash("Report Edited!", 'success')
            return redirect(url_for('.report_detail', report_id=report.id))

        except Exception as e:
            db.session.rollback()
            flash("Error Editing Report!", 'danger')
            H.error_logging(e)

    if report.mission_id:
        model = Mission.query.get_or_404(report.mission_id)
        kind = 'Mission'
    else:
        model = Business.query.get_or_404(report.business_id)
        kind = 'Business'

    if request.method == 'POST':
        flash("Please fix all form errors.", "warning")

    return render_template("reports_crud/edit_report.html",
                           form=form,
                           model=model,
                           kind=kind,
                           report_id=report_id)
Пример #23
0
def logout():
    """User logout view."""

    del session['user_id']
    flash(f"{g.user.username} logged out.", 'success')
    return H.next_page_logic(request)
Пример #24
0
def unauthorized(e):
    return H.render_template("401.html"), 401
Пример #25
0
def add_report():
    """Write Report View."""

    mission_id = request.args.get('mission_id')
    business_id = request.args.get('business_id')

    if mission_id and business_id:
        return BadRequest

    form = AddReportForm()

    if form.validate_on_submit():

        relevant_data = {
            k: v
            for k, v in form.data.items() if k in Report.set_get()
        }

        form, relevant_data, f, path = H.check_file_upload_logic(
            form, relevant_data)

        report = Report.create(user_id=g.user.id,
                               mission_id=mission_id,
                               business_id=business_id,
                               **relevant_data)

        try:
            db.session.commit()
            if f:
                S3_CLIENT.upload_fileobj(f, S3_BUCKET_NAME, path)
            flash("Report added!", 'success')
            return redirect(url_for('.report_detail', report_id=report.id))

        except Exception as e:
            db.session.rollback()
            flash("Error Creating Report!", 'danger')
            H.error_logging(e)

    existing_report = H.check_for_existing_report(mission_id, business_id)
    if existing_report:
        # redirect to edit_report view for this report and relay request args.
        request_ars = request.args.to_dict()
        return redirect(
            url_for('.edit_report',
                    report_id=existing_report.id,
                    **request_ars))

    if mission_id:
        kind = 'Mission'
        model = Mission.query.get_or_404(mission_id)
    else:
        kind = 'Business'
        model = Business.query.get(business_id)
        if not model:
            model = H.add_new_business(business_id, request.args)
            if model is False:
                return BadRequest

    if request.method == 'POST':
        flash("Please fix all form errors.", "warning")

    return render_template("reports_crud/add_report.html",
                           form=form,
                           model=model,
                           kind=kind)
Пример #26
0
def page_not_found(e):
    return H.render_template("404.html"), 404