Created
January 10, 2023 00:53
-
-
Save evandrocoan/7804f10e442e5a379bf1c604b96dc123 to your computer and use it in GitHub Desktop.
Convert Anki decks from JSON to YAML and vice versa.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import timeit | |
import datetime | |
import argparse | |
import tempfile | |
import pathlib | |
# python3 -m pip install pyyaml | |
# import yaml | |
# https://stackoverflow.com/questions/71836675/force-pyyaml-to-write-multiline-string-literals-regardless-of-string-content | |
# python3 -m pip install ruamel.yaml | |
import ruamel.yaml as yaml | |
import sys | |
import json | |
from pathlib import Path | |
from typing import Optional | |
g_start_time = timeit.default_timer() | |
SCRIPT_DIRECTORY = pathlib.Path(__file__).parent.resolve() | |
def main() -> Optional[int]: | |
argumentsNamespace = g_argumentParser.parse_args() | |
if argumentsNamespace.help: | |
g_argumentParser.print_help() | |
return | |
to_json = argumentsNamespace.to_json | |
fast_scandir(SCRIPT_DIRECTORY, max_recursion=1, to_json=to_json) | |
def fast_scandir(current_directory: Path, max_recursion=1, to_json=False, recursion_depth=0): | |
subfolders = [] | |
for subpath in os.scandir(current_directory): | |
fullpath = current_directory / subpath | |
if fullpath.is_dir(): | |
if recursion_depth < max_recursion: | |
subfolders.extend( | |
fast_scandir( | |
fullpath, | |
max_recursion=max_recursion, | |
to_json=to_json, | |
recursion_depth=recursion_depth + 1 | |
) | |
) | |
else: | |
if to_json: | |
if fullpath.name == "deck.yml": | |
newjsonpath = fullpath.with_suffix(".json") | |
with open(fullpath, 'r') as readyml, \ | |
tempfile.NamedTemporaryFile( | |
mode="w", | |
dir=current_directory, | |
suffix=".ignore", | |
newline='\r\n', | |
encoding='utf8', | |
) as temporaryfile: | |
print(f"Converting to json {fullpath}.", file=sys.stderr) | |
json.dump(yaml.safe_load(readyml), temporaryfile, indent=4, ensure_ascii=False) | |
temporaryfile.flush() # atomic write for safety | |
os.replace(temporaryfile.name, newjsonpath) | |
print_time() | |
# NamedTemporaryFile with delete=True should not fail if file already deleted | |
# https://bugs.python.org/issue29573 | |
with open(temporaryfile.name, 'w') as fake: | |
fake.write("nothing") | |
else: | |
if fullpath.name == "deck.json": | |
newymlpath = fullpath.with_suffix(".yml") | |
with open(fullpath, 'r') as readjson, \ | |
tempfile.NamedTemporaryFile( | |
mode="w", | |
dir=current_directory, | |
suffix=".ignore", | |
newline='\n', | |
encoding='utf8', | |
) as temporaryfile: | |
print(f"Converting to yml {fullpath}.", file=sys.stderr) | |
yaml.dump(json.load(readjson), temporaryfile, | |
default_flow_style=False, | |
default_style='|', | |
allow_unicode=True) | |
temporaryfile.flush() # atomic write for safety | |
os.replace(temporaryfile.name, newymlpath) | |
print_time() | |
# NamedTemporaryFile with delete=True should not fail if file already deleted | |
# https://bugs.python.org/issue29573 | |
with open(temporaryfile.name, 'w') as fake: | |
fake.write("nothing") | |
return subfolders | |
# Call it without the start parameter to print the time since the last call | |
def print_time(start=None): | |
global g_start_time | |
start = g_start_time if start is None else start | |
end = timeit.default_timer() | |
print("Time elapsed %s... " % datetime.timedelta(seconds=end-start), | |
end="\n", file=sys.stderr) | |
g_start_time = end | |
# Simple python program example to run tests together with your code using pytest | |
# https://gist.github.com/evandrocoan/69aeaee3e16ad77fc5c889cfd55fc698 | |
g_argumentParser = argparse.ArgumentParser( | |
description = \ | |
""" | |
Convert Anki decks from JSON to YAML and vice versa. | |
""", | |
formatter_class=argparse.RawTextHelpFormatter, | |
add_help=False, | |
) | |
g_argumentParser.add_argument( "-h", "--help", action="store_true", | |
help= """ | |
Show this help message and exits. | |
""" ) | |
g_argumentParser.add_argument( "-j", "--to-json", action="store_true", default=None, | |
help= | |
""" | |
Convert Anki deck back from YAML to json. | |
""" ) | |
if __name__ == '__main__': | |
start = timeit.default_timer() | |
code = main() | |
print_time(start) | |
sys.exit(code if code else 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment