task | add ink support
This commit is contained in:
parent
9f9fd41851
commit
bf3b1fc456
13 changed files with 595 additions and 37 deletions
|
|
@ -3,7 +3,7 @@ import csv
|
|||
import argparse
|
||||
import json
|
||||
from datetime import datetime
|
||||
from .engine import PenTracker, Pen
|
||||
from .engine import PenTracker, Pen, InkTracker, Ink
|
||||
|
||||
def validate_date(date_str: str) -> bool:
|
||||
"""Validate date in YYYY-MM-DD format."""
|
||||
|
|
@ -17,6 +17,10 @@ def validate_date(date_str: str) -> bool:
|
|||
|
||||
class CLITracker(PenTracker):
|
||||
|
||||
def __init__(self, storage_file=None):
|
||||
super().__init__(storage_file)
|
||||
self.ink_tracker = InkTracker()
|
||||
|
||||
def add_pen(self):
|
||||
print("\n--- Add New Fountain Pen ---")
|
||||
new_pen_data = {}
|
||||
|
|
@ -29,6 +33,9 @@ class CLITracker(PenTracker):
|
|||
|
||||
for label, key in fields:
|
||||
while True:
|
||||
if key == 'Current-Ink':
|
||||
value = self.select_ink()
|
||||
break
|
||||
value = input(f"Enter {label}: ").strip()
|
||||
if not value:
|
||||
value = "N/A"
|
||||
|
|
@ -74,6 +81,15 @@ class CLITracker(PenTracker):
|
|||
field = self.key_map.get(header, header)
|
||||
current_val = getattr(pen, field)
|
||||
while True:
|
||||
if header == 'Current-Ink':
|
||||
print(f"Current Ink: {current_val}")
|
||||
change_ink = input("Change ink? (y/n): ").strip().lower()
|
||||
if change_ink == 'y':
|
||||
new_val = self.select_ink()
|
||||
break
|
||||
else:
|
||||
new_val = ""
|
||||
break
|
||||
new_val = input(f"{header} [{current_val}]: ").strip()
|
||||
if not new_val:
|
||||
break
|
||||
|
|
@ -149,6 +165,69 @@ class CLITracker(PenTracker):
|
|||
except (ValueError, IndexError):
|
||||
print("[!] Invalid ID.")
|
||||
|
||||
def add_ink(self):
|
||||
print("\n--- Add New Ink ---")
|
||||
new_ink_data = {}
|
||||
fields = [
|
||||
("Vendor", "Vendor"), ("Name", "Name"), ("Color", "Color"),
|
||||
("Purchased (YYYY-MM-DD)", "Purchased"), ("Size", "Size"), ("Notes", "Notes")
|
||||
]
|
||||
|
||||
for label, key in fields:
|
||||
while True:
|
||||
value = input(f"Enter {label}: ").strip()
|
||||
if not value:
|
||||
value = "N/A"
|
||||
break
|
||||
if key == 'Purchased':
|
||||
if validate_date(value):
|
||||
break
|
||||
else:
|
||||
print("Invalid date format. Use YYYY-MM-DD.")
|
||||
else:
|
||||
break
|
||||
new_ink_data[key] = value
|
||||
|
||||
new_ink = Ink(**new_ink_data)
|
||||
self.ink_tracker.inks.append(new_ink)
|
||||
self.ink_tracker.save_data()
|
||||
print("\n[✔] Ink added successfully to inks.csv!")
|
||||
|
||||
def view_all_inks(self):
|
||||
if not self.ink_tracker.inks:
|
||||
print("\n[!] Your ink collection is currently empty.")
|
||||
return
|
||||
|
||||
print("\n" + "="*80)
|
||||
print(f"{'ID':<4} | {'VENDOR':<12} | {'NAME':<20} | {'COLOR':<15} | {'SIZE':<10}")
|
||||
print("-" * 80)
|
||||
|
||||
for idx, ink in enumerate(self.ink_tracker.inks):
|
||||
vendor = ink.Vendor[:12]
|
||||
name = ink.Name[:20]
|
||||
color = ink.Color[:15]
|
||||
size = ink.Size[:10]
|
||||
print(f"{idx:<4} | {vendor:<12} | {name:<20} | {color:<15} | {size:<10}")
|
||||
|
||||
print("="*80)
|
||||
|
||||
def select_ink(self):
|
||||
"""Helper method to select an ink from the list."""
|
||||
if not self.ink_tracker.inks:
|
||||
print("[!] No inks available. Add some inks first.")
|
||||
return "N/A"
|
||||
|
||||
self.view_all_inks()
|
||||
try:
|
||||
idx = int(input("\nEnter the ID of the ink to select (or -1 for N/A): "))
|
||||
if idx == -1:
|
||||
return "N/A"
|
||||
ink = self.ink_tracker.inks[idx]
|
||||
return ink.Name
|
||||
except (ValueError, IndexError):
|
||||
print("[!] Invalid ID.")
|
||||
return "N/A"
|
||||
|
||||
def clear_screen():
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
||||
|
|
@ -180,6 +259,17 @@ def main():
|
|||
export_parser = subparsers.add_parser('export', help='Export to JSON')
|
||||
export_parser.add_argument('--output', default='pens.json', help='Output file')
|
||||
|
||||
# Ink commands
|
||||
add_ink_parser = subparsers.add_parser('add-ink', help='Add a new ink')
|
||||
add_ink_parser.add_argument('--vendor', required=True)
|
||||
add_ink_parser.add_argument('--name', required=True)
|
||||
add_ink_parser.add_argument('--color')
|
||||
add_ink_parser.add_argument('--purchased')
|
||||
add_ink_parser.add_argument('--size')
|
||||
add_ink_parser.add_argument('--notes')
|
||||
|
||||
list_inks_parser = subparsers.add_parser('list-inks', help='List all inks')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
tracker = CLITracker(args.csv)
|
||||
|
|
@ -217,6 +307,24 @@ def main():
|
|||
with open(args.output, 'w') as f:
|
||||
json.dump([asdict(p) for p in tracker.pens], f, indent=2)
|
||||
print(f"Exported to {args.output}")
|
||||
elif args.command == 'add-ink':
|
||||
if args.purchased and not validate_date(args.purchased):
|
||||
print("Invalid purchased date format.")
|
||||
return
|
||||
ink_data = {
|
||||
'Vendor': args.vendor,
|
||||
'Name': args.name,
|
||||
'Color': args.color or 'N/A',
|
||||
'Purchased': args.purchased or 'N/A',
|
||||
'Size': args.size or 'N/A',
|
||||
'Notes': args.notes or 'N/A'
|
||||
}
|
||||
new_ink = Ink(**ink_data)
|
||||
tracker.ink_tracker.inks.append(new_ink)
|
||||
tracker.ink_tracker.save_data()
|
||||
print("Ink added successfully.")
|
||||
elif args.command == 'list-inks':
|
||||
tracker.view_all_inks()
|
||||
else:
|
||||
# Interactive mode
|
||||
while True:
|
||||
|
|
@ -225,7 +333,9 @@ def main():
|
|||
print("2. Add New Pen")
|
||||
print("3. Edit a Pen")
|
||||
print("4. Delete a Pen")
|
||||
print("5. Exit")
|
||||
print("5. View Ink Collection")
|
||||
print("6. Add New Ink")
|
||||
print("7. Exit")
|
||||
|
||||
choice = input("\nSelect an option: ")
|
||||
|
||||
|
|
@ -242,6 +352,12 @@ def main():
|
|||
clear_screen()
|
||||
tracker.delete_pen()
|
||||
elif choice == '5':
|
||||
clear_screen()
|
||||
tracker.view_all_inks()
|
||||
elif choice == '6':
|
||||
clear_screen()
|
||||
tracker.add_ink()
|
||||
elif choice == '7':
|
||||
print("Goodbye! Happy writing! ✒️")
|
||||
break
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue