Skip to content

Instantly share code, notes, and snippets.

@rduplain
rduplain / calendar_summary.py
Created October 28, 2015 21:03
Provide simple CSV summary of calendar events in .ics file.
#!/usr/bin/env python3
# calendar_summary: provide simple CSV summary of calendar events in .ics file.
#
# Developed on python3.5 with:
#
# pip install click icalendar pytz
#
# Save calendar.ics from:
#
# Google Calendar: Calendar Settings > Calendar Details > Export Calendar
@rduplain
rduplain / linode-node-balancer-500-limitation.md
Last active November 1, 2015 04:20
Linode NodeBalancer: Passive health checks lead to many false positives.

Linode's NodeBalancer assumes (as of Apr 2015) that a 500 response means that the node should be removed from rotation. Naturally, exceptions happen, so this is a very serious design limitation for any application which allows its code to have uncaught exceptions. I have opened a support ticket, with discussion copied here.

Ultimately, we had to rewrite our 500 responses to a non-50x response, which is strange to our application, but at least the change was limited to an nginx config and a single line of JavaScript to handle our status code as a server error. Linode specifically advised to use a non-50x response. All we need is a configuration in the NodeBalancer to not use passive checks on 500 Internal Server Error responses. There is no such configuration.

Due to the head-scratching nature of this configuration, we used 418 I'm a teapot in place of 500 responses. In nginx:

proxy_intercept_errors on;

error_page 500 =418 /_error/internal-serve

@rduplain
rduplain / haproxy-servers.cfg
Last active June 10, 2022 13:23
Rewrite haproxy configuration and reload service.
# Edit this file then run `update-haproxy haproxy-servers.cfg`.
# Alternatively, use a shell pipeline to build server list `... | update-haproxy`.
server demo1 127.0.0.1:8001 check cookie demo1 weight 100
server demo2 127.0.0.1:8002 check cookie demo2 weight 100
server demo3 127.0.0.1:8003 check cookie demo3 weight 0
server demo4 127.0.0.1:8004 check cookie demo3 weight 0
@rduplain
rduplain / start_ventrilo.bat
Last active August 29, 2015 14:12
Wait, then launch Ventrilo, in order to include in autostart programs.
@echo off
title Waiting to Launch Ventrilo
rem Delayed launch ventrilo, since it does not as executable in Startup.
rem Sleep for 60s using a dummy ping.
ping 127.0.0.1 -n 60 > nul
start "Ventrilo" "C:\Program Files\Ventrilo\Ventrilo.exe" -cHOST:PORT:PASSWORD
@rduplain
rduplain / Vagrantfile
Last active August 29, 2015 14:07
Simple Ubuntu LTS vagrant.
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.hostname = "scratch1"
config.vm.box = "ubuntu/trusty64" # vagrantcloud, use vagrant 1.5+
# config.vm.box_url = "http://domain.com/path/to/above.box"
@rduplain
rduplain / wait.py
Last active August 29, 2015 14:06
Avoid race conditions by waiting for 200 OK on a URL.
import datetime as dt
import time
import requests # pip install requests
def get_ok(url):
"GET url and raise an exception if not 200 OK."
r = requests.get(url)
r.raise_for_status()
@rduplain
rduplain / receipt.py
Created August 12, 2014 03:09
Simple project to print text to Epson receipt.
# Print text to serial Epson printer. Escape codes are Epson ESC/POS.
#
# pip install pyserial jeni # Developed on Python 3.4.
import struct
import serial
from jeni import annotate, partial
from jeni import Injector
@rduplain
rduplain / README.md
Last active December 6, 2023 15:08
Demo of the Python `code` module, for interaction and DSLs.

import code

This is a demonstration of the Python [code][1] module, which allows for an interactive interpreter to be embedded into a Python program.

code.interact(banner=None, readfunc=None, local=None)

Convenience function to run a read-eval-print loop. This creates a new instance of [InteractiveConsole][2] and sets readfunc to be used as the

@rduplain
rduplain / gist:e637ac9205d7df82dff4
Last active August 29, 2015 14:02
python: method delegation and copy-able threading.Lock
from threading import Lock
def build_delegating_method(delegate_name, method_name):
def delegating_method(self, *a, **kw):
delegate = getattr(self, delegate_name)
method = getattr(delegate, method_name)
return method(*a, **kw)
doc_format = "Calls self.{}.{}."
delegating_method.__name__ = method_name
@rduplain
rduplain / isatty.py
Created June 3, 2014 14:34
Is stdin a tty? Use this to determine whether to provide prompt or just read stdin for input.
import sys
if sys.stdin.isatty():
print('you are a tty')
else:
print('you are not a tty')