#!/usr/bin/env python3 import argparse import os import csv import sys import xml.etree.ElementTree as ET # Mapping from ZionWorx verse types to labels understood by ProPresenter. # NOTE: Some of these don't have colons after them. VT_MAP = { "stVerse": "Verse:", "stChorus": "Chorus:", "stBridge": "Bridge:", "stPreChorus": "Pre Chorus", "stEnding": "Outro" } # Default verse type DEFAULT_VT = "stVerse" cli_parser = argparse.ArgumentParser( description="ZionWorx to ProPresenter conversion tool" ) cli_parser.add_argument("csv_file", type=str, help="CSV file exported using TurboDB") cli_parser.add_argument("-d", "--delimiter", type=str, default=";", help="CSV delimiter character (default: ;)") cli_parser.add_argument("-q", "--quote", type=str, default="\"", help="CSV quote character (default: \")") cli_parser.add_argument("-o", "--output", type=str, default=os.getcwd(), help="Folder to write song files in (default: current working directory)") cli_args = cli_parser.parse_args() csv_file = cli_args.csv_file delim_char = cli_args.delimiter quote_char = cli_args.quote output_path = cli_args.output print(f"Converting {csv_file} to path {output_path}...", file=sys.stderr) with open(csv_file) as csv_handle: processed_songs = set() reader = csv.reader(csv_handle, delimiter=delim_char, quotechar=quote_char) i = 0 for song in reader: i += 1 if i == 1: continue if len(song) < 8: print("Row does not contain seven columns: " + delim_char.join(song), file=sys.stderr) continue song_id = song[0] title = song[1] print(f"Processing #{song_id}: \"{title}\"...", file=sys.stderr) # Ensure broken whitespace doesn't destroy the conversion lyrics_data = song[4].replace("\v", "\n") lyrics_xml = ET.fromstring(lyrics_data) # copy_str = song[7] lyrics = [] for section in lyrics_xml.findall("section"): if section.text is not None: text = section.text label = VT_MAP.get(section.get("type", DEFAULT_VT), DEFAULT_VT) lyrics.append(f"{label}\n{text}") lyrics_str = "\n\n".join(lyrics) # Sadly I don't know how to get any copyright information into ProPresenter. :( file_contents = f"""Title: {title} {lyrics_str} """ file_name = title.replace("/", "_") if file_name in processed_songs: orig_file_name = file_name r = 0 while file_name in processed_songs: r += 1 file_name = f"{orig_file_name}_{r}" target_file = f"{output_path}/{file_name}.txt" with open(target_file, mode="w") as target: target.write(file_contents) print(f"Wrote {target_file}", file=sys.stderr) processed_songs.add(file_name) print("\nDone!", file=sys.stderr)