Tutorials

Github pages is a very convenient way to host both personal websites, and project websites. Websites are linked to a git branch or repo, and update when pushed too. Github pages supports custom domains as well! Whilst Github Pages supports HTTPS for github.io websites, it does not support HTTPS when using a custom domain.

However, we can use a proxy server to allow us to use a custom domain with HTTPS! Both the connection between the client and the proxy server, and the proxy server and Github will be secure.

Whilst you lose the advantage of Github’s CDN, you still have the following advantages:

  • Websites are linked to a git repo, and you don’t have to worry about pulling changes and rebuilding the sites yourself.
  • Storage space is saved on the server.

Add CNAME file

This is recommended to make sure that example.github.io is redirected to example.com.

Create an NGINX proxy

Point your DNS to the proxy server instead of github.io.

Add the following virtual server to your sites file:

server {
	listen 443 ssl http2;
	server_name example.com;

	# Insert SSL specific settings here

	location / {
		proxy_pass https://example.github.io;
		proxy_intercept_errors on;

		# Makes us request example.github.io, instead of example.com
		proxy_set_header Host example.com;
		proxy_set_header X_FORWARDED_PROTO https;

		# Give GitHub control over caching headers
		expires off;
	}
}

# Redirect HTTP to HTTPS
server {
	listen 80;
	listen [::]:80;
	server_name example.com;
	return 301 https://$server_name$request_uri;
}

Setting up NGINX and SSL is out of scope for this tutorial, I’m assuming you know how to configure both. If not, have a look at installing NGINX and securing NGINX with Let’s Encrypt.

Make sure you add the domain to your certificate first.

Be warned that if you have HSTS enabled, you won’t be able to go back to HTTP.

I had an issue where CMake was failing on a compiler test with the following error:

error: unrecognized option '-rdynamic'

The problem was that CMake caches settings such as compiler flags in CMakeCache.txt, so you need to clear the cache when changing the platform. Do this by deleting CMakeFiles and CMakeCache.txt

It’s very hard to debug a crash when no stack traces are printed. It becomes a case of manually trying to find the error.

GET /foo/bar/
Doing something useful
Error: Expected } near ;

ES6 promises doesn’t seem to offer the functionality to change this, and bluebird has on[Possibly]UnhandledRejection, which can only be used if you don’t add a .catch() case to the promise. There is no global callback for a rejection unless it’s unhandled. To workaround this, we’re going to need to override the method which runs the callbacks. This is a little hacky, and relies on the library not changing - but it’s better than swallowing errors.

First, if you haven’t already, install Bluebird.

npm install --save bluebird

Next, make a file somewhere (perhaps called bluebird.js) with this as its contents:

const Promise = require('bluebird')

// Throw errors in promises rather than calling reject()
// Makes debugging A LOT easier
Promise.prototype._rejectCallback_old = Promise.prototype._rejectCallback
Promise.prototype._rejectCallback =
	function(reason, synchronous, ignoreNonErrorWarnings) {
		if (reason.stack) {
			throw reasong
		} else {
			this._rejectCallback_old(reason, synchronous, ignoreNonErrorWarnings)
		}
	}

module.exports = Promise

Alternatively you could just print reason.stack if it exists, however I prefer a full crash whilst debugging. You could also make it possible for promises to declare whether they should throw errors - similar to the throw keyword in Java - and print out the stack rather than crashing in that case.

Example output
Example output

Combines mats into a strip.

#pragma once
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <assert.h>

using namespace cv;

class MatStrip
{
public:
	Mat current;
	float scale;

	MatStrip(Mat start, float scale=0.3f):
		scale(scale)
	{
		resize(start, current, Size(start.cols * scale, start.rows * scale), 1.0, 1.0, INTER_CUBIC);
	}

	void add(const Mat &in_o)
	{
		Mat in;
		resize(in_o, in, Size(in_o.cols * scale, in_o.rows * scale), 1.0, 1.0, INTER_CUBIC);

		assert(in.type() == current.type());
		Size sz1 = current.size();
		Size sz2 = in.size();
		Mat im3(sz1.height, sz1.width+sz2.width, current.type());
		Mat left(im3, Rect(0, 0, sz1.width, sz1.height));
		current.copyTo(left);
		Mat right(im3, Rect(sz1.width, 0, sz2.width, sz2.height));
		in.copyTo(right);
		current = im3;
	}
};

Usecase: shells dropping in sync with firing, fake bullets, etc

You must use a particle emitter to create particles, however this doesn’t mean it’s impossible to create single particles on command. You can create a particle emitter which simply adds particles from a queue to the system

#pragma once
#include <SFML/Graphics.hpp>
#include <Thor/Math.hpp>
#include <Thor/Graphics.hpp>
#include <Thor/Particles.hpp>

namespace sfext {

class SingleParticleEmitter
{
	std::vector<thor::Particle> *particles;
public:
	SingleParticleEmitter();
	SingleParticleEmitter(const SingleParticleEmitter& that);
	void operator() (thor::EmissionInterface& system, sf::Time dt);

	void push(thor::Particle particle);
	void push(sf::Vector2f position, sf::Vector2f velocity, float lifetime, float rot=0, float rotsp=0);
};

}; // end namesapce sfext

The above allows you to use the push functions to emit particles. Here is an example of it in use:

SingleParticleEmitter single_emitter;
thor::ParticleSystem particle_system;
particle_system.addEmitter(single_emitter);

// When you need to emit a shell:

single_emitter.push(origin, velocity, 1.0f);
// lifetime of the particle in seconds --^

Here is the cpp file:

#include "singleparticleemitter.hpp"

