Ignored By Dinosaurs 🦕

devops

I have a friend for whom I'm building a site right now, and I chose Rails to do so. I think I'll probably reach for Rails for most sites I build until I get bored of it, which isn't going to happen any time soon. I also learned a few things about different browser's implementations of HTML5 audio, which I'll get into first.

My buddy is in a band, and so part of the functionality of the site is a photo gallery, and another part is a music player. Whereas in the past I'd have just reached for something off the shelf like jPlayer, I decided to go the HTML5 route this time, as I was fairly confident that my buddy wouldn't be asking for legacy browser support. In any event, he's not paying for legacy browser support, so I decided to teach myself a few long overdue tricks.

First up is a bit of a primer on the HTML Audio element. I found, as usual, Mozilla to have the most understandable and trustworthy documentation – here, and here. Building the player was fairly straightforward, but required a bunch of repetitive code that I'm too embarrassed to post here. It's fairly simple to create an audio element, list out a bunch of song objects with recording attributes attached to them, set a data-source attribute on those songs that points to the path where your uploaded recording file lives, courtesy of the Carrierwave and jQuery FileUpload gems. When you click on one of the songs, it kicks off the player.play() method and your song plays.

The surprise was that Firefox, in which I work every day, doesn't like mp3 files. There's some contradictory info out there about whether or not FF does or doesn't support mp3, but my version does not, so I had to figure out how to get an ogg version of the file up there also.

The method I came up with was to install FFmpeg to do the conversion, but to place the conversion into a background Sidekiq job so it didn't hang up the browser when my buddy uploaded his song. Sidekiq makes this so absurdly easy, and the Railscast steps you right through the process. Basically any processing that you'd want to do in the create or update action in your controller can be moved into a Sidekiq worker that's called instead of doing the processing synchronously. Watch -

# songs#create

def create
  @song = Song.new(params[:song])
  @song.title = @song.default_name unless @song.title
  if @song.save
    ConversionWorker.perform_async(@song.id)
    #logger.debug path
    redirect_to music_path
  end
end

And the worker —

# app/workers/conversion_worker.rb

