kicad-sch-api 0.3.5__py3-none-any.whl → 0.4.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.
Potentially problematic release.
This version of kicad-sch-api might be problematic. Click here for more details.
- kicad_sch_api/collections/__init__.py +2 -2
- kicad_sch_api/collections/base.py +5 -7
- kicad_sch_api/collections/components.py +24 -12
- kicad_sch_api/collections/junctions.py +31 -43
- kicad_sch_api/collections/labels.py +19 -27
- kicad_sch_api/collections/wires.py +17 -18
- kicad_sch_api/core/components.py +5 -0
- kicad_sch_api/core/formatter.py +3 -1
- kicad_sch_api/core/labels.py +2 -2
- kicad_sch_api/core/managers/__init__.py +26 -0
- kicad_sch_api/core/managers/file_io.py +243 -0
- kicad_sch_api/core/managers/format_sync.py +501 -0
- kicad_sch_api/core/managers/graphics.py +579 -0
- kicad_sch_api/core/managers/metadata.py +268 -0
- kicad_sch_api/core/managers/sheet.py +454 -0
- kicad_sch_api/core/managers/text_elements.py +536 -0
- kicad_sch_api/core/managers/validation.py +474 -0
- kicad_sch_api/core/managers/wire.py +346 -0
- kicad_sch_api/core/nets.py +1 -1
- kicad_sch_api/core/no_connects.py +5 -3
- kicad_sch_api/core/parser.py +75 -41
- kicad_sch_api/core/schematic.py +779 -1083
- kicad_sch_api/core/texts.py +1 -1
- kicad_sch_api/core/types.py +1 -4
- kicad_sch_api/geometry/font_metrics.py +3 -1
- kicad_sch_api/geometry/symbol_bbox.py +40 -21
- kicad_sch_api/interfaces/__init__.py +1 -1
- kicad_sch_api/interfaces/parser.py +1 -1
- kicad_sch_api/interfaces/repository.py +1 -1
- kicad_sch_api/interfaces/resolver.py +1 -1
- kicad_sch_api/parsers/__init__.py +2 -2
- kicad_sch_api/parsers/base.py +7 -10
- kicad_sch_api/parsers/label_parser.py +7 -7
- kicad_sch_api/parsers/registry.py +4 -2
- kicad_sch_api/parsers/symbol_parser.py +5 -10
- kicad_sch_api/parsers/wire_parser.py +2 -2
- kicad_sch_api/symbols/__init__.py +1 -1
- kicad_sch_api/symbols/cache.py +9 -12
- kicad_sch_api/symbols/resolver.py +20 -26
- kicad_sch_api/symbols/validators.py +188 -137
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/METADATA +1 -1
- kicad_sch_api-0.4.0.dist-info/RECORD +67 -0
- kicad_sch_api-0.3.5.dist-info/RECORD +0 -58
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/WHEEL +0 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/entry_points.txt +0 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Metadata Manager for KiCAD schematic configuration.
|
|
3
|
+
|
|
4
|
+
Handles schematic-level settings, properties, and configuration including
|
|
5
|
+
paper size, title block, version information, and instance sections.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MetadataManager:
|
|
15
|
+
"""
|
|
16
|
+
Manages schematic metadata and configuration settings.
|
|
17
|
+
|
|
18
|
+
Responsible for:
|
|
19
|
+
- Title block management
|
|
20
|
+
- Paper size and page setup
|
|
21
|
+
- Version and generator information
|
|
22
|
+
- Library and instance sections
|
|
23
|
+
- Schema-level properties
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, schematic_data: Dict[str, Any]):
|
|
27
|
+
"""
|
|
28
|
+
Initialize MetadataManager with schematic data.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
schematic_data: Reference to schematic data dictionary
|
|
32
|
+
"""
|
|
33
|
+
self._data = schematic_data
|
|
34
|
+
|
|
35
|
+
def set_paper_size(self, paper: str) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Set paper size for the schematic.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
paper: Paper size (e.g., "A4", "A3", "Letter", "Legal")
|
|
41
|
+
"""
|
|
42
|
+
valid_sizes = ["A4", "A3", "A2", "A1", "A0", "Letter", "Legal", "Tabloid"]
|
|
43
|
+
|
|
44
|
+
if paper not in valid_sizes:
|
|
45
|
+
logger.warning(f"Unusual paper size: {paper}. Valid sizes: {valid_sizes}")
|
|
46
|
+
|
|
47
|
+
self._data["paper"] = paper
|
|
48
|
+
logger.debug(f"Set paper size: {paper}")
|
|
49
|
+
|
|
50
|
+
def set_version_info(
|
|
51
|
+
self, version: Optional[int] = None, generator: Optional[str] = None
|
|
52
|
+
) -> None:
|
|
53
|
+
"""
|
|
54
|
+
Set KiCAD version and generator information.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
version: KiCAD schema version number
|
|
58
|
+
generator: Generator application string
|
|
59
|
+
"""
|
|
60
|
+
if version is not None:
|
|
61
|
+
self._data["version"] = version
|
|
62
|
+
logger.debug(f"Set version: {version}")
|
|
63
|
+
|
|
64
|
+
if generator is not None:
|
|
65
|
+
self._data["generator"] = generator
|
|
66
|
+
logger.debug(f"Set generator: {generator}")
|
|
67
|
+
|
|
68
|
+
def set_title_block(
|
|
69
|
+
self,
|
|
70
|
+
title: str = "",
|
|
71
|
+
date: str = "",
|
|
72
|
+
rev: str = "",
|
|
73
|
+
company: str = "",
|
|
74
|
+
comments: Optional[Dict[int, str]] = None,
|
|
75
|
+
) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Set title block information.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
title: Schematic title
|
|
81
|
+
date: Creation/revision date
|
|
82
|
+
rev: Revision number
|
|
83
|
+
company: Company name
|
|
84
|
+
comments: Numbered comments (1, 2, 3, etc.)
|
|
85
|
+
"""
|
|
86
|
+
if comments is None:
|
|
87
|
+
comments = {}
|
|
88
|
+
|
|
89
|
+
self._data["title_block"] = {
|
|
90
|
+
"title": title,
|
|
91
|
+
"date": date,
|
|
92
|
+
"rev": rev,
|
|
93
|
+
"company": company,
|
|
94
|
+
"comments": comments,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
logger.debug(f"Set title block: {title} rev {rev}")
|
|
98
|
+
|
|
99
|
+
def copy_metadata_from(self, source_data: Dict[str, Any]) -> None:
|
|
100
|
+
"""
|
|
101
|
+
Copy metadata from another schematic.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
source_data: Source schematic data to copy from
|
|
105
|
+
"""
|
|
106
|
+
# Copy basic metadata
|
|
107
|
+
for key in ["paper", "version", "generator"]:
|
|
108
|
+
if key in source_data:
|
|
109
|
+
self._data[key] = source_data[key]
|
|
110
|
+
|
|
111
|
+
# Copy title block if present
|
|
112
|
+
if "title_block" in source_data:
|
|
113
|
+
self._data["title_block"] = source_data["title_block"].copy()
|
|
114
|
+
|
|
115
|
+
# Copy lib_symbols if present
|
|
116
|
+
if "lib_symbols" in source_data:
|
|
117
|
+
self._data["lib_symbols"] = source_data["lib_symbols"].copy()
|
|
118
|
+
|
|
119
|
+
logger.info("Copied metadata from source schematic")
|
|
120
|
+
|
|
121
|
+
def add_lib_symbols_section(self, lib_symbols: Dict[str, Any]) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Add or update lib_symbols section.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
lib_symbols: Library symbols data
|
|
127
|
+
"""
|
|
128
|
+
self._data["lib_symbols"] = lib_symbols
|
|
129
|
+
logger.debug(f"Updated lib_symbols section with {len(lib_symbols)} symbols")
|
|
130
|
+
|
|
131
|
+
def add_instances_section(self, instances: Dict[str, Any]) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Add or update symbol instances section.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
instances: Symbol instances data
|
|
137
|
+
"""
|
|
138
|
+
self._data["symbol_instances"] = instances
|
|
139
|
+
logger.debug("Updated symbol_instances section")
|
|
140
|
+
|
|
141
|
+
def add_sheet_instances_section(self, sheet_instances: List[Dict]) -> None:
|
|
142
|
+
"""
|
|
143
|
+
Add or update sheet instances section.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
sheet_instances: List of sheet instance data
|
|
147
|
+
"""
|
|
148
|
+
self._data["sheet_instances"] = sheet_instances
|
|
149
|
+
logger.debug(f"Updated sheet_instances section with {len(sheet_instances)} instances")
|
|
150
|
+
|
|
151
|
+
def set_uuid(self, uuid_str: str) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Set schematic UUID.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
uuid_str: UUID string for the schematic
|
|
157
|
+
"""
|
|
158
|
+
self._data["uuid"] = uuid_str
|
|
159
|
+
logger.debug(f"Set schematic UUID: {uuid_str}")
|
|
160
|
+
|
|
161
|
+
def get_version(self) -> Optional[int]:
|
|
162
|
+
"""Get KiCAD schema version."""
|
|
163
|
+
return self._data.get("version")
|
|
164
|
+
|
|
165
|
+
def get_generator(self) -> Optional[str]:
|
|
166
|
+
"""Get generator application string."""
|
|
167
|
+
return self._data.get("generator")
|
|
168
|
+
|
|
169
|
+
def get_uuid(self) -> Optional[str]:
|
|
170
|
+
"""Get schematic UUID."""
|
|
171
|
+
return self._data.get("uuid")
|
|
172
|
+
|
|
173
|
+
def get_paper_size(self) -> Optional[str]:
|
|
174
|
+
"""Get paper size."""
|
|
175
|
+
return self._data.get("paper")
|
|
176
|
+
|
|
177
|
+
def get_title_block(self) -> Dict[str, Any]:
|
|
178
|
+
"""
|
|
179
|
+
Get title block information.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
Title block data dictionary
|
|
183
|
+
"""
|
|
184
|
+
return self._data.get("title_block", {})
|
|
185
|
+
|
|
186
|
+
def get_lib_symbols(self) -> Dict[str, Any]:
|
|
187
|
+
"""
|
|
188
|
+
Get lib_symbols section.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Library symbols data
|
|
192
|
+
"""
|
|
193
|
+
return self._data.get("lib_symbols", {})
|
|
194
|
+
|
|
195
|
+
def get_symbol_instances(self) -> Dict[str, Any]:
|
|
196
|
+
"""
|
|
197
|
+
Get symbol instances section.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Symbol instances data
|
|
201
|
+
"""
|
|
202
|
+
return self._data.get("symbol_instances", {})
|
|
203
|
+
|
|
204
|
+
def get_sheet_instances(self) -> List[Dict]:
|
|
205
|
+
"""
|
|
206
|
+
Get sheet instances section.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
List of sheet instances
|
|
210
|
+
"""
|
|
211
|
+
return self._data.get("sheet_instances", [])
|
|
212
|
+
|
|
213
|
+
def get_metadata_summary(self) -> Dict[str, Any]:
|
|
214
|
+
"""
|
|
215
|
+
Get comprehensive metadata summary.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Dictionary with all metadata information
|
|
219
|
+
"""
|
|
220
|
+
title_block = self.get_title_block()
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
"version": self.get_version(),
|
|
224
|
+
"generator": self.get_generator(),
|
|
225
|
+
"uuid": self.get_uuid(),
|
|
226
|
+
"paper": self.get_paper_size(),
|
|
227
|
+
"title": title_block.get("title", ""),
|
|
228
|
+
"revision": title_block.get("rev", ""),
|
|
229
|
+
"company": title_block.get("company", ""),
|
|
230
|
+
"date": title_block.get("date", ""),
|
|
231
|
+
"comments": title_block.get("comments", {}),
|
|
232
|
+
"lib_symbols_count": len(self.get_lib_symbols()),
|
|
233
|
+
"symbol_instances_count": (
|
|
234
|
+
len(self.get_symbol_instances())
|
|
235
|
+
if isinstance(self.get_symbol_instances(), list)
|
|
236
|
+
else 1 if self.get_symbol_instances() else 0
|
|
237
|
+
),
|
|
238
|
+
"sheet_instances_count": len(self.get_sheet_instances()),
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
def validate_metadata(self) -> List[str]:
|
|
242
|
+
"""
|
|
243
|
+
Validate metadata consistency and completeness.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
List of validation warnings/issues
|
|
247
|
+
"""
|
|
248
|
+
issues = []
|
|
249
|
+
|
|
250
|
+
# Check required fields
|
|
251
|
+
if not self.get_version():
|
|
252
|
+
issues.append("Missing KiCAD version")
|
|
253
|
+
|
|
254
|
+
if not self.get_generator():
|
|
255
|
+
issues.append("Missing generator information")
|
|
256
|
+
|
|
257
|
+
# Check title block
|
|
258
|
+
title_block = self.get_title_block()
|
|
259
|
+
if not title_block.get("title"):
|
|
260
|
+
issues.append("Title block missing title")
|
|
261
|
+
|
|
262
|
+
# Check paper size
|
|
263
|
+
paper = self.get_paper_size()
|
|
264
|
+
valid_sizes = ["A4", "A3", "A2", "A1", "A0", "Letter", "Legal", "Tabloid"]
|
|
265
|
+
if paper and paper not in valid_sizes:
|
|
266
|
+
issues.append(f"Non-standard paper size: {paper}")
|
|
267
|
+
|
|
268
|
+
return issues
|