#!/usr/bin/env python3 """FSI_FELON Mesh Repo — P2P Git-like module Commands: mesh init Initialize a repo mesh publish Archive and announce to mesh mesh clone / Clone a remote repo mesh pull / Pull latest version mesh push Push new version (alias for publish) mesh search Search repos across mesh mesh fork / Fork a repo mesh log Show version history """ import os, sys, json, time, hashlib, tarfile, shutil, threading from http.server import HTTPServer, BaseHTTPRequestHandler MESH_DB = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mesh_db.json") NODE_ID = None def _set_node_id(nid): global NODE_ID NODE_ID = nid def _load_db(): if os.path.exists(MESH_DB): with open(MESH_DB) as f: return json.load(f) return {"shared": [], "peers": [], "repos": {}} def _save_db(db): with open(MESH_DB, "w") as f: json.dump(db, f, indent=2) class MeshRepo: def __init__(self, workspace=None): if workspace is None: workspace = os.path.join(os.path.dirname(os.path.abspath(__file__)), "workspace") self.workspace = workspace os.makedirs(workspace, exist_ok=True) self._peer_server = None def init(self, name): path = os.path.join(self.workspace, name) if os.path.exists(os.path.join(path, ".mesh", "manifest.json")): return {"error": f"Repo '{name}' already exists"} os.makedirs(path, exist_ok=True) mesh_dir = os.path.join(path, ".mesh") os.makedirs(os.path.join(mesh_dir, "versions"), exist_ok=True) manifest = { "name": name, "description": "", "version": 0, "node_id": NODE_ID or "unknown", "created": int(time.time()), "updated": int(time.time()), "tags": [], "license": "MIT", "origin": None, "versions": [], } with open(os.path.join(mesh_dir, "manifest.json"), "w") as f: json.dump(manifest, f, indent=2) db = _load_db() db.setdefault("repos", {})[name] = {"path": path, "node_id": NODE_ID or "local", "manifest": manifest} _save_db(db) return {"success": True, "name": name, "path": path} def publish(self, name): path = os.path.join(self.workspace, name) mf_path = os.path.join(path, ".mesh", "manifest.json") if not os.path.exists(mf_path): return {"error": f"Repo '{name}' not initialized. Run 'mesh init {name}' first"} manifest = json.load(open(mf_path)) version = manifest["version"] + 1 archive_name = f"v{version}.tar.gz" archive_path = os.path.join(path, ".mesh", "versions", archive_name) with tarfile.open(archive_path, "w:gz") as tar: for root, dirs, files in os.walk(path): parts = root.replace(path, "").split(os.sep) if ".mesh" in parts: dirs[:] = [] continue for f in files: fp = os.path.join(root, f) tar.add(fp, arcname=os.path.relpath(fp, path)) manifest["version"] = version manifest["updated"] = int(time.time()) manifest["versions"].append({ "version": version, "hash": hashlib.sha256(open(archive_path, "rb").read()).hexdigest()[:16], "timestamp": int(time.time()), "size": os.path.getsize(archive_path), }) with open(mf_path, "w") as f: json.dump(manifest, f, indent=2) db = _load_db() db.setdefault("repos", {})[name] = {"path": path, "node_id": NODE_ID or "local", "manifest": manifest} _save_db(db) return {"success": True, "name": name, "version": version, "archive": archive_path, "size": os.path.getsize(archive_path)} def clone(self, source): parts = source.split("/") if len(parts) != 2: return {"error": "Format: node_id/repo_name"} node_id, repo_name = parts db = _load_db() repo = db.get("repos", {}).get(repo_name) if repo and repo["node_id"] == node_id: dst = os.path.join(self.workspace, repo_name) if os.path.exists(dst): return {"error": f"'{repo_name}' already exists in workspace"} shutil.copytree(repo["path"], dst) manifest = json.load(open(os.path.join(dst, ".mesh", "manifest.json"))) return {"success": True, "name": repo_name, "version": manifest["version"], "path": dst} return {"error": f"Repo '{repo_name}' not found on node '{node_id}'"} def pull(self, source): parts = source.split("/") if len(parts) != 2: return {"error": "Format: node_id/repo_name"} node_id, repo_name = parts path = os.path.join(self.workspace, repo_name) if not os.path.exists(os.path.join(path, ".mesh", "manifest.json")): return {"error": f"'{repo_name}' not found locally. Clone first."} db = _load_db() remote = db.get("repos", {}).get(repo_name) if not remote: return {"error": f"Remote repo '{repo_name}' not found on mesh"} local_mf = json.load(open(os.path.join(path, ".mesh", "manifest.json"))) remote_mf = remote["manifest"] if remote_mf["version"] <= local_mf["version"]: return {"success": True, "message": "Already up to date", "version": local_mf["version"]} # Copy all new version archives for v in remote_mf["versions"]: if v["version"] > local_mf["version"]: src = os.path.join(remote["path"], ".mesh", "versions", f"v{v['version']}.tar.gz") dst_dir = os.path.join(path, ".mesh", "versions") os.makedirs(dst_dir, exist_ok=True) shutil.copy(src, os.path.join(dst_dir, f"v{v['version']}.tar.gz")) with tarfile.open(src, "r:gz") as tar: tar.extractall(path) # Update local manifest local_mf["version"] = remote_mf["version"] local_mf["updated"] = int(time.time()) local_mf["versions"] = remote_mf["versions"] with open(os.path.join(path, ".mesh", "manifest.json"), "w") as f: json.dump(local_mf, f, indent=2) return {"success": True, "name": repo_name, "version": remote_mf["version"]} def push(self, name): return self.publish(name) def search(self, query): db = _load_db() repos = db.get("repos", {}) q = query.lower() results = [] for rname, rdata in repos.items(): m = rdata.get("manifest", {}) score = 0 if q in rname.lower(): score += 10 if q in m.get("description", "").lower(): score += 5 for tag in m.get("tags", []): if q in tag.lower(): score += 3 if score > 0: results.append({ "name": rname, "node_id": rdata.get("node_id", ""), "description": m.get("description", ""), "version": m.get("version", 1), "tags": m.get("tags", []), "score": score, }) results.sort(key=lambda x: x["score"], reverse=True) return {"results": results, "count": len(results)} def fork(self, source): result = self.clone(source) if result.get("success"): path = os.path.join(self.workspace, result["name"]) mf = json.load(open(os.path.join(path, ".mesh", "manifest.json"))) mf["origin"] = source with open(os.path.join(path, ".mesh", "manifest.json"), "w") as f: json.dump(mf, f, indent=2) result["origin"] = source return result def log(self, name): path = os.path.join(self.workspace, name, ".mesh", "manifest.json") if not os.path.exists(path): return {"error": f"Repo '{name}' not found"} manifest = json.load(open(path)) return { "name": name, "version_count": len(manifest.get("versions", [])), "versions": manifest.get("versions", []), "created": manifest.get("created"), "updated": manifest.get("updated"), "node_id": manifest.get("node_id"), "origin": manifest.get("origin"), } def serve(self, port=9091): if self._peer_server: return {"port": port, "status": "already running"} class _Handler(BaseHTTPRequestHandler): repo = self def do_GET(self): # /repo//manifest # /repo//download/ parts = self.path.strip("/").split("/") if len(parts) >= 2 and parts[0] == "repo": name = parts[1] path = os.path.join(self.repo.workspace, name, ".mesh", "manifest.json") if os.path.exists(path): if len(parts) == 2 or (len(parts) == 3 and parts[2] == "manifest"): self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(open(path, "rb").read()) return elif len(parts) == 4 and parts[2] == "download": vname = parts[3] apath = os.path.join(self.repo.workspace, name, ".mesh", "versions", vname) if os.path.exists(apath): self.send_response(200) self.send_header("Content-Type", "application/gzip") self.end_headers() self.wfile.write(open(apath, "rb").read()) return self.send_response(404) self.end_headers() def log_message(self, *a): pass try: self._peer_server = HTTPServer(("0.0.0.0", port), _Handler) t = threading.Thread(target=self._peer_server.serve_forever, daemon=True) t.start() return {"port": port, "status": "listening"} except Exception as e: return {"error": str(e)}