This is a valid RSS feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
<p><img fetchpriority="high" decoding="async" src="http://cdn.scooterlabs.co ...
line 52, column 0: (14 occurrences) [help]
<p><img fetchpriority="high" decoding="async" src="http://cdn.scooterlabs.co ...
line 52, column 0: (14 occurrences) [help]
<p><img fetchpriority="high" decoding="async" src="http://cdn.scooterlabs.co ...
<p><iframe loading="lazy" width="640" height="400" src="https://www.loom.com ...
line 233, column 0: (11 occurrences) [help]
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/w ...
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
<title>Brian Cantoni</title>
<atom:link href="http://www.cantoni.org/feed" rel="self" type="application/rss+xml" />
<link>http://www.cantoni.org/</link>
<description>Software engineering leader and occasional side project hacker</description>
<lastBuildDate>Sun, 13 Dec 2020 23:49:49 +0000</lastBuildDate>
<language>en-US</language>
<sy:updatePeriod>
hourly </sy:updatePeriod>
<sy:updateFrequency>
1 </sy:updateFrequency>
<generator>https://wordpress.org/?v=6.6.1</generator>
<item>
<title>Forced to Retire Weather by Text Service</title>
<link>http://www.cantoni.org/2020/11/19/retire-weather-by-text</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Fri, 20 Nov 2020 05:16:55 +0000</pubDate>
<category><![CDATA[Cloud]]></category>
<category><![CDATA[Mobile]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1210</guid>
<description><![CDATA[I finally had to turn off the public number for my free Weather by Text service which I’ve been running for a few years. I was fine with the minimal cost running this on Twilio, but over the last couple of months someone has been abusing the number presumably with some automated script. The challenge with Twilio SMS is there is no way to block any abusive incoming text messages. Even though the pricing is pretty cheap ($ 0.0075 per message), it adds up quickly because you’re charged for both the incoming and outgoing messages. In the end, it’s not…]]></description>
<content:encoded><![CDATA[<p>I finally had to turn off the public number for my <a href="http://scooterlabs.com/wx/">free Weather by Text service</a> which I’ve been running for a few years. I was fine with the minimal cost running this on Twilio, but over the last couple of months someone has been abusing the number presumably with some automated script. The challenge with Twilio SMS is there is <strong>no way to block any abusive incoming text messages</strong>. Even though the pricing is pretty cheap ($ 0.0075 per message), it adds up quickly because you’re charged for both the incoming and outgoing messages. In the end, it’s not worth running a free service where one user can drive hundreds of abusive messages each day with no recourse. <span id="more-1210"></span></p>
<p>Coincidentally it was one year ago today I <a href="http://www.cantoni.org/2019/11/19/weather-by-text-twilio-darksky">rewrote the whole service</a> using <a href="https://developer.here.com/">HERE</a> for geocoding and <a href="https://darksky.net/poweredby/">DarkSky</a> for weather forecasts. I still have the code up on GitHub (<a href="https://github.com/bcantoni/wxtext">bcantoni/wxtext</a>) for anyone interested in running it themselves or just seeing how I built it.</p>
<p><strong>Update:</strong> After turning the service off I did hear back from Twilio tech support who let me know there <em>is</em> a way to block incoming fraudulent traffic. That’s encouraging. In this case I already decommissioned the service, but good to know for the future.</p>
]]></content:encoded>
</item>
<item>
<title>Top 40 Podcasts</title>
<link>http://www.cantoni.org/2020/05/25/top-40-podcasts</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Mon, 25 May 2020 22:44:23 +0000</pubDate>
<category><![CDATA[Podcasting]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1199</guid>
<description><![CDATA[Here in California we’ve entered our third month of sheltering in place and working from home. One positive is less time spent commuting, but that also means it’s been harder to keep up with my podcast subscriptions. Combine that with the fact that there are so many good podcasts out there and I’ve had to shorten my subscription list a little bit (and be pickier about which episodes to listen to). Here’s my current Top 40* list of the best podcasts covering Technology/Software, Startups/Business, Woodworking/Makers and Sports: Technology / Software .NET Rocks! link feed .NET Rocks! is an Internet Audio…]]></description>
<content:encoded><![CDATA[<p>Here in California we’ve entered our third month of sheltering in place and working from home. One positive is less time spent commuting, but that also means it’s been harder to keep up with my podcast subscriptions. Combine that with the fact that there are <em>so many</em> good podcasts out there and I’ve had to shorten my subscription list a little bit (and be pickier about which episodes to listen to).<span id="more-1199"></span></p>
<p><img fetchpriority="high" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/alphacolor-66JMudIjDTw-unsplash.jpg" alt="headphones" width="1000" height="667" class="aligncenter size-full wp-image-1197" srcset="http://www.cantoni.org/wp/wp-content/uploads/alphacolor-66JMudIjDTw-unsplash.jpg 1000w, http://www.cantoni.org/wp/wp-content/uploads/alphacolor-66JMudIjDTw-unsplash-300x200.jpg 300w, http://www.cantoni.org/wp/wp-content/uploads/alphacolor-66JMudIjDTw-unsplash-768x512.jpg 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<p>Here’s my current Top 40<sup>*</sup> list of the best podcasts covering Technology/Software, Startups/Business, Woodworking/Makers and Sports:</p>
<h2>Technology / Software</h2>
<p><strong>.NET Rocks!</strong> <a href="http://www.dotnetrocks.com">link</a> <a href="http://feeds.feedburner.com/netRocksFullMp3Downloads">feed</a> .NET Rocks! is an Internet Audio Talk Show for Microsoft .NET Developers.</p>
<p><strong>Agile for Humans</strong> <a href="https://agile.fireside.fm">link</a> <a href="https://feeds.fireside.fm/agile/rss">feed</a> Agile for Human with Ryan Ripley is a weekly podcast dedicated to the individuals and interactions that make agile work. Our goal is to help you create safe and collaborative working environments where people are empowered to do their best work.</p>
<p><strong>Arrested DevOps</strong> <a href="https://www.arresteddevops.com">link</a> <a href="https://www.arresteddevops.com/episode/index.xml">feed</a> Arrested DevOps is the podcast that helps you achieve understanding, develop good practices, and operate your team and organization for maximum DevOps awesomeness.</p>
<p><strong>The Changelog</strong> <a href="https://changelog.com/podcast">link</a> <a href="https://changelog.com/podcast/feed">feed</a> Conversations with the hackers, leaders, and innovators of software development. Hosts Adam Stacoviak and Jerod Santo face their imposter syndrome so you don’t have to. Expect in-depth interviews with the best and brightest in software engineering, open source, and leadership. This is a polyglot podcast. All programming languages, platforms, and communities are welcome. Open source moves fast. Keep up.</p>
<p><strong>Code Story</strong> <a href="https://codestory.co/">link</a> <a href="https://feeds.transistor.fm/code-story">feed</a> Their tech. Their products. Their stories. Hosted by Noah Labhart, this show is a window into the digital startup world. In their own words, tech veterans share what it feels like to create a world class product, how to recover from critical mistakes, and how to scale your solution to the masses.</p>
<p><strong>Command Line Heroes</strong> <a href="https://www.redhat.com/en/command-line-heroes">link</a> <a href="https://feeds.pacific-content.com/commandlineheroes">feed</a> Stories about the people transforming technology from the command line up.</p>
<p><strong>Full Stack Radio</strong> <a href="http://fullstackradio.com">link</a> <a href="https://rss.simplecast.com/podcasts/279/rss">feed</a> A podcast for developers interested in building great software products. Every episode, Adam Wathan is joined by a guest to talk about everything from product design and user experience to unit testing and system administration.</p>
<p><strong>Girl Geek X</strong> <a href="https://girlgeek.io/">link</a> <a href="https://feeds.buzzsprout.com/245027.rss">feed</a> For women in tech, navigating your career can be as challenging as it is rewarding. Now, after giving female tech leaders a platform for over 10 years at Girl Geek Dinners, we’re sharing the best insight from women in tech every 1st and 3rd Monday. Whether you’re new to the tech world or at the height of your career, the Girl Geek X podcast has tips for you.</p>
<p><strong>Hanselminutes with Scott Hanselman</strong> <a href="https://www.hanselminutes.com">link</a> <a href="https://feeds.simplecast.com/gvtxUiIf">feed</a> Hanselminutes is Fresh Air for Developers. A weekly commute-time podcast that promotes fresh technology and fresh voices. Talk and Tech for Developers, Life-long Learners, and Technologists.</p>
<p><strong>Import This</strong> <a href="http://soundcloud.com/import-this">link</a> <a href="https://feed.pippa.io/public/shows/5cb74ed2304ec1540dfbbadd">feed</a> A Python Podcast for Humans.</p>
<p><strong>Page it to the Limit</strong> <a href="https://www.pageittothelimit.com">link</a> <a href="https://www.pageittothelimit.com/episode/index.xml">feed</a> Page It to the Limit is a podcast that focuses on what it means to operate software in production. Hosted by the PagerDuty Community Team, we cover the leading practices used in the software industry to improve both system reliability and the lives of the people responsible for supporting it.</p>
<p><strong>Planet Performance Podcast</strong> <a href="https://podcast.perfplanet.com">link</a> <a href="http://podcast.perfplanet.com/feed.xml">feed</a> Interviews with Web Performance enthusiasts</p>
<p><strong>Programming Leadership</strong> <a href="https://programmingleadership.podbean.com">link</a> <a href="https://feed.podbean.com/programmingleadership/feed.xml">feed</a> A podcast to help great coders become skilled leaders, and build happy, high-performing software teams.</p>
<p><strong>Real Talk JavaScript</strong> <a href="http://www.realtalkjs.com">link</a> <a href="https://feeds.simplecast.com/tOjNXec5">feed</a> Dive into JavaScript and Web development stories with hosts John Papa, Ward Bell, and Dan Wahlin.</p>
<p><strong>Screaming in the Cloud</strong> <a href="https://screaminginthecloud.com">link</a> <a href="https://feeds.transistor.fm/screaming-in-the-cloud">feed</a> Screaming in the Cloud with Corey Quinn features conversations with domain experts in the world of Cloud Computing. Topics discussed include AWS, GCP, Azure, Oracle Cloud, and the “why” behind how businesses are coming to think about the Cloud.</p>
<p><strong>Software Engineering Unlocked</strong> <a href="https://www.software-engineering-unlocked.com">link</a> <a href="https://feeds.simplecast.com/K1_mv0CJ">feed</a> In this show, I open you the doors to companies and thought leaders around the world. With my guests, I discuss software engineering best practices and pitfalls, and how they strive to build software people love.</p>
<p><strong>The Stack Overflow Podcast</strong> <a href="https://stackoverflow.blog/podcast/">link</a> <a href="https://feeds.simplecast.com/XA_851k3">feed</a> The Stack Overflow podcast is a weekly conversation about working in software development, learning to code, and the art and culture of computer programming. Hosted by Sara Chipps, Paul Ford, and Ben Popper, the series will feature questions from our community, interviews with fascinating guests, and hot takes on what’s happening in tech.</p>
<p><strong>Talk Python To Me</strong> <a href="https://talkpython.fm/">link</a> <a href="https://talkpython.fm/episodes/rss">feed</a> Talk Python to Me is a weekly podcast hosted by Michael Kennedy. The show covers a wide array of Python topics as well as many related topics. Our goal is to bring you the human story behind the Python packages and frameworks you know and love.</p>
<p><strong>Track Changes</strong> <a href="https://postlight.com/trackchanges/podcast">link</a> <a href="http://trackchanges.libsyn.com/rss">feed</a> What happens when software eats the world? Industry veterans Paul Ford and Rich Ziade chat with their friends about technology, design, and business from a distinctly East Coast point of view.</p>
<h2>Startups / Business</h2>
<p><strong>Bootstrapped Web</strong> <a href="http://bootstrappedweb.com/">link</a> <a href="http://bootstrappedweb.com/feed/podcast">feed</a> Bootstrapped Web is for entrepreneurs bootstrapping their startups, who believe that the best way to get to where we’re going is to learn by doing. Conversations, case studies, and interviews with entrepreneurs who are building profitable businesses online. Let’s do this.</p>
<p><strong>Bright & Early</strong> <a href="https://brianrhea.com">link</a> <a href="https://feeds.transistor.fm/bright-early">feed</a> A podcast for people building early-stage startups. Join me each week as I talk to entrepreneurs, product people, designers, and marketing pros about their experiences during the early days of their startup.</p>
<p><strong>Build Your SaaS – bootstrap in 2020</strong> <a href="https://saas.transistor.fm">link</a> <a href="https://feeds.transistor.fm/build-your-saas">feed</a> Can you bootstrap a profitable startup in 2020? Thousands of entrepreneurs, developers, designers, and product people have tried to launch their own web apps. But with so many venture-backed startups now, is it still possible? Follow Jon and Justin as they build their podcasting SaaS, Transistor.fm.</p>
<p><strong>The Important Thing</strong> <a href="https://randsinrepose.com/archives/category/the-important-thing/">link</a> <a href="http://rands.libsyn.com/feed">feed</a> The Important Thing with Michael (“Rands”) Lopp and Lyle Troxell. Let’s spend a few minutes of your life listening and learning about an Important Thing.</p>
<p><strong>Rogue Startups</strong> <a href="https://roguestartups.com/">link</a> <a href="https://roguestartups.com/feed/podcast">feed</a> The Rogue Startups podcast features two bootstrapped startup founders as they grow their businesses. We feature experts in the fields of sales, marketing, and product development to hear how they’re growth hacking their productized services, WordPress plugins, and SaaS products.</p>
<p><strong>Slow & Steady</strong> <a href="https://www.slowandsteadypodcast.com/">link</a> <a href="https://feeds.transistor.fm/slow-steady">feed</a> Join us as we share what it’s like to build and launch a bootstrapped startup while working for yourself full-time. Benedikt is working on Userlist with two other co-founders and Brian is running solo on a product to combat loneliness on remote teams.</p>
<p><strong>Smart Passive Income</strong> <a href="https://www.smartpassiveincome.com">link</a> <a href="http://feeds.feedburner.com/spipodcast">feed</a> Pat Flynn from The Smart Passive Income Blog reveals all of his online business and blogging strategies, income sources and killer marketing tips and tricks so you can be ahead of the curve with your online business or blog.</p>
<p><strong>Rework</strong> <a href="https://rework.fm">link</a> <a href="https://feeds.transistor.fm/rework">feed</a> A podcast by Basecamp about the better way to work and run your business. We bring you stories and unconventional wisdom from Basecamp’s co-founders and other business owners.</p>
<p><strong>Startups For the Rest of Us</strong> <a href="https://www.startupsfortherestofus.com/">link</a> <a href="https://feeds.feedblitz.com/startupsfortherestofus&x=1">feed</a> The longest running (and most popular) podcast for non-venture track startups, this show follow the stories of founders as they start, acquire, and grow SaaS companies.</p>
<h2>Woodworking / Makers</h2>
<p><strong>Clearstory</strong> <a href="http://www.thisoldhouse.com">link</a> <a href="https://feeds.megaphone.fm/clearstory">feed</a> From This Old House, Clearstory is a window that sheds light on the surprising stories behind our homes. Host Kevin O’Connor digs into the systems, structures and materials in our homes from unexpected angles. You’ll hear from Richard Trethewey, Tom Silva, Jeff Sweenor and the This Old House experts, as well as industry leaders, historians, and builders.</p>
<p><strong>Essential Craftsman</strong> <a href="https://essentialcraftsman.podbean.com">link</a> <a href="https://feed.podbean.com/essentialcraftsman/feed.xml">feed</a> In depth discussion of Essential Craftsman videos, related topics, spec house series, and more.</p>
<p><strong>Made for Profit</strong> <a href="https://madeforprofit.com">link</a> <a href="https://madeforprofit.com/feed/podcast/">feed</a> Brad Rodriguez & John Malecki are talking business in the shop and helping you monetize as a Maker.</p>
<p><strong>The Make or Break Show</strong> <a href="http://www.makeorbreakshop.com">link</a> <a href="https://feeds.transistor.fm/the-make-or-break-show">feed</a> The Make or Break Podcast is a weekly audio and video series that features amazing makers across the world. We dive into the greatest things they make as well as lessons learned from the things they break! Featuring woodworking, metalworking, electronics, 3d printing and more!</p>
<p><strong>Makers Weekly</strong> <a href="https://redcircle.com/shows/makers-weekly">link</a> <a href="https://api.podcache.net/shows/3ea4fbd6-b930-449a-9af0-8319d2feaa5a/feed">feed</a> We showcase recently launched products and creative projects by today’s modern makers. We explore the problems they’re solving, the tech they’re using, and tactics they’ve deployed to get to market successfully.</p>
<p><strong>Making It</strong> <a href="http://makingitpodcast.com/">link</a> <a href="http://makingitpodcast.libsyn.com/rss">feed</a> Making It is a weekly audio podcast hosted by Jimmy Diresta, Bob Clagett and David Picciuto. Three different makers with different backgrounds talking about creativity, design and making things with your bare hands.</p>
<p><strong>The Modern Maker Podcast</strong> <a href="https://www.stitcher.com/podcast/mike-montgomery-ben-uyeda-chris-salomone/the-modern-maker-podcast">link</a> <a href="https://feeds.megaphone.fm/modernmaker">feed</a> The Modern Maker Podcast is a weekly podcast about making things by hand. From wood, to concrete, to leather, our hosts Ben Uyeda, Chris Salomone, and Mike Montgomery chat about what it’s like to be a “Maker” in it’s current state.</p>
<h2>Sports</h2>
<p><strong>Danica Patrick Pretty Intense</strong> <a href="http://www.danicapatrick.com">link</a> <a href="https://feeds.simplecast.com/5LExlydD">feed</a> I’m Danica Patrick and I’m Pretty Intense! I believe that each and every one of us has the power within ourselves to create the life that we really want. And I want to inspire you to go conquer your dreams, both professionally and personally.</p>
<p><strong>NASCAR on NBC</strong> <a href="https://art19.com/shows/nascar-on-nbc-podcast">link</a> <a href="https://rss.art19.com/nascar-on-nbc-podcast">feed</a> Discussing the latest NASCAR news, including a weekly recap of races, events and a look ahead to what’s next in the sport. Guests include NBC Sports talent such as Jeff Burton, Steve Letarte and Kyle Petty.</p>
<p><strong>Sports Illustrated Media</strong> <a href="https://www.si.com/podcasts">link</a> <a href="http://feeds.feedburner.com/si-media">feed</a> Welcome to the Sports Illustrated Media Podcast with Jimmy Traina. This podcast, which will be published weekly, will focus on all things sports media via interviews and roundtable discussions. Occasionally, an athlete or celebrity will drop by for a chat as well.</p>
<p><strong>Sports Media with Richard Deitsch</strong> <a href="http://shows.cadence13.com/podcast/sports-media-with-richard-deitsch">link</a> <a href="http://feeds.feedburner.com/media-deitsch">feed</a> The Sports Media Podcast with Richard Deitsch is a weekly show that features interviews with members of the sports media about their work, as well as roundtables with sports media reporters about television, digital, audio/radio, print, and other forms of media.</p>
<p><sup>*</sup>Technically there are 41 here, but 40 was a nice round number…</p>
<p>Photo by <a href="https://unsplash.com/photos/66JMudIjDTw">Alphacolor on Unsplash</a></p>
]]></content:encoded>
</item>
<item>
<title>WordPress Release Candidate Builds in Docker</title>
<link>http://www.cantoni.org/2020/03/05/wordpress-release-candidate-builds-docker</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Fri, 06 Mar 2020 03:54:16 +0000</pubDate>
<category><![CDATA[Web]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1116</guid>
<description><![CDATA[The first WordPress 5.4 release candidate was just published this week. The official WordPress Docker images are only published for release builds, so you can’t test any RC builds from there (for example on the Tags tab you won’t find 5.4-RC1 anywhere). However, it’s pretty straightforward to build the RC build yourself locally following these steps. Build Docker Image Locally The first step is to make a local clone of docker-library/wordpress (the official Docker image source tree for WordPress). Next we need to figure out what the SHA1 checksum is for the release candidate we’re going to use: Visit the…]]></description>
<content:encoded><![CDATA[<p>The first <a href="https://wordpress.org/news/2020/03/wordpress-5-4-release-candidate/">WordPress 5.4 release candidate</a> was just published this week. The <a href="https://hub.docker.com/_/wordpress/">official WordPress Docker images</a> are only published for release builds, so you can’t test any RC builds from there (for example on the Tags tab you won’t find <code>5.4-RC1</code> anywhere). However, it’s pretty straightforward to build the RC build yourself locally following these steps.<span id="more-1116"></span></p>
<h2>Build Docker Image Locally</h2>
<p>The first step is to make a local clone of <a href="https://github.com/docker-library/wordpress">docker-library/wordpress</a> (the official Docker image source tree for WordPress).</p>
<p>Next we need to figure out what the SHA1 checksum is for the release candidate we’re going to use:</p>
<ol>
<li>Visit the <a href="https://wordpress.org/download/releases/">Releases</a> page to understand the download link format</li>
<li>Find and copy the URL for one of the <code>sha1</code> files for the <code>tar.gz</code> download (in this case the latest is <a href="https://wordpress.org/wordpress-5.3.2.tar.gz.sha1">https://wordpress.org/wordpress-5.3.2.tar.gz.sha1</a>)</li>
<li>Substitute in the RC version and view the link to copy the SHA1 value (in this case we have <a href="https://wordpress.org/wordpress-5.4-RC1.tar.gz.sha1">https://wordpress.org/wordpress-5.4-RC1.tar.gz.sha1</a>) which returns <code>7cd079f329b1e9cc1c8148543081ae38301530e3</code></li>
</ol>
<p>Now you can edit the appropriate Dockerfile to refer to the RC release. The WordPress Docker tree currently has 3 different PHP versions and 4 different package types for a total of 12 options. In my case I’m using PHP 7.3 and Apache, so I’ll edit the file <code>php7.3/apache/Dockerfile</code>. Towards the bottom of that file you’ll see environment variables for WORDPRESS_VERSION and WORDPRESS_SHA1. Both of these need to be updated using the value from above:</p>
<pre><code>ENV WORDPRESS_VERSION 5.4-RC1
ENV WORDPRESS_SHA1 7cd079f329b1e9cc1c8148543081ae38301530e3
</code></pre>
<p>Now we can build the specific Docker image locally and tag it. Again using my example of PHP 7.3 + Apache, the build command will be:</p>
<pre><code>docker build ./php7.3/apache/ -t wordpress:5.4-RC1-php7.3-apache
</code></pre>
<p>On my old MacBook Pro this takes about 4 minutes. Assuming the build ran correctly, <code>docker images wordpress</code> should show the result:</p>
<pre><code>REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress 5.4-RC1-php7.3-apache ca70b87fabb4 14 seconds ago 548MB
wordpress 5.3.2-php7.3-apache a9f43b7c47db 2 months ago 539MB
</code></pre>
<h2>Docker Compose with MySQL Database</h2>
<p>Finally, we can refer to that local RC1 image using Docker compose. Follow the instructions in <a href="https://docs.docker.com/compose/wordpress/">Compose and WordPress Quickstart</a> but don’t build the project just yet.</p>
<p>In the <code>docker-compose.yml</code> file, change the WordPress image line from <code>image: wordpress:latest</code> to <code>image: wordpress:5.4-RC1-php7.3-apache</code>.</p>
<p>Now you can continue the instructions by building the project <code>docker-compose up -d</code>. In a few minutes you should now have a running WordPress release candidate!</p>
<h2>Notes</h2>
<ul>
<li>I’ve used the same technique with my <a href="http://www.cantoni.org/2019/10/25/wordpress-github-docker">new WordPress workflow</a> and it worked really well. Also 5.4-RC1 didn’t exhibit any problems, but that’s what I expected considering my use case and plugin collection is pretty simple.</li>
<li>Subscribe to <a href="https://wordpress.org/news/">WordPress News</a> if you’d like to be notified of all release candidate and normal updates. For normal releases, it can take a couple days for the official Docker images to be updated.</li>
</ul>
]]></content:encoded>
</item>
<item>
<title>How to Host a Coming Soon Landing Page on AWS S3</title>
<link>http://www.cantoni.org/2020/02/08/host-coming-soon-page-on-aws-s3</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Sat, 08 Feb 2020 23:26:58 +0000</pubDate>
<category><![CDATA[Other]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1106</guid>
<description><![CDATA[I recently launched a coming soon landing page for Engineering Tourist – a side project I’ve had in mind for a while. The goal is to highlight and discover engineering or technical tourist sites depending on your location. For example if you were in Tucson Arizona, you might discover the Pima Air & Space Museum which is really fantastic. Putting together this landing page was pretty simple (after all, it’s just a single static page), but involved learning and wiring up a bunch of services. Also, every service here is at the free or nearly-free level, so that keeps the…]]></description>
<content:encoded><![CDATA[<p>I recently launched a coming soon landing page for <a href="https://engineeringtourist.com/">Engineering Tourist</a> – a side project I’ve had in mind for a while. The goal is to highlight and discover engineering or technical tourist sites depending on your location. For example if you were in Tucson Arizona, you might discover the <a href="https://pimaair.org/">Pima Air & Space Museum</a> which is really fantastic. Putting together this landing page was pretty simple (after all, it’s just a single static page), but involved learning and wiring up a bunch of services. Also, every service here is at the free or nearly-free level, so that keeps the costs minimal as well.<span id="more-1106"></span></p>
<p><a href="https://engineeringtourist.com/"><img decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/EngineeringTouristWebsite.png" alt="Screenshot of engineering tourist website" width="953" height="697" class="aligncenter size-full wp-image-1105" srcset="http://www.cantoni.org/wp/wp-content/uploads/EngineeringTouristWebsite.png 953w, http://www.cantoni.org/wp/wp-content/uploads/EngineeringTouristWebsite-300x219.png 300w, http://www.cantoni.org/wp/wp-content/uploads/EngineeringTouristWebsite-768x562.png 768w" sizes="(max-width: 953px) 100vw, 953px" /></a></p>
<h2>Amazon Web Services</h2>
<p>The core of this solution is all built on AWS. This site is the example I used while following along with <a href="http://www.cantoni.org/2019/11/15/review-learn-aws-by-using-it">Learn AWS By Using It</a>. It was really helpful to have an actual live project rather than just an “example.com” sort of thing.</p>
<p>Deploying a static website on AWS required learning and using several different services:</p>
<ul>
<li>S3 for static files (the easy part)</li>
<li>CloudFront CDN for better performance around the world</li>
<li>Route 53 for DNS management</li>
<li>Certificate Manager for domain registration and SSL certificate</li>
<li>Simple Email Service for sending messages from EmailOctopus (more below)</li>
</ul>
<h2>Web Site Content</h2>
<p>The goal here was to create a single “coming soon” landing page to collect email addresses, so I started with the <a href="https://html5up.net/eventually">Eventually</a> from HTML5 UP. I wanted to set up a more automated build process for the CSS and JavaScript, so I learned and used <a href="https://gulpjs.com/">gulp</a> for the first time. Among other things it minimizes the image sizes automatically and compresses/combines the status CSS/JS files.</p>
<p>For a starting set of background images, I went through my own collection and picked <a href="https://walkway.org/">Walkway Over The Hudson</a>, <a href="https://www.indianapolismotorspeedway.com/">Indianapolis Motor Speedway</a>, <a href="https://pimaair.org/">Pima Air & Space</a>, <a href="https://www.thehenryford.org/">The Henry Ford</a>, and <a href="https://www.midway.org/">USS Midway Aircraft Carrier</a>.</p>
<p>For deployment, I have a script that uses the <a href="https://aws.amazon.com/cli/">AWS CLI</a> to publish everything to S3. With the CLI I can also control the cache time for all the static files: the main index.html is set for 1 hour and everything else is set for 7 days (but could be longer actually). When I start making changes more frequently here it’ll make sense to automate this deployment with each push to GitHub, but for now running this script works fine.</p>
<h2>StaticKit</h2>
<p>The <a href="https://statickit.com/">StaticKit</a> service provides forms and server-side functionality for static websites. In my case I’m using a simple contact form to gather email addresses which are stored and downloadable from the StaticKit site. Adding and deploying this signup form to my static site was really easy and the free plan should be good enough for now.</p>
<h2>Zapier</h2>
<p><a href="https://zapier.com/">Zapier</a> is used to wire up the new data captured into StaticKit. Thanks to the <a href="https://zapier.com/apps/statickit/integrations">Zapier StaticKit integration</a>, it was easy to create two Zaps:</p>
<ul>
<li>New form submission → Add subscriber in EmailOctopus</li>
<li>New form submission → Send SMS via Twilio to my mobile phone</li>
</ul>
<p>Since I’m just on the free plan with Zapier, this had to be two separate Zaps. For those on any of the paid plans, you can implement this with a simpler “multi step Zap”. Receiving a text message with each new subscriber is just for fun and I’d probably turn that off for anything that became popular.</p>
<h2>EmailOctopus</h2>
<p>I’m using MailChimp for some of my other projects but their free tier has become confusing and more restrictive over time. <a href="https://emailoctopus.com/">EmailOctopus</a> has a generous free tier so I’m giving it a try with this project.</p>
<p>EmailOctopus uses <a href="https://aws.amazon.com/ses/">Amazon SES</a> to send emails, so you’ll need to have an AWS account. The setup process has several steps (including giving EmailOctopus permission to send via your account and setting up SES to send from your domain), but the documentation provided walks you through everything and I didn’t have any problems.</p>
<h2>Conclusion</h2>
<p>Now that I’ve written it all down, that’s a long list of services just to launch a simple single-page website and collect email addresses! If your goal is to just quickly put together a coming soon page like this, it would probably be faster to use a paid service or a WordPress site + plugin. In my case I guess “the journey is the reward”, i.e. a chance to learn a bit about all these services.</p>
<p>The other takeaway is how easy it is to assemble something out of all the parts. Even though there are a lot of moving pieces here, most of it was just “wiring up” services. The only code I wrote was a bit of JavaScript.</p>
<p>Finally, if you’re interested in <a href="https://engineeringtourist.com/">engineering tourism</a> at all, please sign up to keep in touch!</p>
]]></content:encoded>
</item>
<item>
<title>Barcode Scanning Video Games Collection</title>
<link>http://www.cantoni.org/2020/01/23/barcode-scanning-video-games-collection</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Thu, 23 Jan 2020 20:49:55 +0000</pubDate>
<category><![CDATA[Fun]]></category>
<category><![CDATA[Hardware]]></category>
<category><![CDATA[Tools]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1096</guid>
<description><![CDATA[As part of my ongoing effort to clean up all my old computer hardware, I finally organized all my video games for donation, and used a cheap barcode scanner to take inventory. We’re keeping GameCube and Wii, but donating XBox, XBox 360, PS/2 and PC games. This seemed like a good time to try barcode scanning to make a full list. On Amazon I bought a cheap wired USB barcode scanner (affiliate link, currently $14) and then created some Python scripts to find the game title from the barcode value. The scripts dump these into a CSV file for importing…]]></description>
<content:encoded><![CDATA[<p>As part of my ongoing effort to <a href="http://www.cantoni.org/2019/07/30/how-to-tidy-up-your-digital-life">clean up</a> all my old computer hardware, I finally organized all my video games for donation, and used a cheap barcode scanner to take inventory.<span id="more-1096"></span></p>
<p>We’re keeping GameCube and Wii, but donating XBox, XBox 360, PS/2 and PC games. This seemed like a good time to try barcode scanning to make a full list. On Amazon I bought a cheap <a href="https://amzn.to/30Qe9ER">wired USB barcode scanner</a> (affiliate link, currently $14) and then created some Python scripts to find the game title from the barcode value. The scripts dump these into a CSV file for importing into Excel or Google Sheets.</p>
<p><img decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/BarcodeScanGames.jpg" alt="Barcode scanning old video games with Mac laptop" width="1000" height="760" class="aligncenter size-full wp-image-1095" srcset="http://www.cantoni.org/wp/wp-content/uploads/BarcodeScanGames.jpg 1000w, http://www.cantoni.org/wp/wp-content/uploads/BarcodeScanGames-300x228.jpg 300w, http://www.cantoni.org/wp/wp-content/uploads/BarcodeScanGames-768x584.jpg 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<p>Here’s what the result looks like in action, in a short <a href="https://www.loom.com/share/900eebf21bc64a6493883596385224da">Loom video</a>:</p>
<p><iframe loading="lazy" width="640" height="400" src="https://www.loom.com/embed/900eebf21bc64a6493883596385224da" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p>
<p>The code ended up being pretty straightforward but I ended up using two different sources to convert barcode numbers into game titles. (UPC barcode APIs is kind of a messy world which I didn’t quite understand, especially for cheap/free.) I’m using <a href="https://www.pricecharting.com">Price Charting</a> for all the console games and <a href="https://www.upcitemdb.com">upcitemdb.com</a> just for the PC games. The interface for reading barcode numbers from the scanner is really simple: whenever you scan something, it’s equivalent to the keyboard typing in: <code><barcode number> [Enter]</code>, so the code just treats it as any normal input.</p>
<p>I posted the scripts in a <a href="https://gist.github.com/bcantoni/a9a689b441330d83ab74ea859b76e06d">Github gist</a> for those that might be interested.</p>
<p>In the end I’ve got over 90 games (and consoles/controllers) for donation. The plan is to bring them up to <a href="https://themade.org/">The MADE</a> the next time I’m heading that way!</p>
]]></content:encoded>
</item>
<item>
<title>Resurrecting a Dell Precision Workstation 410</title>
<link>http://www.cantoni.org/2020/01/21/resurrecting-dell-precision-workstation-410</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Wed, 22 Jan 2020 00:10:19 +0000</pubDate>
<category><![CDATA[Hardware]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1091</guid>
<description><![CDATA[I’m finally making some good progress sorting through all my old computer hardware for donation or recycling. My collection of old laptops, desktops and computer cables are finally out of my garage and donated to my local Goodwill. This mostly went quickly except for a brief nostalgic time spent with my old workhorse, a Dell Precision Workstation 410MT. The 410MT was first released in 1998. I was at Palm at the time and this was the standard “developer’s desktop” system we started buying. We cycled them through every 3-4 years, and I picked this one up from an internal surplus…]]></description>
<content:encoded><![CDATA[<p>I’m finally making some good progress sorting through all my <a href="http://www.cantoni.org/2019/07/30/how-to-tidy-up-your-digital-life">old computer hardware for donation or recycling</a>. My collection of old laptops, desktops and computer cables are finally out of my garage and donated to my local Goodwill.</p>
<p>This mostly went quickly except for a brief nostalgic time spent with my old workhorse, a Dell Precision Workstation 410MT.<span id="more-1091"></span></p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/DellPrecision-960x1024.jpg" alt="front of Dell Precision Workstation case" width="688" height="734" class="aligncenter size-large wp-image-1087" srcset="http://www.cantoni.org/wp/wp-content/uploads/DellPrecision-960x1024.jpg 960w, http://www.cantoni.org/wp/wp-content/uploads/DellPrecision-281x300.jpg 281w, http://www.cantoni.org/wp/wp-content/uploads/DellPrecision-768x819.jpg 768w, http://www.cantoni.org/wp/wp-content/uploads/DellPrecision.jpg 1000w" sizes="(max-width: 688px) 100vw, 688px" /></p>
<p>The 410MT was first released in 1998. I was at Palm at the time and this was the standard “developer’s desktop” system we started buying. We cycled them through every 3-4 years, and I picked this one up from an internal surplus sale/giveaway probably around 2004.</p>
<p>The stats were not too impressive by modern standards:</p>
<ul>
<li>Pentium II 400MHz (optionally with dual processors; mine just had a single)</li>
<li>256MB RAM (max was 1GB)</li>
<li>Windows NT 4.0</li>
</ul>
<p>On the plus side this was a big tower with tons of expansion slots and room for drives. A nice touch (I’m not sure whether all Dell enterprise products are like this) was everything in the chassis had easy release levers. Even the power supply could swing up out of the way and still remain cabled to the motherboard (no tools required).</p>
<p>At the time I picked this up from company surplus, I installed dual 150GB drives set to mirror each other, then installed Windows Server 2003. I used it for a few years as a home server, naming it Mufasa because the kids liked Lion King when they were younger. (I believe I also had laptops named Simba and Timon, but those have long since been recycled.) I don’t recall why exactly I stopped using this, but it was probably too loud and too big to be worth running just a simple file server.</p>
<p>This server had gathered quite a bit of dust in the garage, but it fired right up. I even remembered the admin password which was a small miracle. The event log confirmed the last boot was in February 2009, so this machine sat quietly for 11 years and still worked.</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/DellEventLog.jpg" alt="Event log showing last system boot was 11 years ago" width="750" height="313" class="aligncenter size-full wp-image-1086" srcset="http://www.cantoni.org/wp/wp-content/uploads/DellEventLog.jpg 750w, http://www.cantoni.org/wp/wp-content/uploads/DellEventLog-300x125.jpg 300w" sizes="(max-width: 750px) 100vw, 750px" /></p>
<p>“Worked” should be in quotes because while the server did boot, it was woefully out of date. It was already up to Windows Server 2003 SP2, but the Windows Update Service would peg at 100% CPU but never seemed to make a connection. The browsers installed were IE 7.0 and Firefox 1.0, neither of which could be upgraded directly. I wasn’t able to find a working Firefox or Chrome browser but did finally find a downloadable IE8 which worked. One thing that makes this tricky is the “Windows Server browser enhanced security” which really limits the scope of websites you can visit from the server (for security reasons).</p>
<p>Once IE8 was installed and the system restarted, the Windows update service became functional again and over the course of the weekend many updates were downloaded and applied. Once everything was stable, I was able to copy out some of the files I wanted to make sure were backed up. Then I could wipe the drive (thanks <a href="https://www.ultimatebootcd.com/">Ultimate Boot CD</a>) and send it off to recycle!</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/HardwareDonation-1024x546.jpg" alt="used computers on their way to donation" width="688" height="367" class="aligncenter size-large wp-image-1090" srcset="http://www.cantoni.org/wp/wp-content/uploads/HardwareDonation-1024x546.jpg 1024w, http://www.cantoni.org/wp/wp-content/uploads/HardwareDonation-300x160.jpg 300w, http://www.cantoni.org/wp/wp-content/uploads/HardwareDonation-768x409.jpg 768w, http://www.cantoni.org/wp/wp-content/uploads/HardwareDonation.jpg 1100w" sizes="(max-width: 688px) 100vw, 688px" /></p>
]]></content:encoded>
</item>
<item>
<title>How to Convert Word DOC to DOCX Format</title>
<link>http://www.cantoni.org/2020/01/15/how-to-convert-word-doc-to-docx-format</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Wed, 15 Jan 2020 21:12:41 +0000</pubDate>
<category><![CDATA[Tools]]></category>
<category><![CDATA[Web]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1081</guid>
<description><![CDATA[Newer versions of Microsoft Word (in particular, Office 365) will no longer open older .DOC files. If you want to convert these to the current supported .DOCX format (especially if you have a batch of files to convert), LibreOffice is a good option. LibreOffice is free open-source software and you’ll get the benefit of doing everything on your computer. There are a lot of online services which advertise converting these files, but for anything personal or confidential I prefer keeping everything local. Quick Background As part of my effort to tidy up my digital life, I’ve been cleaning off and…]]></description>
<content:encoded><![CDATA[<p>Newer versions of Microsoft Word (in particular, Office 365) will no longer open older .DOC files. If you want to convert these to the current supported .DOCX format (especially if you have a batch of files to convert), <a href="https://www.libreoffice.org/">LibreOffice</a> is a good option.</p>
<p>LibreOffice is free open-source software and you’ll get the benefit of doing everything on your computer. There are a lot of online services which advertise converting these files, but for anything personal or confidential I prefer keeping everything local.<span id="more-1081"></span></p>
<h2>Quick Background</h2>
<p>As part of my effort to <a href="http://www.cantoni.org/2019/07/30/how-to-tidy-up-your-digital-life">tidy up my digital life</a>, I’ve been cleaning off and recycling old computers and consolidating a bunch of backup hard drives and disks. Among other gems I found a bunch of old .DOC files and learned that modern versions of Microsoft Word could not open them at all.</p>
<p>I assume this is for security protection reasons, perhaps to block against macros and other live code which were possible in those older formats. Unfortunately this can lead to “format rot” where you have perfectly valid archived files which are no longer usable.</p>
<p>For example, using Word for Mac (Office 365 version), I get this block when I try to open old .DOC files:</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/Word365Mac.png" alt="Error dialog from Word on Mac" width="635" height="292" class="aligncenter size-full wp-image-1078" srcset="http://www.cantoni.org/wp/wp-content/uploads/Word365Mac.png 635w, http://www.cantoni.org/wp/wp-content/uploads/Word365Mac-300x138.png 300w" sizes="(max-width: 635px) 100vw, 635px" /></p>
<p>The link points to this support article: <a href="https://support.office.com/en-us/article/error-filename-uses-a-file-type-that-is-blocked-from-opening-in-this-version-8afc36c0-67bc-43a9-a2f4-3f0b332fef24?ui=en-US&rs=en-US&ad=US">Error: [Filename] uses a file type that is blocked from opening in this version – Word for Mac</a>.</p>
<p>On Windows (also Office 365 subscription version), it will open these files but in protected mode (meaning, no edits are possible):</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/Word365Windows.png" alt="Warning dialog from Word on Mac" width="1000" height="92" class="aligncenter size-full wp-image-1079" srcset="http://www.cantoni.org/wp/wp-content/uploads/Word365Windows.png 1000w, http://www.cantoni.org/wp/wp-content/uploads/Word365Windows-300x28.png 300w, http://www.cantoni.org/wp/wp-content/uploads/Word365Windows-768x71.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<p>Luckily if you’re on Windows you can adjust the settings (Trust Center | File Block Settings) to enable older files which you trust to be opened:</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/Word365WindowsTrustCenter.png" alt="Word trust center settings dialog" width="826" height="678" class="aligncenter size-full wp-image-1080" srcset="http://www.cantoni.org/wp/wp-content/uploads/Word365WindowsTrustCenter.png 826w, http://www.cantoni.org/wp/wp-content/uploads/Word365WindowsTrustCenter-300x246.png 300w, http://www.cantoni.org/wp/wp-content/uploads/Word365WindowsTrustCenter-768x630.png 768w" sizes="(max-width: 826px) 100vw, 826px" /></p>
<p>Finally, if you do have an Office 365 online subscription, these older .DOC files <em>can</em> be viewed. If you want to edit online, it will offer to convert to the newest format for you. This looks like the easiest option if you just have an occasional file you need to convert.</p>
<h2>Installing LibreOffice</h2>
<p>For anything more than the occasional file, LibreOffice is a good option for converting multiple files quickly.</p>
<p>To install, follow the <a href="https://www.libreoffice.org/get-help/install-howto/">LibreOffice installation instructions</a>.</p>
<p>In my case on macOS I like to install things with Brew where possible, so my install step was simply:</p>
<pre><code>$ brew cask install libreoffice libreoffice-language-pack
</code></pre>
<p>Open the LibreOffice app one time to make sure everything was installed and configured correctly.</p>
<h2>Converting DOC to DOCX with LibreOffice</h2>
<p>With LibreOffice installed, you can convert files two different ways. The first way is to open the .DOC file and then “save as” in the .DOCX format. I experimented with this on a few files and it works fine.</p>
<p>If you have several files to convert, you can use the command line. The location will depend on which platform you’re using, but in my case (macOS), it looks like the following.</p>
<p>First to make sure you have the right location, and to see the online help, try the following:</p>
<pre><code>/Applications/LibreOffice.app/Contents/MacOS/soffice --help
</code></pre>
<p>In the help you’ll see the <code>--convert-to</code> and <code>--outdir</code> options which we’ll be using. A simple conversion of one file will look like this:</p>
<pre><code>/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to docx FILE.DOC
</code></pre>
<p>Converting a directory full of files is possible as well:</p>
<pre><code>$ /Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to docx --outdir ~/Desktop/output ~/Desktop/convert/*.DOC
convert ~/Desktop/convert/BAZ.DOC -> ~/Desktop/output/BAZ.docx using filter : Office Open XML Text
convert ~/Desktop/convert/CATHY.DOC -> ~/Desktop/output/CATHY.docx using filter : Office Open XML Text
convert ~/Desktop/convert/FONTS.DOC -> /Users/brian/Desktop/output/FONTS.docx using filter : Office Open XML Text
convert ~/Desktop/convert/RESIGN.DOC -> ~/Desktop/output/RESIGN.docx using filter : Office Open XML Text
</code></pre>
<p>All of the DOCX files should now be fully working in Word. It’s possible that complicated documents may have some layout issues during conversion, but I think those should be relatively minor.</p>
]]></content:encoded>
</item>
<item>
<title>Tech Advent Calendars – 2019</title>
<link>http://www.cantoni.org/2019/12/31/tech-advent-calendars-2019</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Tue, 31 Dec 2019 19:48:43 +0000</pubDate>
<category><![CDATA[Web]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1074</guid>
<description><![CDATA[In past years I’ve listed a few favorite tech advent calendars, each focusing on a different technology and revealing some new content each day from December 1st through 25th. Each year I also have great plans to follow along with each as the days go by, but it’s not easy to keep up. Even though Christmas has passed, here’s my roundup of interesting technical advent calendars, which I’ll hopefully spend some time reading through over New Year’s! 24 Accessibility – all subjects related to digital accessibility 24 ways – Web design and development 25 Days of Serverless – the first…]]></description>
<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/AdventCalendar.jpg" alt="advent calendar" width="799" height="533" class="aligncenter size-full wp-image-1073" srcset="http://www.cantoni.org/wp/wp-content/uploads/AdventCalendar.jpg 799w, http://www.cantoni.org/wp/wp-content/uploads/AdventCalendar-300x200.jpg 300w, http://www.cantoni.org/wp/wp-content/uploads/AdventCalendar-768x512.jpg 768w" sizes="(max-width: 799px) 100vw, 799px" /></p>
<p>In past years I’ve listed a few favorite <a href="http://www.cantoni.org/?s=advent">tech advent calendars</a>, each focusing on a different technology and revealing some new content each day from December 1st through 25th. Each year I <em>also</em> have great plans to follow along with each as the days go by, but it’s not easy to keep up. Even though Christmas has passed, here’s my roundup of interesting technical advent calendars, which I’ll hopefully spend some time reading through over New Year’s!<span id="more-1074"></span></p>
<ul>
<li><a href="https://www.24a11y.com/">24 Accessibility</a> – all subjects related to digital accessibility</li>
<li><a href="https://24ways.org/">24 ways</a> – Web design and development</li>
<li><a href="https://25daysofserverless.com/">25 Days of Serverless</a> – the first year for this collection from the Azure developer relations team</li>
<li><a href="https://andrewshitov.com/category/advent-calendar-2019/">Advent Calendar – Andrew Shitov</a> – introducing a different programming language each day</li>
<li><a href="https://adventofcode.com/">Advent of Code</a> – featuring programming puzzles that gradually get more difficult (and which can be solved using any coding language or software)</li>
<li><a href="https://crosscuttingconcerns.com/The-Third-Annual-csharp-Advent">C# Advent</a></li>
<li><a href="https://www.ripstech.com/java-security-calendar-2019/">Java Security Advent Calendar 2019</a> – daily Java security challenges (spot the vulnerability); also see WordPress and PHP collections from the last two years</li>
<li><a href="https://www.javaadvent.com/">JVM Advent – The JVM Programming Advent Calendar</a> – Java and JVM related languages</li>
<li><a href="http://perladvent.org/2019/">Perl Advent Calendar</a> – Perl! (there was also a <a href="https://perl6advent.wordpress.com/">Raku aka Perl 6 advent</a> but it didn’t seem to come together)</li>
<li><a href="https://sysadvent.blogspot.com/">sysadvent</a> – system administration topics</li>
<li><a href="https://calendar.perfplanet.com/2019/">Web Performance Calendar</a> – One of my favorites, all about web performance; check out past years as well</li>
</ul>
<p><a href="https://bekk.christmas/">Bekk Christmas</a> deserves a special mention. This is quite an ambitious project with 12 separate advent collections covering CSS, Functional, Java, JavaScript, Kotlin, Machine Learning, Open Source, Product, React, Security, Cloud, and UX; with 24 days each that’s over 288 separate articles/topics!</p>
<p>And finally take a look at <a href="http://www.lenjaffe.com/AdventPlanet/2019/">Advent Planet 2019</a>; this is a “planet” site which aggregates content from most of the above collections and several more I didn’t mention here</p>
<p>Good luck and happy 2020!</p>
<p>Photo credit: <a href="https://flickr.com/photos/yto/4129536327/">yto on Flickr</a></p>
]]></content:encoded>
</item>
<item>
<title>How to Build a Free Website Monitor with GitHub Actions</title>
<link>http://www.cantoni.org/2019/12/12/free-website-monitor-github-actions</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Fri, 13 Dec 2019 00:11:33 +0000</pubDate>
<category><![CDATA[Cloud]]></category>
<category><![CDATA[Site]]></category>
<category><![CDATA[Web]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1052</guid>
<description><![CDATA[Website monitoring (or uptime monitoring) is essential for any commercial website or service and there are plenty of commercial vendors that provide these services. With the recent rollout of GitHub Actions, I’ve put together a simple lightweight website monitor you can implement for free, perfect for side projects and personal websites. In addition to this WordPress blog I’m using it to watch my parked domains and Tweetfave project, making sure they are alive and well. Summary The code for this project is on GitHub at bcantoni/sitecheck-example. The basic idea is to treat this as a Python application from the GitHub…]]></description>
<content:encoded><![CDATA[<p>Website monitoring (or uptime monitoring) is essential for any commercial website or service and there are plenty of commercial vendors that provide these services. With the recent rollout of <a href="https://github.com/features/actions">GitHub Actions</a>, I’ve put together a simple lightweight website monitor you can implement for free, perfect for side projects and personal websites. In addition to this WordPress blog I’m using it to watch my <a href="http://www.cantoni.org/2019/06/17/use-github-pages-parked-domains">parked domains</a> and <a href="https://tweetfave.com">Tweetfave</a> project, making sure they are alive and well. <span id="more-1052"></span></p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/github-actions-1024x507.png" alt="GitHub logo connecting with AWS, Twilio and Slack" width="688" height="341" class="aligncenter size-large wp-image-1051" srcset="http://www.cantoni.org/wp/wp-content/uploads/github-actions-1024x507.png 1024w, http://www.cantoni.org/wp/wp-content/uploads/github-actions-300x148.png 300w, http://www.cantoni.org/wp/wp-content/uploads/github-actions-768x380.png 768w, http://www.cantoni.org/wp/wp-content/uploads/github-actions.png 1483w" sizes="(max-width: 688px) 100vw, 688px" /></p>
<h2>Summary</h2>
<p>The code for this project is on GitHub at <a href="https://github.com/bcantoni/sitecheck-example">bcantoni/sitecheck-example</a>. The basic idea is to treat this as a Python application from the GitHub Actions perspective. (In fact, that’s how I created the workflow at the start, by choosing Python App as the template.)</p>
<p>The core of the code will run a series of checks against the configured website. I’m using it to confirm the following:</p>
<ul>
<li>Redirects from www to non-www (or vice versa) are as expected (including 301 vs 302)</li>
<li>Redirects from http to https are as expected (including 301 vs 302)</li>
<li>Website is up with some content text found (to ensure site is alive and being served properly)</li>
<li>SSL certificates are still valid and have an expiration date at least 3 days in the future</li>
</ul>
<p>All of the above are configurable, including any kind of additional changes that make sense for your environment. The status of each test run is saved persistently to S3 using my <a href="https://github.com/bcantoni/s3data">bcantoni/s3data</a> project. The persistent data is used to only report “pass” results once after a previous failure (to keep down the noise).</p>
<p>At the conclusion of the test run, in the case of failures a message is sent via SMS/text messaging and also Slack.</p>
<p>The project README has a lot more detail explaining the code and the structure within GitHub actions/workflows.</p>
<h2>Instructions</h2>
<p>To use this project for your own sites, you’ll need to make a <a href="https://help.github.com/en/github/getting-started-with-github/fork-a-repo">fork</a> of the <a href="https://github.com/bcantoni/sitecheck-example">bcantoni/sitecheck-example</a> project.</p>
<p>Next, follow these steps:</p>
<p>Locally you’ll want a Python 3.7/3.8 environment (probably easiest with a virtual environment). Install dependencies with:</p>
<pre><code>pip install --upgrade pip
pip install -r requirements.txt
</code></pre>
<p>Now you can edit <code>sites.py</code> to put your own sites and/or checks you want to make.</p>
<p>To enable SMS/text messaging, you’ll need an account and number in Twilio. Set up these environment variables (secrets) in GitHub: TWILIO_AUTH_TOKEN, TWILIO_ACCOUNT_SID, TWILIO_FROM_NUMBER and TWILIO_TO_NUMBER. If you don’t want to use Twilio, remove the code for <code>send_sms_messages</code>.</p>
<p>If you’re going to use Slack, set up the SLACK_WEBHOOK secret in GitHub. If you don’t want to use Slack, remove the code for <code>send_slack_messages</code>.</p>
<p>S3 persistent storage between runs will require an AWS account with an S3 bucket configured. Set up these secrets in GitHub: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and S3DATA_BUCKET. If you don’t want to use AWS S3, remove all the code related to <code>s3data</code>.</p>
<p>In fact, if you don’t need any of the above (or want to set it up later), adjust <code>pythonapp.yml</code> to run the code without the <code>--ci</code> option (i.e. just: <code>python sites.py -v</code>). Then you can add the other services later if you want.</p>
<p>Now try running the script locally to make sure everything works:</p>
<pre><code>python sites.py -v
</code></pre>
<p>Once it looks good, push to GitHub and check the Actions tab to see how it goes. It will run each time you commit, so you can test it by committing a known bad check, then reverting back to a good state.</p>
<p>If you try this project yourself and have any feedback or ideas, please let me know!</p>
<h2>Example Failure (Update)</h2>
<p>Just one week after publishing this project, I had a good example of a content failure because the Thunderbird website changed their marketing content slightly. It’s a good reminder to use text which is unlikely to change!</p>
<p>Here’s what the failure looks like on the GitHub Actions tab:</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/sitecheck-example-failure.png" alt="screenshot showing test failure on github.com" width="757" height="729" class="aligncenter size-full wp-image-1067" srcset="http://www.cantoni.org/wp/wp-content/uploads/sitecheck-example-failure.png 757w, http://www.cantoni.org/wp/wp-content/uploads/sitecheck-example-failure-300x289.png 300w" sizes="(max-width: 757px) 100vw, 757px" /></p>
<p>And since I’m integrated with my personal Slack account, you can see what the Slack notifications look like:</p>
<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/sitecheck-example-slack.png" alt="screenshot of slack notifications" width="493" height="204" class="aligncenter size-full wp-image-1069" srcset="http://www.cantoni.org/wp/wp-content/uploads/sitecheck-example-slack.png 493w, http://www.cantoni.org/wp/wp-content/uploads/sitecheck-example-slack-300x124.png 300w" sizes="(max-width: 493px) 100vw, 493px" /></p>
<p>After a <a href="https://github.com/bcantoni/sitecheck-example/commit/c897e243be2ec175e9f867f8cfca99d4e2e20fa5">simple fix</a> was pushed, the test suite is passing once again.</p>
]]></content:encoded>
</item>
<item>
<title>Weather by Text Message Using Twilio and DarkSky</title>
<link>http://www.cantoni.org/2019/11/19/weather-by-text-twilio-darksky</link>
<dc:creator><![CDATA[Brian Cantoni]]></dc:creator>
<pubDate>Wed, 20 Nov 2019 00:59:16 +0000</pubDate>
<category><![CDATA[Cloud]]></category>
<category><![CDATA[Mobile]]></category>
<guid isPermaLink="false">http://www.cantoni.org/?p=1043</guid>
<description><![CDATA[I recently fixed my Weather by Text mini project to get it working again (since Yahoo shut down YQL) and to update with a few improvements. This service is a simple Twilio-based service which delivers the current weather for the location you send via text message. Update 2020-11-19: Due to some abusive behavior, unfortunately I had to disable the public number for the service. The Backstory The service is simple: text your location to the SMS number and receive back the current weather conditions. I created this 5 years ago when I was first learning about the Twilio programmable voice…]]></description>
<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" src="http://cdn.scooterlabs.com/wp/wp-content/uploads/WeatherByText-540x1024.png" alt="Screenshot of iPhone text messages receiving weather forecasts" width="540" height="1024" class="aligncenter size-large wp-image-1042" srcset="http://www.cantoni.org/wp/wp-content/uploads/WeatherByText-540x1024.png 540w, http://www.cantoni.org/wp/wp-content/uploads/WeatherByText-158x300.png 158w, http://www.cantoni.org/wp/wp-content/uploads/WeatherByText-768x1456.png 768w, http://www.cantoni.org/wp/wp-content/uploads/WeatherByText-810x1536.png 810w, http://www.cantoni.org/wp/wp-content/uploads/WeatherByText.png 900w" sizes="(max-width: 540px) 100vw, 540px" /></p>
<p>I recently fixed my <a href="http://scooterlabs.com/wx/">Weather by Text</a> mini project to get it working again (since Yahoo shut down YQL) and to update with a few improvements. This service is a simple Twilio-based service which delivers the current weather for the location you send via text message. <span id="more-1043"></span></p>
<p><strong>Update 2020-11-19:</strong> Due to some abusive behavior, unfortunately I had to <a href="http://www.cantoni.org/2020/11/19/retire-weather-by-text">disable the public number</a> for the service.</p>
<h2>The Backstory</h2>
<p>The service is simple: text your location to the SMS number and receive back the current weather conditions.</p>
<p>I created this 5 years ago when I was first learning about the Twilio programmable voice and SMS services. It was also made pretty easy by using the old Yahoo YQL service which boiled down to two simple calls:</p>
<pre><code>select woeid from geo.placefinder where text='%s'
select * from weather.forecast where woeid=%s
</code></pre>
<p>Unfortunately <a href="https://twitter.com/ydn/status/1079785891558653952?lang=en">Yahoo retired all the YQL services</a> in January of this year, leaving my poor little project dead in the water.</p>
<p>Recently I’ve had some time to revisit and rewrite everything to use current webservices directly, so now it works once again!</p>
<h2>Services Used</h2>
<p>The source code for this project is on GitHub under <a href="https://github.com/bcantoni/wxtext">bcantoni/wxtext</a> if you want to see how any of this was implemented or run it yourself. Here are the services used:</p>
<p><a href="https://twilio.com/">Twilio</a> is the key service here – we’re using the Programmable SMS functionality. This is really the only cost I have for running this service: $1/month for the dedicated number and $0.0075/message (within the US; other countries generally cost more). The best documentation topics that explains the programmable SMS request/response flow are <a href="https://www.twilio.com/docs/usage/webhooks/getting-started-twilio-webhooks">Getting Started with Twilio Webhooks</a> and <a href="https://www.twilio.com/docs/sms/tutorials/how-to-receive-and-reply-python">How to Receive and Reply to SMS and MMS Messages in Python</a>.</p>
<p><a href="https://developer.here.com/documentation/geocoder/dev_guide/topics/what-is.html">HERE Geocoder</a> translates the free form “location” text entered by the user into a physical location (latitude/longitude pair) which is then passed on to the weather API. The Freemium level allows up to 250K requests/month for commercial and non-commercial web sites.</p>
<p><a href="https://darksky.net/dev/docs">DarkSky</a> at the free level provides up to 1000 weather forecast API calls per day; after that it’s still very cheap (compared to Twilio). Currently I’m only using the current conditions, but they also have hourly and daily forecast data which I might add in the future. The data returned by DarkSky is thorough but also well organized and easy to use (unlike some other more complicated weather services I looked into).</p>
<p><a href="https://api.slack.com/messaging/webhooks">Slack</a> support is provided with the ultra-simple webhook support for posting a message to a channel. I’m using this to post all requests to my personal Slack workspace just to keep an eye on activity and any errors.</p>
<h2>What’s Next</h2>
<p>No self-respecting side project is without a long to-do list for what’s next. Here’s the list for Weather by Text:</p>
<ul>
<li>Improve the forecast response with more details like general conditions (sunny, cloudy, etc) and possibly some matching icons</li>
<li>Add better international support including units, look at using city/country code coming with Twilio request to see if those are useful. Right now the results may work for international locations but are skewed towards the US.</li>
<li>Related, do a better job handling cases where more than one location is returned, giving the user a choice to pick which one they meant (San Jose California or San José Costa Rica?)</li>
<li>Convert to Python 3.8 and switch to using the Twilio Python client library and other benefits such as requests caching. The code currently runs on Python 2.7 on a shared web host where I don’t have sudo, so I’m not using any libraries beyond what’s normally present in a 2.7 system. This also means today’s solution relies on CGI handling which has been a real pain to troubleshoot.</li>
<li>Look at hosting on AWS Lambda w/API Gateway rather than requiring a separate web host</li>
<li>Improve error handling everywhere, especially if location is not found (make sure always respond to a request from user)</li>
<li>Add ability to get forecast in addition to current conditions</li>
</ul>
<p>Phone mockup image credit: <a href="https://mockuphone.com/">MockuPhone</a></p>
]]></content:encoded>
</item>
</channel>
</rss>
If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid RSS" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src
attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.feedvalidator.org/check.cgi?url=http%3A//www.cantoni.org/feed