<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Stefan Hayden</title>
    <description>If you don&apos;t pass out by the end of the race you could have run faster</description>
    <link>https://stefanhayden.com</link>
    <atom:link href="https://stefanhayden.com/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Liveblog - a new mastodon client to quickly post durring live events</title>
        <description>
          
          &lt;p&gt;TLDR: &lt;a href=&quot;https://liveblog.stefanhayden.com/&quot;&gt;do your live blogging here.&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;/h3&gt;

&lt;p&gt;I have had the the same problem since the dawn of micro blogging.
If I am watching a live event like an awards show, I often want to have a series of posts all properly tagged with the right hashtags.
I want to quickly see what other are saying and boost and interact with those people.
And I want all other posts not about the event to fade in to the background.&lt;/p&gt;

&lt;p&gt;But normal UI for micro blogging makes you re-type hash tags on every post.
You can reconfigure some UIs to show a column of posts about a topic but you have to do the work to reconfigure the UI.&lt;/p&gt;

&lt;h3 id=&quot;the-solution&quot;&gt;The Solution&lt;/h3&gt;

&lt;p&gt;No more. &lt;a href=&quot;https://liveblog.stefanhayden.com/&quot;&gt;Liveblog is a tool 100% focused on quickly posting during live events&lt;/a&gt;.
Hashtags persist for every post. Content Warnings persist for every post for perfect spoiler warning protection.
Optionally you can toggle thread mode and auto reply to your last post for perfect thread creation.
Below you can do a search to see what others are saying and it will auto refresh to always show fresh content to reply to, boost or favorite.&lt;/p&gt;

&lt;h3 id=&quot;security&quot;&gt;Security&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://liveblog.stefanhayden.com/&quot;&gt;Liveblog&lt;/a&gt; is deployed on vercel. It auths against your mastodon instance with minial permisions. All credidentials are stored in encrypted, httpOnly cookies. This means they are never stored on my servers. It also means if you login from different browsers or clear cookies it will register a new app on your account.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://liveblog.stefanhayden.com/&quot;&gt;&lt;img src=&quot;/wp-content/liveblog-screenshot.png&quot; alt=&quot;Liveblog screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


        </description>
        <pubDate>Sat, 28 Mar 2026 06:14:28 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2026/03/28/Liveblog---a-new-mastodon-client-to-quickly-post-durring-live-events/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2026/03/28/Liveblog---a-new-mastodon-client-to-quickly-post-durring-live-events/</guid>
      </item>
    
      <item>
        <title>TVmarks - a new way to track your tv shows</title>
        <description>
          
          &lt;p&gt;&lt;img src=&quot;/img/tvmarks-screenshot.jpg&quot; alt=&quot;Picture of Tvtime with lots of tv to watch&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I am excited to annouce a new project, &lt;a href=&quot;https://github.com/stefanhayden/tvmarks&quot;&gt;Tvmarks&lt;/a&gt;, a personal website to track your tv shows. It is inspired by and shares much of the same code as &lt;a href=&quot;https://github.com/ckolderup/postmarks&quot;&gt;Postmarks&lt;/a&gt;.
Through the power of the &lt;a href=&quot;https://www.tvmaze.com/&quot;&gt;tvmaze&lt;/a&gt; database Tvmarks lets you a build a selfhosted version of what you are watching, what you have watched, and what you plan to watch.
Tvmarks is also fediverse enabled with shows added and episodes watched shared with your comments to activitypub.&lt;/p&gt;

&lt;h3 id=&quot;how-i-got-here&quot;&gt;How I Got Here&lt;/h3&gt;

&lt;p&gt;Postmarks launched in 2023 but I didn’t discover it till 2025. That still seems wild to think about since I am, or try to be, very pluged in to the fediverse.
But one thing it taught me that I never really thought of is how an sqlite can juist be a file that node can access.
I love web aplications but have never loved needing to care about servers and databses.
Glicth with sqlite really solves so many problems that are needed but I rather not care about.
With those obticals trivialized I was excited with the idea of owning my tv watching data.&lt;/p&gt;

&lt;h3 id=&quot;a-cousin-of-postmarks&quot;&gt;A cousin of Postmarks&lt;/h3&gt;

