dashboards.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. from flask import Blueprint, render_template, request, flash, redirect, url_for
  2. from flask_login import login_required, current_user
  3. from werkzeug.security import generate_password_hash, check_password_hash
  4. from argon2 import PasswordHasher
  5. from sqlalchemy import desc
  6. from .models import User, Art, List, Bids, Wallet, Stripe, TX, Hashchain
  7. from . import db
  8. from . import dispatch
  9. from app.lib import clean_file as cf, tools
  10. from app.lib import collector
  11. from app.lib import stripe
  12. from app.lib import searcher
  13. from .forms import UPForm, PicForm, CAForm, BidForm, WalletForm, SearchForm
  14. dashboards = Blueprint('dashboards', __name__)
  15. # Main Pages
  16. @dashboards.route('/', methods=['GET', 'POST'])
  17. def market():
  18. return_list = collector.join_art_list_table()
  19. seform = SearchForm()
  20. if request.method == "POST":
  21. focus_item = request.form.get('focus_but')
  22. if focus_item and current_user.is_authenticated:
  23. u_dbcall = User.query.filter_by(id=current_user.id).first()
  24. u_dbcall.focus = focus_item
  25. db.session.commit()
  26. return redirect(url_for('dashboards.detail'))
  27. return render_template('market.html', user=current_user, listings = return_list, seform = seform)
  28. @dashboards.route('/profile', methods=['GET', 'POST'])
  29. @login_required
  30. def profile():
  31. form = UPForm()
  32. form2 = PicForm()
  33. form3 = WalletForm()
  34. user_bid_hist = collector.user_bid_hist(current_user.id)
  35. seform = SearchForm()
  36. ph = PasswordHasher()
  37. # Initializes wallet and fetches amount
  38. dispatch.init_wallet(current_user.id)
  39. wallet = Wallet.query.filter_by(user_id = current_user.id).first()
  40. wallet_amount = float(wallet.amount/100)
  41. # This takes a post request button press
  42. # when user clicks on a photo
  43. if request.method == "POST":
  44. focus_item = request.form.get('focus_but')
  45. if focus_item and collector.check_art_listing(focus_item):
  46. u_dbcall = User.query.filter_by(id=current_user.id).first()
  47. u_dbcall.focus = focus_item
  48. db.session.commit()
  49. return redirect(url_for('dashboards.detail'))
  50. elif focus_item and not collector.check_art_listing(focus_item):
  51. # else if there's a click but no listing, don't do anything
  52. flash('Auction page not available to items not for sale!', category='error')
  53. # Wallet Top Up Form
  54. if form3.validate_on_submit():
  55. amount = form3.amount.data
  56. raw_amount = int(amount*100) # converting to cents int for Stripe
  57. # save to db
  58. dispatch.save_tx(current_user.id, raw_amount)
  59. if amount: # Send to stripe checkout
  60. # render a checkout page for Stripe
  61. # card handling
  62. return render_template(
  63. 'checkout.html',
  64. key = stripe.stripe_keys['publishable_key'],
  65. user = current_user,
  66. amount = amount,
  67. ramount = raw_amount,
  68. seform = seform
  69. )
  70. # Profile Picture Update Form
  71. if form2.validate_on_submit():
  72. f = form2.upload.data
  73. if cf.allowed_file(f.filename):
  74. designated_fn = cf.sanitize(f.filename)
  75. f.save(f'{cf.PROFILEPIC_FOLDER}/{designated_fn}')
  76. dispatch.save_pp(designated_fn)
  77. flash('Updated Profile Picture!', category='success')
  78. # Password Update Form
  79. if form.validate_on_submit():
  80. cpasswd = form.cpasswd.data
  81. passwd = form.passwd_1.data
  82. passwd_con = form.passwd_2.data
  83. # Basic password checks before adding to db
  84. if passwd and passwd_con and cpasswd:
  85. if passwd == passwd_con and ph.verify(current_user.password, cpasswd):
  86. if len(passwd_con) >= 12:
  87. ##:
  88. npasswd = ph.hash(passwd_con)
  89. npasswd_dbcall = User.query.filter_by(id=current_user.id).first()
  90. npasswd_dbcall.password = npasswd
  91. db.session.commit()
  92. flash('Updated password!', category='success')
  93. elif len(passwd_con) < 12:
  94. flash('Password must be equal or longer than 12 characters!', category='error')
  95. else:
  96. flash('Password update failed!', category='error')
  97. else:
  98. flash('Fill in all password fields!', category='error')
  99. my_art = Art.query.filter_by(owner=current_user.id).all()
  100. my_creation = Art.query.filter_by(creator=current_user.id).all()
  101. return render_template(
  102. 'profile.html',
  103. user = current_user,
  104. my_art = my_art,
  105. my_creation = my_creation,
  106. form = form,
  107. form2 = form2,
  108. form3 = form3,
  109. ubh = user_bid_hist,
  110. wallet_amount = wallet_amount,
  111. seform = seform
  112. )
  113. @dashboards.route('/create_art', methods=['GET', 'POST'])
  114. @login_required
  115. def create():
  116. form = CAForm()
  117. # checks for available art to list
  118. available_art = collector.check_listing()
  119. seform = SearchForm()
  120. # check POST req
  121. if form.validate_on_submit():
  122. new_art = form.upload.data
  123. art_name = form.art_name.data
  124. art_desc = form.art_desc.data
  125. min_price = form.min_price.data
  126. buyout_price = form.buyout_price.data
  127. close_date = form.close_date.data
  128. # For minting Art
  129. if tools.check_fields([new_art, art_name, min_price, buyout_price, close_date]):
  130. if new_art and new_art.filename != '' and cf.allowed_file(new_art.filename):
  131. designated_fn = cf.sanitize(new_art.filename)
  132. new_art.save(f'{cf.UPLOAD_FOLDER}/{designated_fn}')
  133. dispatch.mint(designated_fn, art_name, art_desc, min_price, buyout_price, close_date)
  134. # For re-Listing Art
  135. if not new_art:
  136. new_art = request.form.get('web_group') # fetch filehash
  137. if new_art:
  138. # get Art obj from filehash
  139. art_obj = collector.get_art_obj(new_art)
  140. # dispatch re-list function
  141. dispatch.list_item(
  142. art_obj.dname,
  143. art_name,
  144. art_desc,
  145. min_price,
  146. buyout_price,
  147. close_date,
  148. art_obj.filehash
  149. )
  150. flash('Listed!', category='success')
  151. return render_template('create_art.html', user = current_user, form = form, av_art = available_art, seform = seform)
  152. @dashboards.route('/search', methods=['GET', 'POST'])
  153. @login_required
  154. def search():
  155. seform = SearchForm()
  156. se_r = searcher.searcher(seform)
  157. #print(f'DEBUG (dash) se_r: {se_r}')##
  158. sr = searcher.shammer(se_r)
  159. #print(f'DEBUG (dash) sr: {sr}')##
  160. # getting user's focus
  161. if request.method == "POST":
  162. focus_item = request.form.get('focus_but')
  163. if focus_item and collector.check_art_listing(focus_item):
  164. u_dbcall = User.query.filter_by(id=current_user.id).first()
  165. u_dbcall.focus = focus_item
  166. db.session.commit()
  167. return redirect(url_for('dashboards.detail'))
  168. elif focus_item and not collector.check_art_listing(focus_item):
  169. # else if there's a click but no listing, don't do anything
  170. flash('Auction page not available to items not for sale!', category='error')
  171. return render_template('search.html', user = current_user, seform = seform, sr = sr)
  172. @dashboards.route('/detail', methods=['GET', 'POST'])
  173. @login_required
  174. def detail():
  175. focus = None
  176. form = BidForm()
  177. seform = SearchForm()
  178. # Collects details of the listing based on the
  179. # focus pointer of the user
  180. # focus is the return of join_art_list_table in collector
  181. return_list = collector.join_art_list_table()
  182. for item in return_list:
  183. if item[11] == current_user.focus: # comparing hash
  184. focus = item
  185. break
  186. owner_obj = collector.find_user_obj(focus[2])
  187. item_bid_hist = collector.item_bid_hist(current_user.focus)
  188. # New Bid
  189. if form.validate_on_submit():
  190. user_bid = form.price.data
  191. # first check if user has wallet balance
  192. dbc_uwallet = Wallet.query.filter_by(user_id = current_user.id).first()
  193. uwealth = float(dbc_uwallet.amount / 100)
  194. if not uwealth >= float(user_bid):
  195. flash('You don\'t have enough cash in your wallet!', category='error')
  196. return redirect(url_for('dashboards.profile'))
  197. # checking if bid is at buyout price or more
  198. if user_bid and user_bid >= focus[8]:
  199. dispatch.enter_bid(user_bid, focus)
  200. dispatch.tx_exchange(current_user.focus, focus[6], user_bid)
  201. dispatch.clean_bid_table(current_user.focus)
  202. flash('You Bought this piece out! Congratulations!', category='success')
  203. return redirect(url_for('dashboards.profile'))
  204. # checking if bid is higher than minimum bidding price
  205. elif user_bid and user_bid > focus[7]:
  206. dispatch.enter_bid(user_bid, focus)
  207. flash('Bid set! Good luck!', category='success')
  208. else:
  209. flash('Your Bid Price is too low!', category='error')
  210. return redirect(url_for('dashboards.detail'))
  211. return render_template(
  212. 'detail_art.html',
  213. user = current_user,
  214. detail = focus,
  215. own_uname = owner_obj.username,
  216. form = form,
  217. ibh = item_bid_hist,
  218. seform = seform
  219. )
  220. @dashboards.route('/charge', methods=['POST'])
  221. @login_required
  222. def charge():
  223. seform = SearchForm()
  224. # Stripe charge POST request method
  225. # Amount in cents
  226. dbc_stripe = Stripe.query.filter_by(user_id = current_user.id).order_by(Stripe.id.desc()).first()
  227. raw_amount = dbc_stripe.raw_amount
  228. customer = stripe.stripe.Customer.create(
  229. email = 'customer@example.com',
  230. source = request.form['stripeToken']
  231. )
  232. charge = stripe.stripe.Charge.create(
  233. customer = customer.id,
  234. amount = raw_amount,
  235. currency = 'usd',
  236. description = 'Flask Charge'
  237. )
  238. # db dispatch for wallet top up
  239. dispatch.top_up(current_user.id, raw_amount)
  240. return render_template('charge.html', user = current_user, seform = seform)
  241. @dashboards.route('/hashchain', methods=['GET'])
  242. def hashchain():
  243. hashchain = Hashchain.query.order_by(desc(Hashchain.id)).all()
  244. txlist = TX.query.order_by(desc(TX.id)).all()
  245. seform = SearchForm()
  246. return render_template('hash.html', user = current_user, hashchain = hashchain, txlist = txlist, seform = seform)
  247. @dashboards.route('/about', methods=['GET'])
  248. def about():
  249. seform = SearchForm()
  250. return render_template('about.html', user = current_user, seform = seform)