Skip to content

Commit

Permalink
Merge pull request #69 from stsewd/read-from-paths
Browse files Browse the repository at this point in the history
LiraApp: load books from config file
  • Loading branch information
stsewd authored Oct 25, 2020
2 parents 6a830d0 + df8470b commit df8ee50
Show file tree
Hide file tree
Showing 13 changed files with 147 additions and 5 deletions.
10 changes: 7 additions & 3 deletions lira/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

from lira.ui import TerminalUI

books_path = Path(__file__).parent / "../tests/data/books/example/"

ui = TerminalUI(books_path)
ui.run()
def main():
books_path = Path(__file__).parent / "../tests/data/books/example/"
ui = TerminalUI(books_path)
ui.run()


main()
67 changes: 66 additions & 1 deletion lira/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import importlib
import logging
from pathlib import Path

from lira.config import CONFIG_DIR, DATA_DIR, LOG_DIR
import yaml

from lira.book import Book
from lira.config import CONFIG_DIR, CONFIG_FILE, DATA_DIR, LOG_DIR

log = logging.getLogger(__name__)


class LiraApp:
Expand All @@ -17,6 +24,64 @@ def _setup_logger(self):
level=logging.WARNING,
)

def _read_config(self):
if not CONFIG_FILE.exists():
log.info("Config file not found")
return {}
with CONFIG_FILE.open() as f:
config = yaml.safe_load(f)
return config

@property
def books(self):
"""
Load all books from the Lira configuration file.
Each book can be a dotted path to the module of the book,
or a local path to the directory of the book
(it can be a relative path to the config file).
.. code-block:: yaml
books:
# A dotted path to the module
- lira.books.intro
# A local path
- ~/local/path/to/book/
# A relative path to the config file
- relative/path
# Install from a package (maybe in the future)
- name: lira.book.basic
package: git+https://gifhub.com/pythonecuador/pythones-lirabook
- name: lira.book.basic
package: pythones-lirabook
"""
config = self._read_config()
books_list = []
for book_path in config.get("books", ["lira.books.intro"]):
path = Path(book_path).expanduser()
if not path.is_absolute():
path = (CONFIG_FILE.parent / path).resolve()

if path.exists() and path.is_dir():
books_list.append(Book(root=path))
else:
try:
package = importlib.import_module(book_path)
path = Path(package.__file__).parent
books_list.append(Book(root=path))
except ModuleNotFoundError:
log.warning("Unable to find book: %s", book_path)
except Exception as e:
log.warning(
"Unable to load book. path=%s error=%s",
book_path,
str(e),
)
return books_list

def setup(self):
self._create_dirs()
self._setup_logger()
Empty file added lira/books/__init__.py
Empty file.
Empty file added lira/books/intro/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions lira/books/intro/book.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
language: en
title: Intro to Lira
description: Introducction to Lira and how to write a Lira book
created: 24/10/2020
updated: 24/10/2020
authors:
- Santos Gallegos

contents:
Introducction: intro.rst
Showcase: showcase.rst
12 changes: 12 additions & 0 deletions lira/books/intro/intro.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
:level: easy
:tags: lira book

Lira
----

Lira is an interactive tutorial.

Writting a book
---------------

TODO
12 changes: 12 additions & 0 deletions lira/books/intro/showcase.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
:level: easy
:tags: showcase book

Basic elements
--------------

This is a paragraph with *some* nodes.
I'm a ``literal`` node, and I'm **strong**.

.. code-block:: python
print("Hello world!")
1 change: 1 addition & 0 deletions lira/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ def _get_data_dir():


CONFIG_DIR = _get_config_dir()
CONFIG_FILE = CONFIG_DIR / "config.yaml"
DATA_DIR = _get_data_dir()
LOG_DIR = DATA_DIR / "log"
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def tests(session):
@nox.session
def coverage(session):
session.install("coverage")
session.run("coverage", "report", "--fail-under", "79")
session.run("coverage", "report", "--fail-under", "84")
session.run("coverage", "html")


Expand Down
5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"PyYAML==5.3.1",
"prompt-toolkit==3.0.7",
],
entry_points={
"console_scripts": [
"lira=lira.__main__:main",
],
},
extras_require={"docs": ["sphinx==3.2.1"], "es": []},
classifiers=[
"Programming Language :: Python :: 3",
Expand Down
3 changes: 3 additions & 0 deletions tests/data/books/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
books:
- lira.books.intro
- example/
Empty file.
29 changes: 29 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pathlib import Path
from unittest import mock

from lira.app import LiraApp

data_dir = Path(__file__).parent / "data"
config_file = data_dir / "books/config.yaml"


class TestApp:
@mock.patch("lira.app.CONFIG_FILE", config_file)
def test_load_books(self):
app = LiraApp()
app.setup()

books = app.books
assert len(books) == 2

book_a, book_b = books
book_a.parse()
book_b.parse()

assert book_a.metadata["title"] == "Intro to Lira"
book_path = data_dir / "../../lira/books/intro"
assert book_a.root == book_path.resolve()

assert book_b.metadata["title"] == "Basic Introducction to Python"
book_path = data_dir / "books/example"
assert book_b.root == book_path

0 comments on commit df8ee50

Please sign in to comment.