libmtp: sendtr.c

- Main Page
- Modules
- Data Structures
- Files
- Directories
- Examples

# sendtr.c

    00001 #include "common.h"
    00002 #include <string.h>
    00003 #include <sys/stat.h>
    00004 #ifdef HAVE_LIBGEN_H
    00005 #include <libgen.h> /* basename() */
    00006 #endif
    00007
    00008 /*
    00009  * This program is derived from the exact equivalent in libnjb.
    00010  *
    00011  * This is an improved commandline track transfer program
    00012  * based on Enrique Jorreto Ledesma's work on the original program by
    00013  * Shaun Jackman and Linus Walleij.
    00014  */
    00015
    00016 /* Function that compensate for missing libgen.h on Windows */
    00017 #ifndef HAVE_LIBGEN_H
    00018 static char *basename(char *in) {
    00019   char *p;
    00020   if (in == NULL)
    00021     return NULL;
    00022   p = in + strlen(in) - 1;
    00023   while (*p != '\\' && *p != '/' && *p != ':')
    00024     { p--; }
    00025   return ++p;
    00026 }
    00027 #endif
    00028
    00029 static int progress (uint64_t const sent, uint64_t const total, void const * const data)
    00030 {
    00031   int percent = (sent*100)/total;
    00032 #ifdef __WIN32__
    00033   printf("Progress: %I64u of %I64u (%d%%)\r", sent, total, percent);
    00034 #else
    00035   printf("Progress: %llu of %llu (%d%%)\r", sent, total, percent);
    00036 #endif
    00037   fflush(stdout);
    00038   return 0;
    00039 }
    00040
    00041 static char *prompt (const char *prompt, char *buffer, size_t bufsz, int required)
    00042 {
    00043   char *cp, *bp;
    00044
    00045   while (1) {
    00046     fprintf(stdout, "%s> ", prompt);
    00047     if ( fgets(buffer, bufsz, stdin) == NULL ) {
    00048       if (ferror(stdin)) {
    00049         perror("fgets");
    00050       } else {
    00051         fprintf(stderr, "EOF on stdin\n");
    00052       }
    00053       return NULL;
    00054     }
    00055
    00056     cp = strrchr(buffer, '\n');
    00057     if ( cp != NULL ) *cp = '\0';
    00058
    00059     bp = buffer;
    00060     while ( bp != cp ) {
    00061       if ( *bp != ' ' && *bp != '\t' ) return bp;
    00062       bp++;
    00063     }
    00064
    00065     if (! required) return bp;
    00066   }
    00067 }
    00068
    00069 static void usage(void)
    00070 {
    00071   fprintf(stderr, "usage: sendtr [ -D debuglvl ] [ -q ] -t <title> -a <artist> -l <album>\n");
    00072   fprintf(stderr, "       -c <codec> -g <genre> -n <track number> -y <year> \n");
    00073   fprintf(stderr, "       -d <duration in seconds> -f \"Folder Name\" <path>\n");
    00074   fprintf(stderr, "(-q means the program will not ask for missing information.)\n");
    00075   exit(1);
    00076 }
    00077
    00078 static uint32_t find_folder_list(char *name, LIBMTP_folder_t *folderlist, int level)
    00079 {
    00080   uint32_t i;
    00081
    00082   if(folderlist==NULL) {
    00083     return 0;
    00084   }
    00085
    00086   if(!strcasecmp(name, folderlist->name))
    00087     return folderlist->folder_id;
    00088
    00089   if ((i = (find_folder_list(name, folderlist->child, level+1))))
    00090     return i;
    00091   if ((i = (find_folder_list(name, folderlist->sibling, level))))
    00092     return i;
    00093
    00094   return 0;
    00095 }
    00096
    00097 int main(int argc, char **argv)
    00098 {
    00099   int opt;
    00100   extern int optind;
    00101   extern char *optarg;
    00102   char *path, *filename;
    00103   char artist[80], title[80], genre[80], codec[80], album[80];
    00104   char num[80];
    00105   char *partist = NULL;
    00106   char *ptitle = NULL;
    00107   char *pgenre = NULL;
    00108   char *pcodec = NULL;
    00109   char *palbum = NULL;
    00110   char *pfolder = NULL;
    00111   uint16_t tracknum = 0;
    00112   uint16_t length = 0;
    00113   uint16_t year = 0;
    00114   uint16_t quiet = 0;
    00115   uint64_t filesize;
    00116   uint32_t parent_id = 0;
    00117   struct stat sb;
    00118   char *lang;
    00119   LIBMTP_mtpdevice_t *device;
    00120   LIBMTP_folder_t *folders = NULL;
    00121   LIBMTP_track_t *trackmeta;
    00122   int ret;
    00123
    00124   LIBMTP_Init();
    00125
    00126   while ( (opt = getopt(argc, argv, "qD:t:a:l:c:g:n:d:y:f:")) != -1 ) {
    00127     switch (opt) {
    00128     case 't':
    00129       ptitle = strdup(optarg);
    00130       break;
    00131     case 'a':
    00132       partist = strdup(optarg);
    00133       break;
    00134     case 'l':
    00135       palbum = strdup(optarg);
    00136       break;
    00137     case 'c':
    00138       pcodec = strdup(optarg); // FIXME: DSM check for MP3, WAV or WMA
    00139       break;
    00140     case 'g':
    00141       pgenre = strdup(optarg);
    00142       break;
    00143     case 'n':
    00144       tracknum = atoi(optarg);
    00145       break;
    00146     case 'd':
    00147       length = atoi(optarg);
    00148       break;
    00149     case 'y':
    00150       year = atoi(optarg);
    00151       break;
    00152     case 'f':
    00153       pfolder = strdup(optarg);
    00154       break;
    00155     case 'q':
    00156       quiet = 1;
    00157       break;
    00158     default:
    00159       usage();
    00160     }
    00161   }
    00162   argc -= optind;
    00163   argv += optind;
    00164
    00165   if ( argc != 1 ) {
    00166     printf("You need to pass a filename.\n");
    00167     usage();
    00168   }
    00169
    00170   /*
    00171    * Check environment variables $LANG and $LC_CTYPE
    00172    * to see if we want to support UTF-8 unicode
    00173    */
    00174   lang = getenv("LANG");
    00175   if (lang != NULL) {
    00176     if (strlen(lang) > 5) {
    00177       char *langsuff = &lang[strlen(lang)-5];
    00178       if (strcmp(langsuff, "UTF-8")) {
    00179         printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);
    00180         printf("If you want to have support for diacritics and Unicode characters,\n");
    00181         printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");
    00182       }
    00183     }
    00184   }
    00185
    00186   path = argv[0];
    00187
    00188   filename = basename(path);
    00189   if (filename == NULL) {
    00190     printf("Error: filename could not be based.\n");
    00191     exit(1);
    00192   }
    00193   if ( stat(path, &sb) == -1 ) {
    00194     fprintf(stderr, "%s: ", path);
    00195     perror("stat");
    00196     exit(1);
    00197   }
    00198   filesize = (uint64_t) sb.st_size;
    00199
    00200   /* Ask for missing parameters if not quiet */
    00201   if (!quiet) {
    00202     if (pcodec == NULL) {
    00203       if ( (pcodec = prompt("Codec", codec, 80, 1)) == NULL ) {
    00204         printf("A codec name is required.\n");
    00205         usage();
    00206       }
    00207     }
    00208     if (!strlen(pcodec)) {
    00209       printf("A codec name is required.\n");
    00210       usage();
    00211     }
    00212
    00213     if (ptitle == NULL) {
    00214       if ( (ptitle = prompt("Title", title, 80, 0)) == NULL )
    00215         usage();
    00216     }
    00217     if (!strlen(ptitle))
    00218       ptitle = NULL;
    00219
    00220
    00221     if (palbum == NULL) {
    00222       if ( (palbum = prompt("Album", album, 80, 0)) == NULL )
    00223         usage();
    00224     }
    00225     if (!strlen(palbum))
    00226       palbum = NULL;
    00227
    00228     if (partist == NULL) {
    00229     if ( (partist = prompt("Artist", artist, 80, 0)) == NULL )
    00230       usage();
    00231     }
    00232     if (!strlen(partist))
    00233       partist = NULL;
    00234
    00235     if (pgenre == NULL) {
    00236       if ( (pgenre = prompt("Genre", genre, 80, 0)) == NULL )
    00237         usage();
    00238     }
    00239     if (!strlen(pgenre))
    00240       pgenre = NULL;
    00241
    00242     if (tracknum == 0) {
    00243       char *pnum;
    00244       if ( (pnum = prompt("Track number", num, 80, 0)) == NULL )
    00245       tracknum = 0;
    00246       if ( strlen(pnum) ) {
    00247         tracknum = strtoul(pnum, 0, 10);
    00248       } else {
    00249         tracknum = 0;
    00250       }
    00251     }
    00252
    00253     if (year == 0) {
    00254       char *pnum;
    00255       if ( (pnum = prompt("Year", num, 80, 0)) == NULL )
    00256         year = 0;
    00257       if ( strlen(pnum) ) {
    00258         year = strtoul(pnum, 0, 10);
    00259       } else {
    00260         year = 0;
    00261       }
    00262     }
    00263
    00264     if (length == 0) {
    00265       char *pnum;
    00266       if ( (pnum = prompt("Length", num, 80, 0)) == NULL )
    00267         length = 0;
    00268       if ( strlen(pnum) ) {
    00269         length = strtoul(pnum, 0, 10);
    00270       } else {
    00271         length = 0;
    00272       }
    00273     }
    00274
    00275   }
    00276
    00277   trackmeta = LIBMTP_new_track_t();
    00278
    00279   printf("Sending track:\n");
    00280   printf("Codec:     %s\n", pcodec);
    00281
    00282   if (!strcasecmp(pcodec,"mp3")) {
    00283     trackmeta->filetype = LIBMTP_FILETYPE_MP3;
    00284   }  else if (!strcasecmp(pcodec,"wav")) {
    00285     trackmeta->filetype = LIBMTP_FILETYPE_WAV;
    00286   } else if (!strcasecmp(pcodec,"ogg")) {
    00287     trackmeta->filetype = LIBMTP_FILETYPE_OGG;
    00288   } else if (!strcasecmp(pcodec,"mp4")) {
    00289     trackmeta->filetype = LIBMTP_FILETYPE_MP4;
    00290   } else if (!strcasecmp(pcodec,"wma") || !strcasecmp(pcodec,"asf")) {
    00291     trackmeta->filetype = LIBMTP_FILETYPE_WMA;
    00292   } else {
    00293     printf("Not a valid codec: \"%s\"\n", pcodec);
    00294     printf("Supported formats: MP3, WAV, OGG, MP4, WMA\n");
    00295     exit(1);
    00296   }
    00297   printf("Codec:     %s\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
    00298   if (ptitle) {
    00299     printf("Title:     %s\n", ptitle);
    00300     trackmeta->title = strdup(ptitle);
    00301   }
    00302   if (palbum) {
    00303     printf("Album:     %s\n", palbum);
    00304     trackmeta->album = strdup(palbum);
    00305   }
    00306   if (partist) {
    00307     printf("Artist:    %s\n", partist);
    00308     trackmeta->artist = strdup(partist);
    00309   }
    00310   if (pgenre) {
    00311     printf("Genre:     %s\n", pgenre);
    00312     trackmeta->genre = strdup(pgenre);
    00313   }
    00314   if (year > 0) {
    00315     char tmp[80];
    00316     printf("Year:      %d\n", year);
    00317     snprintf(tmp, sizeof(tmp)-1, "%4d0101T0000.0", year);
    00318     tmp[sizeof(tmp)-1] = '\0';
    00319     trackmeta->date = strdup(tmp);
    00320   }
    00321   if (tracknum > 0) {
    00322     printf("Track no:  %d\n", tracknum);
    00323     trackmeta->tracknumber = tracknum;
    00324   }
    00325   if (length > 0) {
    00326     printf("Length:    %d\n", length);
    00327     // Multiply by 1000 since this is in milliseconds
    00328     trackmeta->duration = length * 1000;
    00329   }
    00330   if (pfolder != NULL && parent_id != 0) {
    00331     printf("Folder:    %s (ID: %d)\n", pfolder, parent_id);
    00332   }
    00333   // We should always have this
    00334   if (filename != NULL) {
    00335     trackmeta->filename = strdup(filename);
    00336   }
    00337   trackmeta->filesize = filesize;
    00338
    00339   device = LIBMTP_Get_First_Device();
    00340   if (device == NULL) {
    00341     printf("No MTP device found.\n");
    00342     LIBMTP_destroy_track_t(trackmeta);
    00343     exit(1);
    00344   }
    00345
    00346   // If a folder argument was passed in, try to locate the folder.
    00347   if (pfolder) {
    00348     folders = LIBMTP_Get_Folder_List(device);
    00349     if(folders == NULL) {
    00350       printf("No folders found, ignoring folder argument.\n");
    00351     } else {
    00352       parent_id = find_folder_list(pfolder, folders, 0);
    00353       if  (!parent_id) {
    00354         printf("Parent folder could not be found, ignoring folder argument.\n");
    00355       }
    00356     }
    00357   }
    00358
    00359   printf("Sending track...\n");
    00360   ret = LIBMTP_Send_Track_From_File(device, path, trackmeta, progress, NULL, parent_id);
    00361   printf("\n");
    00362
    00363   LIBMTP_Release_Device(device);
    00364
    00365   printf("New track ID: %d\n", trackmeta->item_id);
    00366
    00367   LIBMTP_destroy_track_t(trackmeta);
    00368
    00369   printf("OK.\n");
    00370
    00371   return 0;
    00372 }