Skip to content

Commit

Permalink
Merge pull request #5 from aseemsavio/ux-improvements
Browse files Browse the repository at this point in the history
Ux improvements
  • Loading branch information
aseemsavio authored Dec 22, 2022
2 parents b7b4bc0 + 82ab201 commit ec3e969
Show file tree
Hide file tree
Showing 21 changed files with 310 additions and 121 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ pip3 install --editable .
To create a distributable:

```
python3 setup.py sdist bidist_wheel
python3 setup.py sdist bdist_wheel
```
47 changes: 39 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,43 @@

[![Catholic CLI](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/aseemsavio/catholic-cli)

The `catholic-cli` is the Swiss Army Knife Command Line Utility for quickly accessing
Catholic information. The tool currently has the following functionalities:
The `catholic-cli` is an awesome Catholic Theological knowledge base.
The tool currently has the following functionalities:

1. Access information from **The Catechism** of The Catholic Church,
2. Access information from **The Roman Missal**,
3. Access Information from **The Canon Law** of The Catholic Church

### Installation

The prerequisite is to have Python 3 installed on your computer.

Type the following command on your terminal to install this.

```commandline
pip3 install catholic-cli
```

To do a clean update

```commandline
pip3 uninstall catholic-cli
pip3 install catholic-cli
```

### How to Interact with Catholic CLI

Non advanced users can simply type "catholic" in their terminal to start the application.
Then you can use the arrow keys on your keyboard to select the different options.

![img.png](img.png)

More advanced users can use the command line tool similar to any other CLI.

Typing `--help` at any level displays commands and arguments you can provide to the command at that level.

![img_1.png](img_1.png)

### General Syntax

The general syntax for using the tool is as follows.
Expand All @@ -27,10 +57,11 @@ The allowed sub-commands are:

The options currently supported by the `catholic-cli` are:

| | Option | Short Form | Data Type | Description | Commands/sub-commands that allow this option | Examples |
|-----|---------------|------------|-----------|-----------------------------------------|----------------------------------------------|-------------------------------------------------------------------------------|
| 1 | `--paragraph` | `--p` | INT, TEXT | Displays Paragraph(s) with the given ID | `catechism`<br/>`canon`<br/>`missal` | `--paragraph 10`<br/>`--p 10`<br/> `--p 1-5`<br/>`--p 1,2`<br/> `--p 1,2,4-5` |
| 2 | `--search` | `--s` | TEXT | Search for the given string | `catechism`<br/>`canon`<br/>`missal` | `--search "Christ"`<br/>`--s "eucharist"`<br/>`--s "The Church"` |
| 3 | `--help` | | BOOLEAN | Get help text | `catholic` | `--help` |
| 4 | `--version` | | BOOLEAN | Displays the version of this CLI | `catholic` | `--version` |
| | Option | Short Form | Data Type | Description | Commands/sub-commands that allow this option | Examples |
|-----|---------------|------------|-----------|-----------------------------------------|----------------------------------------------|---------------------------------------------------------------------------|
| 1 | `--paragraph` | `-p` | INT, TEXT | Displays Paragraph(s) with the given ID | `catechism`<br/>`canon`<br/>`missal` | `--paragraph 10`<br/>`-p 10`<br/> `-p 1-5`<br/>`-p 1,2`<br/> `-p 1,2,4-5` |
| 2 | `--search` | `-s` | TEXT | Search for the given string | `catechism`<br/>`canon`<br/>`missal` | `--search "Christ"`<br/>`-s "eucharist"`<br/>`-s "The Church"` |
| 3 | `--help` | | BOOLEAN | Get help text | `catholic` | `--help` |
| 4 | `--version` | | BOOLEAN | Displays the version of this CLI | `catholic` | `--version` |

Feel free to send PRs my way if you're willing to contribute to this project 🍻
26 changes: 14 additions & 12 deletions catholic/catholic.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import click

from catholic.commands import register_commands
from catholic.core.utils.docs import welcome_text
from catholic.commands.choice import interactive_cli
from catholic.core.utils.console import display_welcome_text
from catholic.version import version
from typer import Typer, Context

__version__ = version

# This is the root object to which all the commands get registered to.
cli = Typer()


@cli.callback(invoke_without_command=True)
def catholic_features_callback(ctx: Context):
# Execute this only if there is no sub command.
# https://typer.tiangolo.com/tutorial/commands/context/#exclusive-executable-callback

@click.group(help=welcome_text(__version__))
@click.version_option(__version__)
@click.pass_context
def cli(ctx: click.Context):
"""
Welcome to catholic-cli!
"""
ctx.obj = "Aseem Savio"
pass
if ctx.invoked_subcommand is None:
display_welcome_text()
interactive_cli()


register_commands(cli)
40 changes: 32 additions & 8 deletions catholic/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
import click
from typing import Optional

from catholic.commands.canon import canon
from catholic.commands.catechism import catechism
from catholic.commands.missal import missal
from typer import Typer, Option

from catholic.core.utils.docs import paragraph_help_text, search_help_text

def register_commands(group: click.Group):
group.add_command(cmd=catechism, name="catechism")
group.add_command(cmd=canon, name="canon")
group.add_command(cmd=missal, name="missal")
import catholic.core.catechism.api as catechism_api
import catholic.core.canon.api as canon_api
import catholic.core.missal.api as missal_api


def register_commands(cli: Typer):
"""
This function contains the logic to register the commands in this CLI.
:param cli: Typer Object to which we register commands
:return: None
"""

@cli.command(name="catechism", help="Query The catechism of The Catholic Church.")
def catechism_impl(paragraph: Optional[str] = Option(None, "--paragraph", "-p", help=paragraph_help_text()),
search: Optional[str] = Option(None, "--search", "-s", help=search_help_text())
):
catechism_api.execute(paragraph=paragraph, search=search)

@cli.command(name="canon", help="Query The Canon Law of The Catholic Church.")
def canon_impl(paragraph: Optional[str] = Option(None, "--paragraph", "-p", help=paragraph_help_text()),
search: Optional[str] = Option(None, "--search", "-s", help=search_help_text())
):
canon_api.execute(law=paragraph, search=search)

@cli.command(name="missal", help="Query The general Instruction of The Roman Missal.")
def missal_impl(paragraph: Optional[str] = Option(None, "--paragraph", "-p", help=paragraph_help_text()),
search: Optional[str] = Option(None, "--search", "-s", help=search_help_text())
):
missal_api.execute(missal_id=paragraph, search=search)
12 changes: 0 additions & 12 deletions catholic/commands/canon.py

This file was deleted.

12 changes: 0 additions & 12 deletions catholic/commands/catechism.py

This file was deleted.

81 changes: 81 additions & 0 deletions catholic/commands/choice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from dataclasses import dataclass
from enum import Enum
from typing import List

import questionary as q
from catholic.core.canon import api as canon_api
from catholic.core.catechism import api as catechism_api
from catholic.core.missal import api as missal_api


def interactive_cli():
"""
This function runs the CLI in an interactive mode for non-tech-savy users.
:return: None
"""

root = InteractiveCli(
messages=[
Resource("catechism", "The Catechism of The Catholic Church", [SearchBy.Para, SearchBy.Text]),
Resource("canon", "The Canon Law of The Church", [SearchBy.Para, SearchBy.Text]),
Resource("missal", "The Roman Missal", [SearchBy.Para, SearchBy.Text]),
]
)

###
# root = {
# "messages": {
# "catechism": "The Catechism of The Catholic Church",
# "canon": "The Canon Law of The Church",
# "missal": "The Roman Missal"
# }
# }

# by_para = "Search by Paragraph ID(s)"
# by_text = "Search by Text"

resource = q.select(
"What do you want to search?",
choices=[r.long_name for r in root.messages]
).ask()

resource_name = [r.short_name for r in root.messages if resource == r.long_name][0]

search_by = q.select(
"How do you want to search?",
choices=[str(v.value) for v in
[r for r in root.messages if r.short_name == resource_name][0].search_by_possibilities]
).ask()

para, search_text = None, None

# if search_by == by_para:
# para = q.text(f"Enter the {str(resource_name).capitalize()} paragraphs you wish to search: ").ask()
# else:
# search_text = q.text(f"Enter the exact text you wish to search in {resource}: ").ask()

if resource_name == "catechism":
catechism_api.execute(paragraph=None, search=None, search_by=SearchBy(search_by).name)

elif resource_name == "canon":
canon_api.execute(law=None, search=None, search_by=SearchBy(search_by).name)

elif resource_name == "missal":
missal_api.execute(missal_id=None, search=None, search_by=SearchBy(search_by).name)


class SearchBy(Enum):
Para = "Search by Paragraph ID(s)"
Text = "Search by Text"


@dataclass
class Resource:
short_name: str
long_name: str
search_by_possibilities: List[SearchBy]


@dataclass
class InteractiveCli:
messages: List[Resource]
12 changes: 0 additions & 12 deletions catholic/commands/missal.py

This file was deleted.

18 changes: 14 additions & 4 deletions catholic/core/canon/api.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
from rich.console import Console

from catholic.core.canon.services import get_canon_laws_with_given_substring, \
get_canon_law_paragraphs_by_paragraph_ids, display_canon_law, display_canon_laws
from catholic.core.utils.files import load_pickle_by_name
from catholic.core.utils.console import error, show_matched_para_count, emoji
from catholic.core.utils.console import error, show_matched_para_count
from catholic.core.utils.interact import prompt_para_or_search
from catholic.core.utils.query import decode_query


def execute(law, search):
def execute(law, search, search_by: str = None):
law, search = prompt_para_or_search(law,
search,
search_by,
"Canon",
"The Canon Law")

canon_law_dict = load_pickle_by_name("canon.pickle")
Console().line()

# --p or --paragraph is found in the command
if law:
Expand All @@ -22,12 +32,12 @@ def execute(law, search):
display_canon_laws(matched_laws)
show_matched_para_count(resource="Canon Law", matched=matched_laws, para=True)
except Exception:
error(f"{emoji('🙁')} Could not decode the query: {law}")
error(f"Could not decode the query: {law}")
# --s or --search is found in the command
elif search:
try:
matched_laws = get_canon_laws_with_given_substring(search, canon_law_dict)
display_canon_laws(matched_laws)
show_matched_para_count(resource="Canon Law", matched=matched_laws, search_str=True)
except Exception:
error(f"{emoji('🙁')} Could not decode the search string: {search}")
error(f"Could not decode the search string: {search}")
10 changes: 4 additions & 6 deletions catholic/core/canon/services.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from catholic.core.utils.console import blue_text, markdown, error, emoji
from catholic.core.utils.console import markdown, error
from catholic.core.utils.strings import string_contains


Expand Down Expand Up @@ -44,20 +44,18 @@ def get_canon_laws_with_given_substring(substring: str, canon: list[dict]) -> li

def display_laws_and_sub_laws(canon_law):
if "text" in canon_law:
blue_text(f"Canon Law: {canon_law['id']}")
markdown(canon_law["text"])
markdown(text=canon_law["text"], heading=f"Canon Law: {canon_law['id']}")
elif "sections" in canon_law:
for section in canon_law["sections"]:
blue_text(f"Canon Law: {canon_law['id']} :: §{section['id']}")
markdown(section["text"])
markdown(text=section["text"], heading=f"Canon Law: {canon_law['id']} :: §{section['id']}")


def display_canon_law(canon_law_dict, law):
try:
canon_law = get_canon_law_by_id(int(law), canon_law_dict)
display_laws_and_sub_laws(canon_law)
except IndexError:
error(f"{emoji('🙁')} There is no Canon Law with ID: {law}")
error(f"There is no Canon Law with ID: {law}")


def display_canon_laws(canon_law_dict: list[dict]):
Expand Down
19 changes: 15 additions & 4 deletions catholic/core/catechism/api.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
from rich.console import Console

from catholic.core.catechism.services import get_catechism_paragraphs_with_given_substring, \
get_catechism_paragraphs_by_paragraph_ids, display_catechism_paragraphs, display_catechism_paragraph
from catholic.core.utils.files import load_pickle_by_name
from catholic.core.utils.console import error, show_matched_para_count, emoji
from catholic.core.utils.console import error, show_matched_para_count
from catholic.core.utils.interact import prompt_para_or_search

from catholic.core.utils.query import decode_query


def execute(paragraph, search):
def execute(paragraph, search, search_by: str = None):
"""
This function is a work-around to achieve command aliasing between "catechism" and "c".
:param search_by:
:param search:
:param paragraph: Paragraph_number
:return: None
"""

paragraph, search = prompt_para_or_search(paragraph,
search,
search_by,
"Catechism",
"The Catechism of The Catholic Church")

catechism_dict = load_pickle_by_name("catechism.pickle")
Console().line()

# --p or --paragraph is found in the command
if paragraph:
Expand All @@ -31,7 +42,7 @@ def execute(paragraph, search):
display_catechism_paragraphs(matched_paragraphs)
show_matched_para_count(resource="Catechism", matched=matched_paragraphs, para=True)
except Exception:
error(f"{emoji('🙁')} Could not decode the query: {paragraph}")
error(f"Could not decode the query: {paragraph}")

# --s or --search is found in the command
elif search:
Expand All @@ -40,4 +51,4 @@ def execute(paragraph, search):
display_catechism_paragraphs(matched_catechism_paragraphs)
show_matched_para_count(resource="Catechism", matched=matched_catechism_paragraphs, search_str=True)
except Exception:
error(f"{emoji('🙁')} Could not decode the search string: {search}")
error(f"Could not decode the search string: {search}")
Loading

0 comments on commit ec3e969

Please sign in to comment.