diff --git a/process_keep.py b/process_keep.py new file mode 100644 index 0000000..14464d6 --- /dev/null +++ b/process_keep.py @@ -0,0 +1,306 @@ +import os +import json + +""" This was written almost entirely by Google Gemini 2.5 (apps and code) on 18 Sept. 2025 + +Google Takeout is accessible from the browser when logged in to your Google account. +It can be set up to export dozens of different types of data. Here we only export "Keep" +data. +After running this, move the generated file to expoweb/handbook/troggle +and git add/commit/push +Philip Sargent +""" +# --- CONFIGURATION --- +# š IMPORTANT: Replace this with the actual path to your Google Keep Takeout folder. +TAKEOUT_DIRECTORY = 'Takeout/Keep' # Example for Linux/macOS +# + +def process_keep_files_to_dict(directory_path): + """ + Scans a directory for Google Keep JSON files, filters for a specific + label, prints the content, and returns the data as a list of dictionaries. + + Args: + directory_path (str): The path to the folder containing the JSON files. + + Returns: + list: A list of dictionaries, where each dictionary represents a note. + """ + print(f"š Processing files in: {directory_path}\n") + + # This list will store the dictionary for each matching note + extracted_notes = [] + + if not os.path.isdir(directory_path): + print(f"ā Error: Directory not found at '{directory_path}'.") + print("Please update the TAKEOUT_DIRECTORY variable with the correct path.") + return extracted_notes + + # Iterate over every file in the specified directory + for filename in os.listdir(directory_path): + if filename.endswith('.json'): + file_path = os.path.join(directory_path, filename) + + try: + with open(file_path, 'r', encoding='utf-8') as f: + data = json.load(f) + + # --- Label Check --- + has_expo_label = False + if 'labels' in data: + if any(label.get('name', '').lower() == 'expo' for label in data['labels']): + has_expo_label = True + + if not has_expo_label: + continue # Skip this file + + # --- Data Extraction & Storage --- + + # Create a dictionary to hold the current note's data + current_note = { + 'title': data.get('title') or 'Untitled Note', + 'source_file': filename, + 'content_type': None, + 'color': data.get('color', 'DEFAULT'), + 'content': None + } + + # As before, print to the console for immediate feedback + print("-" * 40) + print(f"ā Title: {current_note['title']}") + + # Handle text notes + if 'textContent' in data: + content = data['textContent'] + current_note['content_type'] = 'text' + current_note['content'] = content + print(content) + + # Handle list notes + elif 'listContent' in data: + current_note['content_type'] = 'list' + list_items = [] + checked_items = [] + unchecked_items = [] + # print("Tasks:") + for item in data['listContent']: + # Create a clean dictionary for the list item + item_data = { + 'text': item.get('text', ''), + 'is_checked': item.get('isChecked', False) + } + list_items.append(item_data) + if item_data['is_checked']: + checked_items.append(item_data) + else: + unchecked_items.append(item_data) + # Print the list item to the console + # status = 'x' if item_data['is_checked'] else ' ' + # print(f" [{status}] {item_data['text']}") + print(f"Tasks: {len(list_items)} of which {len(checked_items)} are done.") + current_note['content'] = list_items + current_note['unchecked'] = unchecked_items + + # Add the completed dictionary for this note to our main list + extracted_notes.append(current_note) + + # print("-" * 40 + "\n") + + except Exception as e: + print(f"āļø An unexpected error occurred with file {filename}: {e}") + + if not extracted_notes: + print("No notes with the 'EXPO' label were found in the directory.") + sorted_notes = sorted(extracted_notes, key=lambda note: len(note['unchecked'])) + + return sorted_notes + +import html +from datetime import datetime + +def write_html_output(notes_data, filename="keep_export.html"): + """ + Generates an HTML file from the extracted Keep notes data. + + Args: + notes_data (list): A list of note dictionaries. + filename (str): The name of the output HTML file. + """ + + # These are the standard Google Keep colors. + color_map = { + "DEFAULT": "#ffffff", + "RED": "#f28b82", + "ORANGE": "#fbbc04", + "YELLOW": "#fff475", + "GREEN": "#ccff90", + "TEAL": "#a7ffeb", + "BLUE": "#cbf0f8", + "DARK_BLUE": "#aecbfa", + "PURPLE": "#d7aefb", + "PINK": "#fdcfe8", + "BROWN": "#e6c9a8", + "GRAY": "#e8eaed", + } + + # --- HTML Head and CSS Styling --- + # The CSS is embedded directly in the HTML file for simplicity. + html_head = f""" + + +
+ + +{text}
(Exported from Philip Sargent's Google Keep notes on {datetime.now().strftime('%Y-%m-%d %H:%M')}) +
Contact Philip if you wish to share these lists on your Google Keep account. +