Exemple #1
0
static int add_track_to_album(LIBMTP_album_t *albuminfo, LIBMTP_track_t *trackmeta)
{
  LIBMTP_album_t *album;
  LIBMTP_album_t *album_orig;
  LIBMTP_album_t *found_album = NULL;
  int ret;

  /* Look for the album */
  album = LIBMTP_Get_Album_List(device);
  album_orig = album;
  while(album != NULL) {
    if ((album->name != NULL &&
	album->artist != NULL &&
	!strcmp(album->name, albuminfo->name) &&
	!strcmp(album->artist, albuminfo->artist)) ||
	  (album->name != NULL &&
	album->composer != NULL &&
	!strcmp(album->name, albuminfo->name) &&
	!strcmp(album->composer, albuminfo->composer))) {
      /* Disconnect this album for later use */
      found_album = album;
      album = album->next;
      found_album->next = NULL;
    } else {
      album = album->next;
    }
  }

  if (found_album == NULL) {
    printf("Could not find Album. Retrying with only Album name\n");
    album = album_orig;
    while(album != NULL) {
      if ((album->name != NULL) &&
          !strcmp(album->name, albuminfo->name) ){
        /* Disconnect this album for later use */
        found_album = album;
        album = album->next;
        found_album->next = NULL;
      } else {
        album = album->next;
      }
    }
  }

  if (found_album != NULL) {
    uint32_t *tracks;

    tracks = (uint32_t *)malloc((found_album->no_tracks+1) * sizeof(uint32_t));
    printf("Album \"%s\" found: updating...\n", found_album->name);
    if (!tracks) {
      printf("failed malloc in add_track_to_album()\n");
      return 1;
    }
    found_album->no_tracks++;
    if (found_album->tracks != NULL) {
      memcpy(tracks, found_album->tracks, found_album->no_tracks * sizeof(uint32_t));
      free(found_album->tracks);
    }
    tracks[found_album->no_tracks-1] = trackmeta->item_id;
    found_album->tracks = tracks;
    ret = LIBMTP_Update_Album(device, found_album);
  } else {
    uint32_t *trackid;

    trackid = (uint32_t *)malloc(sizeof(uint32_t));
    *trackid = trackmeta->item_id;
    albuminfo->tracks = trackid;
    albuminfo->no_tracks = 1;
    albuminfo->storage_id = trackmeta->storage_id;
    printf("Album doesn't exist: creating...\n");
    ret = LIBMTP_Create_New_Album(device, albuminfo);
    /* albuminfo will be destroyed later by caller */
  }

  /* Delete the earlier retrieved Album list */
  album=album_orig;
  while(album!=NULL){
    LIBMTP_album_t *tmp;

    tmp = album;
    album = album->next;
    LIBMTP_destroy_album_t(tmp);
  }

  if (ret != 0) {
    printf("Error creating or updating album.\n");
    printf("(This could be due to that your device does not support albums.)\n");
    LIBMTP_Dump_Errorstack(device);
    LIBMTP_Clear_Errorstack(device);
  } else {
    printf("success!\n");
  }
  return ret;
}
Exemple #2
0
int main () {
    LIBMTP_mtpdevice_t *device_list, *iter;

    LIBMTP_Init();

    fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n");

    switch(LIBMTP_Get_Connected_Devices(&device_list))
    {
    case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
        fprintf(stdout, "mtp-albums: No Devices have been found\n");
        return 0;
    case LIBMTP_ERROR_CONNECTING:
        fprintf(stderr, "mtp-albums: There has been an error connecting. Exit\n");
        return 1;
    case LIBMTP_ERROR_MEMORY_ALLOCATION:
        fprintf(stderr, "mtp-albums: Memory Allocation Error. Exit\n");
        return 1;


    case LIBMTP_ERROR_GENERAL:
    default:
        fprintf(stderr, "mtp-albums: Unknown error, please report "
                "this to the libmtp developers\n");
        return 1;


    case LIBMTP_ERROR_NONE:
        fprintf(stdout, "mtp-albums: Successfully connected\n");
        fflush(stdout);
    }


    for(iter = device_list; iter != NULL; iter = iter->next)
    {
        char *friendlyname;
        LIBMTP_album_t *album_list, *album, *tmp;


        friendlyname = LIBMTP_Get_Friendlyname(iter);
        if (friendlyname == NULL) {
            printf("Retrieving Albums on Device with name: (NULL)\n");
        } else {
            printf("Retrieving Albums on Device with name: %s\n", friendlyname);
            free(friendlyname);
        }

        album_list = LIBMTP_Get_Album_List(iter);
        album = album_list;
        while(album != NULL)
        {
            dump_albuminfo(album);
            tmp = album;
            album = album->next;
            LIBMTP_destroy_album_t(tmp);
        }
    }

    LIBMTP_Release_Device_List(device_list);
    printf("OK.\n");
    return 0;
}
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;
}
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");
	}
}
Exemple #5
0
	void Plugin::AppendAlbum (LIBMTP_mtpdevice_t *device, LIBMTP_track_t *track, const UnmountableFileInfo& info)
	{
		auto albuminfo = LIBMTP_new_album_t ();
		albuminfo->artist = strdup (info.Artist_.toUtf8 ().constData ());
		albuminfo->name = strdup (info.Album_.toUtf8 ().constData ());
		albuminfo->genre = strdup (info.Genres_.join ("; ").toUtf8 ().constData ());

		auto album = LIBMTP_Get_Album_List (device);
		auto albumOrig = album;

		decltype (album) foundAlbum = nullptr, resultingAlgum = nullptr;

		while (album)
		{
			if (album->name &&
					(album->artist || album->composer) &&
					QString::fromUtf8 (album->name) == info.Album_ &&
					(QString::fromUtf8 (album->artist) == info.Artist_ ||
					 QString::fromUtf8 (album->composer) == info.Artist_))
			{
				foundAlbum = album;
				album = album->next;
				foundAlbum->next = nullptr;
			}
			else
				album = album->next;
		}

		if (foundAlbum)
		{
			auto tracks = static_cast<uint32_t*> (malloc ((foundAlbum->no_tracks + 1) * sizeof (uint32_t)));

			++foundAlbum->no_tracks;

			if (foundAlbum->tracks)
			{
				memcpy (tracks, foundAlbum->tracks, foundAlbum->no_tracks * sizeof (uint32_t));
				free (foundAlbum->tracks);
			}

			tracks [foundAlbum->no_tracks - 1] = track->item_id;
			foundAlbum->tracks = tracks;

			if (LIBMTP_Update_Album (device, foundAlbum))
			{
				LIBMTP_Dump_Errorstack (device);
				LIBMTP_Clear_Errorstack (device);
			}

			resultingAlgum = foundAlbum;
		}
		else
		{
			auto trackId = static_cast<uint32_t*> (malloc (sizeof (uint32_t)));
			*trackId = track->item_id;
			albuminfo->tracks = trackId;
			albuminfo->no_tracks = 1;
			albuminfo->storage_id = track->storage_id;

			if (LIBMTP_Create_New_Album (device, albuminfo))
			{
				LIBMTP_Dump_Errorstack (device);
				LIBMTP_Clear_Errorstack (device);
			}

			resultingAlgum = albuminfo;
		}

		SetAlbumArt (device, resultingAlgum, info.AlbumArtPath_);

		while (albumOrig)
		{
			auto tmp = albumOrig;
			albumOrig = albumOrig->next;
			LIBMTP_destroy_album_t (tmp);
		}

		LIBMTP_destroy_album_t (albuminfo);
	}