Browse Source

Create configuration command for user input configuration generation.

feature/create-config
gabriel becker 2 years ago
parent
commit
01eb182c84
  1. 2
      src/ankimaker/commands/__init__.py
  2. 31
      src/ankimaker/commands/make_config.py
  3. 9
      src/ankimaker/config/configuration.py
  4. 1
      src/ankimaker/tasks/__init__.py
  5. 2
      src/ankimaker/tasks/config_tasks/__init__.py
  6. 77
      src/ankimaker/tasks/config_tasks/create_config.py
  7. 2
      src/ankimaker/tasks/config_tasks/enhance_config.py
  8. 1
      src/ankimaker/utils/__init__.py
  9. 3
      src/ankimaker/utils/files.py

2
src/ankimaker/commands/__init__.py

@ -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

31
src/ankimaker/commands/make_config.py

@ -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.')

9
src/ankimaker/config/configuration.py

@ -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

1
src/ankimaker/tasks/__init__.py

@ -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

2
src/ankimaker/tasks/config_tasks/__init__.py

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

77
src/ankimaker/tasks/config_tasks/create_config.py

@ -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

2
src/ankimaker/tasks/config_tasks/enhance_config.py

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

1
src/ankimaker/utils/__init__.py

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

3
src/ankimaker/utils/files.py

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