using namespace sfext;

SingleParticleEmitter::SingleParticleEmitter()
{
	particles = new std::vector<thor::Particle>();
}

SingleParticleEmitter::SingleParticleEmitter(const SingleParticleEmitter& that)
{
	particles = that.particles;
}

void SingleParticleEmitter::operator() (thor::EmissionInterface& system, sf::Time dt)
{
	for (auto particle : *particles) {
		system.emitParticle(particle);
	}
	particles->clear();
}

void SingleParticleEmitter::push(thor::Particle particle)
{
	particles->push_back(particle);
}

void SingleParticleEmitter::push(sf::Vector2f position, sf::Vector2f velocity, float lifetime, float rot, float rotsp)
{
	thor::Particle particle(sf::seconds(lifetime));
	particle.position = position;
	particle.velocity = velocity;
	particle.rotation = rot;
	particle.rotationSpeed = rotsp;
	particle.scale = sf::Vector2f(1.f, 1.f);
	particle.color = sf::Color::White;
	particle.textureIndex = 0u;
	push(particle);
}

Simply get the SFGUI window size using GetAllocation, the sfml window size using getSize, then do this arithmetic:

auto window = sfg::Window::Create();
auto win_rect = window->GetAllocation();
sf::Vector2f size(win_rect.width, win_rect.height);
window->SetPosition(((sf::Vector2f)rwindow->getSize() - size) / 2.0f);

This tutorial will show you how to create a new MonoDevelop solution and project, and how to properly connect it to RimWorld. You’ll need to have an installation of Mono that supports .NET 3.5 - here is a tutorial on how to install it.

This tutorial will show you how to install Mono and Monodevelop in order to develop .NET 3.5 projects. This is useful when writing C# assembly mods for Unity engine based games, such as RimWorld, as they tend to require .NET 3.5.

Now that Github supports unlimited private repos in all plans, you might as well keep things all together (although definitely have backups elsewhere incase Github is DDOS’d again, dies or goes evil). Simply change “rubenwardy” to your username and “XXXX” to a personal access token with “repo” checked. Also make sure you have an SSH key for Github.

# Clone from bitbucket
git clone git@github.com:samkuehn/bitbucket-backup.git
mkdir bk
cd bitbucket-backup
./bitbucket-backup -u rubenwardy --mirror -l ../bk

# Upload to GitHub
cd ../bk
for D in *;
do
	echo $D
	cd $D
	data="{\"name\": \"$D\", \"auto_init\": false, \"private\": true }"
	curl -i -H 'Authorization: token XXXX' -d "$data" https://api.github.com/user/repos
	git push --mirror git@github.com:rubenwardy/$D.git
	cd ../
done
cd ../

I use a dual monitor setup. For each monitor I have a panel, and each panel has a whisker menu. I found that the favourites section of each of these panels is not synchronised. To fix this, I wrote a simple script.

First, you have to decide which whisker config to keep.

$ cd ~/.config/xfce4/panel/
$ ls
whiskermenu-1.rc  whiskermenu-9.rc

The favourites menu is stored at the top of each file, like this:

$ head -n1 whiskermenu-1.rc
favorites=firefox.desktop,google-chrome.desktop,hexchat.desktop,exo-file-manager.desktop,libreoffice-writer.desktop,libreoffice-calc.desktop,exo-terminal-emulator.desktop

Find the one you want to keep. From this point on, replace whiskermenu-1.rc with the config you want to keep and whiskermenu-9.rc with the one you want to ditch.

The script is as simple as this:

#! /bin/bash

rm -f ~/.config/xfce4/panel/whiskermenu-9.rc
cp ~/.config/xfce4/panel/whiskermenu-1.rc ~/.config/xfce4/panel/whiskermenu-9.rc
xfce4-panel -r

If you save that to /usr/local/bin/syncwhisker, then you can use “syncwhisker” in the terminal to keep your menus the same.

I recently successfully dual booted Ubuntu on an ASUS X555LA laptop, the X555LAB variety. This guide will work on most Ubuntu derivatives, I installed Xubuntu using these steps. The only things that are different between them are window managers and preinstalled software.

This article will show you how to verify a user’s identity by letting them associate their account with an external third party phpBB account. I used Python and Flask to achieve this, however any language and framework should work, and shouldn’t be too hard to port to.

I recently wrote and released a python module to allow fetching of profile data. You can install it using pip:

pip install beautifulsoup4 phpbb-parser

Here’s how you import and use a profile:

import phpbb_parser as parser

username = "rubenwardy"
profile = parser.get_profile("https://forum.minetest.net", username)

if profile:
	signature = profile.signature.text
	location = profile.get("location") or "unknown"
	github = profile.get("github") or "none"

	print(username + " from " + location + " has github " + github)
	print("Signatue: " + signature.text)
else:
	print("Could not get profile!")

profile.signature is a beautifulsoup4 object.

Next: Linking a user account to an external phpBB forum.

Here is a shell script specific for GNU/Linux based operating systems to use. On different operating systems the convert commands will be the same, but the for loop will be different due to a different batch file syntax.

rm /tmp/imageex -r
mkdir /tmp/imageex
for filename in *.png; do
	echo "Processing $filename"
	convert $filename -background White \
		label:$filename -gravity Center \
		 -append -pointsize 14 \
		/tmp/imageex/$filename.png
done
echo "Exporting to PDF..."
convert /tmp/imageex/*.png output.pdf
echo "Done."

My blog uses the Jekyll static site generator. This blog post will show you how I implemented the tag system on this blog, without installing any modifications or plugins. My blog is hosted on GitHub pages, so this is a requirement.