Last active
April 5, 2024 05:07
-
-
Save htlin222/02f110744cdf2048d8c5d3b7d7e71d42 to your computer and use it in GitHub Desktop.
search new markdown recently added, with text ANKI in it. Add to Anki Deck, as a raycast command
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
# -*- coding: utf-8 -*- | |
# title: md_to_anki | |
# date: "2023-05-28" | |
# @raycast.title Markdown files 🪴 to ANKI | |
# @raycast.author HTLin the 🦎 | |
# @raycast.description search new markdown recently added, with text ANKI in it. Add to Anki Deck | |
# @raycast.authorURL https://github.com/htlin222 | |
# @raycast.icon 📚 | |
# @raycast.mode silent | |
# @raycast.packageName System | |
# @raycast.schemaVersion 1 | |
import glob | |
import mistune | |
import re | |
import os | |
import requests | |
import json | |
from datetime import datetime, timedelta | |
ANKI_DECK_NAME = "01_garden" | |
ANKI_NOTE_TYPE = 'Basic' | |
ANKI_FRONT_FIELD = 'Front' | |
ANKI_BACK_FIELD = 'Back' | |
ANKICONNECT_ENDPOINT = "http://localhost:8765" | |
KEY_WORD = 'ANKI' | |
FOLDER_TO_WATCH = '~/YOUR/PATH/WITH/MARKDOWN" | |
def search_markdown_files(directory): | |
# Use glob to find Markdown files in the specified directory | |
file_paths = glob.glob(directory + '/*.md') | |
# Get the current time and calculate the time threshold | |
current_time = datetime.now() | |
threshold_time = current_time - timedelta(hours=24) | |
for file_path in file_paths: | |
# Get the modification timestamp of the file | |
file_modified_time = datetime.fromtimestamp(os.path.getmtime(file_path)) | |
# Check if the file was modified or created within the last 24 hours | |
if file_modified_time >= threshold_time: | |
extract_note_content(file_path, KEY_WORD) | |
def extract_note_content(file_path, text): | |
with open(file_path, 'r') as file: | |
content = file.read() | |
pattern = re.compile(text, re.IGNORECASE) | |
matches = pattern.findall(content) | |
pattern = re.compile(text, re.IGNORECASE) | |
content = re.sub(pattern, '', content) | |
if len(matches) > 0: | |
print(f"found {file_path} with {KEY_WORD} in it") | |
title_match = re.search(r'^#\s*(.*)', content, re.MULTILINE) | |
if title_match: | |
title = title_match.group(1).strip() | |
back = content[title_match.end():] | |
back = find_markdown_image_and_and_replace(back) | |
back = remove_blank_lines(back) | |
back = convert_markdown_to_html(back) | |
print(f"after{back}") | |
else: | |
title = None | |
back = None | |
sent_to_anki(title, back) | |
with open(file_path, 'w') as file: | |
file.write(content) | |
def find_markdown_image_and_and_replace(md_content): | |
pattern = r'\!\[(.*)\]\((http.*?)\)' | |
# Find all remote image links in the Markdown content | |
for match in re.finditer(pattern, md_content): | |
image_alt_text = match.group(1) | |
image_url = match.group(2) | |
# Generate a local file path for the image based on its URL | |
image_file_name = os.path.basename(image_url) | |
payload = { | |
"action": "storeMediaFile", | |
"version": 6, | |
"params": { | |
"filename": image_file_name, | |
"url": image_url | |
} | |
} | |
response = requests.post(ANKICONNECT_ENDPOINT, data=json.dumps(payload)) | |
print(f"IMAGE: {response}") | |
# Replace the remote image link with a local image path in the Markdown content | |
md_content = md_content.replace(match.group(0), f'![{image_alt_text}]({image_file_name})') | |
return md_content | |
def remove_blank_lines(text): | |
lines = text.splitlines() | |
non_blank_lines = [line for line in lines if line.strip()] | |
return '\n'.join(non_blank_lines) | |
def convert_markdown_to_html(markdown_text): | |
renderer = mistune.HTMLRenderer() | |
markdown_parser = mistune.Markdown(renderer) | |
html_text = markdown_parser(markdown_text) | |
# Convert ![]() image syntax to HTML format | |
html_text = re.sub(r'!\[([^\]]*)\]\((.*?)\)', r'<img alt="\1" src="\2">', html_text) | |
# Add HTML line breaks after each line | |
# html_text = html_text.replace('\n', '<br>') | |
return html_text | |
def sent_to_anki(title, back): | |
print(back) | |
payload = { | |
'action': 'addNote', | |
'version': 6, | |
'params': { | |
'note': { | |
'deckName': ANKI_DECK_NAME, | |
'modelName': ANKI_NOTE_TYPE, | |
'fields': { | |
ANKI_FRONT_FIELD: title, | |
ANKI_BACK_FIELD: back, | |
}, | |
'options': { | |
'allowDuplicate': True, | |
}, | |
'tags': ['from_garden'], | |
}, | |
}, | |
} | |
# Send the AnkiConnect request | |
response = requests.post(ANKICONNECT_ENDPOINT, data=json.dumps(payload)) | |
print(f'{title} done') | |
# Print the response | |
print(response.content.decode()) | |
if __name__ == '__main__': | |
directory_path = os.path.expanduser(FOLDER_TO_WATCH) | |
search_markdown_files(directory_path) | |
print("😎 Done") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment