예제 #1
0
void spl_to_playlist_t(LIBMTP_mtpdevice_t* device, PTPObjectInfo *oi,
                       const uint32_t id, LIBMTP_playlist_t * const pl)
{
    // Fill in playlist metadata
    // Use the Filename as the playlist name, dropping the ".spl" extension
    pl->name = malloc(sizeof(char)*(strlen(oi->Filename) -4 +1));
    memcpy(pl->name, oi->Filename, strlen(oi->Filename) -4);
    // Set terminating character
    pl->name[strlen(oi->Filename) - 4] = 0;
    pl->playlist_id = id;
    pl->parent_id = oi->ParentObject;
    pl->storage_id = oi->StorageID;
    pl->tracks = NULL;
    pl->no_tracks = 0;
    
    LIBMTP_PLST_DEBUG("pl->name='%s'\n", pl->name);
    
    // open a temporary file
    char tmpname[] = "/tmp/mtp-spl2pl-XXXXXX";
    int fd = mkstemp(tmpname);
    if(fd < 0) {
        LIBMTP_ERROR("failed to make temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
        return;
    }
    // make sure the file will be deleted afterwards
    if(unlink(tmpname) < 0)
        LIBMTP_ERROR("failed to delete temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
    int ret = LIBMTP_Get_File_To_File_Descriptor(device, pl->playlist_id, fd, NULL, NULL);
    if( ret < 0 ) {
        // FIXME     add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Playlist: Could not get .spl playlist file.");
        close(fd);
        LIBMTP_INFO("FIXME closed\n");
    }
    
    text_t* p = read_into_spl_text_t(device, fd);
    close(fd);
    
    // FIXME cache these somewhere else so we don't keep calling this!
    LIBMTP_folder_t *folders;
    LIBMTP_file_t *files;
    folders = LIBMTP_Get_Folder_List(device);
    files = LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL);
    
    // convert the playlist listing to track ids
    pl->no_tracks = trackno_spl_text_t(p);
    LIBMTP_PLST_DEBUG("%u track%s found\n", pl->no_tracks, pl->no_tracks==1?"":"s");
    pl->tracks = malloc(sizeof(uint32_t)*(pl->no_tracks));
    tracks_from_spl_text_t(p, pl->tracks, folders, files);
    
    free_spl_text_t(p);
    
    // debug: add a break since this is the top level function call
    LIBMTP_PLST_DEBUG("------------\n\n");
}
예제 #2
0
int main (int argc, char **argv)
{

    int do_delete = 0;
    int opt;

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

    while ( (opt = getopt(argc, argv, "d")) != -1 ) {
        switch (opt) {
        case 'd':
            do_delete = 1;
            break;
        default:
            break;
        }
    }

    if(do_delete == 0) {
        printf("This is a dummy run. No folders will be deleted.\n");
        printf("To delete folders, use the '-d' option.\n");
    }

    LIBMTP_mtpdevice_t *device;
    LIBMTP_folder_t *folders;
    LIBMTP_file_t *files;

    LIBMTP_Init();
    device = LIBMTP_Get_First_Device();
    if (device == NULL) {
        printf("No devices.\n");
        exit (0);
    }


    files = LIBMTP_Get_Filelisting_With_Callback(device,NULL,NULL);


    folders = LIBMTP_Get_Folder_List(device);

    if(folders == NULL) {
        printf("No folders found\n");
    } else {
        prune_empty_folders(device,files,folders,do_delete);
    }

    LIBMTP_destroy_folder_t(folders);
    LIBMTP_destroy_file_t(files);

    LIBMTP_Release_Device(device);
    printf("OK.\n");
    exit (0);
}
예제 #3
0
/**
 * Push a playlist_t onto the device after converting it to a .spl format
 *
 * @param device mtp device pointer
 * @param pl the LIBMTP_playlist_t to convert (pl->playlist_id will be updated
 *           with the newly created object's id)
 * @return 0 on success, any other value means failure.
 */
int playlist_t_to_spl(LIBMTP_mtpdevice_t *device,
                      LIBMTP_playlist_t * const pl)
{
    text_t* t;
    LIBMTP_folder_t *folders;
    LIBMTP_file_t *files;
    folders = LIBMTP_Get_Folder_List(device);
    files = LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL);
    
    char tmpname[] = "/tmp/mtp-spl2pl-XXXXXX"; // must be a var since mkstemp modifies it
    
    LIBMTP_PLST_DEBUG("pl->name='%s'\n",pl->name);
    
    // open a file descriptor
    int fd = mkstemp(tmpname);
    if(fd < 0) {
        LIBMTP_ERROR("failed to make temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
        return -1;
    }
    // make sure the file will be deleted afterwards
    if(unlink(tmpname) < 0)
        LIBMTP_ERROR("failed to delete temp file for %s.spl -> %s, errno=%s\n", pl->name, tmpname, strerror(errno));
    
    // decide on which version of the .spl format to use
    uint32_t ver_major;
    uint32_t ver_minor = 0;
    PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo;
    if(FLAG_PLAYLIST_SPL_V2(ptp_usb)) ver_major = 2;
    else ver_major = 1; // FLAG_PLAYLIST_SPL_V1()
    
    LIBMTP_PLST_DEBUG("%u track%s\n", pl->no_tracks, pl->no_tracks==1?"":"s");
    LIBMTP_PLST_DEBUG(".spl version %d.%02d\n", ver_major, ver_minor);
    
    // create the text for the playlist
    spl_text_t_from_tracks(&t, pl->tracks, pl->no_tracks, ver_major, ver_minor, NULL, folders, files);
    write_from_spl_text_t(device, fd, t);
    free_spl_text_t(t); // done with the text
    
    // create the file object for storing
    LIBMTP_file_t* f = malloc(sizeof(LIBMTP_file_t));
    f->item_id = 0;
    f->parent_id = pl->parent_id;
    f->storage_id = pl->storage_id;
    f->filename = malloc(sizeof(char)*(strlen(pl->name)+5));
    strcpy(f->filename, pl->name);
    strcat(f->filename, ".spl"); // append suffix
    f->filesize = lseek(fd, 0, SEEK_CUR); // file desc is currently at end of file
    f->filetype = LIBMTP_FILETYPE_UNKNOWN;
    f->next = NULL;
    
    LIBMTP_PLST_DEBUG("%s is %dB\n", f->filename, (int)f->filesize);
    
    // push the playlist to the device
    lseek(fd, 0, SEEK_SET); // reset file desc. to start of file
    int ret = LIBMTP_Send_File_From_File_Descriptor(device, fd, f, NULL, NULL);
    pl->playlist_id = f->item_id;
    free(f->filename);
    free(f);
    
    // release the memory when we're done with it
    close(fd);
    // debug: add a break since this is the top level function call
    LIBMTP_PLST_DEBUG("------------\n\n");
    
    return ret;
}
예제 #4
0
static void
delete_done_cb (LIBMTP_mtpdevice_t *device, TracksDeletedCallbackData *data)
{
	LIBMTP_folder_t *folders;
	LIBMTP_file_t *files;

	data->actually_free = FALSE;
	update_free_space_cb (device, RB_MTP_SOURCE (data->source));

	/* if any of the folders we just deleted from are now empty, delete them */
	folders = LIBMTP_Get_Folder_List (device);
	files = LIBMTP_Get_Filelisting_With_Callback (device, NULL, NULL);
	if (folders != NULL) {
		GHashTableIter iter;
		gpointer key;
		g_hash_table_iter_init (&iter, data->check_folders);
		while (g_hash_table_iter_next (&iter, &key, NULL)) {
			LIBMTP_folder_t *f;
			LIBMTP_folder_t *c;
			LIBMTP_file_t *file;
			uint32_t folder_id = GPOINTER_TO_UINT(key);

			while (folder_id != device->default_music_folder && folder_id != 0) {

				f = LIBMTP_Find_Folder (folders, folder_id);
				if (f == NULL) {
					rb_debug ("unable to find folder %u", folder_id);
					break;
				}

				/* don't delete folders with children that we didn't just delete */
				for (c = f->child; c != NULL; c = c->sibling) {
					if (g_hash_table_lookup (data->check_folders,
								 GUINT_TO_POINTER (c->folder_id)) == NULL) {
						break;
					}
				}
				if (c != NULL) {
					rb_debug ("folder %s has children", f->name);
					break;
				}

				/* don't delete folders that contain files */
				for (file = files; file != NULL; file = file->next) {
					if (file->parent_id == folder_id) {
						break;
					}
				}

				if (file != NULL) {
					rb_debug ("folder %s contains at least one file: %s", f->name, file->filename);
					break;
				}

				/* ok, the folder is empty */
				rb_debug ("deleting empty folder %s", f->name);
				LIBMTP_Delete_Object (device, f->folder_id);

				/* if the folder we just deleted has siblings, the parent
				 * can't be empty.
				 */
				if (f->sibling != NULL) {
					rb_debug ("folder %s has siblings, can't delete parent", f->name);
					break;
				}
				folder_id = f->parent_id;
			}
		}

		LIBMTP_destroy_folder_t (folders);
	} else {
		rb_debug ("unable to get device folder list");
	}

	/* clean up the file list */
	while (files != NULL) {
		LIBMTP_file_t *n;

		n = files->next;
		LIBMTP_destroy_file_t (files);
		files = n;
	}

	g_idle_add ((GSourceFunc) delete_done_idle_cb, data);
}
예제 #5
0
int main (int argc, char **argv)
{
  LIBMTP_mtpdevice_t *device_list, *iter;
  LIBMTP_file_t *files;

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

  LIBMTP_Init();

  switch(LIBMTP_Get_Connected_Devices(&device_list))
  {
  case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
    fprintf(stdout, "mtp-files: No Devices have been found\n");
    return 0;
  case LIBMTP_ERROR_CONNECTING:
    fprintf(stderr, "mtp-files: There has been an error connecting. Exit\n");
    return 1;
  case LIBMTP_ERROR_MEMORY_ALLOCATION:
    fprintf(stderr, "mtp-files: Memory Allocation Error. Exit\n");
    return 1;
 
  /* Unknown general errors - This should never execute */
  case LIBMTP_ERROR_GENERAL:
  default:
    fprintf(stderr, "mtp-files: Unknown error, please report "
                    "this to the libmtp developers\n");
  return 1;

  /* Successfully connected at least one device, so continue */
  case LIBMTP_ERROR_NONE:
    fprintf(stdout, "mtp-files: Successfully connected\n");
    fflush(stdout);
  }
  
  /* iterate through connected MTP devices */
  for(iter = device_list; iter != NULL; iter = iter->next)
  {
  	
    char *friendlyname;
    
    /* Echo the friendly name so we know which device we are working with */
    friendlyname = LIBMTP_Get_Friendlyname(iter);
    if (friendlyname == NULL) {
      printf("Listing File Information on Device with name: (NULL)\n");
    } else {
      printf("Listing File Information on Device with name: %s\n", friendlyname);
      free(friendlyname);
    }
  
	  /* Get track listing. */
	  files = LIBMTP_Get_Filelisting_With_Callback(iter, NULL, NULL);
	  if (files == NULL) {
	    printf("No files.\n");
	    LIBMTP_Dump_Errorstack(iter);
	    LIBMTP_Clear_Errorstack(iter);
	  } else {
	    LIBMTP_file_t *file, *tmp;
	    file = files;
	    while (file != NULL) {
	      dump_fileinfo(file);
	      tmp = file;
	      file = file->next;
	      LIBMTP_destroy_file_t(tmp);
      }
	  }
  }
    
  LIBMTP_Release_Device_List(device_list);
  printf("OK.\n");
  exit (0);
}