00001 #include "common.h"
00002 #include <string.h>
00003 #include <sys/stat.h>
00004 #ifdef HAVE_LIBGEN_H
00005 #include <libgen.h>
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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);
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
00172
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
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
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
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
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 }