Skip to content

Commit 72217c6

Browse files
committed
fix some linter issues
1 parent 928da60 commit 72217c6

6 files changed

Lines changed: 526 additions & 4 deletions

File tree

src/trackr/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
1+
"""
2+
This module provides version information and explicitly defines module exports.
3+
4+
The module defines the `__version__` string for tracking the version of the
5+
application and an `__all__` specifier to limit the public objects made available
6+
when `import *` is used on the module.
7+
8+
Attributes:
9+
__all__ (list of str): Defines the public API of the module.
10+
__version__ (str): Specifies the version of the module.
11+
"""
12+
13+
114
__all__ = ["__version__"]
15+
216
__version__ = "0.1.2"

src/trackr/cli.py

Lines changed: 190 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
21
"""
3-
CLI funtions
2+
A command-line interface (CLI) application for managing a follow-up tracker.
3+
4+
This module provides various commands to initialize a local database, manage
5+
items, and handle metadata and notes associated with each item. The CLI offers
6+
operations to add, update, list, and review items, with robust error handling
7+
for invalid inputs and clipboard interactions.
48
"""
59

610

@@ -53,7 +57,28 @@ def add( # pylint: disable=too-many-arguments,too-many-positional-arguments
5357
meta: Optional[str] = typer.Option(None, help='JSON object, e.g. {"company":"X"}'),
5458
description: Optional[str] = typer.Option(None, "--desc", help="Long description"),
5559
) -> None:
56-
"""Add a new item."""
60+
"""
61+
Add a new item to the inventory system.
62+
63+
This command registers a new item using the provided details such as an
64+
ID, title, state, and optional information like a review date, metadata,
65+
and a detailed description.
66+
67+
:param item_id: The unique identifier for the item.
68+
:type item_id: str
69+
:param title: The title of the item.
70+
:type title: str
71+
:param state: The initial state of the item (default: "created").
72+
:type state: str
73+
:param next_review: The date of the next review in "YYYY-MM-DD" format, if applicable.
74+
:type next_review: Optional[str]
75+
:param meta: Additional metadata in JSON format (e.g., {"company": "X"}).
76+
:type meta: Optional[str]
77+
:param description: A detailed description of the item.
78+
:type description: Optional[str]
79+
:return: None
80+
"""
81+
5782
init_db()
5883
try:
5984
meta_obj = json.loads(meta) if meta else {}
@@ -100,6 +125,18 @@ def apply(
100125
def note_from_clipboard(
101126
item_id: str = typer.Argument(..., help="Item id"),
102127
) -> None:
128+
"""
129+
Add clipboard text as a note to the specified item.
130+
131+
The function retrieves the current text content from the clipboard,
132+
validates it, and attaches it as a note to the item identified by the
133+
given item ID. If the clipboard is empty or an invalid operation
134+
occurs while adding the note, the function raises relevant errors.
135+
136+
:param item_id: Identifier of the item to which the clipboard text will
137+
be added as a note.
138+
:return: This function does not return a value.
139+
"""
103140
"""Add clipboard text as note."""
104141
init_db()
105142
clip = pyperclip.paste().strip()
@@ -123,6 +160,26 @@ def add_from_clipboard( # pylint: disable=too-many-arguments,too-many-positional
123160
source_url: Optional[str] = typer.Option(None, help="Explicit source URL"),
124161
meta_items: list[str] = typer.Option(None, "--meta", help="Extra metadata as key=value"),
125162
) -> None:
163+
"""
164+
Create an item using clipboard text as the title or description. If text from the clipboard is not
165+
available, a provided title can be used instead. Additional metadata such as item state, source,
166+
and review date can also be specified. Metadata extracted from the clipboard text or explicitly
167+
provided will be used to populate the item's attributes.
168+
169+
Handles clipboard interaction, metadata extraction, and item creation with support for additional
170+
options and error handling for invalid inputs.
171+
172+
:param item_id: The unique identifier for the item to be created.
173+
:param title: An optional title override for the item. Defaults to the first 120 characters of the
174+
clipboard text if not provided.
175+
:param state: The initial state of the item, defaults to "created".
176+
:param next_review: An optional field indicating the next review date of the item in "YYYY-MM-DD"
177+
format.
178+
:param source: An optional explicit source for the item (e.g., publication name or reference).
179+
:param source_url: An optional explicit URL source for the item (e.g., link to the original content).
180+
:param meta_items: A list of additional metadata key-value pairs in the format "key=value".
181+
:return: None
182+
"""
126183
"""Create item using clipboard text as title or description."""
127184
init_db()
128185

@@ -173,6 +230,24 @@ def list_cmd(
173230
help="Comma separated fields (id,title,state,...)"
174231
),
175232
) -> None:
233+
"""
234+
List items based on optional filtering criteria and display results in a
235+
human-readable format. This function allows filtering by state and selecting
236+
specific fields for display.
237+
238+
:param state: Optional filter to specify the state of items. If provided,
239+
only items matching this state will be listed.
240+
:type state: Optional[str]
241+
:param fields: Optional comma-separated string of field names to specify the
242+
fields to be included in the output. Valid fields include 'id', 'title',
243+
'description', 'state', 'next_review', and 'last_event_at'.
244+
:type fields: Optional[str]
245+
:return: This function does not return a value but prints the list of items
246+
to the console.
247+
:rtype: None
248+
:raises typer.BadParameter: If the state filter is invalid or if one of the
249+
specified fields in the fields parameter is not valid.
250+
"""
176251
"""List items."""
177252
init_db()
178253