&lt;p&gt;Is it clear I love Postmarks?! I forked it in Febuary and got to work. Most changes were pretty strightforward to support shows and episodes in the database.
Tvmaze has great apis to source data from to host in your own database so you are never dependant of another website to host your data.&lt;/p&gt;

&lt;h3 id=&quot;rip-glicth&quot;&gt;RIP Glicth&lt;/h3&gt;

&lt;p&gt;Though Tvmarks was built to run on glitch.com I have also been able to run it on a VPS and on Render.com.&lt;/p&gt;

&lt;h3 id=&quot;install-it-and-let-me-know&quot;&gt;Install it and let me know&lt;/h3&gt;

&lt;p&gt;If you try it link me to your instance -&amp;gt; &lt;a href=&quot;https://gardenstate.social/@stefan&quot;&gt;@stefan@gardenstate.social&lt;/a&gt;&lt;/p&gt;

        </description>
        <pubDate>Sun, 25 May 2025 15:00:00 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2025/05/18/TVmarks---a-new-way-to-track-your-tv-shows/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2025/05/18/TVmarks---a-new-way-to-track-your-tv-shows/</guid>
      </item>
    
      <item>
        <title>Top Video Essays of 2024</title>
        <description>
          
          &lt;p&gt;These are the video essays I thought were worth sharing this year in a rough order of how much I liked it. I’m not able to give them legit order or cut any but a few out. So here they!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://nebula.tv/videos/patrickhwillems-the-20-best-train-movies-of-all-time&quot;&gt;The 20 Best Train Movies Of All Time&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8o3i10OuMFQ&quot;&gt;The Entire History of RPGs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=y9wKhjwJH5s&quot;&gt;Robert Altman: America’s Rebel Director&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=LbVsYcYaL4k&quot;&gt;An in-depth look at Romance in video games&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=C12BPRykm-Q&quot;&gt;Building Civilization - A Sid Meier Retrospective&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=1Lx8irf1o6g&quot;&gt;How The OC saved indie rock&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://nebula.tv/videos/ladyknightthebrave-know-no-shame-black-sails&quot;&gt;Know No Shame: Black Sails&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8BOF8crF7ls&quot;&gt;The Harry Potter for Grown-Ups Industrial Complex&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=LD6dl5OLD3I&quot;&gt;The Unhingery of Unsolved Mysteries (1987-2002)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=OPKfiRSZxKo&quot;&gt;Sabrina the Teenage Cashcow - A Video Essay&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://nebula.tv/videos/skipintro-how-reality-cop-shows-make-us-less-safe&quot;&gt;How Reality Cop Shows make us LESS SAFE&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=iBoe50-U0mM&quot;&gt;TaleSpin (1990-1991) Retrospective/Review&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=shRBk8SLiVg&quot;&gt;The Lore of FTL: A Deep Dive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=eanvN_rNpqY&quot;&gt;In Praise of Subtle Performance&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=u6Sa761SAb0&quot;&gt;All the RAGE: A Franchise Retrospective by Noah Caldwell-Gervais&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=TCSZN06XiCY&quot;&gt;Theme Hospital - Making of Documentary&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=R3v-7Rndd8M&quot;&gt;How Many Clicks Does It Take To Get to the Center of Diablo? A Franchise Retrospective&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=DpGsHAbfElk&quot;&gt;What’s the deal with Seinfeld? - Renegade Cut&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ZN16KVrEP8Q&quot;&gt;The Past, Present &amp;amp; Future of Soul Reaver - Noclip Documentary&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=fFJOar91Zy4&quot;&gt;Plagiarism: A Measured Response&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=E3rbZnsiOz4&quot;&gt;The Goblin Hypothesis by Curious Archive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=IlpMNtAPxUo&quot;&gt;Star Trek Voyager… The Documentary You’ve Been Waiting For!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ZlK51P0vuc4&quot;&gt;A critical look at how we watch video essays&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Fe8vxyEAFlE&quot;&gt;The 1970s science fiction classic that actually needs a reboot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Q85l1Fenc5w&quot;&gt;Games that Don’t Fake the Space&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BWwws4C20cM&quot;&gt;You’re Standing on My Neck - A Brief Retrospective of Daria&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

        </description>
        <pubDate>Sun, 15 Dec 2024 11:28:03 -0800</pubDate>
        <link>https://stefanhayden.com/blog/2024/12/15/Top-Video-Essays-of-2024/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/12/15/Top-Video-Essays-of-2024/</guid>
      </item>
    
      <item>
        <title>Active Forums</title>
        <description>
          
          &lt;p&gt;&lt;a href=&quot;https://aftermath.site/best-active-forums-internet-today&quot;&gt;Great list of active forums from Aftermath&lt;/a&gt;. I’ve been looking for a search engine that just searches smaller sites lke these and I don’t think it exists!&lt;/p&gt;

        </description>
        <pubDate>Sat, 12 Oct 2024 05:40:06 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/10/12/active-forums/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/10/12/active-forums/</guid>
      </item>
    
      <item>
        <title>What is a tweet called on mastodon?</title>
        <description>
          
          &lt;p&gt;A tweet on mastodon is called a “Post”.&lt;/p&gt;

&lt;p&gt;Before Nov 14, 2022 they were called &lt;a href=&quot;https://gizmodo.com/mastodon-toot-retired-twitter-tweet-equivalent-1849786221&quot;&gt;Toots&lt;/a&gt;. This was fun but mostly was due to a misunder standing of the english meaning.&lt;/p&gt;

&lt;p&gt;this is in responce to this &lt;a href=&quot;https://www.youtube.com/watch?v=NyV54qfSZwg&quot;&gt;youtube video&lt;/a&gt; that arguest that all text posts on social networks should be called tweets which to me makes no sense. 
The idea that a post on twitter with an image and a image on instagram with text should have a different name because of some fundimental valuye of how it is displayed is wild. The only reason
these things ever have different names is for corperate branding purposes.&lt;/p&gt;

&lt;p&gt;In a federated world a text post with an image can be displayed differently on different platforms so the way a post is made has no bearing on how it is displayed.&lt;/p&gt;

        </description>
        <pubDate>Mon, 07 Oct 2024 05:54:55 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/10/07/What-is-a-tweet-called-on-mastodon-/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/10/07/What-is-a-tweet-called-on-mastodon-/</guid>
      </item>
    
      <item>
        <title>Frameland: A Binary Tale - Upcoming pixel-art indie RPG</title>
        <description>
          
          &lt;p&gt;&lt;a href=&quot;https://frameland.net/&quot;&gt;Frameland: A Binary Tale&lt;/a&gt; looks so cool! An indie rpg with a reto look and soundtrack and rich story is 100% my shit. I feel like it has so much of what made me really love Chained Echos.&lt;/p&gt;

&lt;p&gt;it has yet to come out and I don’t like to promote stuff that has not come out but indie studios need more suport so here I am. &lt;a href=&quot;https://store.steampowered.com/app/2137750/Frameland_A_Binary_Tale/&quot;&gt;Add it to your wishlist&lt;/a&gt;! I can’t wait to buy this day 1!&lt;/p&gt;

&lt;iframe loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/T87JjxBXSng?si=VtJy-bGHHL4araFn&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

        </description>
        <pubDate>Sat, 28 Sep 2024 14:59:25 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/09/28/Frameland-A-Binary-Tale---upcoming-pixel-art-indie-RPG/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/09/28/Frameland-A-Binary-Tale---upcoming-pixel-art-indie-RPG/</guid>
      </item>
    
      <item>
        <title>Twilight of the Gods</title>
        <description>
          
          &lt;p&gt;Season 1 Review:&lt;/p&gt;

&lt;p&gt;This show was pretty good for a Zack Snyder which I usually don’t love. Many of the charcaters seem to start out pretty bland and hard to distinguis but I think it got better as the series went on.&lt;/p&gt;

&lt;p&gt;Many episodes are very horny in a way few animations are and in a way different then any anime I have seen is. There is a lot of sex and nudity. Some nudity was not sexualized which is rare in any media.&lt;/p&gt;

&lt;p&gt;While I had a hard time getting in to it by the end I was fully invested. The animation style is very nice.&lt;/p&gt;

        </description>
        <pubDate>Fri, 27 Sep 2024 18:14:40 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/09/28/Twilight-of-the-Gods/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/09/28/Twilight-of-the-Gods/</guid>
      </item>
    
      <item>
        <title>movie reviews</title>
        <description>
          
          &lt;h2 id=&quot;fantastic-mr-fox&quot;&gt;Fantastic Mr. Fox&lt;/h2&gt;

&lt;p&gt;4 stars&lt;/p&gt;

