Cabinet
Cabinet is a lightweight, flexible data organization tool that lets you manage your data with the simplicity of a JSON file or the power of MongoDB - your choice. It also lets you log messages to a file of your choice and send mail from the terminal.
✨ Features
- More easily access your data across multiple projects
- More easily log messages to the file of your choice
- Edit MongoDB as though it were a JSON file
- Log to a file/directory of your choice without having to configure
logger
each time - Easily send mail from the terminal
Installation and Setup
CLI and Python Library
pip install cabinet
cabinet --config
CLI Only
curl -s https://api.github.com/repos/tylerjwoodfin/cabinet/releases/latest \
| grep "browser_download_url" \
| cut -d '"' -f 4 \
| xargs curl -L -o cabinet.pex
sudo mv cabinet.pex /usr/local/bin/cabinet
Dependencies
Outside of the standard Python library, the following packages will be installed as part of pip install cabinet
:
pymongo
: Provides the MongoDB client and related errors.prompt_toolkit
: Provides functionality for command-line interfaces.
Structure
- Data is stored in
~/.cabinet/data.json
or MongoDB
- data from MongoDB is interacted with as if it were a JSON file
- cache is written when retrieving data.
- if cache is older than 1 hour, it is refreshed; otherwise, data is pulled from cache by default
- Logs are written to
~/.cabinet/log/LOG_DAILY_YYYY-MM-DD
by default
- You can change this to something other than
~/.cabinet/log
as needed by setting/modifying ~/.config/cabinet/config.json
-> path_dir_log
CLI usage
Usage: cabinet [OPTIONS]
Options:
-h, --help Show this help message and exit
--configure, -config Configure
--export Export the data in MongoDB to a JSON file
--edit, -e Edit MongoDB in the default editor as a JSON file
--edit-file, -ef Edit a specific file
--no-create (for -ef) Do not create file if it does not exist
--get, -g Get a property from MongoDB (nesting supported)
--put, -p Put a property into MongoDB (nesting supported)
--remove, -rm Removes a property from MongoDB
--get-file Returns the file specified
--strip (for --get-file) Whether to strip file content whitespace
--log, -l Log a message to the default location
--level (for -l) Log level [debug, info, warn, error, critical]
-v, --version show version number and exit
Mail:
--mail Sends an email
--subject SUBJECT, -s SUBJECT
Email subject
--body BODY, -b BODY Email body
--to TO_ADDR, -t TO_ADDR
Configuration
-
Upon first launch, the tool will prompt you to enter your MongoDB credentials, as well as
the cluster name and Database name. These are stored in ~/.config/cabinet/config.json
.
-
You will be asked to configure your default editor from the list of available editors on
your system. If this step is skipped, or an error occurs, nano
will be used.
You can change this with cabinet --config
and modifying the editor
attribute.
edit_file() shortcuts
- see example below to enable something like
cabinet -ef shopping
from the terminal
- rather than
cabinet -ef "/home/{username}/path/to/shopping_list.md"
- or
cabinet.Cabinet().edit("shopping")
- rather than
cabinet.Cabinet().edit("/home/{username}/path/to/whatever.md")
file:
# example only; these commands will be unique to your setup
{
"path": {
"edit": {
"shopping": {
"value": "/home/{username}/path/to/whatever.md",
},
"todo": {
"value": "/home/{username}/path/to/whatever.md",
}
}
}
}
set from terminal:
cabinet -p edit shopping value "/home/{username}/path/to/whatever.md"
cabinet -p edit todo value "/home/{username}/path/to/whatever.md"
mail
- It is NEVER a good idea to store your password openly either locally or in MongoDB; for this reason, I recommend a "throwaway" account that is only used for sending emails, such as a custom domain email.
- Gmail and most other mainstream email providers won't work with this; for support, search for sending mail from your email provider with
smtplib
. - In Cabinet (
cabinet -e
), add the email
object to make your settings file look like this example:
file:
{
"email": {
"from": "throwaway@example.com",
"from_pw": "example",
"from_name": "Cabinet (or other name of your choice)",
"to": "destination@protonmail.com",
"smtp_server": "example.com",
"imap_server": "example.com",
"port": 123
}
}
set from terminal:
cabinet -p email from throwaway@example.com
cabinet -p email from_pw example
...
Examples
put
python:
from cabinet import Cabinet
cab = Cabinet()
cab.put("employee", "Tyler", "salary", 7.25)
or terminal:
cabinet -p employee Tyler salary 7.25
results in this structure in MongoDB:
{
"employee": {
"Tyler": {
"salary": 7.25 # or "7.25" if done from terminal
}
}
}
get
python:
from cabinet import Cabinet
cab = Cabinet()
print(cab.get("employee", "Tyler", "salary"))
or terminal:
cabinet -g employee Tyler salary
- optional:
--force-cache-update
to force a cache update
results in:
7.25
remove
python:
from cabinet import Cabinet
cab = Cabinet()
cab.remove("employee", "Tyler", "salary")
or terminal:
cabinet -rm employee Tyler salary
results in this structure in MongoDB:
{
"employee": {
"tyler": {}
}
}
edit
terminal:
cabinet -e
cabinet --edit
cabinet -e --editor=code
edit_file
python:
from cabinet import Cabinet
cab = Cabinet()
cab.edit("shopping")
cab.edit("/path/to/shopping.md")
cab.edit("/path/to/shopping.md", editor="nvim")
terminal:
cabinet -ef shoppping
cabinet -ef "/path/to/shopping.md"
mail
python:
from cabinet import Mail
mail = Mail()
mail.send('Test Subject', 'Test Body')
terminal:
cabinet --mail --subject "Test Subject" --body "Test Body"
cabinet --mail -s "Test Subject" -b "Test Body"
log
python:
from cabinet import Cabinet
cab = Cabinet()
cab.log("Connection timed out")
cab.log("This function hit a breakpoint", level="debug")
cab.log("Looks like the server is on fire", level="critical")
cab.log("This is fine", level="info")
cab.log("30", log_name="LOG_TEMPERATURE")
cab.log("30", log_name="LOG_TEMPERATURE", log_folder_path="/home/{username}/weather")
terminal:
cabinet -l "Connection timed out"
cabinet --log "Connection timed out"
cabinet --log "Server is on fire" --level "critical"
Disclaimers
- Although I've done quite a bit of testing, I can't guarantee everything that works on my machine will work on yours. Always back up your data to multiple places to avoid data loss.
- If you find any issues, please contact me... or get your hands dirty and raise a PR!
Author