Skip to content

Commit

Permalink
Refactor Codebase to Functional Structure (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
ohare93 committed Sep 6, 2020
2 parents aa8d320 + 5919cf9 commit ccf9718
Show file tree
Hide file tree
Showing 103 changed files with 4,315 additions and 3,556 deletions.
4 changes: 3 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ pytest = "==5.4.1"
args = "==0.1.0"
clint = "==0.5.1"
coverage = "==4.5.4"
PyYAML = "==5.1.2"
ruamel-yaml = "==0.16.10"
yamale = "==3.0.4"
PyYaml = "*"

[requires]
python_version = "3.7"
120 changes: 84 additions & 36 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions brain_brew/argument_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ def _set_parser_arguments(self):
type=str,
help="Global config file to use"
)

self.add_argument(
"-r", "--reversed",
"--verify", "-v",
action="store_true",
dest="run_reversed",
dest="verify_only",
default=False,
help="Run the builder file in reverse"
help="Only verify the builder contents, without running it."
)

def get_parsed(self, override_args=None):
Expand All @@ -42,9 +41,9 @@ def get_parsed(self, override_args=None):

# Optional
config_file = parsed_args.config_file
run_reversed = parsed_args.run_reversed
verify_only = parsed_args.verify_only

return builder, config_file, run_reversed
return builder, config_file, verify_only

def error_if_blank(self, arg):
if arg == "" or arg is None:
Expand Down
16 changes: 0 additions & 16 deletions brain_brew/build_tasks/build_task_generic.py

This file was deleted.

File renamed without changes.
70 changes: 70 additions & 0 deletions brain_brew/build_tasks/crowd_anki/crowd_anki_generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from dataclasses import dataclass, field
import logging
from typing import Union, Optional, List

from brain_brew.build_tasks.crowd_anki.headers_from_crowdanki import HeadersFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.headers_to_crowd_anki import HeadersToCrowdAnki
from brain_brew.build_tasks.crowd_anki.media_to_from_crowd_anki import MediaToFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.note_models_from_crowd_anki import NoteModelsFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.note_models_to_crowd_anki import NoteModelsToCrowdAnki
from brain_brew.build_tasks.crowd_anki.notes_from_crowd_anki import NotesFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.notes_to_crowd_anki import NotesToCrowdAnki
from brain_brew.representation.json.crowd_anki_export import CrowdAnkiExport
from brain_brew.representation.json.wrappers_for_crowd_anki import CrowdAnkiJsonWrapper
from brain_brew.representation.yaml.note_model_repr import NoteModel

from brain_brew.representation.build_config.build_task import TopLevelBuildTask
from brain_brew.representation.build_config.representation_base import RepresentationBase
from brain_brew.utils import all_combos_prepend_append


@dataclass
class CrowdAnkiGenerate(TopLevelBuildTask):
task_regex = r'.*crowd[\s_-]+?anki.*'

@dataclass
class Representation(RepresentationBase):
folder: str
notes: dict
note_models: dict
headers: dict
media: Union[dict, bool] = field(default_factory=lambda: False)

@classmethod
def from_repr(cls, data: Union[Representation, dict]):
rep: cls.Representation = data if isinstance(data, cls.Representation) else cls.Representation.from_dict(data)
return cls(
crowd_anki_export=CrowdAnkiExport.create_or_get(rep.folder),
notes_transform=NotesToCrowdAnki.from_repr(rep.notes),
note_model_transform=NoteModelsToCrowdAnki.from_repr(rep.note_models),
headers_transform=HeadersToCrowdAnki.from_repr(rep.headers),
media_transform=MediaToFromCrowdAnki.from_repr(rep.media)
)

crowd_anki_export: CrowdAnkiExport
notes_transform: NotesToCrowdAnki
note_model_transform: NoteModelsToCrowdAnki
headers_transform: HeadersToCrowdAnki
media_transform: MediaToFromCrowdAnki

def execute(self):
headers = self.headers_transform.execute()
ca_wrapper = CrowdAnkiJsonWrapper(headers)

note_models: List[dict] = self.note_model_transform.execute()

nm_name_to_id: dict = {model.name: model.id for model in self.note_model_transform.note_models}
notes = self.notes_transform.execute(nm_name_to_id)

media_files = self.media_transform.move_to_crowd_anki(
self.notes_transform.notes, self.note_model_transform.note_models, self.crowd_anki_export)

ca_wrapper.media_files = sorted([m.filename for m in media_files])
ca_wrapper.name = self.headers_transform.headers.name
ca_wrapper.note_models = note_models
ca_wrapper.notes = notes

# Set to CrowdAnkiExport
self.crowd_anki_export.write_to_files(ca_wrapper.data)
for media in media_files:
media.copy_source_to_target()
60 changes: 60 additions & 0 deletions brain_brew/build_tasks/crowd_anki/crowd_anki_to_deck_parts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import logging
from dataclasses import dataclass
from typing import Union, Optional, List

from brain_brew.build_tasks.crowd_anki.headers_from_crowdanki import HeadersFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.media_to_from_crowd_anki import MediaToFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.note_models_from_crowd_anki import NoteModelsFromCrowdAnki
from brain_brew.build_tasks.crowd_anki.notes_from_crowd_anki import NotesFromCrowdAnki
from brain_brew.representation.build_config.build_task import DeckPartBuildTask
from brain_brew.representation.build_config.representation_base import RepresentationBase
from brain_brew.representation.json.crowd_anki_export import CrowdAnkiExport
from brain_brew.representation.yaml.note_model_repr import NoteModel
from brain_brew.utils import all_combos_prepend_append


@dataclass
class CrowdAnkiToDeckParts(DeckPartBuildTask):
task_regex = r'.*crowd[\s_-]+?anki.*'

@dataclass
class Representation(RepresentationBase):
folder: str
notes: Optional[dict]
note_models: Optional[list]
headers: Optional[dict]
media: Optional[dict]

@classmethod
def from_repr(cls, data: Union[Representation, dict]):
rep: cls.Representation = data if isinstance(data, cls.Representation) else cls.Representation.from_dict(data)
return cls(
crowd_anki_export=CrowdAnkiExport.create_or_get(rep.folder),
notes_transform=NotesFromCrowdAnki.from_repr(rep.notes),
note_model_transform=NoteModelsFromCrowdAnki.from_list(rep.note_models),
headers_transform=HeadersFromCrowdAnki.from_repr(rep.headers),
media_transform=MediaToFromCrowdAnki.from_repr(rep.media)
)

crowd_anki_export: CrowdAnkiExport
notes_transform: NotesFromCrowdAnki
note_model_transform: NoteModelsFromCrowdAnki
headers_transform: HeadersFromCrowdAnki
media_transform: MediaToFromCrowdAnki

def execute(self):
ca_wrapper = self.crowd_anki_export.read_json_file()

if ca_wrapper.children:
logging.warning("Child Decks / Sub-decks are not currently supported.")

note_models: List[NoteModel] = self.note_model_transform.execute(ca_wrapper)

nm_id_to_name: dict = {model.crowdanki_id: model.name for model in note_models}
notes = self.notes_transform.execute(ca_wrapper, nm_id_to_name)

headers = self.headers_transform.execute(ca_wrapper)

media_files = self.media_transform.move_to_deck_parts(notes, note_models, self.crowd_anki_export)
for media in media_files:
media.copy_source_to_target()
Loading

0 comments on commit ccf9718

Please sign in to comment.