generated from nathanwoodburn/python-webserver-template
136 lines
3.5 KiB
Python
136 lines
3.5 KiB
Python
|
import os
|
||
|
import json
|
||
|
import dotenv
|
||
|
import requests
|
||
|
import time
|
||
|
|
||
|
dotenv.load_dotenv()
|
||
|
HSD_IP = os.getenv("HSD_IP")
|
||
|
HSD_API = os.getenv("HSD_API")
|
||
|
|
||
|
if not os.path.exists("data/listings.json"):
|
||
|
with open("data/listings.json", "w") as f:
|
||
|
f.write("[]")
|
||
|
|
||
|
|
||
|
# region Classes
|
||
|
class Listing:
|
||
|
def __init__(self, **kwargs):
|
||
|
self.domain = ''
|
||
|
self.price = 0
|
||
|
self.description = ''
|
||
|
self.tx = ''
|
||
|
self.updated = -1
|
||
|
|
||
|
for key, value in kwargs.items():
|
||
|
setattr(self, key, value)
|
||
|
|
||
|
self.updated = int(time.time())
|
||
|
|
||
|
def __str__(self):
|
||
|
return f"Listing of {self.domain} for {self.price}, Description: {self.description}, Contact: {self.contact}, Signed: {self.signed}, Signature: {self.signature}, Updated: {self.updated}"
|
||
|
|
||
|
def toHTML(self):
|
||
|
return f"""
|
||
|
<div class="card">
|
||
|
<div class="card-body">
|
||
|
<h4 class="card-title">{self.domain}/</h4>
|
||
|
<h6 class="text-muted card-subtitle mb-2">{self.price} HNS</h6>
|
||
|
<p class="card-text">{self.description}</p>
|
||
|
<p class="card-text">TX: <code>{self.tx}</code></p>
|
||
|
</div>
|
||
|
</div>
|
||
|
"""
|
||
|
|
||
|
def toJSON(self):
|
||
|
return {
|
||
|
'domain': self.domain,
|
||
|
'description': self.description,
|
||
|
'price': self.price,
|
||
|
'tx': self.tx,
|
||
|
'updated': self.updated
|
||
|
}
|
||
|
|
||
|
def to_dict(self):
|
||
|
return self.toJSON()
|
||
|
|
||
|
def txValid(self):
|
||
|
# TODO Validate tx is valid
|
||
|
return True
|
||
|
|
||
|
# endregion
|
||
|
|
||
|
def get_listings() -> list[Listing]:
|
||
|
with open("data/listings.json", "r") as f:
|
||
|
data = json.loads(f.read())
|
||
|
|
||
|
listings = []
|
||
|
for listing in data:
|
||
|
listings.append(Listing(**listing))
|
||
|
return listings
|
||
|
|
||
|
def search_listings(domain) -> Listing:
|
||
|
listings = get_listings()
|
||
|
for listing in listings:
|
||
|
if listing.domain == domain:
|
||
|
return listing
|
||
|
return None
|
||
|
|
||
|
def remove_listing(domain) -> bool:
|
||
|
listings = get_listings()
|
||
|
for listing in listings:
|
||
|
if listing.domain == domain:
|
||
|
listings.remove(listing)
|
||
|
saveListings(listings)
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
def get_listings_rendered() -> str:
|
||
|
listings = get_listings()
|
||
|
html = ""
|
||
|
for listing in listings:
|
||
|
html += listing.toHTML()
|
||
|
return html
|
||
|
|
||
|
def saveListings(listings:list[Listing]):
|
||
|
with open("data/listings.json", "w") as f:
|
||
|
f.write(json.dumps(listings,default=Listing.toJSON,indent=4))
|
||
|
|
||
|
def add_listing(listing:Listing):
|
||
|
if not listing.txValid():
|
||
|
return "Invalid tx"
|
||
|
|
||
|
# Remove any listings with the same domain
|
||
|
remove_listing(listing.domain)
|
||
|
|
||
|
listings = get_listings()
|
||
|
listings.append(listing)
|
||
|
saveListings(listings)
|
||
|
return True
|
||
|
|
||
|
|
||
|
def validate_signature(domain,signature,message) -> bool:
|
||
|
response = requests.post(f"http://x:{HSD_API}@{HSD_IP}:12037", json={
|
||
|
"method":"verifymessagewithname",
|
||
|
"params":[
|
||
|
domain,
|
||
|
signature,
|
||
|
message
|
||
|
]
|
||
|
})
|
||
|
if response.status_code != 200:
|
||
|
return False
|
||
|
|
||
|
response = response.json()
|
||
|
if response['result'] != True:
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
def validate_buy_tx(domain,tx) -> bool:
|
||
|
return False
|
||
|
|
||
|
def validate_cancel_signature(domain,signature) -> bool:
|
||
|
message = f"FS: {domain}"
|
||
|
if (not validate_signature(domain,signature,message)):
|
||
|
return False
|
||
|
return True
|