ruby

Namey - A Random Name Generator

Recently, I had an idea for a project where I wanted to be able to create random names for people on the fly. It's a fictional schedule for a fictional cable channel, the Not Lifetime Movie Network. Some of the movie titles needed random names. I dug around, and found a few name generators out there, but none of them had an API, or available source code, so I ended up making my own. This quickly turned into a classic project -- I spent maybe an hour or two writing some code to generate a list of fake movies, and ten times longer coming up with a generic library for random name generation. it went something like this:

I don't actually like xkcd that much, but this sums things up nicely.

But when I was done, I had Namey -- a website where you can quickly generate some random names, as well as an underlying library written in ruby. It uses files generated by the US Census Bureau for the 1990 census to generate whatever sort of name you would like. You can pick a gender, specify if you want a last name or not, and if you would like a common name, rare name, etc.

The data itself looks a lot like this (in fact, this is the data):

JAMES 3.318 3.318 1
JOHN 3.271 6.589 2
ROBERT 3.143 9.732 3
MICHAEL 2.629 12.361 4
WILLIAM 2.451 14.812 5
DAVID 2.363 17.176 6
RICHARD 1.703 18.878 7
CHARLES 1.523 20.401 8
JOSEPH 1.404 21.805 9
THOMAS 1.380 23.185 10

So, the government is big on ALL CAPS. Also, there's no punctuation, so O'Brian is OBRIAN. I've done a bunch of massaging to the data - names are mostly in proper case, with apostrophes where it's fairly obvious, but I'm sure I missed some.

For nerds, the code is open source and available on github, so you can fork it and play around as much as you want. As I worked on this project, I developed certain goals:

  • Write a decent Ruby gem to generate random names -- this is the bulk of the project
  • Build a website which can use it -- see http://namey.muffinlabs.com/
  • Play with Twitter's bootstrap library -- I built the website with it. It's pretty cool!
  • Generate a Javascript API layer in between. If you wanted to, you could pull the JS onto your own site and generate random names. Still working on this part.

In short, by the time I'm done, I intend to have a ridiculously overbuilt system for generating random names.

Tags: 

Chatterbot Updated

I've just pushed a new version of Chatterbot with a few main changes:

  • When doing searches, it no longer includes retweets. I struggled with making this change but eventually I decided it makes sense. Several people have told me that they are annoyed when they retweet something which triggers one of my bots. And I can tell from watching the logs for my bots that people who RT someone else don't really expect anything to come of it. So, no more retweets by default. You can still include them explicitly by adding 'include:retweets' in a search string.
  • A nifty new chatterbot-registerscript, which will walk you through the Twitter authorization process, and removes the need to generate any sort of config file yourself. In fact, you don't even need to create a bot first -- the script will output a skeleton bot for you once the authorization is complete.
  • A new script with some pretty basic reporting. Run chatterbot-status to get some output of recent tweets from your bots, and totals for the last 1/7/30 days.
  • Some other cleanup and bug fixes.

Tags: 

Chatterbot: A Ruby Library for Twitter Bots

As mentioned here on occasion, I've written a bunch of Twitter bots. The first bot was a pretty simple custom script, then the second one was a little bit improved, and so on. Eventually, I wrote a skeleton class which held most of the guts needed to run a bot, then I would just extend it as needed for actual bots.

This was fine, but not very pretty. The code was a mess, and as I added features, it just kept getting messier. People have asked for help from time to time with their own bots, and I've always been happy enough to share some code, but it wasn't sufficiently documented and was never really intended for public consumption.

So, I spent a couple evenings and spare moments cleaning up the code, documenting it, and properly testing it, and now it's available for public consumption. Introducting Chatterbot, a ruby library for producing bots.

Here are some nice things about Chatterbot:

  • It handles setting up Twitter OAuth permissions fairly nicely. The first time you run a bot, it will walk you through authorization in a couple of steps.
  • It will run searches for you -- multiple searches if you want, and you can also check for responses to your tweets. This is the main functionality of all my bots so far -- search for a phrase or some keywords, and reply to those tweets in some interesting fashion, and then also potentially reply to any mentions of your name. You can do a lot with this sort of functionality on Twitter -- it's mostly what actual humans do on it all day long.
  • A fairly simple, but extensible configuration system. If you just want to run a single bot, it will store your configuration data in a YAML file, and you never even need to look at it. But if you want to run multiple bots, you can setup a global config file to store several common parameters. You can also optionally store your configuration in a database.
  • If desired, you can log tweets to a database. This is handy for tracking your bots activity over time.
  • It has a blacklist system to keep you from annoying users who don't want to be annoyed, and also to make it easy to ignore tweets which have certain keywords in them.
  • It has a 'debug mode' so you can test the bot without sending out actual tweets.
  • It has a very simple DSL for generating basic bots. Here's a basic but functional example for an actual bot:

