<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Python on East of the Sun, West of the Moon</title>
    <link>https://is-here.com/tags/python/</link>
    <description>Recent content in Python on East of the Sun, West of the Moon</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>Erwin Harte</copyright>
    <lastBuildDate>Sun, 28 Dec 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://is-here.com/tags/python/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Teletekst Bot</title>
      <link>https://is-here.com/project/teletekst/</link>
      <pubDate>Sun, 28 Dec 2025 00:00:00 +0000</pubDate>
      
      <category>Mastodon</category><category>Python</category><comments>https://strangeweb.page/@jochie/115805471217337649</comments><guid>https://is-here.com/project/teletekst/</guid>
      <description>
&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-1&#34;&gt;
Status
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;Active since July 2024&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-2&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-2&#34;&gt;
What
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-2&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;Monitor the news (&amp;#34;Nieuws&amp;#34; in Dutch) such as it is shared by the &lt;a href=&#34;https://nos.nl/teletekst&#34;&gt;NOS Teletekst&lt;/a&gt;, by checking the references from the index pages at 101, 102, and 103, and then scan for any other pages from 104 to 199.&lt;/p&gt;
&lt;p&gt;
When a new page is found, or an existing page is updated (using a relatively basic heuristic), post the new or updated page to the Mastodon account. It also attempts to detect when a page is moved around.&lt;/p&gt;
&lt;p&gt;
Because occasionally pages are included for sport (in general) or soccer (voetbal), it will use an appropriate &lt;code class=&#34;verbatim&#34;&gt;#TeletekstXYZ&lt;/code&gt; hashtag for that, so people can mute that. The same goes for the content updates, which can be a bit much especially for emerging stories, and get tagged with &lt;code class=&#34;verbatim&#34;&gt;#TeletekstUpdate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;
For content updates the posts also includes comparison of the previous and current version with color-coding for words or lines that have been removed, were added, or stayed the same. It&amp;#39;s similar to &lt;code class=&#34;verbatim&#34;&gt;git diff&lt;/code&gt; but has been adapted to make more sense in this text context.&lt;/p&gt;
&lt;p&gt;
If the content was unchanged and only the page number or title changed, the existing Mastodon post is updated in place.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-3&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-3&#34;&gt;
Where
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-3&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://mstdn.social/@teletekst&#34;&gt;https://mstdn.social/@teletekst&lt;/a&gt; (originally at &lt;a href=&#34;https://botsin.space/@teletekst,&#34;&gt;https://botsin.space/@teletekst,&lt;/a&gt; but that server shut down at the end of 2024).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-4&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-4&#34;&gt;
How
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-4&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;There are two Cron jobs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Every 5 minutes a program &lt;em&gt;walks&lt;/em&gt; all the pages from 101 to 199, using the &lt;code class=&#34;verbatim&#34;&gt;next page&lt;/code&gt; references. If all pages are exactly identical, discard the results.

It needs to gracefully handle broken &lt;code class=&#34;verbatim&#34;&gt;next page&lt;/code&gt; links and other quirks.&lt;/li&gt;
&lt;li&gt;Also every 5 minutes, but a minute later, a second program checks if changes were found. If so, look for new pages, deletes pages, moved pages, and modified pages.

Two pages are treated differently, namely the &amp;#34;Kort nieuws binnenland&amp;#34; and &amp;#34;Kort nieuws buitenland&amp;#34;, where one or two short national or international news items are dumped.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-5&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-5&#34;&gt;
Disclaimer
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-5&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;This is &lt;strong&gt;not&lt;/strong&gt; an (official or endorsed) &lt;a href=&#34;https://nos.nl/&#34;&gt;NOS.nl&lt;/a&gt; service!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-6&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-6&#34;&gt;
Code
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-6&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://codeberg.org/jochie/Teletekst&#34;&gt;https://codeberg.org/jochie/Teletekst&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Read Later</title>
      <link>https://is-here.com/project/read-later/</link>
      <pubDate>Sun, 13 Jul 2025 00:00:00 +0000</pubDate>
      
      <category>Self-hosting</category><category>Docker</category><category>Python</category><comments>https://strangeweb.page/@@jochie/114848668662470733</comments><guid>https://is-here.com/project/read-later/</guid>
      <description>
&lt;div id=&#34;outline-container-headline-1&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-1&#34;&gt;
Status
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-1&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;Active since July 2025.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-2&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-2&#34;&gt;
What
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-2&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;A self-hosted bookmark/read-later service&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-3&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-3&#34;&gt;
Where
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-3&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://readeck.is-here.com/&#34;&gt;https://readeck.is-here.com/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-4&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-4&#34;&gt;
How
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-4&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;This service is setup as one of several virtual hosts on a virtual machine that is dedicated to a couple of these self-hosted things (the project page for is still WIP/AWOL for now).&lt;/p&gt;
&lt;p&gt;
To try and keep the maintenance requirements relatively low I used the docker approach, only sharing the data with the host system so that it is preserved over restarts and can be backed up regularly:&lt;/p&gt;
&lt;div class=&#34;src src-shell&#34;&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  docker run &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;         --detach &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;         --rm -ti &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;         -p 6080:8000 &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;         -v /var/www/readeck:/readeck &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;         codeberg.org/readeck/readeck:latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
A fragment of the Apache configuration file:&lt;/p&gt;
&lt;div class=&#34;src src-text&#34;&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ProxyPreserveHost On
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ProxyPass / http://0.0.0.0:6080/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ProxyPassReverse / http://0.0.0.0:6080/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  RequestHeader set X-Forwarded-Proto https&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Disclaimer: I don&amp;#39;t have a lot of experience with the &lt;code class=&#34;verbatim&#34;&gt;proxy&lt;/code&gt; or &lt;code class=&#34;verbatim&#34;&gt;proxy_http&lt;/code&gt; modules, so it&amp;#39;s possible that could be done better. There are more complete instructions on the Readeck &lt;a href=&#34;https://readeck.org/en/docs/deploy&#34;&gt;Deployment&lt;/a&gt; documentation page.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-5&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-5&#34;&gt;
Integrating it:
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-5&#34; class=&#34;outline-text-2&#34;&gt;
&lt;ul&gt;
&lt;li&gt;For Firefox I use this &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/user/18046494/&#34;&gt;Readeck add-on&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There is no iOS (or Android, for that matter) app but the (self-hosted) website can be added as a pseudo-app on iOS by using Safari&amp;#39;s &amp;#34;Add to Home Screen&amp;#34;.&lt;/li&gt;
&lt;li&gt;That pseudo-app doesn&amp;#39;t get you a &amp;#34;Share to …&amp;#34; entry, but thankfully there are acceptable workarounds (listed in the &lt;a href=&#34;https://readeck.org/en/docs/faq#is-there-an-android-or-ios-application&#34;&gt;FAQ&lt;/a&gt;) in the form of shortcuts.
It took a little bit of fidgeting to figure out how to configure the shortcut, but after that it was relatively smooth sailing.&lt;/li&gt;
&lt;li&gt;Although it&amp;#39;s somewhat redundant, I also created a script to check my Mastodon bookmarks and import new ones into Readeck. So if I&amp;#39;m in a hurry, I&amp;#39;ll quickly bookmark a &lt;del&gt;post&lt;/del&gt; toot, otherwise I&amp;#39;ll use the &amp;#34;Send Page + Tags To Readeck&amp;#34; shortcut.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;outline-container-headline-6&#34; class=&#34;outline-2&#34;&gt;
&lt;h2 id=&#34;headline-6&#34;&gt;
Code and related things
&lt;/h2&gt;
&lt;div id=&#34;outline-text-headline-6&#34; class=&#34;outline-text-2&#34;&gt;
&lt;p&gt;Originally I had planned to migrate from Instapaper (the read-later service I used for ~15 years) to a self-hosted &lt;a href=&#34;https://wallabag.it/en/&#34;&gt;Wallabag&lt;/a&gt; instance, but before the dust had even settled on that (meaning figuring out what browser add-on to use or how to integrate it on my phone) &lt;a href=&#34;https://shom.dev/posts/20250629_bookmarking-i-mean-omnivoring-no-hoarding-no-bagging-dot-dot-dot-wait-decking/&#34;&gt;this post&lt;/a&gt; by Shom pointed me towards &lt;a href=&#34;https://readeck.org/en/&#34;&gt;Readeck&lt;/a&gt;. That&amp;#39;s why the scripts below have a migration path from Instapaper -&amp;gt; Wallabag -&amp;gt; Readeck, and not Instapaper -&amp;gt; Readeck.&lt;/p&gt;
&lt;p&gt;
My collection of scripts in this &lt;a href=&#34;https://codeberg.org/jochie/read-later&#34;&gt;read-later repository&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&#34;verbatim&#34;&gt;wallabag_import.py&lt;/code&gt;: Iterate over the Instapaper entries and add them one by one to my (also self-hosted) Wallabag service. For the ~17k bookmarks that I had that took multiple hours and possibly got my IP in trouble with a few websites.&lt;/li&gt;
&lt;li&gt;&lt;code class=&#34;verbatim&#34;&gt;readeck_wallabag.py&lt;/code&gt;: Initiate a migration from Wallabag to Readeck (handled entirely by Readeck after that).&lt;/li&gt;
&lt;li&gt;&lt;code class=&#34;verbatim&#34;&gt;reprocess_readeck.py&lt;/code&gt;: Loop over all bookmarks in a Readeck collection, re-adding them and deleting the original ones as it goes.&lt;/li&gt;
&lt;li&gt;&lt;code class=&#34;verbatim&#34;&gt;bookmark_readeck.py&lt;/code&gt;: Check my Mastodon bookmarks and add any new ones to Readeck&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
  </channel>
</rss>
