vasanth-love 1.0.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.
- vasanth_love-1.0.0/.gitignore +39 -0
- vasanth_love-1.0.0/LICENSE +21 -0
- vasanth_love-1.0.0/PKG-INFO +280 -0
- vasanth_love-1.0.0/README.md +236 -0
- vasanth_love-1.0.0/pyproject.toml +45 -0
- vasanth_love-1.0.0/src/vasanth/__init__.py +5 -0
- vasanth_love-1.0.0/src/vasanth/__main__.py +8 -0
- vasanth_love-1.0.0/src/vasanth/animation.py +371 -0
- vasanth_love-1.0.0/src/vasanth/api.py +150 -0
- vasanth_love-1.0.0/src/vasanth/cli.py +637 -0
- vasanth_love-1.0.0/src/vasanth/messages.py +604 -0
- vasanth_love-1.0.0/src/vasanth/ui.py +283 -0
- vasanth_love-1.0.0/tests/test_api_client.py +222 -0
- vasanth_love-1.0.0/tests/test_flow.py +364 -0
- vasanth_love-1.0.0/tests/test_messages.py +97 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.env
|
|
25
|
+
.venv
|
|
26
|
+
env/
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
|
|
30
|
+
# Testing
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.coverage
|
|
33
|
+
htmlcov/
|
|
34
|
+
|
|
35
|
+
# IDE & OS
|
|
36
|
+
.vscode/
|
|
37
|
+
.idea/
|
|
38
|
+
.DS_Store
|
|
39
|
+
Thumbs.db
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Someone who cares
|
|
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.
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: vasanth-love
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A small, quiet terminal experience.
|
|
5
|
+
Author: Made with a lot of thought
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Someone who cares
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Keywords: cli,letter,terminal
|
|
29
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
30
|
+
Classifier: Environment :: Console
|
|
31
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
39
|
+
Classifier: Topic :: Artistic Software
|
|
40
|
+
Requires-Python: >=3.9
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# vasanth-love
|
|
46
|
+
|
|
47
|
+
A small terminal experience.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install vasanth-love
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
vasanth
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
(`vasanth-love` works too — same thing.)
|
|
60
|
+
|
|
61
|
+
That's the whole thing. It runs in the terminal, works offline, and takes a
|
|
62
|
+
few minutes to read through.
|
|
63
|
+
|
|
64
|
+
> If `vasanth-love` is already taken on PyPI when publishing, you can name the distribution
|
|
65
|
+
> `vasanth-love-cli`. The command he actually types remains `vasanth-love` (`vasanth` also works).
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## What it is
|
|
70
|
+
|
|
71
|
+
A Python package that opens a quiet, animated letter in the terminal: a boot
|
|
72
|
+
sequence, a menu, a few scenes to wander through, and one question at the end.
|
|
73
|
+
There is also a way to write a message back.
|
|
74
|
+
|
|
75
|
+
It is a standard console application. It installs like any other package,
|
|
76
|
+
runs like any other command, and uninstalls with `pip uninstall vasanth-love`.
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
* Python 3.9 or newer
|
|
81
|
+
* Any terminal: Windows PowerShell, Windows Terminal, CMD, macOS Terminal,
|
|
82
|
+
iTerm2, or any Linux terminal
|
|
83
|
+
|
|
84
|
+
**Zero runtime dependencies.** Everything is standard library, so the install
|
|
85
|
+
is instant and there is nothing to audit.
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
vasanth # the full experience (vasanth-love works too)
|
|
91
|
+
python -m vasanth # identical, if the command isn't on PATH
|
|
92
|
+
vasanth --skip-intro # straight to the menu
|
|
93
|
+
vasanth --fast # no animation delays
|
|
94
|
+
vasanth --version
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Environment knobs:
|
|
98
|
+
|
|
99
|
+
| Variable | Effect |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `VASANTH_SPEED` | Delay multiplier. `0.5` is twice as fast, `2` is slower. |
|
|
102
|
+
| `VASANTH_FAST` | Set to anything to remove all delays. |
|
|
103
|
+
| `NO_COLOR` | Standard opt-out; renders without colour. |
|
|
104
|
+
| `VASANTH_ENDPOINT` | Points the message feature at a different backend. |
|
|
105
|
+
|
|
106
|
+
`Ctrl+C` exits gracefully at any point.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Customising it
|
|
111
|
+
|
|
112
|
+
**Every personal word lives in exactly one file:** `src/vasanth/messages.py`.
|
|
113
|
+
Nothing personal is scattered through the code, so you can edit that one file
|
|
114
|
+
without reading any of the rest.
|
|
115
|
+
|
|
116
|
+
What's in there, in order:
|
|
117
|
+
|
|
118
|
+
| Section | What it controls |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `NAME`, `TAGLINE` | The name on every screen. `{name}` anywhere expands to it. |
|
|
121
|
+
| `BOOT_*` | The opening sequence and the reveal. |
|
|
122
|
+
| `INTRO_LINES` | The lines shown once after boot. |
|
|
123
|
+
| `MAIN_MESSAGE` | Option 1 — the letter itself. |
|
|
124
|
+
| `REASONS` | Option 2 — numbered automatically; add as many as you like. |
|
|
125
|
+
| `LOVE_EXE_*` | Option 3 — the fake diagnostic. |
|
|
126
|
+
| `MEMORIES` | Option 4 — **placeholders; replace with your own.** |
|
|
127
|
+
| `RANDOM_THOUGHTS` | Option 5 — the random pool. |
|
|
128
|
+
| `QUESTION`, `ANSWER_*` | Option 6 — the question and every reply. |
|
|
129
|
+
| `SEND_*` | Option 7 — the message-back screens and privacy notice. |
|
|
130
|
+
| `SECRET_*` | The hidden screen, and what triggers it. |
|
|
131
|
+
| `EXIT_*` | The goodbye. |
|
|
132
|
+
| `MENU_ITEMS` | Menu labels and order. |
|
|
133
|
+
|
|
134
|
+
Formatting rules, which the test suite enforces:
|
|
135
|
+
|
|
136
|
+
* A block is a list of lines. `""` is a deliberate pause, not a blank string.
|
|
137
|
+
* Keep lines under ~46 characters so they stay centred and never wrap.
|
|
138
|
+
* `{name}` is the only placeholder.
|
|
139
|
+
|
|
140
|
+
Change the name in one place:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
NAME = "Vasanth"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Add a reason — numbering is automatic:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
REASONS = [
|
|
150
|
+
["Because talking to you never feels ordinary."],
|
|
151
|
+
["Because of the way you", "explain things you love."],
|
|
152
|
+
]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Replace the placeholder memories with real ones:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
MEMORIES = [
|
|
159
|
+
"That conversation I still remember.",
|
|
160
|
+
"That day we laughed for no reason.",
|
|
161
|
+
]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Change the question:
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
QUESTION = [
|
|
168
|
+
"Would you like to be",
|
|
169
|
+
"a little more than",
|
|
170
|
+
"just a beautiful part",
|
|
171
|
+
"of my life?",
|
|
172
|
+
]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
After editing, check your work:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pip install -e ".[dev]"
|
|
179
|
+
pytest # catches unbalanced braces, over-long lines, dead menu entries
|
|
180
|
+
vasanth --fast # read it end to end in a few seconds
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Local development
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
git clone <your-repo-url>
|
|
189
|
+
cd Vasanth_project
|
|
190
|
+
pip install -e ".[dev]"
|
|
191
|
+
vasanth-love
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Run the tests:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pytest # the CLI
|
|
198
|
+
cd backend && pytest # the message relay
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Build a distribution:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
pip install build
|
|
205
|
+
python -m build # writes dist/*.whl and dist/*.tar.gz
|
|
206
|
+
pip install dist/vasanth_love-1.0.0-py3-none-any.whl
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Publish:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
pip install twine
|
|
213
|
+
twine upload dist/*
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## The message feature
|
|
219
|
+
|
|
220
|
+
Option 7 lets him write a message and send it to you by email.
|
|
221
|
+
|
|
222
|
+
The important constraint: **this package is public, so it contains no
|
|
223
|
+
credentials.** It knows one public HTTPS URL and nothing else. The email
|
|
224
|
+
provider's API key lives only in the backend's environment variables.
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
vasanth CLI ──HTTPS──▶ your backend ──API──▶ email provider ──▶ your inbox
|
|
228
|
+
(public, (holds the
|
|
229
|
+
no secrets) secret)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
What is sent: the message he typed, and nothing else. No files, contacts,
|
|
233
|
+
location, system information, credentials, or identifiers. No analytics, no
|
|
234
|
+
tracking, no logging to disk. Every other feature works with the network
|
|
235
|
+
unplugged, and a privacy notice is shown before anything leaves the machine.
|
|
236
|
+
|
|
237
|
+
If the backend can't be reached, the CLI says the message was **not**
|
|
238
|
+
delivered. It only claims success on a confirmed 2xx response.
|
|
239
|
+
|
|
240
|
+
### Running the backend
|
|
241
|
+
|
|
242
|
+
See [`backend/README.md`](backend/README.md) for the full deployment guide.
|
|
243
|
+
The short version:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
cd backend
|
|
247
|
+
pip install -r requirements.txt
|
|
248
|
+
cp .env.example .env # then fill in your real values
|
|
249
|
+
uvicorn app.main:app --reload
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Then point the CLI at it while testing:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
VASANTH_ENDPOINT=http://127.0.0.1:8000/api/message vasanth-love
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Before publishing, set the deployed URL in `src/vasanth/api.py`:
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
DEFAULT_ENDPOINT = "https://your-backend.example.com/api/message"
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Never commit
|
|
265
|
+
|
|
266
|
+
`.env` is in `.gitignore` and must stay there. `.env.example` holds the shape
|
|
267
|
+
of the configuration, never the values.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Privacy
|
|
272
|
+
|
|
273
|
+
* No telemetry, no analytics, no tracking, no identifiers.
|
|
274
|
+
* Nothing is written to disk. No config file, no history, no cache.
|
|
275
|
+
* No network access at all unless he chooses to send a message and confirms.
|
|
276
|
+
* Uninstalling removes everything: `pip uninstall vasanth-love`.
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# vasanth-love
|
|
2
|
+
|
|
3
|
+
A small terminal experience.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install vasanth-love
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Then:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
vasanth
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
(`vasanth-love` works too — same thing.)
|
|
16
|
+
|
|
17
|
+
That's the whole thing. It runs in the terminal, works offline, and takes a
|
|
18
|
+
few minutes to read through.
|
|
19
|
+
|
|
20
|
+
> If `vasanth-love` is already taken on PyPI when publishing, you can name the distribution
|
|
21
|
+
> `vasanth-love-cli`. The command he actually types remains `vasanth-love` (`vasanth` also works).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## What it is
|
|
26
|
+
|
|
27
|
+
A Python package that opens a quiet, animated letter in the terminal: a boot
|
|
28
|
+
sequence, a menu, a few scenes to wander through, and one question at the end.
|
|
29
|
+
There is also a way to write a message back.
|
|
30
|
+
|
|
31
|
+
It is a standard console application. It installs like any other package,
|
|
32
|
+
runs like any other command, and uninstalls with `pip uninstall vasanth-love`.
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
* Python 3.9 or newer
|
|
37
|
+
* Any terminal: Windows PowerShell, Windows Terminal, CMD, macOS Terminal,
|
|
38
|
+
iTerm2, or any Linux terminal
|
|
39
|
+
|
|
40
|
+
**Zero runtime dependencies.** Everything is standard library, so the install
|
|
41
|
+
is instant and there is nothing to audit.
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
vasanth # the full experience (vasanth-love works too)
|
|
47
|
+
python -m vasanth # identical, if the command isn't on PATH
|
|
48
|
+
vasanth --skip-intro # straight to the menu
|
|
49
|
+
vasanth --fast # no animation delays
|
|
50
|
+
vasanth --version
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Environment knobs:
|
|
54
|
+
|
|
55
|
+
| Variable | Effect |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `VASANTH_SPEED` | Delay multiplier. `0.5` is twice as fast, `2` is slower. |
|
|
58
|
+
| `VASANTH_FAST` | Set to anything to remove all delays. |
|
|
59
|
+
| `NO_COLOR` | Standard opt-out; renders without colour. |
|
|
60
|
+
| `VASANTH_ENDPOINT` | Points the message feature at a different backend. |
|
|
61
|
+
|
|
62
|
+
`Ctrl+C` exits gracefully at any point.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Customising it
|
|
67
|
+
|
|
68
|
+
**Every personal word lives in exactly one file:** `src/vasanth/messages.py`.
|
|
69
|
+
Nothing personal is scattered through the code, so you can edit that one file
|
|
70
|
+
without reading any of the rest.
|
|
71
|
+
|
|
72
|
+
What's in there, in order:
|
|
73
|
+
|
|
74
|
+
| Section | What it controls |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `NAME`, `TAGLINE` | The name on every screen. `{name}` anywhere expands to it. |
|
|
77
|
+
| `BOOT_*` | The opening sequence and the reveal. |
|
|
78
|
+
| `INTRO_LINES` | The lines shown once after boot. |
|
|
79
|
+
| `MAIN_MESSAGE` | Option 1 — the letter itself. |
|
|
80
|
+
| `REASONS` | Option 2 — numbered automatically; add as many as you like. |
|
|
81
|
+
| `LOVE_EXE_*` | Option 3 — the fake diagnostic. |
|
|
82
|
+
| `MEMORIES` | Option 4 — **placeholders; replace with your own.** |
|
|
83
|
+
| `RANDOM_THOUGHTS` | Option 5 — the random pool. |
|
|
84
|
+
| `QUESTION`, `ANSWER_*` | Option 6 — the question and every reply. |
|
|
85
|
+
| `SEND_*` | Option 7 — the message-back screens and privacy notice. |
|
|
86
|
+
| `SECRET_*` | The hidden screen, and what triggers it. |
|
|
87
|
+
| `EXIT_*` | The goodbye. |
|
|
88
|
+
| `MENU_ITEMS` | Menu labels and order. |
|
|
89
|
+
|
|
90
|
+
Formatting rules, which the test suite enforces:
|
|
91
|
+
|
|
92
|
+
* A block is a list of lines. `""` is a deliberate pause, not a blank string.
|
|
93
|
+
* Keep lines under ~46 characters so they stay centred and never wrap.
|
|
94
|
+
* `{name}` is the only placeholder.
|
|
95
|
+
|
|
96
|
+
Change the name in one place:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
NAME = "Vasanth"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Add a reason — numbering is automatic:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
REASONS = [
|
|
106
|
+
["Because talking to you never feels ordinary."],
|
|
107
|
+
["Because of the way you", "explain things you love."],
|
|
108
|
+
]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Replace the placeholder memories with real ones:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
MEMORIES = [
|
|
115
|
+
"That conversation I still remember.",
|
|
116
|
+
"That day we laughed for no reason.",
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Change the question:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
QUESTION = [
|
|
124
|
+
"Would you like to be",
|
|
125
|
+
"a little more than",
|
|
126
|
+
"just a beautiful part",
|
|
127
|
+
"of my life?",
|
|
128
|
+
]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
After editing, check your work:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
pip install -e ".[dev]"
|
|
135
|
+
pytest # catches unbalanced braces, over-long lines, dead menu entries
|
|
136
|
+
vasanth --fast # read it end to end in a few seconds
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Local development
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
git clone <your-repo-url>
|
|
145
|
+
cd Vasanth_project
|
|
146
|
+
pip install -e ".[dev]"
|
|
147
|
+
vasanth-love
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Run the tests:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
pytest # the CLI
|
|
154
|
+
cd backend && pytest # the message relay
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Build a distribution:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install build
|
|
161
|
+
python -m build # writes dist/*.whl and dist/*.tar.gz
|
|
162
|
+
pip install dist/vasanth_love-1.0.0-py3-none-any.whl
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Publish:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pip install twine
|
|
169
|
+
twine upload dist/*
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## The message feature
|
|
175
|
+
|
|
176
|
+
Option 7 lets him write a message and send it to you by email.
|
|
177
|
+
|
|
178
|
+
The important constraint: **this package is public, so it contains no
|
|
179
|
+
credentials.** It knows one public HTTPS URL and nothing else. The email
|
|
180
|
+
provider's API key lives only in the backend's environment variables.
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
vasanth CLI ──HTTPS──▶ your backend ──API──▶ email provider ──▶ your inbox
|
|
184
|
+
(public, (holds the
|
|
185
|
+
no secrets) secret)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
What is sent: the message he typed, and nothing else. No files, contacts,
|
|
189
|
+
location, system information, credentials, or identifiers. No analytics, no
|
|
190
|
+
tracking, no logging to disk. Every other feature works with the network
|
|
191
|
+
unplugged, and a privacy notice is shown before anything leaves the machine.
|
|
192
|
+
|
|
193
|
+
If the backend can't be reached, the CLI says the message was **not**
|
|
194
|
+
delivered. It only claims success on a confirmed 2xx response.
|
|
195
|
+
|
|
196
|
+
### Running the backend
|
|
197
|
+
|
|
198
|
+
See [`backend/README.md`](backend/README.md) for the full deployment guide.
|
|
199
|
+
The short version:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
cd backend
|
|
203
|
+
pip install -r requirements.txt
|
|
204
|
+
cp .env.example .env # then fill in your real values
|
|
205
|
+
uvicorn app.main:app --reload
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Then point the CLI at it while testing:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
VASANTH_ENDPOINT=http://127.0.0.1:8000/api/message vasanth-love
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Before publishing, set the deployed URL in `src/vasanth/api.py`:
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
DEFAULT_ENDPOINT = "https://your-backend.example.com/api/message"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Never commit
|
|
221
|
+
|
|
222
|
+
`.env` is in `.gitignore` and must stay there. `.env.example` holds the shape
|
|
223
|
+
of the configuration, never the values.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Privacy
|
|
228
|
+
|
|
229
|
+
* No telemetry, no analytics, no tracking, no identifiers.
|
|
230
|
+
* Nothing is written to disk. No config file, no history, no cache.
|
|
231
|
+
* No network access at all unless he chooses to send a message and confirms.
|
|
232
|
+
* Uninstalling removes everything: `pip uninstall vasanth-love`.
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.18"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vasanth-love"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "A small, quiet terminal experience."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "Made with a lot of thought" }]
|
|
13
|
+
keywords = ["cli", "terminal", "letter"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 5 - Production/Stable",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: End Users/Desktop",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Topic :: Artistic Software",
|
|
26
|
+
]
|
|
27
|
+
dependencies = []
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
vasanth-love = "vasanth.cli:main"
|
|
31
|
+
vasanth = "vasanth.cli:main"
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = ["pytest>=7.0"]
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["src/vasanth"]
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.sdist]
|
|
40
|
+
include = ["/src/vasanth", "/tests", "/README.md", "/LICENSE"]
|
|
41
|
+
exclude = ["/backend", "*.env", ".env*"]
|
|
42
|
+
|
|
43
|
+
[tool.pytest.ini_options]
|
|
44
|
+
pythonpath = ["src"]
|
|
45
|
+
testpaths = ["tests"]
|