convoviz 0.2.2__py3-none-any.whl → 0.2.3__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.
convoviz/utils.py CHANGED
@@ -7,16 +7,54 @@ from pathlib import Path
7
7
  def sanitize(filename: str) -> str:
8
8
  """Sanitize a string to be safe for use as a filename.
9
9
 
10
- Replaces invalid characters with underscores.
10
+ Replaces invalid characters with underscores, handles reserved names,
11
+ and prevents path traversal characters.
11
12
 
12
13
  Args:
13
14
  filename: The string to sanitize
14
15
 
15
16
  Returns:
16
- A filename-safe string, or "untitled" if empty
17
+ A filename-safe string, or "untitled" if empty or invalid
17
18
  """
19
+ # Replace invalid characters
18
20
  pattern = re.compile(r'[<>:"/\\|?*\n\r\t\f\v]+')
19
21
  result = pattern.sub("_", filename.strip())
22
+
23
+ # Prevent path traversal
24
+ result = result.replace("..", "_")
25
+
26
+ # Windows reserved names
27
+ reserved = {
28
+ "CON",
29
+ "PRN",
30
+ "AUX",
31
+ "NUL",
32
+ "COM1",
33
+ "COM2",
34
+ "COM3",
35
+ "COM4",
36
+ "COM5",
37
+ "COM6",
38
+ "COM7",
39
+ "COM8",
40
+ "COM9",
41
+ "LPT1",
42
+ "LPT2",
43
+ "LPT3",
44
+ "LPT4",
45
+ "LPT5",
46
+ "LPT6",
47
+ "LPT7",
48
+ "LPT8",
49
+ "LPT9",
50
+ }
51
+ if result.upper() in reserved:
52
+ result = f"_{result}_"
53
+
54
+ # Enforce length limit (255 is common for many filesystems)
55
+ if len(result) > 255:
56
+ result = result[:255]
57
+
20
58
  return result or "untitled"
21
59
 
22
60
 
@@ -50,6 +88,18 @@ def root_dir() -> Path:
50
88
  return Path(__file__).parent
51
89
 
52
90
 
91
+ def get_asset_path(relative_path: str) -> Path:
92
+ """Get the absolute path to an asset file.
93
+
94
+ Args:
95
+ relative_path: Path relative to convoviz root (e.g., "assets/fonts/foo.ttf")
96
+
97
+ Returns:
98
+ Absolute Path to the asset
99
+ """
100
+ return root_dir() / relative_path
101
+
102
+
53
103
  def font_dir() -> Path:
54
104
  """Get the path to the fonts directory.
55
105
 
@@ -87,9 +137,9 @@ def default_font_path() -> Path:
87
137
  """Get the path to the default font.
88
138
 
89
139
  Returns:
