<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Python on Natenoms Blog</title><link>https://natenom.de/tags/python/</link><description>Recent content in Python on Natenoms Blog</description><generator>Hugo -- gohugo.io</generator><language>de</language><copyright/><lastBuildDate>Tue, 09 Jan 2024 21:51:16 +0100</lastBuildDate><atom:link href="https://natenom.de/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>Mein Hugo Helper Python Script und was es tun kann</title><link>https://natenom.de/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/</link><pubDate>Tue, 09 Jan 2024 21:51:16 +0100</pubDate><guid>https://natenom.de/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/</guid><description>&lt;p>Alle meine Webseiten werden mit Hilfe von Hugo statisch generiert. Für die Arbeit mit Hugo nutze ich schon länger ein eigenes Python-Script, das mir einige Arbeit abnimmt.&lt;/p>
&lt;p>Vor ein paar Tagen hat mich jemand gefragt, ob ich das Script nicht öffentlich machen könnte und ich habe das zum Anlass genommen, da mal einige Dinge zu verschönern, damit auch andere Menschen damit etwas anfangen können.&lt;/p></description><content:encoded><![CDATA[<p>Alle meine Webseiten werden mit Hilfe von Hugo statisch generiert. Für die Arbeit mit Hugo nutze ich schon länger ein eigenes Python-Script, das mir einige Arbeit abnimmt.</p>
<p>Vor ein paar Tagen hat mich jemand gefragt, ob ich das Script nicht öffentlich machen könnte und ich habe das zum Anlass genommen, da mal einige Dinge zu verschönern, damit auch andere Menschen damit etwas anfangen können.</p>
<div class="shortcode-notice warnung">
    <div class="shortcode-notice-title warnung">
        Warnung</div>
    <div class="notice-content"><p>Ich bin kein Programmierer und das Script hat vermutlich eine eher schlechte Qualität. Aber das stört mich nicht, denn es funktioniert (für mich).</p>
<p>Wenn es andere Menschen für sich nutzen können, dann ist das großartig. Wenn nicht, dann ist es auch okay.</p>
</div>
</div>


<p>Zur Installation des Scripts bitte in die <code>README.md</code> des Projekts schauen.</p>

<h2 id="konfiguration" data-numberify>Konfiguration<a class="anchor ms-1" href="#konfiguration"></a></h2>
<p>In der Konfigurationsdatei <code>~/.config/hgh/hgh.json</code> gibt es einen Abschnitt für allgemeine Einstellungen und dann je einen Abschnitt pro Website, die mit hgh verwaltet werden soll.</p>
<p>Hier ist hinterlegt, welcher Editor verwendet werden soll, wo die Basisverzeichnisse der Websites liegen, wo die <code>content</code>-Verzeichnisse, welcher Benutzernamen für rsync verwendet werden soll, usw.</p>

<h2 id="ein-alias-macht-das-leben-einfacher" data-numberify>Ein Alias macht das Leben einfacher<a class="anchor ms-1" href="#ein-alias-macht-das-leben-einfacher"></a></h2>
<p>Damit ich nicht dauernd <code>hgh.py --site blog</code> tippen muss, habe ich für jede meiner Websites in der <code>.bashrc</code> einen Alias erstellt:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>alias hgb<span style="color:#f92672">=</span><span style="color:#e6db74">`</span>hgh.py --site blog<span style="color:#e6db74">`</span>
</span></span><span style="display:flex;"><span>alias hgw<span style="color:#f92672">=</span><span style="color:#e6db74">`</span>hgh.py --site wiki<span style="color:#e6db74">`</span>
</span></span></code></pre></div><p>Somit kann ich z. B. mittels <code>hgb -cdb</code> ins Basisverzeichnis des Blogs wechseln.</p>

<h2 id="was-der-hugo-helper-hgh-für-mich-macht" data-numberify>Was der Hugo Helper (hgh) für mich macht<a class="anchor ms-1" href="#was-der-hugo-helper-hgh-für-mich-macht"></a></h2>

<h3 id="allgemeine-infos" data-numberify>Allgemeine Infos<a class="anchor ms-1" href="#allgemeine-infos"></a></h3>
<p>Mit <code>--help</code> gibt es eine hoffentlich hilfreiche Hilfe. 😁</p>
<p>Mit <code>hgh.py --sites</code> bekomme ich eine Liste aller Websites und der zugehörigen Basisverzeichnisse. Mit <code>--printconfig</code> wird die ganze Konfiguration ausgegeben.</p>

<h3 id="verzeichniswechsel" data-numberify>Verzeichniswechsel<a class="anchor ms-1" href="#verzeichniswechsel"></a></h3>
<p>Mit <code>-cdb</code> kann ich ins Basisverzeichnis einer Website wechseln, mit <code>-cdc</code> ins normale Content-Verzeichnis und mit <code>-cdl</code> in ein alternatives Content-Verzeichnis.</p>
<p>Letzeres nutze ich für verschiedene Blogbeiträge im Entwurfsmodus. Denn mein Blog besteht aus mehreren tausend Blogbeiträgen und das Bauen dauert sehr lange. Zum Schreiben von längeren Blogbeiträgen nutze ich dieses Verzeichnis und das Bauen dauert dann nur wenige Sekunden.</p>

<h3 id="kommentar-datei" data-numberify>Kommentar-Datei<a class="anchor ms-1" href="#kommentar-datei"></a></h3>
<p>Für Kommentare im Blog nutze mittlerweile eine eigene Implementation, bei der die Kommentare im Page Bundle innerhalb der Datei <code>comments.json</code> stehen.</p>
<p>Mit <code>hgh.py --site blog --create-comments-file</code> wird im aktuellen Verzeichnis eine <code>comments.json</code>-Datei erstellt, die bereits ein Skelett für einen Kommentar enthält. Dazu wird die Info ausgegeben, dass man noch im Front Matter <code>jsoncomments: true</code> eintragen muss. Da es hier im Blog nur sehr selten Kommentare gibt, vergesse ich das sonst und will auch nicht jedes Mal nachschauen, wie die Syntax eines Kommentars ist.</p>

<h3 id="neuer-blogbeitrag" data-numberify>Neuer Blogbeitrag<a class="anchor ms-1" href="#neuer-blogbeitrag"></a></h3>
<p>Diese Funktion nutze ich nur für meinen Blog und kann mit einem kurzen <code>hgb --create &quot;Ein neuer Blogbeitrag bla blub&quot;</code> gleich mehrere Aufgaben automatisieren:</p>
<ul>
<li>benötigte Verzeichnisse erstellen</li>
<li>Slug aus dem angegebenen Titel erzeugen</li>
<li>Page Bundle erstellen</li>
<li>Markdown-Datei für den Blogbeitrag erstellen und mit einem Template befüllen</li>
</ul>
<p>Details dazu, was alles gemacht wird, gibt es <a  href="/2024/01/neues-helferlein-fuer-hugo-erleichtert-das-bloggen/">in diesem Blogbeitrag</a>.</p>
<p>In der aktuellen Version des Scripts kann ich auch noch mit <code>--template</code> angeben, welches Template verwendet werden soll.</p>
<p>Mit <code>hgh.py --list-templates</code> wird eine Liste aller vorhandenen Templates angezeigt.</p>
<p>Wer das benutzen will, muss den Code dafür im Script anpassen, um alle notwendigen Variablen auch zu befüllen.</p>

<h3 id="tmux" data-numberify>Tmux<a class="anchor ms-1" href="#tmux"></a></h3>
<p>Bevor ich VSCode für die Bearbeitung meiner Websites nutzte, habe ich dafür den micro-Editor auf der Kommandozeile benutzt. Aus dieser Zeit stammt <code>--tmux</code>, das ein bestimmtes Layout in Tmux startet. Das habe ich aber schon länger nicht mehr verwendet und man müsste es für sich anpassen.</p>

<h3 id="lokale-vorschau-einer-website" data-numberify>Lokale Vorschau einer Website<a class="anchor ms-1" href="#lokale-vorschau-einer-website"></a></h3>
<p>Mittels <code>--hugo-server</code> wird der Blog lokal gebaut und auf dem einstellbaren Port zugänglich gemacht. Für das alternative Content-Verzeichnis gibt es <code>--hugo-server-light</code>.</p>
<p>Dazu kann man noch <code>--hugo-server-env</code> angeben, mit dem sich einstellen lässt, welche Umgebung Hugo verwendet. Default hier ist <code>development</code>. Ich nutze diese Funktion, um den umfangreichen Blog testweise so zu bauen, dass nur die Blogbeiträge der letzten Monate enthalten sind, was dann statt 35 Sekunden (für den gesamten Blog) nur ca. 3 Sekunden dauert.</p>

<h3 id="tags-kategorien-und-deren-häufigkeit" data-numberify>Tags, Kategorien und deren Häufigkeit<a class="anchor ms-1" href="#tags-kategorien-und-deren-häufigkeit"></a></h3>
<p>Was mir am Anfang bei Hugo im Vergleich zu WordPress sehr gefehlt hat, waren die Vorschläge für zu verwendende Tags und Kategorien in einem neuen Blogbeitrag.</p>
<p>Hierfür muss man mit dem Hugo Helper eine kleine &ldquo;Datenbank&rdquo; erstellen lassen. Dazu wird mit Hilfe von <code>find</code> und dem Tool <code>yq</code> je eine Liste aller bisher verwendeten Tags und Kategorien erstellt und dazu auch die Häufigkeit der Verwendung angegeben.</p>
<p>Diese &ldquo;Datenbank&rdquo; erstellt man mit <code>hgh.py --site blog --create-tags-categories-caches</code> und das dauert ein paar Sekunden. Im Ergebnis werden innerhalb von <code>~/.cache/hgh/</code> für jede Website zwei Dateien erzeugt:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>&gt; ls -1 .cache/hgh/
</span></span><span style="display:flex;"><span>natenom.de_categories.list
</span></span><span style="display:flex;"><span>natenom.de_tags.list
</span></span></code></pre></div><p>Ein Auszug aus den Tags:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>[…]
</span></span><span style="display:flex;"><span>8:F-Droid
</span></span><span style="display:flex;"><span>1:FLAC
</span></span><span style="display:flex;"><span>4:Facebook
</span></span><span style="display:flex;"><span>1:Fahrbahn
</span></span><span style="display:flex;"><span>556:Fahrrad
</span></span><span style="display:flex;"><span>52:Fahrradanhänger
</span></span><span style="display:flex;"><span>1:Fahrradbubble
</span></span><span style="display:flex;"><span>22:Fahrradcomputer
</span></span><span style="display:flex;"><span>6:Fahrradmordor
</span></span><span style="display:flex;"><span>6:Fahrradparkplätze
</span></span><span style="display:flex;"><span>2:Fahrradstaffel
</span></span><span style="display:flex;"><span>1:Fahrräder
</span></span><span style="display:flex;"><span>10:Falschparker
</span></span><span style="display:flex;"><span>[…]
</span></span></code></pre></div><p>Um nicht manuell in den &ldquo;Datenbanken&rdquo; herumstöbern zu müssen, gibt es <code>--find-tags xyz</code> und <code>--find-categories xyz</code> bzw. die Kurzformen <code>-ft xyz</code> und <code>-fc xyz</code>. Man kann reguläre Ausdrücke verwenden.</p>
<p>Führt man diese aus, wird das Tool <code>fzf</code> (Fuzzy Find) benutzt, um die Liste anzuzeigen und darin suchen zu können:</p>

<figure class="shortcode-video">
    <video preload="metadata" controls>
    <source src="2024-01-06-hugo-searchtag.mp4" type="video/mp4" poster="">
    Your browser does not seem to support video.
    </video>

<figcaption>Mittels fzf kann man in der Liste der Tags suchen. Die Anzahl der Verwendung wird auch angezeigt. (<a href="2024-01-06-hugo-searchtag.mp4">Link zum Video</a>)</figcaption>
</figure>

<div class="shortcode-notice hinweis">
    <div class="shortcode-notice-title hinweis">
        Hinweis</div>
    <div class="notice-content">Ab und zu muss man die Datenbanken neu erstellen lassen, da sonst Tags und Kategorien neuer Blogbeiträge nicht enthalten sind.</div>
</div>


<div class="shortcode-notice hinweis">
    <div class="shortcode-notice-title hinweis">
        Hinweis</div>
    <div class="notice-content">Ich weiß, dass es für VSCode z. B. das Plugin FrontMatter gibt, das genau diese Funktionialität liefert. Ich möchte jedoch kein riesiges Plugin mit tausenden anderen Funktionen nutzen, wenn es auch einfacher geht. Und wer weiß, ob ich in x Zeit immer noch mit VSCode arbeiten werde.</div>
</div>



<h3 id="alles-andere-finden" data-numberify>Alles andere finden<a class="anchor ms-1" href="#alles-andere-finden"></a></h3>
<p>Mittlerweile nutze ich zum Auffinden von Blogbeitragen die Tastenkombination <code>Strg + Shift + f</code> in VSCode. Aber früher brauchte ich dafür etwas Eigenes.</p>
<p>Hierfür gibt es zwei Varianten.</p>

<h4 id="einfache-variante" data-numberify>Einfache Variante<a class="anchor ms-1" href="#einfache-variante"></a></h4>
<p>Mittels <code>--find xyz</code> bzw. der Kurzform <code>-f xyz</code> wird einfach nur rekursiv nach xyz im Content-Verzeichnis der angegebenen Website gegrept und es gibt eine farbige Ausgabe mit Dateinamen und der zum Suchbegriff passenden Zeile. Groß- und Kleinschreibung werden dabei nicht ignoriert.</p>
<p>Hier z. B. das Ergebnis für die Suche nach <code>^hugo</code>. Das ist ein Regulärer Ausdruck, der nur auf Zeilen passt, in denen <code>hugo</code> am Anfang der Zeile steht:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>posts/2022/2022-02-18-mein-workflow-mit-hugo/index.md:130:1:hugo server -E -D -F -v -c /home/hugo-light/content/
</span></span><span style="display:flex;"><span>posts/2022/2022-02-27-hugo-theme-optimiert-zeit-zum-rendern-massiv-verringert.md:24:1:hugo --templateMetrics --templateMetricsHints --gc --minify &gt; hugo-metric_0.txt
</span></span><span style="display:flex;"><span>posts/2022/2022-02-06-ich-mache-wieder-einen-linkdump-woechentlich/index.md:64:1:hugo new -k linkdump posts/2022-02-linkdump-kw-6-2022
</span></span><span style="display:flex;"><span>posts/2022/2022-03-19-umzug-dokuwiki-hugo-3-einrichtung/index.md:29:1:hugo new site wiki.natenom.com
</span></span><span style="display:flex;"><span>posts/2022/2022-02-03-umzug-von-wordpress-zu-hugo-1/index.md:310:1:hugo server --renderToDisk -D -E -F -v
</span></span><span style="display:flex;"><span>posts/2022/2022-02-13-weiterleitungen-auf-umlaut-urls/index.md:55:1:hugo-search-tags -E &#34;(ä|ö|ü|ß)&#34; | cut -d&#39;:&#39; -f2 &gt; /tmp/umlaut-urls-hugo.txt
</span></span></code></pre></div><p>So kann ich z. B. sehr einfach alle Blogbeiträge anzeigen lassen, die ein bestimmtes Tag oder eine Kategorie verwenden, hier z. B. &ldquo;Linux&rdquo;, in dem ich den Regulären Ausdruck <code>hgb -f &quot;^\W+- Linux&quot;</code> nutze, der auf Zeilen passt, die am Zeilenanfang beliebig viele Leerzeichen enthalten, gefolgt von <code>- Linux</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>[…]
</span></span><span style="display:flex;"><span>posts/2013/2013-06-27-alle-videos-eines-youtube-kanals-auf-einmal-herunterladen-mit-youtube-dl.md:7:1:  - Linux
</span></span><span style="display:flex;"><span>posts/2018/2018-11-12-mit-fensterregeln-in-plasma5-kde-bestimmte-fenster-beim-task-switcher-und-anderen-effekten-ignorieren.md:13:1:  - Linux
</span></span><span style="display:flex;"><span>posts/2013/2013-08-15-neuer-versuch-mit-kde-sc.md:11:1:  - Linux
</span></span><span style="display:flex;"><span>[…]
</span></span></code></pre></div>
<h4 id="erweiterte-variante" data-numberify>Erweiterte Variante<a class="anchor ms-1" href="#erweiterte-variante"></a></h4>
<p>Mittels <code>--find-fuzzy xyz</code> bzw. der Kurzform <code>-ff xyz</code> wird die Ausgabe der oben gezeigten einfachen Variante zusätzlich an <code>fzf</code> übergeben, sodass man darin suchen kann, eine Vorschau der Datei angezeigt bekommt und durch Drücken von <code>F4</code> die Datei direkt im Editor öffnen kann, den man in der Konfiguration in <code>bin_editor</code> eingestellt hat.</p>
<p>Auch hier kann man reguläre Ausdürcke verwenden, z. B. <code>-ff &quot;Markdown.*kate&quot;</code></p>
 <figure class="image-caption"><a href="2024-01-09-beispiel-hgh-ff-cover.webp"><picture>
                <source type="image/webp" srcset="/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_360x0_resize_q95_h2_catmullrom_2.webp 360w,/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_500x0_resize_q95_h2_catmullrom_2.webp 500w,/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_816x0_resize_q95_h2_catmullrom_2.webp 816w"
                                          sizes="(max-width: 424px) 360px, (max-width: 596px) 500px, (min-width: 565px) 816px" />
                <img alt="" srcset="/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_360x0_resize_q95_h2_catmullrom_2.webp 360w, /2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_500x0_resize_q95_h2_catmullrom_2.webp 500w, /2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_816x0_resize_q95_h2_catmullrom_2.webp 816w"
                     sizes="(max-width: 424px) 360px, (max-width: 596px) 500px, (min-width: 565px) 816px"
                     src="/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover_hub930d5896ab04f44420e5ef9ccf62eb9_74206_816x0_resize_q95_h2_catmullrom_2.webp" title="" loading="lazy" width="816" height="623" /></picture></a></figure>

<h3 id="website-bauen-und-hochladen" data-numberify>Website bauen und hochladen<a class="anchor ms-1" href="#website-bauen-und-hochladen"></a></h3>
<p>Mit <code>hgh.py --site blog --build</code> wird mein Blog lokal gebaut, sodass ich ihn nach einer kurzen Prüfung mit <code>hgh.py --site blog --upload</code> hochladen kann.</p>
<p>Wenn ich mir sicher bin, kann ich auch beide Schritte vereinen mit <code>hgh.py --site blog --deploy</code>.</p>

<h2 id="hugo-helper-herunterladen" data-numberify>Hugo Helper herunterladen<a class="anchor ms-1" href="#hugo-helper-herunterladen"></a></h2>
<p>Das Hugo Helper Script gibt es <a  class='urlextern'  href="https://code.cozy.town/natenom/hgh">hier</a>.</p>
<p>Viel Spaß damit. Oder eben nicht. ☺️</p>]]></content:encoded><enclosure url="https://natenom.de/2024/01/mein-hugo-helper-python-script-und-was-es-tun-kann/2024-01-09-beispiel-hgh-ff-cover.webp" length="74206" type="image/webp"/></item><item><title>Verbessertes Script für Häufigkeit von Kategorien und Tags in einem Hugo Blog (Update 2024-01-09)</title><link>https://natenom.de/2024/01/verbessertes-script-fuer-haeufigkeit-von-kategorien-und-tags-in-einem-hugo-blog/</link><pubDate>Sat, 06 Jan 2024 07:57:13 +0100</pubDate><guid>https://natenom.de/2024/01/verbessertes-script-fuer-haeufigkeit-von-kategorien-und-tags-in-einem-hugo-blog/</guid><description>&lt;p>Vor langer Zeit hatte ich mal eine sehr umständliche Möglichkeit geschaffen, um in der Shell anzuzeigen, welche Tags und Kategorien in meinem Blog wie häufig verwendet wurden.&lt;/p>
&lt;p>Das habe ich nun deutlich vereinfacht.&lt;/p></description><content:encoded><![CDATA[<p>Vor langer Zeit hatte ich mal eine sehr umständliche Möglichkeit geschaffen, um in der Shell anzuzeigen, welche Tags und Kategorien in meinem Blog wie häufig verwendet wurden.</p>
<p>Das habe ich nun deutlich vereinfacht.</p>
<div class="shortcode-notice update">
    <div class="shortcode-notice-title update">
        Update</div>
    <div class="notice-content">2024-01-09: Das Script ist jetzt in meinem veröffentlichten Hugo Helper enthalten, <a  href="/2024/01/wofuer-ich-mein-hugo-helper-python-script-verwende-und-wo-man-es-findet/">siehe hier</a>.</div>
</div>



<h2 id="alte-lösung-mit-hugo-und-sehr-umständlich" data-numberify>Alte Lösung mit Hugo und sehr umständlich<a class="anchor ms-1" href="#alte-lösung-mit-hugo-und-sehr-umständlich"></a></h2>
<p>Früher hatte ich das mit Hilfe von Hugo gemacht, das lokal eine eigene Seite im Blog erstellt hat. Die HTML-Ausgabe davon habe ich dann durch diverse Shell-Kommandos gefiltert und heraus kamen Tags und deren Häufigkeit. Das musste man dann ab und zu mal neu generieren lassen und war alles andere als einfach zu benutzen. Details siehe <a  href="/2022/02/kategorien-und-tags-anzahl-vorkommen-hugo-anzeige-und-filter/">hier</a>.</p>

<h2 id="jetzt-ohne-hugo" data-numberify>Jetzt ohne Hugo<a class="anchor ms-1" href="#jetzt-ohne-hugo"></a></h2>
<p>Jetzt habe ich das außerhalb von Hugo mit einem Python-Script und einem Shell-Script umgesetzt.</p>
<p>Ich habe ein Shell-Script erstellt, das alle Tags und Kategorien aller Blogbeiträge mit Hilfe von <code>yq</code> ausliest und in eine Datei schreibt, die von einem Python-Script eingelesen wird und Häufigkeit der Tags und Kategorien bestimmt und das Ergebnis in einer endgültigen Datei speichert.</p>
<p>Man könnte das auch alles in einem einzigen Python-Script unterbringen, doch ich kann das nicht. Ich habe es versucht, es aber nicht geschafft.</p>

<h2 id="detaillierter-ablauf" data-numberify>Detaillierter Ablauf<a class="anchor ms-1" href="#detaillierter-ablauf"></a></h2>
<p>Im ersten Schritt werden im <code>content</code>-Verzeichnis des Blogs mit find und mit Hilfe von <code>yq</code> alle Tags jedes Blogbeitrags ausgelesen und ein eine Datei geschrieben:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>find -iname <span style="color:#e6db74">&#34;*.md&#34;</span> -exec yq --front-matter<span style="color:#f92672">=</span>extract <span style="color:#e6db74">&#34;.tags&#34;</span> <span style="color:#e6db74">&#39;{}&#39;</span> &gt;&gt; <span style="color:#e6db74">&#34;/tmp/tmp_tags.list&#34;</span> <span style="color:#ae81ff">\;</span>
</span></span></code></pre></div><p>Für diesen Blogbeitrag hier würde die Ausführung dieser Zeile ergeben:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>- Web
</span></span><span style="display:flex;"><span>- Hugo
</span></span><span style="display:flex;"><span>- Bash
</span></span><span style="display:flex;"><span>- Python
</span></span><span style="display:flex;"><span>- Shell
</span></span></code></pre></div><p>Das Ergebnis ist eine Datei mit ca. 9000 unsortierten und sehr vielen Zeilen und doppelt vorkommenden Tags, weil für jeden Blogbeitrag die Liste aller dort verwendeten Tags in die Datei eingefügt wird.</p>
<p>Im nächsten Schritt wird das Python-Script aufgerufen, das diese Datei Zeile für Zeile einliest, für jedes neue Wort einen eigenen Zähler in einem Dictionary erstellt und für bereits vorgekommene Wörter den Zähler um 1 erhöht. Ich habe dafür <a  class='urlextern'  href="https://www.geeksforgeeks.org/python-count-occurrences-of-each-word-in-given-text-file/">hier</a> ein passendes Script gefunden und es für meine Zwecke angepasst.</p>
<p>Am Ende des Python-Scripts wird das Dictionary sortiert ausgegeben und in eine finale Datei umgeleitet.</p>
<p>Ein Auszug der finalen Datei mit nur noch 819 Zeilen mit je einem Tag pro Zeile und dessen Häufigkeit im Blog:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>[…]
</span></span><span style="display:flex;"><span>Aussicht 5
</span></span><span style="display:flex;"><span>Auswertungen 5
</span></span><span style="display:flex;"><span>Autobahn 7
</span></span><span style="display:flex;"><span>Autofahrer 9
</span></span><span style="display:flex;"><span>Autos 129
</span></span><span style="display:flex;"><span>Avatar 1
</span></span><span style="display:flex;"><span>BNN 2
</span></span><span style="display:flex;"><span>BOA 2
</span></span><span style="display:flex;"><span>[…]
</span></span><span style="display:flex;"><span>Zebrastreifen 4
</span></span><span style="display:flex;"><span>Zeichnen 2
</span></span><span style="display:flex;"><span>Zeit Online 4
</span></span><span style="display:flex;"><span>Zeitraffer 2
</span></span><span style="display:flex;"><span>Zeitungen 8
</span></span><span style="display:flex;"><span>Zeitzonen 1
</span></span><span style="display:flex;"><span>Zertifikate 4
</span></span><span style="display:flex;"><span>Zuständigkeiten 1
</span></span><span style="display:flex;"><span>ZweiRat 3
</span></span><span style="display:flex;"><span>[…]
</span></span></code></pre></div><p>Mit Hilfe des Tools <code>fzf</code> (Fuzzy Finder) kann ich nun sehr einfach in dieser Datei nach Tags suchen, die im Blog verwendet wurden und sehe auch gleich die Häufigkeit.</p>
<p>Und hier ein Video von der Benutzung mittels <code>fzf</code>:</p>

<figure class="shortcode-video">
    <video preload="metadata" controls>
    <source src="2024-01-06-hugo-searchtag.mp4" type="video/mp4" poster="">
    Your browser does not seem to support video.
    </video>

<figcaption>(<a href="2024-01-06-hugo-searchtag.mp4">Link zum Video</a>)</figcaption>
</figure>


<h2 id="update-der-daten" data-numberify>Update der Daten<a class="anchor ms-1" href="#update-der-daten"></a></h2>
<p>Um die Daten zu aktualisieren, muss ich nur ab und zu das Script ausführen und die Ausführung dauert nur ein paar Sekunden.</p>]]></content:encoded></item><item><title>Tool für lokales Mastodon-Archiv, HTML-Export, Suchfunktion und mehr</title><link>https://natenom.de/2023/08/tool-fuer-lokales-mastodon-archiv-html-export-suchfunktion-und-mehr/</link><pubDate>Sun, 06 Aug 2023 17:36:04 +0200</pubDate><guid>https://natenom.de/2023/08/tool-fuer-lokales-mastodon-archiv-html-export-suchfunktion-und-mehr/</guid><description><![CDATA[<p>Der <a  href="https://kagube.de/">kleine Elefant hat schon länger einen eigenen Blog</a> und alle x Zeit versuche ich, dem seine ganzen Selfies nach und nach auch in seinen Blog zu schubsen. Aktuell hängt das ordentlich hinterher und ich habe überlegt, wie ich mir viel Arbeit sparen könnte.</p>
<p>Ich muss dazu jeden wichtigen Toot aus der Timeline heraussuchen, den Text kopieren, die zugehörigen Fotos von der lokalen Festplatte heraussuchen, passend benennen und dann einen Blogpost in Hugo erstellen.</p>
<p>Deshalb habe ich nach Tools gesucht, die diese Arbeit vereinfachen und z. B. eine lokale Version der Timeline zur Verfügung stellen, damit ich diese Arbeit auch ohne Netzwerkzugang machen kann.</p>]]></description><content:encoded><![CDATA[<p>Der <a  href="https://kagube.de/">kleine Elefant hat schon länger einen eigenen Blog</a> und alle x Zeit versuche ich, dem seine ganzen Selfies nach und nach auch in seinen Blog zu schubsen. Aktuell hängt das ordentlich hinterher und ich habe überlegt, wie ich mir viel Arbeit sparen könnte.</p>
<p>Ich muss dazu jeden wichtigen Toot aus der Timeline heraussuchen, den Text kopieren, die zugehörigen Fotos von der lokalen Festplatte heraussuchen, passend benennen und dann einen Blogpost in Hugo erstellen.</p>
<p>Deshalb habe ich nach Tools gesucht, die diese Arbeit vereinfachen und z. B. eine lokale Version der Timeline zur Verfügung stellen, damit ich diese Arbeit auch ohne Netzwerkzugang machen kann.</p>
<h2 id="zwei-methoden-für-erstellung-eines-archivs-von-mastodon" data-numberify>Zwei Methoden für Erstellung eines Archivs von Mastodon<a class="anchor ms-1" href="#zwei-methoden-für-erstellung-eines-archivs-von-mastodon"></a></h2>
<p>Es gibt zwei verschiedene Methoden:</p>
<ol>
<li>In Mastodon anmelden und in den Einstellungen das eigene Archiv anfordern und dieses herunterladen. Dort sind alle Status (Mehrzahl 🥳) enthalten und auch alle hochgeladenen Medien. Händisch möchte ich aus diesem Archiv nichts heraussuchen müssen, da es aus json-Dateien und einer Verzeichnisstruktur für die Mediendateien besteht. Hierfür gibt es jedoch verschiedene Tools, die ein solches Archiv präsentieren und erkundbar darstellen.</li>
<li>Ein Tool, wie das hier vorgestellte, lädt mit entsprechenden Berechtigungen selbst Boots, Toots und alles andere (Fotos, …) direkt vom Mastodon-Server herunter und erstellt lokal ein eigenes Archiv.</li>
</ol>

<h2 id="das-tool-mastodon-archive" data-numberify>Das Tool mastodon-archive<a class="anchor ms-1" href="#das-tool-mastodon-archive"></a></h2>
<p>Es gibt mehrere solcher Werkzeuge, mit gefällt <a  class='urlextern'  href="https://github.com/kensanata/mastodon-archive">mastodon-archive</a>. Es ist in Python geschrieben, lässt sich via pip/pipx installieren, fordert Berechtigungen zum Account an, die man auf Mastodon bestätigen muss und lädt dann alle Toots herunter.</p>
<p>Mit diesen heruntergeladenen Daten kann man schließlich verschiedene Dinge anstellen, z. B. nach einem String in den Toots suchen.</p>
<p>Sie Suchfunktion unterstützt auch Reguläre Ausdrücke, siehe <a  class='urlextern'  href="https://github.com/kensanata/mastodon-archive#searching-your-archive">hier</a>.</p>

<h2 id="installation" data-numberify>Installation<a class="anchor ms-1" href="#installation"></a></h2>
<p>Für mich ganz einfach mit <code>pipx install mastodon-archive</code>.</p>
<p>Siehe auch <a  class='urlextern'  href="https://github.com/kensanata/mastodon-archive#installation">hier</a></p>

<h2 id="archiv-für-einen-mastodon-account-erstellen" data-numberify>Archiv für einen Mastodon-Account erstellen<a class="anchor ms-1" href="#archiv-für-einen-mastodon-account-erstellen"></a></h2>
<p>Am besten ein neues Verzeichnis erstellen und dorthin wechseln:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir archiv
</span></span><span style="display:flex;"><span>cd archiv
</span></span></code></pre></div><p>Dann werden alle Status (Mehrzahl) usw. heruntergeladen, wobei ich kein Interesse an Favoriten und Bookmarks habe:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; mastodon-archive archive --no-favourites --no-bookmarks ploggifanti@plushies.social
</span></span><span style="display:flex;"><span>Registering app
</span></span><span style="display:flex;"><span>This app needs access to your Mastodon account.
</span></span><span style="display:flex;"><span>Visit the following URL and authorize the app:
</span></span><span style="display:flex;"><span>https://plushies.social/oauth/authorize?client_id<span style="color:#f92672">=</span>…&amp;response_type<span style="color:#f92672">=[</span>…<span style="color:#f92672">]</span>&amp;<span style="color:#f92672">[</span>…<span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>Then paste the access token here:
</span></span><span style="display:flex;"><span>abcdefgh…
</span></span><span style="display:flex;"><span>Get user info
</span></span><span style="display:flex;"><span>Get all statuses <span style="color:#f92672">(</span>this may take a <span style="color:#66d9ef">while</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Get favourites <span style="color:#f92672">(</span>this may take a <span style="color:#66d9ef">while</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Get bookmarks <span style="color:#f92672">(</span>this may take a <span style="color:#66d9ef">while</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Skipping mentions
</span></span><span style="display:flex;"><span>Skipping followers
</span></span><span style="display:flex;"><span>Skipping following
</span></span><span style="display:flex;"><span>Saving <span style="color:#ae81ff">182</span> statuses, <span style="color:#ae81ff">354</span> favourites, <span style="color:#ae81ff">5</span> bookmarks, <span style="color:#ae81ff">0</span> mentions, <span style="color:#ae81ff">0</span> followers, and <span style="color:#ae81ff">0</span> following
</span></span></code></pre></div><p>Dann lädt man zusätzlich alle Bilder und Videos herunter:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; mastodon-archive media ploggifanti@plushies.social
</span></span><span style="display:flex;"><span><span style="color:#ae81ff">168</span> urls in your backup <span style="color:#f92672">(</span><span style="color:#ae81ff">83</span> are previews<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>Downloading |<span style="color:#75715e">#############################   | 160/168</span>
</span></span></code></pre></div><p>Das wars schon. Alles weitere geht jetzt auch ohne Netzwerkanbindung.</p>
<p>Zu einem späteren Zeitpunkt kann man beides erneut ausführen, damit neuere Daten heruntergeladen und zum lokalen Archiv hinzugefügt werden.</p>

<h2 id="lokales-archiv-als-html-datei-exportieren" data-numberify>Lokales Archiv als HTML-Datei exportieren<a class="anchor ms-1" href="#lokales-archiv-als-html-datei-exportieren"></a></h2>
<p>Hiermit wird im aktuellen Verzeichnis eine HTML-Datei erstellt, die alle Status (Mehrzahl) enthält.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; mastodon-archive html ploggifanti@plushies.social
</span></span><span style="display:flex;"><span>Loading existing archive: plushies.social.user.ploggifanti.json
</span></span><span style="display:flex;"><span>Writing plushies.social.user.ploggifanti.statuses.0.html
</span></span></code></pre></div>
<h2 id="anpassungen-des-codes-für-eigene-anforderungen" data-numberify>Anpassungen des Codes für eigene Anforderungen<a class="anchor ms-1" href="#anpassungen-des-codes-für-eigene-anforderungen"></a></h2>
<p>Ich habe den Python-Code für die Erstellung des HTML-Archivs etwas angepasst. Zum einen brauche ich daran keine Boosts anderer Toots und zum anderen habe ich einen Fehler beim Anzeigen von Bildern behoben; per Voreinstellung werden diese nur teilweise dargestellt.</p>
<p>Dazu habe ich die Datei <code>html.py</code> wie folgt angepasst:</p>
<ul>
<li>Boosts nicht exportieren:
<ul>
<li>Nach Zeile 241 <code>if status[&quot;reblog&quot;] is not None:</code> ein <code>return</code> eingefügt, damit der Code für Boosts nicht ausgeführt wird.</li>
</ul>
</li>
<li>Fix für Darstellung von Bildern:
<ul>
<li>Zeile 118 <code>height: 110px;</code> auskommentiert.</li>
<li>Zeile 138 <code>transform: translateY(-50%%);</code> auskommentiert.</li>
</ul>
</li>
</ul>
<p>So sieht die erstellte HTML-Datei für den Account vom kleinen Elefanten aus:</p>
 <figure class="image-caption"><a href="2023-08-06-vorschau-mastodon-archiv.webp"><picture><source type="webp" srcset="/2023/08/tool-fuer-lokales-mastodon-archiv-html-export-suchfunktion-und-mehr/2023-08-06-vorschau-mastodon-archiv.webp" />
			         <img alt="" src="/2023/08/tool-fuer-lokales-mastodon-archiv-html-export-suchfunktion-und-mehr/2023-08-06-vorschau-mastodon-archiv.webp" title="" width="648" height="2408" loading="lazy" /></picture></a></figure>

<h2 id="nach-einem-string-suchen" data-numberify>Nach einem String suchen<a class="anchor ms-1" href="#nach-einem-string-suchen"></a></h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; mastodon-archive text ploggifanti@plushies.social wald
</span></span><span style="display:flex;"><span>Kagube @ploggifanti 2023-07-13T19:09:00.188000+00:00
</span></span><span style="display:flex;"><span>🔗 https://plushies.social/@ploggifanti/110708348694463740
</span></span><span style="display:flex;"><span>🐘Heut hab ich mir ein
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span><span style="color:#75715e">#DemKleinenElefantenSeinTäglichesSelfie](https://plushies.social/tags/DemKleinenElefantenSeinT%C3%A4glichesSelfie)</span>
</span></span><span style="display:flex;"><span>auf ner Landstraße mit Sonnenuntergangsstimmung und Wald und Linien und so
</span></span><span style="display:flex;"><span>gewünscht.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>🐘Nebenbei guckn, ob nicht jmd mitm Auto kommt. 🤪🖻 plushies.social.user.ploggifanti/plushiessocial/media_attachments/files/110/708/348/622/325/544/original/3f9e6457b052ea0e.webp
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Kagube @ploggifanti 2023-08-01T15:18:55.330000+00:00
</span></span><span style="display:flex;"><span>🔗 https://plushies.social/@ploggifanti/110815027876908056
</span></span><span style="display:flex;"><span>🐘Wir waren heute 40km mit dem Fahrrad unterwegs und haben schöne Momente für
</span></span><span style="display:flex;"><span>euch eingepackt.  
</span></span><span style="display:flex;"><span>...  
</span></span><span style="display:flex;"><span>🐘Hier warn wir im Wald🎁🌳  
</span></span><span style="display:flex;"><span>🐘Hier auf der <span style="color:#f92672">[</span><span style="color:#75715e">#Pausenbank](https://plushies.social/tags/Pausenbank) sonnen 🎁💺  </span>
</span></span><span style="display:flex;"><span>🐘Hier die schöne Landschaft 🏞🎁  
</span></span><span style="display:flex;"><span>🐘Und hier im Garten 🎁🏡  
</span></span><span style="display:flex;"><span>🐘Das ist ganz besonders toll. Auf der Wiese sitzen und dem Wind zuhören, was
</span></span><span style="display:flex;"><span>der so alles zu erzählen hat. ☁🎁  
</span></span><span style="display:flex;"><span>🐘Und dann auch noch der Moment mit
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span><span style="color:#75715e">#Blümchenbaden](https://plushies.social/tags/Bl%C3%BCmchenbaden) vom</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span><span style="color:#75715e">#DemKleinenElefantenSeinTäglichesSelfie](https://plushies.social/tags/DemKleinenElefantenSeinT%C3%A4glichesSelfie)</span>
</span></span><span style="display:flex;"><span>🎁💐
</span></span><span style="display:flex;"><span>🐘Viel Spaß damit und bis wieder gesund.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>🐘🤗  
</span></span><span style="display:flex;"><span>🚴🤗
</span></span></code></pre></div>
<h2 id="status-mehrzahl-löschen" data-numberify>Status (Mehrzahl) löschen<a class="anchor ms-1" href="#status-mehrzahl-löschen"></a></h2>
<p>Mit dem Tool kann man auch Status löschen, siehe <a  class='urlextern'  href="https://github.com/kensanata/mastodon-archive#expiring-your-toots-and-favourites">hier</a>.</p>
<p>So löscht man z. B. alle Status, die älter als zwei Wochen sind, sofern man noch <code>--confirm</code> angibt:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mastodon-archive expire --older-than <span style="color:#ae81ff">2</span> ploggifanti@plushies.social
</span></span><span style="display:flex;"><span>Loading existing archive: plushies.social.user.ploggifanti.json
</span></span><span style="display:flex;"><span>This is a dry run and nothing will be expired.
</span></span><span style="display:flex;"><span>Instead, we<span style="color:#960050;background-color:#1e0010">&#39;</span>ll just list what would have happened.
</span></span><span style="display:flex;"><span>Use --confirmed to actually <span style="color:#66d9ef">do</span> it.
</span></span><span style="display:flex;"><span>Delete: 2023-07-19 <span style="color:#e6db74">&#34;🐘Ich hab den 🚴 ganz dolle angefeuert, damit wir no...&#34;</span>
</span></span><span style="display:flex;"><span>Delete: 2023-06-09 <span style="color:#e6db74">&#34;🐘Du, 🚴, wann sind wir da?   🚴Wir sind doch gar nic...&#34;</span>
</span></span><span style="display:flex;"><span>Delete: 2023-07-21 <span style="color:#e6db74">&#34;🐘Der 🚴 und der 🐘: 🤪   🐘Immer sind wir draußen und ...&#34;</span>
</span></span><span style="display:flex;"><span>Delete: 2023-07-02 <span style="color:#e6db74">&#34;@Okona   🐘Dafür sind wir gestern extra nach #Tübin...&#34;</span>
</span></span></code></pre></div><div class="shortcode-notice hinweis">
    <div class="shortcode-notice-title hinweis">
        Hinweis</div>
    <div class="notice-content">Wenn ich das richtig verstehe, bleiben Toots im lokalen Archiv auch dann erhalten, wenn man sie mit diesem Tool online löschen lässt. Das finde ich gut. So kann ich das lokale Archiv immer mal wieder aktualisieren und trotzdem online alles nach x Zeit löschen lassen.</div>
</div>



<h2 id="report" data-numberify>Report<a class="anchor ms-1" href="#report"></a></h2>
<p>Es gibt auch die Möglichkeit, ein paar Infos zum Account auszugeben, siehe <a  class='urlextern'  href="https://github.com/kensanata/mastodon-archive#reporting">hier</a>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>&gt; mastodon-archive report --all ploggifanti@plushies.social
</span></span><span style="display:flex;"><span>Considering the entire archive
</span></span><span style="display:flex;"><span>Statuses:               <span style="color:#ae81ff">182</span>
</span></span><span style="display:flex;"><span>Boosts:                  <span style="color:#ae81ff">15</span>
</span></span><span style="display:flex;"><span>Media:                   <span style="color:#ae81ff">74</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Top <span style="color:#ae81ff">10</span> hashtags:
</span></span><span style="display:flex;"><span><span style="color:#75715e">#demkleinenelefantenseintaglichesselfie(48) #gpn21(5) #pausenbank(4)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#criticalmass(3) #kasrue(3) #karlsruhe(2) #fahrradfreitag(2)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#tubingen(2) #tubix(2) #kde(2)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Favourites:             <span style="color:#ae81ff">354</span>
</span></span><span style="display:flex;"><span>Boosts:                   <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>Media:                   <span style="color:#ae81ff">82</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Top <span style="color:#ae81ff">10</span> hashtags:
</span></span><span style="display:flex;"><span><span style="color:#75715e">#turnverein(11) #demkleinenelefantenseintaglichesselfie(5)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#baumklettern(5) #turnvereinys(3) #barland(3) #schlafschlaf(3)</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#eichhornchen(3) #fahrradfreitag(2) #kidicalmass(2) #bamberg(2)</span>
</span></span></code></pre></div>
<h2 id="noch-mehr-vereinfachen" data-numberify>Noch mehr vereinfachen?<a class="anchor ms-1" href="#noch-mehr-vereinfachen"></a></h2>
<p>Das generierte HTML-Archiv hilft mir schon sehr beim Erstellen der Blogbeiträge für den kleinen Elefanten.</p>
<p>Es müsste doch aber auch möglich sein aus diesem Archiv auch direkt Blogbeiträgt für Hugo zu generieren. Mal sehen, wie faul ich bin und ob mir die lokale HTML-Datei schon ausreicht oder ich versuchen werde, das auch noch zu automatisieren, sodass ich am Ende ein Kommando ausführen kann und anhand der Mastodon-Timeline automatisch der Content für Hugo erstellt wird.</p>]]></content:encoded><enclosure url="https://natenom.de/2023/08/tool-fuer-lokales-mastodon-archiv-html-export-suchfunktion-und-mehr/cover.webp" length="35106" type="image/webp"/></item><item><title>Alte Tröts auf Mastodon löschen</title><link>https://natenom.de/2022/11/alte-troets-von-mastodon-loeschen/</link><pubDate>Sun, 20 Nov 2022 17:52:15 +0100</pubDate><guid>https://natenom.de/2022/11/alte-troets-von-mastodon-loeschen/</guid><description>&lt;p>Man kann zwar Mastodon mittlerweile so einstellen, dass alte Tröts automatisch gelöscht werden sollen (&lt;a href="/2022/04/mastodon-kann-selbst-automatisch-loeschen/">siehe hier&lt;/a>), wenn man darüber jedoch etwas mehr Kontrolle haben möchte, benötigt man externe Werkzeuge.&lt;/p></description><content:encoded><![CDATA[<p>Man kann zwar Mastodon mittlerweile so einstellen, dass alte Tröts automatisch gelöscht werden sollen (<a  href="/2022/04/mastodon-kann-selbst-automatisch-loeschen/">siehe hier</a>), wenn man darüber jedoch etwas mehr Kontrolle haben möchte, benötigt man externe Werkzeuge.</p>
<p>So auch für meinen Mastodon-Account. Dort sollen zwar Tröts gelöscht werden, die älter als 3 Monate sind, jedoch nicht, wenn sie das Hashtag <code>#blogcomments</code> beinhalten. Denn das nutze ich, um im Blog <a  href="/2022/11/kommentare-in-meinem-statischen-blog-via-mastodon/">Kommentare zu ermöglichen</a>. Diese speziellen Tröts würde ich dann zukünftig nur manuell nach Belieben löschen.</p>
<p>In der Vergangenheit hatte ich das Tool <a  href="/tags/ephemetoot/">Ephemetoot</a> verwendet, um alte Tröts zu löschen. Als ich das vor ein paar Tagen erneut nutzen wollte, hat es leider nicht mehr funktioniert. Es gab eine Fehlermeldung bei jedem Löschversuch. Das Projekt scheint leider eingeschlafen zu sein.</p>
<p>Also fragte ich im Fediverse nach einer Alternative. &ldquo;D.N:K <a  class='urlextern'  href="https://barcamp.social/@dnkrupinski">@dnkrupinski@barcamp.social</a>&rdquo; wies darauf hin, dass im Github-Repo von Ephemetoot eine Alternative genannt wurde. Das hatte ich beim Querlesen übersehen. Danke für den Hinweis.</p>
<p>Das Tool <a  class='urlextern'  href="https://git.augendre.info/gaugendre/cleantoots">cleantoots</a> habe ich ausprobiert und es funktioniert. Es bietet auch die Möglichkeit, einzustellen, dass Tröts mit bestimmten Hashtags nicht gelöscht werden. Genau das benötige ich.</p>

<h2 id="installation" data-numberify>Installation<a class="anchor ms-1" href="#installation"></a></h2>
<p>Die Installation des Tools ist ganz einfach.</p>
<p>Linux vorausgesetzt:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install cleantoots
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>cleantoots config setup
</span></span><span style="display:flex;"><span>cleantoots config login
</span></span></code></pre></div><p>Dann wird durch das Tool der Browser gestartet und es öffnet sich die Website der Instanz und es wird um Authorisierung gebeten. Den angezeigten Code kopiert man und fügt ihn in die Kommandozeile ein, in der der <code>cleantoots config login</code> noch läuft.</p>
<p>Fertig.</p>

<h2 id="benutzung" data-numberify>Benutzung<a class="anchor ms-1" href="#benutzung"></a></h2>
<p>Von nun an kann man alte Tröts löschen lassen mit:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cleantoots clean --delete
</span></span></code></pre></div><p>Oder sich mit einem &ldquo;Trockenlauf&rdquo; erst einmal anzeigen lassen, was cleantoots machen würde:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cleantoots clean
</span></span></code></pre></div><p>Was zu solch einer Ausgabe führen würde:</p>
<pre tabindex="0"><code>…
2022-11-05 00:28:54,871 | cleantoots.commands.clean | INFO | @foobar hier werden lange Links trotzdem verkürzt angezeigt mit … am Ende.
2022-11-05 00:28:54,871 | cleantoots.commands.clean | INFO | boost of toot https://foo.baaar/@foo/123456 protected because creation time 2022-11-01 14:22:49.675000+00:00 is later than limit 2022-08-07T00:28:50.988279+02:00
2022-11-05 00:28:54,872 | cleantoots.commands.clean | INFO | original toot https://social.anoxinon.de/@natenom/109268995231048789 protected because creation time 2022-11-01 14:22:29.308000+00:00 is later than limit 2022-08-07T00:28:50.988485+02:00
…
</code></pre><p>In Zukunft werde ich dieses Script alle x Zeit manuell starten.</p>]]></content:encoded></item><item><title>Ein Python-Script für die Arbeit mit Hugo (Update 2024-01-09)</title><link>https://natenom.de/2022/03/python-script-fuer-die-arbeit-mit-hugo/</link><pubDate>Thu, 24 Mar 2022 05:35:39 +0100</pubDate><guid>https://natenom.de/2022/03/python-script-fuer-die-arbeit-mit-hugo/</guid><description><![CDATA[<p>Bei der <a  href="/2022/02/umzug-des-blogs-von-wordpress-zu-hugo-teil-1/">Umstellung meines Blogs auf Hugo</a> hatte ich mehrere Shell-Aliase in der <code>.bashrc</code> erstellt, um die Arbeit einfacher zu gestalten, wie z. B. eine tmux-Session im Verzeichnis der Website starten, nach Seitennamen, Kategorien und Tags zu suchen und einiges mehr. Es wurden immer mehr Aliase und es war nicht wirklich flexibel sondern nur richtig hacky.</p>]]></description><content:encoded><![CDATA[<p>Bei der <a  href="/2022/02/umzug-des-blogs-von-wordpress-zu-hugo-teil-1/">Umstellung meines Blogs auf Hugo</a> hatte ich mehrere Shell-Aliase in der <code>.bashrc</code> erstellt, um die Arbeit einfacher zu gestalten, wie z. B. eine tmux-Session im Verzeichnis der Website starten, nach Seitennamen, Kategorien und Tags zu suchen und einiges mehr. Es wurden immer mehr Aliase und es war nicht wirklich flexibel sondern nur richtig hacky.</p>
<div class="shortcode-notice update">
    <div class="shortcode-notice-title update">
        Update</div>
    <div class="notice-content">Update (2024-01-09): Ich habe eine ganz neue Version des Python-Scripts veröffentlicht, das deutlich mehr kann, siehe <a  href="/2024/01/wofuer-ich-mein-hugo-helper-python-script-verwende-und-wo-man-es-findet/">in diesem Blogbeitrag</a>.</div>
</div>


<p>Spätestens seitdem ich auch <a  href="/2022/03/umzug-dokuwiki-hugo-1-vorarbeiten/">mein neues Wiki mit Hugo</a> nutze, funktionieren die vielen Aliase nicht mehr, denn ich bräuchte alles doppelt, um auch die Arbeit mit meinem Wiki damit bewerkstelligen zu können. Flexibel ist anders.</p>
<p>Und weil auch Vri in Zukunft in der Lage sein soll, sowohl im Wiki als auch im Blog Dinge zu tun, musste ich da was Schönes bauen. Denn meine vorherige Frickellösung könnte ich guten Gewissens niemandem zumuten.</p>
<p>Also habe ich heute Nacht ohne Ahnung und viel $Suchmaschine ein Python-Script erstellt, das die ganzen Shell-Aliase ersetzt und jetzt für beliebig viele Webseiten funktioniert. Und dabei habe ich sogar einen fiesen Bug in der <a  class='urlextern'  href="https://community.kde.org/Plasma">Plasmashell</a> gefunden.</p>

<h2 id="was-kann-das-script" data-numberify>Was kann das Script?<a class="anchor ms-1" href="#was-kann-das-script"></a></h2>
<p>Mit dem neuen Script kann ich sehr einfach:</p>
<ul>
<li>Eine Website generieren lassen.</li>
<li>Eine Website hochladen (mit rsync synchronisieren).</li>
<li>Die beiden oberen Dinge in einem Aufruf.</li>
<li>Eine Website lokal zur Verfügung stellen (<code>hugo server</code>).</li>
<li>Eine tmux-Session innerhalb des lokalen Verzeichnisses starten, um dort z. B. git zu verwenden.</li>
<li>(Nur im Blog) nach verwendeten Tags und nach Kategorien suchen. Dabei funktionieren sowohl einfache Strings als auch Reguläre Ausdrücke.</li>
<li>Mittels <code>grep -r</code> suchen.</li>
<li>Aktuelle Uhrzeit inklusive Datum und Zeitzone erhalten. Für das Front Matter (Metadaten einer einzelnen Seite).</li>
</ul>
<p>Hier z. B. die Suche nach allen Seiten im Blog, in denen der String <code>hugo</code> vorkommt:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>[…]
</span></span><span style="display:flex;"><span>content/posts/2016/2016-12-02-hugo-kann-mehrsprachig.md,,Hugo kann mehrsprachig :),2016-12-02T13:29:05Z,0001-01-01T00:00:00Z,2016-12-02T13:29:05Z,false,/2016/12/hugo-kann-mehrsprachig/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>content/posts/2015/2015-12-10-gpeasy-php-durch-hugo-statisches-html-ersetzt.md,,gpEasy (PHP) durch Hugo (statisches HTML) ersetzt,2015-12-10T13:05:11Z,0001-01-01T00:00:00Z,2015-12-10T13:05:11Z,false,/2015/12/gpeasy-php-durch-hugo-statisches-html-ersetzt/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Format: path,slug,title,date,expiryDate,publishDate,draft,permalink
</span></span><span style="display:flex;"><span>Results for &#39;hugo&#39;: 27</span></span></code></pre></div>

<h3 id="externe-konfiguration" data-numberify>Externe Konfiguration<a class="anchor ms-1" href="#externe-konfiguration"></a></h3>
<p>Die Konfigurationsdatei mit den Einstellungen für beliebig viele Websites liegt in <code>~/.config/hugo-noms.conf</code>.</p>

<h3 id="hilfe" data-numberify>Hilfe<a class="anchor ms-1" href="#hilfe"></a></h3>
<p>Da das Script <a  class='urlextern'  href="https://docs.python.org/3/library/argparse.html">argparse</a> verwendet, gibt es automatisch eine schöne Hilfe: <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>usage: hg.py [-h] [--site SITE_NAME | --time | --printconfig | --sites]
</span></span><span style="display:flex;"><span>             [--cd | --build | --upload | --deploy | --tmux | --serve | --serve_light]
</span></span><span style="display:flex;"><span>             [--searchpost SEARCHPOST | --searchgrep SEARCHGREP | --searchtag SEARCHTAG | --searchcat SEARCHCAT]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Handles hugo stuff.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>optional arguments:
</span></span><span style="display:flex;"><span>  -h, --help            show this help message and exit
</span></span><span style="display:flex;"><span>  --site SITE_NAME      Name of the website to work on currently.
</span></span><span style="display:flex;"><span>  --time                Copy current date and time to clipboard.
</span></span><span style="display:flex;"><span>  --printconfig         Print the devices configuration.
</span></span><span style="display:flex;"><span>  --sites               Print sites from configuration
</span></span><span style="display:flex;"><span>  --cd                  Change directory to workdir of site.
</span></span><span style="display:flex;"><span>  --build               Build a site.
</span></span><span style="display:flex;"><span>  --upload              Build AND upload site to remote.
</span></span><span style="display:flex;"><span>  --deploy              Deploy (build AND upload) a site.
</span></span><span style="display:flex;"><span>  --tmux                Start the tmux session for --site.
</span></span><span style="display:flex;"><span>  --serve               Serves site (full).
</span></span><span style="display:flex;"><span>  --serve_light         Serves site (light).
</span></span><span style="display:flex;"><span>  --searchpost SEARCHPOST
</span></span><span style="display:flex;"><span>                        Find pages/posts containing search term in &#39;path, slug, title, date or permalink&#39;.
</span></span><span style="display:flex;"><span>                        Strings and Regular Expressions (regex) are allowed.
</span></span><span style="display:flex;"><span>  --searchgrep SEARCHGREP
</span></span><span style="display:flex;"><span>                        Find pages/posts containing search term in file content. Uses &#39;grep -r&#39;. Strings and
</span></span><span style="display:flex;"><span>                        Regular Expressions (regex) are allowed.
</span></span><span style="display:flex;"><span>  --searchtag SEARCHTAG
</span></span><span style="display:flex;"><span>                        Find tags containing search term. Strings and Regular Expressions (regex) are allowed.
</span></span><span style="display:flex;"><span>  --searchcat SEARCHCAT
</span></span><span style="display:flex;"><span>                        Find categories containing search term. Strings and Regular Expressions (regex) are
</span></span><span style="display:flex;"><span>                        allowed.</span></span></code></pre></div>

<h2 id="wo-gibts-das-script" data-numberify>Wo gibts das Script?<a class="anchor ms-1" href="#wo-gibts-das-script"></a></h2>
<p>Vielleicht kann das ja noch jemand gebrauchen. Ich weiß aktuell nicht, wo ich es hinschubsen könnte, daher liegt es jetzt erst einmal in meinem Wiki im neuen Bereich <code>Hugo</code>, <a  href="https://wiki.natenom.de/docs/sammelsurium/hugo/">siehe hier</a>.</p>

<h2 id="nur-noch-zwei-aliase" data-numberify>Nur noch zwei Aliase<a class="anchor ms-1" href="#nur-noch-zwei-aliase"></a></h2>
<p>Da ich ein extrem fauler Mensch bin, habe ich aber später trotzdem noch zwei Aliase in der <code>.bashrc</code> definiert:</p>
<pre><code>alias hgb='/pfad/zu/hg.py --site blog'
alias hgw='/pfad/zu/hg.py --site wiki'
</code></pre>
<p>Somit kann ich z. B.</p>
<pre><code>hg.py --site blog --tmux
</code></pre>
<p>abkürzen mit</p>
<pre><code>hgb --tmux
</code></pre>
<p>🙂</p>

<h2 id="bug-in-plasmashell" data-numberify>Bug in Plasmashell<a class="anchor ms-1" href="#bug-in-plasmashell"></a></h2>
<p>Ruft man ein Script mit diesen beiden Zeilen auf oder führt es in iPython aus, dann hängt sich die Plasmashell entweder für ein paar Sekunden, lange oder komplett auf. Der String landet trotzdem nicht in der Zwischenablage obwohl xclip als auch xsel installiert sind.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> pyperclip
</span></span><span style="display:flex;"><span>pyperclip<span style="color:#f92672">.</span>copy(<span style="color:#e6db74">&#34;text&#34;</span>)</span></span></code></pre></div>
<p>Ich wollte diese Funktion nutzen, um einen generierten String mit Datum, Uhrzeit und Zeitzone in die Zwischenablage zu kopieren, um diesen dann im Front Matter eines Blogbeitrags manuell über die Zwischenablage einfügen zu können. Stattdessen nutze ich jetzt <code>os.system(&quot;date … | xsel …&quot;)</code>.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>schlechtes Englisch darf behalten werden 🙂&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content:encoded></item><item><title>Linkdump 3/2022</title><link>https://natenom.de/2022/02/linkdump-3-2022/</link><pubDate>Tue, 15 Feb 2022 00:12:34 +0100</pubDate><guid>https://natenom.de/2022/02/linkdump-3-2022/</guid><description> Allgemein Ultrafeine Partikel in der Luft Heizen mit Holz Geschichten über Alltagsgegenstände Denkende Lebewesen(?) Airtags kann man auch nutzen, um Diebstähle vorzubereiten oder jemanden zu stalken Video aus England zeigt rücksichtlose Autofahrende, die über Gehwege an einem Müllwagen vorbei fahren. Rich is a Python library for rich text and beautiful formatting in the terminal Gutes Video zum Thema Dooring vom Radentscheid Essen Regionales Stuttgart und gemessene Abstände beim Überholen von Radfahrenden: Teil 1: Hier wird zu eng überholt Teil 2: Stadt will eigene Daten zu Überholabständen erheben Teil 3: Hier wird es gefährlich – 40 Straßen im Check</description><content:encoded><![CDATA[
<h2 id="allgemein" data-numberify>Allgemein<a class="anchor ms-1" href="#allgemein"></a></h2>
<ul>
<li><a  class='urlextern'  href="https://www.theguardian.com/environment/2022/feb/11/pollutionwatch-ultrafine-particles-from-aircraft-engines-endanger-lives?CMP=twt_a-environment_b-gdneco">Ultrafeine Partikel in der Luft</a></li>
<li><a  class='urlextern'  href="https://www.zdf.de/nachrichten/politik/heizen-holz-umweltbundesamt-100.html">Heizen mit Holz</a></li>
<li><a  class='urlextern'  href="https://blog.fricklers.org/posts/2022-02-13-arte-geschichte-schreiben/">Geschichten über Alltagsgegenstände</a></li>
<li><a  class='urlextern'  href="https://taz.de/Biologe-ueber-denkende-Lebewesen/!5832912/">Denkende Lebewesen</a>(?)</li>
<li>Airtags kann man auch nutzen, um <a  class='urlextern'  href="https://www.heise.de/news/AirTags-an-Autos-versteckt-Erste-Berichte-aus-den-USA-6299608.html">Diebstähle vorzubereiten oder jemanden zu stalken</a></li>
<li>Video aus England zeigt <a  class='urlextern'  href="https://www.bbc.com/news/uk-england-cornwall-60337275">rücksichtlose Autofahrende, die über Gehwege an einem Müllwagen vorbei fahren</a>.</li>
<li><a  class='urlextern'  href="https://github.com/Textualize/rich">Rich is a Python library for rich text and beautiful formatting in the terminal</a></li>
<li><a  class='urlextern'  href="https://radentscheid-essen.de/aktuelles/was-ist-eigentlich-eine-dooring-zone/">Gutes Video zum Thema Dooring</a> vom Radentscheid Essen</li>
</ul>

<h2 id="regionales" data-numberify>Regionales<a class="anchor ms-1" href="#regionales"></a></h2>
<ul>
<li>Stuttgart und gemessene Abstände beim Überholen von Radfahrenden:</li>
<li>Teil 1: <a  class='urlextern'  href="https://www.stuttgarter-zeitung.de/inhalt.radfahren-in-stuttgart-hier-wird-zu-eng-ueberholt.aa39fbcd-bafd-4b89-ad82-262aa2cdd19c.html">Hier wird zu eng überholt</a></li>
<li>Teil 2: <a  class='urlextern'  href="https://www.stuttgarter-zeitung.de/inhalt.radfahren-in-stuttgart-stadt-will-eigene-daten-zu-ueberholabstaenden-erheben.33684cb3-1cd7-47a0-8c05-43325fc0b53e.html">Stadt will eigene Daten zu Überholabständen erheben</a></li>
<li>Teil 3: <a  class='urlextern'  href="https://www.stuttgarter-zeitung.de/inhalt.radfahren-in-stuttgart-wo-zu-eng-ueberholt-wird-40-strassen-im-check.212c4e4e-0605-4bf3-b281-bcfc7a1d0282.html">Hier wird es gefährlich – 40 Straßen im Check</a></li>
</ul>
]]></content:encoded></item><item><title>Alte Toots eines Mastodon-Accounts automatisiert löschen</title><link>https://natenom.de/2021/03/alte-toots-eines-mastodon-accounts-automatisiert-loeschen/</link><pubDate>Wed, 24 Mar 2021 02:34:37 +0000</pubDate><guid>https://natenom.de/2021/03/alte-toots-eines-mastodon-accounts-automatisiert-loeschen/</guid><description><![CDATA[<div class="shortcode-notice update">
    <div class="shortcode-notice-title update">
        Update</div>
    <div class="notice-content">29.04.2022: Mittlerweile kann man direkt in Mastodon einstellen, dass bestimmte (alte) Dinge gelöscht werden, <a  href="/2022/04/mastodon-kann-selbst-automatisch-loeschen/">siehe hier</a>.</div>
</div>


<div class="shortcode-notice update">
    <div class="shortcode-notice-title update">
        Update</div>
    <div class="notice-content">04.05.2021: Ich habe das jetzt ins Wiki verschoben, <a  href="https://wiki.natenom.de/docs/sammelsurium/ephemetoot">siehe hier</a>.</div>
</div>


<p>Ich sehe Mastodon oder Twitter als Werkzeuge für Kommunikation aktueller Themen, nicht als Ort eines Archivs von allem, das man in den letzten Jahren geschrieben hat. Daher lösche ich unregelmäßig alte Toots auf Mastodon und auch Tweets auf Twitter. Anfangs machte ich das manuell und mittlerweile mit schönen Werkzeugen.</p>
<p>Hier geht es um das Tool <a  class='urlextern'  href="https://github.com/hughrun/ephemetoot/">Ephemetoot</a>, das in der Lage ist, alte Toots eines Mastodonaccounts zu löschen.</p>]]></description><content:encoded><![CDATA[<div class="shortcode-notice update">
    <div class="shortcode-notice-title update">
        Update</div>
    <div class="notice-content">29.04.2022: Mittlerweile kann man direkt in Mastodon einstellen, dass bestimmte (alte) Dinge gelöscht werden, <a  href="/2022/04/mastodon-kann-selbst-automatisch-loeschen/">siehe hier</a>.</div>
</div>


<div class="shortcode-notice update">
    <div class="shortcode-notice-title update">
        Update</div>
    <div class="notice-content">04.05.2021: Ich habe das jetzt ins Wiki verschoben, <a  href="https://wiki.natenom.de/docs/sammelsurium/ephemetoot">siehe hier</a>.</div>
</div>


<p>Ich sehe Mastodon oder Twitter als Werkzeuge für Kommunikation aktueller Themen, nicht als Ort eines Archivs von allem, das man in den letzten Jahren geschrieben hat. Daher lösche ich unregelmäßig alte Toots auf Mastodon und auch Tweets auf Twitter. Anfangs machte ich das manuell und mittlerweile mit schönen Werkzeugen.</p>
<p>Hier geht es um das Tool <a  class='urlextern'  href="https://github.com/hughrun/ephemetoot/">Ephemetoot</a>, das in der Lage ist, alte Toots eines Mastodonaccounts zu löschen.</p>
<h2 id="token-für-mastodon" data-numberify>Token für Mastodon<a class="anchor ms-1" href="#token-für-mastodon"></a></h2>
<p>Damit Ephemetoot mit einem Account arbeiten kann, benötigt es einen &ldquo;Zugangstoken&rdquo; bzw. &ldquo;Access token&rdquo;. Den erstellt man in den Einstellungen auf Mastodon, im Bereich &ldquo;Entwicklung&rdquo;.</p>
<p>Dort fügt man einen neue &ldquo;Anwendung&rdquo; hinzu. Es reicht aus, einen Namen einzugeben und die Voreinstellungen unverändert zu lassen. Man kann aber auch die Möglichkeiten einschränken. Ephemetoot muss lesen und schreiben können.</p>

<h2 id="virtualenv" data-numberify>Virtualenv<a class="anchor ms-1" href="#virtualenv"></a></h2>
<p>Mit Virtualenv erstellt man eine Umgebung für Ephemetoot:</p>
<pre><code>virtualenv -p /usr/bin/python3 ephemetoot
</code></pre>
<p>Im aktuellen Verzeichnis wird damit ein Verzeichnis &ldquo;ephemetoot&rdquo; erstellt.</p>
<pre><code>cd ephemetoot
source bin/activate
pip install ephemetoot
</code></pre>
<p>Jetzt startet man das Tool und lässt eine Konfiguration erstellen.</p>
<pre><code>ephemetoot --init
</code></pre>
<p>Dabei werden Accountname, Token und weitere Dinge abgefragt, die dann in die Konfigurationsdatei config.yaml geschrieben werden. Man kann die Konfigurationsdatei aber auch manuell erstellen und diesen Befehl überspringen.</p>
<p>Bei mir sieht die Konfigurationsdatei dann so aus:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>  <span style="color:#f92672">access_token</span>: <span style="color:#ae81ff">blabpluijd123</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">username</span>: <span style="color:#ae81ff">meinbenutzername</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">base_url</span>: <span style="color:#ae81ff">meinserver.tld</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">days_to_keep</span>: <span style="color:#ae81ff">30</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">keep_pinned</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">archive</span>: <span style="color:#ae81ff">archive</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">hashtags_to_keep</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">müllsammeln</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">ontour</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">natenomontour</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">plogging</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#ae81ff">openbikesensor</span>
</span></span></code></pre></div><p>Dabei werden nur Toots gelöscht, die älter als 30 Tage oder nicht angepinnt sind oder die keines der genannten Hashtags enthalten. Gelöschte Toots landen als Backup (ohne angefügte Medien) im Unterverzeichnis archive.</p>

<h2 id="laufen-lassen" data-numberify>Laufen lassen<a class="anchor ms-1" href="#laufen-lassen"></a></h2>
<p>Ohne Angabe von Parametern startet man das Tool. Hier die Ausgabe für meinen Account. Löschvorgänge sind stark limitiert, man muss das Tool also eine Weile laufen lassen oder nach Ablauf der Fristen immer wieder manuell starten.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ephemetoot                    
</span></span><span style="display:flex;"><span><span style="color:#f92672">=============</span> EPHEMETOOT v3.1.0 <span style="color:#f92672">================</span>
</span></span><span style="display:flex;"><span>Running at Tue <span style="color:#ae81ff">23</span> Mar <span style="color:#ae81ff">2021</span> 16:02:31 +0000
</span></span><span style="display:flex;"><span><span style="color:#f92672">================================================</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Fetching account details <span style="color:#66d9ef">for</span> @account@server
</span></span><span style="display:flex;"><span>Checking <span style="color:#ae81ff">336</span> toots
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># skipping toot with hashtag - 105141110016028168</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># skipping toot with hashtag - 105141096555743892</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105141072564203642</span> tooted <span style="color:#ae81ff">02</span> Nov <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># skipping toot with hashtag - 105140264929870540</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105140255682219175</span> tooted <span style="color:#ae81ff">02</span> Nov <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105125588146258105</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105124704483125356</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105124291721722596</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105124268645450132</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105124058673704582</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Rate limit reached at Tue <span style="color:#ae81ff">23</span> Mar <span style="color:#ae81ff">2021</span> 17:31:12 +0000 -
</span></span><span style="display:flex;"><span>next reset due in <span style="color:#ae81ff">29</span> minutes.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105123687719372689</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105123674095282130</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105123670006473110</span> tooted <span style="color:#ae81ff">30</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105077514503516341</span> tooted <span style="color:#ae81ff">22</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># skipping toot with hashtag - 105077420693727860</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105066209174447095</span> tooted <span style="color:#ae81ff">20</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>❌ deleting toot <span style="color:#ae81ff">105062844118829383</span> tooted <span style="color:#ae81ff">19</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span>👎 unboosting toot <span style="color:#ae81ff">105044942015133379</span> boosted <span style="color:#ae81ff">16</span> Oct <span style="color:#ae81ff">2020</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>...<span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>---------------------------------------
</span></span><span style="display:flex;"><span>🥳 <span style="color:#f92672">==</span>&gt; 🧼 <span style="color:#f92672">==</span>&gt; 😇 User cleanup complete!
</span></span><span style="display:flex;"><span>---------------------------------------
</span></span></code></pre></div>
<h2 id="fertig" data-numberify>Fertig<a class="anchor ms-1" href="#fertig"></a></h2>
<p>Dieses Tool kann man jetzt alle x Zeit laufen lassen und alte Toots löschen :)</p>]]></content:encoded></item><item><title>Etwas Automatisierung für Ordnungswidrigkeitenanzeigen wegen zu wenig Abstand</title><link>https://natenom.de/2020/06/etwas-automatisierung-fuer-ordnungswidrigkeitenanzeigen/</link><pubDate>Thu, 11 Jun 2020 17:07:01 +0000</pubDate><guid>https://natenom.de/2020/06/etwas-automatisierung-fuer-ordnungswidrigkeitenanzeigen/</guid><description><![CDATA[<p>Ich habe heute mal etwas Hirn und $Suchmaschine investiert, um das umständliche Schreiben von Ordnungswidrigkeitenanzeigen etwas zu automatisieren und habe mir dafür ein Python-Script erstellt.</p>
<p>Hier muss man wissen, dass die Dateien von Vorfällen bei mir nach einem bestimmen Schema benannt sind. Darin sind Datum, Uhrzeit und Kennzeichen enthalten.</p>
<p>Zum Beispiel:</p>
<pre class="wp-block-code"><code>2025-06-01T15.34 -- ab-cd-1234 vs-abstand.mp4</code></pre>]]></description><content:encoded><![CDATA[<p>Ich habe heute mal etwas Hirn und $Suchmaschine investiert, um das umständliche Schreiben von Ordnungswidrigkeitenanzeigen etwas zu automatisieren und habe mir dafür ein Python-Script erstellt.</p>
<p>Hier muss man wissen, dass die Dateien von Vorfällen bei mir nach einem bestimmen Schema benannt sind. Darin sind Datum, Uhrzeit und Kennzeichen enthalten.</p>
<p>Zum Beispiel:</p>
<pre class="wp-block-code"><code>2025-06-01T15.34 -- ab-cd-1234 vs-abstand.mp4</code></pre>
<h2 id="ablauf-mit-script" data-numberify>Ablauf mit Script<a class="anchor ms-1" href="#ablauf-mit-script"></a></h2>
<p>So sieht das Terminalfenster aus, wenn das Script durchgelaufen ist. Eine Erklärung kommt danach.<figure class="wp-block-image size-full"></p>
<p><img loading="lazy" src="/wp-content/uploads/2020/06/owianzeigen-script.png" alt="" class="wp-image-49077" srcset="/wp-content/uploads/2020/06/owianzeigen-script.png 614w, /wp-content/uploads/2020/06/owianzeigen-script-265x300.png 265w, /wp-content/uploads/2020/06/owianzeigen-script-600x678.png 600w, /wp-content/uploads/2020/06/owianzeigen-script-133x150.png 133w" sizes="(max-width: 614px) 100vw, 614px" /> <figcaption>Ablauf im Terminalfenster. Ein paar Details habe ich aus Gründen entfernt.</figcaption></figure></p>
<p>Der Ablauf mit Verwendung des Scripts ist wie folgt:</p>
<ul>
<li>Rechtsklick auf das Video eines Vorfalls.<figure class="wp-block-image size-large"></li>
</ul>
<p><img loading="lazy" src="/wp-content/uploads/2020/06/owianzeigen-rechtsklick-600x392.png" alt="" class="wp-image-49076" srcset="/wp-content/uploads/2020/06/owianzeigen-rechtsklick-600x392.png 600w, /wp-content/uploads/2020/06/owianzeigen-rechtsklick-300x196.png 300w, /wp-content/uploads/2020/06/owianzeigen-rechtsklick-150x98.png 150w, /wp-content/uploads/2020/06/owianzeigen-rechtsklick-768x502.png 768w, /wp-content/uploads/2020/06/owianzeigen-rechtsklick.png 814w" sizes="(max-width: 600px) 100vw, 600px" /> </figure></p>
<ul>
<li>Es öffnet sich ein Terminalfenster. Datum, Uhrzeit und Kennzeichen werden aus dem Dateinamen ausgelesen und angezeigt. Dabei wird das Datumsformat von 2025-06-01 umgeschrieben auf 01.06.2025; damit kann man bei der Bußgeldstelle in Pforzheim vermutlich mehr anfangen.</li>
<li>Manuelle Eingabe der Daten:
<ul>
<li>Fahrzeugmodell</li>
<li>Fahrzeugfarbe</li>
<li>Fahrer erkennbar? Wiederholungstäter?<br>
Abhängig davon werden bestimmte Sätze in der E-Mail verwendet oder eben nicht.</li>
<li>Ort des Vorfalls</li>
<li>Innerorts/ausserorts?</li>
<li>Zuständigkeit? In meinem Fall entweder Pforzheim oder Enzkreis.</li>
<li>Anmerkung(en)</li>
</ul>
</li>
<li>Der E-Mail-Client wird mit einem Entwurf einer neuen E-Mail gestartet. Empfänger, Betreff und Inhalt der E-Mail sind schon eingetragen.</li>
</ul>
<pre class="wp-block-code"><code>Sehr geehrte Damen und Herren,

hiermit zeige ich – mit der Bitte um Weiterverfolgung durch Ihr Amt – eine Verkehrsordnungswidrigkeit an:

Überholen mit weniger als 1,5 m Abstand innerorts.

Anmerkungen:
Ich habe keine Ahnung von Python, aber es funktioniert :)
Der Fahrzeugführende ist auf den Bildern erkennbar.

Datum: 01.06.2025
Uhrzeit: 15:34 Uhr
Ort: Hinter dem Wasserfall beim Regenbogen
Marke: VW
Farbe: blümchengrün
Kennzeichen: AB CD 1234

Mit freundlichen Grüßen

Natenom

Internetstraße 1
64738 Internet</code></pre>
<ul>
<li>Manuell muss ich nur noch die Absenderadresse im E-Mail-Programm einstellen.</li>
<li>Aus dem Video muss ich wieder manuell mehrere Screenshots erstellen, die in einem definierten Verzeichnis landen.</li>
<li>Das Script zeigt mir nun ein Muster an, das ich verwenden kann, um die erstellten Screenshots umzubenennen (auch mehrere gleichzeitig).<figure class="wp-block-image size-full"></li>
</ul>
<p><img loading="lazy" src="/wp-content/uploads/2020/06/ablauf_owi-anzeige_screenshots.png" alt="" class="wp-image-49056" srcset="/wp-content/uploads/2020/06/ablauf_owi-anzeige_screenshots.png 254w, /wp-content/uploads/2020/06/ablauf_owi-anzeige_screenshots-150x110.png 150w" sizes="(max-width: 254px) 100vw, 254px" /> </figure></p>
<ul>
<li>Mit einem anderen Script kann ich über einen Rechtsklick auf die Screenshots <a  href="https://wiki.natenom.de/docs/linux/kde/servicemenues/metainformationen">alle Metadaten entfernen</a>.</li>
<li>Die Screenshots muss ich an die E-Mail als Anhang anfügen.</li>
<li>Zuletzt noch die E-Mail abschicken.</li>
</ul>

<h2 id="fertig-" data-numberify>Fertig :)<a class="anchor ms-1" href="#fertig-"></a></h2>
<p>Es gibt noch Potenzial für weitere Automatisierung. Trotzdem ist dieser Ablauf schon sehr viel einfacher als ohne Script. Ohne das Script musste ich an alles denken und immer sehr konzentriert bleiben, um nichts zu vergessen. Und ich habe trotzdem immer mal wieder was vergessen.</p>
<p>Jetzt habe ich quasi eine Anleitung im Terminal, die mir sagt, wo ich gerade bin und was ich zu tun habe. So kann ich die Ordnungswidrigkeitenanzeigen auch nebenher erledigen und zwischendurch auch unterbrechen.</p>
<p>Während ich das Script heute geschrieben habe, konnte ich nebenbei 19 Ordnungswidrigkeitenanzeigen erstellen.</p>

<h2 id="todo" data-numberify>Todo<a class="anchor ms-1" href="#todo"></a></h2>
<p>Ich könnte vielleicht noch oft verwendete Tatbestandsnummern aus dem Bußgeldkatalog ins Script integrieren. Dann könnte ich diese direkt nennen statt nur „weniger als x Abstand“, wenn z. B. jemand zusätzlich den Gegenverkehr gefährdet hat.</p>
<p>Möglich wäre auch, dass ich einen E-Mail-Clienten finde, in dem ich das Erstellen der E-Mail automatisieren kann; nicht nur Empfänger, Betreff und Inhalt, sondern auch die Anhänge und den Absender. Ich könnte zwar auch direkt aus Python heraus eine E-Mail verschicken aber ich möchte das per GUI machen und dann dort sehen, was versendet wird.</p>
<p>Weitere Baustellen sind die Umbenennung der Screenshots und das Entfernen der Metadaten.</p>]]></content:encoded></item></channel></rss>