codepacker 10.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
codepacker/__init__.py
ADDED
codepacker/logic.py
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import os, hashlib, json, uuid, zipfile, shutil, io, tkinter as tk
|
|
2
|
+
from tkinter import ttk, filedialog, messagebox
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import random
|
|
5
|
+
|
|
6
|
+
class MoonspicCore:
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.code_exts = {'.py', '.txt', '.js', '.html', '.css', '.json', '.sh', '.md', '.yaml', '.xml', '.c', '.cpp', '.h'}
|
|
9
|
+
self.delimiter = "#MOONSPIC_CODEPACKER#"
|
|
10
|
+
|
|
11
|
+
def get_sha512(self, data):
|
|
12
|
+
return hashlib.sha512(data if isinstance(data, bytes) else data.encode()).hexdigest()
|
|
13
|
+
|
|
14
|
+
def pack(self, src_path, out_dir):
|
|
15
|
+
src, out = Path(src_path).resolve(), Path(out_dir).resolve()
|
|
16
|
+
stage = out / f"STAGE_{uuid.uuid4().hex[:6]}"
|
|
17
|
+
stage.mkdir(parents=True, exist_ok=True)
|
|
18
|
+
meta = {"project_name": src.name, "files": {}, "delimiter": self.delimiter}
|
|
19
|
+
code_blocks = []
|
|
20
|
+
assets_buffer = io.BytesIO()
|
|
21
|
+
with zipfile.ZipFile(assets_buffer, 'w') as az:
|
|
22
|
+
for r, _, files in os.walk(src):
|
|
23
|
+
for f in files:
|
|
24
|
+
fp = Path(r) / f
|
|
25
|
+
rel = str(fp.relative_to(src))
|
|
26
|
+
f_id = str(uuid.uuid4())[:8]
|
|
27
|
+
raw_data = fp.read_bytes()
|
|
28
|
+
if fp.suffix.lower() in self.code_exts:
|
|
29
|
+
content = raw_data.decode('utf-8', errors='ignore')
|
|
30
|
+
code_blocks.append(f"{self.delimiter} {f_id};{rel}\n{content}")
|
|
31
|
+
else:
|
|
32
|
+
az.write(fp, rel)
|
|
33
|
+
(stage / "CODE.txt").write_text("\n".join(code_blocks))
|
|
34
|
+
(stage / "META.json").write_text(json.dumps(meta, indent=4))
|
|
35
|
+
(stage / "Assets.zip").write_bytes(assets_buffer.getvalue())
|
|
36
|
+
final_zip = out / f"{src.name}_BUNDLE.zip"
|
|
37
|
+
with zipfile.ZipFile(final_zip, 'w') as fz:
|
|
38
|
+
for f in ["CODE.txt", "META.json", "Assets.zip"]: fz.write(stage / f, f)
|
|
39
|
+
shutil.rmtree(stage)
|
|
40
|
+
return str(final_zip)
|
|
41
|
+
|
|
42
|
+
def unpack(self, zip_path, target_dir):
|
|
43
|
+
base_target = Path(target_dir).resolve()
|
|
44
|
+
temp = base_target / "TEMP_UNPACK"
|
|
45
|
+
if temp.exists(): shutil.rmtree(temp)
|
|
46
|
+
temp.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
shutil.unpack_archive(zip_path, temp)
|
|
48
|
+
meta = json.loads((temp / "META.json").read_text())
|
|
49
|
+
proj_folder = meta.get("project_name", "restored_project")
|
|
50
|
+
actual_dest = base_target / proj_folder
|
|
51
|
+
if actual_dest.exists(): shutil.rmtree(actual_dest)
|
|
52
|
+
actual_dest.mkdir(parents=True, exist_ok=True)
|
|
53
|
+
if (temp / "Assets.zip").exists():
|
|
54
|
+
with zipfile.ZipFile(temp / "Assets.zip", 'r') as az: az.extractall(actual_dest)
|
|
55
|
+
if (temp / "CODE.txt").exists():
|
|
56
|
+
parts = (temp / "CODE.txt").read_text().split(meta.get("delimiter", self.delimiter))
|
|
57
|
+
for part in parts:
|
|
58
|
+
if not part.strip() or ";" not in part: continue
|
|
59
|
+
header, body = part.split("\n", 1)
|
|
60
|
+
rel = header.strip().split(";")[1]
|
|
61
|
+
out_f = actual_dest / rel.strip()
|
|
62
|
+
out_f.parent.mkdir(parents=True, exist_ok=True)
|
|
63
|
+
out_f.write_text(body.strip())
|
|
64
|
+
shutil.rmtree(temp)
|
|
65
|
+
return str(actual_dest)
|
|
66
|
+
|
|
67
|
+
def calculate_content_hash(self, directory):
|
|
68
|
+
hasher = hashlib.sha512()
|
|
69
|
+
base = Path(directory).resolve()
|
|
70
|
+
for fp in sorted([f for f in base.rglob('*') if f.is_file()]):
|
|
71
|
+
hasher.update(str(fp.relative_to(base)).encode())
|
|
72
|
+
hasher.update(fp.read_bytes())
|
|
73
|
+
return hasher.hexdigest()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class GUI:
|
|
77
|
+
def start(self):
|
|
78
|
+
root = tk.Tk(); root.title("Moonspic v9.6.0"); root.geometry("800x650")
|
|
79
|
+
core = MoonspicCore()
|
|
80
|
+
nb = ttk.Notebook(root); nb.pack(expand=1, fill='both', padx=10, pady=10)
|
|
81
|
+
t1, t2, t3, t4 = ttk.Frame(nb), ttk.Frame(nb), ttk.Frame(nb), ttk.Frame(nb)
|
|
82
|
+
nb.add(t1, text=" Pack "); nb.add(t2, text=" Unpack "); nb.add(t3, text=" IntegrityMatch "); nb.add(t4, text=" Config ")
|
|
83
|
+
|
|
84
|
+
# 1. PACK TAB (Restored)
|
|
85
|
+
in_v, out_v = tk.StringVar(), tk.StringVar()
|
|
86
|
+
tk.Label(t1, text="Source Folder:").pack(pady=5); tk.Entry(t1, textvariable=in_v, width=70).pack()
|
|
87
|
+
tk.Button(t1, text="Browse", command=lambda: [in_v.set(filedialog.askdirectory()), out_v.set(str(Path(in_v.get()).parent)) if in_v.get() else None]).pack()
|
|
88
|
+
tk.Label(t1, text="Output Directory:").pack(pady=5); tk.Entry(t1, textvariable=out_v, width=70).pack()
|
|
89
|
+
tk.Button(t1, text="GENERATE BUNDLE", bg="black", fg="white", font=('bold'), command=lambda: messagebox.showinfo("OK", f"Created: {core.pack(in_v.get(), out_v.get())}")).pack(pady=20)
|
|
90
|
+
|
|
91
|
+
# 2. UNPACK TAB (Restored)
|
|
92
|
+
z_v, d_v = tk.StringVar(), tk.StringVar()
|
|
93
|
+
tk.Label(t2, text="Bundle ZIP:").pack(pady=5); tk.Entry(t2, textvariable=z_v, width=70).pack()
|
|
94
|
+
tk.Button(t2, text="Browse ZIP", command=lambda: [z_v.set(filedialog.askopenfilename()), d_v.set(str(Path(z_v.get()).parent)) if z_v.get() else None]).pack()
|
|
95
|
+
tk.Label(t2, text="Restore Destination:").pack(pady=5); tk.Entry(t2, textvariable=d_v, width=70).pack()
|
|
96
|
+
tk.Button(t2, text="RESTORE PROJECT", bg="blue", fg="white", font=('bold'), command=lambda: [core.unpack(z_v.get(), d_v.get()), messagebox.showinfo("OK", "Restored")]).pack(pady=20)
|
|
97
|
+
|
|
98
|
+
# 3. INTEGRITY TAB (Updated with Automated Paths)
|
|
99
|
+
tk.Label(t3, text="Verification & Random Testing Suite", font=('Arial', 14, 'bold')).pack(pady=10)
|
|
100
|
+
|
|
101
|
+
# Folder Verification Section
|
|
102
|
+
f_src, f_out = tk.StringVar(), tk.StringVar()
|
|
103
|
+
tk.Label(t3, text="Verify Project Folder:", fg="blue").pack()
|
|
104
|
+
tk.Entry(t3, textvariable=f_src, width=70).pack()
|
|
105
|
+
tk.Button(t3, text="Select Project", command=lambda: [f_src.set(filedialog.askdirectory()), f_out.set(str(Path(f_src.get()).parent / "INTEGRITY_RESULTS")) if f_src.get() else None]).pack()
|
|
106
|
+
tk.Label(t3, text="Test Results Location:").pack()
|
|
107
|
+
tk.Entry(t3, textvariable=f_out, width=70).pack()
|
|
108
|
+
tk.Button(t3, text="Browse Results Path", command=lambda: f_out.set(filedialog.askdirectory())).pack()
|
|
109
|
+
|
|
110
|
+
def run_folder_test():
|
|
111
|
+
if not f_src.get() or not f_out.get(): return
|
|
112
|
+
h1 = core.calculate_content_hash(f_src.get())
|
|
113
|
+
bundle = core.pack(f_src.get(), f_out.get())
|
|
114
|
+
restored = core.unpack(bundle, f_out.get())
|
|
115
|
+
h2 = core.calculate_content_hash(restored)
|
|
116
|
+
res = "✅ MATCH" if h1 == h2 else "❌ MISMATCH"
|
|
117
|
+
messagebox.showinfo("Result", f"{res}\n\nOriginal: {h1[:16]}...\nRestored: {h2[:16]}...")
|
|
118
|
+
|
|
119
|
+
tk.Button(t3, text="START FOLDER VERIFICATION", bg="green", fg="white", command=run_folder_test).pack(pady=5)
|
|
120
|
+
|
|
121
|
+
tk.Label(t3, text="-----------------------------------------").pack()
|
|
122
|
+
|
|
123
|
+
# Random Test Section
|
|
124
|
+
r_out = tk.StringVar()
|
|
125
|
+
tk.Label(t3, text="Random Test Output Directory:", fg="purple").pack()
|
|
126
|
+
tk.Entry(t3, textvariable=r_out, width=70).pack()
|
|
127
|
+
tk.Button(t3, text="Browse Random Test Location", command=lambda: r_out.set(filedialog.askdirectory())).pack()
|
|
128
|
+
|
|
129
|
+
def run_random_test():
|
|
130
|
+
dest = Path(r_out.get()) if r_out.get() else Path.cwd() / "RANDOM_TEST_ROOT"
|
|
131
|
+
if dest.exists(): shutil.rmtree(dest)
|
|
132
|
+
proj = dest / "ProjectX"
|
|
133
|
+
proj.mkdir(parents=True); (proj/"src").mkdir(); (proj/"assets").mkdir()
|
|
134
|
+
(proj/"src/app.py").write_text("print('Integrity Pass')")
|
|
135
|
+
(proj/"assets/data.bin").write_bytes(os.urandom(512))
|
|
136
|
+
|
|
137
|
+
h1 = core.calculate_content_hash(proj)
|
|
138
|
+
bundle = core.pack(proj, dest)
|
|
139
|
+
restored = core.unpack(bundle, dest)
|
|
140
|
+
h2 = core.calculate_content_hash(restored)
|
|
141
|
+
res = "✅ MATCH" if h1 == h2 else "❌ MISMATCH"
|
|
142
|
+
messagebox.showinfo("Random Test", f"Created & Verified ProjectX at {dest}\nResult: {res}")
|
|
143
|
+
|
|
144
|
+
tk.Button(t3, text="GENERATE & RUN RANDOM TEST", bg="#2c3e50", fg="white", command=run_random_test).pack(pady=10)
|
|
145
|
+
|
|
146
|
+
# 4. CONFIG TAB
|
|
147
|
+
tk.Label(t4, text="MoonspicAI v9.6.0", font=('Arial', 16, 'bold')).pack(pady=20)
|
|
148
|
+
tk.Label(t4, text="Delimiter: #MOONSPIC_CODEPACKER#").pack()
|
|
149
|
+
tk.Label(t4, text="Identity: Author Unknown\nRepo: Private").pack(pady=10)
|
|
150
|
+
|
|
151
|
+
root.mainloop()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def start():
|
|
155
|
+
gui = GUI()
|
|
156
|
+
gui.start()
|
|
157
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
codepacker/__init__.py,sha256=ztoIrvw3opS3K7WECfQ6JXCZ608qEeUJ_ARIrl5cp-8,38
|
|
2
|
+
codepacker/logic.py,sha256=LxyCQI3z6jWOxn9wieZuCaIiD9d1U-ULDF2q825SFzM,8399
|
|
3
|
+
codepacker-10.0.0.dist-info/METADATA,sha256=XQylLDDzjKyxef60F31VOVBWxpEiMaJUat0jgIYqtvw,178
|
|
4
|
+
codepacker-10.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
codepacker-10.0.0.dist-info/entry_points.txt,sha256=JMOyDChbfWAvdbRZT431RVZ6ivrIz4Hdyp8K_sqoXeM,58
|
|
6
|
+
codepacker-10.0.0.dist-info/top_level.txt,sha256=ithi-VSDIs0clvHs8x-oBVLfU_RSFGcMpRyb9U5MQ84,11
|
|
7
|
+
codepacker-10.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codepacker
|