Created
January 12, 2025 07:42
-
-
Save monperrus/6e43a5216179662655c50b901d0d152b to your computer and use it in GitHub Desktop.
python system tray to show and start joplin notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# python system tray to show and start joplin notes | |
# author: Martin Monperrus | |
# license: public domain | |
# url: https://gist.github.com/monperrus/6e43a5216179662655c50b901d0d152b | |
import pystray | |
from PIL import Image | |
import tkinter as tk | |
from tkinter import simpledialog | |
import os | |
import requests | |
import json | |
import keyring | |
login_keyring=keyring.get_keyring() | |
JOPLIN_API_TOKEN = login_keyring.get_password('login2', 'joplin_data_api') | |
def list_joplin_notes(api_token=JOPLIN_API_TOKEN, base_url="http://localhost:41184"): | |
""" | |
List all notes from Joplin using the Data API | |
Parameters: | |
api_token (str): Your Joplin API token | |
base_url (str): The base URL for the Joplin API (default: http://localhost:41184) | |
""" | |
# Endpoint for getting notes | |
endpoint = f"{base_url}/notes?fields=title,id,updated_time&order_by=updated_time&order_dir=DESC&limit=10" | |
# endpoint = f"{base_url}/notes?token="+api_token | |
# Headers including the authorization token | |
headers = { | |
# "Authorization": f"Bearer {api_token}" | |
} | |
# Make the GET request | |
response = requests.get(endpoint, params = {"token":api_token},headers=headers) | |
return response.json()['items'] | |
class SystemTrayApp: | |
def __init__(self): | |
self.icon = None | |
self.create_icon() | |
def create_icon(self): | |
# Create a simple image for the system tray icon | |
image = Image.new('RGB', (64, 64), color='blue') | |
# Create the system tray icon | |
self.icon = pystray.Icon( | |
"list_app", | |
image, | |
"My List App", | |
self.create_menu() | |
) | |
def items(): | |
return [x["title"] for x in joplin_notes.list_joplin_notes()] | |
def create_menu(self): | |
menu_items = [] | |
# Add the main actions | |
# menu_items.append(pystray.MenuItem("Add Item", self.add_item)) | |
# Add a separator if there are items | |
menu_items.append(pystray.MenuItem("Items:", None, enabled=False)) | |
# Add all items in the list | |
for i, item in enumerate(list_joplin_notes()): | |
id=item["id"] | |
f=eval(f"lambda: os.system('joplin joplin://x-callback-url/openNote?id={id}')") | |
# print(item) | |
menu_items.append( | |
pystray.MenuItem( | |
f"{item["title"]}", | |
f, | |
# partial(self.remove_item, i), # Makes items clickable to remove them | |
enabled=True | |
) | |
) | |
# Add a separator | |
menu_items.append(pystray.MenuItem("-", None)) | |
# Add the remaining actions | |
menu_items.extend([ | |
pystray.MenuItem("Clear All", self.clear_items), | |
# pystray.MenuItem("Exit", self.icon.stop) | |
]) | |
return pystray.Menu(*menu_items) | |
def add_item(self): | |
# Create a temporary root window | |
root = tk.Tk() | |
root.withdraw() # Hide the root window | |
# Show input dialog | |
new_item = simpledialog.askstring("Add Item", "Enter new item:") | |
if new_item: | |
print(new_item) | |
raise Exception("implement adding a note") | |
# Update the icon's menu | |
self.icon.menu = self.create_menu() | |
root.destroy() | |
def show_items(self): | |
# Create a temporary root window | |
root = tk.Tk() | |
root.withdraw() | |
message = "Items:\n" + "\n".join(f"{i+1}. {item}" for i, item in enumerate(self.items())) | |
# Show message box with items | |
tk.messagebox.showinfo("Items List", message) | |
root.destroy() | |
def clear_items(self): | |
raise Exception("not supported") | |
def run(self): | |
self.icon.run() | |
if __name__ == "__main__": | |
app = SystemTrayApp() | |
app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment