Jekyll2017-09-15T16:20:08+02:00https://samneirinck.com/Sam NeirinckSam Neirinck's blog dumpEasy Jekyll blogging on Windows using Docker2016-08-01T00:00:00+02:002016-08-01T00:00:00+02:00https://samneirinck.com/2016/08/01/easy-jekyll-blogging-on-windows-using-docker<p>This blog is hosted on <a href="https://pages.github.com/">Github Pages</a>. It allows me to just write content and not worry about server infrastructure or blog engine upgrades. Github Pages uses <a href="https://jekyllrb.com/">Jekyll</a> behind the scenes, which allows users to just write Markdown posts.</p>
<h1 id="jekyll-and-windows">Jekyll and Windows</h1>
<p>To be able to preview your Jekyll site, you’ll want to run it locally. In the docs we find the following:</p>
<blockquote>
<p>While Windows is not officially supported, it is possible to get it running on Windows. Special instructions can be found on our Windows-specific docs page.</p>
</blockquote>
<p>The page then goes on on how to install Ruby on Windows before installing Jekyll. Until recently, that’s what I did, however it’s a bit of a pain. Preferably, I wouldn’t want to install Ruby just to preview my blog entries.</p>
<p>This sounds like a good use case for using container technology. With the recent release of <a href="https://docs.docker.com/docker-for-windows/">Docker For Windows</a>, setting up Docker on Windows is such a breeze. It uses Hyper-V under the covers, sets up port-forwarding so you can use <em>localhost</em> to access services hosted on Docker, and a bunch of other magic to make it all work seamlesslsy.</p>
<p>If you’ve used Docker before, but found it a bit of a pain to set up (especially on Windows), I highly encourage you to try it out again.</p>
<h1 id="running-jekyll-in-docker">Running Jekyll in Docker</h1>
<blockquote>
<p>If you don’t have a Jekyll site/blog and want to follow along, feel free to clone my blog.
<code class="highlighter-rouge">git clone https://github.com/samneirinck/samneirinck.github.io</code></p>
</blockquote>
<p>Jekyll has an <a href="https://hub.docker.com/r/jekyll/jekyll/">official image</a> on <em>Docker Hub</em>. This makes it even more easy to use. All that’s needed is running the following command:</p>
<p><code class="highlighter-rouge">docker run --rm --volume=/c/path/to/blog:/srv/jekyll -it -p 4000:4000 jekyll/jekyll:pages</code></p>
<p>Sure enough, browsing to <em><a href="http://localhost:4000/">http://localhost:4000</a></em> lets us visit the Jekyll site locally.</p>
<h1 id="creating-a-docker-compose-file">Creating a docker-compose file</h1>
<p>This is great, but the command is a bit long to remember. Why not create a docker-compose file so we can reduce it to just one command.</p>
<p>In the root folder of the site, create a <em>docker-compose.yml</em> file with the following contents:</p>
<div class="language-yaml highlighter-rouge"><pre class="highlight"><code><span class="s">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">2'</span>
<span class="s">services</span><span class="pi">:</span>
<span class="s">web</span><span class="pi">:</span>
<span class="s">image</span><span class="pi">:</span> <span class="s">jekyll/jekyll:pages</span>
<span class="s">command</span><span class="pi">:</span> <span class="s">jekyll s --force_polling --drafts</span>
<span class="s">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">4000:4000"</span>
<span class="s">volumes</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">.:/srv/jekyll</span>
</code></pre>
</div>
<p>We’re using the <code class="highlighter-rouge">--force_polling</code> option to make jekyll regenerate the site whenever there are changes in the markdown files, productivity success.</p>
<p>Once this file is set up, run the following command:
<code class="highlighter-rouge">docker-compose up</code></p>
<p><img src="/img/docker-compose-up.gif" alt="docker-compose up" /></p>
<p>Browsing to <em><a href="http://localhost:4000/">http://localhost:4000</a></em> shows our blog again, and we can now edit our blog drafts, and preview them directly in the browser.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Using Docker For Windows it’s now easier than ever to spin up your Jekyll site on Windows and do your modifications. I can now work on my blog from any machine, with or without internet connection, and have an exact preview on what it will look like if I publish a post.</p>This blog is hosted on Github Pages. It allows me to just write content and not worry about server infrastructure or blog engine upgrades. Github Pages uses Jekyll behind the scenes, which allows users to just write Markdown posts.A look behind the scenes2015-07-25T00:00:00+02:002015-07-25T00:00:00+02:00https://samneirinck.com/2015/07/25/a-look-at-sonos-protocol<p>While Sonos has no official API, it uses open technologies for the apps to communicate with the devices, namely Universal Plug and Play, UPnP. It’s highly likely that you have a device at home supporting UPnP. Things like routers, TV’s and set-top boxes all have UPnP services.</p>
<p>A device supporting UPnP is discoverable and can announce which services it support, along with which functions clients can call and what arguments the device expects. There’s a great utility on Windows to see all this information: Device Spy. It’s included in the <a href="http://opentools.homeip.net/dev-tools-for-upnp">Developer tools for UPnP</a>.</p>
<p>On my network, it finds the following devices:
<img src="/img/upnp-discover1.png" alt="Device Spy" /></p>
<p>You can see the 3 Sonos devices, a router, a TV, a Raspberry Pi, and my set-top box. If I expand the Play 3, we can see it exposes quite a few services.</p>
<p><img src="/img/upnp-discover2.png" alt="Services" /></p>
<p>With Device Spy we can invoke a function, and the Sonos controller application immediately responds to this.</p>
<p><a href="/img/device-spy-sonos.gif"><img src="/img/device-spy-sonos.gif" alt="Animation" /></a></p>
<p>Behind the scenes, the invocation of this method is done via SOAP. Getting the volume of a speaker is done like this:
<script src="https://gist.github.com/samneirinck/904b55b2b75c8f0370cf.js"></script>
The speaker returns with a straight-forward reply:
<script src="https://gist.github.com/samneirinck/8b895b7c8e9061818fef.js"></script></p>
<p>Although this will get you along the road, we still have a missing piece. The apps from Sonos react immediately to any change (volume, next track, mute, etc…). This is done by using UPnP Eventing. In essence, each controller hosts a simple http server, and then notifies the speaker that it wants to subscribe to events. Whenever an event happens, the speaker will notify all of its subscribers of the new value.</p>
<p>We’ll want this functionality in SonosSharp as well, and abstract the HTTP server away, since it has to be cross-platform.</p>
<p>In the next blog post we’ll dive into the code, or at least discuss on how we should structure it.</p>While Sonos has no official API, it uses open technologies for the apps to communicate with the devices, namely Universal Plug and Play, UPnP. It’s highly likely that you have a device at home supporting UPnP. Things like routers, TV’s and set-top boxes all have UPnP services.SonosSharp, a new beginning2015-06-20T00:00:00+02:002015-06-20T00:00:00+02:00https://samneirinck.com/2015/06/20/sonossharp-a-new-beginning<p>Since I bought my first <a href="http://www.sonos.com/">Sonos</a> equipment piece, the Playbar, I’ve been intrigued by the system. It’s so simple to set up and use, and the apps (on Android, iOS and Windows) are a breeze to work with.</p>
<p>At the time of writing, there is no official Sonos app for Windows Phone (<a href="http://www.windowscentral.com/sonos-app-windows-phone-private-beta-promised-no-eta-release-though">although one is apparently in the works</a>). This led me to developing a Windows Phone app that does some of the basics such as controlling volume, mainly as a learning opportunity.</p>
<p>A lot has changed since then, .NET is going cross-platform &amp; open-source, Windows 10 is coming with windowed Metro/Modern/Universal apps. Lately I’ve also been learning about Reactive Extensions, and have fallen in love with it.</p>
<p>This lead me to reinvent SonosSharp, which was previously just a dump of the library I wrote for my Windows Phone app. I’ll be starting with a clean sheet, and will be heavily focusing on ease-of-use of the library. In the following blog posts I’ll describe my process as I go along. The big objectives are:</p>
<ul>
<li>Must be super easy to use, yet allow for more complex scenario’s such as eventing (more on that in another post)</li>
<li>Cross-platform, make it work on Windows, Linux, OSX, mobile platforms</li>
<li>Think about performance as a feature, but also keep the memory under control (memory pooling)</li>
<li>Create a sample app/console application as a showcase</li>
<li>And of course, develop it all in the open, on Github</li>
</ul>
<p>I strive to not let this be another one of my side-projects, as illustrated brilliantly in this commit strip.
<img src="/img/Strip-Side-project-650-finalenglish.jpg" alt="Side-Project" /></p>
<p>Time to get started!</p>Since I bought my first Sonos equipment piece, the Playbar, I’ve been intrigued by the system. It’s so simple to set up and use, and the apps (on Android, iOS and Windows) are a breeze to work with. At the time of writing, there is no official Sonos app for Windows Phone (although one is apparently in the works). This led me to developing a Windows Phone app that does some of the basics such as controlling volume, mainly as a learning opportunity. A lot has changed since then, .NET is going cross-platform &amp; open-source, Windows 10 is coming with windowed Metro/Modern/Universal apps. Lately I’ve also been learning about Reactive Extensions, and have fallen in love with it. This lead me to reinvent SonosSharp, which was previously just a dump of the library I wrote for my Windows Phone app. I’ll be starting with a clean sheet, and will be heavily focusing on ease-of-use of the library. In the following blog posts I’ll describe my process as I go along. The big objectives are: Must be super easy to use, yet allow for more complex scenario’s such as eventing (more on that in another post) Cross-platform, make it work on Windows, Linux, OSX, mobile platforms Think about performance as a feature, but also keep the memory under control (memory pooling) Create a sample app/console application as a showcase And of course, develop it all in the open, on Github I strive to not let this be another one of my side-projects, as illustrated brilliantly in this commit strip. Time to get started!