Skip to content

Commit

Permalink
✨ Adding cancel subcommand (#26)
Browse files Browse the repository at this point in the history
* Adding cancel command

* Fixing linting issues

* Adding extra tests

* Adding links to README

* Bumping version
  • Loading branch information
jossmoff authored Nov 9, 2023
1 parent f69a265 commit 09e9c6d
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 17 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@ The base command for the `bookshelf` CLI.

#### Subcommands

| Name | Description |
| ----------- | ----------- |
| <a href="/reference/create/">create</a> | Create a new story for your bookshelf |
| <a href="/reference/create/">finish </a> | Finish writing a story on your bookshelf |
| <a href="/reference/create/">info </a> | Displays the information for a given story on your bookshelf |
| <a href="/reference/create/">ls </a> | List all the current stories on your bookshelf |
| <a href="/reference/create/">rm </a> | Remove a story from your bookshelf |
| <a href="/reference/create/">start </a> | Start a new chapter for a story on your bookshelf |
| <a href="/reference/create/">stop </a> | Stop the current chapter of a story on your bookshelf |
| Name | Description |
|--------------------------------------------------------------------------|--------------------------------------------------------------|
| <a href="https://bookshelf.docs.joss.dev/reference/create/">cancel</a> | Cancel the current chapter of a story on your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/create/">create</a> | Create a new story for your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/finish/">finish </a> | Finish writing a story on your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/info/">info </a> | Displays the information for a given story on your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/ls/">ls </a> | List all the current stories on your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/rm/">rm </a> | Remove a story from your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/start/">start </a> | Start a new chapter for a story on your bookshelf |
| <a href="https://bookshelf.docs.joss.dev/reference/stop/">stop </a> | Stop the current chapter of a story on your bookshelf |

## 🤝 Contributing

Expand Down
2 changes: 1 addition & 1 deletion bookshelf/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.0"
__version__ = "0.3.0"
28 changes: 24 additions & 4 deletions bookshelf/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from bookshelf.storage import BookshelfStorage
from bookshelf.models import Chapter, Story
from bookshelf.exceptions import StoryAlreadyExistsException, StoryNotFoundException, ChapterInProgressException, \
StoryAlreadyFinishedException
StoryAlreadyFinishedException, ChapterNotInProgressException
from bookshelf.param_types import StoryType

bookshelf_storage = BookshelfStorage()
Expand Down Expand Up @@ -59,10 +59,9 @@ def create_story_entry(story_name: str, force: bool, tags: str, start_chapter: b
story.add_chapter(Chapter(start_time))

bookshelf_storage.save_story(story)

bookshelf_console.render_story_panel(story)
except KeyboardInterrupt:
pass
bookshelf_console.print(f'📕 Story \'{story_name}\' has been created!')


@bookshelf.command(name='start')
Expand All @@ -88,7 +87,7 @@ def start_chapter_entry(story_name):
bookshelf_storage.save_story(story)
bookshelf_console.render_story_panel(story)
except KeyboardInterrupt:
pass
bookshelf_console.print(f'📖 A new chapter in \'{story_name}\' has been started!')


@bookshelf.command(name='stop')
Expand Down Expand Up @@ -159,3 +158,24 @@ def story_info_entry(story_name: str):
bookshelf_console.render_story_panel(story)
except KeyboardInterrupt:
pass


@bookshelf.command(name='cancel')
@click.argument('story_name', type=story_type)
def cancel_chapter(story_name):
"""Cancel the current chapter of a story on your bookshelf"""
try:
if not bookshelf_storage.story_exists(story_name):
raise StoryNotFoundException(story_name)

story = bookshelf_storage.load_story(story_name)

if not story.in_progress():
raise ChapterNotInProgressException(story_name)

story.cancel_chapter()

bookshelf_storage.save_story(story)
bookshelf_console.render_story_panel(story)
except KeyboardInterrupt:
bookshelf_console.print(f'❌ Current chapter in \'{story_name}\' has been cancelled!')
3 changes: 3 additions & 0 deletions bookshelf/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def add_chapter(self, chapter: Chapter) -> None:
def get_last_chapter(self) -> Chapter:
return self.chapters[-1]

def cancel_chapter(self) -> None:
self.chapters.pop()

def finish_chapter(self) -> None:
if self.in_progress():
self.get_last_chapter().end_time = datetime.now()
Expand Down
1 change: 1 addition & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default defineConfig({
items: [
// Each item here is one entry in the navigation menu.
{ label: 'Use the bookshelf command line', link: '/reference/use-bookshelf-cli/' },
{ label: 'bookshelf cancel', link: '/reference/cancel/' },
{ label: 'bookshelf create', link: '/reference/create/' },
{ label: 'bookshelf finish', link: '/reference/finish/' },
{ label: 'bookshelf info', link: '/reference/info/' },
Expand Down
40 changes: 40 additions & 0 deletions docs/src/content/docs/reference/cancel.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: bookshelf cancel
description: Cancel the current chapter of a story on your bookshelf
---

### Usage

```bash
bookshelf cancel [OPTIONS] STORY_NAME
```

### Description

Use `bookshelf cancel` to cancel the current chapter of a story on your bookshelf. The story must exist and have a chapter in progress.
This command is useful if you need quickly stop tracking an existing story.

### Options

| Name | Shorthand | Default | Description |
|------- | --------- | ------- | ----------- |
| | | | |

### Examples

#### Cancel a story
<pre><span style="background-color:#26384B"><font color="#93FF91"> root </font></span><font color="#26384B"></font> <font color="#49FF6D">bookshelf</font> cancel example-story
╭───────────────── 📖 Story 📖 ──────────────────╮
│ <b>✏️ Name:</b> │
│ example-story │
│ <b>🗓️ Start Date:</b> │
│ 22/10/2023 │
│ <b>⏱️ Elapsed Time:</b> │
│ 0 hours, 0 minutes, 0 seconds │
│ <b>🏷️ Tags:</b> │
[]
│ │
[Press <b>CTRL+C</b> to exit]
╰────────────────────────────────────────────────╯</pre>


14 changes: 11 additions & 3 deletions test/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from assertpy import assert_that

from bookshelf.models import Chapter, Story
from test.utils.chapter_utils import create_chapter_from_delta
from test.utils.chapter_utils import create_chapter_from_delta, create_in_progress_chapter

STORY_NAME = 'TEST_STORY'

Expand Down Expand Up @@ -46,7 +46,6 @@ def test_chapter_to_dict(sample_chapter):
def test_story_to_dict(sample_story):
story_dict = sample_story.to_json()
assert_that(story_dict).is_equal_to(STORY_JSON)
assert story_dict == STORY_JSON


def test_story_from_dict():
Expand All @@ -65,5 +64,14 @@ def test_compute_duration_from_chapters():
chapter2 = create_chapter_from_delta(timedelta(hours=1))
chapters = [chapter1, chapter2]
story = Story(STORY_NAME, datetime(2023, 1, 1, 10, 0), datetime(2023, 1, 1, 14, 0), chapters)
assert_that(story.compute_elapsed_time_from_chapters()).is_equal_to(timedelta(hours=2))

assert story.compute_elapsed_time_from_chapters() == timedelta(hours=2)

def test_cancel_chapter():
chapter1 = create_chapter_from_delta(timedelta(hours=1))
chapter2 = create_chapter_from_delta(timedelta(hours=1))
in_progress_chapter = create_in_progress_chapter()
chapters = [chapter1, chapter2, in_progress_chapter]
story = Story(STORY_NAME, datetime(2023, 1, 1, 10, 0), datetime(2023, 1, 1, 14, 0), chapters)
story.cancel_chapter()
assert_that(story.chapters).contains_only(chapter1, chapter2)
5 changes: 5 additions & 0 deletions test/utils/chapter_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from bookshelf.models import Chapter


def create_in_progress_chapter() -> Chapter:
start_time = datetime.now()
return Chapter(start_time)


def create_chapter_from_delta(delta: timedelta, start_time: Optional[datetime] = None) -> Chapter:
if start_time is None:
start_time = datetime.now()
Expand Down

0 comments on commit 09e9c6d

Please sign in to comment.