task | add ink support
This commit is contained in:
parent
9f9fd41851
commit
bf3b1fc456
13 changed files with 595 additions and 37 deletions
|
|
@ -6,6 +6,15 @@ from typing import List
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@dataclass
|
||||
class Ink:
|
||||
Vendor: str = "N/A"
|
||||
Name: str = "N/A"
|
||||
Color: str = "N/A"
|
||||
Purchased: str = "N/A"
|
||||
Size: str = "N/A"
|
||||
Notes: str = "N/A"
|
||||
|
||||
@dataclass
|
||||
class Pen:
|
||||
Make: str = "N/A"
|
||||
|
|
@ -21,6 +30,65 @@ class Pen:
|
|||
Inked_date: str = "N/A"
|
||||
Notes: str = "N/A"
|
||||
|
||||
class InkTracker:
|
||||
def __init__(self, storage_file: str = None):
|
||||
if storage_file is None:
|
||||
storage_file = os.path.abspath('inks.csv')
|
||||
self.storage_file = os.path.abspath(storage_file)
|
||||
self.headers = ['Vendor', 'Name', 'Color', 'Purchased', 'Size', 'Notes']
|
||||
self.inks: List[Ink] = self.load_data()
|
||||
|
||||
def _sort_inks(self):
|
||||
"""Sorts the inks list by Vendor, then by Name alphabetically."""
|
||||
self.inks.sort(key=lambda x: (x.Vendor.lower(), x.Name.lower()))
|
||||
|
||||
def load_data(self) -> List[Ink]:
|
||||
"""Loads data from the CSV file."""
|
||||
if not os.path.exists(self.storage_file):
|
||||
self._create_empty_csv()
|
||||
return []
|
||||
|
||||
inks = []
|
||||
try:
|
||||
with open(self.storage_file, mode='r', encoding='utf-8-sig') as f:
|
||||
reader = csv.DictReader(f)
|
||||
if reader.fieldnames:
|
||||
reader.fieldnames = [h.strip() for h in reader.fieldnames]
|
||||
for row in reader:
|
||||
if None in row:
|
||||
extras = row.pop(None)
|
||||
if extras:
|
||||
extra_text = ",".join(extras).strip()
|
||||
if extra_text:
|
||||
row['Notes'] = (row.get('Notes') or '')
|
||||
if row['Notes']:
|
||||
row['Notes'] += ", "
|
||||
row['Notes'] += extra_text
|
||||
clean_row = {
|
||||
k.strip(): (v.strip() if v else "N/A")
|
||||
for k, v in row.items() if k is not None
|
||||
}
|
||||
inks.append(Ink(**clean_row))
|
||||
inks.sort(key=lambda x: (x.Vendor.lower(), x.Name.lower()))
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading inks CSV: {e}")
|
||||
return inks
|
||||
|
||||
def _create_empty_csv(self):
|
||||
"""Creates the CSV file with headers if it is missing."""
|
||||
with open(self.storage_file, mode='w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=self.headers)
|
||||
writer.writeheader()
|
||||
|
||||
def save_data(self):
|
||||
"""Sorts the data before writing to ensure persistent alphabetical order."""
|
||||
self._sort_inks()
|
||||
with open(self.storage_file, mode='w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=self.headers)
|
||||
writer.writeheader()
|
||||
for ink in self.inks:
|
||||
writer.writerow(asdict(ink))
|
||||
|
||||
class PenTracker:
|
||||
def __init__(self, storage_file: str = None):
|
||||
if storage_file is None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue