<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Clint McMahon]]></title><description><![CDATA[Developer & technology consultant in Minneapolis, MN. ]]></description><link>https://www.clintmcmahon.com/</link><image><url>https://www.clintmcmahon.com/favicon.png</url><title>Clint McMahon</title><link>https://www.clintmcmahon.com/</link></image><generator>Ghost 5.79</generator><lastBuildDate>Tue, 20 Feb 2024 09:39:44 GMT</lastBuildDate><atom:link href="https://www.clintmcmahon.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Progress: Azure B2C User Management App]]></title><description><![CDATA[I'm making good progress on the Azure B2C User Management App that I'm building.]]></description><link>https://www.clintmcmahon.com/progress-azure-b2c-user-management-app/</link><guid isPermaLink="false">65c1497373f9410001a91d08</guid><category><![CDATA[Azure B2C]]></category><category><![CDATA[Azure]]></category><category><![CDATA[c#]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Mon, 05 Feb 2024 23:04:10 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.46.57-PM-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.46.57-PM-1.png" alt="Progress: Azure B2C User Management App"><p>I&apos;m making good progress on the Azure B2C User Management App that <a href="https://www.clintmcmahon.com/creating-azure-b2c-user-admin-app/" rel="noreferrer">I&apos;m building</a>. I&apos;ve been really thinking about how to roll out the app for the initial release and think that the best way to do it is to provide a published .Net Core MVC website. Users will be able to download the compiled website with instructions on how to set up the site and get it working right away. </p><p>The completely published website feels like the simplest way to get the first version of the app out the door. I&apos;m not sure if this is going to be the most useful for people, there is a little configuration that needs to be done on the server side to enable the app to interact with the end user&apos;s Azure B2C tenant. But once the keys are configure, the app itself doesn&apos;t require any more configuration as there is no backing database with it. It uses the client id and client secret of a registered app in the Azure B2C tenant for each request to authenticated and authorize itself into the client&apos;s tenant. </p><p>The initial release of the app will be very simple and will solve the one the problem that lead me to develop the app: You can view and edit custom user attributes and custom extension attributes from a UI instead of having to spin up a <a href="https://www.clintmcmahon.com/add-role-claims-to-an-azure-b2c-user-flow-access-token/" rel="noreferrer">new MS Graph API instance</a> every time you want to view or update your B2C users. The interface will be very simple and consist of three screens initially. Here are the screen shots of the three different screens that a user will initially encounter. </p><ol><li>View a list of all users in the B2C tenant</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.44.22-PM-4.png" class="kg-image" alt="Progress: Azure B2C User Management App" loading="lazy" width="1064" height="925" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/02/Screenshot-2024-02-05-at-4.44.22-PM-4.png 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/02/Screenshot-2024-02-05-at-4.44.22-PM-4.png 1000w, https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.44.22-PM-4.png 1064w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">View all the users in Azure B2C</span></figcaption></figure><ol start="2"><li>View the details of a user</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.46.57-PM.png" class="kg-image" alt="Progress: Azure B2C User Management App" loading="lazy" width="1066" height="926" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/02/Screenshot-2024-02-05-at-4.46.57-PM.png 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/02/Screenshot-2024-02-05-at-4.46.57-PM.png 1000w, https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.46.57-PM.png 1066w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">View user details of a user in Azure AD B2C</span></figcaption></figure><ol start="3"><li>Edit the details of a user - including the custom attributes and external properties that are not either viewable or editable in the Azure Portal.</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.47.27-PM.png" class="kg-image" alt="Progress: Azure B2C User Management App" loading="lazy" width="1078" height="1216" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/02/Screenshot-2024-02-05-at-4.47.27-PM.png 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/02/Screenshot-2024-02-05-at-4.47.27-PM.png 1000w, https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.47.27-PM.png 1078w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Edit user properties including custom attributes/extension in Azure AD B2C </span></figcaption></figure><p>Alongside the out of the box user properties provided by Microsoft.Graph.Models.User I created a section called <strong>Custom Attributes</strong>. Each custom attribute of the tenant is listed here and is editable. When the user clicks <strong>Save Changes</strong> all these values are posted back to the Azure Portal. </p><p>Here you can see the <strong>Is Admin</strong> and <strong>Role</strong> custom user attribute/extension property. Speaking of, I can&apos;t figure out the difference between user attribute/extension property. They both seem to refer to the same underlying object but in the documentation I&apos;ve read seem to be used interchangeably. </p><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.52.11-PM.png" class="kg-image" alt="Progress: Azure B2C User Management App" loading="lazy" width="1281" height="788" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/02/Screenshot-2024-02-05-at-4.52.11-PM.png 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/02/Screenshot-2024-02-05-at-4.52.11-PM.png 1000w, https://www.clintmcmahon.com/content/images/2024/02/Screenshot-2024-02-05-at-4.52.11-PM.png 1281w" sizes="(min-width: 720px) 720px"></figure><p>The MVP is ready to start testing with beta testers but I&apos;m not sure how I want to roll this out just yet. Does it make sense to publish the compiled website to my e-commerce store with a set of instructions on how to install and set up the IIS instance? I&apos;m not sure, it makes sense to me and I&apos;m eager to get the first version out to test how people respond to this feature. Over the next couple of days I&apos;m going to think about a rollout strategy that makes sense and will get the app into the hands of people who can give me some real feedback. </p>]]></content:encoded></item><item><title><![CDATA[Joshua Tree Photos]]></title><description><![CDATA[A few of my favorite pictures from the few hours we spent running around in the Joshua Tree National Park. ]]></description><link>https://www.clintmcmahon.com/joshua-tree-photos/</link><guid isPermaLink="false">65ba7af073f9410001a91cd6</guid><category><![CDATA[Photos]]></category><category><![CDATA[life]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Wed, 31 Jan 2024 17:10:37 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/2024/01/DSC00063.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.clintmcmahon.com/content/images/2024/01/DSC00063.jpg" alt="Joshua Tree Photos"><p>Last weekend we took a long weekend trip to Palm Springs for some sunshine and warm weather. We split up Saturday to be part pool time and the other part we drove out to Joshua Tree National Park. The drive to the west entrance from Palm Springs is a little over an hour. We left late afternoon in order to catch the sunset and do a little bit of star gazing after the sun went down. </p><p>Joshua Tree is a great national park. Seeing this park at sunset and then again at night made us really excited to camp out there some day. </p><p>Here&apos;s a few of my favorite pictures from the few hours we spent running around in the park. </p><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/88648769-6219-494C-A293-0D57F376FDFF_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/88648769-6219-494C-A293-0D57F376FDFF_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/88648769-6219-494C-A293-0D57F376FDFF_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/88648769-6219-494C-A293-0D57F376FDFF_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/BA967C1E-D29E-46DE-B898-D37E1C16381C_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="724" height="1086" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/BA967C1E-D29E-46DE-B898-D37E1C16381C_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/2024/01/BA967C1E-D29E-46DE-B898-D37E1C16381C_1_105_c.jpeg 724w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/1B1BB965-F3E1-4844-89C4-B0E3B6A370C5_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/1B1BB965-F3E1-4844-89C4-B0E3B6A370C5_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/1B1BB965-F3E1-4844-89C4-B0E3B6A370C5_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/1B1BB965-F3E1-4844-89C4-B0E3B6A370C5_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/EFE7D1B7-68EB-4A00-ABE8-48CB17B246E5_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/EFE7D1B7-68EB-4A00-ABE8-48CB17B246E5_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/EFE7D1B7-68EB-4A00-ABE8-48CB17B246E5_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/EFE7D1B7-68EB-4A00-ABE8-48CB17B246E5_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/4B6357EB-AC45-4580-B703-E2CCE04AEEC2_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/4B6357EB-AC45-4580-B703-E2CCE04AEEC2_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/4B6357EB-AC45-4580-B703-E2CCE04AEEC2_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/4B6357EB-AC45-4580-B703-E2CCE04AEEC2_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/F89ECF04-9B78-4E0A-9D1C-3235DC4C0B02_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/F89ECF04-9B78-4E0A-9D1C-3235DC4C0B02_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/F89ECF04-9B78-4E0A-9D1C-3235DC4C0B02_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/F89ECF04-9B78-4E0A-9D1C-3235DC4C0B02_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/5E66DC05-3C9A-4FFC-91C0-58018DB55875_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/5E66DC05-3C9A-4FFC-91C0-58018DB55875_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/5E66DC05-3C9A-4FFC-91C0-58018DB55875_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/5E66DC05-3C9A-4FFC-91C0-58018DB55875_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park at sunset</span></figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/4A99B36E-7EC7-4C33-BFDD-6653DE01B070_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/4A99B36E-7EC7-4C33-BFDD-6653DE01B070_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/4A99B36E-7EC7-4C33-BFDD-6653DE01B070_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/4A99B36E-7EC7-4C33-BFDD-6653DE01B070_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park Sunset</span></figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/79F9474C-38BD-4774-9781-F53519A86722_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/79F9474C-38BD-4774-9781-F53519A86722_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/79F9474C-38BD-4774-9781-F53519A86722_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/79F9474C-38BD-4774-9781-F53519A86722_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/BF913A4B-DAAB-456A-AD53-9242E32DABE0_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/BF913A4B-DAAB-456A-AD53-9242E32DABE0_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/BF913A4B-DAAB-456A-AD53-9242E32DABE0_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/BF913A4B-DAAB-456A-AD53-9242E32DABE0_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/CE91BDEB-3337-48AC-872A-BE60CA1E3F3A_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="724" height="1086" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/CE91BDEB-3337-48AC-872A-BE60CA1E3F3A_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/2024/01/CE91BDEB-3337-48AC-872A-BE60CA1E3F3A_1_105_c.jpeg 724w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park at sunset</span></figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/4B877F49-0F0E-4D8B-AE02-976F70F70F5B_1_201_a.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="2000" height="1333" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/4B877F49-0F0E-4D8B-AE02-976F70F70F5B_1_201_a.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/4B877F49-0F0E-4D8B-AE02-976F70F70F5B_1_201_a.jpeg 1000w, https://www.clintmcmahon.com/content/images/size/w1600/2024/01/4B877F49-0F0E-4D8B-AE02-976F70F70F5B_1_201_a.jpeg 1600w, https://www.clintmcmahon.com/content/images/size/w2400/2024/01/4B877F49-0F0E-4D8B-AE02-976F70F70F5B_1_201_a.jpeg 2400w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park at sunset</span></figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/732B0167-E23A-4C74-872A-39E106C8080B_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/732B0167-E23A-4C74-872A-39E106C8080B_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/732B0167-E23A-4C74-872A-39E106C8080B_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/732B0167-E23A-4C74-872A-39E106C8080B_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park at sunset</span></figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/0B563B54-A755-48D3-AD3E-442BD3E24C92_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="1086" height="724" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/0B563B54-A755-48D3-AD3E-442BD3E24C92_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/size/w1000/2024/01/0B563B54-A755-48D3-AD3E-442BD3E24C92_1_105_c.jpeg 1000w, https://www.clintmcmahon.com/content/images/2024/01/0B563B54-A755-48D3-AD3E-442BD3E24C92_1_105_c.jpeg 1086w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park at sunset</span></figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2024/01/E0616EC2-65F0-4F3F-8445-749320A6240D_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="724" height="1086" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/E0616EC2-65F0-4F3F-8445-749320A6240D_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/2024/01/E0616EC2-65F0-4F3F-8445-749320A6240D_1_105_c.jpeg 724w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2024/01/49A94F50-88B6-4B5D-B304-BD041AFD6736_1_105_c.jpeg" class="kg-image" alt="Joshua Tree Photos" loading="lazy" width="724" height="1086" srcset="https://www.clintmcmahon.com/content/images/size/w600/2024/01/49A94F50-88B6-4B5D-B304-BD041AFD6736_1_105_c.jpeg 600w, https://www.clintmcmahon.com/content/images/2024/01/49A94F50-88B6-4B5D-B304-BD041AFD6736_1_105_c.jpeg 724w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Joshua Tree National Park at sunset</span></figcaption></figure>]]></content:encoded></item><item><title><![CDATA[Just about the warmest winter on record (so far)]]></title><description><![CDATA[I pulled the top ten warmest December, January and February months based on the average temperature for each of the months from the ACIS tool.]]></description><link>https://www.clintmcmahon.com/warmest-winter-on-record-so-far/</link><guid isPermaLink="false">65a940f21249d700012baadf</guid><category><![CDATA[weather]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Thu, 18 Jan 2024 15:34:03 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/2024/01/Screenshot-2024-01-18-at-9.54.22-AM.png" medium="image"/><content:encoded><![CDATA[<img src="https://www.clintmcmahon.com/content/images/2024/01/Screenshot-2024-01-18-at-9.54.22-AM.png" alt="Just about the warmest winter on record (so far)"><p>This winter has been really warm in Minneapolis. December and the beginning of January started out extremely above average with hardly any snow. In the past two weeks it&apos;s cooled down quite a bit. We&apos;ve been hit with some serious cold weather with daily high temperatures not getting above 10&#xB0;F.  Even with these cold days we&apos;re still in the running for the warmest <a href="https://en.wikipedia.org/wiki/Winter?ref=clintmcmahon.com#Meteorological_reckoning" rel="noreferrer">meteorological winter</a> on record. </p><h3 id="top-ten-warmest-winters-in-minneapolisst-paul">Top ten warmest winters in Minneapolis/St. Paul</h3><p>I pulled the top ten warmest December, January and February months based on the average temperature for each of the months from the <a href="https://xmacis.rcc-acis.org/?ref=clintmcmahon.com" rel="noreferrer">ACIS</a> tool. The meteorological winter is defined by December, January and February. You can see that we are barely holding holding onto the #2 spot. This week is suppose to get above average again, so with 43 days to go there is a good chance that we end up with the warmest winter in MPLS / STP history.</p>
<!--kg-card-begin: html-->
<table class="tablesorter tablesorter-default">
   <caption>Maximum 3-Month Mean Avg Temperature <br>for Minneapolis-St Paul Area, MN (ThreadEx)<br>Period of record: 1872-10-01 to 2024-01-17</caption>
   <thead>
      <tr class="tablesorter-headerRow">
         <th class="sorter-sorttrace string-bottom tablesorter-header tablesorter-headerAsc" style="width:10%" data-column="0" tabindex="0" unselectable="on">
            <div class="tablesorter-header-inner">Rank</div>
         </th>
         <th class="sorter-sorttrace string-bottom tablesorter-header" data-column="1" tabindex="0" unselectable="on" style="user-select: none;">
            <div class="tablesorter-header-inner">Average temperature</div>
         </th>
         <th class="sorter-text tablesorter-header tablesorter-headerDesc" data-column="2" tabindex="0" unselectable="on" style="user-select: none;">
            <div class="tablesorter-header-inner">Dates</div>
         </th>
         <th class="sorter-sorttrace string-bottom tablesorter-header" data-column="3" tabindex="0" unselectable="on" style="user-select: none;">
            <div class="tablesorter-header-inner">Missing Days</div>
         </th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>1</td>
         <td>28.9</td>
         <td>1877-12-01 through 1878-02-28</td>
         <td>0</td>
      </tr>
      <tr>
         <td style="font-weight:700">2</td>
         <td style="font-weight:700">28.7</td>
         <td style="font-weight:700">2023-12-01 through 2024-02-29</td>
         <td style="font-weight:700">43</td>
      </tr>
      <tr>
         <td>3</td>
         <td>26.8</td>
         <td>2001-12-01 through 2002-02-28</td>
         <td>0</td>
      </tr>
      <tr>
         <td>4</td>
         <td>26.8</td>
         <td>1930-12-01 through 1931-02-28</td>
         <td>0</td>
      </tr>
      <tr>
         <td>5</td>
         <td>26.2</td>
         <td>2011-12-01 through 2012-02-29</td>
         <td>0</td>
      </tr>
      <tr>
         <td>6</td>
         <td>26.0</td>
         <td>1881-12-01 through 1882-02-28</td>
         <td>0</td>
      </tr>
      <tr>
         <td>7</td>
         <td>25.8</td>
         <td>1997-12-01 through 1998-02-28</td>
         <td>0</td>
      </tr>
      <tr>
         <td>8</td>
         <td>25.7</td>
         <td>1986-12-01 through 1987-02-28</td>
         <td>0</td>
      </tr>
      <tr>
         <td>9</td>
         <td>24.2</td>
         <td>2015-12-01 through 2016-02-29</td>
         <td>0</td>
      </tr>
      <tr>
         <td>10</td>
         <td>24.1</td>
         <td>2016-12-01 through 2017-02-28</td>
         <td>0</td>
      </tr>
   </tbody>
</table>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Creating Azure B2C User Admin App]]></title><description><![CDATA[There isn't a good way for end users who are not Azure admins to update user information without logging into the Azure portal. ]]></description><link>https://www.clintmcmahon.com/creating-azure-b2c-user-admin-app/</link><guid isPermaLink="false">65a6ace91249d700012baa6d</guid><category><![CDATA[Azure B2C]]></category><category><![CDATA[.net]]></category><category><![CDATA[c#]]></category><category><![CDATA[Azure]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Wed, 17 Jan 2024 13:08:56 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1581291518857-4e27b48ff24e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDcxfHx1c2Vyc3xlbnwwfHx8fDE3MDU0MjI5MTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1581291518857-4e27b48ff24e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDcxfHx1c2Vyc3xlbnwwfHx8fDE3MDU0MjI5MTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Creating Azure B2C User Admin App"><p>I started writing an <a href="https://www.clintmcmahon.com/manage-azure-ad-b2c-users-dashboard-2/" rel="noreferrer">Azure B2C user admin app</a> from scratch. This app has been rolling around my head for the past year. I found in the past couple of years that there isn&apos;t a good way for a business end users who are not part of an Azure admin group to update user information. And if those users are part of the Azure admin group the non-tech people need to learn the Azure portal dashboard. This is path is easy for a developer or devops person familiar with the Azure portal interface. But for a regular user who hasn&apos;t spent much time in Azure this can become a pain and can be confusing.</p><p>On top of the user needing to be a granted appropriate rights in Azure, there isn&apos;t a graphical interface that supports <a href="https://www.clintmcmahon.com/add-role-claims-to-an-azure-b2c-user-flow-access-token/" rel="noreferrer">updating user custom properties and extension properties</a>. Anytime I want to update or view a custom property for Azure B2C user I need to get the keys, create an access token and <a href="https://www.clintmcmahon.com/how-to-use-graph-api-to-query-azure-ad-b2c-users-using-postman/" rel="noreferrer">view/update the users via Postman requests</a>. This takes time and knowledge of the MS Graph API, not to mention having to have the correct permissions to be able to get the client secret for the particular Graph API application making the request.</p><p>Because of these reasons I&apos;ve decided to create a new product that will allow users to manage their Azure B2C users from a easy to use management dashboard. The same type of user dashboards that .net developers have been building with ASP Membership providers and lately the Identity provider for years. Instead of having to spin one up and code it yourself, this product will be turn key and ready to go. </p><p>These are the two biggest questions I&apos;m rolling around in my head while I build the code base for this app:</p><ol><li>On-prem or SaaS? Should the application be an on-prem installable IIS instance in the client environment or will users trust this application and allow a SaaS app to store their client credentials for authentication?</li><li>Build the full application or create a client library that is accessible from Nuget and allow the purchaser to build the HTML and user interface. Or can this application be built as an API to allow the backend functionality but keep the interface open to the client?</li></ol><p>To start I&apos;m I&apos;ve been writing the app as an on-prem IIS instance using .Net Core MVC. This will allow me to build out the entire functionality in a separate C# service while I try to answer the questions above. </p>]]></content:encoded></item><item><title><![CDATA[Friday, January 12, 2024]]></title><description><![CDATA[<p>Yesterday I went to work from a coffee shop that I&apos;ve never been but meaning to visit for a while. I met the owners ten years ago selling coffee at the Linden Hills Farmer&apos;s Market. Since then they&apos;ve opened multiple locations and are the</p>]]></description><link>https://www.clintmcmahon.com/friday-january-12/</link><guid isPermaLink="false">65a1ae501249d700012baa2e</guid><category><![CDATA[life]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Fri, 12 Jan 2024 21:44:10 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1453614512568-c4024d13c247?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGNvZmZlZSUyMHNob3B8ZW58MHx8fHwxNzA1MDk1MzQ2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1453614512568-c4024d13c247?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGNvZmZlZSUyMHNob3B8ZW58MHx8fHwxNzA1MDk1MzQ2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Friday, January 12, 2024"><p>Yesterday I went to work from a coffee shop that I&apos;ve never been but meaning to visit for a while. I met the owners ten years ago selling coffee at the Linden Hills Farmer&apos;s Market. Since then they&apos;ve opened multiple locations and are the best coffee roaster in the Twin Cities.</p><p>While I was working a man came into the coffee shop and asked one of the barista&apos;s to use their land line. The barista was helpful and gave the man the phone to make his call. He made the phone call, gave the phone back to the workers and went to sit down. A little while later a person called the coffee shop asking to speak to someone who had just called them from that number. The barista happily obliged and walked the phone over to the man who made the initial phone call patiently waiting. He took the phone call, talked for a bit then hung up and headed out the door.</p><p>That was it, end of transaction. I&apos;m not sure that man even ordered a coffee, but it was a great to watch this interaction in a time of where everyone has a phone and everyone always seems to know where everyone is. </p><p>Later on a person called the coffee shop to ask what the barista&apos;s favorite Chinese food was. I didn&apos;t hear the other end of the phone, but the barista relayed that someone called to find out her favorite Chinese food and was going to bring them lunch.</p><p>This coffee shop also has a heater above the door that is wired to turn on when the door opens and close when the door closes. So each time a person walks into the shop a blast of heat comes down from the ceiling. This is great for people sitting by the door, however I feel that it makes the inside of the coffee shop really really warm. </p>]]></content:encoded></item><item><title><![CDATA[Friday, December 22 2023]]></title><description><![CDATA[<p>I&apos;m writing this post to kick start my blogging habit. Hopefully it sticks this time. Lately I&apos;ve been writing about how to fix bugs or set up environments, but the more I read about writing the more intrigued I am to make writing in public a</p>]]></description><link>https://www.clintmcmahon.com/december-22-2023/</link><guid isPermaLink="false">658597a61249d700012ba9a5</guid><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Fri, 22 Dec 2023 14:47:36 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1504275107627-0c2ba7a43dba?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxibG9nJTIwaG9yaXpvbnRhbHxlbnwwfHx8fDE3MDMyNTY0MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1504275107627-0c2ba7a43dba?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxibG9nJTIwaG9yaXpvbnRhbHxlbnwwfHx8fDE3MDMyNTY0MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Friday, December 22 2023"><p>I&apos;m writing this post to kick start my blogging habit. Hopefully it sticks this time. Lately I&apos;ve been writing about how to fix bugs or set up environments, but the more I read about writing the more intrigued I am to make writing in public a habit. I subscribe to the <a href="https://peopleandblogs.com/?ref=clintmcmahon.com" rel="noreferrer">People &amp; Blogs</a> newsletter and find it fascination how people are still using normal blogging the same way they did in the early 2000s. </p><p>Back in the 2000s I had a local blog with two friends that was semi-popular. We&apos;d write about our things in Minneapolis and I&apos;d post some life updates. This was before Twitter took over and people who wanted to post something in public did it on the Internet. </p><h2 id="winter-break">Winter Break</h2><p>Today technically marks the end of the work year for me and the start of winter break until January 2nd. I plan on working a little bit here and there, enough to manage projects and clients but I&apos;m really going to try and take a break this year. There are some side projects that I have been itching to get done or make progress on, too. This next week feels like the right time to make some head-way on those. </p><p>Some of the projects I want to focus on:</p><ul><li>Today&apos;s Record High<ul><li>Talking to some other developers at my co-working space has renewed my interest in this project. Which isn&apos;t too hard, but when I know someone else feels the same way I do about a project it gets me excited to work on it some more. </li></ul></li><li>Armchair Media Explorer<ul><li>This data set of all the books/movies/shows that are mentioned on Armchair Expert is a little over a year old at this point. Given this good size dataset we should be able to create some pretty graphs and charts.</li></ul></li><li>JetTip Data<ul><li>This is a project that my software company is partners with JetTip. We&apos;ve developed a consumer to feed the JetTip mobile app/website with real-time FAA flight updates. There are some error handling and service configurations that I need to put in place to make sure that the hosting is as rock solid as it needs to be.</li></ul></li></ul><p>T is off school this entire week so we have some time together. I think some nice warm winter walks, a snowboard lesson and general overall just hanging out enjoy time off from work and school. </p><p>I hope to work on my latte art as well. I&apos;m getting better at it since I started drinking a cortado every morning instead of making a pour over. I still make pour overs for K. She prefers straight up coffee to espresso drinks. </p><h2 id="record-highs-for-christmas">Record Highs for Christmas</h2><p>It&apos;s been the warmest December that I can remember in Minneapolis this year. It&apos;s an el nino year so the weather will naturally be warmer, however with the impact of climate change it appears that this year is kind of crazy. With Christmas around the corner I looked up our record highs on Christmas Eve and Christmas where in Minneapolis. It looks like we are going to be close if not breaking these records this year.</p><p>Looking at the temperatures as a record is kind of wild, we have been close, if not above those temperatures for the past couple of weeks it seems. The temperature might not have broken any records over the last couple of weeks but it&apos;s been freakishly abnormally warm here all December and November. </p><p>Here is a look at the record temps for Christmas Eve and Christmas in the Minneapolis area. </p><h3 id="christmas-eve">Christmas Eve</h3>
<!--kg-card-begin: html-->
<table class="tablesorter tablesorter-default"><caption>Maximum 1-Day Mean Max Temperature <br>for Minneapolis-St Paul Area, MN (ThreadEx)<br></caption><thead><tr class="tablesorter-headerRow"><th style="user-select: none;" data-column="0" class="sorter-sorttrace string-bottom tablesorter-header"><div class="tablesorter-header-inner">Rank</div></th><th style="user-select: none;" data-column="1" class="sorter-sorttrace string-bottom tablesorter-header"><div class="tablesorter-header-inner">Temp (F)</div></th><th style="user-select: none;" data-column="2" class="sorter-text tablesorter-header"><div class="tablesorter-header-inner">Date</div></th></tr></thead><tbody><tr><td>1</td><td>46.0</td><td>1957-12-24</td></tr><tr><td>2</td><td>45.0</td><td>1881-12-24</td></tr><tr><td>3</td><td>44.0</td><td>1940-12-24</td></tr><tr><td>4</td><td>43.0</td><td>2021-12-24</td></tr><tr><td>-</td><td>43.0</td><td>1994-12-24</td></tr><tr><td>-</td><td>43.0</td><td>1889-12-24</td></tr><tr><td>7</td><td>42.0</td><td>2011-12-24</td></tr><tr><td>-</td><td>42.0</td><td>1877-12-24</td></tr><tr><td>9</td><td>41.0</td><td>1928-12-24</td></tr><tr><td>10</td><td>40.0</td><td>2006-12-24</td></tr></tbody><tfoot><tr><td data-column="0">Last value also occurred in one or more previous years.</td></tr><tr><td data-column="0">Period of record: 1872-10-01 to 2023-12-21</td></tr></tfoot></table>
<!--kg-card-end: html-->
<p></p><h3 id="christmas-day">Christmas Day</h3>
<!--kg-card-begin: html-->
<table class="tablesorter tablesorter-default"><caption>Maximum 1-Day Mean Max Temperature <br>for Minneapolis-St Paul Area, MN (ThreadEx)<br></caption><thead><tr class="tablesorter-headerRow"><th class="sorter-sorttrace string-bottom tablesorter-header" data-column="0" style="user-select: none;"><div class="tablesorter-header-inner">Rank</div></th><th class="sorter-sorttrace string-bottom tablesorter-header" data-column="1" style="user-select: none;"><div class="tablesorter-header-inner">Temp (F)</div></th><th class="sorter-text tablesorter-header" data-column="2" style="user-select: none;"><div class="tablesorter-header-inner">Date</div></th></tr></thead><tbody><tr><td>1</td><td>51.0</td><td>1922-12-25</td></tr><tr><td>2</td><td>46.0</td><td>1881-12-25</td></tr><tr><td>3</td><td>45.0</td><td>1994-12-25</td></tr><tr><td>4</td><td>43.0</td><td>1999-12-25</td></tr><tr><td>-</td><td>43.0</td><td>1943-12-25</td></tr><tr><td>-</td><td>43.0</td><td>1928-12-25</td></tr><tr><td>7</td><td>42.0</td><td>2011-12-25</td></tr><tr><td>-</td><td>42.0</td><td>1936-12-25</td></tr><tr><td>9</td><td>41.0</td><td>1940-12-25</td></tr><tr><td>10</td><td>40.0</td><td>1919-12-25</td></tr></tbody><tfoot><tr><td data-column="0">Period of record: 1872-10-01 to 2023-12-21</td></tr></tfoot></table>
<!--kg-card-end: html-->
<figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2023/12/Screenshot-2023-12-22-at-8.29.15-AM.png" class="kg-image" alt="Friday, December 22 2023" loading="lazy" width="1581" height="605" srcset="https://www.clintmcmahon.com/content/images/size/w600/2023/12/Screenshot-2023-12-22-at-8.29.15-AM.png 600w, https://www.clintmcmahon.com/content/images/size/w1000/2023/12/Screenshot-2023-12-22-at-8.29.15-AM.png 1000w, https://www.clintmcmahon.com/content/images/2023/12/Screenshot-2023-12-22-at-8.29.15-AM.png 1581w" sizes="(min-width: 720px) 720px"></figure><p>Here&apos;s a look at the recent temperatures for December here as well. I took this screen grab from my side project, <a href="https://todaysrecordhigh.com/?ref=clintmcmahon.com" rel="noreferrer">Today&apos;s Record High</a>. </p><p>That&apos;s about it for today. I seem to have written a good amount of information here which is pretty awesome considering this is the first blog post that I&apos;ve just let my stream of conscious go. It feels good to let your brain run and get those thoughts out onto digital paper.  </p>]]></content:encoded></item><item><title><![CDATA[FizzBuzz in C#]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p><a href="https://news.ycombinator.com/item?id=38503486&amp;ref=clintmcmahon.com" data-type="link" data-id="https://news.ycombinator.com/item?id=38503486" target="_blank" rel="noreferrer noopener">The comments on this Hacker News post</a> generated a bunch of opinions on the ability for developers to solve a FizzBuzz problem. Specifically in a coding interview. I&#x2019;ve never actually seen what the FizzBuzz problem was, so I had to look it up. In this blog post I</p>]]></description><link>https://www.clintmcmahon.com/fizzbuzz-in-c/</link><guid isPermaLink="false">6579d881a340810001abcc16</guid><category><![CDATA[c#]]></category><category><![CDATA[fizzbuzz]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Sun, 03 Dec 2023 13:47:51 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1489829024224-f5ef0434a0ca?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGZpenolMjBob3Jpem9udGFsfGVufDB8fHx8MTcwMjQ5Mzk5Mnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://images.unsplash.com/photo-1489829024224-f5ef0434a0ca?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGZpenolMjBob3Jpem9udGFsfGVufDB8fHx8MTcwMjQ5Mzk5Mnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="FizzBuzz in C#"><p><a href="https://news.ycombinator.com/item?id=38503486&amp;ref=clintmcmahon.com" data-type="link" data-id="https://news.ycombinator.com/item?id=38503486" target="_blank" rel="noreferrer noopener">The comments on this Hacker News post</a> generated a bunch of opinions on the ability for developers to solve a FizzBuzz problem. Specifically in a coding interview. I&#x2019;ve never actually seen what the FizzBuzz problem was, so I had to look it up. In this blog post I solve FizzBuzz in C#. </p>



<p>The FizzBuzz problem is a challenge for a developer to write a method, in any language, to return different parts of the word FizzBuzz. </p>



<p>It goes like this:</p>



<ul>
<li>If a number is divisible by 3 or 5 =&gt; return FizzBuzz</li>



<li>If a number is only divisible by 3 =&gt; return Fizz</li>



<li>If a number is divisible by 5 =&gt; return Buzz</li>



<li>If a number is not divisible by 3 or 5 =&gt; return the number</li>
</ul>



<p>Over twenty years of programming experience and I&#x2019;ve never come across question in an interview so I thought it would be fun to jump onto <a href="https://dotnetfiddle.net/?ref=clintmcmahon.com" data-type="link" data-id="https://dotnetfiddle.net/" target="_blank" rel="noreferrer noopener">.Net Fiddle</a> to give it a try. In this function you take any number and check if it can be divisible by 3 or 5. The trick to this function is to use the <code>% mod</code> operator to check if a number is divisible by another number. The <code>mod</code> operator will return a number if there is a remainder after division between the two supplied numbers. If the number returned after division using the <code>mod</code> operator you will return zero &#x2013; meaning there isn&#x2019;t a remainder after division. This is what the function is all about. Here&#x2019;s my FizzBuzz implementation I wrote this morning after reading the Hacker News post. </p>



<h2 class="wp-block-heading">Simple FizzBuzz implementation in C#</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewbox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"/><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"/><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"/></g></svg></span><span 3="=" 5="=" role="button" tabindex="0" data-code="public class Program
{
	public static void Main()
	{
		int i = 0;
		while(i &lt;=100)
		{
			string fizzWord = GetFizz(i);
			Console.WriteLine(fizzWord);
			i = i + 1;
		}
		
	}
	
	public static string GetFizz(int i)
	{
		if(i % 3 == 0 &amp;&amp; i % 5==0)
		{
		  return " fizzbuzz"; } else if(i % 0) { return "fizz"; "buzz"; i.tostring(); }" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewbox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Program</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Main</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">	{</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #569CD6">int</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #C586C0">while</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> <=< span><span style="color: #B5CEA8">100</span><span style="color: #D4D4D4">)</span></=<></span>
<span class="line"><span style="color: #D4D4D4">		{</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #569CD6">string</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">fizzWord</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">GetFizz</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #9CDCFE">Console</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">WriteLine</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">fizzWord</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> + </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">		}</span></span>
<span class="line"><span style="color: #D4D4D4">		</span></span>
<span class="line"><span style="color: #D4D4D4">	}</span></span>
<span class="line"><span style="color: #D4D4D4">	</span></span>
<span class="line"><span style="color: #D4D4D4">	</span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">string</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">GetFizz</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">int</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">	{</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> % </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4"> == </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4"> &amp;&amp; </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> % </span><span style="color: #B5CEA8">5</span><span style="color: #D4D4D4">==</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">		{</span></span>
<span class="line"><span style="color: #D4D4D4">		  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;FizzBuzz&quot;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">		}</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> % </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4"> == </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">		{</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Fizz&quot;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">		}</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4"> % </span><span style="color: #B5CEA8">5</span><span style="color: #D4D4D4"> == </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">		{</span></span>
<span class="line"><span style="color: #D4D4D4">			</span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Buzz&quot;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">		}</span></span>
<span class="line"><span style="color: #D4D4D4">		</span></span>
<span class="line"><span style="color: #D4D4D4">		</span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">ToString</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">	}</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></span></code></pre></div>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Worlds Colliding: Dr. Becky Kennedy on Armchair Expert and Our Journey with the Armchair Media Explorer]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>The recent episode of the Armchair Expert featured the Dr. Becky Kennedy, a renowned psychologist specializing in parenting, resonated deeply with us. It was a thrilling worlds colliding moment &#x2013; the insightful world of Armchair Expert and the transformative parenting wisdom of Dr. Becky.</p>



<p><strong>Armchair Expert: A Platform for Meaningful</strong></p>]]></description><link>https://www.clintmcmahon.com/the-perfect-collision-dr-becky-kennedy-on-armchair-expert-and-our-journey-with-the-armchair-media-explorer/</link><guid isPermaLink="false">6579d881a340810001abcc15</guid><category><![CDATA[Armchair Expert]]></category><category><![CDATA[life]]></category><category><![CDATA[parenting]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Fri, 17 Nov 2023 16:12:24 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: html-->
<p>The recent episode of the Armchair Expert featured the Dr. Becky Kennedy, a renowned psychologist specializing in parenting, resonated deeply with us. It was a thrilling worlds colliding moment &#x2013; the insightful world of Armchair Expert and the transformative parenting wisdom of Dr. Becky.</p>



<p><strong>Armchair Expert: A Platform for Meaningful Conversations</strong></p>



<p>We created the <a href="https://armchairmediaexplorer.com/?ref=clintmcmahon.com">Armchair Expert Media Explorer</a> (think all the movies, documentaries, shows and podcasts mentioned in each episode) to work along side the Armchair Expert podcast, hosted by Dax Shepard and Monica Padman, has always been a platform where candid, deep, and often surprisingly vulnerable conversations take root. The podcast has a unique way of delving into the human experience, bringing forth the raw, unfiltered aspects of various life facets &#x2013; from celebrity struggles to expert opinions on psychological and social issues. It&#x2019;s this unvarnished approach that makes each episode not just relatable, but also incredibly enlightening.</p>



<p><strong>Dr. Becky Kennedy: A Beacon for Parents</strong></p>



<p>Dr. Becky Kennedy has been nothing short of a lighthouse for parents wading through the complexities of raising children. Her approach, blending compassion with practicality, offers a fresh perspective in a field often muddied by conflicting advice. Her ability to articulate the challenges of parenting, while providing actionable strategies, has been a game changer for many, including us. Dr. Becky doesn&#x2019;t just offer advice; she empowers parents to find their unique path in nurturing their children&#x2019;s development.</p>



<p><strong>Two Worlds Collide</strong></p>



<p>The episode featuring Dr. Becky Kennedy was more than just another podcast &#x2013; it was a meeting point of profound insights and practical wisdom. It provided a space for Dr. Becky to share her invaluable knowledge with a wider audience, offering parents easy access to expert guidance. This episode was a testament to the power of open conversation in breaking down complex topics like parenting into digestible, actionable advice.</p>



<p><strong>Armchair Media Explorer: Enhancing the Experience</strong></p>



<p>To complement such enriching content, we created the Armchair Media Explorer &#x2013; a tool designed to help listeners delve deeper into the subjects discussed on the podcast. Recognizing how often books, movies, shows, podcasts, and articles are mentioned in episodes, we saw the need for a resource that neatly compiles these references. The Armchair Media Explorer does just that, allowing users to easily find and explore the media mentioned, enhancing their learning and enjoyment.</p>



<p><strong>Dr. Becky&#x2019;s Influence on Our Parenting Journey</strong></p>



<p>For us personally, Dr. Becky&#x2019;s insights have been monumental in our parenting journey. In these challenging times, where conventional wisdom often falls short, her advice has been a guiding star. She&#x2019;s helped us navigate the often confusing and guilt-ridden landscape of modern parenting with grace and understanding. Her appearance on Armchair Expert not only amplified her reach but also brought her invaluable advice to an audience eager for grounded, practical parenting wisdom.</p>



<p><strong>Conclusion: A Synergistic Impact</strong></p>



<p>The collaboration between Armchair Expert and Dr. Becky Kennedy symbolizes a powerful synergy. It&#x2019;s a fusion of thought-provoking dialogue with practical, life-changing advice. For listeners like us, who rely on both the enlightening conversations of Armchair Expert and the parenting wisdom of Dr. Becky, this episode was a milestone. It&#x2019;s a vivid reminder of how the right voices, when given a platform, can profoundly impact our lives. The Armchair Media Explorer is our contribution to this ecosystem, hoping to make the journey of exploration and learning a bit easier for every listener out there.</p>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Friday, November 17 2023]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>Good morning. A few notes that I wanted to record for this lovely fall Friday. </p>



<ol>
<li>Near record warm has passed us and we&#x2019;re back to normal cold fall. Should be great for saunaing.</li>



<li>Made a fantastic oat milk cortado this morning. Using regular <a href="https://www.oatly.com/?ref=clintmcmahon.com" data-type="link" data-id="https://www.oatly.com/">Oatly</a> blend, normally I use</li></ol>]]></description><link>https://www.clintmcmahon.com/friday-november-17-2023/</link><guid isPermaLink="false">6579d881a340810001abcc14</guid><category><![CDATA[notes]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Fri, 17 Nov 2023 16:04:06 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/wordpress/2023/11/glenn-carstens-peters-RLw-UC03Gwc-unsplash-scaled.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html-->
<img src="https://www.clintmcmahon.com/content/images/wordpress/2023/11/glenn-carstens-peters-RLw-UC03Gwc-unsplash-scaled.jpg" alt="Friday, November 17 2023"><p>Good morning. A few notes that I wanted to record for this lovely fall Friday. </p>



