<?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[The Finley  Code ]]></title><description><![CDATA[Where music, copyright and code intersect and everything in between.]]></description><link>https://thefinleycode.com/</link><image><url>https://thefinleycode.com/favicon.png</url><title>The Finley  Code </title><link>https://thefinleycode.com/</link></image><generator>Ghost 3.41</generator><lastBuildDate>Sat, 11 Oct 2025 05:46:02 GMT</lastBuildDate><atom:link href="https://thefinleycode.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Get your dev new hires to contribute faster with onboarding documentation]]></title><description><![CDATA[For centuries, the human race has been documenting wars, successes, failures, recipes, and inventions so why should onboarding documents be any different]]></description><link>https://thefinleycode.com/dev-onboarding/</link><guid isPermaLink="false">6029e52ffaf90093100ab175</guid><category><![CDATA[coding]]></category><category><![CDATA[The Finley Code]]></category><category><![CDATA[onboarding]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Wed, 24 Feb 2021 05:29:23 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/onboarding.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/onboarding.jpg" alt="Get your dev new hires to contribute faster with onboarding documentation"><p>You just hired a new software developer and you want them to contribute right away? Of course, who doesn't. But that begs the question do you have onboarding documentation?</p>
<p>What I have found at different jobs is there is about a two-three month ramp up until I have felt really comfortable with the tech stack, intimately familiar with the codebase, the software used, platform architecture, etc. The one thing in common at each of these companies was limited or no onboarding documentation.</p>
<p>However, I don't think it has to take this long, in fact I believe that if you have solid onboarding documentation and a process to usher in new talent you could significantly decrease the amount of time new developers spend getting acclimated</p>
<h3 id="whatisitandwhyshouldicare">What is it and why should I care?</h3>
<p>Onboarding, also known as organizational socialization, as defined by Wikipedia, is the</p>
<blockquote>
<p>&quot;mechanism through which new employees acquire the necessary knowledge, skills, and behaviors in order to become effective organizational members and insiders. It is the process of integrating a new employee into the organization and its culture&quot;.</p>
</blockquote>
<p>I believe that one of these mechanisms is <strong>Onboarding Documentation</strong>. I would even go so far to say it is critical in the success of the team and honestly helps with the overall experience of new hires.</p>
<p>I have first hand experience on how the lack of onboarding docs affects developer efficiency and even moral.  I have been at companies where the onboarding documents were limited or scattered and multiple new hires have started and they were literally swimming in circles because they couldn't find anything or need another developer to walk through <em>ALL</em> of the setup.</p>
<p>I have heard excuses like oh its &quot;tribal knowledge&quot; or  &quot;nobody wants to maintain docs&quot; or &quot;onboarding docs? what are those?&quot;. WOW!!   I mean I am all for laziness but only if it comes on the back of preparation. Because after all efficiency is addressing an issue, minimizing the downstream effect and thus creating room for other optimizations. In other words just create your onboard docs and you will have more productive engaged devs quicker!</p>
<h3 id="whyshouldi">Why should I?</h3>
<p>Don't just take my word, there is a lot of research and articles out there, you should care because:</p>
<blockquote>
<p>Improving developer efficiency has the potential to increase global GDP by $3 trillion.  -Developer Coefficient</p>
</blockquote>
<p>Having quality onboarding docs could affect long term retention.</p>
<blockquote>
<p>In a study of over 1000 workers 31% left after six months citing the top reasons for leaving were a poor onboarding experience. -Bonusly</p>
</blockquote>
<blockquote>
<p>69% of employees are more likely to stay with a company for three years if they experienced great onboarding.  -SHRM</p>
</blockquote>
<h3 id="possibleimplementationstrategies">Possible Implementation Strategies</h3>
<p>For centuries, the human race has been documenting wars, successes, failures, recipes, and inventions so why should onboarding documents be any different. Plus given the benefits mentioned above take charge and just do it.</p>
<h4 id="ideastogetstarted">Ideas to get started:</h4>
<ol>
<li>Speak with stake holders/team leads about where they send new hires looking for documentation and then create a document to track all of those answers</li>
<li>Start with some sort of Wiki document located in an easy central place. In my job we have a central WIKI document in our main code repository were we direct all new hires to and yes I was the one to start the first onboarding document</li>
<li>Create an onboarding checklist. Things in this checklist could include: All technologies to install and download, important links to code README's, build/deploy pipelines, and other misc documents like important hr docs, and internal communications</li>
<li>Create at least one &quot;how-to&quot; on setting up environments. In my job we have at least four different platform environments all using different tech stacks and it gets hairy quick. Documenting it is the easiest way to safeguard against knowledge gaps and to make sure all the teams members can be self-sufficient</li>
<li>If you don't have any formal onboarding process at least start with having another developer sit with the new hire and help get them all set up</li>
<li>Remember onboarding docs are living and breathing so find ways to keep them updated. A few suggestions to ensure this happens:<br>
When any new environments are created or new technologies are added make it a requirement that setup instructions are required</li>
<li>Have a designated person to keep the document updated. If you make the newest developer to the team in charge of this they will have immediate knowledge</li>
<li>Any new hires you bring onboard, have them update the onboarding checklist if there are pieces they are missing or new as they go through the steps. This gives them buy in and ownership on the first day.</li>
</ol>
<p>So go forth and create (or update) YOUR onboarding documents and remember:<br>
“You must be the change you want to see in the world.”  -Ghandi</p>
<hr>
<h5 id="shoutouts">Shout Outs</h5>
<ul>
<li><a href="https://www.linkedin.com/in/gabelevasseur/">Gabe Levasseur</a> for inspiration</li>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=d7lq-jgEFe4">Disco by Sub-Radio</a></li>
</ul>
<h5 id="resources">Resources:</h5>
<p><a href="https://www.atlassian.com/teams/hr/guide/employee-onboarding">Atlasssian Tips</a><br>
<a href="https://stripe.com/reports/developer-coefficient-2018">The Developer Coefficient</a><br>
<a href="https://blog.bonus.ly/10-surprising-employee-retention-statistics-you-need-to-know">Bonusly</a><br>
<a href="https://www.shrm.org/resourcesandtools/hr-topics/talent-acquisition/pages/dont-underestimate-the-importance-of-effective-onboarding.aspx">SHRM</a></p>
<p><a href="https://www.freepik.com/vectors/business">Business vector created by stories - www.freepik.com</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Two simple scripts to backup and restore CosmosDB]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>At my current company, we use Azure to manage our cloud infrastructure and they provide a lot of great resources and cloud solutions. However, creating a backup from a MongoDB based CosmosDB instance isn't very straight forward (if it is I missed it and please tell me where to look</p>]]></description><link>https://thefinleycode.com/easy-mongodb-azure-scripts/</link><guid isPermaLink="false">6029e52ffaf90093100ab172</guid><category><![CDATA[mongodb]]></category><category><![CDATA[azure]]></category><category><![CDATA[nosql]]></category><category><![CDATA[restore a db]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Fri, 09 Aug 2019 05:27:28 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/cosmosdb_mongo.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/cosmosdb_mongo.png" alt="Two simple scripts to backup and restore CosmosDB"><p>At my current company, we use Azure to manage our cloud infrastructure and they provide a lot of great resources and cloud solutions. However, creating a backup from a MongoDB based CosmosDB instance isn't very straight forward (if it is I missed it and please tell me where to look :). If you have a SQL instance easy peasy just go the export tab within in the DB, set a destination, provide login credentials and boom done. NoSql not so much. This is a quick and simple post on the two commands you can run to grab the data from your remote CosmosDB instance (running mongo) and then restore it to another/new CosmosDB instance</p>
<h3 id="theproblem">The problem</h3>
<ol>
<li>We needed to quickly make a copy of a specific CosmosDb production DB instance</li>
<li>We needed to restore a new CosmosDB instance</li>
</ol>
<h3 id="whatyouneed">What you need</h3>
<ol>
<li><a href="https://docs.mongodb.com/manual/installation/">Mongodb</a> installed, as the tool we are using, <code>mongodump</code> comes with mongodb</li>
<li>The <a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest">Azure cli</a> (and you will need to be logged in <code>az login</code>)</li>
</ol>
<h3 id="createabackup">Create a backup</h3>
<p>Run the script below to create a backup of all of the collections in your specified db instance to your local machine</p>
<pre><code>
$ mongodump --host &quot;$HOST_NAME&quot; -u &quot;$SOURCE_DB_ACCOUNT&quot; 
-p &quot;$SOURCE_PASSWORD&quot; --ssl --&lt;type-of-ssl-required&gt; 
--out ./backup --db=&quot;$SOURCE_DB&quot;

$ mongodump --host yourdbname.documents.azure.com --port 10255 
-u &lt;your-username&gt; -p &lt;password&gt; --ssl 
--&lt;type-of-ssl-required&gt; --out ./backup --db=&lt;your-db-name&gt;
</code></pre>
<ul>
<li>Figure 1 below shows where to get your <code>HOST_NAME</code>, <code>SOURCE_DB_ACCOUNT</code> and<code>SOURCE_PASSWORD</code>.</li>
<li>One way you can find your <code>SOURCE_DB</code> is by navigating to the <code>Data Explorer</code> tab (figure 2 below)</li>
</ul>
<h3 id="restoretoanewcosmosdb">Restore to a new CosmosDB</h3>
<p>Run the command below for each collection in your db instance and specifically pointing to the <code>bson</code> files for restoring</p>
<pre><code>$ mongorestore --host &quot;$DESTINATION_HOST_NAME&quot; -u &quot;$DESTINATION_DB_ACCOUNT&quot; 
-p &quot;$DESTINATION_PRIMARY_PASSWORD&quot; --db=&quot;$NEWLY_CREATED_DB_NAME&quot; 
--collection=&quot;$COLLECTION_NAME&quot; 
&lt;PATH_TO_YOUR_LOCAL_FILE&gt;/lms-seeds/&quot;$COLLECTION_NAME&quot;.bson 
--ssl --&lt;type-of-ssl-required&gt;
</code></pre>
<p><strong>IMPORTANT NOTES</strong>:</p>
<ul>
<li>Note that my db requires ssl as seen by the <code>--ssl</code> flag. As such you need to pass that parameter and a second one to specify what type ssl configuration to use to authenticate. See the <a href="https://docs.mongodb.com/manual/tutorial/configure-ssl-clients/">Mongo SSL Docs</a> for more information.</li>
<li>If there is absolutely no possible way for intrusion and you system is highly secure you can use the <code>sslAllowInvalidCertificates</code>, but it is discouraged.</li>
</ul>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1565326993/Cosmos_Data_1_gjoqv3.png" alt="Two simple scripts to backup and restore CosmosDB"><br>
<em>--figure 1: Azure Cosmos DB</em></p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1565327461/Cosmos_dataexplorer_yjnjrs.png" alt="Two simple scripts to backup and restore CosmosDB"><br>
<em>-- figure 2: Azure Data Explorer</em></p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li><a href="https://dribbble.com/evandeininger">Evan Deininger</a> for the inspiration</li>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=8IOT9Zal0N0">Tycho - Division (Heathered Pearls Remix)</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Exposing Home Assistant to the world]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This is the second post in a series of posts about Home Assistant and Alexa. In my previous post - <a href="https://thefinleycode.com/home-automation-with-homeassistant-and-alexa/">Home Automation with Home Assistant and Alexa</a> I discussed how to wire up your Raspberry Pi with the open source IOT platform Home Assistant to work with Alexa. This post</p>]]></description><link>https://thefinleycode.com/writing-custom-alexa-skill-for-home-assistant/</link><guid isPermaLink="false">6029e52ffaf90093100ab170</guid><category><![CDATA[home-automation]]></category><category><![CDATA[home-assistant]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Sun, 28 Jul 2019 07:59:12 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/home_assistant.svg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/home_assistant.svg" alt="Exposing Home Assistant to the world"><p>This is the second post in a series of posts about Home Assistant and Alexa. In my previous post - <a href="https://thefinleycode.com/home-automation-with-homeassistant-and-alexa/">Home Automation with Home Assistant and Alexa</a> I discussed how to wire up your Raspberry Pi with the open source IOT platform Home Assistant to work with Alexa. This post will cover:</p>
<ol>
<li>Upgrading Hass.io to take advantage of the new <code>ADD-ON STORE</code></li>
<li>Adding DNS and port forwarding to make Home Assistant publicly accessible</li>
</ol>
<h5 id="upgradehassio">Upgrade Hass.io</h5>
<ul>
<li>Visit the <a href="https://www.home-assistant.io/hassio/installation/">Hassio Installation site</a> to download the current Hass.io image.</li>
<li>Once you flash the image onto your micro sd (from your computer) and boot up your Pi, it can take up to 20 minutes to get rocking.</li>
<li>After a successful boot, you can visit: <a href="http://hassio.local:8123/">http://hassio.local:8123/</a> to get started and follow the onscreen instructions.</li>
</ul>
<h5 id="addthesshserveraddon">Add the SSH Server Add-On</h5>
<ul>
<li>In order to make changes via SSH to your PI you will want to add the SSH Server add on</li>
<li>To do this, while on your hassio dashboard click on the <code>Hass.io</code> icon in the mid-left-hand side panel</li>
<li>Then click on the <code>ADD-ON STORE</code> and the select <a href="https://www.home-assistant.io/addons/ssh/">SSH Server</a> and click <code>Install</code></li>
<li>Follow the steps there to configure (you will need to create an SSH Key) and SSH into your Rasberry PI</li>
<li>If you have issues connecting make sure you have started the SSH server from the SSH Server details page (see image below)</li>
<li>This piece must be completed before the DNS piece as this is needed to finish setting up DNS below</li>
</ul>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1564300154/SSH_Server_Hassio.png" alt="Exposing Home Assistant to the world"></p>
<p><strong>A few helpful commands</strong></p>
<ul>
<li>To SSH into your pi: <code>ssh root@hassio.local</code> (Home Assistant exists at <code>/config</code> directory)</li>
<li><code>hassio help</code> will list all of your commands</li>
<li><code>hassio host reboot</code> - reboot your pi</li>
</ul>
<h5 id="adddns">Add DNS</h5>
<p>We will be using Duck DNS for our domain and Let's Encrypt for our certs. One of the main reasons I updated to the new Hass.io image is because the new version has an<code>ADD-ON STORE</code> that includes a <a href="https://www.duckdns.org">Duck DNS</a> plugin with built-in <a href="https://letsencrypt.org/">Let's Encrypt</a> support.</p>
<ul>
<li>To install, navigate to the <code>ADD-ON STORE</code> again and select the Duck DNS add-on and click install (this set-up refers to version <code>1.8</code>)</li>
<li>Update the configuration in the add-on to include your Duck DNS token, your domain(s) and set the <code>accept_terms</code> to true. By setting this to true this is what will start generating your certs.</li>
</ul>
<pre><code>{
  &quot;lets_encrypt&quot;: {
    &quot;accept_terms&quot;: true,
    &quot;certfile&quot;: &quot;fullchain.pem&quot;,
    &quot;keyfile&quot;: &quot;privkey.pem&quot;
  },
  &quot;token&quot;: &quot;&lt;YOUR-TOKEN&gt;&quot;,
  &quot;domains&quot;: [
    &quot;&lt;YOUR-DOMAINS&gt;&quot;
  ],
  &quot;seconds&quot;: 300
}
```

* Then SSH into your PI and add the following to the `/config/configuration.yaml` file: 
```
# Example configuration.yaml entry for the HTTP component
http:
  base_url: https://example.duckdns.org:8123
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem
```

![Image Link](http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1564300164/DuckDNS_Hassio.png)

Reference article: [Effortless Encryption](https://www.home-assistant.io/blog/2017/09/27/effortless-encryption-with-lets-encrypt-and-duckdns/)

##### Last Step - Port forwarding
If you are using port 8123 you will need to configure port forwarding

* Login into your router and locate Port Forwarding sometimes called virtual server. You can use this website [port forward](https://portforward.com/) to locate your router and follow the instructions on how add forwarding
* Choose the port you specified in your configuration to forward
* You can test your port has been forwarded using a [Port Forwarding Tester](https://www.yougetsignal.com/tools/open-ports/)



######Navigate to your https://example.duckdns.org:8123 address and Woollahh!!**

![Image Link](https://media.giphy.com/media/OHZ1gSUThmEso/giphy.gif)

---
####Shout Outs

* [Shane Henning](https://www.linkedin.com/in/shane-henning-1a6909a9/) for the inspiration 


</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Deploying a Ghost Blog on AWS with Cloudfront]]></title><description><![CDATA[Want to use Ghost and AWS? This blog describes the steps needed to set up a Ghost blog on AWS with CloudFront caching, Route 53 setup and SSL AWS cert.]]></description><link>https://thefinleycode.com/deploying-a-ghost-blog-on-aws-with-cloudfront/</link><guid isPermaLink="false">6029e52ffaf90093100ab16e</guid><category><![CDATA[Ghost]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Bitnami]]></category><category><![CDATA[SSL]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Tue, 11 Dec 2018 07:42:39 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/aws_ghost-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/aws_ghost-1.jpg" alt="Deploying a Ghost Blog on AWS with Cloudfront"><p>Want to host your own blog on AWS? Don't want to use Wordpress? The Ghost platform is easy to use and comes with a lot right out of the box. This post will walk you through how to spin up a Ghost blog using:</p>
<ul>
<li>An AWS EC2 instance</li>
<li>A Ghost Bitnami AMI</li>
<li>CloudFront (for caching)</li>
<li>Route 53</li>
</ul>
<p><em>This post assumes that you already have an AWS account</em></p>
<h4 id="launchingtheghostami">Launching the Ghost AMI</h4>
<p>Find the image on the AWS marketplace, I used the <a href="https://aws.amazon.com/marketplace/pp/B00NPHLY8W">Bitnami image</a>, follow the onscreen instructions to first subscribe to the image and then launch the EC2 right from the same screens. Or you can go to the AMI tab within EC2 and launch from there.</p>
<p>When launching your instance keep in mind:</p>
<ul>
<li>Ghost needs a minimum of 1GB of memory to run so pick at least a <code>t2.micro</code>.</li>
<li>In the security group, make sure to allow incoming HTTP and set up a rule for SSH with your IP so you can SSH into it. Some security group <a href="https://www.stratoscale.com/blog/compute/aws-security-groups-5-best-practices/">best practices</a>.</li>
<li>Associate an <a href="http://enterprise.arcgis.com/en/server/latest/cloud/amazon/allocate-elastic-ip-and-associate-with-your-instance.htm">Elastic IP address</a> to your instance (this will allow you to keep the same public IP if your instance goes down or you need to stop and restart, etc.)</li>
</ul>
<h4 id="visityoursite">Visit your site</h4>
<p>After your EC2 is up and running, let's go visit your newly launched site.  Find your public IP on the dashboard and hit <code>&lt;public-IP&gt;/admin</code> or <code>&lt;public-IP&gt;/ghost</code>. Fingers crossed... and BAM! you should see your login page. The default username is <code>user@example.com</code>. There are two ways to find your password:</p>
<ol>
<li>You can find it in the logs within the first 24 hours - while on your AWS EC2 dashboard select the instance and select <code>Actions -&gt; Instance Settings -&gt; Get System Logs</code> or</li>
<li>You can SSH into your box and look at the logs using <code>cat ./bitnami_credentials</code></li>
</ol>
<p>**TO SSH into your EC2 you select your instance from the AWS EC2 console and select <code>Connect</code>. It will give you instructions on how to get into your box.</p>
<h4 id="cloudfront">CloudFront</h4>
<p>Now that you have your site running on the public-ip address it is time to add CloudFront to the mix. Navigate to the CloudFront dashboard and create a distribution. Below are the key pieces you need to get your EC2 instance to work with CloudFront:</p>
<ol>
<li>In the <code>Origin Domain Name</code> field put the full public IP of your instance which is in the format: <code>ec2-.....amazonaws.com</code>.</li>
<li>Forward your <code>Host</code> header to the Origin in order to make sure your vanity url doesn't redirect to your <a href="https://aws.amazon.com/premiumsupport/knowledge-center/configure-cloudfront-to-forward-headers/">public IP</a> <img src="http://res.cloudinary.com/thefinleycode/image/upload/c_scale,h_223/v1544512290/Screen_Shot_2018-12-10_at_11.08.10_PM_aeovux.png" alt="Deploying a Ghost Blog on AWS with Cloudfront"></li>
<li>Put your URL in the <code>Alternate Domain Names</code> section</li>
<li>To set up your SSL Cert click the <code>Request or Import a Certification with ACM</code> - you will have to come back to this CloudFront page once the certification has been verified by AWS to add your cert</li>
<li>Leave the other options as default and create the distribution. When back on the dashboard make note of the <code>Domain Name</code> as you will need it for Route 53. Also note that it can take up to 15-30 minutes to create the distribution.</li>
</ol>
<p>**Great step by step to <a href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html#GettingStartedCreateDistribution">CloudFront distributions</a></p>
<h4 id="route53">Route 53</h4>
<p>In order to use Route 53, you will need to have your domain managed by AWS. If you don't you may need to transfer your domain management to AWS or use your current provider (although the directions here only apply if your domain is a hosted zone with AWS).</p>
<p><strong>Now let's add a custom URL</strong></p>
<ol>
<li>Navigate to your Route 53 dashboard and click <code>Hosted Zones</code></li>
<li>Create a new record set</li>
<li>Set your URL, I usually chose <code>blog.&lt;whateveryoursiteis&gt;.com</code></li>
<li>Set the <code>Type</code> to <code>A - IPV4 address</code></li>
<li>Select <code>Alias</code> to <strong>YES</strong></li>
<li>Then in <code>Alias Target</code> add the CloudFront domain name that was the result of the creation of the distribution from above and click save.</li>
<li>Keep the other options as default and save record set</li>
</ol>
<p>Once this is done, SSH into your instance and add the URL used above to your Ghost configuration file at <code>/opt/bitnami/apps/ghost/htdocs/config.production.json</code></p>
<p><img src="https://res.cloudinary.com/thefinleycode/image/upload/c_scale,h_109/v1544506175/ghost-config_iqpmao.png" alt="Deploying a Ghost Blog on AWS with Cloudfront"></p>
<p>**More info on the <a href="https://docs.ghost.org/concepts/config/">Ghost config</a></p>
<h4 id="sslcertificateforhttps">SSL Certificate for HTTPS</h4>
<p>It is important to add a certificate for security reasons. If you have followed the directions from above, your certificate will be processing or at this point verified and ready for use. To view your certificates you can go to your <code>Certificate Manager</code> dashboard.</p>
<p>Once your certificate is done processing:</p>
<ol>
<li>Go back to your CloudFront distribution and add your certificate from the dropdown list below the radio button <img src="http://res.cloudinary.com/thefinleycode/image/upload/v1544510625/CERT_ikuoin.png" alt="Deploying a Ghost Blog on AWS with Cloudfront"></li>
<li>Click save - again it may take a little bit for the distribution to update</li>
</ol>
<h4 id="setupemail">Set up email</h4>
<p>If you want to add additional Authors or Admins to your Ghost account you will need to set up SMTP forwarding. To do that SSH into your instance and go back into the config file <code>/opt/bitnami/apps/ghost/htdocs/config.production.json</code></p>
<p>You will need to add the following:<br>
<img src="http://res.cloudinary.com/thefinleycode/image/upload/v1544510894/Screen_Shot_2018-12-10_at_10.47.50_PM_jtkg44.png" alt="Deploying a Ghost Blog on AWS with Cloudfront"></p>
<p>Lastly, if you are sending from a gmail account you will also want to enable <a href="https://myaccount.google.com/lesssecureapps">Less Secure App</a>(You will need admin access to your account in order enable this). Further reading <a href="https://devanswers.co/allow-less-secure-apps-access-gmail-account/">here</a>.</p>
<p>**More on setting up/configuring Ghost <a href="https://docs.bitnami.com/aws/apps/ghost/configuration/configure-smtp/">email</a></p>
<p>You should be all set. Happy Trails!!</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>A special thanks to <a href="https://www.gabelevasseur.com/">Gabe</a> for his encouragement and support</li>
<li><a href="https://open.spotify.com/user/spotify/playlist/37i9dQZF1Ej8qcKNrWfKAw?si=t9BwCmdQRW2Ge0mCGBtkgA">Music</a> listened to while blogging</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Home Automation with Home Assistant and Alexa]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Do you have an Alexa and all you do is ask her to set a timer? It's time to put her skills to good use. Yep, that's right let's set up your house so you can say things like &quot;Alexa, turn on the bedroom lights&quot;. This blog post</p>]]></description><link>https://thefinleycode.com/home-automation-with-homeassistant-and-alexa/</link><guid isPermaLink="false">6029e52ffaf90093100ab167</guid><category><![CDATA[home-automation]]></category><category><![CDATA[raspberry-pi]]></category><category><![CDATA[alexa-skills]]></category><category><![CDATA[python]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Sat, 03 Feb 2018 00:59:45 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/blogpost_alexa_skill_2019.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/blogpost_alexa_skill_2019.jpg" alt="Home Automation with Home Assistant and Alexa"><p>Do you have an Alexa and all you do is ask her to set a timer? It's time to put her skills to good use. Yep, that's right let's set up your house so you can say things like &quot;Alexa, turn on the bedroom lights&quot;. This blog post will walk you through how to bring Alexa to life and take command of your home. There are plenty of gadgets and gizmos you can buy to set up your home with ease, but what would be the fun in that.</p>
<p>This post outlines all the necessary things you need to get Alexa to turn on your lights. Throughout this tutorial, I also include links to helpful articles because without these I would have been stuck.</p>
<h6 id="thispostwillcoverthefollowing">This post will cover the following:</h6>
<ol>
<li>The hardware needed to get started(at least what I am currently using)</li>
<li>Setting up Home Assistant on your Pi</li>
<li>Configuring Pi to receive radio signals</li>
<li>Wiring up your Pi with the transmitter and receiver</li>
<li>Finding radio signals on your Pi</li>
<li>Adding devices (in this tutorial lights)</li>
<li>Setting up Alexa</li>
</ol>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_339/v1499746692/Raspberry_pi_3.jpg" alt="Home Automation with Home Assistant and Alexa"></p>
<p>Before we begin, I'd like to point that there are two major open source platforms that I have found that you can use to get your system up and running. OpenHab and Home Assistant. After reading many blogs comparing the two I have decided to go with Home Assistant, partially because it is written in python which I find quite interesting.</p>
<p>&quot;Alexa lets get started&quot;</p>
<hr>
<h4 id="physicalitemsyouneedtogetstarted">Physical Items You need to get started</h4>
<p><em>The links listed below are from Amazon but you can get them from whatever vendor you prefer</em></p>
<ol>
<li><a href="https://www.amazon.com/gp/product/B01CD5VC92/ref=oh_aui_detailpage_o03_s00?ie=UTF8&amp;psc=1">Rasberry PI</a>. I am using a Rasberry PI 3 B+. This version has an HDMI (normal) input as well as 4 USB inputs, which makes it really easy to hook up a keyboard, mouse and a monitor or run headless(discussed below) ~ <strong>$36</strong></li>
<li><a href="https://www.amazon.com/gp/product/B01LZWFTPK/ref=oh_aui_detailpage_o03_s00?ie=UTF8&amp;psc=1">Jumper wires</a> to connect your transmitter/receiver to your Pi ~ <strong>$10</strong></li>
<li><a href="https://www.amazon.com/gp/product/B010Q57T02/ref=oh_aui_detailpage_o01_s00?ie=UTF8&amp;psc=1">A micro USB card</a> (used to load Hassbian discussed below ~ <strong>$14</strong></li>
<li><a href="https://www.amazon.com/gp/product/B00DQELHBS/ref=oh_aui_detailpage_o07_s00?ie=UTF8&amp;psc=1">Etek City</a> outlets that transmit/receive 433/hz signals ~ <strong>$30</strong></li>
<li><a href="https://www.amazon.com/gp/product/B01EFPX9XA/ref=oh_aui_detailpage_o01_s00?ie=UTF8&amp;psc=1">A SD card to usb adaptor</a> where you can 'flash' hasbian ~ <strong>$10</strong></li>
<li><a href="https://www.amazon.com/gp/product/B00HEDRHG6/ref=oh_aui_detailpage_o00_s00?ie=UTF8&amp;psc=1">433MHz RF Wireless Transmitter and Receiver Module</a> ~ <strong>$10</strong> (you can get the cheaper ones but I found that this set transmits much further)</li>
<li>An <a href="https://www.amazon.com/UGREEN-Reader-Memory-Windows-Simultaneously/dp/B01EFPX9XA/ref=sr_1_6?ie=UTF8&amp;qid=1517614040&amp;sr=8-6&amp;keywords=sd+card+to+usb">SD card reader</a> to flash your disk image to run the PI ~ <strong>$10</strong></li>
<li><a href="https://www.amazon.com/Amazon-Echo-Dot-Portable-Bluetooth-Speaker-with-Alexa-Black/dp/B01DFKC2SO/ref=sr_tr_sr_2?ie=UTF8&amp;qid=1517617156&amp;sr=8-2&amp;keywords=echo">Amazon Echo</a> ~ <strong>$50</strong></li>
<li><em>Optional</em>: A case for your PI.</li>
</ol>
<p>Total Cost: ~<strong>$170</strong></p>
<hr>
<h4 id="nowforhassbiansetup">Now for Hassbian setup</h4>
<p>Once all of your parts arrive follow the steps below:</p>
<ol>
<li>Using the SD USB card, flash the sd card with Hassbian (download it <a href="https://github.com/home-assistant/pi-gen/releases/tag/v1.31">here</a>) using <a href="https://etcher.io/">Etcher</a> (for mac or windows)</li>
<li>If you want to run in headless mode in the future (without a monitor or keyboard) you will also need to add a file to the boot drive titled <code>ssh</code> without any extension before ejecting from your computer. <a href="https://hackernoon.com/raspberry-pi-headless-install-462ccabd75d0">Reference article</a>.</li>
<li>Follow the instructions that came with your Pi to boot it up with your new SD card inserted into it</li>
<li>Make sure you plug a network cable directly into the PI from your router which will give it access to the internet.</li>
<li>Once it boots up, give the device at least 5-10 minutes to download Home Assistant.</li>
<li>To check to make sure Hassbian has been downloaded, you can check three different ways.
<ul>
<li>You can visit <code>http://hassbian.local:8123/</code> in your computer browser</li>
<li>You can find your <a href="https://www.raspberrypi.org/documentation/remote-access/ip-address.md">IP address</a> and then type it in your browser followed by <code>:8123</code> (ie: <code>10.0.0.1:8123</code>) and it should pull up the same page as before and should look something like the image below.</li>
<li>Lastly, you can <code>ssh</code> into your pi within the Terminal or shell client, using <code>ssh pi@&lt;your-ip&gt;</code>. While in your terminal and in ssh, see if this file path exists: <code>/home/homeassistant/.homeassistant</code>. If it does you are all set. Remember this last option because using <code>ssh</code> is how you will manage and configure your devices later on.</li>
</ul>
</li>
</ol>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1499310346/Screen_Shot_2017-07-05_at_9.47.49_PM_h5ipua.png" alt="Home Automation with Home Assistant and Alexa"></p>
<p>Done!... for now</p>
<hr>
<h4 id="installsoftwareonpitoreceiveradiosignal">Install software on Pi to receive radio signal</h4>
<p>I followed this tutorial to install the appropriate libraries: <a href="https://tutorials-raspberrypi.com/let-raspberry-pis-communicate-with-each-other-per-433mhz-wireless-signals/">Wiriing Pi</a>.<br>
Below are the steps as well.</p>
<ul>
<li>While using <code>ssh</code> on your PI, install <a href="http://wiringpi.com/download-and-install/">wiringPI</a>, cd into the directory and run the build command:</li>
</ul>
<pre><code>git clone git://git.drogon.net/wiringPi &amp;&amp; cd wiringPi &amp;&amp;./build

</code></pre>
<ul>
<li>
<p>Once installed if you run <code>gpio readall</code> should show the  gpio pin allocation on your PI.</p>
</li>
<li>
<p>Next, install a library that allows us to send out data via the transmitter and receive it through the receive module. This library is <a href="https://github.com/ninjablocks/433Utils">433Utils</a></p>
</li>
</ul>
<pre><code>$ cd back to your root
$ git clone --recursive 
$ git://github.com/ninjablocks/433Utils.git
$ cd 433Utils/RPi_utils
$ make all
</code></pre>
<p>You now have the software needed to listen for signals. On to wiring your Pi!</p>
<hr>
<h5 id="wireupthetransmitterandreceivertoyourpi">Wire up the transmitter and receiver to your Pi</h5>
<p>I will walk you through a brief set up on how to wire your Pi. For additional information, feel free to read Jeremy Cook's <a href="http://www.wired.co.uk/article/raspberry-pi-power-outlets-tutorial">article</a>.</p>
<ol>
<li>Before wiring up any of the transmitters, make sure your Raspberry Pi is powered off. You can use the command <code>sudo shutdown -h now</code> to power it down. Wait until the LED stops blinking and then unplug from power.</li>
<li>You can use the image below as a guide to wire up your pi and/or reference the article I mentioned above.</li>
</ol>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_573/v1499310669/pi_wiring.png" alt="Home Automation with Home Assistant and Alexa"></p>
<p>One step closer now!</p>
<hr>
<h5 id="preparepitofindyour433hzreceivers">Prepare Pi to find your 433/hz receivers</h5>
<p>Now that your Pi is all wired up let's start looking for signals</p>
<ol>
<li>Power up your Pi and <code>ssh</code> into it (or use your monitor set up)</li>
<li>Take your EteckCity outlets or comparable devices and plug them into a wall and figure out which number on the remote turns off which lights.</li>
<li>Let's test your Transmitter:</li>
</ol>
<pre><code>$ cd 433Utils/RPi_utils/ 
$ sudo ./RFSniffer

</code></pre>
<p>Then press the <code>on</code> or <code>off</code> button on the Etekcityremote and if it works you will see something like <code>Received 12345</code>.<br>
4. Next, let's test your Reciever:</p>
<pre><code>//open a new tab in terminal or ssh client
$ cd 433Utils/RPi_utils/ 
$ sudo ./codesend 1234  #whatever number you'd like
</code></pre>
<p>If it is working you will see something like <code>sending code[12345]</code>.<br>
5. Last but certainly not least you will need to install <code>rpi_rf</code> which allows Home Assistant to talk to your receivers. Follow instructions <a href="https://pypi.python.org/pypi/rpi-rf">here</a><br>
6. To sniff out your codes and after the <code>rpi_rf</code> is installed first double check to make sure python 3 is installed:</p>
<pre><code>$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install phython3-pip

``` 
7. Then create a python script `touch rfrx.py` which will record your receivers. 
8. Open this file by typing `sudo nano rfrx.py` and copy and paste the `rpi-rf` receive code found [here](https://github.com/milaq/rpi-rf/blob/master/scripts/rpi-rf_receive) and save it.
9. Then run `sudo python3 rfrx.py`, this will trigger your Pi to start listening for signals. 
10. Press the button on your remote and it will register the codes in the terminal (like below).
![Example Codes](http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1517616487/rpi-rf-image.png)

You are now ready to add lights configuration! 


---

####Now the best part, adding your devices
This is where the fun begins

__Lights__: 
In this post we will only set up lights. To set up lights I am using the `rf_rpi switch` api. [Doc Reference](https://home-assistant.io/components/switch.rpi_rf/).

1. To add devices cd into the following path in your Pi `/home/homeassistant/.homeassistant`. 
2. Then open your config file using `nano configuration.yaml`. The docs referenced above highlight what each attribute does, so no need to discuss that here. 
3. Below is an example of how I configured the switch API to set two lights in the living room and two lights in the bedroom: 
```
#settup rf lights
switch:
  platform: rpi_rf
  gpio: 17
  switches:
    bedroom_lights:
      pulselength: 181
      protocol: 1
      code_on: 341251, 335107
      code_off: 341260, 335116
      signal_repetitions: 50
    living_room_lights:
      pulselength: 178
      protocol: 1
      code_on: 333107, 333251
      code_off: 333116, 333260
      signal_repetitions: 50    
```
**You will use the codes you &quot;sniffed&quot; in the previous section and them to your config here. 

Once you have configured it how you want, you can restart HA by calling `sudo systemctl restart home-assistant@homeassistant.service`. You can also use the UI interface to restart HA. 
 
----

#### Lastly, and the best part, let's set up Alexa

1. Start by adding the [cloud component](https://home-assistant.io/components/cloud.alexa/)  from home assistant to your Pi. Follow the directions in the link above This feature just came out late 2017 and is free to use until March 1, 2018. After that is will cost $5 going to a good cause to keep the Home Assistant community growing.

2. Make sure you are running Home Assistant 6.0, you can check the version in the UI `http://hassbian.local:8123/dev-info`

3. Cd into your configruation.yaml again and add the `cloud` piece. See below for my sample setup. The link listed above goes into more explanation on each attribute. Again, no need to repeat it here. 

4. Once configured make sure you restart Home Assistant using the command listed above. Then as mentioned in the Home Assistant docs have you add the `Home Assistant` skill in the Alexa app. 

5. Once this is added and still in the Alexa app, navigate to the `Smart Home` tab, then click `Devices` and then click the button `Discover`. This should pull up the lights you configured previously. That's it! 

Sample config code
![cloud code](http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1517618838/cloudconfig.png)
Alexa Device Dashboard
![Alexa Device Dashboard](http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1517618646/AlexApp_Devices.png)

_&quot;Alexa, turn on the living room lights&quot;_ 

WHOLA!! You made it and now have lights controlled by Alexa. 

---

###### Helpful Home Assistant command line commands
1. SSH into your PI: `ssh pi@&lt;your-ip&gt;`.
2. 'To start, stop or check the status of home assistant: `sudo systemctl status home-assistant@homeassistant.service` and replace `status`, with `start` or `stop` or `restart`.
3. To check if your config file is properly set up:
```
$ sudo su -s /bin/bash homeassistant
$ source /srv/homeassistant/bin/activate
$ hass --script check_config
$ exit
```

[Common Tasks Docs](https://home-assistant.io/docs/installation/hassbian/common-tasks/)

---

####Shout Outs

* Music listened to while blogging: [&quot;Apollo&quot; by Magic Man](https://www.youtube.com/watch?v=D8MOcntooYc)
* [Raspberry Pi SSH](https://www.raspberrypi.org/documentation/remote-access/ssh/unix.md)
* Tutorials/Docs: 
  * [Hassbian Install Docs](https://home-assistant.io/docs/hassbian/installation/)
  * [Cloud Docs](https://home-assistant.io/components/cloud.alexa/) 
  * [Setting up the Eteckcity Outlets with Home Assistant](https://www.youtube.com/watch?v=5UUazFbK-Hg)
* [Stack overflow discussing keys for jessie backports](https://raspberrypi.stackexchange.com/questions/12258/where-is-the-archive-key-for-backports-debian-org)

</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[My attitude as described by a javascript function]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Essentially every day as a developer feels like this:</p>
<pre><code class="language-javascript">function happy(today){
    const coding=&quot;me&quot;+&quot;computer&quot;+&quot;coffee&quot;+&quot;creatingBetterExperiences&quot;;
    if(today === coding){
        alert(&quot;It's great day!&quot;);   
    }
}

happy(today);
</code></pre>
<!--kg-card-end: markdown-->]]></description><link>https://thefinleycode.com/my-js-attitude/</link><guid isPermaLink="false">6029e52ffaf90093100ab169</guid><category><![CDATA[Javascript]]></category><category><![CDATA[attitude]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Thu, 14 Sep 2017 03:03:59 GMT</pubDate><media:content url="http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_409/v1505357762/javascript-736400_640_rd6o8c.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_409/v1505357762/javascript-736400_640_rd6o8c.png" alt="My attitude as described by a javascript function"><p>Essentially every day as a developer feels like this:</p>
<pre><code class="language-javascript">function happy(today){
    const coding=&quot;me&quot;+&quot;computer&quot;+&quot;coffee&quot;+&quot;creatingBetterExperiences&quot;;
    if(today === coding){
        alert(&quot;It's great day!&quot;);   
    }
}

happy(today);
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[A solution for HTTP access control (CORS) issues]]></title><description><![CDATA[This post discusses CORS, what it is, why it's important, how I encountered CORS, and a solution to the problem using a server side route.]]></description><link>https://thefinleycode.com/a-solution-for-http-access-control-cors-issues/</link><guid isPermaLink="false">6029e52ffaf90093100ab161</guid><category><![CDATA[Journeyman Notes]]></category><category><![CDATA[http-access-control]]></category><category><![CDATA[Allow-Origin]]></category><category><![CDATA[CORS]]></category><category><![CDATA[Error-handling]]></category><category><![CDATA[songkick api]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Wed, 08 Mar 2017 04:14:12 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/errorCORS-updated.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/errorCORS-updated.png" alt="A solution for HTTP access control (CORS) issues"><p>A part of building new applications is running into errors and working to find solutions. I am currently working on an application that uses the <a href="https://www.songkick.com/developer">SongKick API</a> and the <a href="https://developer.spotify.com/">Spotify API</a> to generate Spotify playlists based on artists performing in the user location within date range preferences. The error that I encountered involves <code>Cross-Origin Resource Sharing</code> or <code>CORS</code>.  This post discusses CORS, what it is, why it's important, how I encountered CORS, and a solution to the problem.</p>
<h4 id="sowhatiscorsandwhyisitimportant">So what is CORS and why is it important?</h4>
<p>CORS (Cross-origin resource sharing) according to <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">wikipedia</a>:</p>
<blockquote>
<p><em>&quot;defines a way in which a browser and server can interact to determine whether or not it is safe to allow the cross-origin request. &quot;</em></p>
</blockquote>
<p>Further, in current browsers that implement <code>CORS</code> whenever information is requested from one webpage to another on different domains (the <code>cross-origin request</code>) there are certain credentials and permissions that must be provided by the user domain and the domain where the information is being requested from in order for the browser to allow the <code>cross-origin request</code>.  Most modern browsers implement <code>CORS</code> and it is currently the recommended standard of the W3C for accessing web resources that lie on different domains.</p>
<p>Why is it important? For your safety and the safety of others. No, really it's an important security concept that prevents CSS or Javascript to request resources from a different source and from preventing attacks from lurking hackers. To use an appropriate metaphor, modern web browsers are kind of like bouncers for a private club (the club being the domain you want info form), if you don't know the password you ain't getting in.</p>
<p>Fun fact: OWASP (Open Web Application Security Project) listed Cross-Site Scripting (one of the  most popular ways of bypassing the <code>same-origin request</code> policies) as number 3 on their <a href="https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project">top 10</a> list of threats in 2013 and <code>CORS</code> provides the framework and standardization to reduce this threat and grants companies the ability to share information without having to worry about being vulnerable to cyber attacks.</p>
<p>Here are a few more great resources to dive head first into <code>CORS</code>:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS">Mozilla Dev Network</a></li>
<li><a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Wikipedia</a></li>
<li><a href="https://www.maxcdn.com/one/visual-glossary/cors/">MaxCDN</a> - Gives a great step by step on how CORS works</li>
</ul>
<h4 id="mycorsissue">My CORS issue</h4>
<p>Let's look at how this plays out in real life. In the application I am developing,  <code>Songkick.com</code> has artist data that my site <code>discovershowcase.herokuapp.com</code> wants access to. This is considered a <code>cross-origin request</code> because the information being requested is not coming from the same domain. Traditionally, this wouldn't be allowed under browser's same origin policy. However, if <code>CORS</code> is supported, <code>Songkick.com</code> would include in its server response what are called <code>response headers</code>  allowing my site access to the data. The required header as a part of the <code>CORS</code> standard is <code>Access-Control-Allow-Origin</code> followed by either specific domains that can access the data or a <code>*</code> wildcard, indicating that any domain can access the data. Omitting this header will cause the CORS request to fail.</p>
<p>So, when I deployed my application to Heroku and tried using the application online, I received the following error:</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1487612466/XMLHTTPRequest_vwyl1v.png" alt="A solution for HTTP access control (CORS) issues"></p>
<p>This error is saying that the <code>Songkick.com</code> API is not responding with the appropriate header, <code>Access-Control-Allow-Origin</code> in order to allow my domain to communicate with it.</p>
<p>From this error and what we have just discussed about <code>CORS</code> it appears that <code>Songkick.com</code> does not implement CORS. After further research from what I can tell there are no plans for Songkick to implement CORS into their API anytime soon. So I had to find a way to &quot;bypass&quot; the <code>CORS</code> issue.</p>
<h4 id="howtofixthisthesolution">How to fix this - the solution</h4>
<p>To make my application work with <code>CORS</code> I have implemented the use of Node route to act as somewhat of a proxy server to get the data from API instead of going through the browser.</p>
<p>When I was getting the error initially, the information was being requested in the following manner:</p>
<p><code>My application =&gt; Browser =&gt; Songkick API =&gt; Browser =&gt; My application</code></p>
<p>And I was getting the error because Songkick wasn't providing Chrome (the bouncer) with the appropriate password. Instead, and after consultation with a mentor you can request information in the following way to bypass the browser at least initially which will avoid the <code>CORS header</code> issues:</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_960/v1488858834/How_To_Bypass_Browser_And_Avoid_CORS_issue_1_tghdsy.jpg" alt="A solution for HTTP access control (CORS) issues"></p>
<p>Let's look at some code to make sense of the diagram above</p>
<p>The first code snippet (figure 1) is the function that takes in parameters from the UI and will then call the Node route <code>&quot;/songkick&quot;</code>. When line 60 is encountered and the variable <code>queryURL</code> is called inside the <code>axios</code> GET request, this triggers the Node route which leads us to figure 2 (<a href="https://github.com/mzabriskie/axios">axios</a> is a great promise based http client).</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1488859541/Screen_Shot_2017-03-06_at_10.04.29_PM_dxwgtm.png" alt="A solution for HTTP access control (CORS) issues"><br>
<em>figure 1</em></p>
<p>Figure 2 is the abstracted route call using <code>express router</code> that directs the <code>&quot;/songkick&quot;</code> route to the <code>apiProxyController</code>  in figure 3.</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1488860782/Screen_Shot_2017-03-06_at_10.25.51_PM_dro6ck.png" alt="A solution for HTTP access control (CORS) issues"><br>
<em>figure 2</em></p>
<p>Here in figure 3, is where the Node route takes in the parameters from the <code>queryURL</code> variable from figure 1 in the form of <code>req.params</code> and is injected into the songkick api data request query (stored as the variable <code>url</code>). In line 30, a GET request is made using the <a href="https://github.com/request/request">request</a> library passing in the <code>url</code> as the parameter. This effectively bypasses the browser avoiding the <code>CORS</code> issue because the request is now coming from a server route not the browser.</p>
<p>Since this route is first called within the <code>getConcerts</code> function from figure 1, once the GET request finishes, the results are returned and dealt with inside the <code>.then((results)=&gt;{})</code> block in line 61, figure 1.</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1488896989/Screen_Shot_2017-03-07_at_8.28.53_AM_grz4ah.png" alt="A solution for HTTP access control (CORS) issues"><br>
<em>figure 3</em></p>
<h5 id="sothesolution">So the solution?</h5>
<ol>
<li>Create a server route that will be triggered by the user through the UI</li>
<li>Make sure it captures all appropriate parameters</li>
<li>Use an http request library like <a href="https://github.com/mzabriskie/axios">axios</a> or <a href="https://github.com/request/request">request</a> to make the request to the API in question (effectively bypassing the CORS issue)</li>
<li>Return the results to browser and handle the data.</li>
</ol>
<p>Note: You don't have to wrap a <code>request</code> call inside of an <code>axios</code>call, a server route by itself should do the trick. But in my instance, I already had quite a bit of code to handle to results inside of the axios call, so for now and until I refactor, this works for me.</p>
<p>Until next time...</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=MDRdikMNwi8">Youngr - &quot;Out Of My System&quot;</a></li>
<li><a href="https://www.songkick.com/developer">SongKick API</a></li>
<li><a href="https://developer.spotify.com/">Spotify API</a></li>
<li>Thanks to <a href="https://www.linkedin.com/in/brian-doyal-10bb953/">Brian Doyal</a> my Bootcamp Instructor and mentor for helping to diagnose and find a solution</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Node.Js and MySQL]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>As Week 11 and 12 wrapped up, I am officially half-way through the UT BOOTCAMP. Wow. I can definitely see the growth in my skills and knowledge level. The past two weeks were all about Node.js and MySql. Homework assignments for these two weeks were completed in the terminal</p>]]></description><link>https://thefinleycode.com/node-js-server-side-javascript-and-mysql/</link><guid isPermaLink="false">6029e52ffaf90093100ab15c</guid><category><![CDATA[UT Bootcamp]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Tue, 08 Nov 2016 19:16:23 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/eventloop.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/eventloop.jpg" alt="Node.Js and MySQL"><p>As Week 11 and 12 wrapped up, I am officially half-way through the UT BOOTCAMP. Wow. I can definitely see the growth in my skills and knowledge level. The past two weeks were all about Node.js and MySql. Homework assignments for these two weeks were completed in the terminal and are demonstrated here using tutorial videos. We got a lot to cover, so let's get to  learning and discovering.</p>
<h4 id="whatisnodejs">What is Node.js?</h4>
<p>Since Node is such a huge part of Javascript and our class, I feel it is important to dive in a little deeper here.</p>
<p>Node.js is an open source cross-platform runtime environment that is written using Javascript and as defined by it's <a href="https://nodejs.org/en/">documentation</a> is:</p>
<blockquote>
<p>&quot;A Javascript runtime built on Chrome's V8 Javascript engine&quot;</p>
</blockquote>
<p>Let's unpack this really quick:</p>
<ul>
<li><code>Javascript Runtime</code> = the environment that provides built-in libraries available at runtime (or execution time)</li>
<li><code>Javascript Engine</code> = responsible for producing the machine-executable operations from code written in Javascript</li>
</ul>
<p>As such Node.js and Chrome share the engine but have different runtime environments.</p>
<p>Since Node.js is cross-platform it can be run on OSX, Microsoft Windows, and Linux (which is a huge plus).</p>
<p><strong>Features</strong></p>
<ol>
<li>Asynchronous and Event Driven:</li>
</ol>
<ul>
<li><code>Asynchronous</code> or non-blocking, meaning that the server doesn't wait for an API to return data before moving on to the next piece of code. Once the API call has finished and is returned, Node.js will then handle it.</li>
</ul>
<ol start="2">
<li>Single-Threaded:</li>
</ol>
<ul>
<li>This means it uses a single thread model with event looping to handle requests. Also because the single-threaded model is non-blocking and can handle many requests at the same time, it makes this platform very scalable opposed to other servers like Apache that create multiple threads to handle requests. The image below captures how Node handles events.</li>
</ul>
<ol start="3">
<li>Speed:</li>
</ol>
<ul>
<li>It is very fast in its code execution since it runs on top of the Chrome Javascript Engine</li>
</ul>
<ol start="4">
<li>No buffering:</li>
</ol>
<ul>
<li>Node.js apps don't buffer any data, they just return them in managable data pieces.</li>
</ul>
<p>Example of how Node.js uses the event loop:<br>
<img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1478543645/eventloop_ezdxgf.jpg" alt="Node.Js and MySQL"></p>
<p><strong>When to use</strong></p>
<ul>
<li>Single Page Applications</li>
<li>Streaming Applications</li>
<li>JSON APIs based Applications</li>
<li>Server-Side Applications</li>
</ul>
<p>Another great resource for learning Node aside from the documentation mentioned above is <a href="https://www.tutorialspoint.com/nodejs/nodejs_introduction.htm">here</a>.</p>
<h4 id="nodepackagemoduleanddependencies">Node Package Module and Dependencies</h4>
<p>A Node Package Module is basically a packet of pre-built code (modules) that grant the user access to a library of functions or properties that give developers more tools, allow them to build programs faster and give them the ability to interact with other programs like MySql. They are often referred to as <code>dependencies</code> because if you choose to use say the <code>mysql</code> package in your project you must require the package withing your javascript file ie: <code>var mysql = require('mysql');</code> as you are 'dependent' on this module in order for your project to work.</p>
<p>A few helpful links:</p>
<ul>
<li><a href="https://docs.npmjs.com/getting-started/what-is-npm">NPM Info</a></li>
<li><a href="https://www.sitepoint.com/beginners-guide-node-package-manager/">Beginner's Guide</a></li>
</ul>
<p>One fun fact: Node's package ecosystem is one of the largest open source libraries in the world.</p>
<h4 id="whatismysql">What is MySql?</h4>
<p>MySql is an open source relational database built on the SQL architecture. It allows for the storage and retrieval of data. Think of it as a warehouse that stores all of your merchandise and you can send merchandise to your warehouse or retrieve it and send it somewhere else.</p>
<p>There is a lot more to MySql but we will stop here for now. For more in-depth reading the documentation is a great place to start: <a href="http://www.mysql.com/">MySql Documentation</a></p>
<p>Additionally, here is a great list of shortcut commands for <a href="https://gist.github.com/hofmannsven/9164408">SQL</a>.</p>
<h4 id="terminalhangman">Terminal Hangman</h4>
<p>Let's see Node.js in action. This hangman takes on the basic hangman rules (similar to the previous hangman I created) except this one cannot be played online, it can only be run on a local terminal.</p>
<p>In order to play on your computer you would have to do the following:</p>
<ol>
<li>Download my <a href="https://github.com/Nfinley/Week11-Hangman">Github Repo</a> to your computer</li>
<li>Make your way, <code>cd</code>, to the directory you just downloaded</li>
<li>Run <code>npm install</code> which will download all of the dependencies used</li>
<li>Run <code>node main.js</code> to play</li>
</ol>
<p>If you are not that ambitious you can  see a brief video below to see the result:<br>
<video poster="http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_604/v1477868909/week11-hangman_jfwzkz.png" preload="none" controls></video></p>
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_604/v1478545490/TerminalHangman_wjozzm.webm" type="video/webm">
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_604/v1478545490/TerminalHangman_wjozzm.mp4" type="video/mp4">
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_604/v1478545490/TerminalHangman_wjozzm.ogg" type="video/ogg">
   Your browser does not support HTML5 video tags

<p>Now that you have seen how it functions, how was it built?</p>
<p><strong>The build:</strong></p>
<p>The framework is built in Node.js and I have also used a few npm packages to achieve the look and feel. I have used the npm package <a href="https://www.npmjs.com/package/colors">Colors</a> which allows the user to call simple <code>.colorName</code> functions to change the color scheme on your screen. My favorite is <code>.rainbow</code> which is used in the category description. To make the terminal interface more user-friendly the npm package <a href="https://www.npmjs.com/package/inquirer">Inquirer</a> was used.</p>
<h4 id="bamazonstore">Bamazon Store</h4>
<p>This project displays a table of items that are available to the user to purchase. To build this, the framework used is Node.js and I used the Inquirer npm package again. The main difference here is that I used MySql to handle all of the data. The data that is displayed in the terminal is housed as a table in the database and every time the user purchases an item it decreases the available amount to purchase in the database.</p>
<p>Additionally, to prettify the table output I used the <a href="https://www.npmjs.com/package/cli-table">Cli-Table</a> npm package.</p>
<p>Here is a brief overview on how it works:<br>
<video poster="http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_729/v1477867716/BamazonCustomer_szcrmr.png" preload="none" controls></video></p>
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_729/v1477181002/BamazonCustomer_brz6jb.webm" type="video/webm">
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_729/v1477181002/BamazonCustomer_brz6jb.mp4" type="video/mp4">
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_729/v1477181002/BamazonCustomer_brz6jb.ogg" type="video/ogg">
   Your browser does not support HTML5 video tags

<p>Until next time... smile and be strong!!</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=PhvwaujlXoI">Bill Evans - Days of Wines and Roses</a></li>
<li><a href="https://nodejs.org/en/">Node.js Documentation</a></li>
<li><a href="http://www.mysql.com/">MySql Documentation</a></li>
<li><a href="https://docs.npmjs.com/getting-started/what-is-npm">NPM Documentation</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Journeyman Notes #5: Day With Your Dog - First Group Project]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>It has been too long!! Trying to get back on track to posting once every week or so. So to catch up let's chat about our first group project.  We have started and finished our first group project. Our idea: <em>Day With Your Dog</em>. It is a website that gives</p>]]></description><link>https://thefinleycode.com/daywithyourdog/</link><guid isPermaLink="false">6029e52ffaf90093100ab15a</guid><category><![CDATA[Journeyman Notes]]></category><category><![CDATA[UT Bootcamp]]></category><category><![CDATA[Day With Your Dog]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Sun, 30 Oct 2016 20:15:55 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/daywithyourdogscreenshot.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/daywithyourdogscreenshot.png" alt="Journeyman Notes #5: Day With Your Dog - First Group Project"><p>It has been too long!! Trying to get back on track to posting once every week or so. So to catch up let's chat about our first group project.  We have started and finished our first group project. Our idea: <em>Day With Your Dog</em>. It is a website that gives you all of the information you need to spend an entire day with your dog outside of your house. My team members and I really like this idea and found a need for it in the marketplace, so we continue working to iterate and improve on this idea even after we move on in class.  Read on for our mission, the problem it solves, and our minimum viable product and more.</p>
<h4 id="daywithyourdogprojectmission">Day With Your Dog - Project Mission</h4>
<p>In a world that is increasingly more dog-friendly and since they are man's best friend why not take them everywhere. Our mission is to provide a one-stop shop where dog owners can plan their day with their dog.</p>
<h4 id="problemitsolves">Problem it solves</h4>
<p>Our group all own dogs (see 'Our Inspiration' on our website) and while brainstorming we thought hey wouldn't it be convenient to have a place where you could go to plan an entire day where your dog can join too? That is how Day With Your Dog was born. Additionally, the day before my wife and I were trying to find a restaurant where we could bring our mini-schnauzer but had trouble finding one quickly and efficiently.</p>
<h4 id="targetaudience">Target Audience</h4>
<p>Our target audience is anyone who has access to the internet, owns a dog and wants to bring them everywhere!</p>
<h4 id="currentsolutions">Current Solutions</h4>
<p>There is on solution out there that is in direct competition with our app. That solution is <a href="http://barkhappy.com/">BarkHappy</a>. In fact, they are also based here in Austin, TX where we are based. With BarkHappy you can find other dogs nearby, explore dog-friendly places and events, host your own group play dates and it also gives lost and found alerts.</p>
<p>One con to BarkHappy is that it doesn't currently have a website that has the same functionality that their app does. Additionally, it appears restaurants are only added by users and don't take advantage of existing reviews from Google or Yelp.  There are also a few other solutions including <a href="https://dogvacay.com/">Dogvacay</a> and <a href="https://www.rover.com/">Rover</a> but they are more specialty type apps.</p>
<h4 id="assumptions">Assumptions</h4>
<p>With any new product, there are assumptions that you make and we need to test. I think the biggest assumption we are making is that there is a need for our service and that people will use this app. We are also assuming that our application will fill a gap in the market that doesn't currently exist.</p>
<h4 id="howwillsolutiontestassumptions">How will solution test assumptions?</h4>
<p><strong>Assumption 1</strong>: Need for this service in the marketplace</p>
<ul>
<li>We will test this assumption through user test cases and feedback. Based on the results we will incorporate any user feedback in furture iterations to help make our product more user-friendly.</li>
</ul>
<p><strong>Assumption 2</strong>: Our product will fill a gap in the market</p>
<ul>
<li>There are currently other products in the space so we will need to work to differentiate our product offering enough or do it better than the current provider. Based on user feedback and as our technical skill set grows we will be able to position ourselves for success.</li>
</ul>
<p>As will all initial releases of Minimum Viable Products our assumptions will most likely change after user feedback is received and may change the course of our product altogether. As such we need to be prepared to shift our focus.</p>
<h4 id="personalriskstoforyoutocompleteyourproject">Personal Risks to for you to complete your project</h4>
<p>In addition to assumptions, there are also personal risks. For me, I think the biggest risk to complete this application is the knowledge of how to make this a commercial grade application. For example, I currently haven't had any experience with user authentication and integration of map routing through Google. While this isn't a problem currently as we do not have a user section, I think this is a very important piece that will allow for success in the future. With time, however, I will be diving into these limitations and will then have the opportunity to upgrade our application.</p>
<h4 id="sketches">Sketches</h4>
<p>Here is our very first sketch of what Day With Your Dog:<br>
<img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_1142/v1477415318/dwydmockup_ee4wf5.jpg" alt="Journeyman Notes #5: Day With Your Dog - First Group Project"></p>
<h5 id="wireframes">Wireframes</h5>
<p>To get a better understanding of what we would be building we created a wireframe. I mocked this up quickly using the wire-framing software <a href="https://balsamiq.com/">Balsamiq</a>. As you can tell the first deliverable is much different but this process helped us to narrow down the functionality of what our app would do.<br>
<img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_730/v1477331937/DayWithDog_soypto.png" alt="Journeyman Notes #5: Day With Your Dog - First Group Project"></p>
<h4 id="oursolutiontheminimumviableproduct">Our Solution - the Minimum Viable Product</h4>
<p>Here is a brief walkthrough of how our app works.</p>
<video poster="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale%2Cw_1138/v1473654600/daywithyourdogscreenshot_zttivx.png" preload="none" controls>
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_919/v1477332099/DayWithYourDog_lxs3ai.mp4" type="video/webm">
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_919/v1477332099/DayWithYourDog_lxs3ai.mp4" type="video/mp4">
  <source src="http://res.cloudinary.com/thefinleycode/video/upload/c_scale,w_919/v1477332099/DayWithYourDog_lxs3ai.mp4" type="video/ogg">
   Your browser does not support HTML5 video tags
</video>
<p>To plan YOUR DAY WITH YOUR DOG click here: <a href="https://warm-mesa-10020.herokuapp.com/">Day With Your Dog</a> (limited to only Austin at the moment).</p>
<h4 id="futureiterations">Future Iterations</h4>
<p>While this is a crucial piece to our development we haven't done a large sampling of user feedback but plan too in the future. The iterations that we want to make based on the small sampling of feedback and also viability for our own sake are as follows:</p>
<ol>
<li>Create user login/profile where they can save preferences</li>
<li>Build a customer loyalty program</li>
<li>Partner with restaurants/parks/hotels, etc. to offer discounts or specials to our users</li>
<li>Build out our offerings to include:
<ul>
<li>Hotels, Shopping, Vet Clinics, Pet Stores, and Dog Boutiques</li>
</ul>
</li>
<li>Potentially have a dog meet up piece (however this is what BarkPappy specializes in)</li>
<li>Add a dog-walking integration with sites like <a href="https://www.rover.com/">Rover</a></li>
<li>Integration with <a href="http://www.opentable.com/start/home">Open Table</a> to reserve a table at dog-friendly restaurants</li>
<li>Integration with Instagram and have a running feed of owners dog posts</li>
<li>Currently, we are using a database to house the information on the page but ultimately want to either update it dynamically (when user's search) and/or allow user input</li>
</ol>
<p>While these additional implementations would be great we need to wait to see what the user feedback reveals and we have to be careful of scope creep (when you have <em>too</em> many features).</p>
<p>ENJOY and until next time...</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=kg9gjQnSCAw">Tycho - Epoch</a></li>
<li><a href="https://warm-mesa-10020.herokuapp.com/">Day With Your Dog</a></li>
<li>Day With Your Dog Group Members: <a href="https://www.linkedin.com/in/saidigranados">Saidi Granados</a> and <a href="https://www.linkedin.com/in/christinebaba?authType=NAME_SEARCH&amp;authToken=0mk_&amp;locale=en_US&amp;srchid=582947201477416352428&amp;srchindex=1&amp;srchtotal=6&amp;trk=vsrp_people_res_name&amp;trkInfo=VSRPsearchId%3A582947201477416352428%2CVSRPtargetId%3A184014488%2CVSRPcmpt%3Aprimary%2CVSRPnm%3Atrue%2CauthType%3ANAME_SEARCH">Christine Baba</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Journeyman Notes #4: Images not displaying - Found the fix]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Blogging is still such new territory and I am still discovering best methods on things like where and how to host images, how to update themes, how to manage and update Ghost (this blogging platform) and more. This post discusses the issue I had with images not displaying on any</p>]]></description><link>https://thefinleycode.com/journeyman-notes-4-images-not-displaying-found-the-fix/</link><guid isPermaLink="false">6029e52ffaf90093100ab151</guid><category><![CDATA[Journeyman Notes]]></category><category><![CDATA[Problem Solving]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Mon, 26 Sep 2016 03:17:37 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/zip-line-1209881_1280.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/zip-line-1209881_1280.jpg" alt="Journeyman Notes #4: Images not displaying - Found the fix"><p>Blogging is still such new territory and I am still discovering best methods on things like where and how to host images, how to update themes, how to manage and update Ghost (this blogging platform) and more. This post discusses the issue I had with images not displaying on any computer due to the inability of the browser to access them and the process I went through to fix the issue.</p>
<p>** <em>please note that this post was drafted a few months ago when I identified and fixed the image issue but I haven't have time to post it due to the UT Bootcamp.</em></p>
<h4 id="theissuenoimagesdisplaying">The Issue - No Images Displaying</h4>
<p>I first found this to be the case when I tested out my blog on other computers t and when my brother notified me that none of the images where displaying. This was an issue because the images and images of code, etc are very important to the storyline of my posts. So I hunkered down and looked for the root cause.</p>
<h4 id="researchtheissue">Research the issue</h4>
<p>I began hosting my images on Google drive because I had read that it would work, it was easy and free. So I followed the appropriate instructions to get a public folder up and running. But a few weeks in none were displaying in the browser.</p>
<p>So I went to the best 1st line of defense tool in the developers tool belt when dealing with the browser: the Chrome Inspector tool. I navigated to the console and low and behold I found my error:<br>
<img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1470538861/Blog%20Posts/Imageerrorlog.png" alt="Journeyman Notes #4: Images not displaying - Found the fix"></p>
<p>It was a <code>403 Forbidden</code> error, meaning the page or in this case the images that the browser was trying to access was absolutely forbidden. As a result none of my images were loading. I went back to the Google drive where was I hosting and re-read the instructions to set it up, made sure the url links worked but still couldn't get the images to load.</p>
<p>So I Google it!! I read a few posts about how there were issues with the Google drive throwing the exact errors that I was getting and how it may be best not to use this platform.</p>
<h4 id="resolution">Resolution</h4>
<p>So at the encouragement of blogger <a href="http://blog.jeff-owens.com/hosting-ghost-blog-images-with-cloudinary/">Jeff Owens</a> I signed up for <a href="http://cloudinary.com/">Cloudinary</a></p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1474857724/cloudinary_omagp3.png" alt="Journeyman Notes #4: Images not displaying - Found the fix"></p>
<p>This platform is free as long as you stay under 75,000 images and 7,500 images transformations a month, which is no problem for the volume I am dealing with. What I love about this platform is that is also allows you to resize your images and it updates the url link provided. Also Cloudinary is built for developers because it also provided links for various programming languages like Ruby, Python, Java and Node.js among others.</p>
<p>To add an image to my blog all I have to do is:</p>
<ol>
<li>
<p>Upload an image to my console in Cloudinary</p>
</li>
<li>
<p>Resize as desired</p>
</li>
<li>
<p>Drag and drop the url link into my post and it looks like this:</p>
<pre><code> http://res.cloudinary.com/thefinleycode/image/fetch/                     
 http://res.cloudinary.com/thefinleycode/image/upload/
 v1474857724/cloudinary_omagp3.png`
</code></pre>
</li>
</ol>
<p>Read more on how to <code>fetch</code> images using Cloudinary: <a href="http://cloudinary.com/documentation/fetch_remote_images">Fetch Images</a>.</p>
<h4 id="previouspostswithfreshimages">Previous Posts with Fresh Images</h4>
<p>So if you have read any of my previous posts and were missing images you can now go back and double check to see if the images appear :). Here are a few of my favorites:</p>
<ul>
<li><a href="http://thefinleycode.com/project-notes-muzak-archives-website-the-idea/">Muzak Archives Website -The Idea</a></li>
<li><a href="http://thefinleycode.com/finley-code-1-music-is-code/">Music is Code</a></li>
</ul>
<h4 id="otherawesomeimages">Other Awesome Images</h4>
<p>Speaking of images check out how awesome this CodePen of a 3d image is:</p>
<p data-height="507" data-theme-id="0" data-slug-hash="jEjbod" data-default-tab="result" data-user="infomanyak" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/infomanyak/pen/jEjbod/">tutorial rotate image 3d</a> by igor (<a href="http://codepen.io/infomanyak">@infomanyak</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<p>Using my own photo:</p>
<p data-height="628" data-theme-id="0" data-slug-hash="grBVVx" data-default-tab="result" data-user="Nfinleymusic" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/Nfinleymusic/pen/grBVVx/">3d Image Fun</a> by Nigel Finley (<a href="http://codepen.io/Nfinleymusic">@Nfinleymusic</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music Listened to while blogging: <a href="https://www.youtube.com/watch?v=BdF41Ne2cnQ">Kings of Leon: &quot;Walls&quot;</a></li>
<li><a href="http://cloudinary.com/">Cloudinary</a></li>
<li><a href="http://blog.jeff-owens.com">Jeff Owens Blog</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[33% Complete with Bootcamp - Week 7 & 8 done]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Can you believe it has already been 8 weeks since the start of this bootcamp?  We have covered so much in such a sort time. By no means am I an expert but I think I have a solid understanding of the concepts we have discussed and it will only</p>]]></description><link>https://thefinleycode.com/33-complete-with-bootcamp-week-7-8-done/</link><guid isPermaLink="false">6029e52ffaf90093100ab159</guid><category><![CDATA[UT Bootcamp]]></category><category><![CDATA[API]]></category><category><![CDATA[GIPHY]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Mon, 12 Sep 2016 04:39:36 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/33complete.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/33complete.png" alt="33% Complete with Bootcamp - Week 7 & 8 done"><p>Can you believe it has already been 8 weeks since the start of this bootcamp?  We have covered so much in such a sort time. By no means am I an expert but I think I have a solid understanding of the concepts we have discussed and it will only get better as we move through.</p>
<h4 id="topicscovered">Topics covered</h4>
<ul>
<li>We have built basic websites using only HTML and made them mobile responsive using media queries;</li>
<li>We have styled these websites using CSS style sheets;</li>
<li>We have created websites using the <a href="http://getbootstrap.com/">Bootstrap</a> and <a href="http://materializecss.com/">Materialize</a> framework (the GIPHY site included herein);</li>
<li>We have built a hangman game, a star wars game and a trivia game using HTML, CSS, Bootstrap, as well as Javascript and jQuery;</li>
<li>We have explored persistence data both client and server-side;</li>
<li>We have started to dive into databases starting with Google's <a href="https://firebase.google.com/">Firebase</a>;</li>
<li>We have created a website that pulls GIFs using GIPHY's API (included in this post) and;</li>
<li>We are currently working on a group project that will use Materialize as the CSS framework, Javascript and jQuery to handle user on selections and the logic, Firebase to house our data locally and Google and Yelp APIs to gather data (keep reading to see our idea) .</li>
</ul>
<p>And its just 33% of the way done! So many more cool and exciting topics to come. I really love the experience so far and can't wait for the opportunity to do this for a living.</p>
<h4 id="giphyapiweek7">GIPHY API  - Week 7</h4>
<p>One of the most recent projects we completed is a website that uses GIPHY's API to pull animated GIFs from their site. Let me step back for one sec. API stands for Application Program Interface and is a set of protocols and tools for building software applications. APIs are often the bridge between different components. There are three common use cases:</p>
<ol>
<li>To provide pre-built code for sending and retrieving data to a centralized database</li>
<li>To provide pre-built code for creating or utilizing other software components, like Google Maps and;</li>
<li>To interface with physical sensors or hardware like the Nest thermostat (I am stoked to explore this piece).</li>
</ol>
<p>In the case of my website I am using GIPHY's API to run a search  query in their database using the name of the rockstar and then pull the images onto my page. As I discussed in my last post, when I initially tried to use Materialize I had an issue with the container shrinking my page too much. This time on my GIPHY site I figured out how to adjust the width and you will notice that my margins are a lot less than the default width of 70% of the page. Similar to the previous exercises I am using Javascript for the logic and jQuery to update the images to the page.</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_1083/v1473652099/GIHPYAPI_pzj4xn.png" alt="33% Complete with Bootcamp - Week 7 & 8 done"></p>
<p>To go find animated Gif's of your own go here: <a href="https://guarded-bayou-24863.herokuapp.com/">Rockstar Giphy Lookup</a>. Make sure to choose your own rockstars by typing a name in the 'Choose Your Star' field and add it to the search. Then click the name button to see Gif's of that rockstar appear on the page. Click on the Gif to see it animate and click again to stop it.</p>
<h3 id="week8">Week 8</h3>
<p>Group projects began week 8. Our task is to build a site that uses all of the topics covered as mentioned above and also incorporates at least two APIs and uses Firebase. <a href="https://firebase.google.com/">Firebase</a> is a cloud services provider owned by Google. It has a few different features but the key feature is the offering of a realtime cloud database that uses an API allowing for quick and easy retrieval and storage of data.</p>
<p>Our project is all about dogs. Our inspiration came from our own dogs (see my dog, Maggie below) so we wanted to create a page that allowed dog owners to plan an entire day with their dogs. The name, 'Day With Your Dog' was born.</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_466/v1473654112/n_dog_uvwgqp.jpg" alt="33% Complete with Bootcamp - Week 7 & 8 done"></p>
<p>The project is due in a few weeks,  so once the beta is complete you can plan a &quot;Day With Your Dog&quot;. For the time being it will only work relative to Austin, TX (as our proof of concept) but we hope to extend the reach to dog owners everywhere soon. Check out the 1st draft of the homepage below (the first word uses CSS animations and cycles through a few other key words...). Get EXCITED, cause our group is!!!</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_1138/v1473654600/daywithyourdogscreenshot_zttivx.png" alt="33% Complete with Bootcamp - Week 7 & 8 done"></p>
<p>Stay strong and carry on and until next time...</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://play.spotify.com/album/12zXyBEny4zEXixW4Qazpz">Kings of Leon - Waste A Moment</a></li>
<li>CSS Frameworks: <a href="http://getbootstrap.com/">Bootstrap</a> and <a href="http://materializecss.com/">Materialize</a></li>
<li><a href="https://firebase.google.com/">Firebase</a></li>
<li><a href="http://giphy.com/">GIPHY</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Stars Wars game or Music Trivia Anyone?  - Week 5 and 6 complete]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Due to my blog recently being down I have been set back a week on posting my progress of the UT Bootcamp. So this one includes jam pack fun of both a Star Wars game <strong>and</strong> a Music Trivia Game. Both are a result of the homework completed as a</p>]]></description><link>https://thefinleycode.com/stars-wars-game-or-music-trivia-anyone-week-5-and-6-complete/</link><guid isPermaLink="false">6029e52ffaf90093100ab158</guid><category><![CDATA[Star Wars]]></category><category><![CDATA[Trivia]]></category><category><![CDATA[Underscore Library]]></category><category><![CDATA[jQuery]]></category><category><![CDATA[Javascript]]></category><category><![CDATA[UT Bootcamp]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Fri, 02 Sep 2016 18:18:43 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/StarwarsGame.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/StarwarsGame.png" alt="Stars Wars game or Music Trivia Anyone?  - Week 5 and 6 complete"><p>Due to my blog recently being down I have been set back a week on posting my progress of the UT Bootcamp. So this one includes jam pack fun of both a Star Wars game <strong>and</strong> a Music Trivia Game. Both are a result of the homework completed as a part of the course.</p>
<h4 id="javascriptandjquerycontinued">Javascript and JQuery Continued</h4>
<p>To continue on the path of working in javascript and jQuery, I have created a Star Wars RPG Game and a Music Trivia game using HTML 5, CSS, Javascript and JQuery.</p>
<h4 id="starwarsrpggame">Star Wars RPG Game</h4>
<p>The languages used in building the Star Wars Game are HTML 5, CSS, Javascript and jQuery. Initially, I was interested in exploring the <a href="http://materializecss.com/">Materialize</a> styling library (created by Google) to achieve the look and feel of the page but when using it I found that when applying a <code>container</code> tag within their grid system it brings in the margins quite a bit. I needed as mush screen space as possible for game play. I tried to figure it out for a few minutes, however, due to the time limits to finish the entire assignment, I decided to scrap the idea and just use Bootstrap (this time). I plan to go back and explore Materialize in week 7 for an API assignment and will figure out how to customize the <code>container</code> class.</p>
<p>This game was a challenge for me. There were so many elements and conditions that I really had to break it down to the simplest scenario and build it out from there (which from I have been learning is how you should approach a problem). Because of the difficulty I was having and because I really enjoy asking other people's advice on processes and methods I went to our in house developer to pick his brain. One thing he noticed when looking at my code was how I was updating information on the page. I was using jQuery to target certain elements depending on the scenario. Instead he suggested using templating through the <a href="http://underscorejs.org/">Underscore</a> library. Basically, instead of updating each section of the game dynamically and within the javascript, using templating allows you to hard code the basic 'template' within the HTML file and then you pass through the different elements when needed in the javascript. Effectively you then update your entire page every time based on the exiting if conditions in your javascript. Templating allows for cleaner code and you can eliminate concatenating strings and writing long code to dynamically update your page. Also it is easily re-usable and easy for teams to work together since they can manipulate the html with little effort. It was a great learning experience and I am continuing to look for ways to incorporate this method, when applicable.</p>
<p>CLICK HERE to PLAY the Star Wars RPG Game : <a href="http://mighty-hollows-76871.herokuapp.com/">Star Wars Game</a>!</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_997/v1472579242/StarwarsGame_qgrsse.png" alt="Stars Wars game or Music Trivia Anyone?  - Week 5 and 6 complete"></p>
<h4 id="musictriviagame">Music Trivia Game</h4>
<p>Continuing with the music theme, the music trivia game is also built using Javascript to handle to logic and jQuery to handle updating the page dynamically. The look and feel is achieved using Bootstrap grids and buttons with some added stylings. Lately, I have been using my wife to test out my games and provide me feedback on the user experience and she has provided great feedback. Some of her initial thoughts on this game were that the length of time between when the answer displayed and the next question displayed was too long. So I adjusted that. Also she suggested I put in how many questions are left, because she felt like it was dragging on. As of this post I haven't updated this yet but it is on my list of iterations to the trivia game. Go play and have fun!!!</p>
<p>To play the Music Trivia Game Click Here: <a href="https://thawing-peak-92742.herokuapp.com/">Trivia Game</a></p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_915/v1472580207/MusicTrivia_xuq2xa.png" alt="Stars Wars game or Music Trivia Anyone?  - Week 5 and 6 complete"></p>
<p>Until next time, keep calm and carry on...</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music Listened to while blogging: <a href="https://play.spotify.com/user/spotify/playlist/1yHZ5C3penaxRdWR7LRIOb">New Music Friday: Spotify</a></li>
<li><a href="https://colorlib.com/wp/music-wordpress-themes/">Cool Word Press Music Themes</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Journeyman Notes #3: Finley Code was down - 502 Bad Gateway Error]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Up until this point I haven't had any issues running and maintaining my blog. Well the beautiful thing about programming and technology is that you should expect something to break at some point. I finally experienced the heartache of broken things. Last Monday, when I was trying to upgrade my</p>]]></description><link>https://thefinleycode.com/finley-code-was-down-502-bad-gateway-error/</link><guid isPermaLink="false">6029e52ffaf90093100ab157</guid><category><![CDATA[Journeyman Notes]]></category><category><![CDATA[Problem Solving]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Mon, 29 Aug 2016 18:58:45 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/502badgateway.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/502badgateway.jpg" alt="Journeyman Notes #3: Finley Code was down - 502 Bad Gateway Error"><p>Up until this point I haven't had any issues running and maintaining my blog. Well the beautiful thing about programming and technology is that you should expect something to break at some point. I finally experienced the heartache of broken things. Last Monday, when I was trying to upgrade my Ghost platform, my blog broke. Friday of last week, I finally figured out how to fix it and as such my first post back online I had to share what happened, troubleshooting and the inevitable fix.</p>
<h4 id="theproblem">The Problem</h4>
<p>Monday, August 22nd,  while running through an update of Ghost, upon completion I received a '502 Bad Gateway Error' and my site was rendered incapacitated. Disclaimer: I did use a different update command this time, which may be part of the reason why it broke... This is what I used: <a href="https://www.ghostforbeginners.com/how-to-update-ghost/">Update Ghost</a>. I would now recommend this article instead <a href="http://support.ghost.org/how-to-upgrade/#command-guide">Upgrade Ghost 2.0</a>.</p>
<h4 id="troubleshooting">Troubleshooting</h4>
<p>After I ran the update I visited my page only to receive a blank screen save for a message that read:</p>
<blockquote>
<p>&quot;502 Bad Gateway&quot;</p>
</blockquote>
<p>Basically what this means (I found during my research) is that the server was acting as a gateway and received an invalid response from an upstream server. Still not sure what all of this means but I am continuing to research and learn.</p>
<p>At first I was very frustrated and tried running the update a few different ways but to no avail. I also felt disheartened and immediately felt alone not knowing where to turn. So I took to Googling and found quite a bit of documentation on the 502 error. But no specific commands to fix my Ghost issue. It was then that I remembered Ghost has a great slack channel with wonderful people offering their advice, so I turned there. Also since I don't like to sit still I turned to Digital Ocean's message boards <a href="https://www.digitalocean.com/community/questions">Digital Ocean Question Forum</a> since they host my blog. This is where I ultimately received the help that lead to the fix.</p>
<p>Below is the picture of my terminal with the warnings that I received when I tried to update Ghost:</p>
<p><img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_748/v1472493907/GhostErrorPic_nlbq85.png" alt="Journeyman Notes #3: Finley Code was down - 502 Bad Gateway Error"></p>
<p>Based on my conversations with the Slack community since these are just warnings the blog should still run but it didn't. Luckily a gentleman on the Digital Ocean forum responded to my inquiry quickly and I was able to get back up and running.</p>
<h4 id="theresolution">The Resolution</h4>
<p>After comment exchange on the Digital Ocean forum's I found a solution. Here is my fix from start to finish (I am sure there are others but for the time being this works):</p>
<p>I used this <a href="http://support.ghost.org/how-to-upgrade/">article</a> as a baseline (the command line section) and updated the steps to account for my errors.</p>
<ol>
<li>
<p>Get the latest version:<br>
<code>curl -LOk https://ghost.org/zip/ghost-latest.zip</code> OR a specific version <code>curl -LOk https://ghost.org/zip/ghost-&lt;version&gt;.zip</code></p>
</li>
<li>
<p>Unzip to a temporary location:<br>
<code>unzip ghost-latest.zip -d ghost-temp</code>. You will come back to file shortly</p>
</li>
<li>
<p>Change directory into your current ghost install:<br>
<code>cd path-to-ghost-install</code>, E.g. <code>cd /var/www/ghost</code></p>
</li>
<li>
<p>Copy key files to your Ghost install directory:<br>
<code>cp index.js *.json path-to-ghost-install</code></p>
</li>
<li>
<p>Update Casper by copying the casper folder(optional):<br>
<code>cp -R content/themes/casper path-to-ghost-install/content/themes</code></p>
</li>
<li>
<p>Change back to your ghost install directory:<br>
<code>cd path-to-ghost-install</code></p>
</li>
<li>
<p>(optional) Update permissions:<br>
E.g. <code>chown -R ghost:ghost *</code></p>
</li>
<li>
<p>Change directory into your current ghost install:<br>
<code>cd path-to-ghost-install</code>, E.g. <code>cd /var/www/ghost</code></p>
</li>
<li>
<p>Then run the following (this will remove your core and node_modules files as well):</p>
<pre><code> sudo apt-get update  
 sudo apt-get upgrade  
 npm cache clean 
 rm -rf node_modules  
 rm -rf core
</code></pre>
</li>
<li>
<p>Next you need to add your new core file back into your directory, so change back to your download of Ghost latest:<br>
<code>cd path-to-ghost-temp</code> E.g. <code>cd ~/Downloads/ghost-temp</code></p>
</li>
<li>
<p>Copy the new core directory to your Ghost install:<br>
<code>cp -R core path-to-ghost-install</code></p>
</li>
<li>
<p>Upgrade dependencies:<code>npm install --production</code> (you may still see a warning here bur fear not).</p>
</li>
<li>
<p>The start the productin environment: <code>npm start --production</code>.</p>
</li>
<li>
<p>You may get an error about sqlite3 but just run the code below regardless:  <code>npm install sqlite3 -save</code> and then <code>npm start --production</code>.</p>
</li>
<li>
<p>You will find that your blog works however it will be terminated after you close your terminal. So you need run Ghost in <a href="http://docs.ghost.org/pl/installation/deploy/">forever mode</a> type: <code>npm install forever -g</code></p>
</li>
<li>
<p>You made it. Last step restart Ghost in forever mode from the Ghost installation directory: <code>NODE_ENV=production forever start index.js</code>.</p>
</li>
</ol>
<p>Two other helpful forever commands:</p>
<ul>
<li>To stop Ghost type: <code>forever stop index.js</code></li>
<li>To check if Ghost is currently running type: <code>forever list</code></li>
</ul>
<p>If you find any holes or issues please let me know as I would be curious.</p>
<p>Lastly, and for reference, here is my forum exchange on Digital Ocean as well for additional reference: <a href="https://www.digitalocean.com/community/questions/upgraded-ghost-to-0-9-502-bad-gateway">502 Bad Gateway Discussion</a></p>
<h4 id="mytakeawaysherearethreefold">My take-aways here are three-fold:</h4>
<ul>
<li>Always Google to try and find your answer. Stack Overflow should become your best friend.</li>
<li>Don't be afraid to ask for help even from complete strangers, which is exactly what I did on Digital Ocean and it was scary at first.</li>
<li>Try, try try no matter what and don't ever give up. There is always a solution.</li>
</ul>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=ATWU85fxD2k">Rachmaninoff Prelude in D Major</a></li>
<li><a href="http://support.ghost.org/how-to-upgrade/#command-guide">Upgrade Ghost: Command Guide</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Week 4 - Fertig! - How about some Pop Star Hangman?]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Made it through week 4 of UT Coding Bootcamp and this past week was all about Javascript and jQuery. Due to the amount of homework and studying I have been doing lately, I will be relatively brief.</p>
<p>Last post I discussed the very basics of javascript so let's briefly discuss</p>]]></description><link>https://thefinleycode.com/week-4-fertig-how-about-some-pop-star-hangman/</link><guid isPermaLink="false">6029e52ffaf90093100ab155</guid><category><![CDATA[UT Bootcamp]]></category><category><![CDATA[Vanilla Javascript]]></category><category><![CDATA[jQuery]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Wed, 17 Aug 2016 06:28:21 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/Hangman.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/Hangman.png" alt="Week 4 - Fertig! - How about some Pop Star Hangman?"><p>Made it through week 4 of UT Coding Bootcamp and this past week was all about Javascript and jQuery. Due to the amount of homework and studying I have been doing lately, I will be relatively brief.</p>
<p>Last post I discussed the very basics of javascript so let's briefly discuss jQuery.</p>
<h4 id="jquery">jQuery</h4>
<p>What is jQuery? JQuery as defined by their own website says it is a:</p>
<blockquote>
<p>&quot;fast, small and feature-rich javascript library.&quot;</p>
</blockquote>
<p>It can be used in conjunction with javascript as it is a library, an additional tool belt if you will. One thing to note that a few people have told me is that jQuery is not used as frequently as it used to be and learning <em>'vanilla javasctipt'</em>, which is the long form javascript will actually be much more useful and position you for better success in the job market.</p>
<p>jQuery - in a nutshell:</p>
<ol>
<li>We use the jQuery $( ) identifier to capture HTML elements. Like so:  <code>$(‘#idname')</code>, <code>$(“.classname”)</code> or <code>$('elementname)</code></li>
<li>Then we tie the element to a jQuery method of our choosing to capture events and change that element (or a different element). Some examples include the<br>
<code>on(“click”)</code> or <code>.ready()</code> methods</li>
<li>Finally, we tie the element to a jQuery method of our choosing to capture events and change that element. For example you might use: <code>.append(),</code> or <code>.animate()</code>.</li>
</ol>
<p>To see this in action below are a couple examples using javascript and jQuery that we did in class. See if you can spot in the code were jQuery is used to identify elements, calling a method and updating that element or another resulting in a change on the page.</p>
<h5 id="captainplanetexample">Captain Planet Example</h5>
<p>Watch him grow, shrink, move, become invisible and destroy the world (a special touch). This uses the <code>.on('click')</code> and <code>.animate()</code> methods to capture user clicks and then animate those things.</p>
<p data-height="777" data-theme-id="0" data-slug-hash="pbGBoj" data-default-tab="result" data-user="Nfinleymusic" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/Nfinleymusic/pen/pbGBoj/">Bootcamp_4.2_CaptainPlanet</a> by Nigel Finley (<a href="http://codepen.io/Nfinleymusic">@Nfinleymusic</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<h5 id="fridgemagnetexample">Fridge Magnet Example</h5>
<p>In this example, have fun moving these letters on and off the fridge. This is primarily using jQuery code like the <code>.append()</code> method to add the letters to the fridge and the <code>.empty()</code> method to remove by calling an html id.</p>
<p data-height="764" data-theme-id="0" data-slug-hash="WxPWGb" data-default-tab="result" data-user="Nfinleymusic" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/Nfinleymusic/pen/WxPWGb/">Bootcamp_4.2_FridgeMagnets</a> by Nigel Finley (<a href="http://codepen.io/Nfinleymusic">@Nfinleymusic</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<h4 id="popstarhangmanusing">Pop Star Hangman using</h4>
<h6 id="javascripthtmlcssandsomejquery">Javascript, HTML, CSS and some jQuery</h6>
<p>Week four culminated in the completion of a javascript based hangman game. I am still working on it and want to add even cooler features like adding hints and playing a video by the artist you guess correct. Soon enough.<br>
<img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/c_scale,w_948/v1471236325/Hangman_nmrsc2.png" alt="Week 4 - Fertig! - How about some Pop Star Hangman?"></p>
<p>TO PLAY POP STARS OF THE 2000s, click <a href="http://hidden-mesa-66223.herokuapp.com/">HERE!</a></p>
<p>Stay tuned for next week as another game will be unveiled. Think light sabers and far away galaxies!!! Here is your not so subtle hint:<br>
<img src="http://res.cloudinary.com/thefinleycode/image/fetch/http://res.cloudinary.com/thefinleycode/image/upload/v1471238750/starwars_w82qzl.gif" alt="Week 4 - Fertig! - How about some Pop Star Hangman?"></p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=epi2EFX2U-g&amp;index=5&amp;list=PLjeQtXQrIMvnBoYiYro_1VGiX8s7gnarO">Soulive: Tuesday Night Squad</a></li>
<li><a href="http://www.w3schools.com/jquery/jquery_get_started.asp">W3 Schools: jQuery</a></li>
<li><a href="https://jquery.com/">JQuery Home Page</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Week 3 - Finito! - Rock Paper Scissors Anyone?]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Week 3 has concluded  of the UT Bootcamp and I am still enjoying every minute. Besides the lack of sleep and the sure amount of mind-boggling information we have to take in, my mind is wide open to receive. This post includes a game...keep reading!</p>
<h4 id="bootstrapportfoliopage">Bootstrap Portfolio Page</h4>
<p>As</p>]]></description><link>https://thefinleycode.com/week-3-finito-rock-paper-scissors-anyone/</link><guid isPermaLink="false">6029e52ffaf90093100ab152</guid><category><![CDATA[UT Bootcamp]]></category><dc:creator><![CDATA[Nigel Finley]]></dc:creator><pubDate>Fri, 12 Aug 2016 02:23:42 GMT</pubDate><media:content url="https://thefinleycode.com/content/images/2021/02/RPG.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://thefinleycode.com/content/images/2021/02/RPG.png" alt="Week 3 - Finito! - Rock Paper Scissors Anyone?"><p>Week 3 has concluded  of the UT Bootcamp and I am still enjoying every minute. Besides the lack of sleep and the sure amount of mind-boggling information we have to take in, my mind is wide open to receive. This post includes a game...keep reading!</p>
<h4 id="bootstrapportfoliopage">Bootstrap Portfolio Page</h4>
<p>As week two wrapped we were asked to create a second portfolio page this time using the CSS library and pre-built framework Bootstrap. Still tweaking the video I created to put in as the header to make it responsive and making the portfolio pages link to places. <a href="https://thefinleycode.com/week-3-finito-rock-paper-scissors-anyone/glacial-woodland-38082.herokuapp.com">Work in progress portfolio page</a>.<br>
It is still very much a work in progress but I suppose so is life.</p>
<h4 id="javascript">Javascript</h4>
<p>This week we started into the realm of javascript and boy am I excited. Javascript is considered to be one if not the (depending on who you ask) most prevalent, dominant and versatile language out there.</p>
<p>What is it? Wikipedia defines Javascript as</p>
<blockquote>
<p>an object-oriented computer programming language commonly used to create interactive effects within web browsers.</p>
</blockquote>
<p>It allows developers to create dynamic web applications capable of taking in user inputs, changing what’s displayed, crete animations and all sorts of fun things (which we are learning slowly).</p>
<p>Because Javascript has so many pieces and we have only touched on a few, below are a few basics that we have learned so far:</p>
<ul>
<li>
<p><code>Variable</code> or <code>var</code>: are the nouns of javascript and are 'things' and can be strings, numbers, booleans, etc. A variable has to be declared using <code>var</code>. For example <code>var car = 'toyota';</code>. This stores the string <code>'toyota'</code> into the variable of car.</p>
</li>
<li>
<p><code>Arrays</code>: are special variables that can store multiple values within a single variable. They can be numbers or strings or a mix.  For example if you had more than one car you could store them in the variable <code>car</code> like this <code>var car = ['toyota', 'ford', 'chevy'];</code></p>
</li>
<li>
<p><code>Objects</code> : Objects are a type of an array and a type of variable. Where a variable can only hold one value an object can hold many values, like this: <code>var car = {make: 'toyota', model: 'tacoma', color: 'black'}; </code>. Values inside of an object can be anything including arrays, functions, variable and more.</p>
</li>
<li>
<p><code>Functions</code>: are a block of code that are designed to perform a specific task. A function is executed when something calls it. It looks like this:</p>
<pre><code>  function myFunction(make, model) {
     return make + model; }
</code></pre>
</li>
<li>
<p><code>If-Else statements</code>: are conditional statements that perform different actions based on the conditions set. Basically you can think of it as if 'something' then execute a code block, otherwise (else) execute an alternate code block. If loops look like this:</p>
<pre><code>  if (car.make===toyota){
      return true 
    }else 
     return false
</code></pre>
</li>
<li>
<p><code>The For loop</code> : is used when you want to run a block of code multiple times. The syntax looks like this:</p>
<pre><code>   for (i=0; i&lt; car.length; i++){
      text += cars[i] + &lt;&quot;br&quot;&gt;; 
    }
</code></pre>
</li>
</ul>
<p>This sets the initial value to zero <code>i=0</code> and then for as long as i is less than the length of our car array it will increment the function by one (<code>i++)</code>. Then it will return the three values in our array <code>car</code>.</p>
<p>For loops are a little more complicated and you can read more about them and all of the others discussed herein at <a href="https://developer.mozilla.org/en-US/Learn/Getting_started_with_the_web/JavaScript_basics">Mozilla Developer Network</a></p>
<h4 id="thedryprinciple">The DRY Principle</h4>
<p>This is a programming principle that says Don't Repeat Yourself'. Which means always try to find ways to keep your code clean. If you write a function multiple times, the DRY principle applied would be to figure out how to reduce the number of times you needed to write that function into one.</p>
<h4 id="gametime">Game Time</h4>
<p>As a mini-project we were asked to use what we learned in the first few classes of Javascript and create a basic rock paper scissors game. Try your luck playing the computer in this virtual rock paper scissors game.</p>
<p data-height="616" data-theme-id="0" data-slug-hash="pbQEZp" data-default-tab="result" data-user="Nfinleymusic" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/Nfinleymusic/pen/pbQEZp/">Bootcamp_3.2_RockPaperScissors</a> by Nigel Finley (<a href="http://codepen.io/Nfinleymusic">@Nfinleymusic</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
<p>Week 4 continues with Javascript and a hangman game. Stay tuned and brush up on your 2000s pop stars if you want to win hangman!!</p>
<hr>
<h4 id="shoutouts">Shout Outs</h4>
<ul>
<li>Music listened to while blogging: <a href="https://www.youtube.com/watch?v=q7yaHnUPJLE&amp;list=PLA7F06689CB4166B1">Junip: Fields</a></li>
<li><a href="http://www.asmarterwaytolearn.com/js/index-of-exercises.html">A Smarter Way to Learn Javascript</a></li>
<li><a href="http://www.w3schools.com/js/default.asp">W3Schools : Javascript Page</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>