unifi-network-maps 1.4.6__tar.gz → 1.4.8__tar.gz

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.
Files changed (130) hide show
  1. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/CHANGELOG.md +12 -1
  2. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/PKG-INFO +6 -3
  3. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/README.md +2 -0
  4. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/pyproject.toml +4 -3
  5. unifi_network_maps-1.4.8/src/unifi_network_maps/__init__.py +1 -0
  6. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/svg.py +32 -11
  7. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps.egg-info/PKG-INFO +6 -3
  8. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps.egg-info/requires.txt +1 -1
  9. unifi_network_maps-1.4.6/src/unifi_network_maps/__init__.py +0 -1
  10. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/CONTRIBUTING.md +0 -0
  11. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/LICENSE +0 -0
  12. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/LICENSES.md +0 -0
  13. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/MANIFEST.in +0 -0
  14. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/RELEASING.md +0 -0
  15. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/SECURITY.md +0 -0
  16. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/setup.cfg +0 -0
  17. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/__main__.py +0 -0
  18. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/adapters/__init__.py +0 -0
  19. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/adapters/config.py +0 -0
  20. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/adapters/unifi.py +0 -0
  21. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/__init__.py +0 -0
  22. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/__init__.py +0 -0
  23. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/access-point.svg +0 -0
  24. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE +0 -0
  25. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/block.svg +0 -0
  26. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/cache.svg +0 -0
  27. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/cardterminal.svg +0 -0
  28. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/cloud.svg +0 -0
  29. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/cronjob.svg +0 -0
  30. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/cube.svg +0 -0
  31. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/desktop.svg +0 -0
  32. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/diamond.svg +0 -0
  33. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/dns.svg +0 -0
  34. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/document.svg +0 -0
  35. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/firewall.svg +0 -0
  36. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/function-module.svg +0 -0
  37. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/image.svg +0 -0
  38. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/laptop.svg +0 -0
  39. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/loadbalancer.svg +0 -0
  40. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/lock.svg +0 -0
  41. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/mail.svg +0 -0
  42. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/mailmultiple.svg +0 -0
  43. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/mobiledevice.svg +0 -0
  44. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/office.svg +0 -0
  45. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/package-module.svg +0 -0
  46. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/paymentcard.svg +0 -0
  47. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/plane.svg +0 -0
  48. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/printer.svg +0 -0
  49. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/pyramid.svg +0 -0
  50. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/queue.svg +0 -0
  51. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/router.svg +0 -0
  52. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/server.svg +0 -0
  53. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/speech.svg +0 -0
  54. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/sphere.svg +0 -0
  55. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/storage.svg +0 -0
  56. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/switch-module.svg +0 -0
  57. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/tower.svg +0 -0
  58. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/truck-2.svg +0 -0
  59. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/truck.svg +0 -0
  60. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/user.svg +0 -0
  61. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/isometric/vm.svg +0 -0
  62. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/laptop.svg +0 -0
  63. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/router-network.svg +0 -0
  64. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/server-network.svg +0 -0
  65. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/icons/server.svg +0 -0
  66. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/themes/dark.yaml +0 -0
  67. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/assets/themes/default.yaml +0 -0
  68. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/cli/__init__.py +0 -0
  69. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/cli/__main__.py +0 -0
  70. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/cli/args.py +0 -0
  71. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/cli/main.py +0 -0
  72. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/cli/render.py +0 -0
  73. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/cli/runtime.py +0 -0
  74. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/io/__init__.py +0 -0
  75. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/io/debug.py +0 -0
  76. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/io/export.py +0 -0
  77. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/io/mkdocs_assets.py +0 -0
  78. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/io/mock_data.py +0 -0
  79. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/io/mock_generate.py +0 -0
  80. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/model/__init__.py +0 -0
  81. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/model/labels.py +0 -0
  82. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/model/lldp.py +0 -0
  83. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/model/mock.py +0 -0
  84. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/model/ports.py +0 -0
  85. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/model/topology.py +0 -0
  86. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/__init__.py +0 -0
  87. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/device_ports_md.py +0 -0
  88. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/legend.py +0 -0
  89. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/lldp_md.py +0 -0
  90. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/markdown_tables.py +0 -0
  91. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/mermaid.py +0 -0
  92. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/mermaid_theme.py +0 -0
  93. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/mkdocs.py +0 -0
  94. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/svg_theme.py +0 -0
  95. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/device_port_block.md.j2 +0 -0
  96. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/legend_compact.html.j2 +0 -0
  97. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/lldp_device_section.md.j2 +0 -0
  98. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/markdown_section.md.j2 +0 -0
  99. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mermaid_legend.mmd.j2 +0 -0
  100. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mkdocs_document.md.j2 +0 -0
  101. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mkdocs_dual_theme_style.html.j2 +0 -0
  102. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mkdocs_html_block.html.j2 +0 -0
  103. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mkdocs_legend.css.j2 +0 -0
  104. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mkdocs_legend.js.j2 +0 -0
  105. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templates/mkdocs_mermaid_block.md.j2 +0 -0
  106. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/templating.py +0 -0
  107. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps/render/theme.py +0 -0
  108. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps.egg-info/SOURCES.txt +0 -0
  109. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps.egg-info/dependency_links.txt +0 -0
  110. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps.egg-info/entry_points.txt +0 -0
  111. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/src/unifi_network_maps.egg-info/top_level.txt +0 -0
  112. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_cli.py +0 -0
  113. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_clients.py +0 -0
  114. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_config.py +0 -0
  115. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_contract_unifi.py +0 -0
  116. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_contract_unifi_live.py +0 -0
  117. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_debug.py +0 -0
  118. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_device_ports_md.py +0 -0
  119. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_export.py +0 -0
  120. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_groups.py +0 -0
  121. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_labels.py +0 -0
  122. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_lldp.py +0 -0
  123. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_lldp_md.py +0 -0
  124. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_mermaid.py +0 -0
  125. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_mock_generate.py +0 -0
  126. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_svg.py +0 -0
  127. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_svg_iso.py +0 -0
  128. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_theme.py +0 -0
  129. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_topology.py +0 -0
  130. {unifi_network_maps-1.4.6 → unifi_network_maps-1.4.8}/tests/test_unifi.py +0 -0
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.4.8] - 2026-01-15
9
+ ### Changed
10
+ - Declared support for Python 3.12+ (3.13 preferred) and added CI coverage for 3.12.
11
+
12
+ ## [1.4.7] - 2026-01-15
13
+ ### Changed
14
+ - Merged PR #8: https://github.com/merlijntishauser/unifi-network-maps/pull/8
15
+
8
16
  ## [1.4.6] - 2026-01-15
