# Convert converter = CSVToVCFConverter()
1. CSV Format Requirements The converter expects CSV files with the following columns (case-insensitive): csv to vcf
class CSVToVCFConverter: """Convert CSV contacts to VCF vCard format""" # Convert converter = CSVToVCFConverter() 1
def format_date(self, date_str: str) -> str: """Format date for VCF (YYYYMMDD)""" if not date_str: return "" # Try different date formats formats = ['%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%Y%m%d'] for fmt in formats: try: date_obj = datetime.strptime(date_str, fmt) return date_obj.strftime('%Y%m%d') except ValueError: continue return date_str.replace('-', '').replace('/', '') date_str: str) ->
# Check if input file exists if not os.path.exists(args.input): print(f"Error: Input file 'args.input' not found") return 1
def create_vcf_card(self, contact: Dict, index: int) -> str: """Create single VCF card from contact data""" vcf_lines = [] # Begin vCard vcf_lines.append("BEGIN:VCARD") vcf_lines.append(f"VERSION:self.version") # Name (required) name = self.escape_vcf_text(contact.get('name', '')) if name: # Split name into parts name_parts = name.split(maxsplit=1) first_name = name_parts[0] if name_parts else '' last_name = name_parts[1] if len(name_parts) > 1 else '' vcf_lines.append(f"N:last_name;first_name;;;") vcf_lines.append(f"FN:name") else: vcf_lines.append(f"N:;;;index;") vcf_lines.append(f"FN:Contact index") # Phone number phone = self.format_phone(contact.get('phone', '')) if phone: vcf_lines.append(f"TEL;TYPE=CELL:phone") # Work phone (if available) work_phone = self.format_phone(contact.get('workphone', '')) if work_phone: vcf_lines.append(f"TEL;TYPE=WORK:work_phone") # Email email = self.escape_vcf_text(contact.get('email', '')) if email: vcf_lines.append(f"EMAIL;TYPE=INTERNET:email") # Company and Title company = self.escape_vcf_text(contact.get('company', '')) title = self.escape_vcf_text(contact.get('title', '')) if company: vcf_lines.append(f"ORG:company") if title: vcf_lines.append(f"TITLE:title") # Address address = self.escape_vcf_text(contact.get('address', '')) if address: vcf_lines.append(f"ADR;TYPE=WORK:;;address;;;;") # Website website = self.escape_vcf_text(contact.get('website', '')) if website: if not website.startswith(('http://', 'https://')): website = 'http://' + website vcf_lines.append(f"URL:website") # Birthday birthday = self.format_date(contact.get('birthday', '')) if birthday: vcf_lines.append(f"BDAY:birthday") # Notes notes = self.escape_vcf_text(contact.get('notes', '')) if notes: vcf_lines.append(f"NOTE:notes") # UID (unique identifier) import uuid vcf_lines.append(f"UID:uuid.uuid4()") # Revision date vcf_lines.append(f"REV:datetime.now().strftime('%Y%m%dT%H%M%SZ')") # End vCard vcf_lines.append("END:VCARD") vcf_lines.append("") # Empty line between cards return '\n'.join(vcf_lines)
def convert_to_string(self, input_file: str, encoding: Optional[str] = None) -> str: """Convert CSV to VCF string (without saving to file)""" contacts = self.read_csv(input_file, encoding) vcf_strings = [] for i, contact in enumerate(contacts, start=1): vcf_strings.append(self.create_vcf_card(contact, i)) return '\n'.join(vcf_strings) def main(): parser = argparse.ArgumentParser( description='Convert CSV contacts to VCF (vCard) format', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python csv_to_vcf.py contacts.csv python csv_to_vcf.py contacts.csv -o output.vcf python csv_to_vcf.py contacts.csv -e iso-8859-1 """ )