bool MtpLoader::TryLoad() { MtpConnection dev(url_); if (!dev.is_valid()) { emit Error(tr("Error connecting MTP device")); return false; } // Load the list of songs on the device SongList songs; LIBMTP_track_t* tracks = LIBMTP_Get_Tracklisting_With_Callback(dev.device(), nullptr, nullptr); while (tracks) { LIBMTP_track_t* track = tracks; Song song; song.InitFromMTP(track, url_.host()); song.set_directory_id(1); songs << song; tracks = tracks->next; LIBMTP_destroy_track_t(track); } // Need to remove all the existing songs in the database first backend_->DeleteSongs(backend_->FindSongsInDirectory(1)); // Add the songs we've just loaded backend_->AddOrUpdateSongs(songs); return true; }
/***************************************************************************** * Everything else *****************************************************************************/ static int AddDevice( services_discovery_t *p_sd, LIBMTP_raw_device_t *p_raw_device ) { char *psz_name = NULL; LIBMTP_mtpdevice_t *p_device; LIBMTP_track_t *p_track, *p_tmp; if( ( p_device = LIBMTP_Open_Raw_Device( p_raw_device ) ) != NULL ) { if( !( psz_name = LIBMTP_Get_Friendlyname( p_device ) ) ) if( !( psz_name = LIBMTP_Get_Modelname( p_device ) ) ) if( !( psz_name = strdup( N_( "MTP Device" ) ) ) ) return VLC_ENOMEM; msg_Info( p_sd, "Found device: %s", psz_name ); p_sd->p_sys->i_bus = p_raw_device->bus_location; p_sd->p_sys->i_dev = p_raw_device->devnum; p_sd->p_sys->i_product_id = p_raw_device->device_entry.product_id; if( ( p_track = LIBMTP_Get_Tracklisting_With_Callback( p_device, CountTracks, p_sd ) ) == NULL ) { msg_Warn( p_sd, "No tracks on the device" ); } else { if( !( p_sd->p_sys->pp_items = calloc( p_sd->p_sys->i_tracks_num, sizeof( input_item_t * ) ) ) ) { free( psz_name ); return VLC_ENOMEM; } p_sd->p_sys->i_count = 0; while( p_track != NULL ) { msg_Dbg( p_sd, "Track found: %s - %s", p_track->artist, p_track->title ); AddTrack( p_sd, p_track ); p_tmp = p_track; p_track = p_track->next; LIBMTP_destroy_track_t( p_tmp ); } } p_sd->p_sys->psz_name = psz_name; LIBMTP_Release_Device( p_device ); return VLC_SUCCESS; } else { msg_Info( p_sd, "The device seems to be mounted, unmount it first" ); return VLC_EGENERIC; } }
static void get_track_list (RBMtpThread *thread, RBMtpThreadTask *task) { RBMtpTrackListCallback cb = task->callback; gboolean device_forgets_albums = TRUE; GHashTable *update_albums = NULL; LIBMTP_track_t *tracks = NULL; LIBMTP_album_t *albums; LIBMTP_album_t *album; /* get all the albums */ albums = LIBMTP_Get_Album_List (thread->device); rb_mtp_thread_report_errors (thread, FALSE); if (albums != NULL) { LIBMTP_album_t *album; for (album = albums; album != NULL; album = album->next) { if (album->name == NULL) continue; rb_debug ("album: %s, %d tracks", album->name, album->no_tracks); g_hash_table_insert (thread->albums, album->name, album); if (album->no_tracks != 0) { device_forgets_albums = FALSE; } } if (device_forgets_albums) { rb_debug ("stupid mtp device detected. will rebuild all albums."); } } else { rb_debug ("No albums"); device_forgets_albums = FALSE; } tracks = LIBMTP_Get_Tracklisting_With_Callback (thread->device, NULL, NULL); rb_mtp_thread_report_errors (thread, FALSE); if (tracks == NULL) { rb_debug ("no tracks on the device"); } else if (device_forgets_albums) { LIBMTP_track_t *track; rb_debug ("rebuilding albums"); update_albums = g_hash_table_new (g_direct_hash, g_direct_equal); for (track = tracks; track != NULL; track = track->next) { if (track->album != NULL) { gboolean new_album = FALSE; album = add_track_to_album (thread, track->album, track->item_id, track->storage_id, &new_album); g_hash_table_insert (update_albums, album, GINT_TO_POINTER (new_album)); } } rb_debug ("finished rebuilding albums"); } cb (tracks, task->user_data); /* the callback owns the tracklist */ if (device_forgets_albums) { GHashTableIter iter; gpointer album_ptr; gpointer new_album_ptr; rb_debug ("writing rebuilt albums back to the device"); g_hash_table_iter_init (&iter, update_albums); while (g_hash_table_iter_next (&iter, &album_ptr, &new_album_ptr)) { album = album_ptr; rb_debug ("writing album \"%s\"", album->name); write_album_to_device (thread, album, GPOINTER_TO_INT (new_album_ptr)); } g_hash_table_destroy (update_albums); rb_debug ("removing remaining empty albums"); g_hash_table_iter_init (&iter, thread->albums); while (g_hash_table_iter_next (&iter, NULL, &album_ptr)) { int ret; album = album_ptr; if (album->no_tracks == 0) { rb_debug ("pruning empty album \"%s\"", album->name); ret = LIBMTP_Delete_Object (thread->device, album->album_id); if (ret != 0) { rb_mtp_thread_report_errors (thread, FALSE); } g_hash_table_iter_remove (&iter); } } rb_debug ("finished updating albums on the device"); } }
static gboolean load_mtp_db_idle_cb (RBMtpSource* source) { RhythmDB *db = NULL; RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source); LIBMTP_track_t *tracks = NULL; LIBMTP_album_t *albums; gboolean device_forgets_albums = TRUE; db = get_db_for_source (source); g_assert (db != NULL); albums = LIBMTP_Get_Album_List (priv->device); report_libmtp_errors (priv->device, FALSE); if (albums != NULL) { LIBMTP_album_t *album; for (album = albums; album != NULL; album = album->next) { rb_debug ("album: %s, %d tracks", album->name, album->no_tracks); g_hash_table_insert (priv->album_map, album->name, album); if (album->no_tracks != 0) { device_forgets_albums = FALSE; } } if (device_forgets_albums) { rb_debug ("stupid mtp device detected. will rebuild all albums."); } } else { rb_debug ("No albums"); device_forgets_albums = FALSE; } #ifdef HAVE_LIBMTP_030 tracks = LIBMTP_Get_Tracklisting_With_Callback (priv->device, NULL, NULL); #else tracks = LIBMTP_Get_Tracklisting (priv->device); #endif report_libmtp_errors (priv->device, FALSE); if (tracks != NULL) { LIBMTP_track_t *track; for (track = tracks; track != NULL; track = track->next) { add_mtp_track_to_db (source, db, track); if (device_forgets_albums && track->album != NULL) { add_track_to_album (source, track->album, track); } } } else { rb_debug ("No tracks"); } /* for stupid devices, remove any albums left with no tracks */ if (device_forgets_albums) { GHashTableIter iter; gpointer value; LIBMTP_album_t *album; g_hash_table_iter_init (&iter, priv->album_map); while (g_hash_table_iter_next (&iter, NULL, &value)) { int ret; album = value; if (album->no_tracks == 0) { rb_debug ("pruning empty album \"%s\"", album->name); ret = LIBMTP_Delete_Object (priv->device, album->album_id); if (ret != 0) { report_libmtp_errors (priv->device, FALSE); } g_hash_table_iter_remove (&iter); } } } g_object_unref (G_OBJECT (db)); return FALSE; }