@@ -223,7 +298,21 @@ def list_cmd(
223298

224299
@app.command()
225300
def show(item_id: str = typer.Argument(..., help="Item id")) -> None:
226-
"""Show one item and recent events."""
301+
"""
302+
Show one item and recent events.
303+
304+
This function retrieves and displays the details of an item and its recent events.
305+
The item is fetched based on the provided item ID. If the item does not exist, an
306+
error is raised. The function outputs the item's details, metadata, and recent events
307+
in a formatted manner.
308+
309+
:param item_id: The unique identifier for the item to be displayed.
310+
:type item_id: str
311+
:return: None
312+
:rtype: None
313+
:raises typer.BadParameter: If the item with the specified ID is not found.
314+
"""
315+
227316
init_db()
228317
item, events = get_item(item_id)
229318
if item is None:
@@ -250,6 +339,20 @@ def show(item_id: str = typer.Argument(..., help="Item id")) -> None:
250339

251340
@app.command("state")
252341
def set_state_cmd(item_id: str = typer.Argument(...), new_state: str = typer.Argument(...)) -> None:
342+
"""
343+
Change the state of a specified item.
344+
345+
This function initializes the database connection and attempts to change the
346+
state of the item identified by the given `item_id` to the specified
347+
`new_state`. If the provided state is invalid, an appropriate error message is
348+
raised, and the program exits with a bad parameter error.
349+
350+
:param item_id: The unique identifier of the item whose state is to be changed.
351+
:type item_id: str
352+
:param new_state: The new state to assign to the specified item.
353+
:type new_state: str
354+
:return: None
355+
"""
253356
"""Change item state."""
254357
init_db()
255358
try:
@@ -261,6 +364,20 @@ def set_state_cmd(item_id: str = typer.Argument(...), new_state: str = typer.Arg
261364

262365
@app.command()
263366
def note(item_id: str = typer.Argument(...), text: str = typer.Argument(...)) -> None:
367+
"""
368+
Add a note to an item.
369+
370+
This command allows the user to append a textual note to a specific item
371+
designated by its unique identifier. The input values are processed and
372+
persisted internally via supporting database functions. If invalid parameters
373+
are provided, an appropriate error message is raised.
374+
375+
:param item_id: The unique identifier of the item to which the note will be
376+
added.
377+
:param text: The content of the note to be added to the item.
378+
:return: None
379+
:raises typer.BadParameter: If the provided input parameters are invalid.
380+
"""
264381
"""Add a note to an item."""
265382
init_db()
266383
try:
@@ -275,6 +392,19 @@ def set_review_cmd(
275392
item_id: str = typer.Argument(...),
276393
next_review: Optional[str] = typer.Argument(..., help="YYYY-MM-DD or empty string"),
277394
) -> None:
395+
"""
396+
Set the next review date for a specific item.
397+
398+
This function updates the "next review date" for an item identified by its
399+
unique item ID. If an empty string is provided for the next review date,
400+
it will be set to ``None``.
401+
402+
:param item_id: The unique identifier of the item whose review date is
403+
being set.
404+
:param next_review: The next review date in the format ``YYYY-MM-DD``
405+
or an empty string if no date is specified.
406+
:return: None
407+
"""
278408
"""Set next review date."""
279409
init_db()
280410
try:
@@ -291,6 +421,19 @@ def review(
291421
help="Show only overdue/ready waityou items"
292422
)
293423
) -> None:
424+
"""
425+
Show the review agenda of items based on their status.
426+
427+
This command displays categorized lists of items based on their
428+
status: "waitme", "waityou", and optionally "created". The "due_only"
429+
option allows filtering to display only overdue or ready "waityou"
430+
items.
431+
432+
:param due_only: A boolean option to specify whether to display only
433+
overdue or ready "waityou" items. If False, items
434+
from all categories will be displayed.
435+
:return: None
436+
"""
294437
"""Show review agenda."""
295438
init_db()
296439
groups = review_items(due_only=due_only)
@@ -311,6 +454,20 @@ def review(
311454

312455
@app.command("import-yaml")
313456
def import_yaml(path: Path = typer.Argument(..., exists=True, readable=True)) -> None:
457+
"""
458+
Import or upsert items from a YAML file.
459+
460+
This function processes a YAML file specified by the user, validates its content,
461+
and imports or upserts the items into the system database. The YAML file must
462+
contain a top-level key called "items" with its value being a list of objects.
463+
Each object in the list is processed and imported individually.
464+
465+
:param path: The file path to the YAML file to import. The file must exist
466+
and be readable.
467+
:return: None
468+
:raises typer.BadParameter: If the YAML content doesn't meet the required
469+
structure or any individual item within the file is invalid.
470+
"""
314471
"""Import or upsert items from YAML."""
315472
init_db()
316473
with path.open("r", encoding="utf-8") as f:
@@ -335,6 +492,23 @@ def import_yaml(path: Path = typer.Argument(..., exists=True, readable=True)) ->
335492

336493
@app.command("export-yaml")
337494
def export_yaml(path: Path = typer.Argument(...)) -> None:
495+
"""
496+
Export all items to a YAML file at the specified path.
497+
498+
This function initializes the database, retrieves all items using the
499+
`export_items` function, and creates a YAML file containing those items.
500+
If necessary, it creates the parent directories of the provided path.
501+
The YAML file is organized with Unicode compatibility and keys are not
502+
sorted alphabetically.
503+
504+
:param path: The file path where the YAML file will be exported. The path
505+
is created if it does not already exist.
506+
:type path: Path
507+
:return: This function does not return a value. It writes the exported
508+
data to a file and outputs a message indicating the number of
509+
items exported.
510+
:rtype: None
511+
"""
338512
"""Export all items to YAML."""
339513
init_db()
340514
payload = {"items": export_items()}
@@ -371,6 +545,18 @@ def history_cmd(
371545
item_id: str = typer.Argument(..., help="Item id"),
372546
limit: int = typer.Option(50, help="How many events to show"),
373547
) -> None:
548+
"""
549+
Show full event history for one item.
550+
551+
This command fetches and displays the complete event history related to a
552+
specific item, based on the provided item ID. The number of history events
553+
to display can be limited using the `limit` option.
554+
555+
:param item_id: The unique identifier of the item whose event history
556+
is to be displayed.
557+
:param limit: The maximum number of events to display. Default is 50.
558+
:return: None
559+
"""
374560
"""Show full event history for one item."""
375561
init_db()
376562
try:

src/trackr/db.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,47 @@
1+
"""
2+
Provides functions for database connection and schema initialization.
3+
4+
This module contains utility functions for working with an SQLite database. It
5+
includes methods to establish a connection to the database and to initialize
6+
the database schema, ensuring the necessary tables and indices are created
7+
with appropriate configurations.
8+
"""
9+
110
from __future__ import annotations
211

12+
313
import sqlite3
414

515
from .paths import get_db_path
616

717

818
def get_conn() -> sqlite3.Connection:
19+
"""
20+
Establishes and returns a connection to the SQLite database.
21+
22+
This function initializes a database connection to the file path defined by
23+
`get_db_path`. It sets the `row_factory` to return rows as dictionary-like
24+
objects and enables foreign key constraints in the SQLite database. This
25+
ensures that foreign key checks are enforced during database operations.
26+
27+
:returns: A connection object to the SQLite database.
28+
:rtype: sqlite3.Connection
29+
"""
930
conn = sqlite3.connect(get_db_path())
1031
conn.row_factory = sqlite3.Row
1132
conn.execute("PRAGMA foreign_keys = ON")
1233
return conn
1334

1435

1536
def init_db() -> None:
37+
"""
38+
Initializes the database schema by creating necessary tables and indices if they do not already exist.
39+
This function ensures the database structure is properly set up, including the creation of tables `items`
40+
and `events`, the addition of required columns, and the definition of relevant indices for optimized queries.
41+
42+
:raises sqlite3.Error: If any database operation fails during initialization.
43+
:return: None
44+
"""
1645
with get_conn() as conn:
1746
conn.executescript(
1847
"""

0 commit comments

Comments
 (0)