Welcome to Dmuth dot org

Ferris Wheel at Funtown Pier

Welcome to my website! I've been on the web in some form or another since 1996. Even though social media is all the rage these days, I feel it is important to have one's own presence on the web. So I continue to write here as often as I can.

If you'd like to get in touch with me, feel free to reach out! All of my contact info can be found here.

-- Doug

Average: 3.1 (212 votes)
Your rating: None

I Built a Facebook Group Leaderboard

This is a Node.js app which uses the Facebook Graph API to download recent posts from 1 or more groups, and display the top posters, top commenters, and their stats in a leaderboard-style format. In production, I use this app to keep track of some groups I admin with thousands of users each, and make sure that no one is unnecessarily spamming the group.

Live Demo: http://www.dmuth.org/facebook.


The source can be downloaded from here:

Give it a try, and let me know what you think!

Average: 5 (1 vote)
Your rating: None

Two New Open Source Projects

At my day job, I get to write a bit of code. I'm fortunate that my employer is pretty cool about letting us open source what we write, so I'm happy to announce that two of my projects have been open sourced!

The first project is an app which I wrote in PHP, it can be used to compare an arbitrary number of .ini files on a logical basis. What this means is that if you have ini files with similar contents, but the stanzas and key/value pairs are all mixed up, this utility will read in all of the .ini files that you specify, put the stanzas and their keys and values into well defined data structures, perform comparisons, and let you know what the differences are. (if any) In production, we used this to compare configuration files for Splunk from several different installations that we wanted to consolidate. Given that we had dozens of files, some having hundreds of lines, this utility saved us hours of effort and eliminated the possibility of human error. It can be found at:

The next app I developed was written in Node.js and is intended for use in a high-availability environment. In most HA environments, you will have multiple servers running behind a load balancer. In order to check the health of its servers, the load balancer will usually issue an HTTP GET request to a pre-defined endpoint to make sure each server is healthy. But what if... the server didn't have any GET endpoints? This is actually the case with Apache NiFi, which only provides HTTP POST endpoints. What now?

That's where this utility comes in--it starts an HTTP server on the port of your choice, and can be used to turn a GET request into a POST request (with a zero byte payload), send it to a target port on the same server, and relay back the HTTP response. This in effect proxies a GET request as a POST, and returns the result. It's a bit of an odd way to go about it, but it let us more effectively use Apache NiFi in a high-availability environment and did not break any workflow, so we're calling that a win. Smiling That app can be found at:

I hope these are of use to anyone who stumbles across them. If you have any feedback or comments, feel free to leave them below or on GitHub!

Average: 5 (1 vote)
Your rating: None

Anthrocon 2016 Pictures

Another Anthrocon has come and gone, and it's been amazing year!

We had 7,310 attendees this year, a considerable jump up from our previous number of 6,348 attendees. Our Fursuit parade had 2,100 fursuiters in it, an even bigger relative jump from the previous year's number of 1,460.

We raised $31,880 for our charity: The Pittsburgh Zoo & PPG Aquarium.

Anthrocon-2016-012 Anthrocon-2016-023 Anthrocon-2016-030 Anthrocon-2016-163 Anthrocon-2016-042 Anthrocon-2016-049 Anthrocon-2016-111 Anthrocon-2016-121 Anthrocon-2016-134

Average: 5 (2 votes)
Your rating: None

Announcing Real-time SEPTA Train Stats!

I am pleased to announce the launch of the website Septa Stats! This website provides real-time data on all Regional Rail train lines. The following stats and metrics are supported:

That website is at:

The underlying technology stack consists of PHP, Slim (a microframework for PHP), Redis (for query result caching), and Splunk for data storage and reporting.

My source code is also available!

Average: 5 (1 vote)
Your rating: None

Extracting Session IDs from Websocket Requests in Express.js

I decided to learn websockets recently and figured that using the excellent Socket.io library along with Express. The tutorials on their website made sense, however I ran into an issue using the express-session module--cookies are not normally parsed with websocket connections, so I could not get the session data normally.

I then spent several hours reading through blog posts and Stack Overflow to figure out how to manually go through the process of parsing cookie strings and decrypting session data, which I thought I'd share here!

