Flask basics – setting environment variables

Lots of Flask tutorials recommend setting environment variables to protect any private information stored in the settings of the app. This is good advice, it only takes a moment of inattention to commit sensitive information to your GIT repo and then push it to a public place such as GitHub.

If you’re using a virtualenv (if you’re not I recommend you go and fix that before you polute your local python environment too badly to recover it) this is a really simple thing to do:

Open the postactivate file in the virtualenv you’re using in your text editor of choice eg: vim ~/.VirtualEnvs/VENV/bin/postactivate

Add your variables to the bottom of the file, one on each line in the following format: export VARIABLE_NAME='whatever_you_want_here'.

Activate your virtualenv and check that your variables have been loaded by using echo $VARIABLE_NAME.

Now whenever you start your venv your environment variables will be available.

Inkscape experiments: tesselate an SVG then crop to size

Inkscape doesn’t really have a crop function, it’s intended to be non-destructive, but, if you’re using it to laser cut then sometimes you really want to chop a section out of a bigger object or pattern, for example if you want to cover the whole side of an object with a pattern.

Depending on which laser cutter software you’re using this might not be a problem as some work from the rendered area only. Unfortunately if you use the usual method:

  • group the objects you want to clip
  • create a mask in the shape you want the final view to appear
  • Select both things and use `object` > `clip` > `set`

Then when you export your neatly clipped pattern to Visicut all of the vector outside the masked area will reappear. This is extremely frustrating.

This evening one of Hackspace Manchester’s members was getting frustrated trying to crop a tesselated svg of a Gosper curve downloaded from Wikipedia, so that they could laser etch the resulting pattern across the side of a box.

It turns out, after a bit of faffing that it’s totally possible to do this but it does require some quite specific steps to be followed. First, tesselate your image:

Once you’ve done that:

  1. select everything (ctrl+a)
  2. use path > combine to make the mess into a single object
  3. use path > stroke to path to create a pattern that can have sections cut out of it. (This takes a while to complete.)
  4. create a shape that matches the area you want to map your pattern to and place it over the section of the pattern you want to use:
  5. select all again and use path > Intersection to crop the pattern to the shape you want.
  6. send to your laser cutter 🙂

As you can see from the close up, pushing the tesselated pattern through stroke to path has resulted in the laser cutting both sides of the line rather than just the lines themselves. It’s pretty, but wasn’t quite what we meant!

SSH – why can I never remember this stuff?

This is a short post containing all the useful ssh stuff I forget on a distressingly regular basis.

Where are my damn SSH keys anyway?

Unless you need to generate yourself some new ones they’ll be in ~/.ssh

If you need to make some run: ssh-keygen and follow the instructions – need more detail? Digital Ocean’s How to Configure SSH Based Authentication on a Linux Server walks you through the whole process.

Where do I put my public key?

It needs to end up in ~/.ssh/authorized_keys on the computer you’re aiming to log in to. The simplest way to do this (if you can) is to use ssh-copy-id [email protected] which scans your local account for your id_rsa.pub file and copies it across to your end point.

If you can’t do it that way then you’ll need to cat ~/.ssh/id_rsa.pub and paste the result either directly into your authorized_keys file or into the appropriate GUI box in the servce you’re trying to access (GitHub for example).

If you cant use ssh-copy-id but do have password based SSH access you can use the following command to cat the file directly onto your server:

cat ~/.ssh/id_rsa.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Raspberry Pi Setup: tools to make your life better

If you set up a lot of Raspberry Pis you start searching for tools to make your life easier. Here are a few of mine:

Mini keyboard and mouse combo

Although I mostly set things up headless, occasionally it’s helpful to have a USB keyboard and mouse that you can simply plug in and go. MInes looking a little battered now but it still works really well and because it’s so small I can easily carry it around to assist me when I’m setting things up on site. Amazon link (not the exact one I have): Rii i8+ 2.4Ghz LED Backlit Mini Wireless Keyboard With Touch Pad Mouse.

MicroSD > USB adapter

I can’t begin to tell you how much better this tiny gadget has made my life. The standard adapters are erratic, and easy to lose – although I have at least 4 of them, this is consistent and mine convieniently has a little flashing light on the side so that I can see what it’s doing. Get yourself one from amazon (this isn’t the exact one I have): sourcingmap Mini Compact M2 MicroSD USB 2.0 Memory Card Reader

Apple Pi Baker

MacOS only (sorry everyone else) this is a free tool for writing, freezing and restoring Raspberry Pi disk images. It took around 30 minutes to copy a disk image onto a fresh sd card, when I did the same thing using dd it took 3 hours! Download it direct from Tweaking4All.com

Adding a shutdown button to your Raspberry Pi Flask App

If you’re running a Flask App on your Raspberry Pi in Kiosk mode you may find that you want to add a shutdown button to the ensemble so that you can switch the Pi off safely without having to SSH into it and manually issue the shutdown command.

Based on Adding a Shutdown Button to the Raspberry Pi B+