class ConversionWorker
  include Sidekiq::Worker

  def perform(song_id)
    song = Song.find song_id
    path = "#{Rails.root}/public#{song.recording_url}"
    ogg = path.gsub(/mp3$/, "ogg")
    yup = %x[ffmpeg -i #{path} -acodec libvorbis #{ogg}]
  end
end

Converting stuff with FFmpeg was really straightforward, but only in Ubuntu. I fought with trying to get it set up with libvorbis on the Mac and eventually gave up. %x[] is the easiest way I found to execute shell commands from Ruby, complete with string interpolation. Basically this says – load that song, give me the recording_url (convenient that these Carrierwave methods are in scope), and create an ogg version. Do that by putting it right next to the mp3 version, but with the ogg file extension.

#ruby #rails #devops

I've been a Media Temple customer for a long while now, almost 4 years. The file system on my grid server is a timeline of my learning programming and systems administration. I mostly work on big-boy systems over the last 2 years or so, so my comfort level with working through SSH is pretty high now (much higher than working through GUI tools that want to hold your hand, actually). That's one thing that I always loved about MT – the fact that they give you a pretty decent command line experience for administering your server.

One thing that's kind of always gotten on my nerves, however, is the DB admin experience. Lately since it seems like their PHPMyAdmin installation has completely gone to shit. Seriously, it's unusable. I couldn't even restore/import a < 1 MB brand-new-site database the other day because it kept timing out. Of course, this would be a 3 second maneuver on the command line mysql -u user -p pass target_database < dump.sql, but they have the command line locked down on the grid server.

I've recently moved a rather involved client project back onto their production server which is hosted on said grid server. I'm still banging on the thing, so I'd like to delete some rows straight out of the DB without having to spend 30 minutes trying to get PHPMyAdmin to do what I need it to. So the other day I went poking around the hosting admin panel.

I'd seen this years ago, and fortunately it's still there, probably just for this use case. In the “global settings” under the “databases” section of your admin panel at the very bottom of the screen is an option to allow external IP addresses access to the DB server. It even has a handy option to “use current IP” to prefill the field for you. Do this.

Next, invoke mysql locally, but pass it the --host option, like this —

mysql -u user -p pass --host=external-db.s123456.gridserver.com.

You're welcome.

PS – I tried importing the aforementioned <1 MB db in this method to no avail. Don't know if their db servers were on the blink at the time, but it definitely wasn't bandwidth.

PPS – it has occurred to me since this morning that mysql doesn't run on localhost, that's why you can't login as you normally would. Thus, if you were logged into your webserver, you could pass the same --host argument and specify the internal-db host to carry on about your business.

Never said I was that good at this stuff.

#databases #devops #mysql

I've just recently started to discover what Dropbox is really good at. I've had one for at least a year and almost never used it. The only thing I'd ever really used it for was client assets like PSDs and the like. I just discovered the Dropbox secret weapon – the symlink.

A symlink (short for symbolic link), if you don't know, is basically like a pointer to a folder/directory. It's a really nifty way to help you organize your filesystem. Say you use iTunes and for some reason you like to dig around in your iTunes music folder a lot. Rather than going into the Finder and drilling down into the folder from there, you could just create a symlink from your Desktop into that folder. Then, without actually moving your iTunes folder and possibly screwing things up, you've just created a shortcut to get into that folder.

So say I've got a client. Let's also say I have two different computers that I regularly work from. I've started using some code to test the project with that I don't want to check into their repo because they don't even really need to know that I'm doing automated testing with a tool of my choosing. So I add the directory that contains the tests to my .gitignore file. But (!), then I switch computers and need access to those test files. A git pull doesn't do anything because those files were never checked in. This struck me as the perfect use case for my dormant Dropbox folder.

I moved all the test files into a folder in my Dropbox. Then I created symlinks on both computers from that folder into the project directory. That way, they stay in sync across my two computers without needing to be checked in to the client's repo. Thank you Dropbox!

#devops #workflow #git

The short version -

https://github.com/JGrubb/laptop


The longer version -

Setting up your Macintosh for Rails development is actually sort of like Rail development itself – you have to at least kind of know about a lot of different things before you can really get anywhere. I'd say I'm new to Rails development even though I've been poking at it since 2.1. 2.1 is the first version I remember after I first bought a Mac and started trying to teach myself to “program”. It's taken me until 3.2 to come back to Rails with enough of a rounded web development skill set to really be able to fly around and build the things that have been locked up in my head for the last 4 years. I've written about this before, as have many others, but Rails isn't exactly a framework for beginners. That is, it requires you to have at least some idea of what you're trying to do before it will let you sit down and do it. Many of us probably grew up programming in Basic, but some of us might have gotten sidetracked into other vocations besides software development. the world has come quite a ways since then. So this post, or series maybe, will be an attempt to teach you not only what to install, but why.


Step 0 – the compiler

If you are on a Mac, you are lucky to already have a rather large lot of tools that software developers use already installed. But they haven't given you everything. Some of the ones that will come in handy down the line as you get further in to this process will have to be installed by you. This will toughen you up and help you get more acquainted with a side of your computer that perhaps you didn't even know about. The world (and by that I mean the guy who made up Homebrew) has made life a lot easier for the Mac-using developer, but in order to access all of those goodies, you'll need to install a compiler. A compiler is basically a piece of software that builds other software.

One of the first pieces of software that you're going to build will be the Ruby language itself, but first things first.

XCode

If you're on Lion or the latest Snow Leopard, you can open up the App Store and search for “XCode”. XCode is the official Apple development environment. With it you can build iPhone apps, applications for the Macintosh, and really pretty much anything that isn't specifically meant to be run on Windows. It's an enormous download, about 4GB recently.

After you download it, open it up, open the Preferences, and find the extra downloads part. What you're looking for is the “Command Line Tools” bundle. It's in one of the tabs toward the right. Download and install. Should be fairly simple. Just to be safe, restart your computer. Once it's back on open the Terminal.app (get used to the terminal, you'll be there a lot) and type which gcc. If it doesn't spit anything back at you, you haven't installed the compiler. Figure it out and come back for the next step – the package manager.

#rails #devops

I use Git. I'm relatively new to the party and it's all I've ever used. I tried to get SVN working for me back when I was first gettings started and it felt like hand-wiring a tube amplifier – slow, tedious, and you don't know if it's going to work until you're totally done. I've more recently taken on a client who uses a nifty issue tracker called Jira, but they have their source checked in to SVN. I thought I was going to to have to get familiar with it until I rediscovered a tool that comes with Git called git-svn. It works pretty transparently after learning a couple of new commands.

This morning however, I tried something new and was greeted with this (after 5 hours of work).

src/sites/all/modules/eloqua
580e5a6480dfae9ee8aa39e2ff14e4b3604d8827 
doesn't exist in the repository at /usr/local/git/libexec/git-core/git-svn line 4771
Failed to read object 580e5a6480dfae9ee8aa39e2ff14e4b3604d8827 
at /usr/local/git/libexec/git-core/git-svn line 573

This is a Drupal site that I'm working on. To make a long story short, I decided to pull a new module over via Git from drupal.org instead of using Drush like I always do. I figured I might want to chip in on some of the development of this module while I'm already here. Everything went fine, I added the .git folder within the module to .gitignore and went on my way. After finishing up enough of the work to send it over to staging and attempting a git svn dcommit I get the horrifying error above.

I found this post that got me started down the right track. I used a different approach, though. I used the technique of rewriting the history with the info found here. I'm pretty familiar with removing accidentally committed DB passwords, and wasn't familiar with the technique that he had commented out in that post. Worked like a charm, and am now back on track.

To sum up, you delete the offending directory and then run something to the effect of

git filter-branch --index-filter \ 'git rm --cached --ignore-unmatch path/to/the/formerly/misbehaving/module'

from the base path of the git repo. By the way, that backslash doesn't do anything but allow you to wrap a command to two lines. You can leave it out if you want and just type all that as one long line.

The culprit of all this is that git-svn specifically chokes on git repos below the main one, as is the case if you git clone a module straight off of d.o. So, sorry kids, you'll have to contribute that code in some other way.

#devops #git