Monday, October 11, 2010

iTunes playcount updater script

I am pretty busy these days with my new job ( I am heading a start-up in the telecommunications market ) but I took a couple of hours to craft a couple of scripts.

The first script (lastfm_gettracks) downloads all of a user's song track information from Last.fm. It can be found on Pypi here.  More information can be perused here.

The second script takes as input the file generated by the former script and updates the iTunes database on an OSX machine (sorry, I don't do windozes). Documentation for this script can be found here whilst package details can be found on Pypi here.

Thursday, September 9, 2010

Logo contest

Help me choose a logo for my new company.  The logo contest on 99designs has ended and it is now time to vote!

Thanks!

Sunday, September 5, 2010

Chrome Framed extension

I have just published my latest Google Chrome extension:  Chrome-Framed.  The extension allows opening a tab with 2 columns 'frame'.   This functionality enables a user 2 pages side-by-side in the same chrome window.

Enjoy!

Tuesday, August 17, 2010

Musicbrainz and Last.fm proxies updated

Just a quick note to let users of musicbrainz-proxy-dbus & lastfm-proxy-dbus applications that new versions are available on my PPA.  Notable changes include:

- Tray icon support: the main application window can now be closed and a tray icon can control them
- Help button linking to a web accessible page

Sunday, June 20, 2010

Web Services available on Systemical.com

I've decided to open access to some web services I built.  These services are hosted on Google AppEngine and the documentation can be found here.

I will be opening access to more services so stay tuned!

Thursday, June 17, 2010

Last.fm Proxy with DBus interface

I just realized I haven't made a public announcement regarding an application that constitutes a critical piece of my Rhythmbox arsenal:  " lastfm-proxy-dbus ".

This Linux Gnome application serves as "proxy" to a Last.fm user's scrobbling history. The data collected through this proxy serves to populate the "playcount" field of Rhythmbox's database.

More information can be found here.

Tuesday, June 15, 2010

Rhythmbox Synclastfm plugin

Today I announce the availability of a brand new version (2.02) of my Rhythmbox plugin "Synclastfm" (see previous post).

This version packs the much anticipated "batch update" feature i.e. the plugin will walk the user's history on Last.fm in order to update Rhythmbox tracks 'playcount' field.

More information can be found here.  Have fun and don't forget to provide feedback!

Sunday, May 30, 2010

Musicbrainz Proxy service over DBus

I have just finished another building block on my quest to taming my music library: a Linux based application serving as 'proxy' (with caching of course) to Musicbrainz webservice.  The service is exposed through DBus.

Why?
Correlating music tracks across disparate applications / services can be daunting. For example, suppose one  scrobbles his/her tracks to Last.fm. Furthermore, let's say one wishes to keep his/her favorite Music Player in sync with his/her Last.fm profile.  This goal appears, on the surface, to be an easy one but as it turns out, support for finding & cataloging music tracks coherently across various applications / services remains elusive at the moment.

Also worth noting:  access to Musicbrainz's webservice is monitored.  Webservice API access is limited to 1call/sec: if many applications make uncoordinated access to the service, the user's machine might get blacklisted.  As I intend to make the track mbid a central piece of information for correlating my music tracks, I needed to address this issue.

Solution
With this application, it will be easier to integrate the various other building blocks of my music management arsenal. See the other project SyncLastfm that will benefit from this addition.

Project
The project's home page can be found here.  The associated Ohloh page can be found there.

Update:  the application will be installed under Applications / Other.
Update2: more information is accessible here.

Monday, May 10, 2010

Some Google Gadgets

I am in the process of building up my company website based on Google Apps, I need some Google Gadgets to embed but as I am unsure about the majority of the gadgets listed in the directory, I have created  some of my own.

  • Skype Account Information
  • Ohloh Profile Flair
  • Stackoverflow Profile Flair
  • Twitter Profile Flair with latest tweets
Links to the relevant gadgets are provided on my projects page.  I would rather not duplicate them here as I am most likely to forget to update them whereas on the project page they'll get my attention.



Reblog this post [with Zemanta]

Monday, February 8, 2010

Last.fm Web Service desktop interface through DBus

Not too long ago, I started my quest to Music Library Faiyland (my daughter would love this quote). On this journey, I have completed a couple of intermediate steps ( Rhythmbox plugin - Syncing with Last.fm and Rhythmbox plugin for Last.fm desktop client ) and now I am happy to announce another milestone: a DBus accessible interface to Last.fm's Web Service API.

API
The current DBus interface is rudimentary but can be easily extended ( I have abstracted Last.fm's API to a manageable degree ). I will certainly be expanding the methods in the near future based on my needs and "customer feedback" ;-) Below is a non-exhaustive list of the API:

  • Account related:
    • get/set Username
    • getAuthUrl : retrieve a URL for authenticating the service against a user
    • setApiKey , setSecretKey
  • Track related
    • track.addTags
    • track.getTags
    • track.removeTag

I have only implemented these methods because they get me what I need at the moment: the possibility to "rate" my music tracks through a hack using the tags to hold the rating for a track. E.g. a 5 stars track would get "R5" as tag.

Message Based Design Technique
In this project, I have further experimented with a design technique based on "Message Passing". I have made some notes on the subject here.

Project
The home page of this project can be found on my Github repository.  A Debian package can be found on my Launchpad PPA.

Friday, January 29, 2010

Notes on a Message Passing design

I am an avid supporter of "message based" systems. I took the time to perform a quick "brain dump" of some of my thoughts on the subject.



Follows a simple Python based implementation.



I will very likely make other contributions to my blog along the same lines.

Thursday, January 21, 2010

Message Bus for Gnome Object based Python projects

Whilst developing my latest software project (Rhythmbox plugin Last.fm sync), I have crafted a "Message Bus" based on Gnome GObject. Since I didn't have any experience at all with Gnome GObject previously, it took me sometimes to work out the details of the architecture.  For an example usage, please refer to my Git Repository.

""" 
    GObject based "Message Bus"
    
    @author: Jean-Lou Dupont
"""

import gobject #@UnresolvedImport

class Signals(gobject.GObject):
    """
    List of the application level signals
    """
    __gsignals__ = {

         ## NOTE: customization required here
         ## =================================
         ## Announces changes in the user's Last.fm properties
        "lastfm_username_changed":  (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)) 
        ,'lastfm_password_changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))

        ## Used to signal a change in the currently playing track
        ,"playing_song_changed":    (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,))
        
        ## Used to report a failure when accessing Last.fm web service
        ,'lastfm_request_failed':   (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
        
        ## Used for distributing the results of the query against the Last.fm web service
        ,"user_track_info":         (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,))
        
        ## Used to pass around the "shell" global object
        ,"rb_shell":                (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,))              
    }

    def __init__(self):
        gobject.GObject.__init__(self)
        
        
