Compare commits

...

3 Commits

Author SHA1 Message Date
gabriel becker
01eb182c84 Create configuration command for user input configuration generation. 2022-11-30 17:36:01 +11:00
gabriel becker
b513dbd08f Better messages for help. 2022-11-30 17:35:39 +11:00
gabriel becker
3a7cb85aee Create configuration command for user input configuration generation. 2022-11-30 17:05:12 +11:00
12 changed files with 137 additions and 4 deletions

View File

@ -4,3 +4,6 @@ from ankimaker.commands import cli
def main(): def main():
cli(prog_name='ankimaker') cli(prog_name='ankimaker')
if __name__ == '__main__':
main()

View File

@ -1,8 +1,10 @@
import click import click
@click.group("cli") @click.group("cli")
def cli(): def cli():
pass pass
from ..commands.from_csv import generate_anki from ..commands.from_csv import generate_anki
from ..commands.make_config import make_csv_config

View File

@ -5,8 +5,8 @@ from ankimaker.tasks import basic_pandas_to_anki
@cli.command('csv') @cli.command('csv')
@click.argument('-i', '--input', 'input_file', type=click.Path(exists=True)) @click.option('-i', '--input', 'input_file', type=click.Path(exists=True))
@click.argument('-o', '--output', 'output_file', type=click.Path(exists=False)) @click.option('-o', '--output', 'output_file', type=click.Path(exists=False))
@click.option('-c', '--conf', 'config_file', default=None, type=click.STRING) @click.option('-c', '--conf', 'config_file', default=None, type=click.STRING)
@click.option('-n', '--name', 'name', default=None, type=click.STRING) @click.option('-n', '--name', 'name', default=None, type=click.STRING)
def generate_anki( def generate_anki(
@ -15,6 +15,9 @@ def generate_anki(
name, name,
config_file, config_file,
): ):
"""
Create an anki deck from a csv file and a config file.
"""
output_file = parse_output(output_file) output_file = parse_output(output_file)
if name is None: if name is None:
name = get_name_from_output(output_file) name = get_name_from_output(output_file)

View File

@ -0,0 +1,31 @@
import click
from ankimaker.commands import cli
from ankimaker import tasks, utils
_YAML = ['yml', 'yaml']
_CSV = ['csv']
@cli.command('make-csv-config')
@click.option('-i', '--input', 'input_file', type=click.Path(exists=True))
@click.option('-o', '--output', 'output_path', type=click.Path(exists=False))
def make_csv_config(
input_file, output_path
):
"""
Menu for creating a config file.
:param input_file: filepath of the csv used as sample to create configuration
:param output_path: filepath where configuration will be saved
"""
filetype = utils.files.get_fyle_type(input_file)
if filetype in _CSV:
tasks.config_tasks.create_config(input_file, output_path)
elif filetype in _YAML:
tasks.config_tasks.enhance_config(input_file)
else:
click.echo('Wrong File Type. Should be CSV or YAML.')

View File

@ -1,4 +1,6 @@
import yaml import yaml
from typing import Iterable
_empty_list = ()
class AnkimakerConfig(yaml.YAMLObject): class AnkimakerConfig(yaml.YAMLObject):
@ -7,11 +9,15 @@ class AnkimakerConfig(yaml.YAMLObject):
question_column = None question_column = None
answer_column = None answer_column = None
separators = ',' separators = ','
filters: Iterable[dict] = list()
def __init__(self, header=None, answer_column=None, question_column=None): def __init__(
self, header=None, answer_column=None, question_column=None, filters=_empty_list
):
AnkimakerConfig.answer_column = answer_column AnkimakerConfig.answer_column = answer_column
AnkimakerConfig.question_column = question_column AnkimakerConfig.question_column = question_column
AnkimakerConfig.header = header AnkimakerConfig.header = header
AnkimakerConfig.filters = filters
AnkimakerConfig.AnkimakerConfig = AnkimakerConfig AnkimakerConfig.AnkimakerConfig = AnkimakerConfig
@staticmethod @staticmethod
@ -21,3 +27,4 @@ class AnkimakerConfig(yaml.YAMLObject):
AnkimakerConfig.question_column = content.question_column AnkimakerConfig.question_column = content.question_column
AnkimakerConfig.answer_column = content.answer_column AnkimakerConfig.answer_column = content.answer_column
AnkimakerConfig.separators = content.separators AnkimakerConfig.separators = content.separators
AnkimakerConfig.filters = content.filters

View File

@ -1 +1,2 @@
from .basic_csv_to_anki import basic_pandas_to_anki from .basic_csv_to_anki import basic_pandas_to_anki
from .config_tasks import create_config, enhance_config

View File

@ -19,7 +19,8 @@ def create_model():
'qfmt': '<div style="text-align: center;">{{Question}}</div>', 'qfmt': '<div style="text-align: center;">{{Question}}</div>',
'afmt': '{{FrontSide}}<hr id="answer"><div style="text-align: center;">{{Answer}}</div>', 'afmt': '{{FrontSide}}<hr id="answer"><div style="text-align: center;">{{Answer}}</div>',
}, },
]) ]
)
return my_model return my_model

View File

@ -0,0 +1,2 @@
from .create_config import create_config
from .enhance_config import enhance_config

View File

@ -0,0 +1,77 @@
import yaml
import click
import pandas as pd
from typing import Type
from ankimaker.config import Config
__CONFIRMATION_QUESTION = """
Is this read option {option} correct?
______________
{preview}
"""
__SUCCESS_MESSAGE = """
All done. You can now use your configuration with this command:
{command}
"""
__COMMAND_SAMPLE = """ankimaker csv \
-i {input} \
-o my-new-deck.apkg \
--conf {output}
"""
def create_config(input_file, output_path):
new_config = Config()
new_config.separators = handle_read_option(
input_file, read_option='sep', sep=new_config.separators
)
new_config.header = handle_read_option(
input_file, read_option='header', header=new_config.header,
sep=new_config.separators, option_type=int
)
finish_message = __SUCCESS_MESSAGE.format(command=make_sample_command(input_file, output_path))
click.echo(finish_message)
def handle_read_option(input_file, read_option, option_type: Type = str, **kargs):
preview: str
is_finished = False
while not is_finished:
preview = load_preview(input_file, **kargs)
question = __CONFIRMATION_QUESTION.format(
option=str(read_option),
preview=preview
)
answer: str = click.prompt(question, type=str, default='y')
click.clear()
if answer.lower()[0] == 'y':
return kargs[read_option]
else:
updated_option: str = click.prompt('Insert the correct', type=option_type)
kargs[read_option] = updated_option
click.clear()
def load_preview(input_file, *args, **kargs):
try:
df = pd.read_csv(input_file, *args, **kargs)
preview = df.head()
except pd.errors.ParserError:
preview = 'FAIL'
return preview
def save_file(config: Config, file_path):
f = open(file_path, 'w')
yaml.dump(config, f)
def make_sample_command(inputf, output):
command = __COMMAND_SAMPLE.format(
input=inputf, output=output
)
return command

View File

@ -0,0 +1,2 @@
def enhance_config(filename):
raise NotImplementedError()

View File

@ -0,0 +1 @@
from . import files

View File

@ -0,0 +1,3 @@
def get_fyle_type(filename):
filetype = filename.split('.')[-1] if len(filename.split('.')) > 0 else None
return filetype