update notes
This commit is contained in:
parent
21c37d46c7
commit
bbca41c406
225
plugins/notes.py
225
plugins/notes.py
@ -6,18 +6,23 @@ IRC Bot Plugin for Note Taking using TinyDB.
|
|||||||
This plugin provides a single !note command with subcommands to manage both
|
This plugin provides a single !note command with subcommands to manage both
|
||||||
daily and general notes. It supports the following subcommands:
|
daily and general notes. It supports the following subcommands:
|
||||||
|
|
||||||
today [<content>...]
|
today [--add|--replace] [<content>...]
|
||||||
View or update today's daily note.
|
View or update today's daily note. If content is provided and a note for
|
||||||
|
today already exists, a warning is shown unless you specify --add (to append)
|
||||||
|
or --replace (to replace).
|
||||||
|
|
||||||
daily [--date <date>] [<content>...]
|
daily [--date <date>] [--add|--replace] [<content>...]
|
||||||
View or update a daily note for the specified date (default is today).
|
View or update a daily note for the specified date (default is today). If
|
||||||
|
content is provided and a note already exists, a warning is shown unless you
|
||||||
|
specify --add (to append) or --replace (to replace).
|
||||||
|
|
||||||
general <title> [--tags <tags>] [<content>...]
|
general <title> [--tags <tags>] [<content>...]
|
||||||
View or update a general note with the given title.
|
View or update a general note with the given title.
|
||||||
Optionally specify tags.
|
Optionally specify tags.
|
||||||
|
|
||||||
list <type>
|
list <type>
|
||||||
List all notes of the specified type (either 'daily' or 'general').
|
List all notes of the specified type (either 'daily' or 'general'). The
|
||||||
|
content of each note is displayed truncated.
|
||||||
|
|
||||||
search <type> <keyword>
|
search <type> <keyword>
|
||||||
Search for a keyword in notes of the specified type.
|
Search for a keyword in notes of the specified type.
|
||||||
@ -34,8 +39,8 @@ Dependencies:
|
|||||||
- tinydb
|
- tinydb
|
||||||
|
|
||||||
Author: Your Name
|
Author: Your Name
|
||||||
Version: 1.1
|
Version: 1.3
|
||||||
Date: 2025-02-17
|
Date: 2025-02-18
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
@ -121,12 +126,27 @@ def default_general_template(title, tags):
|
|||||||
"""
|
"""
|
||||||
tag_line = f"Tags: {tags}" if tags else ""
|
tag_line = f"Tags: {tags}" if tags else ""
|
||||||
return f"""# General Note: {title}
|
return f"""# General Note: {title}
|
||||||
{tag_line}
|
{tag_line} Created on: {now_str()}
|
||||||
Created on: {now_str()}
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def truncate(text, length=50):
|
||||||
|
"""
|
||||||
|
Truncate the text to a specified length, appending "..." if truncated.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (str): The text to truncate.
|
||||||
|
length (int): Maximum length of the returned text.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The truncated text.
|
||||||
|
"""
|
||||||
|
if not isinstance(text, str):
|
||||||
|
text = str(text)
|
||||||
|
return text if len(text) <= length else text[:length] + "..."
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# NoteTaking Plugin
|
# NoteTaking Plugin
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@ -171,17 +191,21 @@ class NoteTaking:
|
|||||||
@command(aliases=['notes'], public=True, options_first=False, use_shlex=True)
|
@command(aliases=['notes'], public=True, options_first=False, use_shlex=True)
|
||||||
async def note(self, mask, target, args):
|
async def note(self, mask, target, args):
|
||||||
"""
|
"""
|
||||||
%%note
|
%%note today [--add|--replace] [<content>...]
|
||||||
%%note today [<content>...]
|
%%note daily [--date=<date>] [--add|--replace] [<content>...]
|
||||||
%%note daily [<content>...] [--date=<date>]
|
%%note general <title> [--tags=<tags>] [<content>...]
|
||||||
%%note general <title> [<content>...] [--tags <tags>]
|
%%note list [<type>]
|
||||||
%%note list <type>
|
|
||||||
%%note search <type> <keyword>
|
%%note search <type> <keyword>
|
||||||
%%note summary
|
%%note summary
|
||||||
|
%%note
|
||||||
"""
|
"""
|
||||||
# If no subcommand is provided, show the help message.
|
# If no subcommand is provided, show the help message.
|
||||||
if not any(args.get(key) for key in ('today', 'daily', 'general', 'list', 'search', 'summary')):
|
if not any(args.get(key) for key in ('today', 'daily', 'general', 'list', 'search', 'summary')):
|
||||||
self._show_help(target)
|
# If there's content provided without a subcommand, treat it as a daily note update.
|
||||||
|
if args.get('<content>'):
|
||||||
|
await self._note_today(mask, target, args)
|
||||||
|
else:
|
||||||
|
self._show_help(target)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -208,10 +232,10 @@ class NoteTaking:
|
|||||||
help_lines = [
|
help_lines = [
|
||||||
ircstyle.style("Usage: !note <subcommand> [options]", fg="red", bold=True),
|
ircstyle.style("Usage: !note <subcommand> [options]", fg="red", bold=True),
|
||||||
"Subcommands:",
|
"Subcommands:",
|
||||||
f"{ircstyle.style(' today', fg='yellow')} - View or update today's daily note.",
|
f"{ircstyle.style(' today [--add|--replace] [<content>...]', fg='yellow')} - View or update today's daily note.",
|
||||||
f"{ircstyle.style(' daily [--date <date>]', fg='yellow')} - View or update a daily note for a specific date (default is today).",
|
f"{ircstyle.style(' daily [--date <date>] [--add|--replace] [<content>...]', fg='yellow')} - View or update a daily note for a specific date (default is today).",
|
||||||
f"{ircstyle.style(' general <title> [--tags <tags>]', fg='yellow')} - View or update a general note with the given title. Optionally, specify tags.",
|
f"{ircstyle.style(' general <title> [--tags <tags>] [<content>...]', fg='yellow')} - View or update a general note with the given title. Optionally, specify tags.",
|
||||||
f"{ircstyle.style(' list [daily|general]', fg='yellow')} - List all notes of a specific type.",
|
f"{ircstyle.style(' list [daily|general]', fg='yellow')} - List all notes of a specific type with truncated content.",
|
||||||
f"{ircstyle.style(' search <type> <keyword>', fg='yellow')} - Search for a keyword in notes of a specific type.",
|
f"{ircstyle.style(' search <type> <keyword>', fg='yellow')} - Search for a keyword in notes of a specific type.",
|
||||||
f"{ircstyle.style(' summary', fg='yellow')} - Display a summary of note counts.",
|
f"{ircstyle.style(' summary', fg='yellow')} - Display a summary of note counts.",
|
||||||
]
|
]
|
||||||
@ -223,7 +247,9 @@ class NoteTaking:
|
|||||||
"""
|
"""
|
||||||
Handle the 'today' subcommand for daily notes.
|
Handle the 'today' subcommand for daily notes.
|
||||||
|
|
||||||
If content is provided, update today's note; otherwise, display it.
|
If content is provided, update today's note.
|
||||||
|
If a note already exists and content is provided, warn the user unless
|
||||||
|
--add or --replace is specified.
|
||||||
"""
|
"""
|
||||||
day = today_str()
|
day = today_str()
|
||||||
content_list = args.get('<content>')
|
content_list = args.get('<content>')
|
||||||
@ -231,21 +257,50 @@ class NoteTaking:
|
|||||||
note = self._get_daily_note(day)
|
note = self._get_daily_note(day)
|
||||||
if content_list:
|
if content_list:
|
||||||
new_content = " ".join(content_list)
|
new_content = " ".join(content_list)
|
||||||
if note:
|
# Check if both flags are provided
|
||||||
self.daily_table.update(
|
if args.get('--add') and args.get('--replace'):
|
||||||
{'content': new_content, 'updated': now_str()},
|
self.bot.privmsg(
|
||||||
self.User.date == day
|
target,
|
||||||
|
ircstyle.style("❌ Error: Cannot use both --add and --replace simultaneously. Please choose one.", fg="red", bold=True)
|
||||||
)
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if note:
|
||||||
|
# If note exists but neither flag is provided, warn the user.
|
||||||
|
if not (args.get('--add') or args.get('--replace')):
|
||||||
|
warning = ircstyle.style(
|
||||||
|
f"⚠️ Warning: Daily note for {day} already exists. Use --add to append to it or --replace to overwrite it.", fg="red", bold=True
|
||||||
|
)
|
||||||
|
self.bot.privmsg(target, warning)
|
||||||
|
return
|
||||||
|
if args.get('--add'):
|
||||||
|
appended_content = note.get('content') + "\n" + new_content
|
||||||
|
self.daily_table.update(
|
||||||
|
{'content': appended_content, 'updated': now_str()},
|
||||||
|
self.User.date == day
|
||||||
|
)
|
||||||
|
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
||||||
|
f"Daily note for {day} updated (content added).", fg="blue", bold=True
|
||||||
|
)
|
||||||
|
elif args.get('--replace'):
|
||||||
|
self.daily_table.update(
|
||||||
|
{'content': new_content, 'updated': now_str()},
|
||||||
|
self.User.date == day
|
||||||
|
)
|
||||||
|
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
||||||
|
f"Daily note for {day} replaced.", fg="blue", bold=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
|
# No existing note; create a new one.
|
||||||
self.daily_table.insert({
|
self.daily_table.insert({
|
||||||
'date': day,
|
'date': day,
|
||||||
'content': new_content,
|
'content': new_content,
|
||||||
'created': now_str(),
|
'created': now_str(),
|
||||||
'updated': now_str()
|
'updated': now_str()
|
||||||
})
|
})
|
||||||
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
||||||
f"Daily note for {day} updated.", fg="blue", bold=True
|
f"Daily note for {day} created.", fg="blue", bold=True
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if not note:
|
if not note:
|
||||||
default_content = self.daily_template(day)
|
default_content = self.daily_template(day)
|
||||||
@ -272,7 +327,9 @@ class NoteTaking:
|
|||||||
"""
|
"""
|
||||||
Handle the 'daily' subcommand for daily notes with an optional date.
|
Handle the 'daily' subcommand for daily notes with an optional date.
|
||||||
|
|
||||||
If content is provided, update the note; otherwise, display it.
|
If content is provided, update the note.
|
||||||
|
If a note already exists and content is provided, warn the user unless
|
||||||
|
--add or --replace is specified.
|
||||||
"""
|
"""
|
||||||
day = args.get('--date') or today_str()
|
day = args.get('--date') or today_str()
|
||||||
try:
|
try:
|
||||||
@ -290,21 +347,49 @@ class NoteTaking:
|
|||||||
note = self._get_daily_note(day)
|
note = self._get_daily_note(day)
|
||||||
if content_list:
|
if content_list:
|
||||||
new_content = " ".join(content_list)
|
new_content = " ".join(content_list)
|
||||||
if note:
|
# Check if both flags are provided
|
||||||
self.daily_table.update(
|
if args.get('--add') and args.get('--replace'):
|
||||||
{'content': new_content, 'updated': now_str()},
|
self.bot.privmsg(
|
||||||
self.User.date == day
|
target,
|
||||||
|
ircstyle.style("❌ Error: Cannot use both --add and --replace simultaneously. Please choose one.", fg="red", bold=True)
|
||||||
)
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if note:
|
||||||
|
if not (args.get('--add') or args.get('--replace')):
|
||||||
|
self.bot.privmsg(
|
||||||
|
target,
|
||||||
|
ircstyle.style(f"⚠️ Warning: Daily note for {day} already exists. Use --add to append or --replace to overwrite.", fg="red", bold=True)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if args.get('--add'):
|
||||||
|
appended_content = note.get('content') + "\n" + new_content
|
||||||
|
self.daily_table.update(
|
||||||
|
{'content': appended_content, 'updated': now_str()},
|
||||||
|
self.User.date == day
|
||||||
|
)
|
||||||
|
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
||||||
|
f"Daily note for {day} updated (content added).", fg="blue", bold=True
|
||||||
|
)
|
||||||
|
elif args.get('--replace'):
|
||||||
|
self.daily_table.update(
|
||||||
|
{'content': new_content, 'updated': now_str()},
|
||||||
|
self.User.date == day
|
||||||
|
)
|
||||||
|
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
||||||
|
f"Daily note for {day} replaced.", fg="blue", bold=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
|
# Create new note if none exists.
|
||||||
self.daily_table.insert({
|
self.daily_table.insert({
|
||||||
'date': day,
|
'date': day,
|
||||||
'content': new_content,
|
'content': new_content,
|
||||||
'created': now_str(),
|
'created': now_str(),
|
||||||
'updated': now_str()
|
'updated': now_str()
|
||||||
})
|
})
|
||||||
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
msg = ircstyle.style("✅ ", fg="green") + ircstyle.style(
|
||||||
f"Daily note for {day} updated.", fg="blue", bold=True
|
f"Daily note for {day} created.", fg="blue", bold=True
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if not note:
|
if not note:
|
||||||
default_content = self.daily_template(day)
|
default_content = self.daily_template(day)
|
||||||
@ -410,7 +495,7 @@ class NoteTaking:
|
|||||||
|
|
||||||
async def _note_list(self, target, args):
|
async def _note_list(self, target, args):
|
||||||
"""
|
"""
|
||||||
Handle the 'list' subcommand to list notes.
|
Handle the 'list' subcommand to list notes with truncated content.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
%%note list [<type>]
|
%%note list [<type>]
|
||||||
@ -420,43 +505,63 @@ class NoteTaking:
|
|||||||
note_type = args.get('<type>')
|
note_type = args.get('<type>')
|
||||||
try:
|
try:
|
||||||
if not note_type:
|
if not note_type:
|
||||||
# List both daily and general notes
|
# List both daily and general notes with content truncated.
|
||||||
daily_notes = self.daily_table.all()
|
daily_notes = self.daily_table.all()
|
||||||
general_notes = self.general_table.all()
|
general_notes = self.general_table.all()
|
||||||
|
|
||||||
# Filter valid daily notes
|
if not daily_notes and not general_notes:
|
||||||
valid_daily_dates = [n.get('date') for n in daily_notes if isinstance(n.get('date'), str)]
|
|
||||||
# Filter valid general notes
|
|
||||||
valid_general_titles = [n.get('title') for n in general_notes if isinstance(n.get('title'), str)]
|
|
||||||
|
|
||||||
if not valid_daily_dates and not valid_general_titles:
|
|
||||||
msg = ircstyle.style("No notes found.", fg="red", bold=True)
|
msg = ircstyle.style("No notes found.", fg="red", bold=True)
|
||||||
else:
|
else:
|
||||||
msg = ircstyle.style("📝 All Notes:", fg="blue", bold=True) + "\n"
|
msg_lines = [ircstyle.style("📝 All Notes:", fg="blue", bold=True)]
|
||||||
if valid_daily_dates:
|
if daily_notes:
|
||||||
msg += ircstyle.style("📅 Daily Notes:", fg="yellow", bold=True) + "\n"
|
msg_lines.append(ircstyle.style("📅 Daily Notes:", fg="yellow", bold=True))
|
||||||
msg += "\n".join([f"• {date}" for date in sorted(valid_daily_dates)]) + "\n"
|
# Sort daily notes by date.
|
||||||
if valid_general_titles:
|
daily_sorted = sorted(
|
||||||
msg += ircstyle.style("📋 General Notes:", fg="cyan", bold=True) + "\n"
|
[n for n in daily_notes if isinstance(n.get('date'), str)],
|
||||||
msg += "\n".join([f"• {title}" for title in sorted(valid_general_titles)])
|
key=lambda x: x['date']
|
||||||
|
)
|
||||||
|
for note in daily_sorted:
|
||||||
|
date_str = note.get('date')
|
||||||
|
snippet = truncate(note.get('content', ''))
|
||||||
|
msg_lines.append(f" • {ircstyle.style(date_str, fg='green')}: {ircstyle.style(snippet, fg='white')}")
|
||||||
|
if general_notes:
|
||||||
|
msg_lines.append(ircstyle.style("📋 General Notes:", fg="cyan", bold=True))
|
||||||
|
# Sort general notes by title.
|
||||||
|
general_sorted = sorted(
|
||||||
|
[n for n in general_notes if isinstance(n.get('title'), str)],
|
||||||
|
key=lambda x: x['title']
|
||||||
|
)
|
||||||
|
for note in general_sorted:
|
||||||
|
title = note.get('title')
|
||||||
|
snippet = truncate(note.get('content', ''))
|
||||||
|
msg_lines.append(f" • {ircstyle.style(title, fg='green')}: {ircstyle.style(snippet, fg='white')}")
|
||||||
|
msg = "\n".join(msg_lines)
|
||||||
elif note_type == 'daily':
|
elif note_type == 'daily':
|
||||||
notes = self.daily_table.all()
|
notes = self.daily_table.all()
|
||||||
# Filter only notes with a valid date string
|
valid_notes = [n for n in notes if isinstance(n.get('date'), str)]
|
||||||
valid_dates = [n.get('date') for n in notes if isinstance(n.get('date'), str)]
|
if not valid_notes:
|
||||||
if not valid_dates:
|
|
||||||
msg = ircstyle.style("No daily notes found.", fg="red", bold=True)
|
msg = ircstyle.style("No daily notes found.", fg="red", bold=True)
|
||||||
else:
|
else:
|
||||||
dates = sorted(valid_dates)
|
msg_lines = [ircstyle.style("📅 Daily Notes:", fg="blue", bold=True)]
|
||||||
msg = ircstyle.style("📅 Daily Notes:", fg="blue", bold=True) + "\n"
|
daily_sorted = sorted(valid_notes, key=lambda x: x['date'])
|
||||||
msg += "\n".join([f"• {date}" for date in dates])
|
for note in daily_sorted:
|
||||||
|
date_str = note.get('date')
|
||||||
|
snippet = truncate(note.get('content', ''))
|
||||||
|
msg_lines.append(f" • {ircstyle.style(date_str, fg='green')}: {ircstyle.style(snippet, fg='white')}")
|
||||||
|
msg = "\n".join(msg_lines)
|
||||||
elif note_type == 'general':
|
elif note_type == 'general':
|
||||||
notes = self.general_table.all()
|
notes = self.general_table.all()
|
||||||
if not notes:
|
valid_notes = [n for n in notes if isinstance(n.get('title'), str)]
|
||||||
|
if not valid_notes:
|
||||||
msg = ircstyle.style("No general notes found.", fg="red", bold=True)
|
msg = ircstyle.style("No general notes found.", fg="red", bold=True)
|
||||||
else:
|
else:
|
||||||
titles = sorted(n['title'] for n in notes if isinstance(n.get('title'), str))
|
msg_lines = [ircstyle.style("📋 General Notes:", fg="blue", bold=True)]
|
||||||
msg = ircstyle.style("📋 General Notes:", fg="blue", bold=True) + "\n"
|
general_sorted = sorted(valid_notes, key=lambda x: x['title'])
|
||||||
msg += "\n".join([f"• {title}" for title in titles])
|
for note in general_sorted:
|
||||||
|
title = note.get('title')
|
||||||
|
snippet = truncate(note.get('content', ''))
|
||||||
|
msg_lines.append(f" • {ircstyle.style(title, fg='green')}: {ircstyle.style(snippet, fg='white')}")
|
||||||
|
msg = "\n".join(msg_lines)
|
||||||
else:
|
else:
|
||||||
msg = ircstyle.style("Usage: !note list [daily|general]", fg="red", bold=True)
|
msg = ircstyle.style("Usage: !note list [daily|general]", fg="red", bold=True)
|
||||||
for line in msg.split('\n'):
|
for line in msg.split('\n'):
|
||||||
|
Loading…
Reference in New Issue
Block a user