summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddy Pedroni <epedroni@pm.me>2024-09-26 10:02:15 +0200
committerEddy Pedroni <epedroni@pm.me>2024-09-26 10:02:15 +0200
commite65bef9c22244fc9bcd22a37d335f5f76ba16ff5 (patch)
tree9af6fa41bfee6fc03c3ab30cf1b23a82bdf8f2e7
parentce76b00d7b2ccac6843732f92becfabb753864a0 (diff)
Create separate packages for library and CLI
-rw-r--r--.gitignore1
-rwxr-xr-xbootstrap-venv.sh1
-rw-r--r--cli-project/flashcard_cli.py (renamed from src/flashcard_cli.py)7
-rw-r--r--cli-project/pyproject.toml19
-rwxr-xr-xflashcards92
-rw-r--r--flashcards-project/pyproject.toml14
-rw-r--r--flashcards-project/src/flashcards/__init__.py2
-rw-r--r--flashcards-project/src/flashcards/card.py (renamed from src/card.py)1
-rw-r--r--flashcards-project/src/flashcards/parser.py (renamed from src/parser.py)4
-rw-r--r--flashcards-project/src/flashcards/scheduler.py (renamed from src/scheduler.py)5
-rw-r--r--flashcards-project/src/flashcards/scheduler_brutal.py (renamed from src/scheduler_brutal.py)5
-rw-r--r--flashcards-project/src/flashcards/session.py (renamed from src/session.py)9
-rw-r--r--flashcards-project/src/flashcards/state_json.py (renamed from src/state_json.py)1
-rw-r--r--requirements.txt2
-rw-r--r--tests/parser_unittest.py (renamed from src/parser_unittest.py)3
-rw-r--r--tests/scheduler_brutal_unittest.py (renamed from src/scheduler_brutal_unittest.py)7
-rw-r--r--tests/session_integrationtest.py (renamed from src/session_integrationtest.py)3
-rw-r--r--tests/state_json_unittest.py (renamed from src/state_json_unittest.py)3
18 files changed, 64 insertions, 115 deletions
diff --git a/.gitignore b/.gitignore
index 92afa22..fb4ac55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
__pycache__/
venv/
+**/*.egg-info
diff --git a/bootstrap-venv.sh b/bootstrap-venv.sh
index b105996..f3c5580 100755
--- a/bootstrap-venv.sh
+++ b/bootstrap-venv.sh
@@ -1,4 +1,5 @@
#!/usr/bin/zsh
+rm -r venv
python -m venv venv
./venv/bin/pip install -r requirements.txt
diff --git a/src/flashcard_cli.py b/cli-project/flashcard_cli.py
index be05be8..27a3a77 100644
--- a/src/flashcard_cli.py
+++ b/cli-project/flashcard_cli.py
@@ -1,15 +1,13 @@
import click
from random import shuffle
-from scheduler import SCHEDULERS
-from session import Session
-from card import Card
+from flashcards import Session, SCHEDULERS
@click.group()
def cli():
pass
-def displayCard(card: Card, index: int, random_flip: bool) -> None:
+def displayCard(card, index: int, random_flip: bool) -> None:
click.echo(click.style(f"{index + 1} ===========================================================", fg="blue"))
faces = [card.front, card.back]
@@ -21,7 +19,6 @@ def displayCard(card: Card, index: int, random_flip: bool) -> None:
input()
click.echo(faces.pop(0))
-
@cli.command()
@click.argument("state_file", nargs=1, type=click.Path())
@click.argument("card_files", nargs=-1, type=click.Path(exists=True))
diff --git a/cli-project/pyproject.toml b/cli-project/pyproject.toml
new file mode 100644
index 0000000..333c9cd
--- /dev/null
+++ b/cli-project/pyproject.toml
@@ -0,0 +1,19 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "flashcards_cli"
+authors = [
+ {name = "Eddy Pedroni", email = "epedroni@pm.me"},
+]
+description = "A CLI frontend for the flashcards library"
+requires-python = ">=3.12"
+dependencies = [
+ "click",
+ "flashcards"
+]
+dynamic = ["version"]
+
+[project.scripts]
+flashcard_cli = "flashcard_cli:cli"
diff --git a/flashcards b/flashcards
deleted file mode 100755
index e0ba548..0000000
--- a/flashcards
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/python3
-
-import re
-import sys
-from pathlib import Path
-from random import shuffle
-
-class Color:
- PURPLE = '\033[95m'
- CYAN = '\033[96m'
- DARKCYAN = '\033[36m'
- BLUE = '\033[94m'
- GREEN = '\033[92m'
- YELLOW = '\033[93m'
- RED = '\033[91m'
- BOLD = '\033[1m'
- UNDERLINE = '\033[4m'
- END = '\033[0m'
-
-#print color.BOLD + 'Hello World !' + color.END
-
-cardRegex = "CARD: "
-prefixLength = len(cardRegex)
-
-# Returns a list of Path objects, containing the path to each valid file provided
-def getFileList():
- fileList = []
- if len(sys.argv) > 1:
- for f in sys.argv[1:]:
- path = Path(f)
- if path.exists() and path.is_file():
- fileList.append(f)
- return fileList
- else:
- print("Missing arguments")
- sys.exit()
-
-# Returns cards in the form [(front, back)]
-def createCardList(files):
- cards = []
- for f in files:
- cards = cards + extractCards(f)
- return cards
-
-# Extracts cards from a single file into a list of the form [(front, back)]
-def extractCards(f):
- front = ""
- back = ""
- cards = []
- with open(f) as cardFile:
- for l in cardFile:
- match = re.match(cardRegex, l)
- if match:
- if front != "":
- cards.append([front.strip(), back.strip()])
- back = ""
- front = match.string[prefixLength:]
- else:
- back += l
- # do the last front-back pair before returning
- cards.append([front.strip(), back.strip()])
- return cards
-
-# Waits for user input and reacts accordingly
-def wait():
- cmd = input().strip()
- if cmd.startswith("q") or cmd.startswith("quit") or cmd.startswith("exit"):
- sys.exit(0)
-
-# Loops serving cards to the user until the program is exited
-def serveCards(cards):
- while True:
- for i, card in enumerate(cards):
- print("----------------------------------------------------------------------------(" + str(i + 1) + "/" + str(len(cards)) + ")")
- print(Color.BLUE + Color.BOLD + card[0] + Color.END)
- wait()
- print(card[1])
- wait()
-
-def debugCards(cardList):
- for c in cardList:
- print("Front:", c[0])
- print("Back:", c[1])
-
-def main():
- files = getFileList()
- cards = createCardList(files)
- shuffle(cards)
- serveCards(cards)
-
-if __name__ == "__main__":
- main()
diff --git a/flashcards-project/pyproject.toml b/flashcards-project/pyproject.toml
new file mode 100644
index 0000000..06a6931
--- /dev/null
+++ b/flashcards-project/pyproject.toml
@@ -0,0 +1,14 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "flashcards"
+authors = [
+ {name = "Eddy Pedroni", email = "epedroni@pm.me"},
+]
+description = "A library for memorising information with flashcards"
+requires-python = ">=3.12"
+dependencies = [
+]
+dynamic = ["version"]
diff --git a/flashcards-project/src/flashcards/__init__.py b/flashcards-project/src/flashcards/__init__.py
new file mode 100644
index 0000000..38c9936
--- /dev/null
+++ b/flashcards-project/src/flashcards/__init__.py
@@ -0,0 +1,2 @@
+from .session import Session
+from .scheduler import SCHEDULERS
diff --git a/src/card.py b/flashcards-project/src/flashcards/card.py
index c2243a6..3278343 100644
--- a/src/card.py
+++ b/flashcards-project/src/flashcards/card.py
@@ -3,7 +3,6 @@ Defines a struct representing a single card. The struct takes the form:
(front, back)
"""
-
from collections import namedtuple
from hashlib import md5
diff --git a/src/parser.py b/flashcards-project/src/flashcards/parser.py
index 11bb0c6..38abdcc 100644
--- a/src/parser.py
+++ b/flashcards-project/src/flashcards/parser.py
@@ -26,11 +26,11 @@ The cards are represented in dictionary entries of the form:
id: card.Card
"""
-
from pathlib import Path
from enum import Enum
from typing import TextIO, Iterator
-from card import Card, getId
+
+from .card import Card, getId
def _getCard(front_lines: list[str], back_lines: list[str]) -> tuple[str, Card]:
front_text = "".join(front_lines).strip()
diff --git a/src/scheduler.py b/flashcards-project/src/flashcards/scheduler.py
index e1c783b..a9d9470 100644
--- a/src/scheduler.py
+++ b/flashcards-project/src/flashcards/scheduler.py
@@ -1,6 +1,7 @@
from typing import Protocol
from abc import abstractmethod
-from card import Card
+
+from .card import Card
class Scheduler(Protocol):
"""
@@ -54,7 +55,7 @@ def getSchedulerClass(name: str) -> Scheduler:
"""
match name:
case "brutal":
- from scheduler_brutal import SchedulerBrutal
+ from .scheduler_brutal import SchedulerBrutal
return SchedulerBrutal
case _:
raise Exception(f"Unknown scheduler: {name}")
diff --git a/src/scheduler_brutal.py b/flashcards-project/src/flashcards/scheduler_brutal.py
index f0bfe99..ebbc0ff 100644
--- a/src/scheduler_brutal.py
+++ b/flashcards-project/src/flashcards/scheduler_brutal.py
@@ -1,7 +1,8 @@
-from scheduler import Scheduler
-from card import Card
from random import shuffle
+from .scheduler import Scheduler
+from .card import Card
+
HISTORY_DEPTH = 8
class SchedulerBrutal(Scheduler):
diff --git a/src/session.py b/flashcards-project/src/flashcards/session.py
index f30160f..da444dd 100644
--- a/src/session.py
+++ b/flashcards-project/src/flashcards/session.py
@@ -1,9 +1,9 @@
from typing import Iterator, Callable
-from card import Card
-from scheduler import getSchedulerClass
-from parser import parseFiles
-from state_json import load, save
+from .card import Card
+from .scheduler import getSchedulerClass
+from .parser import parseFiles
+from .state_json import load, save
class Session:
"""
@@ -48,3 +48,4 @@ class Session:
self._scheduler.update(results)
save(self._state_file, self._scheduler.getState())
+
diff --git a/src/state_json.py b/flashcards-project/src/flashcards/state_json.py
index a0b487e..673d904 100644
--- a/src/state_json.py
+++ b/flashcards-project/src/flashcards/state_json.py
@@ -1,7 +1,6 @@
"""
Helper functions to store scheduler state as json
"""
-
import json
from pathlib import Path
diff --git a/requirements.txt b/requirements.txt
index ad90bc2..17a9a3d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,4 @@
click
pytest
+-e flashcards-project
+-e cli-project
diff --git a/src/parser_unittest.py b/tests/parser_unittest.py
index 8d0d600..8076369 100644
--- a/src/parser_unittest.py
+++ b/tests/parser_unittest.py
@@ -1,7 +1,8 @@
import pytest
-import parser
from pathlib import Path
+from flashcards import parser
+
# Happy path
def test_validFile(tmp_path):
file_contents = """
diff --git a/src/scheduler_brutal_unittest.py b/tests/scheduler_brutal_unittest.py
index 8dc72fe..a87e5e9 100644
--- a/src/scheduler_brutal_unittest.py
+++ b/tests/scheduler_brutal_unittest.py
@@ -1,7 +1,8 @@
import pytest
-import scheduler_brutal
-from scheduler_brutal import SchedulerBrutal as UUT
-from card import Card
+
+from flashcards import scheduler_brutal
+from flashcards.scheduler_brutal import SchedulerBrutal as UUT
+from flashcards.card import Card
# Force HISTORY_DEPTH to simplify testing
scheduler_brutal.HISTORY_DEPTH = 3
diff --git a/src/session_integrationtest.py b/tests/session_integrationtest.py
index 2c5d608..ddabff9 100644
--- a/src/session_integrationtest.py
+++ b/tests/session_integrationtest.py
@@ -1,6 +1,7 @@
import pytest
import json
-from session import Session
+
+from flashcards.session import Session
@pytest.fixture
def cardFiles(tmp_path):
diff --git a/src/state_json_unittest.py b/tests/state_json_unittest.py
index e784f58..03ea555 100644
--- a/src/state_json_unittest.py
+++ b/tests/state_json_unittest.py
@@ -1,5 +1,6 @@
import pytest
-import state_json
+
+from flashcards import state_json
def test_saveAndLoad(tmp_path):
file = tmp_path / "test.json"