static LIBMTP_track_t *
transfer_track (RBMtpSource *source,
		LIBMTP_mtpdevice_t *device,
		RhythmDBEntry *entry,
		const char *filename,
		guint64 filesize,
		const char *mimetype)
{
	LIBMTP_track_t *trackmeta = LIBMTP_new_track_t ();
	GDate d;
	int ret;

	trackmeta->title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
	trackmeta->album = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);
	trackmeta->artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
	trackmeta->genre = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_GENRE);
	trackmeta->filename = g_path_get_basename (filename);

	if (rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE) > 0) { /* Entries without a date returns 0, g_date_set_julian don't accept that */
		g_date_set_julian (&d, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE));
		trackmeta->date	= gdate_to_char (&d);
	}
	trackmeta->tracknumber = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER);
	trackmeta->duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION) * 1000;
	trackmeta->rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING) * 20;
	trackmeta->usecount = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_PLAY_COUNT);
	trackmeta->filesize = filesize;
	if (mimetype == NULL) {
		mimetype = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE);
	}
	trackmeta->filetype = mimetype_to_filetype (source, mimetype);
	rb_debug ("using libmtp filetype %d (%s) for source media type %s",
		  trackmeta->filetype,
		  LIBMTP_Get_Filetype_Description (trackmeta->filetype),
		  mimetype);

#ifdef HAVE_LIBMTP_030
	ret = LIBMTP_Send_Track_From_File (device, filename, trackmeta, NULL, NULL);
#else
	ret = LIBMTP_Send_Track_From_File (device, filename, trackmeta, NULL, NULL, 0);