class Bus(object):
    """
    Message Bus
    
    Borg Pattern
    """
    _signals=Signals()

    @classmethod
    def emit(cls, name, *pa, **kwa):
        cls._signals.emit(name, *pa, **kwa)

    @classmethod
    def add_emission_hook(cls, name, callback):
        gobject.add_emission_hook(cls._signals, name, callback)
    
mbus=Bus()

## =============================================================== Tests

if __name__=="__main__":

    def callback(signal, data):
        print "callback: signal=%s, data=%s" % (signal, data)
    
    Bus.add_emission_hook("lastfm_username_changed", callback)
    
    Bus.emit("lastfm_username_changed", "jldupont")

Relevant Stackoverflow posts
Here are two Stackoverflow posts in relation with my exercise: question 1, question 2.

Rhythmbox plugin - Syncing with Last.fm

In my quest to manage my music collection seamlessly between media players, I've decided to use Last.Fm as my main database. Last.Fm provides ways to store:

  • History of played tracks
  • Playcount associated with played tracks
  • Tags associated with tracks
  • Playlists
  • etc.
Through their API (see mindmap), it is possible to have access to all this information (and much more).

Rhythmbox 
My music collection is currently organized through Rhythmbox - it wasn't my first choice at the time I've moved from my Windows desktop to my Linux Ubuntu one but it has proven very useful. RB can be extended with Python scripts quite painlessly.
Last.Fm Syncing
The plugin I have developed this time supports the following features:
  • When a track is played, it downloads the corresponding information from the user's Last.Fm account and updates the following fields of the Rhythmbox database:
    • Playcount: if the "last.fm playcount" associated with the track is greater than 0, the local playcount of RB is updated with it
    • Rating: if the "last.fm love" field is set for the track, the local "rating" field of the track is set to 5.0 (5 stars)
With this functionality, it is easier to update a local Rhythmbox media player database with information stored on a user's account on Last.fm.  The standard Last.Fm plugin of Rhythmbox must be enabled and configured correctly.
Installation
The plugin can be installed by following the procedure found at the project's home page. A direct link to the plugin Debian/Ubuntu repository is provided here.
Future
The project is far from being completed - I have many other features in the pipeline. Stay tuned!
Related project
There is a related project to this one: Rhythmbox - Last.Fm Desktop Client plugin.

Feedback is very welcome!

UPDATE: see here for details on the new release.

Monday, January 11, 2010

Rhythmbox plugin for Last.fm desktop client

I've recently lost my music database to the hands of Banshee (actually, the Sqlite3 database file is still somewhat salvageable). I have longed for an application that would make my life easy in managing my music collection (which is pretty extensive) and do this day haven't found one. The recent event pushed me to the edge: I am embarking on a quest to scratch my itch on this matter.

First step
The first step consisted in getting acquainted with Rhythmbox, my new music media player. Why Rhythmbox? because it supports a Python based extension system (compared to Banshee's C# based on) and I happen to really enjoy writing software using Python.
To this effect, I have crafted a plugin that sends the current playing state (START/PAUSED/RESUMED) of Rhythmbox to Last.fm's Desktop Client.
Plugin
The project is located on Github.
Project
I intend to make several other contributions focused on media players. My goal is to be able to synchronize my music collection seamlessly between Rhythmbox, Last.fm and iTunes (with possibly also Musicbrainz). Stay tuned!

Wednesday, January 6, 2010

Google Wave Invites

I've got some Google Wave invites left... first come, first served!