<ol>
<li>Near record warm has passed us and we&#x2019;re back to normal cold fall. Should be great for saunaing.</li>



<li>Made a fantastic oat milk cortado this morning. Using regular <a href="https://www.oatly.com/?ref=clintmcmahon.com" data-type="link" data-id="https://www.oatly.com/">Oatly</a> blend, normally I use the Barista&#x2019;s version, but today&#x2019;s turned out fantastic. I&#x2019;d say top five of all time home made cortados. </li>



<li>Driving T to school this morning he commented that so many people have black jackets. I replied saying they were a popular color. That brought up the question of what does &#x201C;popular&#x201D; mean. After I explained that it&#x2019;s something that a lot of people like, for example Christmas, ice cream, soccer are all things that are popular because many people like them. When I asked him if he could think of something that was also popular, a few seconds passed and he replied &#x201C;I know something that is popular for adults&#x201D;. I asked what and he said &#x201C;relaxing&#x201D;. He got that right.</li>



<li>The <a href="https://armchairmediaexplorer.com/?ref=clintmcmahon.com">Armchair Media Explorer</a> has been slowly gaining traffic among the fans of the popular podcast Armchair Expert. People love it, but I really need someone with a large following to help promote it. So this morning I emailed Dax, Monica and their producer Rob in hopes that they read my emails. Having them Tweet (X?), Instagram it or just promote it would go a long ways for the platform.</li>