90
- Path to RobotoSlab-Thin.ttf
140
+ Path to Kalam-Regular.ttf
91
141
  """
92
- return font_path("RobotoSlab-Thin")
142
+ return font_path("Kalam-Regular")
93
143
 
94
144
 
95
145
  def colormaps() -> list[str]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: convoviz
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Get analytics and visualizations on your ChatGPT data!
5
5
  Keywords: markdown,chatgpt,openai,visualization,analytics,json,export,data-analysis,obsidian
6
6
  Author: Mohamed Cheikh Sidiya
@@ -1,8 +1,8 @@
1
1
  convoviz/__init__.py,sha256=bQLCHO2U9EyMTGqNgsYiCtBQKTKNj4iIM3-TwIkrnRY,612
2
2
  convoviz/__main__.py,sha256=1qiGW13_SgL7wJi8iioIN-AAHGkNGnEl5q_RcPUrI0s,143
3
3
  convoviz/analysis/__init__.py,sha256=FxgH5JJpyypiLJpMQn_HlM51jnb8lQdP63_C_W3Dlx4,241
4
- convoviz/analysis/graphs.py,sha256=hMJmNX4ejFl_yl_kldA91EACpQjfkq-7sTiVnrBQx_w,2653
5
- convoviz/analysis/wordcloud.py,sha256=ZucezsDlgaOgYpjm_S7wKYmk7crD-MM83s4eVex-Bl8,4034
4
+ convoviz/analysis/graphs.py,sha256=zzM7Fc39e3DG0f1KRYH7Nkzu0ULBYehgOWyhsYGrgm0,12604
5
+ convoviz/analysis/wordcloud.py,sha256=UflTUUFZQmivNI1sn3OpaYV-BaR_BAbFwn89nUbkvIk,4666
6
6
  convoviz/assets/colormaps.txt,sha256=59TSGz428AxY14AEvymAH2IJ2RT9Mlp7Sy0N12NEdXQ,108
7
7
  convoviz/assets/fonts/AmaticSC-Regular.ttf,sha256=83clh7a3urnTLud0_yZofuIb6BdyC2LMI9jhE6G2LvU,142696
8
8
  convoviz/assets/fonts/ArchitectsDaughter-Regular.ttf,sha256=fnrj5_N_SlY2Lj3Ehqz5aKECPZVJlJAflgsOU94_qIM,37756
@@ -35,25 +35,27 @@ convoviz/assets/fonts/YsabeauOffice-Regular.ttf,sha256=RnW2erC5p6s2YxvWmwa019hYT
35
35
  convoviz/assets/fonts/YsabeauSC-Regular.ttf,sha256=G4lkq34KKqZOaoomtxFz_KlwVmxg56UbFXFnWgijkDM,116980
36
36
  convoviz/assets/fonts/YsabeauSC-Thin.ttf,sha256=hZGOZNTRrxbiUPE2VDeLbtnaRwkMOBaVQbq7Fwx-34c,116932
37
37
  convoviz/assets/fonts/Zeyada-Regular.ttf,sha256=fKhkrp9VHt_3Aw8JfkfkPeC2j3CilLWuPUudzBeawPQ,57468
38
- convoviz/cli.py,sha256=JqNk2rV1rjver8A7tWtjPeLaw1nYOze4fjghY6ohpCA,3371
39
- convoviz/config.py,sha256=QQ0KAyiacKLMCM1asFrNr6JQH1rVxyhGwNjSFqt_gSc,2445
38
+ convoviz/assets/stopwords.txt,sha256=7_ywpxsKYOj3U5CZTh9lP4GqbbkZLMabSOjKAXFk6Wc,539
39
+ convoviz/cli.py,sha256=8HNn-6kmDN8ECb0BspvjeGa_636SQPDffpM0yINgNII,3463
40
+ convoviz/config.py,sha256=CqF0nq0FfIom1rG0Y8JBVw7hvvrJEq4ATkKCoUrLSwk,2657
40
41
  convoviz/exceptions.py,sha256=bQpIKls48uOQpagEJAxpXf5LF7QoagRRfbD0MjWC7Ak,1476
41
- convoviz/interactive.py,sha256=XFSjBW-8EhEAC6UkGdcML10MIA5ZfToM24A98pWpryI,5500
42
+ convoviz/interactive.py,sha256=sMD2TVIwjRcZrOOzDPnlCx2rAxaEhanQlHyDSPwXoNw,5777
42
43
  convoviz/io/__init__.py,sha256=y70TYypJ36_kaEA04E2wa1EDaKQVjprKItoKR6MMs4M,471
43
- convoviz/io/loaders.py,sha256=Bwat6pmRExuGfBbpWoVqZXcGbWoTN9qaTEcJYtc505M,3653
44
- convoviz/io/writers.py,sha256=aLPmnLpbcho65Wy4ePzP6xoGWYVV0_owxbxv67ojBpA,2880
45
- convoviz/models/__init__.py,sha256=R78W7FvRLhPx36HJmIh1dPv2mNQGOF8X0fGMTpEagkA,628
46
- convoviz/models/collection.py,sha256=aUQq0dgFXCEEqPCBl4l9A99MZdWWunSO2b79-VyR2qY,4033
44
+ convoviz/io/assets.py,sha256=BykidWJG6OQAgbVfUByQ3RLTrldzpZ_NeM7HV3a5Tig,2333
45
+ convoviz/io/loaders.py,sha256=c7806lRHxluuifBhGqhloYtbI47WGn3PAVRwPYGq2u8,4765
46
+ convoviz/io/writers.py,sha256=KaLr0f2F2Pw5XOoQKMA75IeQYXUTT4WbS-HAqRxsp3c,3494
47
+ convoviz/models/__init__.py,sha256=6gAfrk6KJT2QxdvX_v15mUdfIqEw1xKxwQlKSfyA5eI,532
48
+ convoviz/models/collection.py,sha256=sTSRCR4jS94FE02gCmWfNFIrn8t-PCNmHI7wb4Juh4M,4094
47
49
  convoviz/models/conversation.py,sha256=G0wxrcIhY5JzWeIOkGtkELSzc7J32W2wxJVbNOord58,5145
48
- convoviz/models/message.py,sha256=Jc92vXowU2qzMaEH2Sa96nx65sGWsZpF5rj8BXwjK5E,2090
50
+ convoviz/models/message.py,sha256=MN5FrQ1kfmdAbcFUwfzg6FX5pKuZmhtNNrZksqMyuD0,3978
49
51
  convoviz/models/node.py,sha256=1vBAtKVscYsUBDnKAOyLxuZaK9KoVF1dFXiKXRHxUnY,1946
50
- convoviz/pipeline.py,sha256=KRSE-aVYppO-2YhvIzSQqcMfnJPxN-4ggnJ0h2xj2EA,4133
52
+ convoviz/pipeline.py,sha256=E2T82QjKEOmpy_kgY_MXd15MkXP8C2yE7MXG4jgDw1A,5018
51
53
  convoviz/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
54
  convoviz/renderers/__init__.py,sha256=IQgwD9NqtUgbS9zwyPBNZbBIZcFrbZ9C7WMAV-X3Xdg,261
53
- convoviz/renderers/markdown.py,sha256=4DLXPiZe_56cUNf1xGbcuw_qHq03CUMLCEdsIOhjq_Y,4836
55
+ convoviz/renderers/markdown.py,sha256=Gvc8x2OecmzcGMAab5i3f20VQHK_ITEepmJw_J-6zSo,6105
54
56
  convoviz/renderers/yaml.py,sha256=FqO2zToXp96gQRDrjALgchESWLg49LxuehXP59SEFeU,1522
55
- convoviz/utils.py,sha256=6LqoTEHgZg7ICkepxkNqr44LKgztiS37O6RkMsHHNbw,2363
56
- convoviz-0.2.2.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
57
- convoviz-0.2.2.dist-info/entry_points.txt,sha256=HYsmsw5vt36yYHB05uVU48AK2WLkcwshly7m7KKuZMY,54
58
- convoviz-0.2.2.dist-info/METADATA,sha256=32vJQF7cmiua-b9bqVIlLy-YeM-j7KIYg8uVUpNU9l8,4619
59
- convoviz-0.2.2.dist-info/RECORD,,
57
+ convoviz/utils.py,sha256=IQEKYHhWOnYxlr4GwAHoquG0BXTlVRkORL80oUSaIeQ,3417
58
+ convoviz-0.2.3.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
59
+ convoviz-0.2.3.dist-info/entry_points.txt,sha256=HYsmsw5vt36yYHB05uVU48AK2WLkcwshly7m7KKuZMY,54
60
+ convoviz-0.2.3.dist-info/METADATA,sha256=KPvRv4fDHpbiW7xM-_o5neTCWPEsI35E114Oulu1CRQ,4619
61
+ convoviz-0.2.3.dist-info/RECORD,,