developer-assistant 0.3.5__tar.gz → 0.3.7__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.
- {developer_assistant-0.3.5/developer_assistant.egg-info → developer_assistant-0.3.7}/PKG-INFO +19 -16
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/PYPI.md +17 -6
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/README.md +12 -5
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/interface.py +148 -79
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/intro.md +9 -3
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/modules/config_manager.py +27 -8
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/modules/opener.py +4 -2
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/modules/projects_manager.py +40 -31
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/modules/version_logic.py +71 -32
- {developer_assistant-0.3.5 → developer_assistant-0.3.7/developer_assistant.egg-info}/PKG-INFO +19 -16
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/pyproject.toml +2 -2
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/LICENSE +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/__init__.py +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/default/default-changelog.md +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/default/default-memory.ini +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/default/test-project.ini +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/modules/__init__.py +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/templates/changelog_template.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/templates/entry_template.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/da/templates/header_template.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/developer_assistant.egg-info/SOURCES.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/developer_assistant.egg-info/dependency_links.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/developer_assistant.egg-info/entry_points.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/developer_assistant.egg-info/requires.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/developer_assistant.egg-info/top_level.txt +0 -0
- {developer_assistant-0.3.5 → developer_assistant-0.3.7}/setup.cfg +0 -0
{developer_assistant-0.3.5/developer_assistant.egg-info → developer_assistant-0.3.7}/PKG-INFO
RENAMED
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: developer-assistant
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7
|
|
4
4
|
Summary: A lightweight TUI app for managing and simplifying your Markdown changelogs.
|
|
5
|
-
License:
|
|
6
|
-
|
|
7
|
-
Copyright (c) 2026 Ivori Huobolainen
|
|
8
|
-
|
|
9
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
-
|
|
11
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
12
|
-
|
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
5
|
+
License-Expression: MIT
|
|
14
6
|
Project-URL: Homepage, https://github.com/Ivory-Hubert/Developer-Assistant
|
|
15
7
|
Project-URL: Changelog, https://github.com/Ivory-Hubert/Developer-Assistant/blob/main/CHANGELOG.md
|
|
16
8
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -30,7 +22,7 @@ Dynamic: license-file
|
|
|
30
22
|
|
|
31
23
|
## Installing from PyPI
|
|
32
24
|
|
|
33
|
-
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same process is used for new profiles.
|
|
25
|
+
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same automatic process is used for creating new profiles.
|
|
34
26
|
|
|
35
27
|
**Using uv:**
|
|
36
28
|
`uv tool install developer-assistant`
|
|
@@ -46,6 +38,8 @@ The program is designed for minimal friction and simple setup. Only installation
|
|
|
46
38
|
> Avoid using `sudo pip install` because it installs into the system Python.
|
|
47
39
|
If you want a system‑wide install, use the uv method or use `pip install --user`
|
|
48
40
|
|
|
41
|
+
---
|
|
42
|
+
|
|
49
43
|
## Updating DA
|
|
50
44
|
Two possibilities, depending on how you installed.
|
|
51
45
|
|
|
@@ -56,13 +50,16 @@ B. **Using pip:** `python -m pip install -U developer-assistant`
|
|
|
56
50
|
|
|
57
51
|
## Introduction
|
|
58
52
|
|
|
59
|
-
### What does this
|
|
53
|
+
### What does this program do?
|
|
60
54
|
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
61
55
|
|
|
62
56
|
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
63
57
|
|
|
64
|
-
|
|
58
|
+
Each project `.ini` can also hold a custom terminal command, that's run in the projects folder. So you can easly integrate updating your changelogs in DA with Git commands for example.
|
|
65
59
|
|
|
60
|
+
**Your files are kept safe at all times.** Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
61
|
+
|
|
62
|
+
---
|
|
66
63
|
|
|
67
64
|
### Using the program.
|
|
68
65
|
1. **What *not* to do**
|
|
@@ -81,13 +78,13 @@ Don't change the folder structure or modify variable names inside `.ini` files.
|
|
|
81
78
|
|
|
82
79
|
The `da-ui/` folder and subfolders will be created automatically.
|
|
83
80
|
|
|
84
|
-
You can access its content quickly when going to: `Main menu / Settings`
|
|
81
|
+
> **Tip:** You can access its content quickly when going to: `Main menu / Settings`
|
|
85
82
|
|
|
86
83
|
**Profiles for seperate projects and templates**
|
|
87
84
|
|
|
88
85
|
The program comes with the "Default" profile, you can choose to either stick with this one or create your own profiles in `Main menu / Profiles`. Each profile has seperate projects and they can't be accessed by other profiles. You can choose to customize the templates seperately too.
|
|
89
86
|
|
|
90
|
-
Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
87
|
+
> **Note:** Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
91
88
|
|
|
92
89
|
---
|
|
93
90
|
|
|
@@ -124,6 +121,11 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
124
121
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
125
122
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
126
123
|
|
|
124
|
+
Furthermore, you can safely work on one changelog in separate sessions, your changes are staged in the temporary log file and only deleted with your confirmation.
|
|
125
|
+
|
|
126
|
+
> **Note:**
|
|
127
|
+
> DA can only keep **one** projects WIP changes staged, switching projects with staged changes appends the same file. If you update/reinstall the program with unsaved changes they are lost for good, so it's **not** long-term storage.
|
|
128
|
+
|
|
127
129
|
|
|
128
130
|
**Ease of navigation**
|
|
129
131
|
|
|
@@ -144,8 +146,9 @@ The `memory.ini` file does exactly what you'd expect, it features:
|
|
|
144
146
|
|
|
145
147
|
Last project & active profile get updated automatically, the rest are up to you.
|
|
146
148
|
|
|
147
|
-
|
|
149
|
+
> **Tip:** `Ctrl+C` works everywhere to quickly exit DA.
|
|
148
150
|
|
|
151
|
+
---
|
|
149
152
|
|
|
150
153
|
### Setting up the test project
|
|
151
154
|
For a dummy changelog to experiment with, navigate to `Main menu / Projects`, choose `test-project`, then choose option `3.` to start adjusting this projects paths. **Before setting up your own profile don't change "*Default*"**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Installing from PyPI
|
|
4
4
|
|
|
5
|
-
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same process is used for new profiles.
|
|
5
|
+
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same automatic process is used for creating new profiles.
|
|
6
6
|
|
|
7
7
|
**Using uv:**
|
|
8
8
|
`uv tool install developer-assistant`
|
|
@@ -18,6 +18,8 @@ The program is designed for minimal friction and simple setup. Only installation
|
|
|
18
18
|
> Avoid using `sudo pip install` because it installs into the system Python.
|
|
19
19
|
If you want a system‑wide install, use the uv method or use `pip install --user`
|
|
20
20
|
|
|
21
|
+
---
|
|
22
|
+
|
|
21
23
|
## Updating DA
|
|
22
24
|
Two possibilities, depending on how you installed.
|
|
23
25
|
|
|
@@ -28,13 +30,16 @@ B. **Using pip:** `python -m pip install -U developer-assistant`
|
|
|
28
30
|
|
|
29
31
|
## Introduction
|
|
30
32
|
|
|
31
|
-
### What does this
|
|
33
|
+
### What does this program do?
|
|
32
34
|
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
33
35
|
|
|
34
36
|
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
Each project `.ini` can also hold a custom terminal command, that's run in the projects folder. So you can easly integrate updating your changelogs in DA with Git commands for example.
|
|
37
39
|
|
|
40
|
+
**Your files are kept safe at all times.** Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
41
|
+
|
|
42
|
+
---
|
|
38
43
|
|
|
39
44
|
### Using the program.
|
|
40
45
|
1. **What *not* to do**
|
|
@@ -53,13 +58,13 @@ Don't change the folder structure or modify variable names inside `.ini` files.
|
|
|
53
58
|
|
|
54
59
|
The `da-ui/` folder and subfolders will be created automatically.
|
|
55
60
|
|
|
56
|
-
You can access its content quickly when going to: `Main menu / Settings`
|
|
61
|
+
> **Tip:** You can access its content quickly when going to: `Main menu / Settings`
|
|
57
62
|
|
|
58
63
|
**Profiles for seperate projects and templates**
|
|
59
64
|
|
|
60
65
|
The program comes with the "Default" profile, you can choose to either stick with this one or create your own profiles in `Main menu / Profiles`. Each profile has seperate projects and they can't be accessed by other profiles. You can choose to customize the templates seperately too.
|
|
61
66
|
|
|
62
|
-
Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
67
|
+
> **Note:** Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
63
68
|
|
|
64
69
|
---
|
|
65
70
|
|
|
@@ -96,6 +101,11 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
96
101
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
97
102
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
98
103
|
|
|
104
|
+
Furthermore, you can safely work on one changelog in separate sessions, your changes are staged in the temporary log file and only deleted with your confirmation.
|
|
105
|
+
|
|
106
|
+
> **Note:**
|
|
107
|
+
> DA can only keep **one** projects WIP changes staged, switching projects with staged changes appends the same file. If you update/reinstall the program with unsaved changes they are lost for good, so it's **not** long-term storage.
|
|
108
|
+
|
|
99
109
|
|
|
100
110
|
**Ease of navigation**
|
|
101
111
|
|
|
@@ -116,8 +126,9 @@ The `memory.ini` file does exactly what you'd expect, it features:
|
|
|
116
126
|
|
|
117
127
|
Last project & active profile get updated automatically, the rest are up to you.
|
|
118
128
|
|
|
119
|
-
|
|
129
|
+
> **Tip:** `Ctrl+C` works everywhere to quickly exit DA.
|
|
120
130
|
|
|
131
|
+
---
|
|
121
132
|
|
|
122
133
|
### Setting up the test project
|
|
123
134
|
For a dummy changelog to experiment with, navigate to `Main menu / Projects`, choose `test-project`, then choose option `3.` to start adjusting this projects paths. **Before setting up your own profile don't change "*Default*"**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
> `pip install developer-assistant`
|
|
7
7
|
|
|
8
|
-
* **Installation:**
|
|
8
|
+
* **Installation:** more options in [SETUP](./SETUP.md)
|
|
9
9
|
|
|
10
10
|
* **Changes:** yes, I keep a [CHANGELOG](./CHANGELOG.md)
|
|
11
11
|
|
|
@@ -33,12 +33,14 @@ Preview your Markdown changelogs directly in the terminal with Rich rendering:
|
|
|
33
33
|
|
|
34
34
|
## Introduction
|
|
35
35
|
|
|
36
|
-
### What does this
|
|
36
|
+
### What does this program do?
|
|
37
37
|
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
38
38
|
|
|
39
39
|
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Each project `.ini` can also hold a custom terminal command, that's run in the projects folder. So you can easly integrate updating your changelogs in DA with Git commands for example.
|
|
42
|
+
|
|
43
|
+
**Your files are kept safe at all times.** Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
42
44
|
|
|
43
45
|
---
|
|
44
46
|
|
|
@@ -60,7 +62,7 @@ Don't change the folder structure or modify variable names inside `.ini` files.
|
|
|
60
62
|
The `da-ui/` folder and subfolders will be created automatically.
|
|
61
63
|
|
|
62
64
|
> [!TIP]
|
|
63
|
-
> You can access its
|
|
65
|
+
> You can access its contents quickly when going to: `Main menu / Settings`
|
|
64
66
|
|
|
65
67
|
**Profiles for seperate projects and templates**
|
|
66
68
|
|
|
@@ -90,7 +92,7 @@ The `Projects/` folder holds the `.ini` files you create when starting a new pro
|
|
|
90
92
|
|
|
91
93
|
[Project.ini example](./documents/project-example.ini)
|
|
92
94
|
|
|
93
|
-
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even
|
|
95
|
+
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even if provided, it is **not** run without your confirmation, first it's printed with the folder name and you can choose to skip it.
|
|
94
96
|
|
|
95
97
|
`owner` & `edited` are filled out automatically when a new project is created and `edited` updates with every changelog update.
|
|
96
98
|
|
|
@@ -104,6 +106,11 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
104
106
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
105
107
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
106
108
|
|
|
109
|
+
Furthermore, you can safely work on one changelog in separate sessions, your changes are staged in the temporary log file and only deleted with your confirmation.
|
|
110
|
+
|
|
111
|
+
> [!NOTE]
|
|
112
|
+
> DA can only keep **one** projects WIP changes staged, switching projects with staged changes appends the same file. If you update/reinstall the program with unsaved changes they are lost for good, so it's **not** long-term storage.
|
|
113
|
+
|
|
107
114
|
|
|
108
115
|
**Ease of navigation**
|
|
109
116
|
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import os, sys
|
|
2
|
-
import time
|
|
3
2
|
import platform
|
|
4
|
-
import subprocess
|
|
5
3
|
import shutil
|
|
4
|
+
import time
|
|
5
|
+
from importlib import resources
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
from termcolor import colored
|
|
9
|
-
from rich.progress import track
|
|
10
8
|
from rich.console import Console
|
|
11
9
|
from rich.markdown import Markdown
|
|
10
|
+
from rich.progress import track
|
|
11
|
+
from termcolor import colored
|
|
12
12
|
|
|
13
|
-
from da.modules.projects_manager import ProjectsManager
|
|
14
13
|
from da.modules.config_manager import ConfigManager
|
|
15
14
|
from da.modules.opener import Opener
|
|
16
|
-
from
|
|
15
|
+
from da.modules.projects_manager import ProjectsManager
|
|
16
|
+
|
|
17
17
|
|
|
18
18
|
class Interface:
|
|
19
19
|
def __init__(self):
|
|
20
|
-
self.version = "0.3.
|
|
21
|
-
self.clear =
|
|
20
|
+
self.version = "0.3.7"
|
|
21
|
+
self.clear = "cls" if platform.system() == "Windows" else "clear"
|
|
22
22
|
|
|
23
23
|
title = f"DA - {self.version}"
|
|
24
24
|
|
|
25
25
|
if platform.system() == "Windows":
|
|
26
|
-
os.system(f
|
|
26
|
+
os.system(f"title {title}")
|
|
27
27
|
else:
|
|
28
|
-
print(f
|
|
28
|
+
print(f"\33]0;{title}\a", end="", flush=True)
|
|
29
29
|
|
|
30
|
-
self.config = ConfigManager(
|
|
30
|
+
self.config = ConfigManager("memory.ini", profile="Default")
|
|
31
31
|
|
|
32
32
|
self.memory = None
|
|
33
33
|
self.color = None
|
|
@@ -35,11 +35,12 @@ class Interface:
|
|
|
35
35
|
self.user_path = None
|
|
36
36
|
|
|
37
37
|
self.first_run = False
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
|
|
39
40
|
def run(self):
|
|
40
41
|
steps = [
|
|
41
42
|
("Initializing runtime...", self.runtime_init),
|
|
42
|
-
("Checking configuration...", self.config.data_check)
|
|
43
|
+
("Checking configuration...", self.config.data_check),
|
|
43
44
|
]
|
|
44
45
|
|
|
45
46
|
for label, step in track(steps):
|
|
@@ -50,15 +51,20 @@ class Interface:
|
|
|
50
51
|
if isinstance(result, list):
|
|
51
52
|
for msg in result:
|
|
52
53
|
print(msg.center(65))
|
|
53
|
-
time.sleep(
|
|
54
|
+
time.sleep(1)
|
|
54
55
|
|
|
55
56
|
temp_log = Path(__file__).parent / "CHANGELOG.tmp"
|
|
56
57
|
|
|
57
58
|
if os.path.exists(temp_log):
|
|
58
59
|
while True:
|
|
59
60
|
os.system(self.clear)
|
|
60
|
-
print(colored(
|
|
61
|
-
print(
|
|
61
|
+
print(colored("Unsaved changes detected from your last session!\n", "yellow",))
|
|
62
|
+
print(
|
|
63
|
+
colored("D", "light_red")
|
|
64
|
+
+ "elete or "
|
|
65
|
+
+ colored("K", "light_red")
|
|
66
|
+
+ "eep?\n"
|
|
67
|
+
)
|
|
62
68
|
choice = input(f"{self.user_path}> ").lower()
|
|
63
69
|
if choice == "d":
|
|
64
70
|
os.remove(temp_log)
|
|
@@ -67,8 +73,8 @@ class Interface:
|
|
|
67
73
|
break
|
|
68
74
|
else:
|
|
69
75
|
print(colored("\nPlease make a valid choice.", "light_red"))
|
|
70
|
-
time.sleep(
|
|
71
|
-
|
|
76
|
+
time.sleep(0.5)
|
|
77
|
+
|
|
72
78
|
state = "intro" if self.first_run else "menu"
|
|
73
79
|
|
|
74
80
|
while state != "exit":
|
|
@@ -90,22 +96,26 @@ class Interface:
|
|
|
90
96
|
state = "exit"
|
|
91
97
|
|
|
92
98
|
def menu(self):
|
|
93
|
-
self.active_profile = self.memory.get(
|
|
99
|
+
self.active_profile = self.memory.get("profile")
|
|
100
|
+
last_project = self.memory.get("last_project")
|
|
94
101
|
|
|
95
102
|
projects_manager = ProjectsManager(
|
|
96
103
|
config=self.config,
|
|
97
104
|
color=self.color,
|
|
98
105
|
header=self.header,
|
|
99
106
|
cls=self.clear,
|
|
100
|
-
user_path=self.user_path
|
|
107
|
+
user_path=self.user_path,
|
|
101
108
|
)
|
|
102
109
|
|
|
103
|
-
last_project = self.memory.get('last_project')
|
|
104
110
|
while True:
|
|
105
111
|
os.system(self.clear)
|
|
106
|
-
print(
|
|
112
|
+
print(
|
|
113
|
+
colored(
|
|
114
|
+
f"{self.active_profile}", f"{self.color}")
|
|
115
|
+
+ " / Main menu"
|
|
116
|
+
)
|
|
107
117
|
print(self.header)
|
|
108
|
-
print("
|
|
118
|
+
print("Q. Exit\n")
|
|
109
119
|
print("Last project:")
|
|
110
120
|
print(colored(last_project, f"{self.color}"))
|
|
111
121
|
print("\n1. Projects")
|
|
@@ -114,7 +124,7 @@ class Interface:
|
|
|
114
124
|
|
|
115
125
|
choice = input(f"{self.user_path}> ").strip()
|
|
116
126
|
|
|
117
|
-
if choice.lower() == "
|
|
127
|
+
if choice.lower() == "q":
|
|
118
128
|
os.system(self.clear)
|
|
119
129
|
print(self.header)
|
|
120
130
|
print("Bye!")
|
|
@@ -130,16 +140,18 @@ class Interface:
|
|
|
130
140
|
elif choice == "3":
|
|
131
141
|
return "settings"
|
|
132
142
|
else:
|
|
133
|
-
print("")
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
print(colored("\nUnknown option...", "light_red", attrs=["bold"]))
|
|
144
|
+
time.sleep(0.5)
|
|
145
|
+
|
|
137
146
|
def settings(self):
|
|
138
147
|
while True:
|
|
139
148
|
os.system(self.clear)
|
|
140
|
-
print(
|
|
149
|
+
print(
|
|
150
|
+
colored(f"{self.active_profile}", f"{self.color}")
|
|
151
|
+
+ " / Main menu / Settings"
|
|
152
|
+
)
|
|
141
153
|
print(self.header)
|
|
142
|
-
print("
|
|
154
|
+
print("Q. Back\n")
|
|
143
155
|
|
|
144
156
|
print(colored("Configuration options", attrs=["underline"]))
|
|
145
157
|
print("1. Edit pinned projects [WIP]")
|
|
@@ -152,12 +164,12 @@ class Interface:
|
|
|
152
164
|
|
|
153
165
|
choice = input(f"{self.user_path}> ").strip()
|
|
154
166
|
|
|
155
|
-
if choice.lower() == "
|
|
167
|
+
if choice.lower() == "q":
|
|
156
168
|
return
|
|
157
|
-
#elif choice == "1":
|
|
158
|
-
|
|
159
|
-
#elif choice == "2":
|
|
160
|
-
|
|
169
|
+
# elif choice == "1":
|
|
170
|
+
# pass
|
|
171
|
+
# elif choice == "2":
|
|
172
|
+
# pass
|
|
161
173
|
elif choice == "3":
|
|
162
174
|
Opener.open(self.config.memory_ini)
|
|
163
175
|
elif choice == "4":
|
|
@@ -165,59 +177,55 @@ class Interface:
|
|
|
165
177
|
elif choice == "5":
|
|
166
178
|
Opener.open(self.config.templates_folder)
|
|
167
179
|
else:
|
|
168
|
-
print("")
|
|
169
|
-
|
|
170
|
-
time.sleep(1)
|
|
180
|
+
print(colored("\nUnknown option...", "light_red", attrs=["bold"]))
|
|
181
|
+
time.sleep(0.5)
|
|
171
182
|
|
|
172
183
|
def profiles(self):
|
|
173
184
|
while True:
|
|
174
185
|
os.system(self.clear)
|
|
175
|
-
print(
|
|
186
|
+
print(
|
|
187
|
+
colored(f"{self.active_profile}", f"{self.color}")
|
|
188
|
+
+ " / Main menu / Profiles"
|
|
189
|
+
)
|
|
176
190
|
print(self.header)
|
|
177
|
-
print("
|
|
191
|
+
print("Q. Back\n")
|
|
192
|
+
|
|
193
|
+
print("1. Switch profiles\n")
|
|
178
194
|
|
|
179
|
-
print("
|
|
180
|
-
print("
|
|
195
|
+
print("2. Create a new profile")
|
|
196
|
+
print("3. Delete a profile\n")
|
|
181
197
|
|
|
182
198
|
choice = input(f"{self.user_path}> ").strip()
|
|
183
199
|
|
|
184
|
-
if choice.lower() == "
|
|
200
|
+
if choice.lower() == "q":
|
|
185
201
|
return
|
|
186
202
|
elif choice == "1":
|
|
187
|
-
self.new_profile()
|
|
188
|
-
elif choice == "2":
|
|
189
203
|
self.switch_profile()
|
|
204
|
+
elif choice == "2":
|
|
205
|
+
self.new_profile()
|
|
206
|
+
elif choice == "3":
|
|
207
|
+
self.delete_profile()
|
|
190
208
|
else:
|
|
191
|
-
print("")
|
|
192
|
-
|
|
193
|
-
time.sleep(1)
|
|
209
|
+
print(colored("\nUnknown option...", "light_red", attrs=["bold"]))
|
|
210
|
+
time.sleep(0.5)
|
|
194
211
|
|
|
195
212
|
def switch_profile(self):
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
contents = os.listdir(prof_dir)
|
|
199
|
-
|
|
200
|
-
print("\nYour profiles:")
|
|
201
|
-
for item in contents:
|
|
202
|
-
print(colored(f" - {item}", f"{self.color}"))
|
|
203
|
-
|
|
204
|
-
name = input("\nProfile name > ").strip()
|
|
213
|
+
prof_dir = self.config.profile_dir
|
|
214
|
+
contents = os.listdir(prof_dir)
|
|
205
215
|
|
|
206
|
-
|
|
207
|
-
|
|
216
|
+
print("\nYour profiles:")
|
|
217
|
+
for item in contents:
|
|
218
|
+
print(" -" + colored(f" {item}", f"{self.color}"))
|
|
208
219
|
|
|
209
|
-
|
|
220
|
+
name = input("\nProfile name > ").strip()
|
|
210
221
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
print(colored("\nInvalid name!", "yellow"))
|
|
219
|
-
time.sleep(1)
|
|
220
|
-
os.system(self.clear)
|
|
222
|
+
if name in contents:
|
|
223
|
+
self.load_profile(name)
|
|
224
|
+
return
|
|
225
|
+
else:
|
|
226
|
+
print(colored("\nInvalid name!", "yellow"))
|
|
227
|
+
time.sleep(0.5)
|
|
228
|
+
os.system(self.clear)
|
|
221
229
|
|
|
222
230
|
def new_profile(self):
|
|
223
231
|
name = input("\nNew profile name > ").strip()
|
|
@@ -233,16 +241,42 @@ class Interface:
|
|
|
233
241
|
dest = profile_dir / "Templates"
|
|
234
242
|
shutil.copy(item, dest)
|
|
235
243
|
|
|
244
|
+
self.load_profile(name)
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
def delete_profile(self):
|
|
248
|
+
prof_dir = self.config.profile_dir
|
|
249
|
+
contents = os.listdir(prof_dir)
|
|
250
|
+
|
|
251
|
+
print("\nYour profiles:")
|
|
252
|
+
for item in contents:
|
|
253
|
+
print(" -" + colored(f" {item}", f"{self.color}"))
|
|
254
|
+
|
|
255
|
+
name = input("\nProfile name > ").strip()
|
|
256
|
+
|
|
257
|
+
if name in contents and name != "Default":
|
|
258
|
+
profiles = self.config.profile_dir
|
|
259
|
+
profile = profiles / name
|
|
260
|
+
shutil.rmtree(profile)
|
|
261
|
+
|
|
262
|
+
if name == self.active_profile:
|
|
263
|
+
self.load_profile(name="Default")
|
|
264
|
+
return
|
|
265
|
+
else:
|
|
266
|
+
print(colored("\nInvalid name!", "yellow"))
|
|
267
|
+
time.sleep(0.5)
|
|
268
|
+
os.system(self.clear)
|
|
269
|
+
|
|
270
|
+
def load_profile(self, name):
|
|
236
271
|
self.config.update_memory("CONFIG", "profile", name)
|
|
237
272
|
|
|
238
273
|
self.memory = self.config.load_memory()
|
|
239
274
|
|
|
240
|
-
profile = self.memory.get(
|
|
275
|
+
profile = self.memory.get("profile")
|
|
241
276
|
self.config = ConfigManager("memory.ini", profile=profile)
|
|
242
277
|
|
|
243
278
|
self.memory = self.config.load_memory()
|
|
244
|
-
self.active_profile = self.memory.get(
|
|
245
|
-
return
|
|
279
|
+
self.active_profile = self.memory.get("profile")
|
|
246
280
|
|
|
247
281
|
def runtime_init(self):
|
|
248
282
|
if not self.config.memory_ini.exists():
|
|
@@ -255,10 +289,11 @@ class Interface:
|
|
|
255
289
|
self.config = ConfigManager("memory.ini", profile=active_profile)
|
|
256
290
|
self.memory = self.config.load_memory()
|
|
257
291
|
|
|
258
|
-
self.color = self.memory.get(
|
|
259
|
-
self.user_path = os.environ.get(
|
|
292
|
+
self.color = self.memory.get("color") or "light_blue"
|
|
293
|
+
self.user_path = os.environ.get("USERPROFILE") or os.environ.get("HOME", "User")
|
|
294
|
+
|
|
260
295
|
|
|
261
|
-
brand =
|
|
296
|
+
brand = colored(" Developer Assistant ", f"{self.color}")
|
|
262
297
|
text = " Developer Assistant "
|
|
263
298
|
|
|
264
299
|
columns, _ = shutil.get_terminal_size()
|
|
@@ -268,6 +303,7 @@ class Interface:
|
|
|
268
303
|
self.header = f"{bars}{brand}{bars}"
|
|
269
304
|
|
|
270
305
|
def local_init(self):
|
|
306
|
+
# Works together with ConfigManager.data_check()
|
|
271
307
|
default_files = resources.files("da.default")
|
|
272
308
|
dest = self.config.memory_ini
|
|
273
309
|
|
|
@@ -284,7 +320,11 @@ class Interface:
|
|
|
284
320
|
|
|
285
321
|
def intro(self):
|
|
286
322
|
os.system(self.clear)
|
|
287
|
-
print(
|
|
323
|
+
print(
|
|
324
|
+
colored("Welcome to the Developer Assistant\n",
|
|
325
|
+
f"{self.color}", attrs=["bold"]
|
|
326
|
+
)
|
|
327
|
+
)
|
|
288
328
|
print("Here's everything you need to get started...\n")
|
|
289
329
|
|
|
290
330
|
time.sleep(2)
|
|
@@ -297,13 +337,42 @@ class Interface:
|
|
|
297
337
|
|
|
298
338
|
input("\nContinue..." + colored("[Enter]", f"{self.color}"))
|
|
299
339
|
|
|
340
|
+
# [WIP code, implementation could change]
|
|
341
|
+
|
|
342
|
+
# print(colored("\nChoose an accent colour.\n", attrs=["underline"]))
|
|
343
|
+
# print("1. Default - " + colored("light blue", f"{self.color}"))
|
|
344
|
+
#
|
|
345
|
+
# print("\n2. " + colored("red", "red"))
|
|
346
|
+
# print("3. " + colored("green", "green"))
|
|
347
|
+
# print("4. " + colored("blue", "blue"))
|
|
348
|
+
# print("5. " + colored("yellow", "yellow"))
|
|
349
|
+
# print("6. " + colored("cyan", "cyan"))
|
|
350
|
+
# print("7. " + colored("magenta", "magenta"))
|
|
351
|
+
#
|
|
352
|
+
# print("\n8. " + colored("light green", "light_green"))
|
|
353
|
+
# print("9. " + colored("light yellow", "light_yellow"))
|
|
354
|
+
# print("10. " + colored("light magenta", "light_magenta"))
|
|
355
|
+
# print("11. " + colored("light cyan", "light_cyan"))
|
|
356
|
+
#
|
|
357
|
+
# choice = input("\nChoice > ").strip()
|
|
358
|
+
#
|
|
359
|
+
# key_map = {
|
|
360
|
+
# "1": "",
|
|
361
|
+
# "2": "red",
|
|
362
|
+
# }
|
|
363
|
+
|
|
300
364
|
def main():
|
|
301
365
|
try:
|
|
302
366
|
app = Interface()
|
|
303
367
|
app.run()
|
|
368
|
+
os.system(app.clear)
|
|
304
369
|
except KeyboardInterrupt:
|
|
305
|
-
print(
|
|
306
|
-
|
|
370
|
+
print(
|
|
371
|
+
"\n\n"
|
|
372
|
+
+ colored("Execution interrupted. Exiting...", "cyan", attrs=["bold"])
|
|
373
|
+
)
|
|
374
|
+
time.sleep(0.5)
|
|
375
|
+
os.system(app.clear)
|
|
307
376
|
sys.exit(0)
|
|
308
377
|
|
|
309
378
|
if __name__ == "__main__":
|
|
@@ -31,14 +31,14 @@ Don't change the folder structure or modify variable names inside `.ini` files.
|
|
|
31
31
|
|
|
32
32
|
The `da-ui/` folder and subfolders will be created automatically.
|
|
33
33
|
|
|
34
|
-
> Tip
|
|
34
|
+
> **Tip:**
|
|
35
35
|
> You can access its content quickly when going to: `Main menu / Settings`
|
|
36
36
|
|
|
37
37
|
**Profiles for seperate projects and templates**
|
|
38
38
|
|
|
39
39
|
The program comes with the "Default" profile, you can choose to either stick with this one or create your own profiles in `Main menu / Profiles`. Each profile has seperate projects and they can't be accessed by other profiles. You can choose to customize the templates seperately too.
|
|
40
40
|
|
|
41
|
-
> Note
|
|
41
|
+
> **Note:**
|
|
42
42
|
> Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
43
43
|
|
|
44
44
|
---
|
|
@@ -74,6 +74,11 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
74
74
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
75
75
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
76
76
|
|
|
77
|
+
Furthermore, you can safely work on one changelog in separate sessions, your changes are staged in the temporary log file and only deleted with your confirmation.
|
|
78
|
+
|
|
79
|
+
> **Note:**
|
|
80
|
+
> DA can only keep **one** projects WIP changes staged, switching projects with staged changes appends the same file. If you update/reinstall the program with unsaved changes they are lost for good, so it's **not** long-term storage.
|
|
81
|
+
|
|
77
82
|
|
|
78
83
|
**Ease of navigation**
|
|
79
84
|
|
|
@@ -94,4 +99,5 @@ The `memory.ini` file does exactly what you'd expect, it features:
|
|
|
94
99
|
|
|
95
100
|
Last project & active profile get updated automatically, the rest are up to you.
|
|
96
101
|
|
|
97
|
-
>
|
|
102
|
+
> **Tip:**
|
|
103
|
+
> `Ctrl+C` works everywhere to quickly exit DA.
|