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

Feat/donation #22

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ class Config(object):
CSRF_ENABLED = True
SECRET_KEY = os.environ.get(
'SECRET_KEY') or os.urandom(32)
AWS_ACCESS_KEY = os.getenv('AWS_ACCESS_KEY')
AWS_SECRET_KEY = os.getenv('AWS_SECRET_KEY')
AWS_BUCKET_NAME = os.getenv('AWS_BUCKET_NAME')


class ProductionConfig(Config):
Expand All @@ -25,6 +28,7 @@ class DevelopmentConfig(Config):
DEBUG = True
ASSETS_DEBUG = False


class TestingConfig(Config):
TESTING = True
DEBUG = True
Expand Down
31 changes: 31 additions & 0 deletions instagram_web/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
from flask_wtf.csrf import CSRFProtect
from app import app
from flask import render_template
from instagram_web.blueprints.users.views import users_blueprint
from instagram_web.blueprints.sessions.views import sessions_blueprint
from instagram_web.blueprints.donations.views import donations_blueprint

from flask_assets import Environment, Bundle
from .util.assets import bundles
from flask_login import LoginManager
from models.user import User

assets = Environment(app)
assets.register(bundles)

app.register_blueprint(users_blueprint, url_prefix="/users")
app.register_blueprint(sessions_blueprint, url_prefix="/sessions")
app.register_blueprint(donations_blueprint, url_prefix="/donations")
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "home"

csrf = CSRFProtect(app)


@login_manager.user_loader
def load_user(user_id):
return User.get_by_id(user_id)


@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500


@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404


@app.errorhandler(401)
def forbidden_entry(e):
return render_template('401.html'), 401


@app.route("/")
def home():
return render_template('home.html')

# everytime create a new table, register the blueprint here
49 changes: 49 additions & 0 deletions instagram_web/blueprints/donations/templates/donations/new.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{% extends "_layout.html" %}

{% block title %}
Payment Page
{% endblock %}

{% block header %}
<script src="https://js.braintreegateway.com/web/dropin/1.22.1/js/dropin.min.js"></script>
{% endblock %}

{% block content %}
<div class="container mb-3">
<div class="row justify-content-center">
<div class="col-6">
<img class="w-50 mx-auto d-block mb-4" src="{{image.user_image_url}}" alt="">
<!-- FORM FOR PASSING CLIENT TOKEN -->
<form id="donation-form" method="post" action="{{url_for('donations.create', image_id=image.id)}}">
<input type="hidden" name="payment_method_nonce" id="pmn-field">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<div class="form-group">
<label for="amount">Amount:</label>
<input type="text" name="amount" class="form-control">
</div>
</form>
<div id="dropin-container"></div>
<button class="btn btn-primary mx-auto d-block" id="submit-button">Request payment method</button>
</div>
</div>
</div>

<script>
var button = document.querySelector('#submit-button');

braintree.dropin.create({
authorization: '{{client_token}}',
container: '#dropin-container'
}, function (createErr, instance) {
button.addEventListener('click', function () {
instance.requestPaymentMethod(function (err, payload) {
// Submit payload.nonce to your server
// console.log(payload)
$('#pmn-field').val(payload.nonce)
$('#donation-form').submit()
});
});
});
</script>

{% endblock %}
81 changes: 81 additions & 0 deletions instagram_web/blueprints/donations/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from flask import Flask, redirect, url_for, escape, request, Blueprint, render_template, request, flash
from models.userimages import UserImage
from models.user import User
from flask_login import login_required, current_user
from instagram_web.util.bthelper import gateway
from instagram_web.util.mailhelper import send_simple_message
from models.donation import Donation
import requests
import os

donations_blueprint = Blueprint('donations',
__name__,
template_folder='templates')


@donations_blueprint.route('/<image_id>/new', methods=["GET"])
@login_required
def new(image_id):
image = UserImage.get_or_none(UserImage.id == image_id)

if not image:
flash(f"No Image was found with the provided ID")
return redirect(url_for('users.index'))

# BELOW TAKEN FROM from instagram_web.util.bthelper import gateway
client_token = gateway.client_token.generate()
# breakpoint()

if not client_token:
flash(f"Unable to obtain client token")
return redirect(url_for('users.index'))

return render_template('donations/new.html', image=image, client_token=client_token)


@donations_blueprint.route('/<image_id>', methods=["POST"])
@login_required
def create(image_id):
nonce = request.form.get('payment_method_nonce')

if not nonce:
flash(f"Error with payment method nonce", 'warning')
return redirect(url_for('users.index'))

image = UserImage.get_or_none(UserImage.id == image_id)

