88 lines
4.5 KiB
Python
88 lines
4.5 KiB
Python
"""JSON-file store for the demo. Test data only."""
|
|
import json, os, threading, time, uuid, copy
|
|
|
|
SEED_LISTINGS = [
|
|
{"title": "Used road bike (54 cm frame)", "kind": "product", "price": 18000, "category": "bikes",
|
|
"description": "Aluminium road bike, 18 gears, new tyres last season. Some scratches on the top tube.",
|
|
"tags": ["bike", "bicycle", "cycling", "road"], "emoji": "🚲", "seller": "test-seller-01", "seller_type": "human",
|
|
"area": "Demo Town (north)", "payment_options": ["online", "cash"]},
|
|
{"title": "Maths tutoring, 1 hour (high school)", "kind": "service", "price": 3500, "category": "tutoring",
|
|
"description": "One-on-one algebra, geometry or calculus help. Online or at a library.",
|
|
"tags": ["tutor", "tutoring", "math", "maths", "lesson", "school"], "emoji": "📐", "seller": "test-seller-02",
|
|
"seller_type": "human", "area": "Online / Demo Town", "payment_options": ["online", "cash"]},
|
|
{"title": "Python coding tutoring, 1 hour", "kind": "service", "price": 4500, "category": "tutoring",
|
|
"description": "Beginner-friendly Python sessions: basics, small projects, debugging help.",
|
|
"tags": ["tutor", "tutoring", "coding", "python", "programming", "lesson"], "emoji": "🐍",
|
|
"seller": "agent:tutor-bot (test agent)", "seller_type": "agent", "area": "Online", "payment_options": ["online"]},
|
|
{"title": "Handmade ceramic table lamp", "kind": "product", "price": 6500, "category": "home",
|
|
"description": "Wheel-thrown glazed ceramic base, linen shade, warm LED bulb included.",
|
|
"tags": ["lamp", "light", "handmade", "ceramic", "home", "decor"], "emoji": "🪔", "seller": "test-seller-03",
|
|
"seller_type": "human", "area": "Demo Town (east)", "payment_options": ["online", "cash"]},
|
|
{"title": "Lawn mowing, small yard", "kind": "service", "price": 4000, "category": "garden",
|
|
"description": "Mow, edge and blow for yards up to about 300 m². Green waste taken away.",
|
|
"tags": ["lawn", "mowing", "garden", "yard", "grass"], "emoji": "🌿", "seller": "test-seller-04",
|
|
"seller_type": "human", "area": "Demo Town (south)", "payment_options": ["online", "cash"]},
|
|
{"title": "Bike tune-up service", "kind": "service", "price": 3000, "category": "bikes",
|
|
"description": "Gears and brakes adjusted, chain cleaned and lubed, tyres checked.",
|
|
"tags": ["bike", "bicycle", "repair", "service", "tune"], "emoji": "🔧",
|
|
"seller": "agent:fixit-bot (test agent)", "seller_type": "agent", "area": "Demo Town (west)",
|
|
"payment_options": ["online", "cash"]},
|
|
{"title": "Kids' bike, 16 inch", "kind": "product", "price": 5500, "category": "bikes",
|
|
"description": "Training wheels included. Fits ages 4 to 6.",
|
|
"tags": ["bike", "bicycle", "kids"], "emoji": "🚴", "seller": "test-seller-05", "seller_type": "human",
|
|
"area": "Demo Town (north)", "payment_options": ["cash"]},
|
|
]
|
|
|
|
|
|
def now():
|
|
return time.strftime("%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
|
|
def new_id(prefix):
|
|
return f"{prefix}_{uuid.uuid4().hex[:8]}"
|
|
|
|
|
|
class Store:
|
|
def __init__(self, data_dir):
|
|
os.makedirs(data_dir, exist_ok=True)
|
|
self.path = os.path.join(data_dir, "store.json")
|
|
self.lock = threading.RLock()
|
|
if os.path.exists(self.path):
|
|
with open(self.path) as f:
|
|
self.db = json.load(f)
|
|
else:
|
|
self.db = {"listings": {}, "intents": {}, "orders": {}, "cash_deals": {}, "events": []}
|
|
for s in SEED_LISTINGS:
|
|
lid = new_id("lst")
|
|
self.db["listings"][lid] = {**s, "id": lid, "currency": "USD", "status": "active",
|
|
"test_data": True, "created_at": now()}
|
|
self.save()
|
|
|
|
def save(self):
|
|
with self.lock:
|
|
tmp = self.path + ".tmp"
|
|
with open(tmp, "w") as f:
|
|
json.dump(self.db, f, indent=1)
|
|
os.replace(tmp, self.path)
|
|
|
|
def get(self, table, key):
|
|
with self.lock:
|
|
v = self.db[table].get(key)
|
|
return copy.deepcopy(v) if v else None
|
|
|
|
def put(self, table, obj):
|
|
with self.lock:
|
|
self.db[table][obj["id"]] = obj
|
|
self.save()
|
|
return copy.deepcopy(obj)
|
|
|
|
def all(self, table):
|
|
with self.lock:
|
|
return copy.deepcopy(list(self.db[table].values()))
|
|
|
|
def log(self, kind, data):
|
|
with self.lock:
|
|
self.db["events"].append({"at": now(), "kind": kind, **data})
|
|
self.db["events"] = self.db["events"][-500:]
|
|
self.save()
|