Skip to main content

Merge pull request #3 from alexwlchan/add-obsidian-mastodon-script

ID
bb70efc
date
2023-12-10 10:33:19+00:00
author
Alex Chan <alex@alexwlchan.net>
parents
7193319, 06e36c8
message
Merge pull request #3 from alexwlchan/add-obsidian-mastodon-script

Add obsidian mastodon script
changed files
5 files, 146 additions, 1 deletion

Changed files

requirements.in (86) → requirements.in (99)

diff --git a/requirements.in b/requirements.in
index b8e8f1d..1077b60 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,10 +1,12 @@
 black
 flake8
+httpx
 humanize
 hyperlink
 keyring
 Pillow
 pillow_heif
 pip-tools
+pytest
 termcolor
 yt-dlp

requirements.txt (1596) → requirements.txt (1982)

diff --git a/requirements.txt b/requirements.txt
index f2cdf8c..983181a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,8 +2,10 @@
 # This file is autogenerated by pip-compile with Python 3.12
 # by the following command:
 #
-#    pip-compile
+#    pip-compile requirements.in
 #
+anyio==4.1.0
+    # via httpx
 black==23.11.0
     # via -r requirements.in
 brotli==1.1.0
@@ -12,6 +14,8 @@ build==1.0.3
     # via pip-tools
 certifi==2023.11.17
     # via
+    #   httpcore
+    #   httpx
     #   requests
     #   yt-dlp
 charset-normalizer==3.3.2
@@ -22,14 +26,24 @@ click==8.1.7
     #   pip-tools
 flake8==6.1.0
     # via -r requirements.in
+h11==0.14.0
+    # via httpcore
+httpcore==1.0.2
+    # via httpx
+httpx==0.25.2
+    # via -r requirements.in
 humanize==4.9.0
     # via -r requirements.in
 hyperlink==21.0.0
     # via -r requirements.in
 idna==3.4
     # via
+    #   anyio
+    #   httpx
     #   hyperlink
     #   requests
+iniconfig==2.0.0
+    # via pytest
 jaraco-classes==3.3.0
     # via keyring
 keyring==24.3.0
@@ -46,6 +60,7 @@ packaging==23.2
     # via
     #   black
     #   build
+    #   pytest
 pathspec==0.11.2
     # via black
 pillow==10.1.0
@@ -58,6 +73,8 @@ pip-tools==7.3.0
     # via -r requirements.in
 platformdirs==4.0.0
     # via black
+pluggy==1.3.0
+    # via pytest
 pycodestyle==2.11.1
     # via flake8
 pycryptodomex==3.19.0
@@ -66,8 +83,14 @@ pyflakes==3.1.0
     # via flake8
 pyproject-hooks==1.0.0
     # via build
+pytest==7.4.3
+    # via -r requirements.in
 requests==2.31.0
     # via yt-dlp
+sniffio==1.3.0
+    # via
+    #   anyio
+    #   httpx
 termcolor==2.3.0
     # via -r requirements.in
 urllib3==2.1.0

textexpander/README.md (0) → textexpander/README.md (437)

diff --git a/textexpander/README.md b/textexpander/README.md
new file mode 100644
index 0000000..c215b88
--- /dev/null
+++ b/textexpander/README.md
@@ -0,0 +1,16 @@
+# textexpander
+
+These scripts I invoke as text expansion macros in [TextExpander](https://textexpander.com/).
+
+## The individual scripts
+
+<dl>
+  <dt>
+    <a href="https://github.com/alexwlchan/scripts/blob/main/obsidian/get_mastodon_text.py">
+      <code>get_mastodon_text.py</code>
+    </a>
+  </dt>
+  <dd>
+    print a Markdown-formatted blockquote of a Mastodon I've got open in Safari, suitable for pasting into Obsidian
+  </dd>
+</dl>

textexpander/get_mastodon_text.py (0) → textexpander/get_mastodon_text.py (2171)

diff --git a/textexpander/get_mastodon_text.py b/textexpander/get_mastodon_text.py
new file mode 100755
index 0000000..be8e69d
--- /dev/null
+++ b/textexpander/get_mastodon_text.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+"""
+Look at the Mastodon URL in the frontmost Safari window, and print it
+as a blockquote.
+"""
+
+import datetime
+import os
+import pathlib
+import re
+import subprocess
+
+import httpx
+import hyperlink
+
+
+ATTACHMENTS_DIR = pathlib.Path.home() / "textfiles" / "Attachments" / "mastodon"
+
+
+def download(url):
+    """
+    Download a file to the attachments directory, or do nothing if it's
+    already downloaded.
+    """
+    resp = httpx.get(url)
+    content = resp.content
+
+    ATTACHMENTS_DIR.mkdir(exist_ok=True)
+
+    out_path = ATTACHMENTS_DIR / os.path.basename(url)
+
+    try:
+        with open(out_path, "xb") as out_file:
+            out_file.write(content)
+    except FileExistsError:
+        if open(out_path, "rb").read() == content:
+            pass
+        else:
+            raise
+
+
+def normalise_text(text: str) -> str:
+    text = text.replace("<p>", "").replace("</p>", "")
+    text = re.sub(
+        r'<a href="[^"]+" class="mention hashtag" rel="tag">#<span>(?P<hashtag>[^<]+)</span></a>',
+        r"\\#\g<hashtag>",
+        text,
+    )
+    return text
+
+
+if __name__ == "__main__":
+    url = subprocess.check_output(["/usr/local/bin/safari", "url"]).decode("utf8")
+
+    u = hyperlink.URL.from_text(url)
+
+    # e.g. https://hachyderm.io/@djnavarro/111535929722933178
+    # ~>  https://hachyderm.io/api/v1/statuses/111535929722933178
+    api_url = f"https://{u.host}/api/v1/statuses/{u.path[1]}"
+
+    resp = httpx.get(api_url)
+
+    post_data = resp.json()
+
+    for attachment in post_data["media_attachments"]:
+        download(attachment["url"])
+
+    author = post_data["account"]["display_name"]
+    post_url = post_data["url"]
+
+    # e.g. 2023-12-06T22:53:44.536Z
+    created_at = datetime.datetime.strptime(
+        post_data["created_at"], "%Y-%m-%dT%H:%M:%S.%fz"
+    )
+
+    print(f'[{author}]({post_url}) ({created_at.strftime("%-d %B %Y")}):')
+    print("")
+    print("> " + normalise_text(post_data["content"]))
+
+    if post_data["media_attachments"]:
+        print(">\n> ", end="")
+        for attachment in post_data["media_attachments"]:
+            print("![[%s|200]]" % os.path.basename(attachment["url"]), end="")
+
+    print("")

textexpander/test_get_mastodon_text.py (0) → textexpander/test_get_mastodon_text.py (575)

diff --git a/textexpander/test_get_mastodon_text.py b/textexpander/test_get_mastodon_text.py
new file mode 100644
index 0000000..00659f6
--- /dev/null
+++ b/textexpander/test_get_mastodon_text.py
@@ -0,0 +1,19 @@
+import pytest
+
+from get_mastodon_text import normalise_text
+
+
+@pytest.mark.parametrize(
+    ["input", "output"],
+    [
+        (
+            "<p>A variation on the previous system for todays <a "
+            'href="https://hachyderm.io/tags/ArtAdventCalendar" class="mention '
+            'hashtag" rel="tag">#<span>ArtAdventCalendar</span></a> '
+            "contribution</p>",
+            "A variation on the previous system for todays \#ArtAdventCalendar contribution",
+        )
+    ],
+)
+def test_normalise_text(input, output):
+    assert normalise_text(input) == output