Houndhub.co.uk (2017–2018)


Orchestration Designs (2018–ongoing)
- gitlab project page
A small collection of designs (in the form of a newsletter), specifically targeting an idea of providing a renderfarm management tool.
Temps.co.uk (2014)
- gitlab source page
A job board specifically designed for the temporary workforce; developed for multiple shakeholders using a basic microservice approach built on the Rackspace Platform, services were developed in golang with an Angular (1.x) UI/UX.

Architectural Lighting (2012–ongoing)
LED control box using embeddied HTTP server in a microcontroller.
Countryside Aura Marketing Site Phase 1
Domain Specific Language Configuration Sample
# Countryside Aura Marketing Site Phase 1
for site "aura-6" described as "Countryside Aura Marketing Site Phase 1"
use interface version 1
configure with
generated key
set all defaults as off
attractor, pulsar and test as on
markandtally
events and load as on
program with
generated key
baseurl is "/countryside/aura/phase1"
start led is 1
for led 1 to 46
map led to "/%03d/"
map
colour red to "/sold/"
colour white to "/aval/"
blank to "/"
attract of 2 leds with slow timing to "/attract/slow/"
attract of 5 leds with fast timing to "/attract/"
pulsar of 2 intervals with slow timing to "/pulsar/slow/"
pulsar of 8 intervals with fast timing to "/pulsar/"
reset to "/reset/"
Auto-Generated S-Expression Configuration Sample
;;; Auto-Generated 2014-03-28 20:10:15.155999462 +0000 GMT
;;; Machine Hal
;;; User mae
;;; Source /home/mae/local/work/pinhole.design/sites/countryside/aura/phase-1/lbox/aura-6.conf
;;;
;;; Countryside Aura Marketing Site Phase 1
(Config "aura-6" (1 "lightbox/api/v1") (
(key 927a74a4)
(info "Countryside Aura Marketing Site Phase 1" "2014-03-28T20:10:15Z")
(set attract on)
(set pulsar on)
(set accumulate off)
(set test on)
(markandtally (events on) (load on))))
(Program "aura-6" (1 "lightbox/api/v1") (
(key 9afc490c)
(info "Countryside Aura Marketing Site Phase 1" "2014-03-28T20:10:15Z")
(baseurl "/countryside/aura/phase1")
(start led 1)
(led 1 "/001/")
(led 2 "/002/")
(led 3 "/003/")
(led 4 "/004/")
(led 5 "/005/")
(led 6 "/006/")
(led 7 "/007/")
(led 8 "/008/")
(led 9 "/009/")
(led 10 "/010/")
(led 11 "/011/")
(led 12 "/012/")
(led 13 "/013/")
(led 14 "/014/")
(led 15 "/015/")
(led 16 "/016/")
(led 17 "/017/")
(led 18 "/018/")
(led 19 "/019/")
(led 20 "/020/")
(led 21 "/021/")
(led 22 "/022/")
(led 23 "/023/")
(led 24 "/024/")
(led 25 "/025/")
(led 26 "/026/")
(led 27 "/027/")
(led 28 "/056/")
(led 29 "/057/")
(led 30 "/058/")
(led 31 "/059/")
(led 32 "/060/")
(led 33 "/061/")
(led 34 "/062/")
(led 35 "/066/")
(led 36 "/063/")
(led 37 "/064/")
(led 38 "/065/")
(led 39 "/070/")
(led 40 "/067/")
(led 41 "/068/")
(led 42 "/069/")
(led 43 "/074/")
(led 44 "/071/")
(led 45 "/073/")
(led 46 "/072/")
(colour (255 0 0) "/sold/")
(colour (255 255 255) "/aval/")
(blank 0 "/")
(attract (2 slow) "/attract/slow/")
(attract (5 fast) "/attract/")
(pulsar (2 slow) "/pulsar/slow/")
(pulsar (8 fast) "/pulsar/")
(reset 0 "/reset/")))
Thecircuitboard.co.uk
Misc
Hello World in go
package main
import (
"bufio"
"flag"
"fmt"
"os"
"os/user"
"strings"
"time"
)
var (
Salutations = []string{"Hello $@", "Bye $@", "See you later", "Hi $@, how are you?", "The time is $T"}
)
func main() {
echo := flag.Bool("echo", false, "echo from standard input")
help := flag.Bool("help", false, "help description")
dmenu := flag.Bool("dmenu", false, "output list of salutations for dmenu")
salutation := flag.Bool("salutation", false, "use input as salutation template")
flag.Parse()
/* show usage and help */
if *help {
fmt.Fprintf(os.Stdout, "example usage :-\n")
fmt.Fprintf(os.Stdout, "\t./hello | ./hello -echo\n")
fmt.Fprintf(os.Stdout, "\tusing dmenu to choose saluation, ./hello -dmenu | dmenu -p \"salutation\" | ./hello -salutation\n\n")
flag.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(os.Stdout, "%6s | %s\n", f.Name, f.Usage)
})
os.Exit(0)
}
/* generate dmenu list */
if *dmenu {
for _, sal := range Salutations {
fmt.Fprintf(os.Stdout, sal+"\n")
}
os.Exit(0)
}
/* create a simple template function, we only template for
* username $@, stdin $_, and current time $T */
template := func(t string, u *user.User, now time.Time) string {
if strings.Contains(t, "$@") {
t = strings.Replace(t, "$@", u.Name, -1)
}
if strings.Contains(t, "$T") {
t = strings.Replace(t, "$T", now.Format("15:04"), -1)
}
return t
}
snip := func(in string) string {
if in[len(in)-1] == '\n' {
return in[:len(in)-1]
}
return in
}
/* gather information about the current user */
whoami, err := user.Current()
if err != nil {
goto hello
}
/* if in echo mode then read-in on standard input */
if *echo {
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
goto hello
}
fmt.Fprintf(os.Stdout, "[%s] says %q\n", whoami.Username, snip(input))
os.Exit(0)
}
if *salutation {
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
goto hello
}
fmt.Fprintf(os.Stdout, "%s\n", template(snip(input), whoami, time.Now()))
os.Exit(0)
}
/* otherwise say hello to the user */
fmt.Fprintf(os.Stdout, "%s\n", template(Salutations[0], whoami, time.Now()))
os.Exit(0)
/* this is generally bad form -- but it's a nice way
* to handle errors and give an expected reply.
*/
hello:
fmt.Fprintf(os.Stdout, "Hello there\n")
}
./hello -dmenu | dmenu -p "salutation" | ./hello -salutation
[select "Hi $@, how are you?" from dmenu]
Hi Alice, how are you?