# Dispatches data to hasher and adds to database tables import sqlalchemy import os from datetime import datetime from flask import flash from flask_login import current_user from .models import Hashchain, Art, List, TX , User, Bids, List from . import db from app.lib import clean_file as cf from app.lib import hasher as hsh def mint(designated_fn, art_name, art_desc, min_price, buyout_price, close_date): # gen filehash filehash = hsh.hashfile(f'{cf.UPLOAD_FOLDER}/{designated_fn}') # gen txhash (if exchanged or minted) ddt = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") dt = sqlalchemy.func.now() txstring = f'[{filehash}, {ddt}, {current_user.id}, {current_user.id}, 0.0]' # minting txhash = hsh.gen_txhash(txstring) # fetch prev block hash OR GEN HASH try: prev_bhash = db.session.query(Hashchain).order_by(Hashchain.id.desc()).first().blockhash if prev_bhash is None: prev_bhash = hsh.GENESIS_HASH except: prev_bhash = hsh.GENESIS_HASH # gen block hash add to hashchain new_bhash = hsh.append_tx(txhash, prev_bhash) new_block = Hashchain(blockhash = new_bhash) db.session.add(new_block) # move the file into external secure storage (NOT DONE) os.rename(f'{cf.UPLOAD_FOLDER}/{designated_fn}', f'{cf.REPO_FOLDER}/{designated_fn}') # add to TX table (mint) new_tx = TX( filehash = filehash, datetime = dt, source_id = current_user.id, destination_id = current_user.id, price = 0.0, txhash = txhash ) db.session.add(new_tx) # add to Art table new_art = Art( name = art_name, description = art_desc, filehash = filehash, owner = current_user.id, creator = current_user.id, dname = designated_fn ) db.session.add(new_art) # add to List table new_listing = List( filehash = filehash, seller = current_user.id, min_price = min_price, out_price = buyout_price, timeout = close_date, ) db.session.add(new_listing) try: db.session.commit() flash('Minted & Listed!', category='success') except Exception: flash('Error Minting! Cannot Add an Already Existing File!', category='error') def list_item(designated_fn, art_name, art_desc, min_price, buyout_price, close_date, filehash): # gen txhash ddt = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") dt = sqlalchemy.func.now() txstring = f'[{filehash}, {ddt}, {current_user.id}, {current_user.id}, 0.0]' # listing txhash = hsh.gen_txhash(txstring) # fetch prev block hash OR GEN HASH try: prev_bhash = db.session.query(Hashchain).order_by(Hashchain.id.desc()).first().blockhash if prev_bhash is None: prev_bhash = hsh.GENESIS_HASH except: prev_bhash = hsh.GENESIS_HASH # gen block hash add to hashchain new_bhash = hsh.append_tx(txhash, prev_bhash) new_block = Hashchain(blockhash = new_bhash) db.session.add(new_block) # add to TX table (list) new_tx = TX( filehash = filehash, datetime = dt, source_id = current_user.id, destination_id = current_user.id, price = 0.0, txhash = txhash ) db.session.add(new_tx) # add to List table new_listing = List( filehash = filehash, seller = current_user.id, min_price = min_price, out_price = buyout_price, timeout = close_date, ) db.session.add(new_listing) db.session.commit() def tx_exchange(filehash, source_id, price, dest_id=None): if not dest_id: if current_user.is_authenticated: dest_id = current_user.id # create tx hash dt = sqlalchemy.func.now() ddt = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") txstring = f'[{filehash}, {ddt}, {source_id}, {dest_id}, {price}]' # exchange txhash = hsh.gen_txhash(txstring) # fetch prev block hash OR GEN HASH try: prev_bhash = db.session.query(Hashchain).order_by(Hashchain.id.desc()).first().blockhash if prev_bhash is None: prev_bhash = hsh.GENESIS_HASH except: prev_bhash = hsh.GENESIS_HASH # gen block hash add to hashchain new_bhash = hsh.append_tx(txhash, prev_bhash) new_block = Hashchain(blockhash = new_bhash) db.session.add(new_block) new_tx = TX( filehash = filehash, datetime = dt, source_id = source_id, destination_id = dest_id, price = price, txhash = txhash ) # add to TX table (exchange) db.session.add(new_tx) # remove from List table List.query.filter_by(filehash = filehash).delete() # change owner at Art table dbcall = Art.query.filter_by(filehash = filehash).first() dbcall.owner = dest_id db.session.commit() def clean_bid_table(filehash): # cleans Bid table when Artwork is bought old_bids = Bids.query.filter_by(filehash = filehash).all() for bid in old_bids: db.session.delete(bid) db.session.commit() def enter_bid(user_bid, focus): # add to Bids table new_bid = Bids( filehash = current_user.focus, buyer = current_user.id, bid_price = user_bid ) db.session.add(new_bid) # update List table dbcall = List.query.filter_by(filehash = current_user.focus).first() dbcall.min_price = user_bid dbcall.cur_bid = user_bid db.session.commit() def save_pp(pp_path): new_pppath = User.query.filter_by(id=current_user.id).first() new_pppath.profile_image = pp_path db.session.commit() def check_auction_end(): # background scheduler runs this daily # to check for Auction end all_listings = List.query.all() # go through List table and check for timeout for listing in all_listings: # if close_date and min bid reached ddt = datetime.utcnow().strftime("%Y-%m-%d") if listing.timeout == ddt and listing.cur_bid > listing.min_price: print(f'DEBUG: scheduler >>> EXCHANGING!!') ## # transaction for the last bid made # get buyer id from Bids table using filehash buyer_bid = Bids.query.filter_by(filehash = listing.filehash).order_by(desc(Bids.id)).first() # initiate exchange transaction and clean bid table tx_exchange(listing.filehash, listing.seller, buyer_bid.bid_price, buyer_bid.buyer) clean_bid_table(listing.filehash) # if close_date and min bid not reached (no one made a qualifying bid) elif listing.timeout == ddt and not listing.cur_bid > listing.min_price: print(f'DEBUG: scheduler >>> DE-LISTING!!') ## # remove from List table List.query.filter_by(filehash = filehash).delete()