The Hardware

  • a momentary button
  • a breadboard
  • a couple of jumper wires
  • a raspberry pi (I’m using a 3)

Wire the momentary switch up to Pin 18 and Gnd of the Raspberry Pi. As it’s a momentary switch it doesn’t matter which way around the wires are.

The Python Script

So, to make this button do anything you need a fairly short python script

import RPi.GPIO as GPIO
import os

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def shutdown(channel):
    os.system("sudo shutdown -h now")

GPIO.add_event_detect(18, GPIO.FALLING, callback=shutdown, bouncetime=2000)

Break the code down a little

  • GPIO.setmode(GPIO.BCM). This is where you decide whether you want to use the GPIO numbers (BCM – which change with different revisions of the Raspberry Pi or the board numbers (BOARD) which correlate to the numbers actually printed on the Pi. If you fancy going deeper into this there’s a clear and consise explanation of the difference between the two settings in this Stack Exchange answer and a very useful walkthrough of using the GPIO header and pins on Raspberry Pi Spy.
  • GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP). This sets up the channel number (acording to the schema you specified in the previous line, whether it’s an input or and out put and whether it’s pulling up or down (for down use PUD_DOWN.
  • Shutdown function – what you want to do when the interrupt fires.
  • the event_detected() function – this is where the really cool stuff happens. According to the Rasperry Pi GPIO wiki:

    The event_detected() function is designed to be used in a loop with other things, but unlike polling it is not going to miss the change in state of an input while the CPU is busy working on other things. This could be useful when using something like Pygame or PyQt where there is a main loop listening and responding to GUI events in a timely basis.

    This is also why it’s really useful to us.

    What we’re setting up:

    • the channel (again, acording to the schema you specified earlier).
    • which bit of the signal we’re looking for
    • the callback
    • how long we should wait to debounce.

If you transfer this to your Pi and run it (python /route/to/file/rpi_shutdown.py) when you press the button your Pi should shut itself down. You may need to pip install RPi.GPIO to make it work especially if you have an active virtualenv.

Adding the shutdown functionality to your Flask App

In the original tutorial this is called from /etc/rc.local so that it’s accissible from everywhere, unfortunately Python threads really badly and, if you’re using a virtualenv then the chances of it working at all are slim to none so you want to add the watcher to your flask app. This isn’t actually difficult to do but where you do it will depend on whether or not your app is modular. You need the function to be called in the whereever you initialise your app. In my case this is usually in a file called something like run.py which I use to call all the rest of the functions.

run.py

# shutdown button imports
import RPi.GPIO as GPIO
import os

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)


def shutdown(channel):
    os.system("sudo shutdown -h now")


if __name__ == '__main__':
    # initialise the button inside the main loop
    GPIO.add_event_detect(18, GPIO.FALLING, callback=shutdown, bouncetime=2000)
    app.run()

Now when you run your app you’re also setting up the gpio for the shutdown button so you can arbitrarily shutdown the pi from inside your app. Very useful if you’re running in kiosk mode.

Urbex: South Marsden Hotel

Today I went for a wander around South Marston Hotel with Joe of Loath, Skippy and theorbtwo.

The hotel went into administration in July 2016, 3 months before it was due to close leaving “[h]undreds of guests and more than 1,000 leisure members … [without refunds] for […] bookings already made” (source: Swindon Advertiser) and leaving the 45 employees without wages for the month.

The majority of the assets were auctioned off leaving many of the rooms with lot numbers above the doors and what remains has been trashed by the removal of any and all saleable goods (mostly copper, lead and hard wood).

The site has a registered planning application dating from November 2015 (yup that’s before the closure was announced) for the demolition of the existing hotel buildings and redevelopment to provide up to 70 dwellings. So it’s unlikely that these (now) scruffy buildings will be here much longer.

Joe of Loath did a good job of documenting the state of the property in his report. So the majority of my photographs focus on details, things that amused or saddened me.


Somehow the swimming pool in the spa complex is more of less intact – the retaining rail around the baby pool (pictured) is missing which, combined with the depth of the pool next to it makes it faintly terrifying. As Joe said, the entire hot tub has been removed and the presence of demolition detritus in the pool itself reminds me a little of a drained canal. Albeit one that has less mud than usual in it.


It almost feels like the wilful destruction of this motivational quote on the wall in the not-so-soft-anymore-play area is a commentary on society.


This is from the balcony cafĂ© adjacent to the softplay. Given the state of the place (there is rotten food heaped next to one of the walk in fridges in what remains of the kitchen area – be grateful I can’t post smells), I think I’d rather they didn’t.


Decorations: hundreds of them, ghosts of Christmases, halloweens, easters. At one point we had to walk over fake trees in order to pass through a corridor. Another missed photograph there.


The majority of the office area rooms are filled with the what didn’t sell in the auction, there is very little that is personal here – with the exception of the personnel files – it’s corporate furniture, corporate crockery – corporate, impersonal junk.


Joe doesn’t remember that being there. Looks like a previous explorer might have forgotten it. While we’re on the subject of previous explorers…


I feel like this in rooms full of mirrors a lot.


These are the kitchen in the on site flat. Very low ceilings and just as trashed as the rest of the site.


I find the very existence of this sign both worrying and telling of the state of the hotel prior to it’s closure. This is on the “out” door from the kitchen.


What remains of the cellar (the place where they stored the alcohol, it’s not actually underground).


Possibly the most post-apocalyptic part of the whole site.

Judging by the difference between the first lot of photos taken by Joe and what we saw today this site is getting destroyed pretty quickly. I know it looks like a horrible mess, but, if you visit please please don’t destroy it further.

3D Printing with Ninjaflex on a Mendel90

Today, for the first time I tried printing with Ninjaflex. Having not printed with it before, I was a little concerned that it might prove a touch difficult. It really didn’t, but I did learn that most people set their printers to run a lot hotter and faster than I do.

Printer: Mendel90
Filament: 3mm Ninjaflex in blue

Before I started I did a bit of reading around the subject:

Based on the advice in those articles (and a test print at 195°C which failed to extrude properly) I tried the following settings:

  • Print speed: 30mm/s
  • Printing temperature: 210°C
  • Bed temperature: 50°C
  • Retraction:
    • Minimum travel: 1mm
    • Z hop when extracting: 0.1mm

If you would like the full profile I used it’s here: https://raw.githubusercontent.com/HACManchester/cura-settings/master/ninjaflex.ini

I coated the bed in dilute PVA just as I would if I were using PLA in the printer although it appears you can also get good results using blue printers tape or possibly even nothing on the bed.

2016-08-18 14.52.57

The final print is a bit bobbly in places but has generally come out pretty well:

2016-08-18 15.53.59 2016-08-18 15.54.11

JQuery snippet: automatic highlights

Sometimes you want to highlight a word automagically without having to go through and manually add <span> tags all over the place. Of course you also want to do this without breaking anything else that has been wrapped in a <p> tag. Ahem, WordPress I’m looking at you.

The first line of this iterates over every single <p> tag on the page.

The if statement then checks to see whether or not the paragraph in question actually contains the phrase and if it does replaces the sections of it that contain the phrase with the alternative text.

NOTE: if you don’t nest the actual replace within a $(this).html(); call what you end up with is just the text being returned and any child elements (e.g. p or img elements being removed from the DOM. This might not bother you if you’re working with a site only you are ever likely to update because you will be aware of the issues, however, if you’re working with clients you probably want to make sure nothing unexpected is going to happen.

(function($) {
  $('p').each(function() {
    var search_this = $(this).text();
    if (search_this.indexOf('Highlight phrase') >= 0) {
      $(this).html($(this).html().replace(/Highlight phrase/g, "<span>Highlight </span> phrase"));
    }
  });
})(jQuery);

Obviously this wont highlight any instances of the word “highlight” that have been incorrectly spelled but that, is a different problem.

WordPress Basics: get recent featured images by category

Sometimes you want to have an image slider which not only contains the most recent images on your site but does so by category to ensure that all of the categories on your site are included:

First get the categories:

$categories=get_categories();

By default this returns the categories in alphabetical order and ignores any empty ones. That’s fine by me so I’m not going to fiddle with it.

Now we’ve got our categories we need to loop over them. Don’t forget to close your foreach!

 foreach ($categories as $category) :
    # code here
endforeach; 

Inside that foreach loop we’re going to run a new WP_Query(), first though we need to set up our args:

$args = array(
            'cat' => $category->term_id,
            'post_type' => 'post',
            'posts_per_page' => '5'
          );

This pulls out the first 5 posts in each category. Once we’ve done that we can run our WP_Query().

$images_query = new WP_Query( $args );

if ( $images_query->have_posts() ): ?>
    <?php while ( $images_query->have_posts() ) : $images_query->the_post();
        if ( has_post_thumbnail() ) :
            the_post_thumbnail('post-thumbnail', array("class" => "slider_image"));
endif; endwhile; endif;?>

Excluding a category

In this example I don’t want to pull out featured images associated posts in the category 'Blog' so I added

&& $category->cat_name != 'Blog'

to the if statement inside my query.

Argh! I have posts in more than one category and the images are duplicating

To get rid of duplicate posts add the following on the line above your call to get_categories:

$do_not_duplicate = array()

Then, under $images_query->the_post(); add

$do_not_duplicate[] = $post->ID;

Now, that we have an array containing the ID’s of the posts that have already been pulled we can add a line to our $args to make the query check it:

$post__not_in => $do_not_duplicate

Voila, no more duplicate images.

Flask basics: lose the favicon 404

If the fact that the Flask development server cant find your favicon annoys you shove your favicon into your static folder and do this:

@app.route("/favicon.ico")
def favicon():
    return(url_for('static',filename='favicon.ico')

NOTE: this is one of several ways of getting rid of that particular error and is the one I’m using today. I’ll add more as I use them.