pynotes-cli 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pynotes/__init__.py ADDED
File without changes
pynotes/db.py ADDED
@@ -0,0 +1,50 @@
1
+ import sqlite3
2
+ from pathlib import Path
3
+
4
+ DB_PATH = Path.home() / ".pynotes.db"
5
+
6
+ def get_connection():
7
+ return sqlite3.connect(DB_PATH)
8
+
9
+ def init_db():
10
+ with get_connection() as conn:
11
+ conn.execute("""
12
+ CREATE TABLE IF NOT EXISTS notes (
13
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
14
+ title TEXT NOT NULL,
15
+ tags TEXT NOT NULL,
16
+ content TEXT NOT NULL,
17
+ created_at DATE DEFAULT CURRENT_DATE
18
+ )
19
+ """)
20
+
21
+ def add_note(title: str, tags: str, content: str):
22
+ with get_connection() as conn:
23
+ conn.execute(
24
+ "INSERT INTO notes (title, tags, content) VALUES (?, ?, ?)",
25
+ (title, tags, content)
26
+ )
27
+
28
+ def get_notes(tag: str = None):
29
+ with get_connection() as conn:
30
+ if tag:
31
+ # Simple wildcard search for tags
32
+ return conn.execute(
33
+ "SELECT id, title, tags, created_at FROM notes WHERE tags LIKE ?",
34
+ (f"%{tag}%",)
35
+ ).fetchall()
36
+ return conn.execute("SELECT id, title, tags, created_at FROM notes").fetchall()
37
+
38
+ def get_note(note_id: int):
39
+ with get_connection() as conn:
40
+ return conn.execute(
41
+ "SELECT title, tags, content FROM notes WHERE id = ?",
42
+ (note_id,)
43
+ ).fetchone()
44
+
45
+ def update_note(note_id: int, title: str, tags: str, content: str):
46
+ with get_connection() as conn:
47
+ conn.execute(
48
+ "UPDATE notes SET title = ?, tags = ?, content = ? WHERE id = ?",
49
+ (title, tags, content, note_id)
50
+ )
pynotes/main.py ADDED
@@ -0,0 +1,57 @@
1
+ import typer
2
+ from pynotes import db, ui, prompts
3
+
4
+ app = typer.Typer(help="A lightning-fast terminal Markdown journal.")
5
+
6
+ @app.callback()
7
+ def main_callback():
8
+ db.init_db()
9
+
10
+ @app.command()
11
+ def init():
12
+ ui.display_success("Knowledge base initialized at ~/.pynotes.db")
13
+
14
+ @app.command()
15
+ def new():
16
+ note_data = prompts.prompt_new_note()
17
+
18
+ if note_data and note_data["title"]:
19
+ db.add_note(note_data["title"], note_data["tags"], note_data["content"])
20
+ ui.display_success("Note saved successfully!")
21
+ else:
22
+ ui.display_error("Note creation cancelled.")
23
+
24
+ @app.command(name="list")
25
+ def list_notes(tag: str = typer.Option(None, help="Filter notes by tag")):
26
+ #list notes ( and filter tag)
27
+ notes = db.get_notes(tag)
28
+ ui.display_notes_table(notes)
29
+
30
+ @app.command()
31
+ def view(note_id: int):
32
+ note = db.get_note(note_id)
33
+
34
+ #view note w/ id
35
+ if note:
36
+ ui.display_note(title=note[0], content=note[2])
37
+ else:
38
+ ui.display_error(f"Note with ID {note_id} not found.")
39
+
40
+ @app.command()
41
+ def edit(note_id: int):
42
+ note = db.get_note(note_id)
43
+ if not note:
44
+ ui.display_error(f"Note with ID {note_id} not found.")
45
+ return
46
+
47
+ ui.display_success(f"Editing note: {note[0]}")
48
+ note_data = prompts.prompt_edit_note(existing_title=note[0], existing_tags=note[1], existing_content=note[2])
49
+
50
+ if note_data and note_data["title"]:
51
+ db.update_note(note_id, note_data["title"], note_data["tags"], note_data["content"])
52
+ ui.display_success("Note updated successfully!")
53
+ else:
54
+ ui.display_error("Note edit cancelled.")
55
+
56
+ if __name__ == "__main__":
57
+ app()
pynotes/prompts.py ADDED
@@ -0,0 +1,59 @@
1
+ import questionary
2
+
3
+ def prompt_new_note():
4
+ title = questionary.text("Enter note title:").ask()
5
+ if not title:
6
+ return None
7
+
8
+ tags = questionary.text("Enter tags (comma separated):").ask()
9
+
10
+ # multiline=True allows hitting Enter for new lines.
11
+ # The user presses Alt+Enter (or Esc then Enter on Mac) to submit.
12
+ content = questionary.text(
13
+ "Content (Markdown supported - Press Alt+Enter to save):",
14
+ multiline=True
15
+ ).ask()
16
+
17
+ return {
18
+ "title": title,
19
+ "tags": tags,
20
+ "content": content
21
+ }
22
+
23
+ def prompt_edit_note(existing_title: str, existing_tags: str, existing_content: str):
24
+ title = questionary.text("Edit note title:", default=existing_title).ask()
25
+ if not title:
26
+ return None
27
+
28
+ tags = questionary.text("Edit tags (comma separated):", default=existing_tags).ask()
29
+
30
+ content = questionary.text(
31
+ "Edit Content (Markdown supported - Press Alt+Enter to save):",
32
+ default=existing_content,
33
+ multiline=True
34
+ ).ask()
35
+
36
+ return {
37
+ "title": title,
38
+ "tags": tags,
39
+ "content": content
40
+ }
41
+
42
+ def prompt_edit_note(existing_title: str, existing_tags: str, existing_content: str):
43
+ title = questionary.text("Edit note title:", default=existing_title).ask()
44
+ if not title:
45
+ return None
46
+
47
+ tags = questionary.text("Edit tags (comma separated):", default=existing_tags).ask()
48
+
49
+ content = questionary.text(
50
+ "Edit Content (Markdown supported - Press Alt+Enter to save):",
51
+ default=existing_content,
52
+ multiline=True
53
+ ).ask()
54
+
55
+ return {
56
+ "title": title,
57
+ "tags": tags,
58
+ "content": content
59
+ }
pynotes/ui.py ADDED
@@ -0,0 +1,35 @@
1
+ from rich.console import Console
2
+ from rich.table import Table
3
+ from rich.markdown import Markdown
4
+ from rich import box
5
+
6
+ console = Console()
7
+
8
+ def display_notes_table(notes):
9
+ if not notes:
10
+ console.print("[yellow]No notes found.[/yellow]")
11
+ return
12
+
13
+ table = Table(title="Pynotes", box=box.SIMPLE)
14
+ table.add_column("ID", justify="right", style="cyan", no_wrap=True)
15
+ table.add_column("Title", style="magenta")
16
+ table.add_column("Tags", style="green")
17
+ table.add_column("Date", style="dim")
18
+
19
+ for note in notes:
20
+ table.add_row(str(note[0]), note[1], note[2], note[3])
21
+
22
+ console.print(table)
23
+
24
+ def display_note(title: str, content: str):
25
+ console.print(f"\n[magenta]# {title}[/magenta]")
26
+ console.print("-" * 50)
27
+ # Renders the text as actual markdown (bolding, code blocks, etc.)
28
+ console.print(Markdown(content))
29
+ console.print("\n")
30
+
31
+ def display_success(message: str):
32
+ console.print(f"[green]✔ {message}[/green]")
33
+
34
+ def display_error(message: str):
35
+ console.print(f"[red]✖ {message}[/red]")
@@ -0,0 +1,8 @@
1
+ Metadata-Version: 2.4
2
+ Name: pynotes-cli
3
+ Version: 0.1.0
4
+ Summary: A terminal Markdown personal journal and notes tool.
5
+ Requires-Python: >=3.9
6
+ Requires-Dist: typer>=0.9.0
7
+ Requires-Dist: rich>=13.0.0
8
+ Requires-Dist: questionary>=2.0.0
@@ -0,0 +1,10 @@
1
+ pynotes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ pynotes/db.py,sha256=hkcf5-mQb77nBw2j2Ow6SRi_c0IlG8Slo4ljTBonT84,1586
3
+ pynotes/main.py,sha256=J6I8_pFAxwHJMq3PXH4RuZDxiamLSMMrvacxoCs7LXQ,1656
4
+ pynotes/prompts.py,sha256=ZWSqKketEkLMLgKGy9Xa6P-zQ7KPlLNgoAN9EAqXTB4,1722
5
+ pynotes/ui.py,sha256=HEas7Sxc0rms0v25n04FT6GpgeKDF3yZmGpoEVAwBEw,1067
6
+ pynotes_cli-0.1.0.dist-info/METADATA,sha256=MXuoXfnLyHcJ8btpIfEbLTkfrQb1JHM0HigU6Ggyep0,230
7
+ pynotes_cli-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
8
+ pynotes_cli-0.1.0.dist-info/entry_points.txt,sha256=D3i3snDpaTmXLMQtTAkZ_0KM_G-ZwvQKjrRTXTrwNA0,45
9
+ pynotes_cli-0.1.0.dist-info/top_level.txt,sha256=Jgv39OAu_fP6yA6OXIsFtyFhYoZmQO1HTyUDnGyoR4E,8
10
+ pynotes_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pynotes = pynotes.main:app
@@ -0,0 +1 @@
1
+ pynotes