reckn 1.0.0__py3-none-any.whl
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.
- reckn/__init__.py +3 -0
- reckn/__main__.py +110 -0
- reckn/app.py +1679 -0
- reckn/assets/reckn.svg +28 -0
- reckn/clipboard.py +121 -0
- reckn/currencies.py +374 -0
- reckn/dates.py +806 -0
- reckn/evaluator.py +1150 -0
- reckn/highlighter.py +208 -0
- reckn/pad.py +123 -0
- reckn/parser.py +269 -0
- reckn/percentages.py +191 -0
- reckn/test_repl.py +78 -0
- reckn/units.py +647 -0
- reckn/value.py +218 -0
- reckn-1.0.0.dist-info/METADATA +203 -0
- reckn-1.0.0.dist-info/RECORD +21 -0
- reckn-1.0.0.dist-info/WHEEL +5 -0
- reckn-1.0.0.dist-info/entry_points.txt +2 -0
- reckn-1.0.0.dist-info/licenses/LICENSE +21 -0
- reckn-1.0.0.dist-info/top_level.txt +1 -0
reckn/__init__.py
ADDED
reckn/__main__.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Entry point for running Reckn as a module."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from . import __version__
|
|
7
|
+
from .pad import list_pads, load_pad, PADS_DIR
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def install_desktop():
|
|
11
|
+
"""Install desktop entry and icon for Linux desktop integration."""
|
|
12
|
+
import shutil
|
|
13
|
+
import subprocess
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
pkg_dir = Path(__file__).parent
|
|
17
|
+
icon_src = pkg_dir / "assets" / "reckn.svg"
|
|
18
|
+
|
|
19
|
+
if not icon_src.exists():
|
|
20
|
+
print(f"Error: icon not found at {icon_src}", file=sys.stderr)
|
|
21
|
+
sys.exit(1)
|
|
22
|
+
|
|
23
|
+
# Install icon
|
|
24
|
+
icon_dir = Path.home() / ".local" / "share" / "icons" / "hicolor" / "scalable" / "apps"
|
|
25
|
+
icon_dir.mkdir(parents=True, exist_ok=True)
|
|
26
|
+
shutil.copy2(icon_src, icon_dir / "reckn.svg")
|
|
27
|
+
print(f" Icon -> {icon_dir / 'reckn.svg'}")
|
|
28
|
+
|
|
29
|
+
# Generate and install .desktop file
|
|
30
|
+
reckn_exe = shutil.which("reckn") or "reckn"
|
|
31
|
+
desktop_content = (
|
|
32
|
+
"[Desktop Entry]\n"
|
|
33
|
+
"Name=Reckn\n"
|
|
34
|
+
"Comment=A calculator notepad for the terminal\n"
|
|
35
|
+
f"Exec={reckn_exe}\n"
|
|
36
|
+
"Icon=reckn\n"
|
|
37
|
+
"Terminal=true\n"
|
|
38
|
+
"Type=Application\n"
|
|
39
|
+
"Categories=Utility;Calculator;\n"
|
|
40
|
+
"Keywords=calculator;notepad;math;units;currency;\n"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
desktop_dir = Path.home() / ".local" / "share" / "applications"
|
|
44
|
+
desktop_dir.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
desktop_file = desktop_dir / "reckn.desktop"
|
|
46
|
+
desktop_file.write_text(desktop_content)
|
|
47
|
+
print(f" Desktop entry -> {desktop_file}")
|
|
48
|
+
|
|
49
|
+
# Update desktop database (best effort)
|
|
50
|
+
try:
|
|
51
|
+
subprocess.run(["update-desktop-database", str(desktop_dir)],
|
|
52
|
+
capture_output=True, check=False)
|
|
53
|
+
except FileNotFoundError:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
print("Done. Reckn should now appear in your application menu.")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def main():
|
|
60
|
+
parser = argparse.ArgumentParser(
|
|
61
|
+
prog="reckn",
|
|
62
|
+
description="Reckn - A calculator notepad for the terminal"
|
|
63
|
+
)
|
|
64
|
+
parser.add_argument(
|
|
65
|
+
"pad_name",
|
|
66
|
+
nargs="?",
|
|
67
|
+
help="Name of pad to open"
|
|
68
|
+
)
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"--version", "-V",
|
|
71
|
+
action="version",
|
|
72
|
+
version=f"reckn {__version__}"
|
|
73
|
+
)
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"--list", "-l",
|
|
76
|
+
action="store_true",
|
|
77
|
+
help="List all saved pads"
|
|
78
|
+
)
|
|
79
|
+
parser.add_argument(
|
|
80
|
+
"--install-desktop",
|
|
81
|
+
action="store_true",
|
|
82
|
+
help="Install desktop entry and icon (Linux)"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
args = parser.parse_args()
|
|
86
|
+
|
|
87
|
+
if args.install_desktop:
|
|
88
|
+
install_desktop()
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
if args.list:
|
|
92
|
+
pads = list_pads()
|
|
93
|
+
if not pads:
|
|
94
|
+
print(f"No saved pads found in {PADS_DIR}")
|
|
95
|
+
else:
|
|
96
|
+
print(f"Saved pads ({len(pads)}):")
|
|
97
|
+
for pad in pads:
|
|
98
|
+
modified = pad.get("modified", "")[:10] # Just the date part
|
|
99
|
+
print(f" {pad['name']:20} {modified}")
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
# Import app here to avoid loading Textual for --list
|
|
103
|
+
from .app import RecknApp
|
|
104
|
+
|
|
105
|
+
app = RecknApp(pad_name=args.pad_name)
|
|
106
|
+
app.run()
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
if __name__ == "__main__":
|
|
110
|
+
main()
|