&lt;p&gt;just a very chill and nice movie.&lt;/p&gt;

&lt;h2 id=&quot;land-of-bad&quot;&gt;Land of Bad&lt;/h2&gt;

&lt;p&gt;2.5 stars&lt;/p&gt;

&lt;p&gt;little dose of American jingoism.&lt;/p&gt;

&lt;h2 id=&quot;polite-society&quot;&gt;Polite Society&lt;/h2&gt;

&lt;p&gt;4.5 stars&lt;/p&gt;

&lt;p&gt;What a amazing movie. Blending romcom and action movie seamlessly. Amazing writing, acting, production, and stunt coordination.&lt;/p&gt;

&lt;h2 id=&quot;baby-driver&quot;&gt;Baby Driver&lt;/h2&gt;

&lt;p&gt;4 stars&lt;/p&gt;

&lt;p&gt;a fun movie with a lot of actors that have aged very poorly. I’ve wanted to watch this since Thomas Flight had his great opening breakdown of the movie. &lt;a href=&quot;www.youtube.com/watch?v=LNGYsmTPWug&quot;&gt;www.youtube.com/watch?v=LNGYsmTPWug&lt;/a&gt;&lt;/p&gt;

        </description>
        <pubDate>Fri, 27 Sep 2024 18:04:38 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/09/28/movie-reviews/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/09/28/movie-reviews/</guid>
      </item>
    
      <item>
        <title>Furiosa: A Mad Max Saga</title>
        <description>
          
          &lt;p&gt;3.5 stars&lt;/p&gt;

&lt;p&gt;I love Fury Road. This movie had many many good parts but I don’t think it came together to make a compelling movie. Action was great. Characters were kind of weak. The the plot was uneven. The world building was great. I think this movie did sand better then Dune.&lt;/p&gt;

        </description>
        <pubDate>Sat, 17 Aug 2024 19:21:43 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/08/18/Furiosa-A-Mad-Max-Saga/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/08/18/Furiosa-A-Mad-Max-Saga/</guid>
      </item>
    
      <item>
        <title>TV Shows That Didn&apos;t End At The Right Time</title>
        <description>
          
          &lt;h2 id=&quot;a-crime-they-ended-so-soon&quot;&gt;A Crime They Ended So Soon&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Freaks And Geeks&lt;/li&gt;
  &lt;li&gt;Reservation Dogs&lt;/li&gt;
  &lt;li&gt;The Wonder Years&lt;/li&gt;
  &lt;li&gt;Single Drunk Female&lt;/li&gt;
  &lt;li&gt;Willow&lt;/li&gt;
  &lt;li&gt;A League of Their Own&lt;/li&gt;
  &lt;li&gt;The Carrie Diaries&lt;/li&gt;
  &lt;li&gt;Lovecraft Country&lt;/li&gt;
  &lt;li&gt;Vagrant Queen&lt;/li&gt;
  &lt;li&gt;Party of Five (2020)&lt;/li&gt;
  &lt;li&gt;Everything Sucks&lt;/li&gt;
  &lt;li&gt;Selfie&lt;/li&gt;
  &lt;li&gt;Don’t Trust the B in Apt 23&lt;/li&gt;
  &lt;li&gt;Happy Endings&lt;/li&gt;
  &lt;li&gt;The Middle Man&lt;/li&gt;
  &lt;li&gt;I Am Not Okay With This&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;a-misdemeanor-they-ended-so-soon&quot;&gt;A Misdemeanor They Ended So Soon&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;I’m Sorry&lt;/li&gt;
  &lt;li&gt;Other Space&lt;/li&gt;
  &lt;li&gt;Alone Together&lt;/li&gt;
  &lt;li&gt;Happy Together&lt;/li&gt;
  &lt;li&gt;Hollywood Darlings&lt;/li&gt;
  &lt;li&gt;Trophy Wife&lt;/li&gt;
  &lt;li&gt;Grand Crew&lt;/li&gt;
  &lt;li&gt;Shanara&lt;/li&gt;
  &lt;li&gt;Good Girls Revolt&lt;/li&gt;
  &lt;li&gt;Pitch&lt;/li&gt;
  &lt;li&gt;Life As We Know It&lt;/li&gt;
  &lt;li&gt;Privileged&lt;/li&gt;
  &lt;li&gt;Battle Ground&lt;/li&gt;
  &lt;li&gt;Suburgatory&lt;/li&gt;
  &lt;li&gt;Rutherford Falls&lt;/li&gt;
  &lt;li&gt;XO, Kitty&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;had-more-to-give&quot;&gt;Had More To Give&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Dickenson&lt;/li&gt;
  &lt;li&gt;Raised By Wolves&lt;/li&gt;
  &lt;li&gt;Single Parents&lt;/li&gt;
  &lt;li&gt;Santa Clarita Diet&lt;/li&gt;
  &lt;li&gt;Dark Matter&lt;/li&gt;
  &lt;li&gt;Review&lt;/li&gt;
  &lt;li&gt;American Dreams&lt;/li&gt;
  &lt;li&gt;Joan of Arcadia&lt;/li&gt;
  &lt;li&gt;Sports Night&lt;/li&gt;
  &lt;li&gt;Black Lady Sketch Show&lt;/li&gt;
  &lt;li&gt;My Boys&lt;/li&gt;
  &lt;li&gt;Tuca &amp;amp; Bertie&lt;/li&gt;
  &lt;li&gt;Home Economics&lt;/li&gt;
  &lt;li&gt;Colony&lt;/li&gt;
  &lt;li&gt;Not Dead Yet&lt;/li&gt;
  &lt;li&gt;Motherland: Fort Salem&lt;/li&gt;
  &lt;li&gt;Veronica Mars&lt;/li&gt;
  &lt;li&gt;The Carmichael Show&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ended-at-the-right-time-but-i-miss-them&quot;&gt;Ended At The Right Time But I Miss Them&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Your The Worst&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;went-on-way-too-long&quot;&gt;Went On Way Too Long&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;How I Met Your Mother&lt;/li&gt;
  &lt;li&gt;The 100&lt;/li&gt;
  &lt;li&gt;Orphan Black&lt;/li&gt;
&lt;/ul&gt;


        </description>
        <pubDate>Sat, 17 Aug 2024 08:54:51 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/08/17/TV-Shows-That-Didn-t-End-At-The-Right-Time/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/08/17/TV-Shows-That-Didn-t-End-At-The-Right-Time/</guid>
      </item>
    
      <item>
        <title>Kamala Harris intros Tim Walz</title>
        <description>
          
          &lt;p&gt;This rally is wild. Probably no rally has been this pumped since Obama.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/wP5qOjgY88M?si=jlENhEi8n38Wk33m&amp;amp;start=1772&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

        </description>
        <pubDate>Wed, 07 Aug 2024 19:51:28 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/08/08/Kamala-Harris-intros-Tim-Walz/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/08/08/Kamala-Harris-intros-Tim-Walz/</guid>
      </item>
    
      <item>
        <title>Flashing the Sonoff S31 with ESPHome</title>
        <description>
          
          &lt;p&gt;&lt;a href=&quot;https://roborooter.com/post/flashing-sonoff-s31-with-esphome/&quot;&gt;Great guide on Flashing the Sonoff S31 with ESPHome here.&lt;/a&gt;&lt;/p&gt;

        </description>
        <pubDate>Tue, 06 Aug 2024 19:24:26 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/08/07/Flashing-the-Sonoff-S31-with-ESPHome/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/08/07/Flashing-the-Sonoff-S31-with-ESPHome/</guid>
      </item>
    
      <item>
        <title>How long does a Mastodon post take to federate between servers?</title>
        <description>
          
          &lt;p&gt;&lt;a href=&quot;https://stefanbohacek.com/blog/data-on-sending-a-post-into-the-fediverse/&quot;&gt;Recently Stefan Bohacek ran a poll to find out how long a post takes to appear to his followers.&lt;/a&gt; A great question!&lt;/p&gt;

&lt;p&gt;There is no one speed a post is circulated. When a post is made it enters a queue on sidekiq (below) to be sent out to other servers. Those servers receive that message and it goes in a queue to be processed. At peak times these queues can grow thousands of entries depending on how it is provisioned.&lt;/p&gt;

&lt;p&gt;My server, &lt;a href=&quot;https://gardenstate.social&quot;&gt;GardenState.social&lt;/a&gt;, is hosted on &lt;a href=&quot;https://cloudplane.org/docs/applications/mastodon&quot;&gt;cloudplane at the medium level&lt;/a&gt;. It has 2 cpus and 8 sidekiq queues.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/stefanhayden/stefanhayden.github.io/assets/87616/44f5518a-38a8-47a2-a0ee-724a78818bd9&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-speed-test&quot;&gt;The Speed Test&lt;/h2&gt;