9
17
  ### Added
10
18
  - Home Assistant docs pointing to the standalone integration repo.
@@ -151,7 +159,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
151
159
  - Introduced SVG renderer and tree layout fixes.
152
160
  - Increased test coverage and added coverage tooling.
153
161
 
154
- [Unreleased]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.5...HEAD
162
+ [Unreleased]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.8...HEAD
163
+ [1.4.8]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.7...v1.4.8
164
+ [1.4.7]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.6...v1.4.7
165
+ [1.4.6]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.5...v1.4.6
155
166
  [1.4.5]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.4...v1.4.5
156
167
  [1.4.4]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.2...v1.4.4
157
168
  [1.4.2]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.1...v1.4.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unifi-network-maps
3
- Version: 1.4.6
3
+ Version: 1.4.8
4
4
  Summary: Dynamic UniFi -> network maps in mermaid or svg
5
5
  Author: Merlijn
6
6
  License-Expression: MIT
@@ -14,10 +14,11 @@ Classifier: Intended Audience :: System Administrators
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
17
18
  Classifier: Programming Language :: Python :: 3.13
18
19
  Classifier: Topic :: Documentation
19
20
  Classifier: Topic :: System :: Networking
20
- Requires-Python: >=3.13
21
+ Requires-Python: >=3.12
21
22
  Description-Content-Type: text/markdown
22
23
  License-File: LICENSE
23
24
  Requires-Dist: unifi-controller-api==0.3.2
@@ -25,7 +26,7 @@ Requires-Dist: python-dotenv==1.2.1
25
26
  Requires-Dist: PyYAML==6.0.3
26
27
  Requires-Dist: Jinja2==3.1.6
27
28
  Provides-Extra: dev