<li>Started a new project I&#x2019;m calling the Radio Station Project. It&#x2019;s going to contain a lot of radio station data and some nice data visualizations. More to come after I can collect some data.</li>
</ol>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Real-time FAA Flight Data Powering the JetTip Smart Alert System]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>Over the past year I&#x2019;ve been working with <a href="https://jettip.net/?ref=clintmcmahon.com" data-type="link" data-id="https://jettip.net" target="_blank" rel="noreferrer noopener">JetTip</a> to provide their <a href="https://jettip.net/blog/real-time-faa-data-is-now-powering-jettips-smart-flight-alert-system?ref=clintmcmahon.com" data-type="link" data-id="https://jettip.net/blog/real-time-faa-data-is-now-powering-jettips-smart-flight-alert-system" target="_blank" rel="noreferrer noopener">smart alert system with real-time FAA flight data</a>. We finally launched the service into production last month so I decided to write this blog post about the real-time FAA flight data powering the JetTip smart alert</p>]]></description><link>https://www.clintmcmahon.com/real-time-faa-flight-data-powering-the-jettip-smart-alert-system/</link><guid isPermaLink="false">6579d881a340810001abcc11</guid><category><![CDATA[faa]]></category><category><![CDATA[flight data]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Wed, 15 Nov 2023 22:09:01 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/wordpress/2023/11/IMG_3110-scaled.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html-->
<img src="https://www.clintmcmahon.com/content/images/wordpress/2023/11/IMG_3110-scaled.jpg" alt="Real-time FAA Flight Data Powering the JetTip Smart Alert System"><p>Over the past year I&#x2019;ve been working with <a href="https://jettip.net/?ref=clintmcmahon.com" data-type="link" data-id="https://jettip.net" target="_blank" rel="noreferrer noopener">JetTip</a> to provide their <a href="https://jettip.net/blog/real-time-faa-data-is-now-powering-jettips-smart-flight-alert-system?ref=clintmcmahon.com" data-type="link" data-id="https://jettip.net/blog/real-time-faa-data-is-now-powering-jettips-smart-flight-alert-system" target="_blank" rel="noreferrer noopener">smart alert system with real-time FAA flight data</a>. We finally launched the service into production last month so I decided to write this blog post about the real-time FAA flight data powering the JetTip smart alert system. The collaboration between JetTip and me has led us to the creation of a cutting-edge software solution that has a direct connection to the FAA data stream which is now integral to the JetTip smart alert system. </p>



<p>I started working with JetTip a couple summers ago when they hired me to build the <a href="https://jettip.net/blog/new-flight-tracking-app-helps-aviation-enthusiasts-see-interesting-aircraft?ref=clintmcmahon.com" data-type="link" data-id="https://jettip.net/blog/new-flight-tracking-app-helps-aviation-enthusiasts-see-interesting-aircraft">JetTip mobile app</a>. The app has been downloaded by thousands of users for both <a href="https://apps.apple.com/us/app/jettip/id1577380011?ref=clintmcmahon.com" data-type="link" data-id="https://apps.apple.com/us/app/jettip/id1577380011" target="_blank" rel="noreferrer noopener">iOS</a> and <a href="https://play.google.com/store/apps/details?id=com.jettip.mobile&amp;hl=en_US&amp;gl=US&amp;ref=clintmcmahon.com" data-type="link" data-id="https://play.google.com/store/apps/details?id=com.jettip.mobile&amp;hl=en_US&amp;gl=US" target="_blank" rel="noreferrer noopener">Android</a> mobile operating systems. The mobile app allowed JetTip&#x2019;s users to move from a text messages based alert system to a push notification system. This update not only saves money via the loss of text messaging rates but allows more flexibility for the end users who can now pause and update their notifications much more easily via the app interface. </p>



<p>The mobile app project was just the beginning of what&#x2019;s turned into a pretty rad relationship. Over the past couple years I&#x2019;ve gotten to know Nick from JetTip quite well and even consider him a friend. When he came to me with the idea of creating a system to process the FAA data in real-time I was on board immediately. So, as flight data providers shifted their focus to enterprise clients and costs surged, we saw an opportunity to use our development backgrounds and data processing experience to create our own flight data processing product.</p>



<p>I&#x2019;ve become pretty comfortable processing <a href="https://clintmcmahon.com/portfolio/?ref=clintmcmahon.com" data-type="link" data-id="https://clintmcmahon.com/portfolio/">large amounts of data</a>, so plugging into the FAA fire host wasn&#x2019;t a huge overhaul. The biggest challenge was how to process all that data so fast and store it efficiently. Managing gigs and gigs of data is not a trivial thing, I quickly become pretty good at fine tuning MySQL databases and managing server resources. The core objective was to develop a system capable of ingesting and processing all of that FAA flight data accurately. This system was not just about managing data; it was about transforming it into actionable insights for all the aviation enthusiasts out there. But build in a way that we can utilize the data source in the future for more products. </p>



<p>This direct feed has revolutionized how JetTip subscribers receive information and opened up my mind to additional flight data products that we can develop in the future. Part of the new service that we&#x2019;ve created is virtually instant diversion alerts, real-time notifications of international departures, and the ability to see flight plans well into the future were all made possible by this integration. Based on this information, I think there is room for more robust products that are just as good, or better, than some of the competitors out there that we can provide at a much lower cost.</p>



<h4 class="wp-block-heading">Looking Ahead</h4>



<p>I&#x2019;ve been working on this product for the past nine months and have learned a ton about high transactional databases, Java Messaging and managing large databases. We&#x2019;re excited about the future possibilities this data has in store. The feedback from the community has been pretty great and have spurred more thoughts about how to incorporating these insights into additional products. The goal is to not only maintain this data set, but grow the level of service provided and products to the plane spotting community and anyone else interested in real-time flight updates.</p>



<hr class="wp-block-separator has-alpha-channel-opacity">



<p><em>This blog post aims to provide a background to the JetTip announcement regarding their new in-house FAA data source. For more details on this exciting development, please refer to the <a href="https://jettip.net/blog/real-time-faa-data-is-now-powering-jettips-smart-flight-alert-system?ref=clintmcmahon.com" target="_blank" data-type="link" data-id="https://jettip.net/blog/real-time-faa-data-is-now-powering-jettips-smart-flight-alert-system" rel="noreferrer noopener">original JetTip post</a>.</em></p>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[How to Configure Cloudflare's Load Balancer Monitoring When Health of the Pool is Critical]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>I recently faced an issue where my Cloudflare managed API endpoint was functioning correctly&#x2014;returning a 200 OK status when I hit the endpoint manually&#x2014;but Cloudflare&#x2019;s Load Balancer was reporting a &#x201C;Critical&#x201D; health status. After a lot of trial and error with some</p>]]></description><link>https://www.clintmcmahon.com/how-to-configure-cloudflare-load-balancer-monitoring-when-health-of-the-pool-is-critical/</link><guid isPermaLink="false">6579d881a340810001abcc0f</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[hosting]]></category><category><![CDATA[how to]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Mon, 23 Oct 2023 15:51:00 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/wordpress/2023/10/Screenshot-2023-10-23-at-10.43.05%E2%80%AFAM.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html-->
<img src="https://www.clintmcmahon.com/content/images/wordpress/2023/10/Screenshot-2023-10-23-at-10.43.05%E2%80%AFAM.png" alt="How to Configure Cloudflare&apos;s Load Balancer Monitoring When Health of the Pool is Critical"><p>I recently faced an issue where my Cloudflare managed API endpoint was functioning correctly&#x2014;returning a 200 OK status when I hit the endpoint manually&#x2014;but Cloudflare&#x2019;s Load Balancer was reporting a &#x201C;Critical&#x201D; health status. After a lot of trial and error with some investigation, I found that the problem was with the Header Settings in the monitor health check. This post will outline the steps I took to get the health monitor check to return healthy.</p>



<h2 class="wp-block-heading">Initial Troubleshooting</h2>



<p>I created a simple endpoint in my API specifically for the health monitor. The endpoint was a simple GET and returned a 200 along with the server name as the body text. This endpoint was returning a 200 response code from Postman and through my browser, so I double checked that the monitor configuration was correct in Cloudflare:</p>



<ul>
<li><strong>URL</strong>: I made sure it was pointing to the correct endpoint that was returning 200 when I manually hit the url.</li>



<li><strong>Method</strong>: Set to <code>GET</code> as my API was expecting.</li>



<li><strong>Timeout and Frequency</strong>: Set to 60.</li>
</ul>



<p>These checked out but the health of the monitor was still returning &#x201C;Critical&#x201D;. At first I didn&#x2019;t think that I needed to set any additional headers, ignorantly thinking that Cloudflare would would set default headers of the monitor like Postman does, but that&#x2019;s not the case. So I went to the next step and manually set the headers.</p>



<h2 class="wp-block-heading">The Breakthrough: Header Settings</h2>



<p>After further digging and reading troubleshooting posts on Cloudflare forums, I decided to manually set the headers under the Advanced settings for the monitor. Within the health monitor set up, I filled out the name, url and type of request. Then I clicked Advanced Settings and created the following header settings for the monitor.</p>



<ul>
<li><strong>Host</strong>: I set this to the domain that the health check was targeting, for example, <code>api.parkasoftware.com</code>.</li>



<li><strong>User-Agent</strong>: I set this to <code>Cloudflare-Health-Check</code>.</li>



<li><strong>Authorization</strong>: Since my API was public I didn&#x2019;t set this to anything.</li>



<li><strong>Accept</strong>: I set this to <code>application/json</code>.</li>
</ul>



<p>And would&#x2019;nt you know it, my API health monitor started returning <strong>Healthy</strong>!</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1017" height="551" src="https://www.clintmcmahon.com/content/images/wordpress/2023/10/Screenshot-2023-10-23-at-10.43.05%E2%80%AFAM.png" alt="How to Configure Cloudflare&apos;s Load Balancer Monitoring When Health of the Pool is Critical" class="wp-image-1277"></figure>



<h2 class="wp-block-heading">The How-To: Setting Up Headers in Cloudflare</h2>



<p>Here are the steps I took to get the Headers set up in my Cloudflare load balancer health monitor.</p>



<ol>
<li><strong>Log in to Cloudflare Dashboard</strong>: Go to the &#x201C;Traffic&#x201D; tab and locate the Load Balancer section. Click edit on the load balancer to edit.</li>



<li><strong>Click Monitors</strong>: Next to your Load Balancer, you&#x2019;ll see the health check configurations. Click edit. Click Remove if you already have a monitor configured. Then create a new monitor.</li>



<li><strong>Add Default Options</strong>: Fill out the default name, Action and Url.</li>



<li><strong>Add Headers</strong>: Click advanced settings and scroll down to the section where you can add headers. Here, enter the key-value pairs for each header.
<ul>
<li>Key: <code>Host</code>, Value: <code>api.parkasoftware.com</code></li>



<li>Key: <code>User-Agent</code>, Value: <code>Cloudflare-Health-Check</code></li>



<li>Key: <code>Authorization</code>, Value: None or your <code>Bearer access token if required</code></li>



<li>Key: <code>Accept</code>, Value: <code>application/json</code></li>
</ul>
</li>



<li><strong>Save and Test</strong>: Once all headers are added, save your changes. It&#x2019;s a good idea to test the health check to make sure it&#x2019;s working as expected.</li>
</ol>



<h2 class="wp-block-heading">Conclusion</h2>



<p>The issue was resolved after correctly configuring the Header Settings in Cloudflare&#x2019;s health check. If you ever find yourself in a similar situation, double-checking these settings could be the key to solving your problem.</p>



<p>Good luck!</p>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[How To Migrate WordPress Websites to WP Engine]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>This blog post outlines how to migrate a WordPress website from any hosting provider to WP Engine hosting account without access to source FTP site. The post focuses around utilizing the WP Engine Migration Assistant Plugin. WP Engine offers a specialized plug in to make WordPress migrations a pretty simple</p>]]></description><link>https://www.clintmcmahon.com/how-to-migrate-wordpress-websites-to-wp-engine/</link><guid isPermaLink="false">6579d881a340810001abcc0c</guid><category><![CDATA[hosting]]></category><category><![CDATA[wordpress]]></category><category><![CDATA[wp engine]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Mon, 18 Sep 2023 22:03:53 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/wordpress/2023/09/markus-winkler-cV9-hOgoaok-unsplash-scaled.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html-->
<img src="https://www.clintmcmahon.com/content/images/wordpress/2023/09/markus-winkler-cV9-hOgoaok-unsplash-scaled.jpg" alt="How To Migrate WordPress Websites to WP Engine"><p>This blog post outlines how to migrate a WordPress website from any hosting provider to WP Engine hosting account without access to source FTP site. The post focuses around utilizing the WP Engine Migration Assistant Plugin. WP Engine offers a specialized plug in to make WordPress migrations a pretty simple from one hosting provider to another. In this example it doesn&#x2019;t matter what your hosting provider is, this plug in should work with any of them. And best of all, you don&#x2019;t need access to the source FTP site to do the migration.</p>



<h2 class="wp-block-heading">Managed Hosting for Business Operations</h2>



<p>A large part of my business is providing an array of WordPress hosting services that cover all the backend configurations, including SSL installations, plugin updates, and server-side optimizations for my clients&#x2019; websites. This frees them up to focus on their business and what they do best instead of having to struggle working on a system they dont&#x2019; understand nor do they care about understanding it. Part of my service offering is migrating WordPress sites from their old hosting provider to my own managed WP Engine hosting service.</p>



<p>Let&#x2019;s get started.</p>



<h2 class="wp-block-heading">Prerequisites</h2>



<ul>
<li>Access to the existing WordPress site&#x2019;s admin panel</li>



<li>WP Engine account with appropriate permissions</li>
</ul>



<h2 class="wp-block-heading">Migration Using WP Engine Migration Assistant Plugin</h2>



<p>This is how you utilize the WP Engine Migration Assistant Plug in to migrate just about any WordPress site to your WP Engine hosting account.</p>



<h3 class="wp-block-heading">Step 1: WP Engine Plugin Installation</h3>



<ol>
<li>Log into the existing/source WordPress site.</li>



<li>Navigate to <code>Plugins -&gt; Add New</code> on the WordPress Dashboard.</li>



<li>Search for <code>WP Engine Automated Migration</code>. Or you can <a href="https://wordpress.org/plugins/wp-site-migrate/?ref=clintmcmahon.com" data-type="link" data-id="https://wordpress.org/plugins/wp-site-migrate/">download the plug in here</a>.</li>



<li>Click <code>Install</code> and then <code>Activate</code>. </li>
</ol>



<h3 class="wp-block-heading">Step 2: Retrieve Migration Credentials</h3>



<ol>
<li>Log in to the WP Engine User Portal.</li>



<li>Create the new site environment if you have not already done so. </li>



<li>Navigate to new WP Engine site and click<code> Migrations</code> in the left side navigation menu.</li>



<li>You&#x2019;ll see a screen that looks like this one below. Here you see the site properties that you&#x2019;ll need to input into the source/existing website migration plug in. You can generate the migration SFTP credentials here if you have not already done so.</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="711" src="https://www.clintmcmahon.com/content/images/wordpress/2023/09/Screenshot-2023-09-18-at-4.20.42-PM-1024x711.png" alt="How To Migrate WordPress Websites to WP Engine" class="wp-image-1245"></figure>



<h3 class="wp-block-heading">Step 3: Plugin Configuration</h3>



<ol>
<li>On the existing/source WordPress Dashboard, go to<code> WP Engine Migratio</code>n from the left side navigation.</li>



<li>Input the migration credentials from Step 2.</li>



<li>Click <code>Start Migration</code>.</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="717" src="https://www.clintmcmahon.com/content/images/wordpress/2023/09/Screenshot-2023-09-18-at-4.20.25-PM-1024x717.png" alt="How To Migrate WordPress Websites to WP Engine" class="wp-image-1248"></figure>



<h3 class="wp-block-heading">Step 4: Monitoring and Verification</h3>



<ol>
<li>Monitor migration status in the WP Engine User Portal.</li>



<li>You&#x2019;ll receive a confirmation email upon successful migration.</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="692" src="https://www.clintmcmahon.com/content/images/wordpress/2023/09/Screenshot-2023-09-18-at-4.22.38-PM-1024x692.png" alt="How To Migrate WordPress Websites to WP Engine" class="wp-image-1246"></figure>



<h3 class="wp-block-heading">Step 5: DNS Update</h3>



<ol>
<li>Now update the DNS records to point to WP Engine&#x2019;s IP address or CNAME records.</li>
</ol>



<h2 class="wp-block-heading">Conclusion</h2>



<p>This blog post provides a step by step approach for migrating a WordPress website from any provider to WP Engine utilizing the WP Engine Migration plug in.</p>



<p>For more specialized migration services or hosting solutions, feel free to contact me. Happy migrating!</p>
<!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Moving Docker SQL Server databases between machines]]></title><description><![CDATA[In this blog post I'll show how I migrated my SQL Server databases between machines and Docker containers.]]></description><link>https://www.clintmcmahon.com/move-sql-server-between-development-machiens/</link><guid isPermaLink="false">64df960b79919e0001b50d29</guid><category><![CDATA[docker]]></category><category><![CDATA[sql server]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Thu, 31 Aug 2023 14:59:30 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1605745341075-1b7460b99df8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fGRvY2tlcnxlbnwwfHx8fDE2OTM0OTM5NDd8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1605745341075-1b7460b99df8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fGRvY2tlcnxlbnwwfHx8fDE2OTM0OTM5NDd8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Moving Docker SQL Server databases between machines"><p>I&apos;m in the middle of migrating all my apps and databases to a new Macbook Air machine. Since I do all my .Net Core development on MacOS I use Docker containers to manage any SQL Server databases that I&apos;m working with. In this blog post I&apos;ll show how I migrated my SQL Server databases between machines and Docker containers.</p><h2 id="create-a-database-backup-on-machine-1">Create a database backup on machine 1 </h2><p>I used Azure Data Studio to manage SQL Server databases from my Mac. Azure Data studio is a fine substitute for SQL Server Management Studio, but it lakes the majority of the features. Though I&apos;ll take the lack of features for the ability to development on my macOS machine any day. </p><p>To back up a database from Azure Data Studio, connect to your server, navigate to the database and right click the database. Then select the Backup option from the drop down menu. Select the options you need and click <strong>Backup</strong>. Take not of the <strong>Backup files </strong>location as you&apos;re going to need this to copy the file from the Docker container to your local machine. Here my backup copy will be made in <code>/var/opt/mssql/data</code> folder within the current Docker container.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-18-at-11.11.25-AM.png" class="kg-image" alt="Moving Docker SQL Server databases between machines" loading="lazy" width="724" height="754" srcset="https://www.clintmcmahon.com/content/images/size/w600/2023/08/Screenshot-2023-08-18-at-11.11.25-AM.png 600w, https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-18-at-11.11.25-AM.png 724w" sizes="(min-width: 720px) 720px"><figcaption>Use Azure Data Studio to backup a database</figcaption></figure><h2 id="copy-the-database-backup-to-a-central-location">Copy the database backup to a central location</h2><p>Now using the Docker command <code>docker cp</code> copy the the database backup file from the Docker container to your local machine and then to a central location where you can access the backup file from the destination machine. </p><ol><li>Open the Docker dashboard on the source machine, locate the SQL Server container, then copy the container id. </li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-18-at-11.18.40-AM.png" class="kg-image" alt="Moving Docker SQL Server databases between machines" loading="lazy" width="956" height="340" srcset="https://www.clintmcmahon.com/content/images/size/w600/2023/08/Screenshot-2023-08-18-at-11.18.40-AM.png 600w, https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-18-at-11.18.40-AM.png 956w" sizes="(min-width: 720px) 720px"><figcaption>Locate SQL Server container</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-18-at-11.18.55-AM.png" class="kg-image" alt="Moving Docker SQL Server databases between machines" loading="lazy" width="966" height="208" srcset="https://www.clintmcmahon.com/content/images/size/w600/2023/08/Screenshot-2023-08-18-at-11.18.55-AM.png 600w, https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-18-at-11.18.55-AM.png 966w" sizes="(min-width: 720px) 720px"><figcaption>Copy the container id</figcaption></figure><p>2. &#xA0;Open Terminal and execute the <code>docker cp</code> command with the following parameters: {yourContainerId}:{containerBackupFileLocation} {destinationFolder}<br></p><pre><code class="language-bash">docker cp cbd5323d5caf78c9b7434ff46eccbba0b5c20e2e4807d71fd83a6394372fc1c0:/var/opt/mssql/data/Machine-1-2023818-11-11-11.bak ~/code</code></pre><p>3. &#xA0;This will copy the .bak file from the previous step into a folder called <code>code</code> on your local machine. Make sure the destination folder <code>code</code> exists before you run this command.</p><p>4. Transfer the .bak to a central location that the new machine can access. Something like Dropbox or shared filed location is good. And then download the file to the new machine. </p><p>5. Run the following command from the new machine to create the backup folder within the new Docker Container. <code>sql</code> is the name of the new SQL Server container running on the new machine.</p><pre><code class="language-bash">sudo docker exec -it sql mkdir /var/opt/mssql/backup</code></pre><p>6. Run the following command on the new machine to copy the database from your new machine into the new SQL Server container. Replacing `Machine 1-2023818-11-11-11.bak` with the name of your backup file.</p><pre><code class="language-bash">sudo docker cp Machine-1-2023818-11-11-11.bak sql:/var/opt/mssql/backup</code></pre><p>7. Open Azure Data Studio, right click on your database name and select <code>restore</code>. The current version of Azure Data Studio requires the database to exist before you can do a restore. If the database does not already exist, create a blank database to restore to. Navigate to the location inside the container that was created in the previous step.</p><figure class="kg-card kg-image-card"><img src="https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-31-at-9.51.21-AM.png" class="kg-image" alt="Moving Docker SQL Server databases between machines" loading="lazy" width="1010" height="811" srcset="https://www.clintmcmahon.com/content/images/size/w600/2023/08/Screenshot-2023-08-31-at-9.51.21-AM.png 600w, https://www.clintmcmahon.com/content/images/size/w1000/2023/08/Screenshot-2023-08-31-at-9.51.21-AM.png 1000w, https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-31-at-9.51.21-AM.png 1010w" sizes="(min-width: 720px) 720px"></figure><p>That should do it. You are now able to use the old database. I actually ran into an issue during this process where the containers I was using for my new M1 machine were too far ahead of the existing database that I was trying to transfer over. So keep in mind that depending on the container you are using, certain versions of SQL Server might not be compatible between Docker instances.</p>]]></content:encoded></item><item><title><![CDATA[Armchair Expert Books]]></title><description><![CDATA[Or how to get the cover for a book programmatically. In the Armchair Expert Media Explorer is a website I built to track all the book, movies, documentaries, podcasts and shows that are discussed on Armchair Expert between the hosts, Dax and Monica, and their guests. ]]></description><link>https://www.clintmcmahon.com/armchair-expert-books/</link><guid isPermaLink="false">64d1531c829439000161f08d</guid><category><![CDATA[Armchair Expert]]></category><category><![CDATA[c#]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Mon, 07 Aug 2023 20:55:09 GMT</pubDate><media:content url="https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-07-at-3.28.14-PM.png" medium="image"/><content:encoded><![CDATA[<img src="https://www.clintmcmahon.com/content/images/2023/08/Screenshot-2023-08-07-at-3.28.14-PM.png" alt="Armchair Expert Books"><p>Or how to get the cover image of a book programmatically. The <a href="https://armchairmediaexplorer.com/?ref=clintmcmahon.com">Armchair Expert Media Explorer</a> is a website I built to track all the book, movies, documentaries, podcasts and shows that are discussed on the Armchair Expert podcast between the hosts, Dax and Monica, and their guests. For each book that is entered into the database, I make a call to an API to get the book cover image. This blog post will show how to get the cover image of a book programmatically using C# and a third party API.</p><h2 id="call-the-getbook-method">Call the GetBook method</h2><p>I&apos;m using the <a href="https://openlibrary.org/developers/api?ref=clintmcmahon.com">OpenLibrary API</a> to retrieve book covers for newly added books. The process to return a book cover image is two steps. Firstk call the search endpoint to search for a book by its title and author. The object returned will contain a variable called <code>CoverI</code> which is identifies the cover image for the book. </p><p>The second step in the process is to call the covers.openlibrary.org endpoint by passing the <code>CoverI</code> property returned from the first step in the url. You&apos;re able to tell the API what size cover image you want (ie S, M, L, XL) by appending the size to the end of the CoverI property - like <code>{book.CoverI}-M</code>. In my case I&apos;m asking for size medium. </p><p>Here you can see the starting point to get the book object. I first make a call to `GetBook` by passing in the title and the author as string variables. &#xA0; </p><pre><code class="language-csharp">var book = await GetBook(title, author);
    if (book != null &amp;&amp; book?.CoverI != 0)
    {
        var thumbnailUrl = $&quot;https://covers.openlibrary.org/b/id/{book.CoverI}-M.jpg&quot;;
    }</code></pre><h2 id="getbook-method">GetBook method</h2><p>The <code>GetBook</code> method takes title and author to make a <code>GET</code> request to the search endpoint of the OpenLibrary API. I&apos;m casting the response as <code>OpenLibraryBookResponse</code> which allows me to look at the returned list of documents. Note that <code>Docs</code> is a <code>List&lt;T&gt;</code> because the search returns books that match the search parameters. It&apos;s highly likely you will return multiple results from your searches.</p><p>In this case, if the title and author search comes up empty, I make another call to just search by the title. This pattern works for 99.99% of all books I&apos;m searching for.</p><pre><code class="language-csharp"> public async Task&lt;OpenLibraryBook&gt; GetBook(string title, string author)
    {
        using var httpClient = new HttpClient();
        var url = $&quot;https://openlibrary.org/search.json?author={HttpUtility.UrlEncode(author)}&amp;title={HttpUtility.UrlEncode(title)}&quot;;
        var response = await httpClient.GetAsync(url);
        var content = await response.Content.ReadAsStringAsync();
        var bookResponse = JsonConvert.DeserializeObject&lt;OpenLibraryBookResponse&gt;(content);

        if (bookResponse.Docs == null || bookResponse.Docs.Count() == 0)
        {
            Console.WriteLine(url);
            url = $&quot;https://openlibrary.org/search.json?q={HttpUtility.UrlEncode(title)}&amp;mode=everything&quot;;
            response = await httpClient.GetAsync(url);
            content = await response.Content.ReadAsStringAsync();
            bookResponse = JsonConvert.DeserializeObject&lt;OpenLibraryBookResponse&gt;(content);
            if (bookResponse.Docs == null || bookResponse.Docs.Count() == 0)
            {
                Console.WriteLine(url);
            }
        }
        return bookResponse.Docs.FirstOrDefault();
    }
   </code></pre><h2 id="openlibrarybook-class">OpenLibraryBook class</h2><p>This is the class representation of the OpenLibrary API response and book search results. Using <code>JsonConvert.DesrializeObject</code> will convert the JSON response into an object based on the classes below. Once the results has been deserialized into an object you can freely explore all of the properties.</p><pre><code class="language-csharp">using Newtonsoft.Json;

public class OpenLibraryBookResponse
{
    public int NumFound { get; set; }
    public int Start { get; set; }
    public bool NumFoundExact { get; set; }
    public OpenLibraryBook[] Docs { get; set; }
}

public class OpenLibraryBook
{
    [JsonProperty(&quot;key&quot;)]
    public string Key { get; set; }

    [JsonProperty(&quot;seed&quot;)]
    public string[] Seed { get; set; }

    [JsonProperty(&quot;type&quot;)]
    public string Type { get; set; }

    [JsonProperty(&quot;title&quot;)]
    public string Title { get; set; }

    [JsonProperty(&quot;title_suggest&quot;)]
    public string TitleSuggest { get; set; }

    [JsonProperty(&quot;title_sort&quot;)]
    public string TitleSort { get; set; }

    [JsonProperty(&quot;edition_count&quot;)]
    public int EditionCount { get; set; }

    [JsonProperty(&quot;edition_key&quot;)]
    public string[] EditionKey { get; set; }

    [JsonProperty(&quot;publish_date&quot;)]
    public string[] PublishDate { get; set; }

    [JsonProperty(&quot;publish_year&quot;)]
    public int[] PublishYear { get; set; }

    [JsonProperty(&quot;first_publish_year&quot;)]
    public int FirstPublishYear { get; set; }

    [JsonProperty(&quot;number_of_pages_median&quot;)]
    public int NumberOfPagesMedian { get; set; }

    [JsonProperty(&quot;lcc&quot;)]
    public string[] Lcc { get; set; }

    [JsonProperty(&quot;isbn&quot;)]
    public string[] Isbn { get; set; }

    [JsonProperty(&quot;last_modified_i&quot;)]
    public long LastModified { get; set; }

    [JsonProperty(&quot;ebook_count_i&quot;)]
    public int EbookCount { get; set; }

    [JsonProperty(&quot;ebook_access&quot;)]
    public string EbookAccess { get; set; }

    [JsonProperty(&quot;has_fulltext&quot;)]
    public bool HasFulltext { get; set; }

    [JsonProperty(&quot;public_scan_b&quot;)]
    public bool PublicScan { get; set; }

    [JsonProperty(&quot;ratings_count_1&quot;)]
    public int RatingsCount1 { get; set; }

    [JsonProperty(&quot;ratings_count_2&quot;)]
    public int RatingsCount2 { get; set; }

    [JsonProperty(&quot;ratings_count_3&quot;)]
    public int RatingsCount3 { get; set; }

    [JsonProperty(&quot;ratings_count_4&quot;)]
    public int RatingsCount4 { get; set; }

    [JsonProperty(&quot;ratings_count_5&quot;)]
    public int RatingsCount5 { get; set; }

    [JsonProperty(&quot;ratings_average&quot;)]
    public double RatingsAverage { get; set; }

    [JsonProperty(&quot;ratings_sortable&quot;)]
    public double RatingsSortable { get; set; }

    [JsonProperty(&quot;ratings_count&quot;)]
    public int RatingsCount { get; set; }

    [JsonProperty(&quot;readinglog_count&quot;)]
    public int ReadinglogCount { get; set; }

    [JsonProperty(&quot;want_to_read_count&quot;)]
    public int WantToReadCount { get; set; }

    [JsonProperty(&quot;currently_reading_count&quot;)]
    public int CurrentlyReadingCount { get; set; }

    [JsonProperty(&quot;already_read_count&quot;)]
    public int AlreadyReadCount { get; set; }

    [JsonProperty(&quot;cover_edition_key&quot;)]
    public string CoverEditionKey { get; set; }

    [JsonProperty(&quot;cover_i&quot;)]
    public int CoverI { get; set; }

    [JsonProperty(&quot;publisher&quot;)]
    public string[] Publisher { get; set; }

    [JsonProperty(&quot;language&quot;)]
    public string[] Language { get; set; }

    [JsonProperty(&quot;author_key&quot;)]
    public string[] AuthorKey { get; set; }

    [JsonProperty(&quot;author_name&quot;)]
    public string[] AuthorName { get; set; }

    [JsonProperty(&quot;author_alternative_name&quot;)]
    public string[] AuthorAlternativeName { get; set; }

    [JsonProperty(&quot;subject&quot;)]
    public string[] Subject { get; set; }
    [JsonProperty(&quot;publisher_facet&quot;)]

    public string[] PublisherFacet { get; set; }
    [JsonProperty(&quot;subject_facet&quot;)]

    public string[] SubjectFacet { get; set; }
    [JsonProperty(&quot;_version_&quot;)]

    public long Version { get; set; }
    [JsonProperty(&quot;LccSort&quot;)]

    public string LccSort { get; set; }
    [JsonProperty(&quot;author_facet&quot;)]

    public string[] AuthorFacet { get; set; }
    [JsonProperty(&quot;subject_key&quot;)]

    public string[] SubjectKey { get; set; }
}</code></pre><p>And that is it. If you use the <code>GetBook</code> method along with the supporting classes you should be able to programmatically get cover images of books from the OpenLibrary API.</p>]]></content:encoded></item><item><title><![CDATA[React Native: Loaded "env" configuration for the "production" profile: no environment variables specified.]]></title><description><![CDATA[This is a post to describe a fix for an error in React Native, specifically an Expo Bare project, that looks like "Loaded "env" configuration for the "production" profile: no environment variables specified". ]]></description><link>https://www.clintmcmahon.com/react-native-loaded-env-configuration-for-the-production-profile-no-environment-variables-specified/</link><guid isPermaLink="false">64cabcff1325c000012f5746</guid><category><![CDATA[react native]]></category><category><![CDATA[bugfix]]></category><dc:creator><![CDATA[Clint McMahon]]></dc:creator><pubDate>Fri, 04 Aug 2023 16:00:01 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1520410973988-f551cf36c60d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGNyYWNrZWQlMjBzY3JlZW58ZW58MHx8fHwxNjkxMDA4MjQxfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1520410973988-f551cf36c60d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGNyYWNrZWQlMjBzY3JlZW58ZW58MHx8fHwxNjkxMDA4MjQxfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="React Native: Loaded &quot;env&quot; configuration for the &quot;production&quot; profile: no environment variables specified."><p>This is a post to describe a fix for an error in React Native, specifically an Expo Bare project, that looks like &quot;Loaded &quot;env&quot; configuration for the &quot;production&quot; profile: no environment variables specified&quot;. </p><p>I ran into this bug trying to upgrade a client&apos;s React Native Android app. The app is built using Expo and I&apos;m using <code>eas</code> to build and submit both iOS and Android apps to their app stores. After I made a code change, I started a build using <code>eas build</code> but after the build started I remembered I didn&apos;t was logged into Expo with the wrong user account. So I killed the build process, logged out of my Expo account, opened a new terminal and logged into the Expo CLI with the right credentials.</p><p>I ran a new <code>eas build</code> but the build failed with the following error:</p><pre><code class="language-bash">&#x2714; Select platform &#x203A; Android
Loaded &quot;env&quot; configuration for the &quot;production&quot; profile: no environment variables specified. Learn more: https://docs.expo.dev/build-reference/variables/
You don&apos;t have the required permissions to perform this operation.

Entity not authorized: AccountEntity[ID] (viewer = RegularUserViewerContext[ID], action = READ, ruleIndex = -1)
Request ID: ID
    Error: GraphQL request failed.
</code></pre><p>I did some Googling and found <a href="https://github.com/expo/eas-cli/issues/1324?ref=clintmcmahon.com">this helpful Github post</a> which made me realize my mistake. When I started the first build using my own Expo account instead of the client&apos;s Expo account, the build process wrote a JSON property called <code>extra.eas.projectId</code> to the <code>app.json</code> file of my project. Because I didn&apos;t have a project under my Expo account that matched what I was trying to build, Expo created a new project with a new id in my account using with the value written to <code>extra.eas.projectId</code>. As soon as I deleted the <code>extra</code> property from <code>app.json</code> I was able to build the project successfully again. </p><p>At first I didn&apos;t think the error made any sense, but the more I thought about it you can see that &quot;Entity not authorized&quot; actually makes sense here - the first part about the <code>env</code> configuration is a little bit of a red herring though. So what happened was Expo was trying to build my project under an Expo project that the current user didn&apos;t have access to. Which makes sense now. </p><p>So, in conclusion if you run into this error, delete this property from your <code>app.json</code> file and do a new <code>eas build</code> command. The new command will create a new <code>extra.eas.projectId</code> with the appropriate project id and you&apos;ll be golden.</p><pre><code class="language-json">&quot;extra&quot;: {
      &quot;eas&quot;: {
        &quot;projectId&quot;: &quot;12345678-1234-1234-be5b-f844590a0aad&quot;
      }
    }</code></pre>]]></content:encoded></item></channel></rss>