Band Contacts to Google Contacts v3

This commit is contained in:
2026-06-23 09:47:28 -07:00
parent 6fe273d9d2
commit dad2265871
+27 -14
View File
@@ -2,10 +2,11 @@ import csv
import argparse import argparse
import datetime import datetime
import re import re
import sys
def clean_instrument_name(instrument_raw): def clean_instrument_name(instrument_raw):
"""Cleans the instrument name based on Percussion, Winds, and Default rules.""" """Cleans the instrument name based on Percussion, Winds, and Default rules."""
# Strip numerical prefix (e.g., "12 - Percussion (electronics)" -> "Percussion (electronics)") # Strip numerical prefix
if '-' in instrument_raw: if '-' in instrument_raw:
instrument = instrument_raw.split('-', 1)[-1].strip() instrument = instrument_raw.split('-', 1)[-1].strip()
else: else:
@@ -13,11 +14,24 @@ def clean_instrument_name(instrument_raw):
lower_inst = instrument.lower() lower_inst = instrument.lower()
# Pre-catch Drum Major so they are always cleanly named
if 'drum major' in lower_inst:
return 'Drum Major'
# 1. The Percussion Rule # 1. The Percussion Rule
if 'percussion' in lower_inst and '(' in instrument and ')' in instrument: if 'percussion' in lower_inst and '(' in instrument and ')' in instrument:
match = re.search(r'\((.*?)\)', instrument) match = re.search(r'\((.*?)\)', instrument)
if match: if match:
return match.group(1).strip().title() extracted = match.group(1).strip().title()
# Ensure "Drum" is in the name
if 'Drum' not in extracted:
if extracted.lower() in ['tenor', 'tenors']:
return 'Tenor Drums'
else:
return f"{extracted} Drum"
return extracted
# 2. The Winds/General Rule # 2. The Winds/General Rule
elif '(' in instrument and ')' in instrument: elif '(' in instrument and ')' in instrument:
@@ -27,9 +41,13 @@ def clean_instrument_name(instrument_raw):
return instrument return instrument
def get_category(instrument): def get_category(instrument):
"""Categorize the instrument into Woodwinds, Brass, Percussion, or Colorguard.""" """Categorize the instrument into groups, isolating Drum Majors first."""
inst_lower = instrument.lower() inst_lower = instrument.lower()
# Catch Drum Majors first so they don't get trapped by the 'drum' keyword in Percussion
if 'drum major' in inst_lower:
return 'Drum Majors'
if any(x in inst_lower for x in ['flute', 'clarinet', 'sax', 'oboe', 'bassoon', 'piccolo']): if any(x in inst_lower for x in ['flute', 'clarinet', 'sax', 'oboe', 'bassoon', 'piccolo']):
return 'Woodwinds' return 'Woodwinds'
if any(x in inst_lower for x in ['trumpet', 'mellophone', 'horn', 'trombone', 'baritone', 'euphonium', 'tuba', 'sousaphone']): if any(x in inst_lower for x in ['trumpet', 'mellophone', 'horn', 'trombone', 'baritone', 'euphonium', 'tuba', 'sousaphone']):
@@ -39,7 +57,7 @@ def get_category(instrument):
if 'guard' in inst_lower or 'color' in inst_lower: if 'guard' in inst_lower or 'color' in inst_lower:
return 'Colorguard' return 'Colorguard'
return 'Leadership' # Fallback for generic roles like Drum Major return 'Leadership' # Fallback for other potential roles
def format_phone(phone_str): def format_phone(phone_str):
"""Clean and standardize the phone numbers.""" """Clean and standardize the phone numbers."""
@@ -65,8 +83,6 @@ def main():
parser.add_argument("input_file", help="Path to the input CSV file") parser.add_argument("input_file", help="Path to the input CSV file")
parser.add_argument("-y", "--year", type=int, default=datetime.datetime.now().year, parser.add_argument("-y", "--year", type=int, default=datetime.datetime.now().year,
help="Target year for labels and grade calculation (defaults to current year)") help="Target year for labels and grade calculation (defaults to current year)")
parser.add_argument("-o", "--output", default="google_contacts_import.csv",
help="Output file name")
args = parser.parse_args() args = parser.parse_args()
target_year = args.year target_year = args.year
@@ -83,11 +99,10 @@ def main():
"Address 1 - Extended Address" "Address 1 - Extended Address"
] ]
with open(args.input_file, mode='r', encoding='utf-8') as infile, \ with open(args.input_file, mode='r', encoding='utf-8') as infile:
open(args.output, mode='w', encoding='utf-8', newline='') as outfile:
reader = csv.DictReader(infile) reader = csv.DictReader(infile)
writer = csv.DictWriter(outfile, fieldnames=google_headers) # lineterminator='\n' ensures consistent newlines across OS when printing to stdout
writer = csv.DictWriter(sys.stdout, fieldnames=google_headers, lineterminator='\n')
writer.writeheader() writer.writeheader()
for row in reader: for row in reader:
@@ -117,9 +132,9 @@ def main():
else: else:
notes = grade_raw notes = grade_raw
# Determine Label (Appended with Marching Band) # Determine Label
category = get_category(instrument) category = get_category(instrument)
label = f"{target_year} {category} ::: Marching Band {target_year} ::: * myContacts" label = f"{target_year} {category} ::: Marching Band ::: * myContacts"
# Build the output row # Build the output row
out_row = {key: "" for key in google_headers} out_row = {key: "" for key in google_headers}
@@ -142,7 +157,5 @@ def main():
writer.writerow(out_row) writer.writerow(out_row)
print(f"Success! Formatted contacts saved to {args.output}")
if __name__ == '__main__': if __name__ == '__main__':
main() main()