SyntaxHighlighter

Wednesday, April 20, 2011

Controlling Your Tunes In F#

Every so often I find myself in the interactive window while listening to iTunes in the background. Today I thought to myself "It would be really cool to change the track, mute the sound, or even rewind the track of a song in FSI." Conveniently enough iTunes allows us to generate a typed library out of the executable. There's a couple of ways to get at this library, you could use the visual studio command prompt and generate a typed library to store in some known location or you can let visual studio do it for you. I'm lazy so I opted for the latter. =)

To generate an iTunes library for consumption in F# using visual studio simply do the following:
1) create a new F# console application.
2) right + click references and add a new reference off the COM tab. We want the iTunes Type Library. I happen to have version 1.13 but you may have a newer version which is fine, go ahead an add the type library.















3) You can see from the screen shot above that the reference got added
and generated a typed library for us in the project bin or obj directory.
The name of the generated library is Interop.iTunesLib.dll


Now the fun begins, we can open a new F# script file
and dot into this library to see what it offers.
Below is the F# script file that I came up with.


#i @"path-to-dll-here"
#r "Interop.iTunesLib.dll"

open iTunesLib

(*** Grab a handle to iTunes ***)
let appcls = new iTunesAppClass()

(*** Play the current playlist ***)
appcls.Play()

(*** Shuffle the current playlist ***)
do appcls.CurrentPlaylist.Shuffle <- true

(*** Next Track  ***)
do applcs.NextTrack()
(*** Previous Track  ***)
do applcs.PreviousTrack()
(*** Back Track (Go back to the beginning of the track  ***)
do appcls.BackTrack()
(*** Sound Volume ***)
do appcls.SoundVolume <-75
(*** Pause ***)
do appcls.Pause()
(*** Rewind ***)
do appcls.Rewind()
(*** FastFoward ***)
do appcls.FastFoward()
(*** Co-worker interruption ***)
do appcls.Mute <- true

//Lets have some fun with tracks
(*** Helper function to play a track ***)
let play (track: IITTrack) = track.Play()

(*** Print out All tracks in current playlist ***)
do
    for item: IITTrack in appcls.CurrentPlaylist.Tracks do
        printf "%s \n" item.Name

(*** Retrieve track by name & play it ***)
do appcls.CurrentPlaylist.Tracks.ItemByName "Too Much" |> play

(*** Just found out about a new FP Podcast ***)
do appcls.SubscribeToPodcast("url-of-podcast-here")
(*** What's New on iTunes!? ***)
do appcls.GotoMusicStoreHomePage()


A couple of things worth noting here.
1) iTunes needs to be open and running before you can manipulate it.
2) The above script just scratches the surface of what's possible with communicating with iTunes.
You can also convert files,  tap into the browser and other operations
that you'd normally have to use the UI to do.
Personally I like staying in the fsharp interactive window. =)

-Develop with passion

Sunday, April 3, 2011

Exploring MongoHQ with F#

Recently, I've been working on a Silverlight 4 project which will hopefully go live soon.
This project started off nice and light as all green field projects do, and then the unavoidable requirement came up... storage. A few customers utter'd access. After I finished  laughing I thought to myself- maybe SQL?
So I turned to my data structure and immediately realized that its not structured for SQL. I've played around with a few object databases... db4o, ravendb, etc. Then I remembered Mongodb, over the past several years this object database has received quite a bit of attention. I must admit I haven't paid much attention to it, so I decided to give it a world. Headed over to the spot, read through some of the docs and realized I need essentially two dll's.
1) MongoDB.Bson.dll
2) MongoDB.Driver.dll

So I downloaded it and ran through the introduction tutorial.
After I got the Mongod server up and running on my local box I was able to store and retrieve some mock data (using the mongo client) with ease.  Now it was finally time to write some code and see it in action.
So, I fired up FSI and produced the simple F# script.

#I @"D:\ODev Solutions\MongoDb\CSharpDriver"
#r "MongoDB.Bson.dll"
#r "MongoDB.Driver"

open MongoDB.Bson
open MongoDB.Bson.Serialization
open MongoDB.Driver
open MongoDB.Bson.IO

// helper func insert name_value in Bson document
let Bson_NameValue (name,value) =
 new BsonElement(name,BsonValue.Create value)

// helper func get all keys in a Bson document
let getkeys (document: BsonDocument) =
    document.Names

(* Connect to Mongo Server *)
let connectionString = "mongodb://localhost"
let server = MongoServer.Create connectionString
server.Connect

(* Get Database - if it does not exists then one is created. *)
let test = server.GetDatabase "test"

(* Store usernames and passwords *)
let profilescollection = test.GetCollection "mockprofiles"

(* Create the mock structure that will store a single user profile *)
type profile = {UserName : string; Password : string; }
let p = { UserName = "someuser@somedomain.com"; Password = "password"; }

let convert_profile_to_BsonDocument (p: profile) =
     let d = new BsonDocument()
    d.Add(Bson_NameValue("UserName",p.UserName)) |> ignore
    d.Add(Bson_NameValue("Password",p.Password)) |> ignore
    d
let profilebson = convert_profile_to_BsonDocument p

(* Insert the mock profile into the newly created profiles collection *)
profilescollection.Insert profilebson

*Retrieve mock profile*

(* Mongodb Query Document - can think of it as a where clause *)
let qd = new QueryDocument(Bson_NameValue("UserName","someuser@somedomain.com"))

let mockprofile = profilescollection.FindOne(qd)
printf  "UserName: %s   Password: %s" mockprofile.UserName mockprofile.Password

Okay, all good right? Wait... if I'm going to use this as production solution how do I even go about deploying something like Mongodb? Do I look for a hosting account that knows about monogo? Do I look for a hosting account that will give me full access to the box so that I can run mongo and manage it myself? After some searching around I found MongoHQ.













The guys over at monogohq make it super simple to setup a production object database.
They charge monthly or annually based on the disk space you use. Starting at free accounts up to 16mb and then progressively goes up from there. I like this solution a lot because I don't have to think about the maintenance and they provide an admin portal so I can manage the database and get reports from their web interface. As for the code changes there was only one. the connection string. =)

example: mongodb://username:password@flame.mongohq.com:portnumber/databasename

If you're considering a project with an object database check out Mongodb and MongoHQ.
Really slick!