gabriel becker
2 years ago
commit
aca3d88c19
8 changed files with 143 additions and 0 deletions
@ -0,0 +1,23 @@
|
||||
# Ankimaker |
||||
|
||||
WIP |
||||
|
||||
A CLI app to generate anki decks. |
||||
|
||||
From csv file, with configurable parameters, filters and media. |
||||
|
||||
From epub, finding difficult* words in the book and getting their translations. |
||||
|
||||
*I still don't know what 'difficult' will mean. Probably difficult words will be less frequent words that are more frequent in the text than in some corpus, cut above a grade threshold. The grades will map percentiles of frequency. |
||||
|
||||
| Language Level | Number of Base Words Needed | |
||||
| ----- | ------ | |
||||
| A1 | 500| |
||||
| A2 | 1000| |
||||
| B1 | 2000| |
||||
| B2 | 4000| |
||||
| C1 | 8000| |
||||
| C2 | 16000| |
||||
|
||||
|
||||
This project is only possible because of the awesome work of genanki team. |
@ -0,0 +1,9 @@
|
||||
from ankimaker.commands import cli |
||||
|
||||
|
||||
def main(): |
||||
cli(prog_name='ankimaker') |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
@ -0,0 +1,7 @@
|
||||
import click |
||||
|
||||
@click.group("cli") |
||||
def cli(): |
||||
pass |
||||
|
||||
from ankimaker.commands.from_csv import generate_anki |
@ -0,0 +1,38 @@
|
||||
import click |
||||
import re |
||||
from ankimaker.commands import cli |
||||
from ankimaker.tasks import basic_pandas_to_anki |
||||
|
||||
|
||||
@cli.command('csv') |
||||
@click.option('-i', '--input', 'input_file', type=click.Path(exists=True)) |
||||
@click.option('-o', '--output', 'output_file', type=click.Path(exists=False)) |
||||
@click.option('-c', '--conf', 'config_file', default=None, type=click.STRING) |
||||
@click.option('-n', '--name', 'name', default=None, type=click.STRING) |
||||
def generate_anki( |
||||
input_file, |
||||
output_file, |
||||
name, |
||||
config_file, |
||||
): |
||||
output_file = parse_output(output_file) |
||||
if name is None: |
||||
name = get_name_from_output(output_file) |
||||
basic_pandas_to_anki(input_file, output_file, name) |
||||
|
||||
|
||||
def parse_output(filename): |
||||
filetype = filename.split('.')[-1] if len(filename.split('.')) > 0 else None |
||||
if filetype is None: |
||||
return filename + '.apkg' |
||||
elif filetype != 'apkg': |
||||
filename.replace(filetype, 'apkg') |
||||
return filename+filetype |
||||
else: |
||||
return filename |
||||
|
||||
|
||||
def get_name_from_output(filename): |
||||
updated_file = filename.split('/')[-1] if len(filename.split('/')) > 0 else filename |
||||
updated_file = re.sub(r'(.apkg)', '', updated_file) |
||||
return updated_file |
@ -0,0 +1 @@
|
||||
from .basic_csv_to_anki import basic_pandas_to_anki |
@ -0,0 +1,62 @@
|
||||
import genanki |
||||
import pandas as pd |
||||
|
||||
|
||||
def create_model(): |
||||
my_model = genanki.Model( |
||||
1607392319, |
||||
'Simple Model', |
||||
fields=[ |
||||
{'name': 'Question'}, |
||||
{'name': 'Answer'}, |
||||
], |
||||
templates=[ |
||||
{ |
||||
'name': 'Card 1', |
||||
'qfmt': '{{Question}}', |
||||
'afmt': '{{FrontSide}}<hr id="answer">{{Answer}}', |
||||
}, |
||||
]) |
||||
return my_model |
||||
|
||||
|
||||
def create_note(model, fields): |
||||
note = genanki.Note( |
||||
model=model, |
||||
fields=fields |
||||
) |
||||
return note |
||||
|
||||
|
||||
def create_deck(name): |
||||
deck = genanki.Deck( |
||||
2059400110, |
||||
name |
||||
) |
||||
return deck |
||||
|
||||
|
||||
def save_deck(deck, destination): |
||||
my_package = genanki.Package(deck) |
||||
# my_package.media_files = ['sound.mp3', 'images/image.jpg'] |
||||
my_package.write_to_file(destination) |
||||
|
||||
|
||||
def load_csv(path): |
||||
df = pd.read_csv(path, header=None) |
||||
return df |
||||
|
||||
|
||||
def add_df_to_deck(df: pd.DataFrame, deck: genanki.Deck): |
||||
model = create_model() |
||||
for x in df.to_dict('records'): |
||||
note = create_note(model, fields=(x[2], x[3])) |
||||
deck.add_note(note) |
||||
return deck |
||||
|
||||
|
||||
def basic_pandas_to_anki(csv_path, output_path, name): |
||||
df = load_csv(csv_path) |
||||
deck = create_deck(name) |
||||
add_df_to_deck(df, deck) |
||||
save_deck(deck, output_path) |
Loading…
Reference in new issue