#endif
	rb_debug ("LIBMTP_Send_Track_From_File (%s) returned %d", filename, ret);
	if (ret != 0) {
		report_libmtp_errors (device, TRUE);
		LIBMTP_destroy_track_t (trackmeta);
		return NULL;
	}

	if (strcmp (trackmeta->album, _("Unknown")) != 0) {
		add_track_to_album (source, trackmeta->album, trackmeta);
	}

	return trackmeta;
}
Esempio n. 2
0
bool MtpDevice::GetSupportedFiletypes(QList<Song::FileType>* ret,
                                      LIBMTP_mtpdevice_t* device) {
    uint16_t* list = nullptr;
    uint16_t length = 0;

    if (LIBMTP_Get_Supported_Filetypes(device, &list, &length) || !list ||
            !length)
        return false;

    for (int i = 0; i < length; ++i) {
        switch (LIBMTP_filetype_t(list[i])) {
        case LIBMTP_FILETYPE_WAV:
            *ret << Song::Type_Wav;
            break;
        case LIBMTP_FILETYPE_MP2:
        case LIBMTP_FILETYPE_MP3:
            *ret << Song::Type_Mpeg;
            break;
        case LIBMTP_FILETYPE_WMA:
            *ret << Song::Type_Asf;
            break;
        case LIBMTP_FILETYPE_MP4:
        case LIBMTP_FILETYPE_M4A:
        case LIBMTP_FILETYPE_AAC:
            *ret << Song::Type_Mp4;
            break;
        case LIBMTP_FILETYPE_FLAC:
            *ret << Song::Type_Flac;
            *ret << Song::Type_OggFlac;
            break;
        case LIBMTP_FILETYPE_OGG:
            *ret << Song::Type_OggVorbis;
            *ret << Song::Type_OggSpeex;
            *ret << Song::Type_OggFlac;
            break;
        default:
            qLog(Error) << "Unknown MTP file format"
                        << LIBMTP_Get_Filetype_Description(
                            LIBMTP_filetype_t(list[i]));
            break;
        }
    }

    free(list);
    return true;
}
Esempio n. 3
0
static char *
impl_build_dest_uri (RBRemovableMediaSource *source,
		     RhythmDBEntry *entry,
		     const char *mimetype,
		     const char *extension)
{
	gulong id;
	char *uri;
	LIBMTP_filetype_t filetype;

	if (mimetype == NULL) {
		mimetype = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE);
	}
	filetype = mimetype_to_filetype (RB_MTP_SOURCE (source), mimetype);
	rb_debug ("using libmtp filetype %d (%s) for source media type %s",
		  filetype,
		  LIBMTP_Get_Filetype_Description (filetype),
		  mimetype);

	/* the prepare-sink callback needs the entry ID to set up the
	 * upload data, and we want to use the supplied extension for
	 * the filename on the device.
	 *
	 * this is pretty ugly - it'd be much nicer to have a source-defined
	 * structure that got passed around (or was accessible from) the various
	 * hooks and methods called during the track transfer process.  probably
	 * something to address in my horribly stalled track transfer rewrite..
	 *
	 * the structure would either be created when queuing the track for transfer,
	 * or here; passed to any prepare-source or prepare-sink callbacks for the
	 * encoder; and then passed to whatever gets called when the transfer is complete.
	 */
	id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
	if (extension == NULL) {
		extension = "";
	}
	uri = g_strdup_printf ("xrbmtp://%lu/%s/%d", id, extension, filetype);
	return uri;
}
Esempio n. 4
0
static void dump_fileinfo(LIBMTP_file_t *file)
{
  printf("File ID: %u\n", file->item_id);
  if (file->filename != NULL)
    printf("   Filename: %s\n", file->filename);

  // This is sort of special...
  if (file->filesize == (uint32_t) -1) {
    printf("   None. (abstract file, size = -1)\n");
  } else {
#ifdef __WIN32__
    printf("   File size %llu (0x%016I64X) bytes\n", file->filesize, file->filesize);
#else
    printf("   File size %llu (0x%016llX) bytes\n",
	   (long long unsigned int) file->filesize, 
	   (long long unsigned int) file->filesize);
#endif
  }
  printf("   Parent ID: %u\n", file->parent_id);
  printf("   Storage ID: 0x%08X\n", file->storage_id);
  printf("   Filetype: %s\n", LIBMTP_Get_Filetype_Description(file->filetype));
}
Esempio n. 5
0
int sendtrack_function(char * from_path, char * to_path, char *partist, char *palbumartist, char *ptitle, char *pgenre, char *palbum, char *pcomposer, uint16_t tracknum, uint16_t length, uint16_t year, uint32_t storageid, uint16_t quiet)
{
  char *filename, *parent;
  char artist[80], albumartist[80], title[80], genre[80], album[80], composer[80];
  char num[80];
  uint64_t filesize;
  uint32_t parent_id = 0;
  struct stat sb;
  LIBMTP_track_t *trackmeta;
  LIBMTP_album_t *albuminfo;
  int ret;

  printf("Sending track %s to %s\n", from_path, to_path);

  trackmeta = LIBMTP_new_track_t();
  albuminfo = LIBMTP_new_album_t();

  parent = dirname(strdup(to_path));
  filename = basename(strdup(to_path));
  parent_id = parse_path (parent,files,folders);
  if (parent_id == -1) {
    printf("Parent folder could not be found, skipping\n");
    return 1;
  }

  if (stat(from_path, &sb) == -1) {
    fprintf(stderr, "%s: ", from_path);
    perror("stat");
    return 1;
  }

  if (!S_ISREG(sb.st_mode))
    return 0;

  filesize = sb.st_size;
  trackmeta->filetype = find_filetype (from_path);
  if (!LIBMTP_FILETYPE_IS_TRACK(trackmeta->filetype)) {
    printf("Not a valid track codec: \"%s\"\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
    return 1;
  }

  if ((ptitle == NULL) && (quiet == 0)) {
    if ( (ptitle = prompt("Title", title, 80, 0)) != NULL )
      if (!strlen(ptitle)) ptitle = NULL;
  }

  if ((palbum == NULL) && (quiet == 0)) {
    if ( (palbum = prompt("Album", album, 80, 0)) != NULL )
      if (!strlen(palbum)) palbum = NULL;
  }

  if ((palbumartist == NULL) && (quiet == 0)) {
    if ( (palbumartist = prompt("Album artist", albumartist, 80, 0)) != NULL )
      if (!strlen(palbumartist)) palbumartist = NULL;
  }

  if ((partist == NULL) && (quiet == 0)) {
    if ( (partist = prompt("Artist", artist, 80, 0)) != NULL )
      if (!strlen(partist)) partist = NULL;
  }

  if ((pcomposer == NULL) && (quiet == 0)) {
    if ( (pcomposer = prompt("Writer or Composer", composer, 80, 0)) != NULL )
      if (!strlen(pcomposer)) pcomposer = NULL;
  }

  if ((pgenre == NULL) && (quiet == 0)) {
    if ( (pgenre = prompt("Genre", genre, 80, 0)) != NULL )
      if (!strlen(pgenre)) pgenre = NULL;
  }

  if ((tracknum == 0) && (quiet == 0)) {
    char *pnum;
    if ( (pnum = prompt("Track number", num, 80, 0)) == NULL )
      tracknum = 0;
    else
      tracknum = strtoul(pnum, 0, 10);
  }

  if ((year == 0) && (quiet == 0)) {
    char *pnum;
    if ( (pnum = prompt("Year", num, 80, 0)) == NULL )
      year = 0;
    else
      year = strtoul(pnum, 0, 10);
  }

  if ((length == 0) && (quiet == 0)) {
    char *pnum;
    if ( (pnum = prompt("Length", num, 80, 0)) == NULL )
      length = 0;
    else
      length = strtoul(pnum, 0, 10);
  }

  printf("Sending track:\n");
  printf("Codec:     %s\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
  if (ptitle) {
    printf("Title:     %s\n", ptitle);
    trackmeta->title = strdup(ptitle);
  }
  if (palbum) {
    printf("Album:     %s\n", palbum);
    trackmeta->album = strdup(palbum);
    albuminfo->name = strdup(palbum);
  }
  if (palbumartist) {
    printf("Album artist:    %s\n", palbumartist);
    albuminfo->artist = strdup(palbumartist);
  }
  if (partist) {
    printf("Artist:    %s\n", partist);
    trackmeta->artist = strdup(partist);
    if (palbumartist == NULL)
      albuminfo->artist = strdup(partist);
  }
  if (pcomposer) {
    printf("Writer or Composer:    %s\n", pcomposer);
    trackmeta->composer = strdup(pcomposer);
    albuminfo->composer = strdup(pcomposer);
  }
  if (pgenre) {
    printf("Genre:     %s\n", pgenre);
    trackmeta->genre = strdup(pgenre);
    albuminfo->genre = strdup(pgenre);
  }
  if (year > 0) {
    char tmp[80];
    printf("Year:      %d\n", year);
    snprintf(tmp, sizeof(tmp)-1, "%4d0101T0000.0", year);
    tmp[sizeof(tmp)-1] = '\0';
    trackmeta->date = strdup(tmp);
  }
  if (tracknum > 0) {
    printf("Track no:  %d\n", tracknum);
    trackmeta->tracknumber = tracknum;
  }
  if (length > 0) {
    printf("Length:    %d\n", length);
    // Multiply by 1000 since this is in milliseconds
    trackmeta->duration = length * 1000;
  }
  // We should always have this
  if (filename != NULL) {
    trackmeta->filename = strdup(filename);
  }
  trackmeta->filesize = filesize;
  trackmeta->parent_id = parent_id;
  {
    int rc;
    char *desc = NULL;
    LIBMTP_devicestorage_t *pds = NULL;

    if (0 != (rc=LIBMTP_Get_Storage(device, LIBMTP_STORAGE_SORTBY_NOTSORTED))) {
      perror("LIBMTP_Get_Storage()");
      exit(-1);
    }
    for (pds = device->storage; pds != NULL; pds = pds->next) {
      if (pds->id == storageid) {
	desc = strdup(pds->StorageDescription);
	break;
      }
    }
    if (NULL != desc) {
      printf("Storage ID: %s (%u)\n", desc, storageid);
      free(desc);
    } else
      printf("Storage ID: %u\n", storageid);
    trackmeta->storage_id = storageid;
  }

  printf("Sending track...\n");
  ret = LIBMTP_Send_Track_From_File(device, from_path, trackmeta, progress, NULL);
  printf("\n");
  if (ret != 0) {
    printf("Error sending track.\n");
    LIBMTP_Dump_Errorstack(device);
    LIBMTP_Clear_Errorstack(device);
    ret = 1;
  } else {
    printf("New track ID: %d\n", trackmeta->item_id);
  }

  /* Add here add to album call */
  if (palbum)
    ret = add_track_to_album(albuminfo, trackmeta);

  LIBMTP_destroy_album_t(albuminfo);
  LIBMTP_destroy_track_t(trackmeta);

  return ret;
}
Esempio n. 6
0
static gboolean
device_opened_idle (DeviceOpenedData *data)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (data->source);
	int i;
	gboolean has_mp3 = FALSE;

	if (data->name != NULL) {
		g_object_set (data->source, "name", data->name, NULL);
	}

	/* when the source name changes after this, try to update the device name */
	g_signal_connect (G_OBJECT (data->source), "notify::name",
			  (GCallback)rb_mtp_source_name_changed_cb, NULL);

	rb_media_player_source_load (RB_MEDIA_PLAYER_SOURCE (data->source));

	for (i = 0; i < data->num_types; i++) {
		const char *mediatype;

		if (i <= LIBMTP_FILETYPE_UNKNOWN) {
			priv->supported_types[data->types[i]] = 1;
		}

		/* this has to work with the remapping done in
		 * rb-removable-media-source.c:impl_paste.
		 */
		switch (data->types[i]) {
		case LIBMTP_FILETYPE_WAV:
			mediatype = "audio/x-wav";
			break;
		case LIBMTP_FILETYPE_MP3:
			/* special handling for mp3: always put it at the front of the list
			 * if it's supported.
			 */
			has_mp3 = TRUE;
			mediatype = NULL;
			break;
		case LIBMTP_FILETYPE_WMA:
			mediatype = "audio/x-ms-wma";
			break;
		case LIBMTP_FILETYPE_OGG:
			mediatype = "application/ogg";
			break;
		case LIBMTP_FILETYPE_MP4:
		case LIBMTP_FILETYPE_M4A:
		case LIBMTP_FILETYPE_AAC:
			mediatype = "audio/aac";
			break;
		case LIBMTP_FILETYPE_WMV:
			mediatype = "audio/x-ms-wmv";
			break;
		case LIBMTP_FILETYPE_ASF:
			mediatype = "video/x-ms-asf";
			break;
		case LIBMTP_FILETYPE_FLAC:
			mediatype = "audio/flac";
			break;

		case LIBMTP_FILETYPE_JPEG:
			rb_debug ("JPEG (album art) supported");
			mediatype = NULL;
			priv->album_art_supported = TRUE;
			break;

		default:
			rb_debug ("unknown libmtp filetype %s supported", LIBMTP_Get_Filetype_Description (data->types[i]));
			mediatype = NULL;
			break;
		}

		if (mediatype != NULL) {
			rb_debug ("media type %s supported", mediatype);
			priv->mediatypes = g_list_prepend (priv->mediatypes,
							   g_strdup (mediatype));
		}
	}

	if (has_mp3) {
		rb_debug ("audio/mpeg supported");
		priv->mediatypes = g_list_prepend (priv->mediatypes, g_strdup ("audio/mpeg"));
	}

	g_object_unref (data->source);
	free (data->types);
	g_free (data->name);
	g_free (data);

	return FALSE;
}
Esempio n. 7
0
static RhythmDBEntry *
add_mtp_track_to_db (RBMtpSource *source,
		     RhythmDB *db,
		     LIBMTP_track_t *track)
{
	RhythmDBEntry *entry = NULL;
	RhythmDBEntryType *entry_type;
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	char *name = NULL;

	/* ignore everything except audio (allow audio/video types too, since they're probably pretty common) */
	if (!(LIBMTP_FILETYPE_IS_AUDIO (track->filetype) || LIBMTP_FILETYPE_IS_AUDIOVIDEO (track->filetype))) {
		rb_debug ("ignoring non-audio item %d (filetype %s)",
			  track->item_id,
			  LIBMTP_Get_Filetype_Description (track->filetype));
		return NULL;
	}

	/* Set URI */
	g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
	name = g_strdup_printf ("xrbmtp://%i/%s", track->item_id, track->filename);
	entry = rhythmdb_entry_new (RHYTHMDB (db), entry_type, name);
	g_free (name);
        g_object_unref (entry_type);

	if (entry == NULL) {
		rb_debug ("cannot create entry %i", track->item_id);
		g_object_unref (G_OBJECT (db));
		return NULL;
	}

	/* Set track number */
	if (track->tracknumber != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->tracknumber);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_TRACK_NUMBER,
				    &value);
		g_value_unset (&value);
	}

	/* Set length */
	if (track->duration != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->duration/1000);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_DURATION,
				    &value);
		g_value_unset (&value);
	}

	/* Set file size */
	if (track->filesize != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_UINT64);
		g_value_set_uint64 (&value, track->filesize);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_FILE_SIZE,
				    &value);
		g_value_unset (&value);
	}

	/* Set playcount */
	if (track->usecount != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->usecount);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
					       RHYTHMDB_PROP_PLAY_COUNT,
					       &value);
		g_value_unset (&value);
	}
	/* Set rating */
	if (track->rating != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_DOUBLE);
		g_value_set_double (&value, track->rating/20);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
					       RHYTHMDB_PROP_RATING,
					       &value);
		g_value_unset (&value);
	}
	/* Set release date */
	if (track->date != NULL && track->date[0] != '\0') {
		GTimeVal tv;
		if (g_time_val_from_iso8601 (track->date, &tv)) {
			GDate d;
			GValue value = {0, };
			g_value_init (&value, G_TYPE_ULONG);
			g_date_set_time_val (&d, &tv);
			g_value_set_ulong (&value, g_date_get_julian (&d));
			rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_DATE, &value);
			g_value_unset (&value);
		}
	}

	/* Set title */
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_TITLE, track->title);

	/* Set album, artist and genre from MTP */
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ARTIST, track->artist);
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ALBUM, track->album);
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_GENRE, track->genre);

	g_hash_table_insert (priv->entry_map, entry, track);
	rhythmdb_commit (RHYTHMDB (db));

	return entry;
}
Esempio n. 8
0
static gboolean
device_opened_idle (DeviceOpenedData *data)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (data->source);
	int i;
	GstEncodingTarget *target;
	GList *profiles = NULL;

	if (data->name != NULL) {
		g_object_set (data->source, "name", data->name, NULL);
	}

	/* when the source name changes after this, try to update the device name */
	g_signal_connect (G_OBJECT (data->source), "notify::name",
			  (GCallback)rb_mtp_source_name_changed_cb, NULL);

	rb_media_player_source_load (RB_MEDIA_PLAYER_SOURCE (data->source));

	for (i = 0; i < data->num_types; i++) {
		const char *mediatype;
		gboolean prepend;
		if (i <= LIBMTP_FILETYPE_UNKNOWN) {
			priv->supported_types[data->types[i]] = 1;
		}

		mediatype = NULL;
		prepend = FALSE;
		switch (data->types[i]) {
		case LIBMTP_FILETYPE_WAV:
			/*mediatype = "audio/x-wav";*/
			/* don't bother including this? */
			break;
		case LIBMTP_FILETYPE_MP3:
			mediatype = "audio/mpeg";
			prepend = TRUE;		/* always goes first if supported */
			break;
		case LIBMTP_FILETYPE_WMA:
			mediatype = "audio/x-wma";
			break;
		case LIBMTP_FILETYPE_OGG:
			mediatype = "audio/x-vorbis";
			break;
		case LIBMTP_FILETYPE_MP4:
		case LIBMTP_FILETYPE_M4A:
		case LIBMTP_FILETYPE_AAC:
			mediatype = "audio/x-aac";
			break;
		case LIBMTP_FILETYPE_WMV:
			mediatype = "audio/x-ms-wmv";		/* media type? */
			break;
		case LIBMTP_FILETYPE_ASF:
			mediatype = "video/x-ms-asf";		/* media type? */
			break;
		case LIBMTP_FILETYPE_FLAC:
			mediatype = "audio/x-flac";
			break;

		case LIBMTP_FILETYPE_JPEG:
			rb_debug ("JPEG (album art) supported");
			priv->album_art_supported = TRUE;
			break;

		default:
			rb_debug ("unknown libmtp filetype %s supported", LIBMTP_Get_Filetype_Description (data->types[i]));
			break;
		}

		if (mediatype != NULL) {
			GstEncodingProfile *profile;
			profile = rb_gst_get_encoding_profile (mediatype);
			if (profile != NULL) {
				rb_debug ("media type %s supported", mediatype);
				if (prepend) {
					profiles = g_list_prepend (profiles, profile);
				} else {
					profiles = g_list_append (profiles, profile);
				}
			} else {
				rb_debug ("no encoding profile for supported media type %s", mediatype);
			}
		}
	}

	if (priv->album_art_supported) {
		priv->art_store = rb_ext_db_new ("album-art");
	}

	target = gst_encoding_target_new ("mtpdevice", "device", "", profiles);
	g_object_set (data->source, "encoding-target", target, NULL);

	g_object_unref (data->source);
	free (data->types);
	g_free (data->name);
	g_free (data);

	return FALSE;
}
static GObject *
rb_mtp_source_constructor (GType type, guint n_construct_properties,
			   GObjectConstructParam *construct_properties)
{
	RBMtpSource *source;
	RBMtpSourcePrivate *priv;
	RBEntryView *tracks;
	GtkIconTheme *theme;
	GdkPixbuf *pixbuf;
	gint size;
	guint16 *types = NULL;
	guint16 num_types= 0;

	source = RB_MTP_SOURCE (G_OBJECT_CLASS (rb_mtp_source_parent_class)->
				constructor (type, n_construct_properties, construct_properties));

	tracks = rb_source_get_entry_view (RB_SOURCE (source));
	rb_entry_view_append_column (tracks, RB_ENTRY_VIEW_COL_RATING, FALSE);
	rb_entry_view_append_column (tracks, RB_ENTRY_VIEW_COL_LAST_PLAYED, FALSE);

	/* icon */
	theme = gtk_icon_theme_get_default ();
	gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR, &size, NULL);
	pixbuf = gtk_icon_theme_load_icon (theme, "multimedia-player", size, 0, NULL);

	rb_source_set_pixbuf (RB_SOURCE (source), pixbuf);
	g_object_unref (pixbuf);

	g_signal_connect (G_OBJECT (source), "notify::name",
			  (GCallback)rb_mtp_source_name_changed_cb, NULL);
	
	/* figure out supported file types */
	priv = MTP_SOURCE_GET_PRIVATE (source);
	if (LIBMTP_Get_Supported_Filetypes(priv->device, &types, &num_types) == 0) {
		int i;
		gboolean has_mp3 = FALSE;
		for (i = 0; i < num_types; i++) {
			const char *mediatype;

			if (i <= LIBMTP_FILETYPE_UNKNOWN) {
				priv->supported_types[types[i]] = 1;
			}

			/* this has to work with the remapping done in 
			 * rb-removable-media-source.c:impl_paste.
			 */
			switch (types[i]) {
			case LIBMTP_FILETYPE_WAV:
				mediatype = "audio/x-wav";
				break;
			case LIBMTP_FILETYPE_MP3:
				/* special handling for mp3: always put it at the front of the list
				 * if it's supported.
				 */
				has_mp3 = TRUE;
				mediatype = NULL;
				break;
			case LIBMTP_FILETYPE_WMA:
				mediatype = "audio/x-ms-wma";
				break;
			case LIBMTP_FILETYPE_OGG:
				mediatype = "application/ogg";
				break;
			case LIBMTP_FILETYPE_MP4:
			case LIBMTP_FILETYPE_M4A:
			case LIBMTP_FILETYPE_AAC:
				mediatype = "audio/aac";
				break;
			case LIBMTP_FILETYPE_WMV:
				mediatype = "audio/x-ms-wmv";
				break;
			case LIBMTP_FILETYPE_ASF:
				mediatype = "video/x-ms-asf";
				break;
			case LIBMTP_FILETYPE_FLAC:
				mediatype = "audio/flac";
				break;

			case LIBMTP_FILETYPE_JPEG:
				rb_debug ("JPEG (album art) supported");
				mediatype = NULL;
				priv->album_art_supported = TRUE;
				break;

			default:
				rb_debug ("unknown libmtp filetype %s supported", LIBMTP_Get_Filetype_Description (types[i]));
				mediatype = NULL;
				break;
			}

			if (mediatype != NULL) {
				rb_debug ("media type %s supported", mediatype);
				priv->mediatypes = g_list_prepend (priv->mediatypes,
								   g_strdup (mediatype));
			}
		}

		if (has_mp3) {
			rb_debug ("audio/mpeg supported");
			priv->mediatypes = g_list_prepend (priv->mediatypes, g_strdup ("audio/mpeg"));
		}
	} else {
		report_libmtp_errors (priv->device, FALSE);
	}
	
	if (priv->album_art_supported) {
		RhythmDB *db;

		db = get_db_for_source (source);
		g_signal_connect_object (db, "entry-extra-metadata-notify::rb:coverArt",
					 G_CALLBACK (artwork_notify_cb), source, 0);
		g_object_unref (db);
	}

	rb_mtp_source_load_tracks (source);

	return G_OBJECT (source);
}
Esempio n. 10
0
int main (int argc, char **argv)
{
    LIBMTP_raw_device_t * rawdevices;
    int numrawdevices;
    LIBMTP_error_number_t err;
    int i;

    int opt;
    extern int optind;
    extern char *optarg;

    while ((opt = getopt(argc, argv, "d")) != -1 ) {
        switch (opt) {
        case 'd':
            LIBMTP_Set_Debug(LIBMTP_DEBUG_PTP | LIBMTP_DEBUG_DATA);
            break;
        }
    }

    argc -= optind;
    argv += optind;

    LIBMTP_Init();

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

    fprintf(stdout, "Listing raw device(s)\n");
    err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
    switch(err) {
    case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
        fprintf(stdout, "   No raw devices found.\n");
        return 0;
    case LIBMTP_ERROR_CONNECTING:
        fprintf(stderr, "Detect: There has been an error connecting. Exiting\n");
        return 1;
    case LIBMTP_ERROR_MEMORY_ALLOCATION:
        fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n");
        return 1;
    case LIBMTP_ERROR_NONE:
    {
        int i;

        fprintf(stdout, "   Found %d device(s):\n", numrawdevices);
        for (i = 0; i < numrawdevices; i++) {
            if (rawdevices[i].device_entry.vendor != NULL ||
                    rawdevices[i].device_entry.product != NULL) {
                fprintf(stdout, "   %s: %s (%04x:%04x) @ bus %d, dev %d\n",
                        rawdevices[i].device_entry.vendor,
                        rawdevices[i].device_entry.product,
                        rawdevices[i].device_entry.vendor_id,
                        rawdevices[i].device_entry.product_id,
                        rawdevices[i].bus_location,
                        rawdevices[i].devnum);
            } else {
                fprintf(stdout, "   %04x:%04x @ bus %d, dev %d\n",
                        rawdevices[i].device_entry.vendor_id,
                        rawdevices[i].device_entry.product_id,
                        rawdevices[i].bus_location,
                        rawdevices[i].devnum);
            }
        }
    }
    break;
    case LIBMTP_ERROR_GENERAL:
    default:
        fprintf(stderr, "Unknown connection error.\n");
        return 1;
    }

    /* Iterate over connected MTP devices */
    fprintf(stdout, "Attempting to connect device(s)\n");
    for (i = 0; i < numrawdevices; i++) {
        LIBMTP_mtpdevice_t *device;
        LIBMTP_devicestorage_t *storage;
        char *friendlyname;
        char *syncpartner;
        char *sectime;
        char *devcert;
        uint16_t *filetypes;
        uint16_t filetypes_len;
        uint8_t maxbattlevel;
        uint8_t currbattlevel;
        int ret;

        device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]);
        if (device == NULL) {
            fprintf(stderr, "Unable to open raw device %d\n", i);
            continue;
        }

        LIBMTP_Dump_Errorstack(device);
        LIBMTP_Clear_Errorstack(device);
        LIBMTP_Dump_Device_Info(device);

        printf("MTP-specific device properties:\n");
        // The friendly name
        friendlyname = LIBMTP_Get_Friendlyname(device);
        if (friendlyname == NULL) {
            fprintf(stdout, "   Friendly name: (NULL)\n");
        } else {
            fprintf(stdout, "   Friendly name: %s\n", friendlyname);
            free(friendlyname);
        }
        syncpartner = LIBMTP_Get_Syncpartner(device);
        if (syncpartner == NULL) {
            fprintf(stdout, "   Synchronization partner: (NULL)\n");
        } else {
            fprintf(stdout, "   Synchronization partner: %s\n", syncpartner);
            free(syncpartner);
        }

        // Some battery info
        ret = LIBMTP_Get_Batterylevel(device, &maxbattlevel, &currbattlevel);
        if (ret == 0) {
            fprintf(stdout, "   Battery level %d of %d (%d%%)\n",currbattlevel, maxbattlevel,
                    (int) ((float) currbattlevel/ (float) maxbattlevel * 100.0));
        } else {
            // Silently ignore. Some devices does not support getting the
            // battery level.
            LIBMTP_Clear_Errorstack(device);
        }

        ret = LIBMTP_Get_Supported_Filetypes(device, &filetypes, &filetypes_len);
        if (ret == 0) {
            uint16_t i;

            printf("libmtp supported (playable) filetypes:\n");
            for (i = 0; i < filetypes_len; i++) {
                fprintf(stdout, "   %s\n", LIBMTP_Get_Filetype_Description(filetypes[i]));
            }
        } else {
            LIBMTP_Dump_Errorstack(device);
            LIBMTP_Clear_Errorstack(device);
        }

        // Secure time XML fragment
        ret = LIBMTP_Get_Secure_Time(device, &sectime);
        if (ret == 0 && sectime != NULL) {
            fprintf(stdout, "\nSecure Time:\n%s\n", sectime);
            free(sectime);
        } else {
            // Silently ignore - there may be devices not supporting secure time.
            LIBMTP_Clear_Errorstack(device);
        }

        // Device certificate XML fragment
        if (rawdevices[i].device_entry.vendor_id == 0x041e) {
            /*
             * This code is currently disabled except for vendors we
             * know does support it: all devices say that
             * they support getting a device certificate but a lot of
             * them obviously doesn't, instead they crash when you try
             * to obtain it.
             */
            ret = LIBMTP_Get_Device_Certificate(device, &devcert);
            if (ret == 0 && devcert != NULL) {
                fprintf(stdout, "\nDevice Certificate:\n%s\n", devcert);
                free(devcert);
            } else {
                fprintf(stdout, "Unable to acquire device certificate, perhaps this device "
                        "does not support this\n");
                LIBMTP_Dump_Errorstack(device);
                LIBMTP_Clear_Errorstack(device);
            }
        }

        /* Try to get Media player device info XML file... */
        /* Loop over storages */
        for (storage = device->storage; storage != 0; storage = storage->next) {
            LIBMTP_file_t *files;

            /* Get file listing for the root directory, no other dirs */
            files = LIBMTP_Get_Files_And_Folders(device,
                                                 storage->id,
                                                 0);

            if (files != NULL) {
                LIBMTP_file_t *file, *tmp;
                file = files;
                while (file != NULL) {
                    if (!strcmp(file->filename, "WMPInfo.xml") ||
                            !strcmp(file->filename, "WMPinfo.xml") ||
                            !strcmp(file->filename, "default-capabilities.xml")) {
                        if (file->item_id != 0) {
                            /* Dump this file */
                            FILE *xmltmp = tmpfile();
                            int tmpfiledescriptor = fileno(xmltmp);

                            if (tmpfiledescriptor != -1) {
                                int ret = LIBMTP_Get_Track_To_File_Descriptor(device,
                                          file->item_id,
                                          tmpfiledescriptor,
                                          NULL,
                                          NULL);
                                if (ret == 0) {
                                    uint8_t *buf = NULL;
                                    uint32_t readbytes;

                                    buf = malloc(XML_BUFSIZE);
                                    if (buf == NULL) {
                                        printf("Could not allocate %08x bytes...\n", XML_BUFSIZE);
                                        LIBMTP_Dump_Errorstack(device);
                                        LIBMTP_Clear_Errorstack(device);
                                        free(rawdevices);
                                        return 1;
                                    }

                                    lseek(tmpfiledescriptor, 0, SEEK_SET);
                                    readbytes = read(tmpfiledescriptor, (void*) buf, XML_BUFSIZE);

                                    if (readbytes >= 2 && readbytes < XML_BUFSIZE) {
                                        fprintf(stdout, "\n%s file contents:\n", file->filename);
                                        dump_xml_fragment(buf, readbytes);
                                    } else {
                                        perror("Unable to read file");
                                        LIBMTP_Dump_Errorstack(device);
                                        LIBMTP_Clear_Errorstack(device);
                                    }
                                    free(buf);
                                } else {
                                    LIBMTP_Dump_Errorstack(device);
                                    LIBMTP_Clear_Errorstack(device);
                                }
                                fclose(xmltmp);
                            }
                        }
                    }
                    tmp = file;
                    file = file->next;
                    LIBMTP_destroy_file_t(tmp);
                }
            }
        }
        LIBMTP_Release_Device(device);
    } /* End For Loop */

    free(rawdevices);

    printf("OK.\n");

    return 0;
}