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()