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.
@@ -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
+ ![birthdays GIF demo](https://raw.githubusercontent.com/l1asis/birthdays/refs/heads/main/examples/demo.gif)
29
+
30
+ [![PyPI Version](https://img.shields.io/pypi/v/birthdays-cli.svg)](https://pypi.org/project/birthdays-cli/)
31
+ [![PyPI Python version](https://img.shields.io/pypi/pyversions/birthdays-cli.svg)](https://pypi.org/project/birthdays-cli/)
32
+ ![PyPI downloads](https://img.shields.io/pypi/dm/birthdays-cli)
33
+ [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
34
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](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
+ ![birthdays GIF demo](https://raw.githubusercontent.com/l1asis/birthdays/refs/heads/main/examples/demo.gif)
4
+
5
+ [![PyPI Version](https://img.shields.io/pypi/v/birthdays-cli.svg)](https://pypi.org/project/birthdays-cli/)
6
+ [![PyPI Python version](https://img.shields.io/pypi/pyversions/birthdays-cli.svg)](https://pypi.org/project/birthdays-cli/)
7
+ ![PyPI downloads](https://img.shields.io/pypi/dm/birthdays-cli)
8
+ [![License](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
9
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](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
+ """
@@ -0,0 +1,4 @@
1
+ from .birthdays import main
2
+
3
+ if __name__ == "__main__":
4
+ main()