Sunday, December 16, 2012

Driving youtube using currently playing spotify tracks

I had the idea of using Spotify to drive youtube, basically providing a 'video jukebox' (although I hate that term!). Although it's a mash of different technologies, the implementation is pretty straight forward.



First, I used an apple script invoked from PHP to provide an XML webservice providing the currently playing track. Here's the script:

I then wrote a local HTML page that included an embedded Youtube Player. On startup the page would retrieve the currently playing track (using JQuery to call the aforementioned Webservice), query youtube (using the youtube search api), and then play the first search result in the embedded youtube player. It would then frequently check in with spotify and when the track changes, it will update the video. Here's the webpage:
This works quite well and even when in fullscreen the track automatically changes without interuption. There are a few issues though. Firstly, some tracks cannot be shown in the embedded player for copyright reasons. Secondly, sometimes the strategy of using the first youtube search result can be a bit hit and miss. To resolve this I think i'd need to add a hardcoded list of videos to use for particular spotify track IDs.

This could work quite well as a free-to-use website as the user's browser and youtube take the load - i'd just provide a HTML page. If only I could find a way to easily retrieve the currently playing spotify track that didn't cost me money. I could query last.fm using their neat web api, but they track usage per api account, not end user. This means that if multiple users used my embedded code, i'd quickly hit their fair use policy.

Saturday, November 24, 2012

Backing up my Spotify Playlists

I've been using Spotify for a number as my exclusive source of music, during which time i've built up some rather large playlists. If Spotify were to loose these lists it would take me years to recall and collate all of the tracks again, especially as many are 'Spotify Discoveries', for which I can't remember the artist seconds after adding, let alone years later. This makes me slightly paranoid.

Strangely, there doesn't appear to be a way to save a playlist tracklisting to a file (unless i'm missing something). You can copy the playlist into a text file, but this gives you Spotify URLs rather than track names. You can also choose to copy all tracks as Spotify URIs, but these are just internal Spotify Track IDs.

Spotify have a web API that allows you to query the spotify database, returning results as XML. This does allow you to query individual tracks, using the aforementioned URIs.

Therefore, with a bit of automation it's possible to take the list of URIs exported from Spotify and to query the Web API for each individual track, writing the call results to a CSV file..

I'm a Java programmer by trade, and I know that there are far more elegant ways of dealing with web APIs than the Java SDK plus a bunch of third party libraries. I could of used Groovy, but that felt like cheating, so I went with PhantomJS, a 'Headless Webkit' with a Javascript API.

The result is a script that given a named file containing a list of spotify URIs (one on each line), would query Spotify for the track name and artist, writing the result to a CSV file. All of this in less than 50 lines of code. Nice!
Obviously this is all a bit hacky and there's no error handling, but it's successfully saved my 445 track playlist outside of Spotify's Infrastructure. And I get to use recursion, which is always fun!

Friday, June 8, 2012

SMTP on Lion, Again!

I completely forgot that i'd blogged a solution for this before. This time I used gmail for outbound email due to ntl/virgin using a dodgy port for SSL connection.

Kudos to this page for helping - http://slashusr.wordpress.com/2012/02/14/enabling-postfix-for-outbound-relay-via-gmail-on-os-x-lion-11/

I followed it, ignoring all the parts about mapping mapping local users to 'real' email addresses.

As I have two phase login for gmail I had to generate an 'application specific' password for my postfix relay.

Thursday, September 22, 2011

And to mock a static void...

Next up, mocking a static void to make it do nothing and then verifiying it was called. Here's how I did it using PowerMock:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Thing.class)
public class MyTest {

   public void test() {

      // mock all static methods, rendering them useless/pointless
      PowerMockito.mockStatic(Thing.class)

      new Thing().save();

      // check save was called
      PowerMockito.verifyStatic();
      Thing.save();

   }

}

Wednesday, September 21, 2011

Mocking Roo Entities CRUD methods

When working with Roo it can be a pain to write true unit tests when your code interacts with CRUD/persistence methods on an Entity you've passed to it. The simple way around this is to use Mockito's 'spy' AKA partial mocking.

I tried this according to Mockito's documentation:
 Thing spy = spy(new Thing());
 when(spy.merge()).thenReturn(spy);
Unfortunately, as part of this code 'merge' is actually called, which will fail because Roo's logic attempts to merge the Mockito spy. The solution around this is to change how you setup the method stub:
 doReturn(spy).when(spy).merge();
For persist, i'd do
 doNothing().when(spy).persist();
I figured this out thanks to this page

Note that having to use a spy generally indicates poor design. Maybe that says something about Roo and its active record pattern...

Sunday, August 7, 2011

SMTP on Macbook with VirginMedia

After upgrading to Lion PostfixEnabler no longer worked, so I had to do this by hand. It was less than straight forward. Cudos to the following pages for pushing me in the right direction:

  • http://cloughnet.org/jeremy/linux/postfix/relaying-to-an-email-server-using-tls-wrapper-mode/
  • http://marc.info/?l=postfix-users&m=123799751204881

Virgin Media's SMTP server uses SSL on port 465. For reasons I don't care to understand, this is deprecated, and not supported by Postfix. Therefore, to use this we have to setup a secure tunnel using stunnel, and then get postfix to use the newly created stunnel as a relay.

Stunnel is already installed on Lion (as stunnel3). As I didn't realise this until after the event, I built stunnel from source my self:
  • Install XCode (required for 'make')
  • Go to the stunnel website
  • Get latest source
  • Extract to disk
  • Following stunnel build instructions
  • Put any old stuff in the generated certificate
Add the following to the stunnel.conf file in the root of the source

[smtp-tls-wrapper]
accept = 11125
client = yes
connect = smtp.ntlworld.com:465

Fire stunnel up with this config check there are no errors
sudo stunnel stunnel.conf
Before configuring postfix, we need to stop OS X from getting involved (for reasons why, see here). Edit the org.postfix.master.plist file in /System/Library/LaunchDaemons (as root or using sudo) and add the following two tags within the <dict> container:
<key>Disabled</key>
<true/>

Then Restart your Mac.

Finally, configure postfix. Add the following to the end of /etc/postfix/main.cf
myhostname = davidatkins.co.uk
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = localhost.localdomain, localhost, 127.0.0.1
relayhost = [127.0.0.1]:11125
mynetworks_style = subnet

Note the relayhost to stunnel.

You should then be able to send mail:
echo "hello" | mail -s "subject" dave@davidatkins.co.uk
You can view the postfix logs in /var/log/mail.log
tail -f /var/log/mail.log

Note that once you've done this you'll need to manually start postfix and stunnel after every reboot to send mail.