dispatch.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. # Dispatches data to hasher and adds to database tables
  2. import sqlalchemy
  3. import os
  4. from datetime import datetime
  5. from flask import flash
  6. from flask_login import current_user
  7. from .models import Hashchain, Art, List, TX , User, Bids, List, Wallet, Stripe
  8. from . import db
  9. from app.lib import clean_file as cf
  10. from app.lib import hasher as hsh
  11. def mint(designated_fn, art_name, art_desc, min_price, buyout_price, close_date):
  12. # gen filehash
  13. filehash = hsh.hashfile(f'{cf.UPLOAD_FOLDER}/{designated_fn}')
  14. # gen txhash (if exchanged or minted)
  15. ddt = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
  16. dt = sqlalchemy.func.now()
  17. txstring = f'[{filehash}, {ddt}, {current_user.id}, {current_user.id}, 0.0]' # minting
  18. txhash = hsh.gen_txhash(txstring)
  19. # fetch prev block hash OR GEN HASH
  20. try:
  21. prev_bhash = db.session.query(Hashchain).order_by(Hashchain.id.desc()).first().blockhash
  22. if prev_bhash is None:
  23. prev_bhash = hsh.GENESIS_HASH
  24. except:
  25. prev_bhash = hsh.GENESIS_HASH
  26. # gen block hash add to hashchain
  27. new_bhash = hsh.append_tx(txhash, prev_bhash)
  28. new_block = Hashchain(blockhash = new_bhash)
  29. db.session.add(new_block)
  30. # move the file into external secure storage (NOT DONE)
  31. os.rename(f'{cf.UPLOAD_FOLDER}/{designated_fn}', f'{cf.REPO_FOLDER}/{designated_fn}')
  32. # add to TX table (mint)
  33. new_tx = TX(
  34. filehash = filehash,
  35. datetime = dt,
  36. source_id = current_user.id,
  37. destination_id = current_user.id,
  38. price = 0.0,
  39. txhash = txhash
  40. )
  41. db.session.add(new_tx)
  42. # add to Art table
  43. new_art = Art(
  44. name = art_name,
  45. description = art_desc,
  46. filehash = filehash,
  47. owner = current_user.id,
  48. creator = current_user.id,
  49. dname = designated_fn
  50. )
  51. db.session.add(new_art)
  52. # add to List table
  53. new_listing = List(
  54. filehash = filehash,
  55. seller = current_user.id,
  56. min_price = min_price,
  57. out_price = buyout_price,
  58. timeout = close_date,
  59. )
  60. db.session.add(new_listing)
  61. try:
  62. db.session.commit()
  63. flash('Minted & Listed!', category='success')
  64. except Exception:
  65. flash('Error Minting! Cannot Add an Already Existing File!', category='error')
  66. def list_item(designated_fn, art_name, art_desc, min_price, buyout_price, close_date, filehash):
  67. # gen txhash
  68. ddt = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
  69. dt = sqlalchemy.func.now()
  70. txstring = f'[{filehash}, {ddt}, {current_user.id}, {current_user.id}, 0.0]' # listing
  71. txhash = hsh.gen_txhash(txstring)
  72. # fetch prev block hash OR GEN HASH
  73. try:
  74. prev_bhash = db.session.query(Hashchain).order_by(Hashchain.id.desc()).first().blockhash
  75. if prev_bhash is None:
  76. prev_bhash = hsh.GENESIS_HASH
  77. except:
  78. prev_bhash = hsh.GENESIS_HASH
  79. # gen block hash add to hashchain
  80. new_bhash = hsh.append_tx(txhash, prev_bhash)
  81. new_block = Hashchain(blockhash = new_bhash)
  82. db.session.add(new_block)
  83. # add to TX table (list)
  84. new_tx = TX(
  85. filehash = filehash,
  86. datetime = dt,
  87. source_id = current_user.id,
  88. destination_id = current_user.id,
  89. price = 0.0,
  90. txhash = txhash
  91. )
  92. db.session.add(new_tx)
  93. # add to List table
  94. new_listing = List(
  95. filehash = filehash,
  96. seller = current_user.id,
  97. min_price = min_price,
  98. out_price = buyout_price,
  99. timeout = close_date,
  100. )
  101. db.session.add(new_listing)
  102. db.session.commit()
  103. def tx_exchange(filehash, source_id, price, dest_id=None):
  104. if not dest_id:
  105. if current_user.is_authenticated:
  106. dest_id = current_user.id
  107. # create tx hash
  108. dt = sqlalchemy.func.now()
  109. ddt = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
  110. txstring = f'[{filehash}, {ddt}, {source_id}, {dest_id}, {price}]' # exchange
  111. txhash = hsh.gen_txhash(txstring)
  112. # fetch prev block hash OR GEN HASH
  113. try:
  114. prev_bhash = db.session.query(Hashchain).order_by(Hashchain.id.desc()).first().blockhash
  115. if prev_bhash is None:
  116. prev_bhash = hsh.GENESIS_HASH
  117. except:
  118. prev_bhash = hsh.GENESIS_HASH
  119. # gen block hash add to hashchain
  120. new_bhash = hsh.append_tx(txhash, prev_bhash)
  121. new_block = Hashchain(blockhash = new_bhash)
  122. db.session.add(new_block)
  123. new_tx = TX(
  124. filehash = filehash,
  125. datetime = dt,
  126. source_id = source_id,
  127. destination_id = dest_id,
  128. price = price,
  129. txhash = txhash
  130. )
  131. # add to TX table (exchange)
  132. db.session.add(new_tx)
  133. # remove from List table
  134. List.query.filter_by(filehash = filehash).delete()
  135. # change owner at Art table
  136. dbcall = Art.query.filter_by(filehash = filehash).first()
  137. dbcall.owner = dest_id
  138. db.session.commit()
  139. # transaction action on wallets
  140. tx_wallet(dest_id, source_id, price)
  141. def clean_bid_table(filehash):
  142. # cleans Bid table when Artwork is bought
  143. old_bids = Bids.query.filter_by(filehash = filehash).all()
  144. for bid in old_bids:
  145. db.session.delete(bid)
  146. db.session.commit()
  147. def enter_bid(user_bid, focus):
  148. # add to Bids table
  149. new_bid = Bids(
  150. filehash = current_user.focus,
  151. buyer = current_user.id,
  152. bid_price = user_bid
  153. )
  154. db.session.add(new_bid)
  155. # update List table
  156. dbcall = List.query.filter_by(filehash = current_user.focus).first()
  157. dbcall.min_price = user_bid
  158. dbcall.cur_bid = user_bid
  159. db.session.commit()
  160. def save_pp(pp_path):
  161. new_pppath = User.query.filter_by(id=current_user.id).first()
  162. new_pppath.profile_image = pp_path
  163. db.session.commit()
  164. def check_auction_end():
  165. # background scheduler runs this daily
  166. # to check for Auction end
  167. all_listings = List.query.all()
  168. # go through List table and check for timeout
  169. for listing in all_listings:
  170. # if close_date and min bid reached
  171. ddt = datetime.utcnow().strftime("%Y-%m-%d")
  172. if listing.timeout == ddt and listing.cur_bid > listing.min_price:
  173. # transaction for the last bid made
  174. # get buyer id from Bids table using filehash
  175. buyer_bid = Bids.query.filter_by(filehash = listing.filehash).order_by(desc(Bids.id)).first()
  176. # initiate exchange transaction and clean bid table
  177. tx_exchange(listing.filehash, listing.seller, buyer_bid.bid_price, buyer_bid.buyer)
  178. clean_bid_table(listing.filehash)
  179. # if close_date and min bid not reached (no one made a qualifying bid)
  180. elif listing.timeout == ddt and not listing.cur_bid > listing.min_price:
  181. # remove from List table
  182. List.query.filter_by(filehash = filehash).delete()
  183. def init_wallet(user_id):
  184. user_wallet = Wallet.query.filter_by(user_id = user_id).first()
  185. if not user_wallet:
  186. dbc_ntable = Wallet(
  187. user_id = user_id,
  188. amount = 0
  189. )
  190. db.session.add(dbc_ntable)
  191. db.session.commit()
  192. def top_up(user_id, raw_amount):
  193. # add to Stripe top up transaction table
  194. dbc_ntable = Stripe(
  195. user_id = user_id,
  196. raw_amount = raw_amount,
  197. )
  198. db.session.add(dbc_ntable)
  199. # Append to user Wallet amount
  200. dbc_wallet = Wallet.query.filter_by(user_id = user_id).first()
  201. dbc_wallet.amount += raw_amount # converted to dollars float in db
  202. db.session.commit()
  203. def tx_wallet(src_id, dest_id, tx_amount):
  204. # user paying
  205. dbc_src = Wallet.query.filter_by(user_id = src_id).first()
  206. # user receiving
  207. dbc_dest = Wallet.query.filter_by(user_id = dest_id).first()
  208. tx_amount = int(tx_amount*100) # converting to cents int
  209. dbc_src.amount -= tx_amount
  210. dbc_dest.amount += tx_amount
  211. db.session.commit()