qlam 2.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.
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: qlam
3
+ Version: 2.0.0
4
+ Summary: Python SDK for Qalam Document Format (.qlm)
5
+ Author: Antigravity
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.6
10
+ Dynamic: author
11
+ Dynamic: classifier
12
+ Dynamic: requires-python
13
+ Dynamic: summary
@@ -0,0 +1,5 @@
1
+ qlam.py,sha256=ev4OsHnuJrlkF26OtRNPLi2fcejBBcLashBl1MTusCA,6384
2
+ qlam-2.0.0.dist-info/METADATA,sha256=RBxdHfE6iPieXyyKissV-_BPkFQrBCA6eStelKM8178,381
3
+ qlam-2.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
4
+ qlam-2.0.0.dist-info/top_level.txt,sha256=6cRi9EdJrS0LfziPMrmuAjl-5JJpqV7eWey0Gvcr84Y,5
5
+ qlam-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ qlam
qlam.py ADDED
@@ -0,0 +1,180 @@
1
+ import json
2
+ import os
3
+ import struct
4
+
5
+ class QlmNode:
6
+ """Represents a structured node block in a QLM document."""
7
+ def __init__(self, node_type, title, data=None, parent_id=None, asset_bytes=None, display_style=None):
8
+ self.id = f"node_{os.urandom(8).hex()}"
9
+ self.parent_id = parent_id
10
+ self.type = node_type # text, model3d, image, docx, zip, pdf, etc.
11
+ self.title = title
12
+ self.data = data or {}
13
+ self.display_style = display_style or {"width_ratio": 1.0, "collapsed": False}
14
+ self.asset_bytes = asset_bytes
15
+
16
+ def to_dict(self):
17
+ return {
18
+ "id": self.id,
19
+ "parent_id": self.parent_id,
20
+ "type": self.type,
21
+ "title": self.title,
22
+ "data": self.data,
23
+ "display_style": self.display_style
24
+ }
25
+
26
+ class QlmDocument:
27
+ """Core class for compiling and reading unified .qlm files in Python."""
28
+ def __init__(self, title, author="Anonim"):
29
+ self.id = f"doc_{os.urandom(8).hex()}"
30
+ self.metadata = {
31
+ "title": title,
32
+ "author": author,
33
+ "description": "",
34
+ "language": "tr",
35
+ "created_at": 0,
36
+ "version": "2.0.0",
37
+ "is_encrypted": False,
38
+ "tags": []
39
+ }
40
+ self.nodes = []
41
+ self.relationships = []
42
+
43
+ def add_text(self, title, content, level=3, parent_id=None):
44
+ node = QlmNode(
45
+ node_type="text",
46
+ title=title,
47
+ data={"content": content, "level": level},
48
+ parent_id=parent_id
49
+ )
50
+ self.nodes.append(node)
51
+ return node
52
+
53
+ def add_embed(self, node_type, title, asset_path, mime_type, parent_id=None):
54
+ """Embeds any binary file (3D, docx, zip, image, mp4) to the document."""
55
+ if not os.path.exists(asset_path):
56
+ raise FileNotFoundError(f"Asset file not found: {asset_path}")
57
+
58
+ with open(asset_path, "rb") as f:
59
+ data_bytes = f.read()
60
+
61
+ node = QlmNode(
62
+ node_type=node_type,
63
+ title=title,
64
+ data={"mime": mime_type, "asset_length": len(data_bytes)},
65
+ parent_id=parent_id,
66
+ asset_bytes=data_bytes
67
+ )
68
+ self.nodes.append(node)
69
+ return node
70
+
71
+ def compile(self, output_path):
72
+ """Compiles the document into a high performance manifest-indexed binary QLM document."""
73
+ buffer = bytearray()
74
+
75
+ # 1. Header (14 bytes)
76
+ buffer.extend(b"QLAM")
77
+ # Version (2 bytes) = 2 (u16 little endian)
78
+ buffer.extend(struct.pack("<H", 2))
79
+ # Manifest Offset Placeholder (8 bytes, updated at end)
80
+ manifest_offset_pos = len(buffer)
81
+ buffer.extend(struct.pack("<Q", 0))
82
+
83
+ # 2. Write binary payloads and update node manifests
84
+ nodes_dict = []
85
+ for node in self.nodes:
86
+ node_dict = node.to_dict()
87
+ if node.asset_bytes:
88
+ start_byte = len(buffer)
89
+ buffer.extend(node.asset_bytes)
90
+
91
+ # Update json manifest offsets
92
+ node_dict["data"]["asset_start_byte"] = start_byte
93
+ node_dict["data"]["asset_length"] = len(node.asset_bytes)
94
+
95
+ # 8-byte alignment padding
96
+ padding = (8 - (len(buffer) % 8)) % 8
97
+ buffer.extend(b"\x00" * padding)
98
+
99
+ nodes_dict.append(node_dict)
100
+
101
+ # 3. Calculate final manifest offset and write manifest JSON
102
+ manifest_offset = len(buffer)
103
+
104
+ manifest_doc = {
105
+ "id": self.id,
106
+ "metadata": self.metadata,
107
+ "nodes": nodes_dict,
108
+ "relationships": self.relationships
109
+ }
110
+
111
+ manifest_json = json.dumps(manifest_doc).encode("utf-8")
112
+ buffer.extend(manifest_json)
113
+
114
+ # 4. Fill in the header manifest offset
115
+ struct.pack_into("<Q", buffer, manifest_offset_pos, manifest_offset)
116
+
117
+ # 5. Write to file
118
+ with open(output_path, "wb") as f:
119
+ f.write(buffer)
120
+
121
+ print(f"[QLM] Compiled '{self.metadata['title']}' to {output_path} ({len(buffer)} bytes)")
122
+
123
+ @classmethod
124
+ def load(cls, file_path):
125
+ """Loads and parses a .qlm document into a Python object."""
126
+ if not os.path.exists(file_path):
127
+ raise FileNotFoundError(f"QLM file not found: {file_path}")
128
+
129
+ with open(file_path, "rb") as f:
130
+ data = f.read()
131
+
132
+ if len(data) < 14:
133
+ raise ValueError("Invalid QLM file: too short")
134
+
135
+ # Read magic & version
136
+ magic = data[0:4]
137
+ if magic != b"QLAM":
138
+ raise ValueError(f"Invalid QLM signature: {magic}")
139
+
140
+ version = struct.unpack("<H", data[4:6])[0]
141
+ if version != 2:
142
+ raise ValueError(f"Unsupported QLM version: {version}")
143
+
144
+ # Read manifest offset
145
+ manifest_offset = struct.unpack("<Q", data[6:14])[0]
146
+ if manifest_offset >= len(data):
147
+ raise ValueError("Invalid manifest offset")
148
+
149
+ # Parse JSON manifest
150
+ manifest_json = data[manifest_offset:].decode("utf-8")
151
+ doc_dict = json.loads(manifest_json)
152
+
153
+ # Construct Python QlmDocument instance
154
+ doc = cls(title=doc_dict["metadata"]["title"])
155
+ doc.id = doc_dict["id"]
156
+ doc.metadata = doc_dict["metadata"]
157
+ doc.relationships = doc_dict.get("relationships", [])
158
+
159
+ # Build node tree models and attach internal asset slices
160
+ for node_dict in doc_dict.get("nodes", []):
161
+ asset_bytes = None
162
+ if "asset_start_byte" in node_dict["data"]:
163
+ start = node_dict["data"]["asset_start_byte"]
164
+ length = node_dict["data"]["asset_length"]
165
+ if start + length <= len(data):
166
+ # Zero-copy reference slicing of binary file payload
167
+ asset_bytes = data[start:start+length]
168
+
169
+ node = QlmNode(
170
+ node_type=node_dict["type"],
171
+ title=node_dict["title"],
172
+ data=node_dict["data"],
173
+ parent_id=node_dict.get("parent_id"),
174
+ asset_bytes=asset_bytes,
175
+ display_style=node_dict.get("display_style")
176
+ )
177
+ node.id = node_dict["id"]
178
+ doc.nodes.append(node)
179
+
180
+ return doc