Apply Gmail label to message that contains string in body

July 9th, 2013 No comments

Unfortunately gmail filters do not allow you to search just the body in a filter. IE body:myname is not valid. If your email address is and you want to label all mail that contains First in the body, you cannot create a filter that works. You can however create a google apps script that will do it.

1. Go to, select Create script for Gmail.

2. Change label_name and name below then paste into google scripts.


function label_mention_in_body() {
  var label_name = 'YourLabel';
  var name = 'YourName';
  // I ignore name followed by . because 
  // my name is in my email address and I don't want that to count
  var regex = new RegExp(name + '[^.]', 'gi');
  // get all threads in inbox
  var threads = GmailApp.getInboxThreads();
  for (var i = 0; i < threads.length; i++) {
    // get all messages in a given thread
    var messages = threads[i].getMessages();
    // iterate over each message
    for (var j = 0; j < messages.length; j++) {
      var body = messages[j].getBody();
      if (body.match(regex)) {
        Logger.log("Adding label " + label_name + " to " + messages[j].getSubject() + " from " + messages[j].getTo());  
        var thread = messages[j].getThread();
        var label = GmailApp.getUserLabelByName(label_name);

3. From the toolbar click Run -> label_mention_in_body

Assuming that did the right thing, you can now create a trigger to run this.

4. From the toolbar click Resources -> Current Project’s Triggers

5. Click add a new trigger. Change the drop downs to run every minute.

Done! It would be nice if you events could be OnNewMail or something, but this is better than nothing. I whipped this up pretty quick having never used google app scripts before. Pretty neat. Granted if this account had the ability for me to enable IMAP, I would have tried to set this sort of thing up with procmail.

Velocity 2013 Standout Presentations

June 21st, 2013 No comments

Here are the presentations and people that stood out to me from Velocity 2013 conference. Definitely worth stalking all these folks. Great talks and ideas!

Facebook: Building A Billion User Load Balancer

How To Run a Post-Mortem With Humans (Not Robots)

The Secret of Safe, Continuous Deployment: Perceptual Diffs
Tool + Video:

Stop the Guessing: Performance Methodologies for Production Systems

Application Resilience Engineering and Operations at Netflix

Quantifying Abnormal Behavior

Bring the Noise: Making Effective Use of a Quarter Million Metrics
Video of what appears to be same presentation:

Categories: Uncategorized Tags: ,

Deploy Status Box using Raspberry Pi, LEDs, and Erlang

February 27th, 2013 No comments

Over the weekend I decided to put together a small project using a Rasbperry Pi. One way of monitoring deployments at my company is IRC. I thought it would be neat to put together a Raspberry Pi to run erlbot and a plugin to toggle a couple LEDs to tell me when a deployment is in progress and when there was a problem with the deployment. (Note problem does not mean downtime, it just means a potential rollback or unexpected behavior during deployment which is transparent to our users). Here is the result:

pi_deploy (5)

pi_deploy (1)

pi_deploy (4)

pi_deploy (2)

There is a ton of helpful information out there on the Raspberry Pi. Here are a few links I found useful:

Beginner’s Guide to Raspberry Pi
LED tutorials: 1, 2, 3
Ten More Awesome Projects for your Raspberry Pi

I couldn’t find any Erlang modules for the Raspberry Pi to control LEDs on the Raspberry Pi, but I did find this post which pointed out you just write 1 or 0 to a file to toggle the LED. This is the basis of the led_controller.erl I wrote. You need to be root to write do anything with these files, but I wanted to run my Erlang script as a non-privileged user. Here is what to do if you want to control the LEDs while running as a normal user.

At your shell:

# Add user group gpio
sudo addgroup gpio
# Put pi user in group
usermod -a -G gpio pi

Next we update rc.local so we set our pins to work as outputs on boot and give the pi user the proper access. Note I’m using GPIO pins 17 and 22. Replace those numbers with whatever pins you use. Put this in /etc/rc.local before exit 0:

# Use pin gpio17 as output
echo 17 &gt; /sys/class/gpio/export
echo out &gt; /sys/class/gpio/gpio17/direction
# Allow users in gpio group to toggle pins
chgrp gpio /sys/class/gpio/gpio17/value
chmod g+w /sys/class/gpio/gpio17/value
# Use pin gpio17 as output
echo 22 &gt; /sys/class/gpio/export
echo out &gt; /sys/class/gpio/gpio22/direction
# Allow users in gpio group to toggle pins
chgrp gpio /sys/class/gpio/gpio22/value
chmod g+w /sys/class/gpio/gpio22/value
# This was there already
exit 0

You’ll need to run those lines as root or reboot before it will work.  If you have your LEDs wired up and you’ve run the above, you can verify it works:

# Turn LED on pin 17 on!
echo 1 > /sys/class/gpio/gpio17/value
# Turn it off!
echo 0 > /sys/class/gpio/gpio17/value

Finally if you want to toggle or blink LEDs in Erlang, here is the led_controller.erl I wrote.

You can try it at the erl shell:

% Compile module
% Start led controller module (My Red LED is on pin 22, Green on 17)
led_controller:start_link([{red, 22}, {green, 17}]).
% Turn on the green led
% Blink the green led 10 times. When done it returns to previous state, on
led_controller:blink(green, 10).
% Blink the red led 5 times. When done it returns to previous state, off
led_controller:blink(green, 5).
Categories: Uncategorized Tags: , ,

erlbot: The Erlang IRC Bot

February 20th, 2013 No comments

I recently took a month long introductory course on Erlang. Erlang is a functional language. The closest I’ve come to functional programming is XSLT, so this was quite different for me. Erlang excels at concurrency and fault tolerance. It has made me think differently about how to solve problems which is always great. If you’re interested in Erlang, there is a great free tutorial Learn You Some Erlang

The project I decided to create to help me learn Erlang is an IRC bot. When I first went on the internet in 1995 or so, IRC was one of the first things I found and loved. My network of choice was EFnet. At the time, I recall it was somewhat lawless. People constantly warring over nicks and channels. People were always trying to flood each other off. It was a bit of an arms race. You ran scripts to protect yourself from other users. I bet one of the earliest uses of botnets was IRC. The original purpose was so you could steal a channel or keep one. Thanks to the internet, the world is a lot smaller now. IRC was one of the early technologies that helped regular people connect with each other across the world.

Like many organizations, the one I work for has offices all over the world. I’m on a team that has members in multiple locations. One old, but great way we keep connected is IRC. Different teams have different channels, but you’re free to watch or contribute to the conversation of any group. We use Google Hangouts to do our standups, but everyone I work with uses IRC for fast and easy communication throughout the day. Some people prefer to use an instant messenger client, but I always try to move those conversations to IRC. When you have conversations in a shared space, other people get a chance to listen in and contribute.

Erlbot is no HUBOT (yet). But it is a fun way to learn Erlang for me. I will be maintaining the bot at github:

Features so far:
- Fault tolerance – Using Erlang’s supervisor behavior, an error in a plugin or part of the bot won’t bring the bot down
- Uptime – Erlang supports hot code loading and I’ve built the plugin system to allow the addition of plugins while running
- Extensibility – Plugins!
- Evangelize Plugin – erlbot will send a random fact to the channel when someone mentions Erlang

My one Erlang tip is Reloader from mochiweb. I added this to my erlbot source code and now the first thing I do when I launch the erl shell is reloader:start_link(). This will automatically reload beam files when they are recompiled (say using ./rebar compile).

Categories: Uncategorized Tags: ,

Running Django on Windows: Python 2.7.2 x64, PyISAPIe and IIS 7.5

March 13th, 2012 4 comments


Ok so I wanted to try serving Django from IIS 7.5 using Python 2.7.  The advice available says to install PyISAPIe.  Unfortunately there is not a compiled version of this available for Python 2.7 (x64 in my case).  geographika has a great post on compiling one yourself.  The following instructions are based on his guide, updated with newer versions.  If you don’t want/can’t compile it, here is my compiled version: PyISAPIe-trunk-r201-Py2.7.2×

Install Python

I did this on Win2k8 R2 Standard with VS2010.

I used ActiveState’s Python from (Windows 64bit

Install Python

Compile PyISAPIe

(or you can skip this and unzip PyISAPIe-trunk-r201-Py2.7.2× into c:\PyISAPIe (remove the PyISAPIe-trunk-r201-Py2.7.2×64 folder)

cd \temp

# If you want to duplicate what I’m doing exactly add -r 201 to get the revision I got

svn co pyisapi-trunk

robocopy c:\python27 pyisapi-trunk\Python\x64\Python27 /mir

open pisapi-trunk\PyISAPI.sln in VS2010

Change target to Release|x64

Right click PyISAPIe project, Properties, Configuration Properties->C/C++

Change Preprocessor PYI_PY_VERSION=PY_27 to PYI_PY_VERSION=PY_27_2

Open PyISAPIe.h and insert the following after #define PY_27

#define PY_27_2   (PY_27 + 2)


I got a couple of IntelliSense errors, but you can safely ignore those.

PyISAPIe.dll is produced under pyisapi-trunk\x64\Release

mkdir c:\PyISAPIe

copy pyisapi-trunk\x64\Release\PyISAPIe.dll c:\PyISAPIe

# Case may be important here

robocopy pyisapi-trunk\PyISAPIe\Python\Http c:\PyISAPIe\Http

Configure Website

Edit the properties -> security settings of c:\pyisapie\PyISAPIe.dll, add “Network Service” and tick “read” permission. (So IIS can use it).

# This is where we’ll put our python web app

mkdir c:\inetpub\PyApp

copy pyisapi-trunk\PyISAPIe\Python\Examples\ c:\inetpub\PyApp

Open IIS Manager

Create new site called PyApp, set physical path to c:\inetpub\PyApp, set port to 8090 (or whatever is unused)

Select PyApp, Handler Mappings->Open Feature

Click Add Script Map” with the following setting
Request Path = *
Executable = C:\PyISAPIe\PyISAPIe.dll
Name = PyISAPIe

Ok now browse http://localhost:8090/ and it should work!

Install Django

Download Django 1.3.1 from

Extract and run python install

cd c:\inetpub\PyApp

# Create test Django project startproject djangotest

Stick the following in djangotest\

from django.http import HttpResponse
def index(request):
    return HttpResponse("Hello world!")

Replace djangotest\ with:

from django.conf.urls.defaults import *
urlpatterns = patterns('',
    # Example:
    # (r'^newtest/', include('')),
    (r'^.*$', 'djangotest.helloworld.index'),
    # Uncomment this for admin:
#     (r'^admin/', include('django.contrib.admin.urls')),

python djangotest\ runserver

now browse to to make sure the internal Django server serves the site ok

Before Django will work in IIS, you need just a couple more steps.

copy /y c:\PyISAPe\Examples\Django\*.py c:\PyISAPIe\Http

Now edit C:\PyISAPIe\Http\ after ‘Import DjangoMap’ add:

import os
# Probably a better way to do this, but this will get us going!

then jump down a bit and replace the following:
["/1" , "mysite1.settings" ], # first Django app
["/djangotest" , "djangotest.settings" ], # first Django app

Ok now try browsing http://localhost:8090/djangotest (or whatever port you configured the site on). You should see “Hello World!”. As geographika noted, you will need to recycle the PyApp app pool if you change any files on disk. I may try his modifications on’s Request method to get immediate feedback.

That seemed to have done it. I’ll try to post an update after I’ve been using it a bit.

Very Helpful Links

Compiling a 64bit Version of PyISAPIe –

Setting up Python on IIS7 –

Django Tutorial –

My Compiled PyISAPIe for Python 2.7.2 x64 – PyISAPIe-trunk-r201-Py2.7.2×

Categories: Uncategorized Tags: , ,

The specified baseline is not the latest baseline, so it may not be checked out. Checkout of ‘/svn/yourrepo/!svn/bln/123456′: 409 Conflict (

February 21st, 2012 No comments

Are you getting “The specified baseline is not the latest baseline, so it may not be checked out.  Checkout of ‘/svn/yourrepo/!svn/bln/123456′: 409 Conflict (” when trying to commit to Subversion?  I’ve setup a Subversion write-through proxy to improve multi-site performance.  Unfortunately this seems to be one of the downsides.

The solution to the above is to update and try committing again.  It is possible you may need to wait until your write-through proxy has synced with the master before it will work.

Categories: Uncategorized Tags:

PowerShell Log function with word wrapped output to the screen

February 16th, 2012 No comments

I like to have logging in most scripts I write, and this is the current incarnation of my logging function. It logs to c:\location\of\script.ps1.log (or wherever/whatever your script is named). It uses write-host to output a word wrapped version of the text to the screen. It reads in the window size to determine the best place to cut up the sentence.

# Name of the currently executing script
$ScriptName = $MyInvocation.MyCommand.Path 
# Simple log file name, OurScriptName.ps1.log
$LogFile = $ScriptName + ".log"
# Word wrap function, return word wrapped version of passed string
function WordWrapStr($str)
	# Holds the final version of $str with newlines
	$strWithNewLines = ""
	# current line, never contains more than screen width
	$curLine = ""
	# Loop over the words and write a line out just short of window size
	foreach ($word in $str.Split(" "))
		# Lets see if adding a word makes our string longer then window width
		$checkLinePlusWord = $curLine + " " + $word
		if ($checkLinePlusWord.length -gt (get-host).ui.rawui.windowsize.width)
			# With the new word we've gone over width
			# append newline before we append new word
			$strWithNewLines += [Environment]::Newline
			# Reset current line
			$curLine = ""
		# Append word to current line and final str
		$curLine += $word + " "
		$strWithNewLines += $word + " "
	# return our word wrapped string
	return $strWithNewLines
# Log function, append passed string to log file
function Log([string]$logline)
    $timestamp = Get-Date -f "yyyy-MM-dd HH:mm:ss"
    $StdLogLine = "$timestamp&gt; $logline"
	# Add the log line to our log file in ascii with timestamp
    Add-Content $LogFile $StdLogLine -encoding ascii
    # Print to the screen the word wrapped version (no timestamp)
	write-host (WordWrapStr $logline)
Log "This text will first be appended to $LogFile, ascii encoded.  Also cut up the text and print it out word wrapped to the screen.  It works even with really long lines."

Example with and without word wrapped write-host:

Categories: Uncategorized Tags:

Batch file bootstrap PowerShell script for easy double click running

February 16th, 2012 No comments

The scenario is you have a PowerShell script that takes no paramaters and prompts the user for all the information it needs. How do you make it extra simple for people to check it out of source control and run it?

You have 1 .bat or .cmd file in the root of the folder. Create a subfolder like internal and put all your ps1 files in there. Here is what I put together so you could just double click the .bat/.cmd file and have your PowerShell script execute without worry.

@echo off
REM Check to see if Powershell is in path
for %%X in (powershell.exe) do (set FOUND=%%~$PATH:X)
if not defined FOUND (
	echo Please install PowerShell v2 or newer.
	exit /b 1

REM Check to see if we have powershell v2 or later
PowerShell.exe -command "& { if ($host.Version.Major -lt 2) { exit 1 } }"
	echo Please upgrade to PowerShell v2 or later.
	exit /b 1

REM Set scriptDir to directory the batch file is located
set scriptDir=%~dp0
echo Running powershell.exe %scriptDir%internal\MyScript.ps1
REM Note the RemoteSigned in case the system is defaulted to restricted
powershell.exe -ExecutionPolicy RemoteSigned -command "& { "%scriptDir%internal\MyScript.ps1"; exit $LastExitCode }"
if "%ERRORLEVEL%" NEQ "0" (
	echo There may have been a problem with MyScript.  Please read the above text carefully before exiting.

After replacing MyScript with the name of your script, stick the contents in MyScript.cmd in your main directory. Make sure you have your powershell script in a subdirectory called internal. When the user double clicks on the file we check if PowerShell is in the path and that it is v2 or greater. We abort if either of those conditions are false. Finally we execute the PowerShell script with paramaters to ensure it runs on a new system without having the execution policy set yet. If you exit your powershell script with a non-zero the batch file will remind the user to read carefully before the window closes.

Categories: Uncategorized Tags: ,

[SOLVED] svn user commits _svn folder !?!?!?

February 8th, 2012 No comments

Names and paths changed to protect the innocent :)

Here’s a quick one that wreaked a moment of havoc. A user had comitted _svn folders to the repository. The build server uses _svn instead of .svn by way of an environment variable SVN_ASP_DOT_NET_HACK. This caused the continuous integration server to stop updating since it freaked out trying to pull down a _svn folder over a _svn folder.

This is what it looked like in the log:

PS J:\&gt; svn log --verbose -r 1234 https://svnserver/svn/WidgetX/trunk
r1234 | johnsmith | 2012-02-08 11:14:09 -0800 (Wed, 08 Feb 2012) | 1 line
Changed paths:
   A /trunk/src/newthing
   A /trunk/src/newthing/0.jpg
   A /trunk/src/newthing/1.jpg
   A /trunk/src/newthing/2.jpg
   A /trunk/src/newthing/9.jpg
   A /trunk/src/newthing/_svn
   A /trunk/src/newthing/_svn/prop-base
   A /trunk/src/newthing/_svn/props
   A /trunk/src/newthing/_svn/text-base
   A /trunk/src/newthing/_svn/tmp
   A /trunk/src/newthing/_svn/tmp/prop-base
   A /trunk/src/newthing/_svn/tmp/props
   A /trunk/src/newthing/_svn/tmp/text-base
Just another commit

To fix a user comitting _svn folders:

# My environment variable was set so checkouts use _svn instead of .svn (legacy reasons)
# Unset it so we get .svn folders as normal
# Checkout the branch so we get a working copy with .svn instead of _svn as usual
svn co https://svnserver/svn/WidgetX/trunk
# Round up the offending _svn folders and delete them!
get-childitem -recurse -force | where { $ -eq "_svn" } | foreach {  svn delete ""$_.fullname"" }
svn commit -m "Cleaning up _svn folders" trunk

I tried to reproduce this scenario using .svn folders, but svn smartly told me it was a reserved name. Adding _svn it didn’t complain at all (see bug). There might be some way to force a .svn folder in, in which case you can use this procedure except set the SVN_ASP_DOT_NET_HACK variable to any value instead of unsetting it. Also change $ -eq “_svn” to $ -eq “.svn”.

Categories: Uncategorized Tags: ,

smbsrv: [ID 421734 kern.notice] NOTICE: [domain\user]: shared share not found

June 4th, 2011 No comments

I was doing some performance testing of my migrated Solaris 11 share from windows and it would never finish, always terminating at some point with windows popping up a dialog that said specified network share is no longer available.  On the Solaris box, this was showing up in the /var/adm/messages log:

smbsrv: [ID 421734 kern.notice] NOTICE: [domain\USER]: shared SHARE NOT found

Thankfully it didn’t take me too much searching to find satcat66′s post about the same topic.  In my case, my old server was offline, but I had created a DNS A record to point the old name to the new server in case I forgot to update a reference to the share somewhere.  Once I removed the alias, the performance test completes without error.

Categories: Uncategorized Tags: