Auto-Filter your tweets with Tweet# and LINQ

Every so often on twitter a topic becomes so popular as to become annoying. If you follow a lot of people this happens pretty much on a daily basis.

This also gives rise to another twitter phenomenon – people announcing that they’re filtering out #trendyTopic because of the noise it generates, thus contributing further to the noise.

This gave me an idea in passing that I immediately posted to twitter. “What if my client could be set to auto-filter out trending topics.” I initially thought it was a silly idea, but then as I let it roll around in my noggin a bit I decided it could actually have some promise, if implemented properly.

So…if you’re developing a twitter client (admit it, you are, everyone’s doing it) and you’re using TweetSharp to do it, here’s some code to get you started. It’s easy!

First, we need the code to get the current trends.

/// <summary>
/// Gets current trends as a string enumeration
/// </summary>
/// <returns></returns>
public static IEnumerable<string> GetTrendingTopics()
{
    var search = FluentTwitter.CreateRequest()
        .Search().Trends().Current()
        .AsJson();
    var response = search.Request();
    var trends = response.AsTrends();
    foreach ( var trend in trends.Trends )
    {
        yield return trend.Name;
    }
}

This code will get us today’s trending topics.

Next, we’ll get our friends’ timeline

public static IEnumerable<TwitterStatus> GetFriendsTimeline()
{
    var twitter = FluentTwitter.CreateRequest()
        .AuthenticateAs( UserName, Password )
        .Statuses().OnFriendsTimeline().AsJson();

    var response = twitter.Request();
    return response.AsStatuses();
}

Now that you have trends, and tweets, it’s just a matter of writing a bit of LINQ code to filter out any tweets that have the trending string in the text.

public static IEnumerable<TwitterStatus> FilterTweets( IEnumerable<TwitterStatus>tweets, IEnumerable<string> filterTexts )
{
    var filteredTweets = from t in tweets
                             from f in filterTexts
                             where t.Text.Contains(f)
                             select t;
    return filteredTweets;
}

For the purposes of this example we’ll just dump the tweets out to the console.

public static void WriteFilteredTweets( )
{
    var tweets = GetFriendsTimeline();
    var trends = GetTrendingTopics();
    var filtered = FilterTweets(tweets, trends);
    foreach ( var status in filtered )
    {
        Console.WriteLine("{0} - {1}", status.User.ScreenName, status.Text);
    }
}

This is obviously a fairly trivial example, and represents the nuclear option of tweet filtering. If I were to implement this fully I would probably want to show the user a list of trending topics and have a one-click filter option (i.e. one button or check box per trend) that automatically expired when the trending topic dropped off the list of current trends.

Other ways this could be better

  • Apply it except when you are @replied to in the tweet
  • Rather than simply hiding the tweets, move them to a less prominent area of your client
  • Adapt the code and use it to highlight trending tweets instead of hiding them

Use the iTunes API and C# to do spring cleaning on your music collection

I was somewhat of an early adopter when it came to digital music. Due to the inordinate amount of time spent sitting at the keyboard, the PC was, for a very long time, my primary music player of choice. I usually have a decent set of speakers or headphones hooked up to my PC and use that to listen both while I work, or when I’m doing other stuff in the vicinity of the PC. However swapping CDs and dragging them to work and back seemed rather pointless once I could easily rip CDs to digital formats and store it on the computer and nothing beats having ones whole library of music at ones fingertips.

For the longest time, Winamp was what I used to play music…then I bought an iPod. I love my iPod because now I can take my entire music collection with me wherever I go, including the car. The iPod, however, did more or less force me to change my PC music software from WinAmp to iTunes (yes, I know there are alternatives, including WinAmp plugins, that would have saved me having to switch, but I was curious enough about iTunes that it didn’t bother me too much).

The first problem I had after importing my library was that iTunes had no album art for well over half of what I had imported. However, I had the album art. I had created a ‘folder.jpg’ file with the album art for every album in my collection so that it would appear in the Windows Explorer thumbnail view for the associated folder. The problem is, iTunes doesn’t look at that, it looks at the the file for embedded art (in the ID3 tag).

Now, I could have gone through and manually associated the images via the iTunes GUI, but dammit, I’m a programmer and that’s just not how we roll!!

Faced with a repetitive task, I, like any lazy-assed programmer would, looked for an automation solution. I was pleasantly surprised to find out that the iTunes App has an API. It’s a COM API, which ain’t my favourite, but it’ll do. So, without further ado, here’s how I associated the ‘folder.jpg’ album art, with every one of my nearly 10,000 song files, in no time flat.

First, I created a simple Console App and added a reference to the ‘iTunesLib’ COM component. (If you have iTunes installed, it should appear on the “COM” tab of Visual Studio’s ‘References’ dialog as “iTunes 1.xx Type Library”):

adding a reference

The next thing we need is a connection to the app and a reference to the main library object. The Library is exposed as a specific type of playlist, we can use the following code for that:

private static IITPlaylist GetLibraryPlaylist()
{
    IITPlaylist libraryPlaylist = null;
    Console.WriteLine( "Connecting to iTunes App... " );
    IiTunes iTunes = new iTunesLib.iTunesAppClass();
    Console.WriteLine( "Getting library:" );
    iTunesLib.IITSource librarySource = null;
    foreach ( iTunesLib.IITSource source in iTunes.Sources )
    {
        if ( source.Kind == ITSourceKind.ITSourceKindLibrary )
        {
            librarySource = source;
            break;
        }
    }
    if ( librarySource != null )
    {
        foreach ( IITPlaylist pl in librarySource.Playlists )
        {
            if ( pl.Kind == ITPlaylistKind.ITPlaylistKindLibrary )
            {
                libraryPlaylist = pl;
                break;
            }
        }
    }
    return libraryPlaylist;
}

Now we can iterate over the tracks in the library and call a function to assign the artwork (defined below)

IITPlaylist libraryPlaylist = GetLibraryPlaylist();
if ( libraryPlaylist != null )
{
    Console.WriteLine( "Repairing Tracks... " );
    IITTrackCollection tracks = libraryPlaylist.Tracks;
    int i = 1;
    foreach ( IITFileOrCDTrack track in tracks )
    {
        Console.CursorLeft = 0;
        Console.Write( "Checking track {0} of {1}......", i, tracks.Count );
        SetTrackArt( track );
        i++;
    }
}

…and lastly, here’s the code to set the album artwork to the ‘folder.jpg’ file in the same folder as the track, if it exists

private static void SetTrackArt( IITFileOrCDTrack track )
{
    if ( track.Artwork.Count == 0 && !track.Podcast )
    {
        string fileLoc = System.IO.Path.GetDirectoryName( track.Location );
        string artPath = System.IO.Path.Combine( fileLoc, "folder.jpg" );
        if ( System.IO.File.Exists( artPath ) )
        {
            Console.WriteLine( "Adding art to {0}", track.Location );
            try
            {
                track.AddArtworkFromFile( artPath );
            }
            catch
            {
                Console.WriteLine( "FAILED!" );
            }
        }
    }
}

As you can probably imagine, once you’re iterating over your entire iTunes Library, there’s lots of stuff you can to do make cleaning up your metadata easier. Some of other stuff I’ve used the iTunes API for include:

  • Normalizing band names so everything matches and is correct. (e.g. “Beatles”, “Beetles”, “The Beatles” all become “The Beatles”)
  • Finding tracks with missing album or artist information and list them in a text file to peruse and deal with later.
  • Populate the “Album Artist” to match the “Artist” field.
  • Find tracks in the library that are missing from the disk and delete them from the library

Hope you found this useful!

Going Technical

For the most part I’ve use this space for very infrequent updates about what I and the family have been up to.  The need to do that has been largely supplanted by Facebook and (to a lesser extent) Twitter.  So, I’ve decided to re-purpose this blog for nerdy technical content.

All four of us are on Facebook, and Samantha and I (Jason) can both be found on Twitter, so follow our goings on over there, and check back here for nerdy tech stuff.

Some Vegas Pictures on Flickr

I posted some pictures from our trip to Vegas on Flickr

vegas 028

Click here to see them all.

Here’s Sam’s Tap Number from Champions – April 12/08

Thriller

Julianna’s Competition Dances – April 19, 2008

All That Jazz

Fight for Your Right

Package Tracking Insanity

A couple of years ago I bought a laptop from Dell. It was my first mail-order computer. This comic perfectly sums up my life during the 10 day period between when I placed the order and when the laptop arrived.


From the always brilliant xkcd.com

A great warrior? Moi?

A friend and co-worker managed to both snap a picture of me with a ridiculous hairdo,  AND to photoshop that picture into the dashing samurai you see below.  I think I’m gonna start dressing like that all the time.
Samurai Me

Facebook – Yeah, we’re all over that.

Head on over to Facebook.com and look us up.

Eek! A teenager!

13 years ago today I became the proud papa to a little girl. Now she’s a teenager. How the time flies!
Happy birthday, doodle!