&lt;p&gt;To do my own test I wrote a script (&lt;a href=&quot;https://github.com/stefanhayden/mastodon-federation-speed-test&quot;&gt;code on github&lt;/a&gt;) to get all my followers, get all their servers, make a post and then check each server until that post appears. Because mastodon redirects you back to your server when viewing your own profile I instead generated a unique hashtag and then check to see if the page for that hashtag 404s or 200s.&lt;/p&gt;

&lt;p&gt;I ran this code at 7:30 on May 10th. There is no way to know the queue status of other servers but my own servers had empty queues.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;My post made it to 251 servers over 240 seconds (4 minutes). The average time for my post to appear on another server was 8.6 seconds.&lt;/p&gt;

&lt;p&gt;The top 5 fastest servers (in seconds):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;0.959 - lostcreek.social&lt;/li&gt;
  &lt;li&gt;0.985 - social.giurdanella.it&lt;/li&gt;
  &lt;li&gt;1.045 - happyfedi.better-than.tv&lt;/li&gt;
  &lt;li&gt;1.068 - social.lugal.io&lt;/li&gt;
  &lt;li&gt;1.069 - blahaj.zone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The top 5 slowest servers (in seconds):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;240.34 - climatejustice.rocks&lt;/li&gt;
  &lt;li&gt;54.134 - postchat.io&lt;/li&gt;
  &lt;li&gt;51.491 - mastodon.africa&lt;/li&gt;
  &lt;li&gt;18.53 - mastodon.acc.sunet.se&lt;/li&gt;
  &lt;li&gt;17.733 - mstdn.party&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notible servers (in seconds):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;3.308 - beige.party&lt;/li&gt;
  &lt;li&gt;6.394 - mastodon.social&lt;/li&gt;
  &lt;li&gt;5.535 - mas.to&lt;/li&gt;
  &lt;li&gt;11.662 - universeodon.com&lt;/li&gt;
  &lt;li&gt;4.716 - fosstodon.org&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/stefanhayden/mastodon-federation-speed-test/blob/main/results.txt&quot;&gt;see the full results dataset here!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I could imagine this being turned into a bot and report some kind of federation health check. Though this does spam the servers with web requests a bit so it seems like something we can just run occasionally to get a feel for the state of the fediverse.&lt;/p&gt;

&lt;p&gt;Overall, federation seems to be pretty speedy!&lt;/p&gt;


        </description>
        <pubDate>Fri, 10 May 2024 16:53:05 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/05/10/mastodon-federation-speed-test/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/05/10/mastodon-federation-speed-test/</guid>
      </item>
    
      <item>
        <title>Tidal track not available for streaming</title>
        <description>
          
          &lt;p&gt;I kept finding songs on Tidal I had added to my tracks list but were marked as “not available for streaming” but if you went to the artist page the song stil existsed.&lt;/p&gt;

&lt;p&gt;For some reason Tidal’s backend seems to generate a lot of new track IDs when they update or need to make some change to a track. Really frusterating.&lt;/p&gt;

&lt;p&gt;To fix this I wrote a script to find exact song title matches of songs from the same artist and swap them. Its been working really well for me and &lt;a href=&quot;https://github.com/stefanhayden/music&quot;&gt;you can find it here on github&lt;/a&gt;.&lt;/p&gt;

        </description>
        <pubDate>Sat, 13 Apr 2024 13:38:13 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2024/04/13/Tidal-track-not-available-for-streaming/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2024/04/13/Tidal-track-not-available-for-streaming/</guid>
      </item>
    
      <item>
        <title>React Context Provider Optimization</title>
        <description>
          
          &lt;p&gt;React &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createContext&lt;/code&gt; is a powerful way to to use react to communicate between components
but there are a lot of easy mistakes to be made that will slow down your app. From
memoizing everything to separating component with hooks and components with UI.&lt;/p&gt;

&lt;p&gt;Yet even if you follow all of those patterns you can still find your app rendering 
components that could be expensive to render.&lt;/p&gt;

&lt;p&gt;This is because providers trigger renders any time they render. It does not matter if a hook or 
parent triggers them to render or if it passes in a memoized value. If a provider
renders it will trigger &lt;em&gt;anything&lt;/em&gt; subscribed to it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;useContext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Consider this provider:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-jsx&quot; data-lang=&quot;jsx&quot;&gt;  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setActiveModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;useCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setActiveModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModalContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModalContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Above the provider has two values. One to know what the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activeModal&lt;/code&gt; is. 
The other, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show&lt;/code&gt;, will let components around the appo set a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activeModal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Because the both values share one prodiver ALL components who access the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show&lt;/code&gt; function will render when ANY component calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show()&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I learned that dozens of components were getting rendered simply because they 
wanted the option of possibly calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show()&lt;/code&gt; I was a little shocked.
Fixing this is not immediately obvious. Memoization can not save you and this might 
make you start to look at react state libraries. But there is a solution that is architectural.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-jsx&quot; data-lang=&quot;jsx&quot;&gt;  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setActiveModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;useCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setActiveModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModalActionContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModalContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeModal&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModalContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModalActionContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Provider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With values that change separated from function that do not change now any component can access the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show()&lt;/code&gt;
function and never have it trigger a re-render.&lt;/p&gt;

&lt;p&gt;You can play with this below. The red components on the left only use one provider and calling 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show()&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hide()&lt;/code&gt; causes all red components to render every time. On the right the green components are 
broken in two providers and calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show()&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hide()&lt;/code&gt; only renders the components that need to know the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activeModal&lt;/code&gt;.
It doesn’t even trigger a render on the component with the button!&lt;/p&gt;

&lt;iframe src=&quot;/react/React-Provider-Opimization-Example/&quot; height=&quot;930&quot; width=&quot;100%&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;a href=&quot;https://codesandbox.io/p/github/stefanhayden/React-Provider-Opimization-Example/main&quot;&gt;Play with this code on codesandbox.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Separating the values and functions is a great start and can save many renders around the application. 
Depending on the data you can think of more ways to separate data. If some values update every time 
and others only sometime then it might make sense to break those in to separate providers as well.&lt;/p&gt;

        </description>
        <pubDate>Sat, 06 Apr 2024 05:07:50 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2023/12/09/ract-context-provider-optimization/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2023/12/09/ract-context-provider-optimization/</guid>
      </item>
    
      <item>
        <title>Most Followed Mastodon Accounts</title>
        <description>
          
          &lt;p&gt;I’ve launched a new bot / website. &lt;a href=&quot;https://most-followed-mastodon-accounts.stefanhayden.com/&quot;&gt;Mastodon Most Followed&lt;/a&gt; tracks the top 10,000 mastodon accounts. At the moment to make the list you only need over 500 followers to make the list. 
The list is compiled though monitoring the federated timeline of mastodon.social as well as any mention accounts.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://most-followed-mastodon-accounts.stefanhayden.com/&quot;&gt;&lt;img src=&quot;https://github.com/stefanhayden/stefanhayden.github.io/assets/87616/91b33486-dbfe-4210-ab4d-b4561d918cd5&quot; alt=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


        </description>
        <pubDate>Sat, 09 Dec 2023 09:07:50 -0800</pubDate>
        <link>https://stefanhayden.com/blog/2023/12/09/Most-Followed-Mastodon-Accounts/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2023/12/09/Most-Followed-Mastodon-Accounts/</guid>
      </item>
    
      <item>
        <title>Tidal Music Metadata Csv Export</title>
        <description>
          
          &lt;p&gt;I never trust these music services to remember what music I love. Tidal doesn’t have an easy way to export this. I just want a CSV file to keep so Tidal doesn’t own the music I have found.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/stefanhayden/music&quot;&gt;So here is a small repo you can clone to run against your Tidal and pull your favorites out.&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;You&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;need&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tidalapi&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tidalapi &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;more&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;can&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;found&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;here&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;https&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//github.com/tamland/python-tidal)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;had&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fixed&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;https&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//github.com/tamland/python-tidal/pull/130&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;csv&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pprint&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tidalapi&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tidalapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;login_oauth_simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;favorites&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tidalapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Favorites&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Tracks&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;../tracks.csv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;../tracks.csv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;track,album,artist&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;tracks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;favorites&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tracks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tracks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;track&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tracks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;album&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;artist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Artists&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;../artists.csv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;../artists.csv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;artist&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;artists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;favorites&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;artists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;artists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;artist&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;artists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;artist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Album&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;../albums.csv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;../albums.csv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;album,artist&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;albums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;favorites&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;albums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;albums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;getMore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;False&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;album&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;albums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;album&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;album&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;artist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

        </description>
        <pubDate>Mon, 10 Apr 2023 18:34:10 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2023/04/11/Tidal-Music-Metadata-Csv-Export/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2023/04/11/Tidal-Music-Metadata-Csv-Export/</guid>
      </item>
    
      <item>
        <title>Mechanical Keyboards</title>
        <description>
          
          &lt;p&gt;Had a fun time getting in to mechanical keyboards for real this time. In the past I got a low profile keychron with Gateron blues and a air75 Nuphy with browns.&lt;/p&gt;

&lt;p&gt;The low profile keychrone had flat keys and I couldn’t feel which key my fingers were on and I also didn’t like the blue switch but I didn’t know it at the time.&lt;/p&gt;

&lt;p&gt;The Nuphy was much better but I need more room around the sift and arrow keys for me to type well. Also I didn’t like the brown switch though I didn’t know it at the time.&lt;/p&gt;

&lt;h2 id=&quot;keychron-q2-qmk---65-with-knob-and-gateron-g-pro-red&quot;&gt;Keychron Q2 QMK - 65% with knob and Gateron G Pro Red&lt;/h2&gt;

&lt;p&gt;One I got this keyboard I realized why I had problems with the others. I really need that gap for the arrow keys and the linear reds made typing feel good to me.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/87616/231029124-18cc1a10-78c7-4f35-ad0b-040f208d3250.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;ajazz-ak816-from-epomaker---75-with-gold-knob-and-gateron-pro-20-silver-linears&quot;&gt;Ajazz AK816 from Epomaker - 75% with gold knob and Gateron Pro 2.0 Silver linears&lt;/h2&gt;

&lt;p&gt;Once I hit on how much I love the Keychron and why I felt much better with this purchase. I know I like they layout. I was excited to try the silvers which are just like the reds but with a shorter travel distance. I really love a linear with a short travel distance.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://prod-244acc89-mastodon-6cad389c-bucket.s3.fr-par.scw.cloud/media_attachments/files/110/103/383/479/851/390/original/9142c12055167194.jpeg&quot; alt=&quot;Ajazz AK816 from Epomaker&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that I know what I like I can go back to the original keychron and get better keys and switches and the Nuphy and get linear switches for that as well. It took some money but I’ve set myself up well to always be happy with the keyboard I have.&lt;/p&gt;

        </description>
        <pubDate>Mon, 10 Apr 2023 18:00:09 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2023/04/11/Mechanical-Keyboards/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2023/04/11/Mechanical-Keyboards/</guid>
      </item>
    
      <item>
        <title>Mastodon Instance GardenState.social for all things New Jersey</title>
        <description>
          
          &lt;p&gt;I’ve started a Mastodon instance called &lt;a href=&quot;https://GardenState.social&quot;&gt;GardenState.social&lt;/a&gt; for all of New Jersey. Come and join and escape twitter.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/87616/204714759-0fc1db77-cb6a-4895-9752-41ff88b122ec.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

        </description>
        <pubDate>Tue, 29 Nov 2022 21:24:47 -0800</pubDate>
        <link>https://stefanhayden.com/blog/2022/11/30/Mastodon-Instance-GardenState.social-for-all-things-New-Jersey/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2022/11/30/Mastodon-Instance-GardenState.social-for-all-things-New-Jersey/</guid>
      </item>
    
      <item>
        <title>That Moment Saddam Hussein Took Power On Live Television</title>
        <description>
          
          &lt;p&gt;Wild and incredible and scary this was ever broadcast.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/OynP5pnvWOs&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

        </description>
        <pubDate>Sat, 22 Oct 2022 11:49:32 -0700</pubDate>
        <link>https://stefanhayden.com/blog/2022/10/22/That-moment-Saddam-Hussein-took-power-on-live-television/</link>
        <guid isPermaLink="true">https://stefanhayden.com/blog/2022/10/22/That-moment-Saddam-Hussein-took-power-on-live-television/</guid>
      </item>
    
  </channel>
</rss>
