feat(backend): make cli interactive
This commit is contained in:
@@ -1,82 +1,42 @@
|
|||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████████████████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████████████████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████████████████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
█████████████████████████████████████████████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▓▓████████████████████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
███████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░▒▒▒████████████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
████████████████████████████▓▒▒▒▒▒▒▒▒▓▓████████████████████████████████▓▒▒▒▒▒▒░░░░░▒▓███████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
██████████████████████▓▒▒▒▒▓██████████████████████████████████████████████████▒▒▒▒░░░░░▒████████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
█████████████████▓▒▒▓████████████████████████████████████████████████████████████▓▒▒▒░░░░▒██████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
█████████████▓▓▓████████████████████████████████████████████████████████████████████▒▒▒░░░░▒████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
██████████▓██████████████████████████████████████████████████████████████████████████▓▒▒░░░░▒███████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
███████████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████▓▒░░░░░▒██████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
████████████████████████▓▓▓▓█████████▓▒▒▒▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒█████████████████████████▒▒░░░░▒▓█████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
███████████████████▓▒▒▒▒░░░░░░▒▓▓▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░▒▒██████████████████████▓▒░░░░░▒▒█████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
█████████████████▓▒▒▒░░░░░░░░░░░░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒█████████████████████▒░░░░░▒▒▓█████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
████████████████▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒███████████████████▒░░░░░▒▒▒▓█████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
███████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒████████████████▓▒░░░░░░▒▒▒▒██████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
███████████████▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒██████████████▒░░░░░░░▒▒▒▒▒███████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
█████████████▓▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░▒▒▒▒▒▓███████▓▒░░░░░░░░░▒▒▒▒▒▓████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
███████████▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒░░░░░░░░░░░░▒▒▒▒▓▓▒░░░░░░░░░░░░▒▒▒▒▒▒██████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
██████████▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒░░░░░░░░░░░░▒▒▒▒░░░░░░░░░░▒▒▒▒▒▒▒▒▓███████████
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
█████████▒▒▒▒░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▒▒░░░░░░░░░░░▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▒▓██████████████
|
||||||
█████████████████████████████████████████████████████████████████████▓▓▒▒▒▒▒░░▒░▒▒░░░░░░░░░░░░░░░░▒▒▒▓▓███████████████████████████████████████████████
|
███████▒▒▒▒░░░░░░░░░░▒▒▒▒▒░░░░░░░░▒▒▒░░░░░░░░░░░░░░▒▒▒▒░░░░░▒░░░░▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████
|
||||||
████████████████████████████████████████████████████████████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒░░░░░░░░░░░▒▒▓████████████████████████████████████████
|
██████▒▒▒▒░░░░░░░░░░▒▒▒░░░░░░░░░░░░░░▒▒░░░░░░░░░░░▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████
|
||||||
██████████████████████████████████████████████████████▓▒▒▒▒▒▒▒▒▒▓▓▓████████████████████████████████▓▓▒░░░░░░░░░░▒▓████████████████████████████████████
|
█████▒▒▒▒░░░░░░░░░▒▒▒░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░▒▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████████
|
||||||
█████████████████████████████████████████████████▓▒▒▒▒▓▓██████████████████████████████████████████████████▒░░░░░░░░░▓█████████████████████████████████
|
█████▒▒▒▒░░░░░▒▒░▒▒▒▒░░░░░░░▒▒░░░░░░░░▒▒░░░░░░░░░░▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓████████████████████████████
|
||||||
████████████████████████████████████████████▓▒▒▒▓████████████████████████████████████████████████████████████▓░░░░░░░░▓███████████████████████████████
|
█████▒▒▒▒░░░░░▒▒░▒▒▒▒░░░░░▒▒░░░░░░░░░░▒▒▒░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████████████████████
|
||||||
████████████████████████████████████████▓▒▒█████████████████████████████████████████████████████████████████████▒▒░░░░░▒██████████████████████████████
|
█████▒▒▒▒░░░░▒▒▒░▒▒▒▒░░░░▒▒░░░░░░░░░░░▒▒░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████
|
||||||
█████████████████████████████████████▓▓████████████████████████████████▓▓▓▓▓█████████████████████████████████████▓▒░░░░░░▓████████████████████████████
|
█████▓▒▒▒▒▒░░▒▒▒▒▒▒▒▒░░░░▒▒░░░░░░░░░░▒▒▒░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████
|
||||||
███████████████████████████████████████████████████████████████████▒▒▒▒▒▒░░▒▒░▒▓███▓▓▓▓▓██████████████████████████▓▒░░░░░░▓███████████████████████████
|
██████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▒░░░░░░▒▒▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓████████████████████████████████
|
||||||
██████████████████████████████████████████████████▓▓▒▒▒▓▓█████▓▓▓▒▒▒▒░░░░░░░░░░▒▒▒▒░░░▒▒▒▒▓████████████████████████▒░░░░░░▒███████████████████████████
|
████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████████
|
||||||
███████████████████████████████████████████████▒▒▒░░░░░░░░▒▓▒▒▒▒░░░▒░░░░░░░░░░░░░░░░░░░░░░▒▒███████████████████████▒░░░░░▒▒███████████████████████████
|
██████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████████
|
||||||
█████████████████████████████████████████████▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒█████████████████████▒░░░░░░▒▒███████████████████████████
|
███████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████████
|
||||||
███████████████████████████████████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒██████████████████▓░░░░░░░▒▒▓███████████████████████████
|
███████████▓▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████████████████████████████████
|
||||||
███████████████████████████████████████████▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒████████████████▓░░░░░░░░▒▒▒████████████████████████████
|
█████████████▓▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█████████████████████████████████████████
|
||||||
██████████████████████████████████████████▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒█████████████▓▒░░░░░░░░▒▒▒▒█████████████████████████████
|
███████████████████▓▒▒▒▒░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██████████████████████████████████████████
|
||||||
████████████████████████████████████████▓▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▓███████▓▒░░░░░░░░░░▒▒▒▒▒██████████████████████████████
|
████████████████████▓▒▒▒▒░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▓█████████████████████████████████████████████
|
||||||
██████████████████████████████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒░░░░░░░░░░░░░░▒▒▒▓▓▒░░░░░░░░░░░░░▒▒▒▒▒▓███████████████████████████████
|
█████████████████████▓▒▒▒▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████████
|
||||||
█████████████████████████████████████▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░▒▒▒▒▒▒▓█████████████████████████████████
|
███████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████████████████████████████████████████████████████
|
||||||
████████████████████████████████████▒▒▒▒░░░░░░░░░░░░░▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░░▒▒▒░░░░░░░░▒▒▒▒▒▒▒▒▓███████████████████████████████████
|
███████████████████████████▓▒▒▒▒▒▒▓█████████████████████████████████████████████████████████████████
|
||||||
██████████████████████████████████▓▒▒▒░░░░░░░░░░░░▒▒░░░░░░░░░░░▒░░░░░░░░░░░░░░░░▒▒░░░░░░░░░░░░▒░▒▒░░░░▒▒▒▒▒▒▒▒▒▓██████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████████████████████████
|
||||||
█████████████████████████████████▒▒▒▒░░░░░░░░░░░▒▒░░░░░░░░░░░░░░░▒░░░░░░░░░░░░░▒▒░░░░░░░░▒░░▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████████████████████████
|
||||||
█████████████████████████████████▒▒▒░░░░░░░░░░▒▒▒░░░░░░░░░░░░░░░░░▒░░░░░░░░░░▒▒▒▒░░░░░░░░▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒█████████████████████████████████████████████
|
████████████████████████████████████████████████████████████████████████████████████████████████████
|
||||||
████████████████████████████████▒▒▒▒░░░░░░░░░▒▒▒░░░░░░░░░░░░░░░░░░▒░░░░░░░░░░░░▒▒▒░░░░░░▒▒▒░░░░▒▒▒▒▒▓█████████████████████████████████████████████████
|
|
||||||
████████████████████████████████▒▒▒▒░░░░░░▒░░▒▒▒░░░░░░░▒░░░░░░░░░░░▒░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░▒░░░▒▒▒████████████████████████████████████████████████████
|
|
||||||
████████████████████████████████▒▒▒▒░░░░░▒▒░▒▒▒▒░░░░░▒▒░░░░░░░░░░░░▒░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒░░▒░░▒▒▒▒████████████████████████████████████████████████████
|
|
||||||
█████████████████████████████████▒▒▒▒░░░░▒▒▒▒▒▒▒░░░░░▒░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒▒▒█████████████████████████████████████████████████████
|
|
||||||
█████████████████████████████████▓▒▒▒▒▒░░░▒▒▒▒▒▒▒░░░░▒▒░░░░░░░░░░░▒░░░░░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████
|
|
||||||
███████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒▒▒░░░░░░░░▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▒░░░░░░▒▒▒▒▒▒▒▒▓███████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████▒▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░▒▒▒▒▒▓██████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████▒▒▒░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░▒░░░░░░▒▒░░░░░░░░░░░▒▒▒█████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████▓▒▒▒░░░░▒▒▒▒░░░░░░░░░░░░░░░░░▒░░░░░░▒▒░░░░░░░░▒▒▒▒▓█████████████████████████████████████████████████████████████
|
|
||||||
████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░▒░░░░░░▒▒░░░░░░▒▒▒▒▒▓██████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████▓▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░▒▒▒░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓███████████████████████████████████████████████████████████████
|
|
||||||
███████████████████████████████████████████████▓▒▒▒░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████████████████
|
|
||||||
████████████████████████████████████████████████▓▒▒▒▒░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓███▓▓▓▓▓█████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒███████████████████████████████████████████████████████████████████████████████████
|
|
||||||
████████████████████████████████████████████████████▓▒▒▒▒▒▒▒▒▒▒▒▓█████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
|
|
||||||
322
backend/cli/interactive.py
Normal file
322
backend/cli/interactive.py
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
"""
|
||||||
|
Interactive CLI interface for NimbusFlow.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .base import NimbusFlowCLI
|
||||||
|
|
||||||
|
from .commands import (
|
||||||
|
cmd_members_list, cmd_members_show,
|
||||||
|
cmd_schedules_list, cmd_schedules_show, cmd_schedules_accept, cmd_schedules_decline,
|
||||||
|
cmd_services_list,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def load_ascii_art() -> str:
|
||||||
|
"""Load ASCII art from file."""
|
||||||
|
ascii_file = Path(__file__).parent / "ascii.txt"
|
||||||
|
if ascii_file.exists():
|
||||||
|
with open(ascii_file, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
# Use only the cloud portion (middle section) for better display
|
||||||
|
lines = content.strip().split('\n')
|
||||||
|
if len(lines) > 30:
|
||||||
|
# Take a smaller portion of the cloud art
|
||||||
|
start = len(lines) // 3
|
||||||
|
end = start + 15
|
||||||
|
return '\n'.join(lines[start:end])
|
||||||
|
return content
|
||||||
|
return "🎵 NimbusFlow 🎵" # Fallback if file doesn't exist
|
||||||
|
|
||||||
|
|
||||||
|
def display_welcome():
|
||||||
|
"""Display welcome screen with ASCII art."""
|
||||||
|
print("\033[2J\033[H") # Clear screen and move cursor to top
|
||||||
|
|
||||||
|
# Display the cloud ASCII art
|
||||||
|
ascii_art = load_ascii_art()
|
||||||
|
print(ascii_art)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Add the NimbusFlow branding
|
||||||
|
welcome_text = """
|
||||||
|
╔═══════════════════════════════════════════════════════════════════════════════╗
|
||||||
|
║ ║
|
||||||
|
║ ███╗ ██╗██╗███╗ ███╗██████╗ ██╗ ██╗███████╗ ███████╗██╗ ██████╗ ██╗ ██╗ ║
|
||||||
|
║ ████╗ ██║██║████╗ ████║██╔══██╗██║ ██║██╔════╝ ██╔════╝██║ ██╔═══██╗██║ ██║ ║
|
||||||
|
║ ██╔██╗ ██║██║██╔████╔██║██████╔╝██║ ██║███████╗ █████╗ ██║ ██║ ██║██║ █╗ ██║ ║
|
||||||
|
║ ██║╚██╗██║██║██║╚██╔╝██║██╔══██╗██║ ██║╚════██║ ██╔══╝ ██║ ██║ ██║██║███╗██║ ║
|
||||||
|
║ ██║ ╚████║██║██║ ╚═╝ ██║██████╔╝╚██████╔╝███████║ ██║ ███████╗╚██████╔╝╚███╔███╔╝ ║
|
||||||
|
║ ╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ║
|
||||||
|
║ ║
|
||||||
|
║ 🎵 Choir Scheduling System 🎵 ║
|
||||||
|
╚═══════════════════════════════════════════════════════════════════════════════╝
|
||||||
|
"""
|
||||||
|
print(welcome_text)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def display_main_menu():
|
||||||
|
"""Display the main menu options."""
|
||||||
|
print("🎯 " + "="*60)
|
||||||
|
print(" MAIN MENU - What would you like to manage?")
|
||||||
|
print("🎯 " + "="*60)
|
||||||
|
print()
|
||||||
|
print(" 1️⃣ 👥 Members - Manage choir members")
|
||||||
|
print(" 2️⃣ 📅 Schedules - View and manage schedules")
|
||||||
|
print(" 3️⃣ 🎼 Services - Manage services and events")
|
||||||
|
print(" 4️⃣ ❌ Exit - Close NimbusFlow CLI")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def display_members_menu():
|
||||||
|
"""Display members submenu."""
|
||||||
|
print("\n👥 " + "="*50)
|
||||||
|
print(" MEMBERS MENU")
|
||||||
|
print("👥 " + "="*50)
|
||||||
|
print()
|
||||||
|
print(" 1️⃣ 📋 List all members")
|
||||||
|
print(" 2️⃣ ✅ List active members only")
|
||||||
|
print(" 3️⃣ 🎵 List by classification")
|
||||||
|
print(" 4️⃣ 👤 Show member details")
|
||||||
|
print(" 5️⃣ 🔙 Back to main menu")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def display_schedules_menu():
|
||||||
|
"""Display schedules submenu."""
|
||||||
|
print("\n📅 " + "="*50)
|
||||||
|
print(" SCHEDULES MENU")
|
||||||
|
print("📅 " + "="*50)
|
||||||
|
print()
|
||||||
|
print(" 1️⃣ 📋 List all schedules")
|
||||||
|
print(" 2️⃣ ⏳ List pending schedules")
|
||||||
|
print(" 3️⃣ ✅ List accepted schedules")
|
||||||
|
print(" 4️⃣ ❌ List declined schedules")
|
||||||
|
print(" 5️⃣ 👤 Show schedule details")
|
||||||
|
print(" 6️⃣ ✨ Accept a schedule (interactive)")
|
||||||
|
print(" 7️⃣ 🚫 Decline a schedule (interactive)")
|
||||||
|
print(" 8️⃣ 🔙 Back to main menu")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def display_services_menu():
|
||||||
|
"""Display services submenu."""
|
||||||
|
print("\n🎼 " + "="*50)
|
||||||
|
print(" SERVICES MENU")
|
||||||
|
print("🎼 " + "="*50)
|
||||||
|
print()
|
||||||
|
print(" 1️⃣ 📋 List all services")
|
||||||
|
print(" 2️⃣ 🔮 List upcoming services")
|
||||||
|
print(" 3️⃣ 📅 List services by date")
|
||||||
|
print(" 4️⃣ 🔙 Back to main menu")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_choice(max_options: int) -> int:
|
||||||
|
"""Get user menu choice with validation."""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
choice = input(f"🎯 Enter your choice (1-{max_options}): ").strip()
|
||||||
|
if not choice:
|
||||||
|
continue
|
||||||
|
choice_int = int(choice)
|
||||||
|
if 1 <= choice_int <= max_options:
|
||||||
|
return choice_int
|
||||||
|
else:
|
||||||
|
print(f"❌ Please enter a number between 1 and {max_options}")
|
||||||
|
except ValueError:
|
||||||
|
print("❌ Please enter a valid number")
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
print("\n🛑 Goodbye!")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def get_text_input(prompt: str, required: bool = True) -> str:
|
||||||
|
"""Get text input from user."""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
value = input(f"📝 {prompt}: ").strip()
|
||||||
|
if value or not required:
|
||||||
|
return value
|
||||||
|
print("❌ This field is required")
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
print("\n🛑 Operation cancelled")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def get_date_input(prompt: str = "Enter date (YYYY-MM-DD)") -> str:
|
||||||
|
"""Get date input from user."""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
date_str = input(f"📅 {prompt}: ").strip()
|
||||||
|
if not date_str:
|
||||||
|
print("❌ Date is required")
|
||||||
|
continue
|
||||||
|
# Basic date format validation
|
||||||
|
if len(date_str) == 10 and date_str.count('-') == 2:
|
||||||
|
parts = date_str.split('-')
|
||||||
|
if len(parts[0]) == 4 and len(parts[1]) == 2 and len(parts[2]) == 2:
|
||||||
|
return date_str
|
||||||
|
print("❌ Please use format YYYY-MM-DD (e.g., 2025-09-07)")
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
print("\n🛑 Operation cancelled")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class MockArgs:
|
||||||
|
"""Mock args object for interactive commands."""
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_members_menu(cli: "NimbusFlowCLI"):
|
||||||
|
"""Handle members menu interactions."""
|
||||||
|
while True:
|
||||||
|
display_members_menu()
|
||||||
|
choice = get_user_choice(5)
|
||||||
|
|
||||||
|
if choice == 1: # List all members
|
||||||
|
print("\n🔍 Listing all members...")
|
||||||
|
cmd_members_list(cli, MockArgs(active=False, classification=None))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 2: # List active members
|
||||||
|
print("\n🔍 Listing active members...")
|
||||||
|
cmd_members_list(cli, MockArgs(active=True, classification=None))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 3: # List by classification
|
||||||
|
classification = get_text_input("Enter classification (Soprano, Alto / Mezzo, Tenor, Baritone)", True)
|
||||||
|
if classification:
|
||||||
|
print(f"\n🔍 Listing {classification} members...")
|
||||||
|
cmd_members_list(cli, MockArgs(active=False, classification=classification))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 4: # Show member details
|
||||||
|
member_id = get_text_input("Enter member ID", True)
|
||||||
|
if member_id.isdigit():
|
||||||
|
print(f"\n🔍 Showing details for member {member_id}...")
|
||||||
|
cmd_members_show(cli, MockArgs(member_id=int(member_id)))
|
||||||
|
else:
|
||||||
|
print("❌ Invalid member ID")
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 5: # Back to main menu
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def handle_schedules_menu(cli: "NimbusFlowCLI"):
|
||||||
|
"""Handle schedules menu interactions."""
|
||||||
|
while True:
|
||||||
|
display_schedules_menu()
|
||||||
|
choice = get_user_choice(8)
|
||||||
|
|
||||||
|
if choice == 1: # List all schedules
|
||||||
|
print("\n🔍 Listing all schedules...")
|
||||||
|
cmd_schedules_list(cli, MockArgs(service_id=None, status=None))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 2: # List pending schedules
|
||||||
|
print("\n🔍 Listing pending schedules...")
|
||||||
|
cmd_schedules_list(cli, MockArgs(service_id=None, status="pending"))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 3: # List accepted schedules
|
||||||
|
print("\n🔍 Listing accepted schedules...")
|
||||||
|
cmd_schedules_list(cli, MockArgs(service_id=None, status="accepted"))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 4: # List declined schedules
|
||||||
|
print("\n🔍 Listing declined schedules...")
|
||||||
|
cmd_schedules_list(cli, MockArgs(service_id=None, status="declined"))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 5: # Show schedule details
|
||||||
|
schedule_id = get_text_input("Enter schedule ID", True)
|
||||||
|
if schedule_id.isdigit():
|
||||||
|
print(f"\n🔍 Showing details for schedule {schedule_id}...")
|
||||||
|
cmd_schedules_show(cli, MockArgs(schedule_id=int(schedule_id)))
|
||||||
|
else:
|
||||||
|
print("❌ Invalid schedule ID")
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 6: # Accept schedule
|
||||||
|
date = get_date_input("Enter date for interactive accept")
|
||||||
|
if date:
|
||||||
|
print(f"\n✨ Starting interactive accept for {date}...")
|
||||||
|
cmd_schedules_accept(cli, MockArgs(date=date, schedule_id=None))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 7: # Decline schedule
|
||||||
|
date = get_date_input("Enter date for interactive decline")
|
||||||
|
if date:
|
||||||
|
reason = get_text_input("Enter decline reason (optional)", False)
|
||||||
|
print(f"\n🚫 Starting interactive decline for {date}...")
|
||||||
|
cmd_schedules_decline(cli, MockArgs(date=date, schedule_id=None, reason=reason))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 8: # Back to main menu
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def handle_services_menu(cli: "NimbusFlowCLI"):
|
||||||
|
"""Handle services menu interactions."""
|
||||||
|
while True:
|
||||||
|
display_services_menu()
|
||||||
|
choice = get_user_choice(4)
|
||||||
|
|
||||||
|
if choice == 1: # List all services
|
||||||
|
print("\n🔍 Listing all services...")
|
||||||
|
cmd_services_list(cli, MockArgs(date=None, upcoming=False, limit=None))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 2: # List upcoming services
|
||||||
|
print("\n🔍 Listing upcoming services...")
|
||||||
|
cmd_services_list(cli, MockArgs(date=None, upcoming=True, limit=20))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 3: # List by date
|
||||||
|
date = get_date_input("Enter date to filter services")
|
||||||
|
if date:
|
||||||
|
print(f"\n🔍 Listing services for {date}...")
|
||||||
|
cmd_services_list(cli, MockArgs(date=date, upcoming=False, limit=None))
|
||||||
|
input("\n⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
elif choice == 4: # Back to main menu
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def run_interactive_mode(cli: "NimbusFlowCLI"):
|
||||||
|
"""Run the main interactive CLI mode."""
|
||||||
|
display_welcome()
|
||||||
|
|
||||||
|
print("🎉 Welcome to the NimbusFlow Interactive CLI!")
|
||||||
|
print(" Navigate through menus to manage your choir scheduling system.")
|
||||||
|
print()
|
||||||
|
input("⏸️ Press Enter to continue...")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print("\033[2J\033[H") # Clear screen
|
||||||
|
display_main_menu()
|
||||||
|
|
||||||
|
choice = get_user_choice(4)
|
||||||
|
|
||||||
|
if choice == 1: # Members
|
||||||
|
handle_members_menu(cli)
|
||||||
|
|
||||||
|
elif choice == 2: # Schedules
|
||||||
|
handle_schedules_menu(cli)
|
||||||
|
|
||||||
|
elif choice == 3: # Services
|
||||||
|
handle_services_menu(cli)
|
||||||
|
|
||||||
|
elif choice == 4: # Exit
|
||||||
|
print("\n🎵 Thank you for using NimbusFlow!")
|
||||||
|
print(" Have a wonderful day! 🌟")
|
||||||
|
break
|
||||||
@@ -15,6 +15,7 @@ from .commands import (
|
|||||||
# Service commands
|
# Service commands
|
||||||
cmd_services_list, setup_services_parser,
|
cmd_services_list, setup_services_parser,
|
||||||
)
|
)
|
||||||
|
from .interactive import run_interactive_mode
|
||||||
|
|
||||||
|
|
||||||
def setup_parser() -> argparse.ArgumentParser:
|
def setup_parser() -> argparse.ArgumentParser:
|
||||||
@@ -41,7 +42,22 @@ def main():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if not args.command:
|
if not args.command:
|
||||||
parser.print_help()
|
# Launch interactive mode when no command is provided
|
||||||
|
try:
|
||||||
|
cli = NimbusFlowCLI()
|
||||||
|
run_interactive_mode(cli)
|
||||||
|
except CLIError as e:
|
||||||
|
print(f"❌ Error: {e}")
|
||||||
|
return 1
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n🛑 Interrupted by user")
|
||||||
|
return 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Unexpected error: {e}")
|
||||||
|
return 1
|
||||||
|
finally:
|
||||||
|
if 'cli' in locals():
|
||||||
|
cli.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user