Skip to content

Instantly share code, notes, and snippets.

@lincolnthalles
Created May 29, 2024 10:20
Show Gist options
  • Select an option

  • Save lincolnthalles/b220586cf9d74234f8f407ce984e6ee4 to your computer and use it in GitHub Desktop.

Select an option

Save lincolnthalles/b220586cf9d74234f8f407ce984e6ee4 to your computer and use it in GitHub Desktop.
#
# Text file importer for Memos
# https://www.usememos.com
#
# This script imports text files (preferably in Markdown format) into your Memos instance.
#
# Provide the instance's URL and acess token, and it will create a new memo for each matching
# file in the source folder and subfolders.
#
# This script is designed to work with Python's 3.10 (or later) standard library. There's
# no need to install any additional packages or deal with virtual environments.
#
# Memo visibility:
# - PUBLIC: everyone can see.
# - PROTECTED: all logged-in users can see.
# - PRIVATE: only you can see.
#
# NOTES
# -----
# - Memos imposes a 8 KiB limit for a single memo content.
#
# USAGE
# -----
# python import_text_files.py --url=http://127.0.0.1:5230/ --token="YOUR_TOKEN" \
# --folder="~/Desktop/Obsidian" --visibility=PUBLIC --extensions .txt .md
#
import json
from argparse import ArgumentParser
from http.client import HTTPConnection, HTTPResponse, HTTPSConnection
from pathlib import Path
from sys import exit
from urllib.parse import urlparse
########## DEFAULT SETTINGS ##########
SOURCE_FOLDER = r"~/Desktop/Obsidian"
SOURCE_EXTENSIONS = [".txt", ".md"]
# Format: [http|https]://host:port
MEMOS_URL = "http://127.0.0.1:32768/"
# Token from Settings -> My Account
MEMOS_TOKEN = r"YOUR_TOKEN"
# PUBLIC, PROTECTED or PRIVATE
MEMO_VISIBILITY = "PUBLIC"
#####################################
def connect_to_memos(server_url: str) -> HTTPSConnection | HTTPConnection:
url = urlparse(server_url)
if not url.hostname:
error = "invalid Memos server URL"
raise ValueError(error)
if url.scheme == "https":
return HTTPSConnection(url.hostname, port=url.port or 443, timeout=5)
return HTTPConnection(url.hostname, port=url.port or 80, timeout=5)
def create_memo(
http_conn: HTTPSConnection | HTTPConnection, token: str, content: str, visibility: str
) -> tuple[HTTPResponse, str]:
http_conn.request(
method="POST",
url="/api/v2/memos",
body=json.dumps({"content": content, "visibility": visibility.upper()}),
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
},
)
response = http_conn.getresponse()
response_body = response.read().decode(errors="ignore")
return response, response_body
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument(
"--url", "-u", default=MEMOS_URL, help='"Something like "http://127.0.0.1:5230/"'
)
parser.add_argument("--token", "-t", default=MEMOS_TOKEN, help="Your Memos token")
parser.add_argument(
"--visibility", "-v", default=MEMO_VISIBILITY, help="PUBLIC, PROTECTED or PRIVATE"
)
parser.add_argument(
"--folder", "-f", default=SOURCE_FOLDER, help="Folder containing the text files"
)
parser.add_argument(
"--extensions",
"-e",
nargs="*",
default=SOURCE_EXTENSIONS,
help="Comma-separated list of file extensions",
)
args = parser.parse_args()
try:
connection = connect_to_memos(args.url)
except ValueError:
raise
root = Path(args.folder).expanduser().resolve()
if not root.is_dir():
exit("Invalid source folder")
print(f"Creating memos from {args.extensions} files in `{root}`...")
col_width = len(args.url) + 28
ok, failed = 0, 0
for file in root.glob("**/*"):
if not file.is_file() or file.suffix not in args.extensions:
continue
response, response_body = create_memo(
http_conn=connection,
token=args.token,
content=file.read_text(encoding="utf-8"),
visibility=args.visibility,
)
filename = f"{file.parent.name}/{file.name}"
body = json.loads(response_body)
if response.status != 200:
error = body.get("message")
print(
f"[❌] {response.reason} ({response.status}) - {error}".ljust(col_width)
+ f" ❌ {filename}"
)
failed += 1
else:
memo_uuid = body.get("memo").get("name")
memo_url = args.url.rstrip("/") + f"/m/{memo_uuid}"
print(f"[✅] {memo_url}".ljust(col_width) + f" ⏪ {filename}")
ok += 1
print(f"[DONE] {ok} memos were created successfully. Failed: {failed}.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment