Browse Source

Add filter creation in configuration creation command.

feature/create-config
gabriel becker 2 years ago
parent
commit
79e7714395
  1. 5
      .gitignore
  2. 3
      requirements.txt
  3. 3
      setup.py
  4. 34
      src/ankimaker/config/configuration.py
  5. 7
      src/ankimaker/config/filters.py
  6. 90
      src/ankimaker/tasks/config_tasks/create_config.py

5
.gitignore vendored

@ -157,4 +157,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/
# Project Specific
scripts/

3
requirements.txt

@ -1,4 +1,5 @@
click
genanki
pandas
pyyaml
pyyaml
bullet

3
setup.py

@ -8,7 +8,7 @@ def readme():
setup(
name='ankimaker',
version='0.0.4',
version='0.0.5',
description='Makes anki with files',
url="https://git.lgoon.xyz/gabriel/ankimaker",
license="BSD-3-Clause",
@ -27,6 +27,7 @@ setup(
"genanki",
"pandas",
"pyyaml",
"bullet"
],
long_description_content_type='text/markdown',
)

34
src/ankimaker/config/configuration.py

@ -14,12 +14,15 @@ class AnkimakerConfig(yaml.YAMLObject):
separators = ','
filters: List[List[FilterConfig]] = list()
def __init__(self, header=None, answer_column=None, question_column=None, filters=tuple()):
AnkimakerConfig.answer_column = answer_column
AnkimakerConfig.question_column = question_column
AnkimakerConfig.header = header
AnkimakerConfig.AnkimakerConfig = AnkimakerConfig
AnkimakerConfig.filters = list(map(lambda x: FilterConfig, filters))
def __init__(
self, separators=',', header=None, answer_column=None, question_column=None,
filters=tuple(), *args, **karhs
):
self.answer_column = answer_column
self.question_column = question_column
self.header = header
self.separators = separators
self.filters = _conditionally_create_new_filters(filters)
@staticmethod
def loader(configuration_content):
@ -31,8 +34,19 @@ class AnkimakerConfig(yaml.YAMLObject):
AnkimakerConfig.question_column = content.question_column
AnkimakerConfig.answer_column = content.answer_column
AnkimakerConfig.separators = content.separators
AnkimakerConfig.filters = [
[FilterConfig(**x) for x in or_filter]
for or_filter in content.filters
]
AnkimakerConfig.filters = _conditionally_create_new_filters(content.filters)
def _conditionally_create_new_filters(filters):
conf_has_filters = len(filters) > 0
if conf_has_filters:
should_cast_filter = not isinstance(filters[0][0], FilterConfig)
if should_cast_filter:
new_filters = [
[FilterConfig(**x) for x in or_filter]
for or_filter in filters
]
else:
new_filters = filters
return new_filters
return list()

7
src/ankimaker/config/filters.py

@ -1,7 +1,10 @@
import yaml
from typing import List, Union
class FilterConfig:
class FilterConfig(yaml.YAMLObject):
yaml_tag = '!fitlerconfig'
column: Union[str, int]
values: Union[List[Union[int, str]], Union[int, str]]
@ -10,7 +13,7 @@ class FilterConfig:
self.values = values
def __str__(self):
return f'<ankimaker.config.filters.FilterConfig {self.column}: {self.values} >'
return f'<F({self.column}:{self.values})>'
def __repr__(self):
return self.__str__()

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

@ -1,10 +1,12 @@
import os
import yaml
import click
import pandas as pd
from typing import Type
from typing import Type, List
from bullet import Bullet, Input, YesNo
from ankimaker.config import Config
from ankimaker.config import Config, FilterConfig
__CONFIRMATION_QUESTION = """
@ -25,25 +27,93 @@ __COMMAND_SAMPLE = """ankimaker csv \
"""
__ADD_FILTER_QUESTION = """Do you want do add a filter to the configuration?"""
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
separators = handle_read_option(
input_file, read_option='sep', sep=','
)
new_config.header = handle_read_option(
input_file, read_option='header', header=new_config.header,
sep=new_config.separators, option_type=int
header = handle_read_option(
input_file, read_option='header', header=None,
sep=separators, option_type=int
)
new_config.question_column = get_column('question')
new_config.answer_column = get_column('answer')
question_column = get_column('question')
answer_column = get_column('answer')
filters = process_filters(input_file, header, separators)
new_config = Config(
separators=separators,
header=header,
question_column=question_column,
answer_column=answer_column,
filters=filters
)
save_file(new_config, output_path)
finish_message = __SUCCESS_MESSAGE.format(command=make_sample_command(input_file, output_path))
click.clear()
click.echo(finish_message)
def process_filters(input_file, header, separators):
df = pd.read_csv(input_file, header=header, sep=separators)
filters = add_filters_to_config(df)
return filters
def __inline_yes_or_no_question(question):
answer = YesNo(prompt=question, default='n').launch()
return answer
def add_filters_to_config(df: pd.DataFrame) -> List[List[FilterConfig]]:
config = Config()
should_add_filter = __inline_yes_or_no_question(__ADD_FILTER_QUESTION)
while should_add_filter:
config = add_filter_to_or_create_filter_group(df, config)
should_add_filter = __inline_yes_or_no_question(__ADD_FILTER_QUESTION)
return config.filters
def add_filter_to_or_create_filter_group(df: pd.DataFrame, config: Config) -> Config:
config_has_filters = len(config.filters) > 0
chosen_group = -1
if config_has_filters:
filter_options = [f'({"|".join(map(str, group)):.45s})' for group in config.filters]
filter_options = [f'Group{i+1}{s}' for i, s in enumerate(filter_options)]
cli = Bullet(
prompt="Select group: ",
choices=["Create new", *filter_options],
return_index=True,
)
chosen_group = cli.launch()[1] - 1
new_filter = create_filter_config(df)
if chosen_group < 0:
config.filters.append([new_filter])
else:
config.filters[chosen_group].append(new_filter)
return config
def create_filter_config(df: pd.DataFrame) -> FilterConfig:
options = list(df.columns)
cli = Bullet(
prompt="Select a columns to filter: ",
choices=list(map(str, options)),
return_index=True
)
chosen = cli.launch()[1]
filter_column = options[chosen]
columns_values = df[filter_column].unique()
values = Input(f'Which values fo filter out? values[{columns_values}]: ').launch()
new_filter = FilterConfig(column=filter_column, values=values)
return new_filter
def get_column(name: str) -> str:
answer = click.prompt(f'Which is your {name} column?', type=str, confirmation_prompt=True)
return answer

Loading…
Cancel
Save