dispatch.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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
  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. def clean_bid_table(filehash):
  140. # cleans Bid table when Artwork is bought
  141. old_bids = Bids.query.filter_by(filehash = filehash).all()
  142. for bid in old_bids:
  143. db.session.delete(bid)
  144. db.session.commit()
  145. def enter_bid(user_bid, focus):
  146. # add to Bids table
  147. new_bid = Bids(
  148. filehash = current_user.focus,
  149. buyer = current_user.id,
  150. bid_price = user_bid
  151. )
  152. db.session.add(new_bid)
  153. # update List table
  154. dbcall = List.query.filter_by(filehash = current_user.focus).first()
  155. dbcall.min_price = user_bid
  156. dbcall.cur_bid = user_bid
  157. db.session.commit()
  158. def save_pp(pp_path):
  159. new_pppath = User.query.filter_by(id=current_user.id).first()
  160. new_pppath.profile_image = pp_path
  161. db.session.commit()
  162. def check_auction_end():
  163. # background scheduler runs this daily
  164. # to check for Auction end
  165. all_listings = List.query.all()
  166. # go through List table and check for timeout
  167. for listing in all_listings:
  168. # if close_date and min bid reached
  169. ddt = datetime.utcnow().strftime("%Y-%m-%d")
  170. if listing.timeout == ddt and listing.cur_bid > listing.min_price:
  171. print(f'DEBUG: scheduler >>> EXCHANGING!!') ##
  172. # transaction for the last bid made
  173. # get buyer id from Bids table using filehash
  174. buyer_bid = Bids.query.filter_by(filehash = listing.filehash).order_by(desc(Bids.id)).first()
  175. # initiate exchange transaction and clean bid table
  176. tx_exchange(listing.filehash, listing.seller, buyer_bid.bid_price, buyer_bid.buyer)
  177. clean_bid_table(listing.filehash)
  178. # if close_date and min bid not reached (no one made a qualifying bid)
  179. elif listing.timeout == ddt and not listing.cur_bid > listing.min_price:
  180. print(f'DEBUG: scheduler >>> DE-LISTING!!') ##
  181. # remove from List table
  182. List.query.filter_by(filehash = filehash).delete()