birthdays-cli 0.1.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.
- birthdays_cli-0.1.0/.gitignore +223 -0
- birthdays_cli-0.1.0/LICENSE +21 -0
- birthdays_cli-0.1.0/PKG-INFO +134 -0
- birthdays_cli-0.1.0/README.md +109 -0
- birthdays_cli-0.1.0/examples/contacts.vcf +56 -0
- birthdays_cli-0.1.0/examples/demo.gif +0 -0
- birthdays_cli-0.1.0/examples/demo.tape +59 -0
- birthdays_cli-0.1.0/pyproject.toml +58 -0
- birthdays_cli-0.1.0/src/birthdays/__init__.py +32 -0
- birthdays_cli-0.1.0/src/birthdays/__main__.py +4 -0
- birthdays_cli-0.1.0/src/birthdays/birthdays.py +979 -0
- birthdays_cli-0.1.0/src/birthdays/emojis.py +132 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Local tests
|
|
2
|
+
tests/untracked
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[codz]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
.Python
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
wheels/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
MANIFEST
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.nox/
|
|
46
|
+
.coverage
|
|
47
|
+
.coverage.*
|
|
48
|
+
.cache
|
|
49
|
+
nosetests.xml
|
|
50
|
+
coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py.cover
|
|
53
|
+
*.lcov
|
|
54
|
+
.hypothesis/
|
|
55
|
+
.pytest_cache/
|
|
56
|
+
cover/
|
|
57
|
+
|
|
58
|
+
# Translations
|
|
59
|
+
*.mo
|
|
60
|
+
*.pot
|
|
61
|
+
|
|
62
|
+
# Django stuff:
|
|
63
|
+
*.log
|
|
64
|
+
local_settings.py
|
|
65
|
+
db.sqlite3
|
|
66
|
+
db.sqlite3-journal
|
|
67
|
+
|
|
68
|
+
# Flask stuff:
|
|
69
|
+
instance/
|
|
70
|
+
.webassets-cache
|
|
71
|
+
|
|
72
|
+
# Scrapy stuff:
|
|
73
|
+
.scrapy
|
|
74
|
+
|
|
75
|
+
# Sphinx documentation
|
|
76
|
+
docs/_build/
|
|
77
|
+
|
|
78
|
+
# PyBuilder
|
|
79
|
+
.pybuilder/
|
|
80
|
+
target/
|
|
81
|
+
|
|
82
|
+
# Jupyter Notebook
|
|
83
|
+
.ipynb_checkpoints
|
|
84
|
+
|
|
85
|
+
# IPython
|
|
86
|
+
profile_default/
|
|
87
|
+
ipython_config.py
|
|
88
|
+
|
|
89
|
+
# pyenv
|
|
90
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
91
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
92
|
+
# .python-version
|
|
93
|
+
|
|
94
|
+
# pipenv
|
|
95
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
96
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
97
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
98
|
+
# install all needed dependencies.
|
|
99
|
+
# Pipfile.lock
|
|
100
|
+
|
|
101
|
+
# UV
|
|
102
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
103
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
104
|
+
# commonly ignored for libraries.
|
|
105
|
+
# uv.lock
|
|
106
|
+
|
|
107
|
+
# poetry
|
|
108
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
109
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
110
|
+
# commonly ignored for libraries.
|
|
111
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
112
|
+
# poetry.lock
|
|
113
|
+
# poetry.toml
|
|
114
|
+
|
|
115
|
+
# pdm
|
|
116
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
117
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
118
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
119
|
+
# pdm.lock
|
|
120
|
+
# pdm.toml
|
|
121
|
+
.pdm-python
|
|
122
|
+
.pdm-build/
|
|
123
|
+
|
|
124
|
+
# pixi
|
|
125
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
126
|
+
# pixi.lock
|
|
127
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
128
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
129
|
+
.pixi/*
|
|
130
|
+
!.pixi/config.toml
|
|
131
|
+
|
|
132
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
133
|
+
__pypackages__/
|
|
134
|
+
|
|
135
|
+
# Celery stuff
|
|
136
|
+
celerybeat-schedule*
|
|
137
|
+
celerybeat.pid
|
|
138
|
+
|
|
139
|
+
# Redis
|
|
140
|
+
*.rdb
|
|
141
|
+
*.aof
|
|
142
|
+
*.pid
|
|
143
|
+
|
|
144
|
+
# RabbitMQ
|
|
145
|
+
mnesia/
|
|
146
|
+
rabbitmq/
|
|
147
|
+
rabbitmq-data/
|
|
148
|
+
|
|
149
|
+
# ActiveMQ
|
|
150
|
+
activemq-data/
|
|
151
|
+
|
|
152
|
+
# SageMath parsed files
|
|
153
|
+
*.sage.py
|
|
154
|
+
|
|
155
|
+
# Environments
|
|
156
|
+
.env
|
|
157
|
+
.envrc
|
|
158
|
+
.venv
|
|
159
|
+
env/
|
|
160
|
+
venv/
|
|
161
|
+
ENV/
|
|
162
|
+
env.bak/
|
|
163
|
+
venv.bak/
|
|
164
|
+
|
|
165
|
+
# Spyder project settings
|
|
166
|
+
.spyderproject
|
|
167
|
+
.spyproject
|
|
168
|
+
|
|
169
|
+
# Rope project settings
|
|
170
|
+
.ropeproject
|
|
171
|
+
|
|
172
|
+
# mkdocs documentation
|
|
173
|
+
/site
|
|
174
|
+
|
|
175
|
+
# mypy
|
|
176
|
+
.mypy_cache/
|
|
177
|
+
.dmypy.json
|
|
178
|
+
dmypy.json
|
|
179
|
+
|
|
180
|
+
# Pyre type checker
|
|
181
|
+
.pyre/
|
|
182
|
+
|
|
183
|
+
# pytype static type analyzer
|
|
184
|
+
.pytype/
|
|
185
|
+
|
|
186
|
+
# Cython debug symbols
|
|
187
|
+
cython_debug/
|
|
188
|
+
|
|
189
|
+
# PyCharm
|
|
190
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
191
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
192
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
193
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
194
|
+
# .idea/
|
|
195
|
+
|
|
196
|
+
# Abstra
|
|
197
|
+
# Abstra is an AI-powered process automation framework.
|
|
198
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
199
|
+
# Learn more at https://abstra.io/docs
|
|
200
|
+
.abstra/
|
|
201
|
+
|
|
202
|
+
# Visual Studio Code
|
|
203
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
204
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
205
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
206
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
207
|
+
# .vscode/
|
|
208
|
+
# Temporary file for partial code execution
|
|
209
|
+
tempCodeRunnerFile.py
|
|
210
|
+
|
|
211
|
+
# Ruff stuff:
|
|
212
|
+
.ruff_cache/
|
|
213
|
+
|
|
214
|
+
# PyPI configuration file
|
|
215
|
+
.pypirc
|
|
216
|
+
|
|
217
|
+
# Marimo
|
|
218
|
+
marimo/_static/
|
|
219
|
+
marimo/_lsp/
|
|
220
|
+
__marimo__/
|
|
221
|
+
|
|
222
|
+
# Streamlit
|
|
223
|
+
.streamlit/secrets.toml
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Volodymyr Horshenin
|
|
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,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: birthdays-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A command-line utility for displaying and managing birthdays from JSON- or vCard-based contacts.
|
|
5
|
+
Project-URL: Repository, https://github.com/l1asis/birthdays.git
|
|
6
|
+
Project-URL: Issues, https://github.com/l1asis/birthdays/issues
|
|
7
|
+
Author: Volodymyr Horshenin
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: address-book,birthday-tracker,birthdays,calendar,cli,command-line,contacts,vcard,vcf
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: platformdirs>=4.0.0
|
|
23
|
+
Requires-Dist: python-dateutil>=2.8.2
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# birthdays
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
[](https://pypi.org/project/birthdays-cli/)
|
|
31
|
+
[](https://pypi.org/project/birthdays-cli/)
|
|
32
|
+

|
|
33
|
+
[](https://opensource.org/licenses/MIT)
|
|
34
|
+
[](https://github.com/astral-sh/ruff)
|
|
35
|
+
|
|
36
|
+
`birthdays` is a robust Python command-line tool designed to conveniently manage, track, and celebrate your contacts' birthdays.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- **Customizable Sorting:** List birthdays exactly how you want to see them (by upcoming, recent, age, name, or date)
|
|
41
|
+
- **CRUD Operations:** Easily `add`, `edit`, and `delete` entries. The deletion and edit commands feature a convenient fuzzy search so you don't have to type out exact names
|
|
42
|
+
- **Smart Imports:** Import contacts directly from `.vcf` vCard files or JSON databases
|
|
43
|
+
- **Interactive Merging:** During imports, the CLI intelligently detects duplicates or data collisions and prompts you to safely merge them
|
|
44
|
+
- **Leapling Support:** Configure how leap year birthdays (February 29th) are handled in non-leap years, choosing to celebrate either the day before or the day after
|
|
45
|
+
- **Festive UI:** Every date is assigned a unique, deterministic emoji to keep the terminal vibe bright and colorful
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- Python 3.11+
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
Install the package from PyPI using your favorite package management tool such as pip, pipx, or uv:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install birthdays-cli
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or install the latest version from source:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git clone https://github.com/l1asis/birthdays.git
|
|
63
|
+
cd birthdays
|
|
64
|
+
pip install .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Usage
|
|
68
|
+
|
|
69
|
+
`birthdays` uses simple subcommands to organize different operations. You can append `--help` to any command to see its available arguments.
|
|
70
|
+
|
|
71
|
+
### Listing Birthdays
|
|
72
|
+
|
|
73
|
+
> [!NOTE]
|
|
74
|
+
> By default, this sorts by upcoming birthdays in descending order so the most immediate celebrations are right at your cursor.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
birthdays list
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Options:**
|
|
81
|
+
|
|
82
|
+
- `--sort`: Choose from `name`, `date`, `upcoming`, `recent`, or `age`.
|
|
83
|
+
- `--order`: Choose `asc` or `desc`.
|
|
84
|
+
- `-f`, `--file`: Temporarily read and display birthdays directly from a `.vcf` or `.json` file without modifying your local database.
|
|
85
|
+
|
|
86
|
+
### Adding an Entry
|
|
87
|
+
|
|
88
|
+
> [!NOTE]
|
|
89
|
+
> The date can be formatted as `YYYY-MM-DD`, or simply `MM-DD` if the year is unknown.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
birthdays add "John Doe" 1990-05-14 --note "Loves chocolate cake"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Editing an Entry
|
|
96
|
+
|
|
97
|
+
> [!NOTE]
|
|
98
|
+
> You can use either the name or UUID. You only need to pass the flags for the specific data you want to change.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
birthdays edit "John Doe" --date 1991-05-14
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Deleting an Entry
|
|
105
|
+
|
|
106
|
+
> [!TIP]
|
|
107
|
+
> The CLI uses fuzzy matching, so typing a partial name usually works! Append `-y` to skip the confirmation prompt.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
birthdays delete "John Doe"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Importing Contacts
|
|
114
|
+
|
|
115
|
+
> [!TIP]
|
|
116
|
+
> The interactive prompt will guide you through any data collisions. Append `-y` to automatically skip these prompts and blindly merge safe entries.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
birthdays import ./contacts.vcf
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Contributing
|
|
123
|
+
|
|
124
|
+
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
|
125
|
+
|
|
126
|
+
1. Fork the Project
|
|
127
|
+
2. Create your Feature Branch (`git checkout -b feat/amazing-feature`)
|
|
128
|
+
3. Commit your Changes (`git commit -m 'feat: ✨ add some amazing-feature'`)
|
|
129
|
+
4. Push to the Branch (`git push origin feat/amazing-feature`)
|
|
130
|
+
5. Open a Pull Request
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# birthdays
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/birthdays-cli/)
|
|
6
|
+
[](https://pypi.org/project/birthdays-cli/)
|
|
7
|
+

|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://github.com/astral-sh/ruff)
|
|
10
|
+
|
|
11
|
+
`birthdays` is a robust Python command-line tool designed to conveniently manage, track, and celebrate your contacts' birthdays.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Customizable Sorting:** List birthdays exactly how you want to see them (by upcoming, recent, age, name, or date)
|
|
16
|
+
- **CRUD Operations:** Easily `add`, `edit`, and `delete` entries. The deletion and edit commands feature a convenient fuzzy search so you don't have to type out exact names
|
|
17
|
+
- **Smart Imports:** Import contacts directly from `.vcf` vCard files or JSON databases
|
|
18
|
+
- **Interactive Merging:** During imports, the CLI intelligently detects duplicates or data collisions and prompts you to safely merge them
|
|
19
|
+
- **Leapling Support:** Configure how leap year birthdays (February 29th) are handled in non-leap years, choosing to celebrate either the day before or the day after
|
|
20
|
+
- **Festive UI:** Every date is assigned a unique, deterministic emoji to keep the terminal vibe bright and colorful
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- Python 3.11+
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Install the package from PyPI using your favorite package management tool such as pip, pipx, or uv:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install birthdays-cli
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or install the latest version from source:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/l1asis/birthdays.git
|
|
38
|
+
cd birthdays
|
|
39
|
+
pip install .
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
`birthdays` uses simple subcommands to organize different operations. You can append `--help` to any command to see its available arguments.
|
|
45
|
+
|
|
46
|
+
### Listing Birthdays
|
|
47
|
+
|
|
48
|
+
> [!NOTE]
|
|
49
|
+
> By default, this sorts by upcoming birthdays in descending order so the most immediate celebrations are right at your cursor.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
birthdays list
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Options:**
|
|
56
|
+
|
|
57
|
+
- `--sort`: Choose from `name`, `date`, `upcoming`, `recent`, or `age`.
|
|
58
|
+
- `--order`: Choose `asc` or `desc`.
|
|
59
|
+
- `-f`, `--file`: Temporarily read and display birthdays directly from a `.vcf` or `.json` file without modifying your local database.
|
|
60
|
+
|
|
61
|
+
### Adding an Entry
|
|
62
|
+
|
|
63
|
+
> [!NOTE]
|
|
64
|
+
> The date can be formatted as `YYYY-MM-DD`, or simply `MM-DD` if the year is unknown.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
birthdays add "John Doe" 1990-05-14 --note "Loves chocolate cake"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Editing an Entry
|
|
71
|
+
|
|
72
|
+
> [!NOTE]
|
|
73
|
+
> You can use either the name or UUID. You only need to pass the flags for the specific data you want to change.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
birthdays edit "John Doe" --date 1991-05-14
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Deleting an Entry
|
|
80
|
+
|
|
81
|
+
> [!TIP]
|
|
82
|
+
> The CLI uses fuzzy matching, so typing a partial name usually works! Append `-y` to skip the confirmation prompt.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
birthdays delete "John Doe"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Importing Contacts
|
|
89
|
+
|
|
90
|
+
> [!TIP]
|
|
91
|
+
> The interactive prompt will guide you through any data collisions. Append `-y` to automatically skip these prompts and blindly merge safe entries.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
birthdays import ./contacts.vcf
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Contributing
|
|
98
|
+
|
|
99
|
+
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
|
100
|
+
|
|
101
|
+
1. Fork the Project
|
|
102
|
+
2. Create your Feature Branch (`git checkout -b feat/amazing-feature`)
|
|
103
|
+
3. Commit your Changes (`git commit -m 'feat: ✨ add some amazing-feature'`)
|
|
104
|
+
4. Push to the Branch (`git push origin feat/amazing-feature`)
|
|
105
|
+
5. Open a Pull Request
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
BEGIN:VCARD
|
|
2
|
+
VERSION:3.0
|
|
3
|
+
FN:Amélie Laurent
|
|
4
|
+
BDAY:1990-05-14
|
|
5
|
+
NOTE:Met at the UX conference in Paris. Always brings great coffee.
|
|
6
|
+
END:VCARD
|
|
7
|
+
|
|
8
|
+
BEGIN:VCARD
|
|
9
|
+
VERSION:3.0
|
|
10
|
+
FN:Hiroshi Tanaka
|
|
11
|
+
BDAY:1992-02-29
|
|
12
|
+
NOTE:University roommate. Leapling! 🐸
|
|
13
|
+
END:VCARD
|
|
14
|
+
|
|
15
|
+
BEGIN:VCARD
|
|
16
|
+
VERSION:3.0
|
|
17
|
+
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=D0=94=D1=96=D0=B4=D1=83=D1=81=D1=8C =D0=86=D0=B2=D0=B0=D0=BD
|
|
18
|
+
BDAY:1955-01-07
|
|
19
|
+
NOTE;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:The absolute best grandfather.=20=
|
|
20
|
+
Always tells the greatest stories about his youth.
|
|
21
|
+
END:VCARD
|
|
22
|
+
|
|
23
|
+
BEGIN:VCARD
|
|
24
|
+
VERSION:3.0
|
|
25
|
+
FN:María José García
|
|
26
|
+
BDAY:--10-31
|
|
27
|
+
NOTE:Halloween birthday party organizer.
|
|
28
|
+
END:VCARD
|
|
29
|
+
|
|
30
|
+
BEGIN:VCARD
|
|
31
|
+
VERSION:3.0
|
|
32
|
+
FN:Fatima Al-Sayed
|
|
33
|
+
BDAY:1988-08-12
|
|
34
|
+
NOTE:Project manager for the backend migration.
|
|
35
|
+
Needs to be reminded about the server timezone changes.
|
|
36
|
+
END:VCARD
|
|
37
|
+
|
|
38
|
+
BEGIN:VCARD
|
|
39
|
+
VERSION:3.0
|
|
40
|
+
FN:Kwame Osei
|
|
41
|
+
BDAY:--03-15
|
|
42
|
+
NOTE:Gym buddy.
|
|
43
|
+
END:VCARD
|
|
44
|
+
|
|
45
|
+
BEGIN:VCARD
|
|
46
|
+
VERSION:3.0
|
|
47
|
+
FN:Mateusz Kowalski
|
|
48
|
+
BDAY:1995-11-11
|
|
49
|
+
NOTE:Brings the best pierogi to the office potlucks.
|
|
50
|
+
END:VCARD
|
|
51
|
+
|
|
52
|
+
BEGIN:VCARD
|
|
53
|
+
VERSION:3.0
|
|
54
|
+
FN:Priya Sharma
|
|
55
|
+
BDAY:1999-07-21
|
|
56
|
+
END:VCARD
|
|
Binary file
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Output settings
|
|
2
|
+
Output examples/demo.gif
|
|
3
|
+
Set FontSize 15
|
|
4
|
+
Set Width 915
|
|
5
|
+
Set Height 600
|
|
6
|
+
Set Padding 30
|
|
7
|
+
Set Theme "Dracula"
|
|
8
|
+
Set WindowBar Colorful
|
|
9
|
+
|
|
10
|
+
# Hidden setup
|
|
11
|
+
Hide
|
|
12
|
+
Type "export DEBIAN_FRONTEND=noninteractive"
|
|
13
|
+
Enter
|
|
14
|
+
|
|
15
|
+
# Install base requirements
|
|
16
|
+
# DEBUG: "> examples/setup.log 2>&1"
|
|
17
|
+
Type "apt update && apt install -y python3 python3-pip python3-venv"
|
|
18
|
+
Enter
|
|
19
|
+
Sleep 60s
|
|
20
|
+
|
|
21
|
+
# Download the Charm's gum
|
|
22
|
+
Type "apt update && apt -y install gum"
|
|
23
|
+
Enter
|
|
24
|
+
Sleep 45s
|
|
25
|
+
|
|
26
|
+
# Install the birthdays package
|
|
27
|
+
Type "pip3 install . --break-system-packages"
|
|
28
|
+
Enter
|
|
29
|
+
Sleep 15s
|
|
30
|
+
|
|
31
|
+
Type "clear"
|
|
32
|
+
Enter
|
|
33
|
+
Show
|
|
34
|
+
|
|
35
|
+
# Show the fake contacts data
|
|
36
|
+
Type "gum pager < examples/contacts.vcf"
|
|
37
|
+
Sleep 500ms
|
|
38
|
+
Enter
|
|
39
|
+
Sleep 500ms
|
|
40
|
+
|
|
41
|
+
# Scroll down to view more contacts
|
|
42
|
+
Down@40ms 35
|
|
43
|
+
Sleep 500ms
|
|
44
|
+
|
|
45
|
+
# Exit the pager so we can run commands again
|
|
46
|
+
Type "q"
|
|
47
|
+
Sleep 500ms
|
|
48
|
+
|
|
49
|
+
# Run the import command
|
|
50
|
+
Type "birthdays import examples/contacts.vcf"
|
|
51
|
+
Sleep 500ms
|
|
52
|
+
Enter
|
|
53
|
+
Sleep 1s
|
|
54
|
+
|
|
55
|
+
# Show the list view
|
|
56
|
+
Type "birthdays list --sort upcoming"
|
|
57
|
+
Sleep 500ms
|
|
58
|
+
Enter
|
|
59
|
+
Sleep 6s
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "birthdays-cli"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"python-dateutil>=2.8.2",
|
|
10
|
+
"platformdirs>=4.0.0",
|
|
11
|
+
]
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "Volodymyr Horshenin"}
|
|
15
|
+
]
|
|
16
|
+
description = "A command-line utility for displaying and managing birthdays from JSON- or vCard-based contacts."
|
|
17
|
+
readme = "README.md"
|
|
18
|
+
license = "MIT"
|
|
19
|
+
license-files = ["LICEN[CS]E*"]
|
|
20
|
+
keywords = [
|
|
21
|
+
"cli", "command-line", "birthdays", "birthday-tracker",
|
|
22
|
+
"contacts", "vcard", "vcf", "calendar", "address-book"
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
|
|
27
|
+
"Intended Audience :: End Users/Desktop",
|
|
28
|
+
"Topic :: Utilities",
|
|
29
|
+
"Environment :: Console",
|
|
30
|
+
|
|
31
|
+
"Operating System :: OS Independent",
|
|
32
|
+
|
|
33
|
+
"Programming Language :: Python :: 3",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Programming Language :: Python :: 3.13",
|
|
37
|
+
"Programming Language :: Python :: 3.14",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Repository = "https://github.com/l1asis/birthdays.git"
|
|
42
|
+
Issues = "https://github.com/l1asis/birthdays/issues"
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
birthdays = "birthdays.birthdays:main"
|
|
46
|
+
bday = "birthdays.birthdays:main"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["src/birthdays"]
|
|
50
|
+
|
|
51
|
+
[tool.ruff]
|
|
52
|
+
target-version = "py311"
|
|
53
|
+
|
|
54
|
+
[tool.ruff.lint]
|
|
55
|
+
select = ["E", "F", "I"]
|
|
56
|
+
|
|
57
|
+
[tool.ruff.lint.isort]
|
|
58
|
+
combine-as-imports = true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
__version__ = version("birthdays-cli")
|
|
5
|
+
except PackageNotFoundError:
|
|
6
|
+
__version__ = "unknown"
|
|
7
|
+
|
|
8
|
+
__about__ = rf"""
|
|
9
|
+
✦ ̲ ✦ ✦ 🔥 ✦
|
|
10
|
+
' (o) . 🔥 /^\ 🔥 ✦
|
|
11
|
+
╱:╲ __/^\____|_|____/^\__ *
|
|
12
|
+
+ ✦ ╱.:|╲ ✦ / |_| |_| \
|
|
13
|
+
╱..::|╲ \_____________________/ ✦
|
|
14
|
+
╱...:::|╲ ✦ | . . . . . . . . . |
|
|
15
|
+
. (_________) | -~-~-~-~-~-~-~-~-~- | ✦
|
|
16
|
+
╭╯ ╭─╯ | ~-~-~-~-~-~-~-~-~-~ | *
|
|
17
|
+
╰────────╯ *_____________________*
|
|
18
|
+
|
|
19
|
+
birthdays: Your birthday list is in your hands only.
|
|
20
|
+
----------------------------------------------------------
|
|
21
|
+
Version: {__version__}
|
|
22
|
+
Author: Volodymyr Horshenin (@l1asis)
|
|
23
|
+
License: MIT
|
|
24
|
+
Repository: https://github.com/l1asis/birthdays
|
|
25
|
+
|
|
26
|
+
Description:
|
|
27
|
+
A command-line utility for displaying and managing birthdays
|
|
28
|
+
from JSON- or vCard-based contacts.
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
Run `python -m birthdays --help` to see available commands.
|
|
32
|
+
"""
|