A Note About Being an Asshole

I am a big fan of the WTFPL - Do What The Fuck You Want To Public License. I decided to release chatterbot under the WTFPL, but with one alteration. I really don't want people to use this code for evil. Spamming people on Twitter is not okay. However, this code could definitely be used to aid spamming. So, I've invented the WTFDBAL. It's pretty simple -- do whatever you want with the code, but don't be an asshole:

DO WHAT THE FUCK YOU WANT TO -- BUT DON'T BE AN ASSHOLE PUBLIC LICENSE

   Version 1, May 2011

Copyright (C) 2011 Colin Mitchell 
Derived from WTFPL, Copyright (C) 2004 Sam Hocevar 

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

 DO WHAT THE FUCK YOU WANT TO -- BUT DON'T BE AN 
ASSHOLE PUBLIC LICENSE 0. You just DO WHAT THE FUCK YOU WANT TO. 1. Don't be an asshole. Really.

Is that enforceable? I assume not. But if you even have to ask the question, then you're probably doing something wrong.

Got questions? Did I document something poorly? Contact me here or on Github and I'll see what I can do about that.

Tags: 

RVM and Bundler on Dreamhost

So, I run all my sites on DreamHost, and I've been a pretty happy customer for years. Very little downtime, fairly responsive to support questions, great price, and about as much control over a server as you can get without being root.

But... there's no root access, so sometimes you have to play some tricks. My site WhalePail is on Dreamhost. It runs on Ruby/Sinatra. Getting it working the first time took a little work. I use Ruby every day for work, and so I've been using Bundler for awhile now. Also, I have been getting into RVM, since I actually am maintaining a couple different projects with different ruby version/library needs. Anyway, I made a bunch of updates to WhalePail and wanted to get RVM and Bundler running on Dreamhost. I pretty much got it working, and here's what I did.

First, I installed RVM:

bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Then, I used it to download and compile ruby 1.8.7. This is the same version of Ruby as is running on DH now. I don't think this would work with Ruby 1.9 unfortunately. I also setup a gemset for my sinatra project.


rvm install ruby-1.8.7-p334
rvm gemset create sinatra
rvm use 1.8.7@sinatra

Install bundler next:

gem install bundler

Then I setup a Gemfile for the app. There's one important thing here, which is to match the version of Rack that DH has:


gem "rack", "=1.2.1"

Run bundle install to get your gems loaded.

I have a couple scripts that run alongside the app. In order to make sure they're running the same version of ruby, you can create an .rvmrc file that specifies what version you want:

echo "rvm use 1.8.7@sinatra" > .rvmrc

Next, you need to add a couple special lines to your config.ru file. Mine looks like this:

#!/usr/bin/env ruby

require 'rubygems'

ENV['GEM_HOME']="/home/username/.rvm/gems/ruby-1.8.7-p334@sinatra"
ENV['GEM_PATH']="/home/username/.rvm/gems/ruby-1.8.7-p334@sinatra:/home/username/.rvm/gems/ruby-1.8.7-p334@global"

require 'rubygems'
Gem.clear_paths

require 'bundler'
Bundler.require

require 'mufftweet'
run MuffTweet

The important stuff here is the hardcoded ENV variables, and also the Gem.clear_paths. At this point, you're actually running Dreamhost's pre-installed ruby via passenger. After you hardcode the path to custom gems, and clear out any preset paths via the call to clear_paths, the only gems loaded will be your bundle.

Finally, if you need something to run in cron, you can do it like this:


*/10 * * * * . ~/.bash_profile; cd /home/username/appname; /home/username/appname/cron.rb

The ". ~/.bash_profile" bit loads in the RVM functions that you will need to run anything in cron.

Tags: 

Pages

Subscribe to RSS - ruby