diff -d -c -r last.fm-1.4.1.57486-old/src/AudioController.cpp last.fm-1.4.1.57486/src/AudioController.cpp
*** last.fm-1.4.1.57486-old/src/AudioController.cpp	Tue Dec 25 15:14:58 2007
--- last.fm-1.4.1.57486/src/AudioController.cpp	Tue Dec 25 15:21:09 2007
***************
*** 66,71 ****
--- 66,149 ----
  // Max number of errors in a row before we abort
  static const int k_streamerErrorLimit = 5;
  
+ 
+ 
+ 
+ 
+ 
+ // ID3V1 tag format
+ // HINT: this are fixed widths, which are directly read out of the file
+ struct id3v1_t {
+ 	char		name[30];
+ 	char		interpreter[30];
+ 	char		album[30];
+ 	char		year[4];
+ 	char		comment[30];
+ 	char		genre;
+ };
+ 
+ // call it at the end of the writing-process
+ void fwriteMp3Tags(const id3v1_t& tags, FILE* f) {
+ 	fwrite("TAG", 3, 1, f);
+ 	fwrite(&tags, sizeof(id3v1_t), 1, f);
+ }
+ 
+ 
+ Ripper* Ripper::singleton = NULL;
+ 
+ int Ripper::onNewEvent( const QString& msg ) {
+ 	QString script = MooseUtils::savePath( "onNewEvent" );
+ 	QString cmd = "\"" + script + "\" " + msg;
+ 	printf("executing: %s\n", cmd.toUtf8().constData());
+ 	return system(cmd.toUtf8().constData());
+ }
+ 
+ void Ripper::onTrackStarted( const TrackInfo& track ) {
+ 	curTrack = &track;
+ 	printf("onTrackStarted: %s - %s\n",
+ 		track.artist().toUtf8().constData(), track.track().toUtf8().constData());
+ 	onNewEvent("newtrack: \"" + track.artist() + "\" - \"" + track.track() + "\"");
+ }
+ 
+ void Ripper::onTrackEndReached( int atPosition ) {
+ 	if(!curTrack) return;
+ 	
+ 	QString filename = MooseUtils::savePath( curTrack->artist() + " - " + curTrack->track() + ".mp3" );
+ 	printf("onTrackEndReached: %s - %s\n",
+ 		curTrack->artist().toUtf8().constData(), curTrack->track().toUtf8().constData());
+ 	
+ 	if(onNewEvent("endtrack: \"" + curTrack->artist() + "\" - \"" + curTrack->track() + "\"") == 0) {
+ 		printf("   saving %s\n", filename.toUtf8().constData());
+ 	
+ 		id3v1_t tags;
+ 		strncpy(tags.name, curTrack->track().toAscii().constData(), 30);
+ 		strncpy(tags.interpreter, curTrack->artist().toAscii().constData(), 30);
+ 		strncpy(tags.album, curTrack->album().toAscii().constData(), 30);
+ 		strncpy(tags.year, "", 4);
+ 		strncpy(tags.comment, "", 30);
+ 		tags.genre = 255;
+ 		
+ 		FILE* f = fopen(filename.toUtf8().constData(), "wb");
+ 		fwrite(buffer.constData(), buffer.length(), 1, f);
+ 		fwriteMp3Tags(tags, f);
+ 		fclose(f);
+ 	} else
+ 		printf("   not saving\n");
+ 	
+ 	finishCurrent();
+ }
+ 
+ void Ripper::processData( const QByteArray &data ) {
+ 	buffer.append(data);
+ }
+ 
+ void Ripper::ignoreCurrent() {
+ 	finishCurrent();
+ 	printf("ignore current track\n");
+ }
+ 
+ 
+ 
  AudioControllerThread::AudioControllerThread( QObject* parent ) :
          QThread( parent ),
          m_input( 0 ),
***************
*** 350,355 ****
--- 428,434 ----
  
                  m_proxyOutput->processData( data );
                  bool fine = m_transcode->processData( data );
+ 				if(fine && Ripper::singleton) Ripper::singleton->processData( data );
  
                  if ( !fine )
                  {
***************
*** 749,757 ****
--- 828,838 ----
  }
  
  
+ 
  void
  AudioController::onTrackStarted()
  {
+ 	ripper.onTrackStarted( m_currentTrack );
      emit trackStarted( m_currentTrack );
  }
  
***************
*** 760,766 ****
  AudioController::onTrackEndReached( int atPosition )
  {
      LOGL( 4, "AudioController::onTrackEndReached" );
! 
      emit trackEnded( m_currentTrack, atPosition );
  }
  
--- 841,848 ----
  AudioController::onTrackEndReached( int atPosition )
  {
      LOGL( 4, "AudioController::onTrackEndReached" );
! 	
! 	ripper.onTrackEndReached( atPosition );
      emit trackEnded( m_currentTrack, atPosition );
  }
  
***************
*** 768,773 ****
--- 850,858 ----
  void
  AudioController::onThreadStateChanged( RadioState newState )
  {
+     if( m_state == State_Stopping || m_state == State_Skipping )
+        	ripper.ignoreCurrent();
+ 
      switch ( m_state )
      {
          // When we're in Skipping or Stopping, all we're interested in is
diff -d -c -r last.fm-1.4.1.57486-old/src/AudioController.h last.fm-1.4.1.57486/src/AudioController.h
*** last.fm-1.4.1.57486-old/src/AudioController.h	Tue Dec 25 15:14:58 2007
--- last.fm-1.4.1.57486/src/AudioController.h	Tue Dec 25 15:16:26 2007
***************
*** 253,258 ****
--- 253,280 ----
  };
  
  
+ 
+ class Ripper {
+ protected:
+ 	const TrackInfo* curTrack;
+ 	QByteArray buffer;
+ 	
+ 	void finishCurrent() { curTrack = NULL; buffer.clear(); }
+ 	int onNewEvent( const QString& msg );
+ 	
+ public:
+ 	static Ripper* singleton;
+ 	Ripper() : curTrack(NULL) { singleton = this; }
+ 	~Ripper() { singleton = NULL; }
+ 	
+ 	void onTrackStarted( const TrackInfo& track );
+ 	void onTrackEndReached( int atPosition );
+ 	void processData( const QByteArray &data );
+ 	void ignoreCurrent();
+ };
+ 
+ 
+ 
  /*************************************************************************/ /**
      The AudioController manages playback of audio, it can take individual
      tracks or a playlist and manage the changing of tracks automatically.
***************
*** 376,382 ****
      QStringList m_devices;
      
      QMutex m_mutex;
!     
  private slots:
  
      void onTrackStarted();
--- 398,406 ----
      QStringList m_devices;
      
      QMutex m_mutex;
! 
! 	Ripper ripper;
! 
  private slots:
  
      void onTrackStarted();