if not image:
flash(f"Could not find image with provided ID", 'warning')
return redirect(url_for('users.index'))

amount = request.form.get("amount")

if not amount:
flash(f"No donation provided", "warning")
return redirect(url_for('users.index'))

result = gateway.transaction.sale({
"amount": amount,
"payment_method_nonce": nonce,
"options": {
"submit_for_settlement": True
}
})

if not result.is_success:
flash(
f"Error in gateway transaction", "warning")
return redirect(request.referrer)

donation = Donation(amount=amount, image_id=image.id,
user_id=current_user.id)
# ---- GET DONATOR NAME AND PASS TO EMAIL------
donator = User.get_or_none(User.id == current_user.id)

if not donation.save():
flash(f"Donated succesfully but error creating a record in database", 'warning')
return redirect(url_for('users.index'))

flash(f"Donated: ${amount}", 'sucess')
send_simple_message(amount=amount, name=donator.name)
return redirect(url_for('users.index'))
35 changes: 35 additions & 0 deletions instagram_web/blueprints/sessions/templates/sessions/new.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{% extends "_layout.html" %}

{% block title %}
Sign Up
{% endblock %}

{% block header %}
{% endblock %}

{% block content %}
<h1>Signin</h1>


<!-- ----------------- CREATE SIGNIN FORM ---------------->
<form method="post" action="{{url_for('sessions.sign_in')}}">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" name="login_email">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" name="login_password">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

{% for error in errors if errors|length > 0 %}
<div style="margin:30px" class="alert alert-danger" role="alert">
<li>{{error}}</li>
</div>
{% endfor %}

{% endblock %}
52 changes: 52 additions & 0 deletions instagram_web/blueprints/sessions/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from flask import Flask, session, redirect, url_for, escape, request, Blueprint, render_template, request, flash
from models.user import User
from werkzeug.security import check_password_hash
from flask_login import login_user, logout_user, login_required, current_user

sessions_blueprint = Blueprint('sessions',
__name__,
template_folder='templates')


@sessions_blueprint.route('/', methods=["GET"])
def new():
return render_template("sessions/new.html")


@sessions_blueprint.route('/new', methods=['POST'])
def sign_in():
login_email = request.form.get("login_email")
login_password = request.form.get("login_password")
# passw = User.get_or_none(User.password == login_password)

user = User.get_or_none(User.email == login_email)
# check in db if there is a user with the email we typed in in signin form

checked = check_password_hash(user.password, login_password)

if not user: # CHANGE TO == USERID
flash(f"Email does not exist")
return redirect(url_for('sessions.new'))
else:

if not checked:
flash(f"Password does not match our records")
return redirect(url_for('sessions.new'))
else:
# session cannot store a whole python object, just the attritbute, so choose between id, name, email, etc
# SESSION METHOD
# session["user"] = user.id
# session["name"] = user.name
# FLASK METHOD
login_user(user)
flash(f"Login sucessful")
# return redirect(url_for('sessions.new'))
return redirect(url_for('home'))


@sessions_blueprint.route('/logout')
def logout():
# remove the username from the session if it's there
logout_user()
flash(f"Logout sucessful")
return redirect(url_for('sessions.new'))
50 changes: 50 additions & 0 deletions instagram_web/blueprints/users/templates/users/edit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{% extends "_layout.html" %}

{% block title %}
Sign Up
{% endblock %}

{% block header %}
{% endblock %}

{% block content %}
<div id="editpage">
<h1>Edit User Page</h1>

<!-- DISPLAY PREVIEW OF IMAGE TO BE UPLOADED HERE? OR JUST DISPLAY PLACEHOLDER IF NONE
-->
{% if user.profile_image %}
<img class="editpic" src="{{user.profile_image_url}}" alt="profile placeholder">
{% else %}
<img class="editpic" src="{{url_for('static', filename='images/placeholder.png')}}" alt=" profile placeholder">
{% endif %}
<form id="image-form" action="{{url_for('users.upload')}}" method="post" enctype="multipart/form-data">
<input type="file" class="form-control" name="profile_image" id="image-file">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<!-- <button id="change-profile">Change Profile Image</button> -->
<button id="upload-button">Upload Profile Image</button>
</form>


<form method="post" action="{{url_for('users.update', id=user.id)}}">
<div class="form-group">
<label for="exampleInputUsername">Username</label>
<input type="username" class="form-control" name="new_name" value={{user.name}}>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" name="new_email" value={{user.email}}>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

{% for error in errors if errors|length > 0 %}
<div style="margin:30px" class="alert alert-danger" role="alert">
<li>{{error}}</li>
</div>
{% endfor %}
</div>
{% endblock %}
Loading