28
- Requires-Dist: Faker==40.1.0; extra == "dev"
29
+ Requires-Dist: Faker==40.1.2; extra == "dev"
29
30
  Requires-Dist: behave==1.3.3; extra == "dev"
30
31
  Requires-Dist: pre-commit==4.5.1; extra == "dev"
31
32
  Requires-Dist: pytest==9.0.2; extra == "dev"
@@ -44,6 +45,8 @@ Dynamic: license-file
44
45
  Dynamic UniFi network maps generated from LLDP topology. Output can be a range of options including Markdown,
45
46
  Mermaid, SVG (including an Isometric view), and MkDocs.
46
47
 
48
+ Python 3.12+ is supported (3.13 preferred).
49
+
47
50
  ## Installation
48
51
 
49
52
  PyPI:
@@ -8,6 +8,8 @@
8
8
  Dynamic UniFi network maps generated from LLDP topology. Output can be a range of options including Markdown,
9
9
  Mermaid, SVG (including an Isometric view), and MkDocs.
10
10
 
11
+ Python 3.12+ is supported (3.13 preferred).
12
+
11
13
  ## Installation
12
14
 
13
15
  PyPI:
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "unifi-network-maps"
7
- version = "1.4.6"
7
+ version = "1.4.8"
8
8
  description = "Dynamic UniFi -> network maps in mermaid or svg"
9
9
  readme = "README.md"
10
- requires-python = ">=3.13"
10
+ requires-python = ">=3.12"
11
11
  license = "MIT"
12
12
  license-files = ["LICENSE"]
13
13
  authors = [{ name = "Merlijn" }]
