Listing Social Networks in Ruby

Friday, June 25th, 2010 | Ruby, Ruby on Rails, Sinatra | No Comments

I spent a little time tonight working on The Enclave's new member page. The site overall is the most beautiful thing in the world, but I have been using it as an excuse to plan more with Sinatra.

Tonight, I found the need to provide a way for our members to list their social networks should they choose to do so. The obvious way was to add a list of anchor tags. I found this to be rather distasteful. I mean, we are dealing with Ruby here, right? So, I started by considering what I wanted the UI code to look like. Would do I want to have to work with on a weekly basis. I came up with the following:

This would allow me to add as many usernames and networks as I desired. Perfect! So I began to work on the code that would make this function as intended. I came up with the following:

So, basically, I list all of the networks I want to use. This list not only includes the URL (and a place holder for the username), but any prefix or suffix for the displayed username for which I might find a need (i.e.: Twitter's "@" in "@slant") Next, the script iterates through my list, catching each network as it does so. Each time the script reaches a network, it proceeds through each username in the list, building an appropriate anchor tag for each one.

In the end, you have a beautiful categorized list of usernames, each linking to their respective page.

linkedin: ryanlcross | facebook: rcross | twitter: @slant, @cylenceweb

Fluid + MenuExtra = Even More Awesome

Monday, May 31st, 2010 | Mac OS X | No Comments

I just ran across an incredibly useful feature in Fluid, thanks to @takeo. The 'Convert to MenuExtra SSB' feature allows you to run a single site browser as a menu item at the top of your screen. Brilliant! I now realize that my life has not been complete until today. This is easily my new favorite feature of Fluid.

Why would you want to do this?

You seriously have you ask? Okay… I'll humor you. Once I understood what this feature did, I immediately came up with a few benefits:

  • Keep Fluid apps that you rarely interact with out of the way
  • Keep Fluid apps that you tend to need quickly at the ready
  • Get a Fluid app out of the app switcher

I'm sure there are more reasons, but those are the ones that sold me. My use case was MOG, an online subscription music player. It uses a Flash interface for its player, which was a real disappointment to realize, but here we are.

What I didn't want

When I started using MOG, I just opened it in Chrome, opened their player in the popup window, moving it to my media Space. First of all, that's an annoying process, not practical at all for a service I want to use daily. They don't have a desktop player yet, and from what I hear, it will be in Adobe Air anyway, of which I'm not a huge fan. Don't get me wrong, they did a great job on the player's interface, its just… well, its Flash.

Creating a Fluid app would surely be useful in keeping MOG distinct throughout my experience using the site, but its still a clunky browser window that doesn't size correctly to the Flash interface of the player without – yet again – opening the popup through the site. So, what would be the benefit of creating a Fluid app for MOG?

At Last: Awesomeness!

This is where the solution I found came into play. I'll just give you the step by step on how to get this running smoothly and let you decide whether or not its worth the time.

Creating the Fluid app

To start things off, we need to create a new Fluid SSB for mog.com.

Creating a new Fluid SSB for mog.com

Now open the new the newly created application.

Fixing an issue with Spaces

This next step is for those of you who use Spaces. If you don't, feel free to skip this one: Open System Preferences followed by Exposé & Spaces. In the Spaces tab, look for your new Fluid app in the list below. In the second column, select Every Space for your app and close System Preferences. This will prevent some Space-switching grief when we move into MenuExtra mode.

This can also be accomplished from inside the application itself. In the app's Preferences, click on the Behavior tab. Change the top option (Spaces Behavior) to "Windows Appear in all Spaces".

Login and Fluid Settings

In your Fluid app, log into MOG. You don't have to yet, but its easier to do it now while in this mode. These next two steps are critical for maximizing the awesomeness, so pay attention! Navigate to http://mog.com/player in your SSB to bring up the player, then hide the Toolbar, either through the Viewmenu or by pressing Cmd+Opt+T. Lastly, setting a Global shortcut is a very good idea. On the first tab in the app's preferences, you'll be able to accomplish this.

MenuExtra Time

Now, select the MOG menu option (or whatever you named your app) followed by Convert to MenuExtra SSB....

Select 'Convert to MenuExtra SSB...'

Accept the warning that pops up next. You will now see a new icon in your menu bar!

New icon in menu bar

Clicking this new icon will bring up the player in a popup window. It is resizable, but not scrollable. Furthermore, you can access this menu item from any Space now. Let me know if you find any other sites that work really well with this setup, or perhaps other benefits to using MenuExtra SSBs that I've not mentioned here.

edited by Ryan Cross

MOG icon

@takeo just threw this icon together which I think looks pretty darned nice in the menu bar. Thanks, Toby.

Tags: , ,

Custom Categories in iBooks

Tuesday, May 25th, 2010 | iPhone | No Comments

So, the iPad has finally arrived. I'm probably enjoying mine more than I should be.

I find myself particularly drawn to iBooks with regards to technical books. I am incredibly grateful to The Pragmatic Bookshelf and O'Reilly for making previously purchased ebooks available in the epub format, the format native to iBooks (as well as many other readers including Stanza, the iPhone app that had this capability a few years ago).

As much as I have been enjoying this app, I've been frustrated with how the seemingly arbitrary categories sort the books when viewing the them in list view. One such category was:

COMPUTERS / Hardware / Personal Computers / Macintosh

Seriously? Not only this, but the formatting was awful! Some were in partial caps while others used slashes and other various characters. It turns out the fix was really simple!

The Fix

In iTunes, under the Books library, start by right-clicking on an ebook and selecting Get Info. Heading over to the Info tab reveals the answer. iBooks is apparently using the Genre of the ebooks as the categories!

iTunes Get Info window

Meh. Okay, I can see how that makes sense. Come up with a way to logically organize the ebooks you have and go to town! I found that the technical books I currently have seem to fall under 'Web Development' and 'iPhone Development'. Much better.

iBooks on iPad

Next complaint

I'd love to see categories make their way into the shelf view. There's currently no way to sort the books found in this view.

Tags: ,

Gmail, Unsubscribe Me!

Tuesday, December 22nd, 2009 | Interwebs | No Comments

After receiving one too many offers from EA to purchase a few of their products at a discounted rate, I decided that I'd had enough and parsed the email for the fated unsubscribe link. While doing so, I noticed something new. In the email's header data, I saw an "Unsubscribe" line, where the value was a link ("Unsubscribe from this sender"). Doing a little research turned up a post on the Official Gmail Blog detailing this new feature which I've apparently found success in avoiding since July.

It looks like Google is only displaying this header for trusted companies, such as EA, since anyone else might just take your request as a cue that you want more spam.

"This only works for some senders right now. We're actively encouraging senders to support auto-unsubscribe — we think 100% should."

In the same post, Google is also letting senders of such email know how to take advantage of this new feature.

"… including a standard "List-Unsubscribe" header in your email with a "mailto" URL and, of course, honoring requests from users wishing to unsubscribe."

Gmail has always had a pretty decent spam filter – in fact, that's why I jumped on board with them as my primary email provider back in the early beta days. This is just one more reason to stick with them. I still wonder why they're only the third largest email provider. Perhaps its the same reason why Internet Explorer is still the most commonly used browser… I am change, fear me!

Journey to Snow Leopard

Monday, September 7th, 2009 | Mac OS X, Ruby, Ruby on Rails | No Comments

Like many, I was in my local Apple Store on August 28th to pick up their newest operating system update, Snow Leopard. Despite hearing about some compatibility issues, my inner-first-adopter got the better of me and since it was basically the beginning of a weekend, I began down the path of the upgrade.

Luckily, I walked out of the installation process unscathed for the most part with only a few minor issues to deal with.  One example would be that Phusion Passenger was no longer working – but mongrel was – so that was livable.  Realizing that I'd not yet setup a decent database for development since getting my new MacBook Pro, I set to work on basically reinstalling the entire Rails stack to ensure that everything would be ready to roll when I get back to work on Monday.

I found a few fantastic resources to guide me through the majority of what I was looking to do including Hivelogic's guide on Compiling Ruby, RubyGems, and Rails on Snow Leopard as well as another guide on Compiling Git on Snow Leopard.  I also found some great information on installing PostgreSQL on Snow Leopard. Lastly, I discovered a very short guide on compiling the PostgreSQL RubyGem for use on Snow Leopard (enabling 64bit compatibility).

Equipped with these guides, I successfully got everything upgraded and am now waiting for all of the other 10.6 bugs to pop up!

edit: A definitive guide in deed. I just found a guide for those of you who want to install things like MySQL and SQLite as well.

Tags: ,

Cross-subdomain Cookies on Different Servers

Sunday, November 30th, 2008 | Uncategorized | No Comments

So, I have two servers, each on a different subdomain of the same domain. We needed to send data from one to the other. Cookies seemed like the logical method, but the data that we needed to pass was actually coming from the second server. The solution I'm going to demonstrate uses an HTML image tag to invoke and retrieve data from the remote server. I've seen this solution before, never needing to try it for myself, but it's actually pretty handy (even though I find it a bit too hacky for my liking).

We will assume that our domain is domain.com with subdomains one and two.

Let's start with the image tag code of the first server:

Extremely basic. Just a URL leading to the remote PHP script. Now for the code in the file to which the image tag points.

In case you are not familiar with PHP's setcookie() function, have a look at the last variable being passed: ".domain.com". Note the dot before the word "domain". This allows the cookie to be set and used by any subdomain on that domain. Had there not been a dot there, only the root of the domain would have been able to access the cookie.

Once the image tag is placed somewhere in the files which will be accessed by visitors on server 'one,' the cookie will be set once the page loads (loading the image tag along with everything else). After all of this has happened and the cookie is set, it can then be accessed from either server. On a side note, the "display: none;" portion of the image tag is necessary so the tag won't render a broken image on the page.

One last point. In my example, I sent GET data directly to the target script and set it in a cookie without ANY validation. This is an extremely bad idea in a real world scenario. Sanitization is recommended at the very least. With that said, the resulting cookie in my example would have a value of "yoink!" since that's what we sent the script in the image tag's query string.

Tags: , ,

Presentation at Refresh Denver

Monday, September 22nd, 2008 | Ruby on Rails | 2 Comments

Last week, Jay Graves and myself presented the differences between Ruby on Rails and Django at Refresh Denver.  We decided on a common database schema, functionality and design.  We then each built the same application in our respective frameworks.

During the presentation, we each explained our frameworks on a surface level followed by a brief demonstration of how each framework accomplished a few of the things that our applications did.

Jay's presentation can be found here and his Django application here.

My presentation can be found here and my Rails application here.

Overall, I absolutely believed this presentation to be a success!  I'd like to see other frameworks and languages go head to head like this in the future.  I feel like the ability to see two frameworks side by side was a real benefit, allowing a clearer look at how each works with respect to the other.

Tags: , , ,

Amazon MP3 Playlist in iTunes

Thursday, September 4th, 2008 | Mac OS X | No Comments

If you purchase your MP3s from Amazon with any regularity at all, then you may have encountered a problem with how to keep track of them.  iTunes has a built-in playlist for music purchased from the iTunes Store, but Amazon MP3s, while downloaded to a specific directory in your file system, are just dumped straight into your iTunes Music Library, to be lost forever amongst your delicious and sultry tunes.

Luckily, thanks to the addition of Smart Playlists way back in iTunes 3 as well as the presence of a common element amongst all Amazon-purchased MP3s, we can solve this problem with very little effort.

All MP3s downloaded from Amazon contain a string starting with "Amazon.com Song ID", we can safely assume that any MP3s with "Amazon" in the Comments field will be from Amazon.  Unless, that is, you have a penchant for adding the word "Amazon" to your MP3s' manually.  To each their own.

First, create your new Smart Playlist by going to 'File' > 'New Smart Playlist…'.  We're going to want to modify the existing rule to look for something in the Comment field, so select 'Comment', 'contains' and enter 'Amazon' in the last field.

So, now you have a playlist with all of your Amazon purchases in it!  If you want to be really cool, and want a single playlist containing all purchases from both Amazon and the iTunes Store, you can create a second Smart Playlist that looks like this.  One note worth mentioning: I have an iPhone, so I included my iPhone purchases playlist as the second rule. If you don't have an iPhone, simply disregard that rule.

If you are not seeing any results from this last playlist, it is likely you forgot to change the top drop down box from "all" to "any".  Enjoy!

Tags: , ,

Using Hash#values

Monday, July 28th, 2008 | Ruby on Rails | No Comments

This is minor, but I thought it was interesting nonetheless.

I needed to iterate through the values of a Hash. So I called .values on the Hash in question. What was interesting about this had nothing to do with the results of calling this method, but instead what it was actually doing to the Hash.

>> myhash = { :first => "one", :second => "two", :third => "three" }
=> {:second=>"two", :first=>"one", :third=>"three"}

The myhash how has a class of Hash, which is to be expected, since that's what I gave it.

>> myhash.class
=> Hash

When .values is called, it returns all of the values in the Hash.

>> myhash.values
=> ["one", "two", "three"]

You may have noticed this in that last example, but when .values was called on that Hash, the class of the result changed altogether. Let's examine the class of this Hash while we are calling .values on it.

>> myhash.values.class
=> Array

So calling .values on the Hash literally built an Array with the values from the preceding Hash!

Read more about Hash#values in the Ruby Documentation.

Tags: ,

Git Aliases

Monday, July 28th, 2008 | Ruby on Rails | No Comments

There has been talk about how to shorten Git commands, mostly in an effort to assist those of us who are coming from Subversion. One proposed solution has been to use the alias mechanism native to your shell environment.

Another solution does exist. This one is internal to git itself. Due to that fact, the two main benefits are a shorter load time when starting a new shell (since you're not dealing with alias entries in your .profile script) and easier git-centric configuration.

Simply add the following to ~/.gitconfig:

[alias]
  co = checkout
  st = status
  br = branch
  ba = branch -a

Now instead of typing git checkout branch you only need to type git co branch. You can customized these as much as you'd like, adding other commands as well, as long as the command after the equals sign is a valid git command.

The obvious down side to this method is that you have to type git before these aliases. Using the other method, you do not.

Tags: ,