Last active
July 16, 2025 02:39
-
-
Save terbo/f87a137a13af3d12806795c19fd796d8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
# Original code from https://github.com/usememos/memos/issues/4425 | |
# Imports google keep notes from a takeout into Memos (usememos.com) | |
# TODO: Add tags from labels/title [x] | |
# Add creation/update time [x] | |
# Import images | |
# Add HTML/Markdown | |
import os, requests, json | |
from datetime import datetime | |
# Konfiguration | |
MEMOS_API_URL = "http://localhost:5230/api/v1/memos" #correct url to your memos | |
AUTH_TOKEN = "" #memos api token | |
TAKEOUT_FOLDER = "/home/user/Downloads/Takeout/Keep/" #path to your backup | |
HEADERS = { | |
"Content-Type": "application/json", | |
"Authorization": f"Bearer {AUTH_TOKEN}" | |
} | |
# create notes from takeout files | |
def upload_takeout_notes(): | |
memo_ids = [] | |
for filename in os.listdir(TAKEOUT_FOLDER): | |
if filename.endswith(".json"): | |
filepath = os.path.join(TAKEOUT_FOLDER, filename) | |
with open(filepath, "r", encoding="utf-8") as file: | |
data = json.load(file) | |
text = data.get("textContent", "").strip() | |
timestamp_usec = data.get("createdTimestampUsec", 0) | |
edited_usec = data.get("userEditedTimestampUsec", 0) | |
labels = data.get('labels',[]) | |
title = data.get('title','') | |
filepath = data.get("filePath", '') | |
is_pinned = data.get("isPinned", False) # Prüfe, ob die Notiz gepinnt ist | |
if timestamp_usec: | |
if labels: | |
labeltext = '' | |
for label in labels: | |
labeltext += '#' + label['name'].replace(' ','_').lower() + ' ' | |
text += '\n\n' + labeltext | |
if title: | |
titletext = f'### {title}\n' | |
text = titletext + text | |
if text: | |
data_payload = {"content": text, "visibility": "PRIVATE", "pinned": is_pinned} | |
else: # FIX: image only post | |
continue | |
# data_payload = {"resources": [{'filename':filepath}], "visibility": "PRIVATE", "pinned": is_pinned} | |
response = requests.post(MEMOS_API_URL, headers=HEADERS, json=data_payload) | |
if response.status_code == 200: | |
memo_id = response.json().get("name", "").replace("memos/", "") | |
memo_ids.append((memo_id, timestamp_usec, edited_usec, is_pinned)) | |
print(f"New Memo: {filename} (ID: {memo_id}, Pinned: {is_pinned})") | |
else: | |
print(f"Error: {filename}, Status: {response.status_code}, Antwort: {response.text}") | |
return memo_ids | |
# update notes with correct date and pinned status | |
def update_memo_dates(memo_ids): | |
for memo_id, timestamp_usec, update_usec, is_pinned in memo_ids: | |
iso_time = datetime.utcfromtimestamp(timestamp_usec / 1e6).isoformat() + "Z" | |
up_time = datetime.utcfromtimestamp(update_usec / 1e6).isoformat() + "Z" | |
update_url = f"{MEMOS_API_URL}/{memo_id}" | |
data = { | |
"name": f"memos/{memo_id}", | |
"create_time": iso_time, | |
"update_time": up_time, | |
"pinned": is_pinned | |
} | |
response = requests.patch(update_url, headers=HEADERS, json=data) | |
print(f"Update {memo_id}: {response.status_code} - {response.text}") | |
# Hauptlogik | |
memo_ids = upload_takeout_notes() | |
if memo_ids: | |
update_memo_dates(memo_ids) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment