Ogre Codes

Follow @ogre_codes to get notified when new articles are posted to this site.


Momentum and Focus πŸ‘¨πŸ»β€πŸ’»

Jun 15, 2017 at 10:27 AM

So much going on right now in my life it’s been incredibly hard to find a peaceful place and state of mind where I can be heads down on code. The past week I’ve finally been able to get some time and I’ve made a ton of progress on my blogging app.

I switched the app to use UIDocument and FileWrappers so I could support images and other attachments and possibly iCloud syncronization. Currently images can be selected and saved as part of the document, to add them to the documents, I have to add support to the templates, image scaling, and uploading which I’ll be working on over the next few days.

In addition to switching the document model, I changes the table-views to use iOS’s built in table row update support. Previously I was reloading the entire table every time I updated a row which was quite crude and visually a bit gross. The new method checks if the row has moved and if needed relocates it in the table.

func updateListEntry(_ entry: BlogEntry) {
    // Refresh the view and move the row if needed
    guard let oldRow = entryList.entries.index(of:entry) else {
        fatalError(β€œEntry is not in the table”)
    let oldIndex = IndexPath(row:oldRow, section: 0)
    entryTableView.reloadRows(at: [oldIndex], with: .automatic)
    guard let newRow = entryList.entries.index(of:entry) else {
        fatalError(β€œEntry removed from the table”)
    if oldRow != newRow {
        let newIndex = IndexPath(row:newRow, section: 0)
        entryTableView.moveRow(at: oldIndex, to: newIndex)

Making The Switch To Python 3 πŸ‘¨πŸ»β€πŸ’»

Apr 19, 2017 at 9:53 PM

I'm finally fully on board with Python 3, and I suspect the majority of the community is too. It's been a long haul, but all of the biggest drags to Python 3 adoption have finally been swept away.

  • Most Linux distributions now ship with Python 3 support available and some are working towards using Python 3 as the default Python implementation.
  • 339 of the 360 most popular libraries now ship with Python 3 support by default.
  • Unicode adoption in general has become more important which puts one of the biggest reasons to migrate to Python 3 at the forefront.

In addition to most of the barriers to switching to Python 3 being removed, there is one rather large reason more and more developers are going to make the switch to Python 3, with the release of Django 2.0 at the end of this year, Django is dropping support for Python 2. The Django team will continue with updates to older versions of Django until 2020, but it would be extremely short sighted to implement a new Django server with Python 2 at this point. Django is responsible for roughly 20% of Python questions on Stack Overflow and is easily the largest Python web framework so this is going to have a rather large impact on the entire community.

To be honest though, the switch is rather underwhelming from a coding perspective. Once you get past the initial environment setup, the language is 99% identical and since most of the libraries are there and Django supports it, the only thing changes are trivial and suddenly unicode support is much better.

If you want to try it out, I've put together a Docker environment for running Django under Python 3 . The installation is straight-forward and you'll be surprised at how straight forward the change is.

Take a look and let me know if you see anything which needs improved.


A Docker Image For Django Development πŸ‘¨πŸ»β€πŸ’»

Apr 2, 2017 at 5:23 PM

Maintaining consistent build environments between multiple development and staging servers can be a chore. Products like Fabric or Ansible work well for managing multiple permanent servers, but don't help much when you are building a test environment development system which requires some kind of VM layer. Docker presents a good solution for this kind of setup. You can build complete environments which are simple to deploy either on a test server or even on a MacBook or other laptop.

A while ago I put together an image for deploying Django with Docker for my team at BiomedGPS and it worked so well I decided I would rebuild it as an open source project. I've released the resulting image on GitHub.com/OgreCodes .

I've tried a few similar images out there, but most of them require you rebuild the image for fairly minor configuration changes. I've set this image up so you should only need to rebuild the image if you need to make changes to the Python environment via requirements.txt. You can deploy a complete Docker image with Django and Nginx serving static and media files, less than 10 minutes. Adding MySQL server instead of SQLLight increases the time by a couple minutes.

The other big thing which makes this image stand out is the step by step instructions on launching the image. If you are familiar with docker and django but have never put together an image, this should be very helpful. Please give it a try and let me know what you think.

If you use Django and you need a straight forward docker container, give it a spin and let me know what you think.


A Couple Javascript Projects πŸ‘¨πŸ»β€πŸ’»

Mar 16, 2017 at 11:30 PM

Since my last post, I've moved to another state and I'm still getting settled so the blog took a back seat for a little bit. I should be back posting about my adventures learning Swift soon, but for the moment, I've been doing a couple deep dives into some Javascript mini-projects which I've posted in full on github.

Photos Near

This is is a simple photo gallery app that pulls images from the Flickr API based on a set of locations. At the moment it has a list of hard coded locations I've selected, but it can be easily adapted to show the most recent photos near the current computer or whatever. While this app is fairly simple, it does have some fairly solid transitions and load animations for when you are first starting the page and when you are waiting for a new set of photos to load. You can check out the demo app here or I have a github page for the project .

Oakridge Trails

This project was partly for a job pitch but it turned into a pet project which I dug deeper into because I love trails and maps. I discovered a new mapping library called leafletjs which lets you pull in OpenStreet Map tiles and overlay layers of data on top of them. In this case I used OpenTopo Maps to pull up topographic maps of the various trails near Oakridge Oregon and overlay both the map route and an elevation profile of the trail (using elevation data from bike rides on those same trails.

The result is pretty cool (Ok, I'm biased) and I'm likely to be doing a few more trail maps like this one based on requests. As with my Photos page, the source is on github so if you see a use for this, please fork it and let me know!

One of the really curious things about this project was the charting. I've used highcharts.js for charting in the past and overall I've been quite happy with it, but it's a lot more than what I needed for the simple elevation charts. So I grabbed the super light weight chartist.js library which is a fraction of the size of highcharts and does exactly what I need.

Marking Progress

All isn't quiet on the Swift front, I've just been working on a small framework I'm going to release on Github soon which I use on the page to format code samples. It's also the foundation of some bigger projects pieces of the page which I'm looking forward to putting out soon. For the moment, the demands of relocating and job hunting have taken over priorty. My intent is to keep posting at least weekly on this Blog.


WordPress Security Woes πŸ™ˆπŸ˜§

Feb 28, 2017 at 10:35 AM

Stories like this are entirely too common:

Researchers Find "Severe" flaw in WordPress plugin with 1 million installs
The vulnerability stems from a "severe" SQL injection bug in NextGEN Gallery, a WordPress plugin with more than 1 million installations. Until the flaw was recently fixed, NextGEN Gallery allowed input from untrusted visitors to be included in WordPress-prepared SQL queries. Under certain conditions, attackers can exploit the weakness to pipe powerful commands to a Web server's backend database.

The inherent problem with having your platform be both an authoring tool and a publishing platform is vulnerabilities in the publishing platform expose your authoring tools to the world. This is one of the primary reasons SwiftBlog has strict separation between authoring and publishing.

A few select older vulnerabilities:


Roll Your Own Split View πŸ‘¨πŸ»β€πŸ’»

Feb 19, 2017 at 7:48 PM

Almost every single tutorial I see which talks about getting started with iOS programming suggests you should write for one form factor, either for the phone or for the iPad (usually for the phone). I get why, it's much easier to build an app for one platform. Much easier, often you wind up doing 2-3 times as much work to get something fairly simple done when you are building for both. Of course—since I'm a glutton for punishment—I like my iPad and I like my phone and I want an app that works on both, so SwiftBlog is a universal app. I spent most of Yesterday making the Instant Preview pane work for the iPad, Today I built the same feature for the phone.

Obviously a different approach is needed for the phone, the screen isn't wide enough for dual panes to make any sense. So my approach was a simple "Preview" button in the upper right which let you instantly switch to see what the page will look like on the site. There were two aspects to this which were a bit tricky, the first was supporting both split view and a separate switching view for the phone, the second was getting a nice smooth animation when switching to the preview mode.

Split View

Apple has a special SplitView container for doing something similar to what I had in mind, but it's specific UITableViews which didn't exactly work for what I wanted. My approach was based on some simple auto-layout logic.

I started by laying out the Stack View with the entry editor (EntryStack) and the Web View side-by-side and pinning the non-joined sides to the adjacent elements. Then I added an equal widths constraint to the two containers and set a constraint which pinned the leading edge of the Web View to the trailing edge of the EntryStack. This was the basic side-by-side view for the iPad.

To set up the iPhone view, I added a size based variation to turn off the constraint that pins the joining edge of the EntryStack to the Web View and added a second size based constraint to the Web View which made it equal widths to the main view when it's on an iPhone.

Using this setup, I was able to set a simple button to toggle between the two views by either raising or lowering the WebView, or toggling it's "hidden" state, but I wanted something a little snazzier than that.

37 Pieces of Flair

The final piece of this was to make the switch on the iPhone a bit more fluid, the instant flip between the two views didn't feel complete, it need a bit of animation. I decided a cross-fade would be a nice way to indicate the transformative nature of the preview.

A quick search made UIView.transitionFromView look promising and while it seemed to do the right thing the first time, I couldn't get it to transition back to the edit view. The solution I came up with was to just animate the alpha of both layers in opposite directions and the result was the fairly smooth animation between the two states. The result looks like this:

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">togglePreview</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">if</span> webView.isHidden {
        <span class="hljs-type">RenderPage</span>()
        <span class="hljs-keyword">self</span>.webView.alpha = <span class="hljs-number">0.0</span>
        <span class="hljs-keyword">self</span>.webView.isHidden = <span class="hljs-literal">false</span>
        <span class="hljs-type">UIView</span>.transition(with: webView,
                          duration: <span class="hljs-number">0.33</span>,
                          options: .curveEaseIn,
                          animations: {
                            <span class="hljs-keyword">self</span>.webView.alpha = <span class="hljs-number">1.0</span>
                            <span class="hljs-keyword">self</span>.entryStack.alpha = <span class="hljs-number">0.0</span>
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-type">UIView</span>.transition(with: webView,
                          duration: <span class="hljs-number">0.33</span>,
                          options: .curveEaseIn,
                          animations: {
                            <span class="hljs-keyword">self</span>.webView.alpha = <span class="hljs-number">0.0</span>
                            <span class="hljs-keyword">self</span>.entryStack.alpha = <span class="hljs-number">1.0</span>
        }) { <span class="hljs-number">_</span> <span class="hljs-keyword">in</span> <span class="hljs-keyword">self</span>.webView.isHidden = <span class="hljs-literal">true</span> }

The Web View is hidden at the end of the animation to avoid having a transparent view floating over the top of the edit pane.

In retrospect, this all would have been easier and likely a little more consistent with the "Apple Way" if I'd just pushed a new WebView onto the Navigation Stack, and I might still switch to that, but right now it was fun learning how to do the crossfade effectively and it looks quite slick.


Dealing with Timers in a View Controller πŸ‘¨πŸ»β€πŸ’»

Feb 18, 2017 at 11:08 PM

My instant preview uses a timer that checks if the page has updated and if it has, updates the webview. To do this, I set up a timer with a callback to a class method on the View Controller.

If you want to use a timer in a View Controller in iOS, it's fairly simple, just add the timer in viewWillAppear .

timer = <span class="hljs-type">Timer</span>.scheduledTimer(timeInterval: <span class="hljs-number">5</span>, target: <span class="hljs-keyword">self</span>, selector: #selector(timedServices), userInfo: <span class="hljs-literal">nil</span>, repeats: <span class="hljs-literal">true</span>);

What is less obvious is the fact that timers persist beyond the life of the view and keep polling the selected method long after you've exited the page where you launched them from. This creates a memory retention cycle, the timer is hanging onto a reference to the View Controller so it can access it's method and the View Controller is hanging onto a reference to the timer. Additionally, it's burning CPU time (and by extension battery life) checking to see if it needs to update a view which is no longer valid.

The solution I came up with was to check if the view was visible in the timer event and if it wasn't, invalidate the timer. It turns out this was somewhat overengineered; there is a much simpler way to do this simply by invalidating the timer in viewWillDisappear .

<span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">viewWillDisappear</span><span class="hljs-params">(<span class="hljs-number">_</span> animated: Bool)</span></span> {
    <span class="hljs-keyword">super</span>.viewWillDisappear(animated)

Source StackOverflow .

By having the timer start and stop in viewWillAppear and viewWillDisappear respectively, you ensure it's running the entire time the view is active and no longer. In more general terms, this is a good way to keep the program balanced. If you set something up in viewWillAppear , there's a fair chance you'll need to set up some kind of teardown code in viewWillDisappear , keeping things balanced makes housekeeping a lot simpler.