@@ -18,6 +18,7 @@ classifiers = [
18
18
  "Operating System :: OS Independent",
19
19
  "Programming Language :: Python :: 3",
20
20
  "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.12",
21
22
  "Programming Language :: Python :: 3.13",
22
23
  "Topic :: Documentation",
23
24
  "Topic :: System :: Networking",
@@ -37,7 +38,7 @@ Changelog = "https://github.com/merlijntishauser/unifi-network-maps/blob/main/CH
37
38
 
38
39
  [project.optional-dependencies]
39
40
  dev = [
40
- "Faker==40.1.0",
41
+ "Faker==40.1.2",
41
42
  "behave==1.3.3",
42
43
  "pre-commit==4.5.1",
43
44
  "pytest==9.0.2",
@@ -0,0 +1 @@
1
+ __version__ = "1.4.8"
@@ -609,9 +609,13 @@ def _render_svg_nodes(
609
609
  node_type = node_types.get(name, "other")
610
610
  fill, stroke = _TYPE_COLORS.get(node_type, _TYPE_COLORS["other"])
611
611
  fill = f"url(#node-{node_type})"
612
- extra_attrs = _svg_node_attrs(node_data, name)
613
- if extra_attrs:
614
- lines.append(f"<g{extra_attrs}>")
612
+ group_attrs = _svg_node_group_attrs(node_data, name, node_type)
613
+ lines.append(f"<g{group_attrs}>")
614
+ lines.append(f"<title>{_escape_text(name)}</title>")
615
+ lines.append(
616
+ f'<rect x="{x}" y="{y}" width="{options.node_width}" height="{options.node_height}" '
617
+ 'fill="transparent" pointer-events="all" class="node-hitbox"/>'
618
+ )
615
619
  lines.append(
616
620
  f'<rect x="{x}" y="{y}" width="{options.node_width}" height="{options.node_height}" '
617
621
  f'rx="6" ry="6" fill="{fill}" stroke="{stroke}" stroke-width="1"/>'
@@ -649,16 +653,25 @@ def _render_svg_nodes(
649
653
  lines.append(
650
654
  f'<text x="{text_x}" y="{text_y}" fill="#1f1f1f" text-anchor="start">{safe_name}</text>'
651
655
  )
652
- if extra_attrs:
653
- lines.append("</g>")
656
+ lines.append("</g>")
654
657
 
655
658
 
656
- def _svg_node_attrs(node_data: dict[str, dict[str, str]] | None, name: str) -> str:
657
- if not node_data:
658
- return ""
659
- attrs = node_data.get(name)
660
- if not attrs:
661
- return ""
659
+ def _svg_node_group_attrs(
660
+ node_data: dict[str, dict[str, str]] | None,
661
+ name: str,
662
+ node_type: str,
663
+ ) -> str:
664
+ attrs: dict[str, str] = {
665
+ "class": "unm-node",
666
+ "data-node-id": name,
667
+ "data-node-type": node_type,
668
+ }
669
+ if node_data and (extra := node_data.get(name)):
670
+ for key, value in extra.items():
671
+ if key == "class":
672
+ attrs["class"] = f"{attrs['class']} {value}".strip()
673
+ else:
674
+ attrs[key] = value
662
675
  rendered = [f' {key}="{_escape_attr(value, quote=True)}"' for key, value in attrs.items()]
663
676
  return "".join(rendered)
664
677
 
@@ -1050,7 +1063,14 @@ def _render_iso_node(
1050
1063
  node_depth = 0.0
1051
1064
  tile_w = layout.tile_width
1052
1065
  tile_h = layout.tile_height
1066
+ group_attrs = _svg_node_group_attrs(None, name, node_type)
1067
+ lines.append(f"<g{group_attrs}>")
1068
+ lines.append(f"<title>{_escape_text(name)}</title>")
1053
1069
  top, left, right = _iso_node_polygons(x, y, tile_w, tile_h, node_depth)
1070
+ lines.append(
1071
+ f'<polygon points="{_points_to_svg(top)}" fill="transparent" '
1072
+ 'pointer-events="all" class="node-hitbox"/>'
1073
+ )
1054
1074
  left_fill = "#d0d0d0" if node_type == "other" else "#dcdcdc"
1055
1075
  right_fill = "#c2c2c2" if node_type == "other" else "#c8c8c8"
1056
1076
  _iso_render_faces(
@@ -1116,6 +1136,7 @@ def _render_iso_node(
1116
1136
  f'<text x="{name_x}" y="{name_y}" text-anchor="middle" fill="#1f1f1f" '
1117
1137
  f'font-size="{name_font_size}" transform="{name_transform}">{_escape_text(name)}</text>'
1118
1138
  )
1139
+ lines.append("</g>")
1119
1140
 
1120
1141
 
1121
1142
  def _render_iso_nodes(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unifi-network-maps
3
- Version: 1.4.6
3
+ Version: 1.4.8
4
4
  Summary: Dynamic UniFi -> network maps in mermaid or svg
5
5
  Author: Merlijn
6
6
  License-Expression: MIT
@@ -14,10 +14,11 @@ Classifier: Intended Audience :: System Administrators
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
17
18
  Classifier: Programming Language :: Python :: 3.13
18
19
  Classifier: Topic :: Documentation
19
20
  Classifier: Topic :: System :: Networking
20
- Requires-Python: >=3.13
21
+ Requires-Python: >=3.12
21
22
  Description-Content-Type: text/markdown
22
23
  License-File: LICENSE
23
24
  Requires-Dist: unifi-controller-api==0.3.2
@@ -25,7 +26,7 @@ Requires-Dist: python-dotenv==1.2.1
25
26
  Requires-Dist: PyYAML==6.0.3
26
27
  Requires-Dist: Jinja2==3.1.6
27
28
  Provides-Extra: dev
28
- Requires-Dist: Faker==40.1.0; extra == "dev"
29
+ Requires-Dist: Faker==40.1.2; extra == "dev"
29
30
  Requires-Dist: behave==1.3.3; extra == "dev"
30
31
  Requires-Dist: pre-commit==4.5.1; extra == "dev"
31
32
  Requires-Dist: pytest==9.0.2; extra == "dev"
@@ -44,6 +45,8 @@ Dynamic: license-file
44
45
  Dynamic UniFi network maps generated from LLDP topology. Output can be a range of options including Markdown,
45
46
  Mermaid, SVG (including an Isometric view), and MkDocs.
46
47
 
48
+ Python 3.12+ is supported (3.13 preferred).
49
+
47
50
  ## Installation
48
51
 
49
52
  PyPI:
@@ -4,7 +4,7 @@ PyYAML==6.0.3
4
4
  Jinja2==3.1.6
5
5
 
6
6
  [dev]
7
- Faker==40.1.0
7
+ Faker==40.1.2
8
8
  behave==1.3.3
9
9
  pre-commit==4.5.1
10
10
  pytest==9.0.2
@@ -1 +0,0 @@
1
- __version__ = "1.4.6"