Ogre Codes

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

πŸ‘¨πŸ»β€πŸ’»

What Is This Page?? πŸ‘¨πŸ»β€πŸ’»

I'm Dennis Bakerβ€”a developer, mountain biker, writer, sometimes photographer, and geek. I post about Python, Django, Javascript, Swift, and anything else technology related I find interesting. This blog is published by Swift Blogger an iOS blogging app I created.

You can also find me on Github, Twitter, or Stack Overflow

πŸ‘¨πŸ»β€πŸ’»

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

Apr 2, 2017, 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, 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](http://leafletjs.com) 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 funny 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 I don't have a personal license for it and

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, 11: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, 8: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:

func togglePreview() {
    if webView.isHidden {
        RenderPage()
        self.webView.alpha = 0.0
        self.webView.isHidden = false
        UIView.transition(with: webView,
                          duration: 0.33,
                          options: .curveEaseIn,
                          animations: {
                            self.webView.alpha = 1.0
                            self.entryStack.alpha = 0.0
        })
    } else {
        UIView.transition(with: webView,
                          duration: 0.33,
                          options: .curveEaseIn,
                          animations: {
                            self.webView.alpha = 0.0
                            self.entryStack.alpha = 1.0
        }) { _ in self.webView.isHidden = true }
    }
}

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 19, 2017, 12:08 AM

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 = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(timedServices), userInfo: nil, repeats: true);

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.

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    timer?.invalidate()
}

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.

.

πŸ‘¨πŸ»β€πŸ’»πŸ‘¨πŸ»β€πŸŽ€

Added an "Instant" Preview πŸ‘¨πŸ»β€πŸ’»πŸ‘¨πŸ»β€πŸŽ€

Feb 18, 2017, 11:42 PM

It took about a day of banging my head against the wall, a lot of research, and a ton of fighting "auto"layout but I managed to cook up a fairly solid auto-updating preview pane that even reads the CSS for the page.

I tried to use the built in "DownView" included with the MarkDown parser I'm using, but the View built into it seems to be a bit... glitchy and it turns out it's much simpler just to use a WebView and pipe the HTML the Markdown encoder cranks out directly. This works out better regardless because I can support the templates and CSS I use and actually preview the exact page output as I'll see it.

This adventure of course included the required struggle with autolayout and Interface Builder, but I think I'm starting to get the hang of it because it only took me an hour or so to work out how to get the webview added in the way I want. Lesson of the day is: Stack Views aren't as magical as Apple would have you believe. Overall I'm very happy with the results.