copy-n-launch-xlsx 0.2.8__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.
- copy_n_launch_xlsx-0.2.8/LICENSE +19 -0
- copy_n_launch_xlsx-0.2.8/PKG-INFO +52 -0
- copy_n_launch_xlsx-0.2.8/README.md +18 -0
- copy_n_launch_xlsx-0.2.8/pyproject.toml +84 -0
- copy_n_launch_xlsx-0.2.8/setup.cfg +4 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/VERSION +2 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/__init__.py +73 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/__main__.py +6 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/_version.py +26 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/cli.py +125 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/context.py +1 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/core.py +104 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/README.md +18 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-blue.svg +7 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-blue_1024x1024.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-blue_256x256.ico +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.icns +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_128x128.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_16x16.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_16x16@2x.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_256x256.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_256x256@2x.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_512x512.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_512x512@2x.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.svg +12 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green_1024x1024.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green_256x256.ico +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-magenta.svg +7 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-magenta_1024x1024.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-magenta_256x256.ico +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-accent-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-invalid.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/card.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-tri-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-tri-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-tri-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-unsel-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-unsel-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-unsel-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-unsel-pressed.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/combo-button-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/combo-button-focus.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/combo-button-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/down.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/empty.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/hor-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/hor-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/hor-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/notebook.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/off-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/off-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/off-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/on-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/on-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/on-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-tri-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-tri-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-tri-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-unsel-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-unsel-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-unsel-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/radio-unsel-pressed.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/rect-accent-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/rect-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/rect-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/rect-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/right.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/scale-hor.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/scale-vert.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/separator.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/sizegrip.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/spin-button-down-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/spin-button-down-focus.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/spin-button-up.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/tab-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/tab-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/tab-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/thumb-hor-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/thumb-hor-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/thumb-hor-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/thumb-vert-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/thumb-vert-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/thumb-vert-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/tree-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/tree-pressed.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/up.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/vert-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/vert-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/vert-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark.tcl +536 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/border-accent-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/border-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/border-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/border-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/border-invalid.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/card.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-tri-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-tri-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-tri-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-unsel-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-unsel-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-unsel-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/check-unsel-pressed.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/combo-button-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/combo-button-focus.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/combo-button-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/down-focus.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/down.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/empty.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/hor-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/hor-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/hor-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/notebook.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/off-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/off-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/off-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/on-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/on-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/on-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-tri-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-tri-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-tri-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-unsel-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-unsel-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-unsel-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/radio-unsel-pressed.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/rect-accent-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/rect-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/rect-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/rect-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/right-focus.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/right.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/scale-hor.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/scale-vert.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/separator.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/sizegrip.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/spin-button-down-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/spin-button-down-focus.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/spin-button-up.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/tab-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/tab-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/tab-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/thumb-hor-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/thumb-hor-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/thumb-hor-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/thumb-vert-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/thumb-vert-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/thumb-vert-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/tree-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/tree-pressed.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/up.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/vert-accent.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/vert-basic.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light/vert-hover.png +0 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-light.tcl +544 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/datacopy.py +46 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/environment.py +12 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/gui.py +290 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/helpers.py +37 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/logging_setup.py +64 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/paths.py +94 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/splash.py +39 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/tk_utils.py +188 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/webapp.py +455 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx.egg-info/PKG-INFO +52 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx.egg-info/SOURCES.txt +184 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx.egg-info/dependency_links.txt +1 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx.egg-info/entry_points.txt +3 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx.egg-info/requires.txt +8 -0
- copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx.egg-info/top_level.txt +1 -0
- copy_n_launch_xlsx-0.2.8/test/test_get_target_copy_dir.py +7 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2026 George Clayton Bennett, george.bennett@memphistn.gov, github.com/City-of-Memphis/copy-n-launch-xlsx/
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
9
|
+
Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by:
|
|
10
|
+
|
|
11
|
+
(a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of contributors, in source or binary form) alone; or
|
|
12
|
+
|
|
13
|
+
(b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution.
|
|
14
|
+
|
|
15
|
+
Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this license, whether expressly, by implication, estoppel or otherwise.
|
|
16
|
+
|
|
17
|
+
DISCLAIMER
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: copy-n-launch-xlsx
|
|
3
|
+
Version: 0.2.8
|
|
4
|
+
Summary: Stable spreadsheet copy, renaming, and dating, for municipal wastewater operator daily data entry.
|
|
5
|
+
Author-email: George Clayton Bennett <george.bennett@memphistn.gov>
|
|
6
|
+
Maintainer-email: George Clayton Bennett <george.bennett@memphistn.gov>
|
|
7
|
+
Project-URL: Homepage, https://github.com/city-of-memphis-wastewater/copy-n-launch-xlsx
|
|
8
|
+
Project-URL: Repository, https://github.com/city-of-memphis-wastewater/copy-n-launch-xlsx
|
|
9
|
+
Project-URL: Issues, https://github.com/city-of-memphis-wastewater/copy-n-launch-xlsx/issues
|
|
10
|
+
Project-URL: Changelog, https://raw.githubusercontent.com/city-of-memphis-wastewater/copy-n-launch-xlsx/main/docs/CHANGELOG.md
|
|
11
|
+
Keywords: data entry,xlsx
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
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: Operating System :: OS Independent
|
|
21
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: pyhabitat>=1.3.2
|
|
26
|
+
Requires-Dist: rich>=14.2.0
|
|
27
|
+
Requires-Dist: typer>=0.20.0
|
|
28
|
+
Requires-Dist: click>=8.1.8
|
|
29
|
+
Requires-Dist: openpyxl>=3.1.5
|
|
30
|
+
Requires-Dist: dworshak-config>=0.2.8
|
|
31
|
+
Requires-Dist: dworshak-env>=0.1.8
|
|
32
|
+
Requires-Dist: typer-helptree>=0.2.10.5
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# copy-n-launch-xlsx
|
|
36
|
+
|
|
37
|
+
Build a GUI that:
|
|
38
|
+
|
|
39
|
+
- Copies a blank spreadsheet files
|
|
40
|
+
|
|
41
|
+
- Renames it, with the date in the filename
|
|
42
|
+
|
|
43
|
+
- Moves te new renamed file to a target folder
|
|
44
|
+
|
|
45
|
+
In this way, the stable file can be updated in a centralized way.
|
|
46
|
+
Users can safely launch new daily data entry sheets, without needing to choose a file to launch directly.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Sheets should use variable names and possibly tables, for later reference and data aggregation.
|
|
50
|
+
Variable names allow the cell locations to be adjusted and not referenced.
|
|
51
|
+
|
|
52
|
+
This project should stay private, and it is specific to the Maxson Wastewater Treatment Operator data input.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# copy-n-launch-xlsx
|
|
2
|
+
|
|
3
|
+
Build a GUI that:
|
|
4
|
+
|
|
5
|
+
- Copies a blank spreadsheet files
|
|
6
|
+
|
|
7
|
+
- Renames it, with the date in the filename
|
|
8
|
+
|
|
9
|
+
- Moves te new renamed file to a target folder
|
|
10
|
+
|
|
11
|
+
In this way, the stable file can be updated in a centralized way.
|
|
12
|
+
Users can safely launch new daily data entry sheets, without needing to choose a file to launch directly.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Sheets should use variable names and possibly tables, for later reference and data aggregation.
|
|
16
|
+
Variable names allow the cell locations to be adjusted and not referenced.
|
|
17
|
+
|
|
18
|
+
This project should stay private, and it is specific to the Maxson Wastewater Treatment Operator data input.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "copy-n-launch-xlsx"
|
|
3
|
+
#version = "0.1.0"
|
|
4
|
+
dynamic = ["version"]
|
|
5
|
+
description = "Stable spreadsheet copy, renaming, and dating, for municipal wastewater operator daily data entry."
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
requires-python = ">=3.9"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"pyhabitat>=1.3.2",
|
|
10
|
+
"rich>=14.2.0",
|
|
11
|
+
"typer>=0.20.0",
|
|
12
|
+
"click>=8.1.8",
|
|
13
|
+
"openpyxl>=3.1.5",
|
|
14
|
+
"dworshak-config>=0.2.8",
|
|
15
|
+
"dworshak-env>=0.1.8",
|
|
16
|
+
"typer-helptree>=0.2.10.5",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
#license = "MIT"
|
|
20
|
+
#license-files = ["LICENSE"]
|
|
21
|
+
|
|
22
|
+
classifiers=[
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
25
|
+
"Programming Language :: Python :: 3.9",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
31
|
+
"Operating System :: OS Independent",
|
|
32
|
+
#"Intended Audience :: Developers", # library and documentation
|
|
33
|
+
#"Environment :: Console",
|
|
34
|
+
#"Typing :: Typed",
|
|
35
|
+
#"Development Status :: 4 - Beta",
|
|
36
|
+
"Development Status :: 5 - Production/Stable",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
authors = [
|
|
40
|
+
{ name = "George Clayton Bennett", email = "george.bennett@memphistn.gov" },
|
|
41
|
+
]
|
|
42
|
+
maintainers = [
|
|
43
|
+
{ name = "George Clayton Bennett", email = "george.bennett@memphistn.gov" },
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
keywords = [
|
|
47
|
+
"data entry",
|
|
48
|
+
"xlsx"
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.urls]
|
|
52
|
+
Homepage = "https://github.com/city-of-memphis-wastewater/copy-n-launch-xlsx"
|
|
53
|
+
Repository = "https://github.com/city-of-memphis-wastewater/copy-n-launch-xlsx"
|
|
54
|
+
Issues = "https://github.com/city-of-memphis-wastewater/copy-n-launch-xlsx/issues"
|
|
55
|
+
Changelog = "https://raw.githubusercontent.com/city-of-memphis-wastewater/copy-n-launch-xlsx/main/docs/CHANGELOG.md"
|
|
56
|
+
|
|
57
|
+
[project.scripts]
|
|
58
|
+
copy-n-launch-xlsx = "copy_n_launch_xlsx.__main__:app"
|
|
59
|
+
cnlx = "copy_n_launch_xlsx.__main__:app"
|
|
60
|
+
|
|
61
|
+
#[project.optional-dependencies]
|
|
62
|
+
|
|
63
|
+
# add with `uv sync --group dev`
|
|
64
|
+
[dependency-groups]
|
|
65
|
+
dev = [
|
|
66
|
+
"build>=1.3.0",
|
|
67
|
+
"pyinstaller>=6.21.0",
|
|
68
|
+
"shiv>=1.0.8",
|
|
69
|
+
#"ruff>=0.7.0 ; platform_system == 'Linux' and platform_machine != 'aarch64'", # to avoid on termux
|
|
70
|
+
"pytest>=8.0.0",
|
|
71
|
+
"pytest-cov>=4.1.0",
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
[build-system]
|
|
76
|
+
requires = ["setuptools>=64", "wheel"]
|
|
77
|
+
build-backend = "setuptools.build_meta"
|
|
78
|
+
|
|
79
|
+
[tool.setuptools.dynamic]
|
|
80
|
+
version = {file = "src/copy_n_launch_xlsx/VERSION"}
|
|
81
|
+
|
|
82
|
+
# --- Add this section to include your asset directories ---
|
|
83
|
+
[tool.setuptools.package-data]
|
|
84
|
+
copy_n_launch_xlsx = ["data/**/*"]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# # src/copy_n_launch_xlsx/__init__.py
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from ._version import __version__
|
|
7
|
+
|
|
8
|
+
# 1. Clean public facing mapping
|
|
9
|
+
__all__ = [
|
|
10
|
+
"__version__",
|
|
11
|
+
"get_target_copy_dir",
|
|
12
|
+
"copy_then_rename_and_move_then_try_launch",
|
|
13
|
+
"CopyResult",
|
|
14
|
+
"__gui_easteregg_enabled__", # Re-added for REPL discovery
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
def _check_easteregg_env() -> bool:
|
|
18
|
+
"""Helper to dynamically read environment state at call-time."""
|
|
19
|
+
env_flag = os.environ.get('CNLX_GUI_EASTEREGG', '').strip().lower()
|
|
20
|
+
return env_flag in ('true', '1', 'yes', 'on')
|
|
21
|
+
|
|
22
|
+
# 2. Fully dynamic attribute routing
|
|
23
|
+
def __getattr__(name: str):
|
|
24
|
+
if name == "get_target_copy_dir":
|
|
25
|
+
from .paths import get_target_copy_dir
|
|
26
|
+
return get_target_copy_dir
|
|
27
|
+
|
|
28
|
+
if name == "copy_then_rename_and_move_then_try_launch":
|
|
29
|
+
from .core import copy_then_rename_and_move_then_try_launch
|
|
30
|
+
return copy_then_rename_and_move_then_try_launch
|
|
31
|
+
|
|
32
|
+
if name == "CopyResult":
|
|
33
|
+
from .core import CopyResult
|
|
34
|
+
return CopyResult
|
|
35
|
+
|
|
36
|
+
# Dynamic boolean evaluation for the breadcrumb attribute
|
|
37
|
+
if name == "__gui_easteregg_enabled__":
|
|
38
|
+
return _check_easteregg_env()
|
|
39
|
+
|
|
40
|
+
# Dynamic lookups for the GUI function invocation
|
|
41
|
+
if name == "start_gui":
|
|
42
|
+
def _missing_gui():
|
|
43
|
+
raise RuntimeError(
|
|
44
|
+
"start_gui requires pyhabitat and a Tkinter-capable environment"
|
|
45
|
+
)
|
|
46
|
+
_missing_gui.__name__ = "start_gui"
|
|
47
|
+
_missing_gui.__doc__ = (
|
|
48
|
+
"GUI support is unavailable in this environment."
|
|
49
|
+
)
|
|
50
|
+
if _check_easteregg_env():
|
|
51
|
+
try:
|
|
52
|
+
import pyhabitat
|
|
53
|
+
if pyhabitat.tkinter_is_available():
|
|
54
|
+
from .gui import start_gui
|
|
55
|
+
return start_gui
|
|
56
|
+
except ImportError:
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
return _missing_gui
|
|
60
|
+
|
|
61
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# 3. Dynamic introspection reflecting runtime changes
|
|
65
|
+
def __dir__():
|
|
66
|
+
exported = list(__all__)
|
|
67
|
+
if _check_easteregg_env():
|
|
68
|
+
exported.append("start_gui")
|
|
69
|
+
|
|
70
|
+
return sorted(exported + [
|
|
71
|
+
"__builtins__", "__cached__", "__doc__", "__file__",
|
|
72
|
+
"__getattr__", "__dir__", "__loader__", "__name__", "__package__", "__path__", "__spec__"
|
|
73
|
+
])
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# src/copy_n_launch_xlsx/_version.py
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
def get_version() -> str:
|
|
5
|
+
|
|
6
|
+
# Try local VERSION file (Source/Dev)
|
|
7
|
+
try:
|
|
8
|
+
# __file__ is src/copy_n_launch_xlsx/_version.py
|
|
9
|
+
# VERSION is src/copy_n_launch_xlsx/VERSION
|
|
10
|
+
version_file = Path(__file__).parent / "VERSION"
|
|
11
|
+
if version_file.exists():
|
|
12
|
+
return version_file.read_text(encoding="utf-8").strip()
|
|
13
|
+
except Exception:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
# Try metadata (Installed)
|
|
17
|
+
try:
|
|
18
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
19
|
+
return version("copy-n-launch-xlsx")
|
|
20
|
+
except (ImportError, PackageNotFoundError):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
return "0.0.0-unknown"
|
|
25
|
+
|
|
26
|
+
__version__ = get_version()
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# # src/copy_n_launch_xlsx/cli.py.py
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import typer
|
|
5
|
+
import click
|
|
6
|
+
from typing import Literal, List, Dict, Optional, Union
|
|
7
|
+
from typer.models import OptionInfo
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import pyhabitat
|
|
10
|
+
import sys
|
|
11
|
+
import os
|
|
12
|
+
from importlib.resources import files
|
|
13
|
+
from typer_helptree import add_typer_helptree
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
import logging
|
|
16
|
+
logger=logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
from .paths import APP_NAME
|
|
19
|
+
from .context import DESCRIPTION_STR
|
|
20
|
+
from .logging_setup import configure_logging_for_application
|
|
21
|
+
from ._version import __version__
|
|
22
|
+
from .core import copy_then_rename_and_move_then_try_launch
|
|
23
|
+
from .webapp import run_webapp
|
|
24
|
+
|
|
25
|
+
console = Console(stderr=True)
|
|
26
|
+
|
|
27
|
+
# Force Rich to always enable colors, even when running from a .pyz bundle
|
|
28
|
+
os.environ["FORCE_COLOR"] = "1"
|
|
29
|
+
# Optional but helpful for full terminal feature detection
|
|
30
|
+
os.environ["TERM"] = "xterm-256color"
|
|
31
|
+
|
|
32
|
+
app = typer.Typer(
|
|
33
|
+
name=APP_NAME,
|
|
34
|
+
help=f"DESCRIPTION_STR (v{__version__})",
|
|
35
|
+
add_completion=False,
|
|
36
|
+
invoke_without_command = True,
|
|
37
|
+
no_args_is_help = False,
|
|
38
|
+
context_settings={"ignore_unknown_options": True,
|
|
39
|
+
"allow_extra_args": True,
|
|
40
|
+
"help_option_names": ["-h", "--help"]},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
@app.callback(invoke_without_command=True, no_args_is_help=False)
|
|
44
|
+
def main(
|
|
45
|
+
ctx: typer.Context,
|
|
46
|
+
version: bool = typer.Option(False, "--version", is_flag=True),
|
|
47
|
+
debug: bool = typer.Option(False, "--debug","-d", is_flag=True),
|
|
48
|
+
verbose: bool = typer.Option(False, "--verbose","-v", is_flag=True),
|
|
49
|
+
):
|
|
50
|
+
if version:
|
|
51
|
+
typer.echo(__version__)
|
|
52
|
+
raise typer.Exit()
|
|
53
|
+
|
|
54
|
+
configure_logging_for_application(debug,verbose)
|
|
55
|
+
|
|
56
|
+
# Join the string from the command line arg and log debug to show the command.
|
|
57
|
+
full_command_list = sys.argv
|
|
58
|
+
command_string = " ".join(full_command_list)
|
|
59
|
+
logging.debug(f"command:\n{command_string}\n")
|
|
60
|
+
|
|
61
|
+
if ctx.invoked_subcommand is None:
|
|
62
|
+
gui_command()
|
|
63
|
+
|
|
64
|
+
add_typer_helptree(app = app, console = console, version = __version__, hidden = False)
|
|
65
|
+
|
|
66
|
+
@app.command(name="copylaunch")
|
|
67
|
+
def copyrenamelaunch(
|
|
68
|
+
)->None:
|
|
69
|
+
"""
|
|
70
|
+
Run the core function.
|
|
71
|
+
"""
|
|
72
|
+
result = copy_then_rename_and_move_then_try_launch()
|
|
73
|
+
destination = result.destination
|
|
74
|
+
|
|
75
|
+
if result.is_new:
|
|
76
|
+
logger.debug(f"File created:\n{destination}\n")
|
|
77
|
+
elif not result.is_new:
|
|
78
|
+
logger.debug(f"File exists:\n{destination}\n")
|
|
79
|
+
|
|
80
|
+
@app.command(name="webapp")
|
|
81
|
+
def webapp(
|
|
82
|
+
)->None:
|
|
83
|
+
"""
|
|
84
|
+
Serve the web interface to localhost.
|
|
85
|
+
"""
|
|
86
|
+
run_webapp()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@app.command(name="gui")
|
|
90
|
+
def gui_command(
|
|
91
|
+
auto_close: int = typer.Option(0,
|
|
92
|
+
"--auto-close", "-c",
|
|
93
|
+
help = "Delay in milliseconds after which the GUI window will close (for automated testing). Use 0 to disable auto-closing.",
|
|
94
|
+
min=0)
|
|
95
|
+
)->None:
|
|
96
|
+
"""
|
|
97
|
+
Launch tkinter-based GUI.
|
|
98
|
+
"""
|
|
99
|
+
assured_auto_close_value = 0
|
|
100
|
+
|
|
101
|
+
if isinstance(auto_close, OptionInfo):
|
|
102
|
+
# Case 1: Called implicitly from main() (with no args)
|
|
103
|
+
# We received the metadata object, so use the function's default value (0).
|
|
104
|
+
# We don't need to do anything here since final_auto_close_value is already 0.
|
|
105
|
+
pass
|
|
106
|
+
else:
|
|
107
|
+
# Case 2: Called explicitly by Typer
|
|
108
|
+
# Typer has successfully converted the command line argument, and auto_close is an int.
|
|
109
|
+
assured_auto_close_value = int(auto_close)
|
|
110
|
+
|
|
111
|
+
if not pyhabitat.tkinter_is_available():
|
|
112
|
+
_gui_failure_msg()
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
from .gui import start_gui
|
|
116
|
+
start_gui(time_auto_close = assured_auto_close_value)
|
|
117
|
+
|
|
118
|
+
def _gui_failure_msg():
|
|
119
|
+
console.print("[bold red]GUI failed to launch[/bold red]")
|
|
120
|
+
console.print("Use cli or webapp instead.")
|
|
121
|
+
console.print(f"pyhabitat.tkinter_is_available() = {pyhabitat.tkinter_is_available()}")
|
|
122
|
+
console.print(f"pyhabitat.on_termux() = {pyhabitat.on_termux()}")
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
app()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DESCRIPTION_STR = "Stable fresh spreadsheet assistant for Maxson Operators."
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# src/copy_n_launch_xlsx/core.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from datetime import date
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import shutil
|
|
7
|
+
import openpyxl
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
import pyhabitat
|
|
12
|
+
from datetime import date
|
|
13
|
+
from openpyxl.workbook.defined_name import DefinedName
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
from .paths import BLANK_DAILY_XLSX, get_target_copy_dir
|
|
19
|
+
|
|
20
|
+
FILENAME_FORMAT = "daily_%Y-%m-%d.xlsx"
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class CopyResult:
|
|
24
|
+
destination: Optional[str] = None
|
|
25
|
+
is_new: Optional[bool] = False
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def status_message(self) -> str:
|
|
29
|
+
"""Statuses."""
|
|
30
|
+
return {
|
|
31
|
+
True: "File copied.",
|
|
32
|
+
False: "File exists.",
|
|
33
|
+
None: "Exited."
|
|
34
|
+
}.get(self.is_new, "Error.")
|
|
35
|
+
|
|
36
|
+
def __bool__(self):
|
|
37
|
+
return self.destination is not None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def build_filename(day: date | None = None) -> str:
|
|
41
|
+
if day is None:
|
|
42
|
+
day = date.today()
|
|
43
|
+
filename = day.strftime(FILENAME_FORMAT)
|
|
44
|
+
return filename
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def copy_then_rename_and_move_then_try_launch() -> Path:
|
|
48
|
+
target_dir = get_target_copy_dir()
|
|
49
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
50
|
+
|
|
51
|
+
destination = target_dir / build_filename()
|
|
52
|
+
logger.debug(f"{destination=}")
|
|
53
|
+
# Check if the file is already there
|
|
54
|
+
if destination.exists():
|
|
55
|
+
logger.info(f"Daily file already exists at {destination}. Skipping copy. Launching existing file.")
|
|
56
|
+
pyhabitat.launch_file(destination)
|
|
57
|
+
#return destination
|
|
58
|
+
return CopyResult(destination=destination,is_new=False)
|
|
59
|
+
if BLANK_DAILY_XLSX.exists():
|
|
60
|
+
shutil.copy2(BLANK_DAILY_XLSX, destination)
|
|
61
|
+
else:
|
|
62
|
+
print(f"Please put daily_blank.xlsx in the expected place: {BLANK_DAILY_XLSX}")
|
|
63
|
+
sys.exit(0)
|
|
64
|
+
# Open/save if you later want to update named ranges,
|
|
65
|
+
# dates, workbook properties, etc.
|
|
66
|
+
wb = openpyxl.load_workbook(destination)
|
|
67
|
+
|
|
68
|
+
# future edits go here
|
|
69
|
+
set_date_in_spreadsheet(wb)
|
|
70
|
+
wb.save(destination)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
pyhabitat.launch_file(destination)
|
|
74
|
+
|
|
75
|
+
#return destination
|
|
76
|
+
return CopyResult(destination=destination,is_new=True)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def set_date_in_spreadsheet(wb):
|
|
80
|
+
|
|
81
|
+
today_str = date.today().strftime("%m/%d/%Y")
|
|
82
|
+
|
|
83
|
+
if "date" in wb.defined_names:
|
|
84
|
+
defn = wb.defined_names["date"]
|
|
85
|
+
|
|
86
|
+
# Use whichever field contains the reference string
|
|
87
|
+
raw_value = defn.value if defn.value else defn.attr_text
|
|
88
|
+
|
|
89
|
+
if raw_value and "!" in raw_value:
|
|
90
|
+
sheet_name, cell_coord = raw_value.split("!")
|
|
91
|
+
sheet_name = sheet_name.strip("'") # Strip potential quote wrapping
|
|
92
|
+
cell_coord = cell_coord.replace("$", "") # Strip absolute reference anchoring
|
|
93
|
+
|
|
94
|
+
if sheet_name in wb.sheetnames:
|
|
95
|
+
ws = wb[sheet_name]
|
|
96
|
+
ws[cell_coord] = today_str
|
|
97
|
+
logger.debug(f"Successfully updated cell {cell_coord} on sheet '{sheet_name}' to {today_str}.")
|
|
98
|
+
else:
|
|
99
|
+
defn.value = f'="{today_str}"'
|
|
100
|
+
logger.debug(f"Updated global value expression for named range 'date' to {today_str}.")
|
|
101
|
+
else:
|
|
102
|
+
new_name = DefinedName("date", attr_text=f'="{today_str}"')
|
|
103
|
+
wb.defined_names.add(new_name)
|
|
104
|
+
logger.debug(f"Named range 'date' not found. Created global expression variable set to {today_str}.")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# copy-n-launch-xlsx
|
|
2
|
+
|
|
3
|
+
Build a GUI that:
|
|
4
|
+
|
|
5
|
+
- Copies a blank spreadsheet files
|
|
6
|
+
|
|
7
|
+
- Renames it, with the date in the filename
|
|
8
|
+
|
|
9
|
+
- Moves te new renamed file to a target folder
|
|
10
|
+
|
|
11
|
+
In this way, the stable file can be updated in a centralized way.
|
|
12
|
+
Users can safely launch new daily data entry sheets, without needing to choose a file to launch directly.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Sheets should use variable names and possibly tables, for later reference and data aggregation.
|
|
16
|
+
Variable names allow the cell locations to be adjusted and not referenced.
|
|
17
|
+
|
|
18
|
+
This project should stay private, and it is specific to the Maxson Wastewater Treatment Operator data input.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
2
|
+
|
|
3
|
+
<svg fill="#00d5ff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800px" height="800px" viewBox="0 0 550.80 550.80" xml:space="preserve" stroke="#00d5ff" stroke-width="0.005508010000000001">
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
Binary file
|
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_16x16@2x.png
ADDED
|
Binary file
|
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_256x256@2x.png
ADDED
|
Binary file
|
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/icons/max-green.iconset/icon_512x512@2x.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
2
|
+
|
|
3
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools, URL: https://www.svgrepo.com/svg/90695/max-file-format-extension -->
|
|
4
|
+
<svg fill="#1a9933" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800px" height="800px" viewBox="0 0 550.801 550.801" xml:space="preserve" stroke="#1a9933">
|
|
5
|
+
|
|
6
|
+
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
|
7
|
+
|
|
8
|
+
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
|
9
|
+
|
|
10
|
+
<g id="SVGRepo_iconCarrier"> <g> <path d="M303.993,286.912c-2.447-8.132-4.884-18.312-6.919-26.449h-0.411c-2.036,8.142-4.071,18.523-6.308,26.449l-8.142,29.094 h30.322L303.993,286.912z"/> <path d="M488.426,197.014H475.2v-63.817c0-0.401-0.063-0.799-0.116-1.205c-0.021-2.534-0.827-5.023-2.562-6.993L366.325,3.694 c-0.032-0.034-0.063-0.045-0.085-0.076c-0.633-0.707-1.371-1.298-2.151-1.804c-0.231-0.158-0.464-0.287-0.706-0.422 c-0.676-0.366-1.393-0.675-2.131-0.896c-0.2-0.053-0.38-0.135-0.58-0.19C359.87,0.119,359.037,0,358.193,0H97.2 c-11.918,0-21.6,9.693-21.6,21.601v175.413H62.377c-17.049,0-30.873,13.818-30.873,30.87v160.542 c0,17.044,13.824,30.876,30.873,30.876h13.224V529.2c0,11.907,9.682,21.601,21.6,21.601h356.4c11.907,0,21.6-9.693,21.6-21.601 V419.302h13.226c17.044,0,30.871-13.827,30.871-30.87v-160.54C519.297,210.832,505.47,197.014,488.426,197.014z M97.2,21.601 h250.193v110.51c0,5.967,4.841,10.8,10.8,10.8h95.407v54.108H97.2V21.601z M360.946,374.388h-33.36l-10.589-35.2H277.75l-9.77,35.2 h-32.144l41.914-137.111h40.682L360.946,374.388z M71.276,374.388l8.743-137.111h41.299l13.424,45.765 c4.271,15.868,8.543,32.965,11.588,49.033h0.612c3.87-15.873,8.54-33.972,13.022-49.223l14.639-45.57h40.489l7.523,137.112h-30.31 l-2.035-52.481c-0.612-16.475-1.227-36.418-1.227-56.357h-0.611c-4.271,17.486-9.967,37.015-15.248,53.093l-16.688,53.494h-24.203 l-14.639-53.083c-4.482-16.089-9.152-35.611-12.414-53.504h-0.4c-0.82,18.516-1.435,39.672-2.444,56.758l-2.437,52.081H71.276 V374.388z M453.601,523.347H97.2V419.302h356.4V523.347z M446.576,374.388l-12.414-24.821c-5.072-9.562-8.332-16.686-12.202-24.627 h-0.401c-2.848,7.941-6.307,15.061-10.578,24.627l-11.391,24.821h-35.396l39.667-69.382l-38.254-67.729h35.606l12.019,25.027 c4.061,8.335,7.104,15.037,10.367,22.773h0.396c3.265-8.743,5.901-14.85,9.366-22.773l11.591-25.027h35.396l-38.654,66.922 l40.7,70.189H446.576z"/> </g> </g>
|
|
11
|
+
|
|
12
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
2
|
+
|
|
3
|
+
<svg fill="#ae00d1" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800px" height="800px" viewBox="0 0 550.80 550.80" xml:space="preserve" stroke="#ae00d1" stroke-width="0.005508010000000001">
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-accent.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-basic.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-hover.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/border-invalid.png
ADDED
|
Binary file
|
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-accent.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-basic.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-hover.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-tri-accent.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-tri-basic.png
ADDED
|
Binary file
|
copy_n_launch_xlsx-0.2.8/src/copy_n_launch_xlsx/data/themes/forest/forest-dark/check-tri-hover.png
ADDED
|
Binary file
|
|
Binary file
|