This assumes that you are using Express 4.x and have installed the following modules:

  • cookie - Used to parse the cookie string
  • cookie-signature - Used to decrypt the cookie
  • debug - Used to display debug messages. Replace with Winston or similar if you like.
  • express-session - Used to interface with sessions
  • session-file-store - If you're using a different data store, replace accordingly

And the resulting code looks like this:

Average: 5 (1 vote)
Your rating: None

How to Copy Uploads From AWS S3 Automatically

The problem: you write files to an S3 bucket on Amazon Web services. Maybe a single user/process does this, maybe multiple users or processes do this. But you want to keep a particular process from going rogue and deleting your data. What do you do?

The answer: You write a function in AWS Lambda that is fired whenever something is uploaded to the S3 bucket in question. It then calls the copyObject() method and makes a copy of the file to another bucket--one that only it (and your admin account, presumably) have access to write to.

The GitHub repository is at:

It's a quick and dirty thing that I put together mostly as a demo of how to integrate AWS Lambda with other S3 services.

Feel free to give it a try--AWS has a free tier for all new accounts. If you like it, let me know. If you didn't like it, let me know.

Average: 5 (2 votes)
Your rating: None

Anthro New England 2016 Con Report and Pictures

I haven't written too many convention reports lately, and that's pretty much my fault. I've been struggling with some health issues which have kept me from attending as many cons as I'd like. That said, I was able to make it to Anthro New England this past January. It was held in Boston, Massachusetts.

I wasn't staff at this con, but I did end up volunteering for the cash registers in the Dealers Room throughout the convention. It was a different experience than what I used to, but provided a great way to help out the convention. For the cash registers, we used custom software developed by Kotanu Cheetah. The software did a great job of running both regular register functions and having integration with the membership system.

AnthroNewEngland-2016-155 AnthroNewEngland-2016-110 AnthroNewEngland-2016-161 AnthroNewEngland-2016-073 AnthroNewEngland-2016-082 AnthroNewEngland-2016-017

Average: 5 (1 vote)
Your rating: None

So I Wrote A Craps Simulator

Work is sending me to a conference that just happens to be hosted in Las Vegas, a city where there are a few casinos. I'm not much for gambling, so I figured I should learn a little about it before I even think of doing such a thing. I read that craps is a fun game that has some pretty safe bets, so I decided to learn more about that. To that end, I wrote a craps simulator.

To get it up and running, make sure you have PHP and Composer installed, and do the following:

git clone git@github.com:dmuth/craps-simulator.git
cd craps-simulator/
composer installer

Syntax is explained in the README.md file, but just by running the file main.php, you can run games of craps and see what the results are. The simulator allows you to place "Pass" and "Take Odds on the Point" bets. Multiple players with different starting balances, bet amounts, and betting/exit strategies can also be simulated.

A successful run will look something like this:

Note that if you simulate enough games, you will lose all of your money. That's the whole point of how casinos work, actually. Use my simulator to see how it works instead of playing a few dozen games and finding out for yourself. Smiling

Average: 5 (2 votes)
Your rating: None

What a Phone Scam Sounds Like: Meet "Rachel from cardholder services"

"If you could just give me all your money, that would be great."

I got this voicemail the other day from "Rachel at cardholder services":

(If the embedded player doesn't work, here's the link: http://vocaroo.com/i/s1ohu312tpBe)

This one is kinda clever, that rather than a human using high-pressure tactics to get you to enter your credit card number, what you hear instead is a recorded message which asks you to "press 1 to get a lower interest rate". Had I pressed 1, I suspect I'd be transferred to a nice sounding human operator who would try to coax me into giving them my credit card number.

There's two takeaways from this:

1) Never give out your card card number to someone who calls you on the phone. (caller ID can be spoofed)

2) Strongly consider against picking up the phone when an unknown number calls you. Let it go to voicemail. If it's someone trying to get a hold of you, you can listen to the voicemail right away (or use Google Voice, which does transcripts), and call the person back.

Stay safe.

Average: 5 (1 vote)
Your rating: None