convoviz 0.1.7__tar.gz → 0.2.0__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.
- {convoviz-0.1.7 → convoviz-0.2.0}/LICENSE +21 -21
- {convoviz-0.1.7 → convoviz-0.2.0}/PKG-INFO +61 -42
- {convoviz-0.1.7 → convoviz-0.2.0}/README.md +88 -88
- convoviz-0.2.0/convoviz/__init__.py +25 -0
- convoviz-0.2.0/convoviz/__main__.py +6 -0
- convoviz-0.2.0/convoviz/analysis/__init__.py +9 -0
- convoviz-0.2.0/convoviz/analysis/graphs.py +98 -0
- convoviz-0.2.0/convoviz/analysis/wordcloud.py +142 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/colormaps.txt +15 -16
- convoviz-0.2.0/convoviz/cli.py +106 -0
- convoviz-0.2.0/convoviz/config.py +88 -0
- convoviz-0.2.0/convoviz/exceptions.py +47 -0
- convoviz-0.2.0/convoviz/interactive.py +178 -0
- convoviz-0.2.0/convoviz/io/__init__.py +21 -0
- convoviz-0.2.0/convoviz/io/loaders.py +135 -0
- convoviz-0.2.0/convoviz/io/writers.py +96 -0
- convoviz-0.2.0/convoviz/models/__init__.py +28 -0
- convoviz-0.2.0/convoviz/models/collection.py +107 -0
- convoviz-0.2.0/convoviz/models/conversation.py +149 -0
- convoviz-0.2.0/convoviz/models/message.py +77 -0
- convoviz-0.2.0/convoviz/models/node.py +66 -0
- convoviz-0.2.0/convoviz/pipeline.py +120 -0
- convoviz-0.2.0/convoviz/renderers/__init__.py +10 -0
- convoviz-0.2.0/convoviz/renderers/markdown.py +182 -0
- convoviz-0.2.0/convoviz/renderers/yaml.py +42 -0
- convoviz-0.2.0/convoviz/utils.py +105 -0
- convoviz-0.2.0/pyproject.toml +104 -0
- convoviz-0.1.7/convoviz/__init__.py +0 -5
- convoviz-0.1.7/convoviz/__main__.py +0 -5
- convoviz-0.1.7/convoviz/cli.py +0 -99
- convoviz-0.1.7/convoviz/configuration.py +0 -125
- convoviz-0.1.7/convoviz/data_analysis.py +0 -119
- convoviz-0.1.7/convoviz/long_runs.py +0 -93
- convoviz-0.1.7/convoviz/models/__init__.py +0 -8
- convoviz-0.1.7/convoviz/models/_conversation.py +0 -289
- convoviz-0.1.7/convoviz/models/_conversation_set.py +0 -191
- convoviz-0.1.7/convoviz/models/_message.py +0 -89
- convoviz-0.1.7/convoviz/models/_node.py +0 -74
- convoviz-0.1.7/convoviz/utils.py +0 -274
- convoviz-0.1.7/pyproject.toml +0 -60
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/AmaticSC-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/ArchitectsDaughter-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/BebasNeue-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Borel-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Courgette-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/CroissantOne-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Handjet-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/IndieFlower-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Kalam-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Lobster-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/MartianMono-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/MartianMono-Thin.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Montserrat-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Mooli-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Pacifico-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/PlayfairDisplay-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Raleway-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/RobotoMono-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/RobotoMono-Thin.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/RobotoSlab-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/RobotoSlab-Thin.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Ruwudu-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Sacramento-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/SedgwickAveDisplay-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/ShadowsIntoLight-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/TitilliumWeb-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Yellowtail-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/YsabeauOffice-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/YsabeauSC-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/YsabeauSC-Thin.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/assets/fonts/Zeyada-Regular.ttf +0 -0
- {convoviz-0.1.7 → convoviz-0.2.0}/convoviz/py.typed +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Mohamed Cheikh Sidiya
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Mohamed Cheikh Sidiya
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,26 +1,46 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: convoviz
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Get analytics and visualizations on your ChatGPT data
|
|
5
|
-
|
|
6
|
-
License: MIT
|
|
7
|
-
Keywords: markdown,advanced-data-analysis,json,zip,openai,chatgpt,bookmarklet,obsidian-md,code-interpreter
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Get analytics and visualizations on your ChatGPT data!
|
|
5
|
+
Keywords: markdown,chatgpt,openai,visualization,analytics,json,export,data-analysis,obsidian
|
|
8
6
|
Author: Mohamed Cheikh Sidiya
|
|
9
|
-
Author-email: mohamedcheikhsidiya77@gmail.com
|
|
10
|
-
|
|
7
|
+
Author-email: Mohamed Cheikh Sidiya <mohamedcheikhsidiya77@gmail.com>
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2023 Mohamed Cheikh Sidiya
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
11
29
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
30
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
16
31
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
-
Requires-Dist: matplotlib
|
|
18
|
-
Requires-Dist: nltk
|
|
19
|
-
Requires-Dist: orjson
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
32
|
+
Requires-Dist: matplotlib>=3.9.4
|
|
33
|
+
Requires-Dist: nltk>=3.9.2
|
|
34
|
+
Requires-Dist: orjson>=3.11.5
|
|
35
|
+
Requires-Dist: pillow>=11.3.0
|
|
36
|
+
Requires-Dist: pydantic>=2.12.5
|
|
37
|
+
Requires-Dist: pydantic-settings>=2.7.0
|
|
38
|
+
Requires-Dist: questionary>=2.1.1
|
|
39
|
+
Requires-Dist: rich>=14.2.0
|
|
40
|
+
Requires-Dist: tqdm>=4.67.1
|
|
41
|
+
Requires-Dist: typer>=0.21.0
|
|
42
|
+
Requires-Dist: wordcloud>=1.9.5
|
|
43
|
+
Requires-Python: >=3.12
|
|
24
44
|
Project-URL: Repository, https://github.com/mohamed-chs/chatgpt-history-export-to-md
|
|
25
45
|
Description-Content-Type: text/markdown
|
|
26
46
|
|
|
@@ -51,41 +71,49 @@ See examples [here](demo).
|
|
|
51
71
|
|
|
52
72
|
### 2. Install the tool 🛠
|
|
53
73
|
|
|
54
|
-
|
|
74
|
+
You can install the tool using `pip` (or `uv`):
|
|
55
75
|
|
|
56
76
|
```bash
|
|
57
77
|
pip install convoviz
|
|
78
|
+
# or
|
|
79
|
+
uv pip install convoviz
|
|
58
80
|
```
|
|
59
81
|
|
|
60
|
-
to install the package.
|
|
61
|
-
|
|
62
82
|
### 3. Run the Script 🏃♂️
|
|
63
83
|
|
|
64
|
-
|
|
84
|
+
You have two options: **Interactive Mode** or **Command Line Arguments**.
|
|
85
|
+
|
|
86
|
+
#### Interactive Mode
|
|
87
|
+
|
|
88
|
+
Simply run the command and follow the prompts:
|
|
65
89
|
|
|
66
90
|
```bash
|
|
67
|
-
|
|
91
|
+
convoviz
|
|
68
92
|
```
|
|
69
93
|
|
|
70
|
-
|
|
94
|
+
#### Command Line Arguments
|
|
71
95
|
|
|
72
|
-
|
|
96
|
+
You can provide arguments directly to skip the prompts:
|
|
73
97
|
|
|
74
|
-
|
|
98
|
+
```bash
|
|
99
|
+
convoviz --zip path/to/your/export.zip --output path/to/output/folder
|
|
100
|
+
```
|
|
75
101
|
|
|
76
|
-
|
|
102
|
+
For more options, run:
|
|
77
103
|
|
|
78
|
-
|
|
104
|
+
```bash
|
|
105
|
+
convoviz --help
|
|
106
|
+
```
|
|
79
107
|
|
|
80
|
-
###
|
|
108
|
+
### 4. Check the Output 🎉
|
|
81
109
|
|
|
82
|
-
|
|
110
|
+
And that's it! After running the script, head over to the output folder to see your nice word clouds, graphs, and neatly formatted Markdown files. Enjoy !
|
|
83
111
|
|
|
84
112
|
## Share Your Feedback! 💌
|
|
85
113
|
|
|
86
114
|
I hope you find this tool useful. I'm continuously looking to improve on this, but I need your help for that.
|
|
87
115
|
|
|
88
|
-
Whether you're a tech wizard or you're new to all this
|
|
116
|
+
Whether you're a tech wizard or you're new to all this, I'd love to hear about your journey with the tool. Found a quirk? Have a suggestion? Or just want to send some good vibes? I'm all ears!
|
|
89
117
|
|
|
90
118
|
**Here's how you can share your thoughts:**
|
|
91
119
|
|
|
@@ -99,17 +127,8 @@ Thank you for being awesome! 🌟
|
|
|
99
127
|
|
|
100
128
|
## Notes
|
|
101
129
|
|
|
102
|
-
This project requires Python 3.
|
|
130
|
+
This project requires Python 3.9 or higher.
|
|
103
131
|
|
|
104
132
|
This is just a small thing I coded to help me see my convos in beautiful markdown, in [Obsidian](https://obsidian.md/) (my go-to note-taking app).
|
|
105
133
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
It was also a great opportunity to learn more about Python and type annotations. I had mypy, pyright, and ruff all on strict mode, 'twas fun.
|
|
109
|
-
|
|
110
|
-
It also works as package, so you can **import** it in your own projects, and use the models and functions as you wish. I need to add more documentation for that tho. Feel free to reach out if you need help.
|
|
111
|
-
|
|
112
|
-
I'm working on automating it to add new conversations and updating old ones. Had some luck with a JavaScript bookmarklet, still ironing it out tho. Shouldn't take long.
|
|
113
|
-
|
|
114
|
-
> for an older version with zero dependencies, see https://github.com/mohamed-chs/chatgpt-history-export-to-md/tree/fe13a701fe8653c9f946b1e12979ce3bfe7104b8.
|
|
115
|
-
|
|
134
|
+
It also works as package, so you can **import** it in your own projects, and use the models and functions as you wish.
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
# Convoviz 📊: Visualize your entire ChatGPT data !
|
|
2
|
-
|
|
3
|
-
Convert your ChatGPT history into well-formatted Markdown files. Additionally, visualize your data with word clouds 🔡☁️, view your prompt history graphs 📈, and access all your custom instructions 🤖 in a single location.
|
|
4
|
-
|
|
5
|
-

|
|
6
|
-

|
|
7
|
-
|
|
8
|
-
## Features
|
|
9
|
-
|
|
10
|
-
- **YAML Headers**: Optional and included by default.
|
|
11
|
-
- **Track message versions**: prompt/response edits included.
|
|
12
|
-
- **Code Interpreter**: Environment code blocks and execution results.
|
|
13
|
-
- **Data Visualizations**: Word clouds, graphs, and more.
|
|
14
|
-
- **Custom Instructions**: All your custom instructions in one JSON file.
|
|
15
|
-
|
|
16
|
-
See examples [here](demo).
|
|
17
|
-
|
|
18
|
-
## How to Use 📖
|
|
19
|
-
|
|
20
|
-
### 1. Export Your ChatGPT Data 🗂
|
|
21
|
-
|
|
22
|
-
- Sign in at [chat.openai.com](https://chat.openai.com).
|
|
23
|
-
- Navigate: Profile Name (bottom left) -> **Settings** -> **Data controls** -> **Export** -> **Confirm export**.
|
|
24
|
-
- Await email from OpenAI and download the `.zip` file.
|
|
25
|
-
|
|
26
|
-
### 2. Install the tool 🛠
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
pip install convoviz
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
### 3. Run the Script 🏃♂️
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
# Convoviz 📊: Visualize your entire ChatGPT data !
|
|
2
|
+
|
|
3
|
+
Convert your ChatGPT history into well-formatted Markdown files. Additionally, visualize your data with word clouds 🔡☁️, view your prompt history graphs 📈, and access all your custom instructions 🤖 in a single location.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **YAML Headers**: Optional and included by default.
|
|
11
|
+
- **Track message versions**: prompt/response edits included.
|
|
12
|
+
- **Code Interpreter**: Environment code blocks and execution results.
|
|
13
|
+
- **Data Visualizations**: Word clouds, graphs, and more.
|
|
14
|
+
- **Custom Instructions**: All your custom instructions in one JSON file.
|
|
15
|
+
|
|
16
|
+
See examples [here](demo).
|
|
17
|
+
|
|
18
|
+
## How to Use 📖
|
|
19
|
+
|
|
20
|
+
### 1. Export Your ChatGPT Data 🗂
|
|
21
|
+
|
|
22
|
+
- Sign in at [chat.openai.com](https://chat.openai.com).
|
|
23
|
+
- Navigate: Profile Name (bottom left) -> **Settings** -> **Data controls** -> **Export** -> **Confirm export**.
|
|
24
|
+
- Await email from OpenAI and download the `.zip` file.
|
|
25
|
+
|
|
26
|
+
### 2. Install the tool 🛠
|
|
27
|
+
|
|
28
|
+
You can install the tool using `pip` (or `uv`):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install convoviz
|
|
32
|
+
# or
|
|
33
|
+
uv pip install convoviz
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Run the Script 🏃♂️
|
|
37
|
+
|
|
38
|
+
You have two options: **Interactive Mode** or **Command Line Arguments**.
|
|
39
|
+
|
|
40
|
+
#### Interactive Mode
|
|
41
|
+
|
|
42
|
+
Simply run the command and follow the prompts:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
convoviz
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Command Line Arguments
|
|
49
|
+
|
|
50
|
+
You can provide arguments directly to skip the prompts:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
convoviz --zip path/to/your/export.zip --output path/to/output/folder
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For more options, run:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
convoviz --help
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 4. Check the Output 🎉
|
|
63
|
+
|
|
64
|
+
And that's it! After running the script, head over to the output folder to see your nice word clouds, graphs, and neatly formatted Markdown files. Enjoy !
|
|
65
|
+
|
|
66
|
+
## Share Your Feedback! 💌
|
|
67
|
+
|
|
68
|
+
I hope you find this tool useful. I'm continuously looking to improve on this, but I need your help for that.
|
|
69
|
+
|
|
70
|
+
Whether you're a tech wizard or you're new to all this, I'd love to hear about your journey with the tool. Found a quirk? Have a suggestion? Or just want to send some good vibes? I'm all ears!
|
|
71
|
+
|
|
72
|
+
**Here's how you can share your thoughts:**
|
|
73
|
+
|
|
74
|
+
1. **GitHub Issues**: For more specific feedback or if you've stumbled upon a bug, please open an [issue](https://github.com/mohamed-chs/chatgpt-history-export-to-md/issues). This helps me track and address them effectively.
|
|
75
|
+
|
|
76
|
+
2. **GitHub Discussions**: If you just want to share your general experience, have a suggestion, or maybe a cool idea for a new feature, jump into the [discussions](https://github.com/mohamed-chs/chatgpt-history-export-to-md/discussions) page. It's a more casual space where we can chat.
|
|
77
|
+
|
|
78
|
+
And if you've had a great experience, consider giving the project a star ⭐. It keeps me motivated and helps others discover it!
|
|
79
|
+
|
|
80
|
+
Thank you for being awesome! 🌟
|
|
81
|
+
|
|
82
|
+
## Notes
|
|
83
|
+
|
|
84
|
+
This project requires Python 3.9 or higher.
|
|
85
|
+
|
|
86
|
+
This is just a small thing I coded to help me see my convos in beautiful markdown, in [Obsidian](https://obsidian.md/) (my go-to note-taking app).
|
|
87
|
+
|
|
88
|
+
It also works as package, so you can **import** it in your own projects, and use the models and functions as you wish.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Convoviz - ChatGPT data visualization and export tool."""
|
|
2
|
+
|
|
3
|
+
from convoviz import analysis, config, io, models, renderers, utils
|
|
4
|
+
from convoviz.config import ConvovizConfig, get_default_config
|
|
5
|
+
from convoviz.models import Conversation, ConversationCollection, Message, Node
|
|
6
|
+
from convoviz.pipeline import run_pipeline
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
# Submodules
|
|
10
|
+
"analysis",
|
|
11
|
+
"config",
|
|
12
|
+
"io",
|
|
13
|
+
"models",
|
|
14
|
+
"renderers",
|
|
15
|
+
"utils",
|
|
16
|
+
# Main classes
|
|
17
|
+
"Conversation",
|
|
18
|
+
"ConversationCollection",
|
|
19
|
+
"ConvovizConfig",
|
|
20
|
+
"Message",
|
|
21
|
+
"Node",
|
|
22
|
+
# Functions
|
|
23
|
+
"get_default_config",
|
|
24
|
+
"run_pipeline",
|
|
25
|
+
]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Graph generation for conversation analytics."""
|
|
2
|
+
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from datetime import UTC, datetime
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from matplotlib.figure import Figure
|
|
8
|
+
from tqdm import tqdm
|
|
9
|
+
|
|
10
|
+
from convoviz.config import GraphConfig
|
|
11
|
+
from convoviz.models import ConversationCollection
|
|
12
|
+
|
|
13
|
+
WEEKDAYS = [
|
|
14
|
+
"Monday",
|
|
15
|
+
"Tuesday",
|
|
16
|
+
"Wednesday",
|
|
17
|
+
"Thursday",
|
|
18
|
+
"Friday",
|
|
19
|
+
"Saturday",
|
|
20
|
+
"Sunday",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def generate_week_barplot(
|
|
25
|
+
timestamps: list[float],
|
|
26
|
+
title: str,
|
|
27
|
+
_config: GraphConfig | None = None,
|
|
28
|
+
) -> Figure:
|
|
29
|
+
"""Create a bar graph showing message distribution across weekdays.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
timestamps: List of Unix timestamps
|
|
33
|
+
title: Title for the graph
|
|
34
|
+
config: Optional graph configuration (for future extensions)
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Matplotlib Figure object
|
|
38
|
+
"""
|
|
39
|
+
dates = [datetime.fromtimestamp(ts, UTC) for ts in timestamps]
|
|
40
|
+
|
|
41
|
+
weekday_counts: defaultdict[str, int] = defaultdict(int)
|
|
42
|
+
for date in dates:
|
|
43
|
+
weekday_counts[WEEKDAYS[date.weekday()]] += 1
|
|
44
|
+
|
|
45
|
+
x = WEEKDAYS
|
|
46
|
+
y = [weekday_counts[day] for day in WEEKDAYS]
|
|
47
|
+
|
|
48
|
+
fig = Figure(dpi=300)
|
|
49
|
+
ax = fig.add_subplot()
|
|
50
|
+
|
|
51
|
+
ax.bar(x, y)
|
|
52
|
+
ax.set_xlabel("Weekday")
|
|
53
|
+
ax.set_ylabel("Prompt Count")
|
|
54
|
+
ax.set_title(title)
|
|
55
|
+
ax.set_xticks(range(len(x)))
|
|
56
|
+
ax.set_xticklabels(x, rotation=45)
|
|
57
|
+
fig.tight_layout()
|
|
58
|
+
|
|
59
|
+
return fig
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def generate_week_barplots(
|
|
63
|
+
collection: ConversationCollection,
|
|
64
|
+
output_dir: Path,
|
|
65
|
+
config: GraphConfig | None = None,
|
|
66
|
+
*,
|
|
67
|
+
progress_bar: bool = False,
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Generate weekly bar plots for monthly and yearly groupings.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
collection: Collection of conversations
|
|
73
|
+
output_dir: Directory to save the graphs
|
|
74
|
+
config: Optional graph configuration
|
|
75
|
+
progress_bar: Whether to show progress bars
|
|
76
|
+
"""
|
|
77
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
78
|
+
|
|
79
|
+
month_groups = collection.group_by_month()
|
|
80
|
+
year_groups = collection.group_by_year()
|
|
81
|
+
|
|
82
|
+
for month, group in tqdm(
|
|
83
|
+
month_groups.items(),
|
|
84
|
+
desc="Creating monthly weekwise graphs 📈",
|
|
85
|
+
disable=not progress_bar,
|
|
86
|
+
):
|
|
87
|
+
title = month.strftime("%B '%y")
|
|
88
|
+
fig = generate_week_barplot(group.timestamps("user"), title, config)
|
|
89
|
+
fig.savefig(output_dir / f"{month.strftime('%Y %B')}.png")
|
|
90
|
+
|
|
91
|
+
for year, group in tqdm(
|
|
92
|
+
year_groups.items(),
|
|
93
|
+
desc="Creating yearly weekwise graphs 📈",
|
|
94
|
+
disable=not progress_bar,
|
|
95
|
+
):
|
|
96
|
+
title = year.strftime("%Y")
|
|
97
|
+
fig = generate_week_barplot(group.timestamps("user"), title, config)
|
|
98
|
+
fig.savefig(output_dir / f"{year.strftime('%Y')}.png")
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Word cloud generation for conversation text."""
|
|
2
|
+
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from nltk import download as nltk_download
|
|
7
|
+
from nltk.corpus import stopwords as nltk_stopwords
|
|
8
|
+
from nltk.data import find as nltk_find
|
|
9
|
+
from PIL.Image import Image
|
|
10
|
+
from tqdm import tqdm
|
|
11
|
+
from wordcloud import WordCloud
|
|
12
|
+
|
|
13
|
+
from convoviz.config import WordCloudConfig
|
|
14
|
+
from convoviz.models import ConversationCollection
|
|
15
|
+
|
|
16
|
+
# Languages for stopwords
|
|
17
|
+
STOPWORD_LANGUAGES = [
|
|
18
|
+
"arabic",
|
|
19
|
+
"english",
|
|
20
|
+
"french",
|
|
21
|
+
"german",
|
|
22
|
+
"spanish",
|
|
23
|
+
"portuguese",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@lru_cache(maxsize=1)
|
|
28
|
+
def load_nltk_stopwords() -> frozenset[str]:
|
|
29
|
+
"""Load and cache NLTK stopwords.
|
|
30
|
+
|
|
31
|
+
Downloads stopwords if not already present.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Frozen set of stopwords from multiple languages
|
|
35
|
+
"""
|
|
36
|
+
try:
|
|
37
|
+
nltk_find("corpora/stopwords")
|
|
38
|
+
except LookupError:
|
|
39
|
+
nltk_download("stopwords", quiet=True)
|
|
40
|
+
|
|
41
|
+
words: set[str] = set()
|
|
42
|
+
for lang in STOPWORD_LANGUAGES:
|
|
43
|
+
words.update(nltk_stopwords.words(fileids=lang))
|
|
44
|
+
|
|
45
|
+
return frozenset(words)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def parse_custom_stopwords(stopwords_str: str) -> set[str]:
|
|
49
|
+
"""Parse a comma-separated string of custom stopwords.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
stopwords_str: Comma-separated stopwords
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Set of lowercase, stripped stopwords
|
|
56
|
+
"""
|
|
57
|
+
if not stopwords_str:
|
|
58
|
+
return set()
|
|
59
|
+
|
|
60
|
+
return {word.strip().lower() for word in stopwords_str.split(",") if word.strip()}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def generate_wordcloud(text: str, config: WordCloudConfig) -> Image:
|
|
64
|
+
"""Generate a word cloud from text.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
text: The text to create a word cloud from
|
|
68
|
+
config: Word cloud configuration
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
PIL Image of the word cloud
|
|
72
|
+
"""
|
|
73
|
+
# Combine NLTK and custom stopwords
|
|
74
|
+
stopwords = set(load_nltk_stopwords())
|
|
75
|
+
stopwords.update(parse_custom_stopwords(config.custom_stopwords))
|
|
76
|
+
|
|
77
|
+
wc = WordCloud(
|
|
78
|
+
font_path=str(config.font_path) if config.font_path else None,
|
|
79
|
+
width=config.width,
|
|
80
|
+
height=config.height,
|
|
81
|
+
stopwords=stopwords,
|
|
82
|
+
background_color=config.background_color,
|
|
83
|
+
mode=config.mode,
|
|
84
|
+
colormap=config.colormap,
|
|
85
|
+
include_numbers=config.include_numbers,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
wc.generate(text)
|
|
89
|
+
result: Image = wc.to_image()
|
|
90
|
+
return result
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def generate_wordclouds(
|
|
94
|
+
collection: ConversationCollection,
|
|
95
|
+
output_dir: Path,
|
|
96
|
+
config: WordCloudConfig,
|
|
97
|
+
*,
|
|
98
|
+
progress_bar: bool = False,
|
|
99
|
+
) -> None:
|
|
100
|
+
"""Generate word clouds for weekly, monthly, and yearly groupings.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
collection: Collection of conversations
|
|
104
|
+
output_dir: Directory to save the word clouds
|
|
105
|
+
config: Word cloud configuration
|
|
106
|
+
progress_bar: Whether to show progress bars
|
|
107
|
+
"""
|
|
108
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
109
|
+
|
|
110
|
+
week_groups = collection.group_by_week()
|
|
111
|
+
month_groups = collection.group_by_month()
|
|
112
|
+
year_groups = collection.group_by_year()
|
|
113
|
+
|
|
114
|
+
for week, group in tqdm(
|
|
115
|
+
week_groups.items(),
|
|
116
|
+
desc="Creating weekly wordclouds 🔡☁️",
|
|
117
|
+
disable=not progress_bar,
|
|
118
|
+
):
|
|
119
|
+
text = group.plaintext("user", "assistant")
|
|
120
|
+
if text.strip():
|
|
121
|
+
img = generate_wordcloud(text, config)
|
|
122
|
+
img.save(output_dir / f"{week.strftime('%Y week %W')}.png", optimize=True)
|
|
123
|
+
|
|
124
|
+
for month, group in tqdm(
|
|
125
|
+
month_groups.items(),
|
|
126
|
+
desc="Creating monthly wordclouds 🔡☁️",
|
|
127
|
+
disable=not progress_bar,
|
|
128
|
+
):
|
|
129
|
+
text = group.plaintext("user", "assistant")
|
|
130
|
+
if text.strip():
|
|
131
|
+
img = generate_wordcloud(text, config)
|
|
132
|
+
img.save(output_dir / f"{month.strftime('%Y %B')}.png", optimize=True)
|
|
133
|
+
|
|
134
|
+
for year, group in tqdm(
|
|
135
|
+
year_groups.items(),
|
|
136
|
+
desc="Creating yearly wordclouds 🔡☁️",
|
|
137
|
+
disable=not progress_bar,
|
|
138
|
+
):
|
|
139
|
+
text = group.plaintext("user", "assistant")
|
|
140
|
+
if text.strip():
|
|
141
|
+
img = generate_wordcloud(text, config)
|
|
142
|
+
img.save(output_dir / f"{year.strftime('%Y')}.png", optimize=True)
|