00001
00029 #define _LARGEFILE_SOURCE
00030 #define _LARGEFILE64_SOURCE
00031
00032 #include <string.h>
00033 #include <libgen.h>
00034 #include <sys/stat.h>
00035 #include <sys/types.h>
00036 #include <fcntl.h>
00037 #include "common.h"
00038 #include "libmtp.h"
00039 #include "pathutils.h"
00040
00041 extern LIBMTP_folder_t *folders;
00042 extern LIBMTP_file_t *files;
00043 extern LIBMTP_mtpdevice_t *device;
00044
00045 int sendtrack_function (char *, char *, char *, char *, char *, char *, uint16_t, uint16_t, uint16_t);
00046 void sendtrack_command (int, char **);
00047 void sendtrack_usage (void);
00048
00049 void sendtrack_usage (void)
00050 {
00051 fprintf(stderr, "usage: sendtr [ -D debuglvl ] [ -q ] -t <title> -a <artist> -l <album>\n");
00052 fprintf(stderr, " -c <codec> -g <genre> -n <track number> -y <year> \n");
00053 fprintf(stderr, " -d <duration in seconds> <local path> <remote path>\n");
00054 fprintf(stderr, "(-q means the program will not ask for missing information.)\n");
00055 }
00056
00057 static char *prompt (const char *prompt, char *buffer, size_t bufsz, int required)
00058 {
00059 char *cp, *bp;
00060
00061 while (1) {
00062 fprintf(stdout, "%s> ", prompt);
00063 if ( fgets(buffer, bufsz, stdin) == NULL ) {
00064 if (ferror(stdin)) {
00065 perror("fgets");
00066 } else {
00067 fprintf(stderr, "EOF on stdin\n");
00068 }
00069 return NULL;
00070 }
00071
00072 cp = strrchr(buffer, '\n');
00073 if ( cp != NULL ) *cp = '\0';
00074
00075 bp = buffer;
00076 while ( bp != cp ) {
00077 if ( *bp != ' ' && *bp != '\t' ) return bp;
00078 bp++;
00079 }
00080
00081 if (! required) return bp;
00082 }
00083 }
00084
00085 static int add_track_to_album(LIBMTP_album_t *albuminfo, LIBMTP_track_t *trackmeta)
00086 {
00087 LIBMTP_album_t *album;
00088 LIBMTP_album_t *found_album = NULL;
00089 int ret;
00090
00091
00092 album = LIBMTP_Get_Album_List(device);
00093 while(album != NULL) {
00094 if (album->name != NULL &&
00095 album->artist != NULL &&
00096 !strcmp(album->name, albuminfo->name) &&
00097 !strcmp(album->artist, albuminfo->artist)) {
00098
00099 found_album = album;
00100 album = album->next;
00101 found_album->next = NULL;
00102 } else {
00103 LIBMTP_album_t *tmp;
00104
00105 tmp = album;
00106 album = album->next;
00107 LIBMTP_destroy_album_t(tmp);
00108 }
00109 }
00110
00111 if (found_album != NULL) {
00112 uint32_t *tracks;
00113
00114 tracks = (uint32_t *)malloc((found_album->no_tracks+1) * sizeof(uint32_t));
00115 printf("Album \"%s\" found: updating...\n", found_album->name);
00116 if (!tracks) {
00117 printf("failed malloc in add_track_to_album()\n");
00118 return 1;
00119 }
00120 found_album->no_tracks++;
00121 if (found_album->tracks != NULL) {
00122 memcpy(tracks, found_album->tracks, found_album->no_tracks * sizeof(uint32_t));
00123 free(found_album->tracks);
00124 }
00125 tracks[found_album->no_tracks-1] = trackmeta->item_id;
00126 found_album->tracks = tracks;
00127 ret = LIBMTP_Update_Album(device, found_album);
00128 LIBMTP_destroy_album_t(found_album);
00129 } else {
00130 uint32_t *trackid;
00131
00132 trackid = (uint32_t *)malloc(sizeof(uint32_t));
00133 *trackid = trackmeta->item_id;
00134 albuminfo->tracks = trackid;
00135 albuminfo->no_tracks = 1;
00136 printf("Album doesn't exist: creating...\n");
00137 ret = LIBMTP_Create_New_Album(device, albuminfo, 0);
00138
00139 }
00140
00141 if (ret != 0) {
00142 printf("Error creating or updating album.\n");
00143 LIBMTP_Dump_Errorstack(device);
00144 LIBMTP_Clear_Errorstack(device);
00145 } else {
00146 printf("success!\n");
00147 }
00148 }
00149
00150 int sendtrack_function(char * from_path, char * to_path, char *partist, char *ptitle, char *pgenre, char *palbum, uint16_t tracknum, uint16_t length, uint16_t year)
00151 {
00152 char *filename, *parent;
00153 char artist[80], title[80], genre[80], album[80];
00154 char num[80];
00155 uint64_t filesize;
00156 uint32_t parent_id = 0;
00157 #ifdef __USE_LARGEFILE64
00158 struct stat64 sb;
00159 #else
00160 struct stat sb;
00161 #endif
00162 LIBMTP_track_t *trackmeta;
00163 LIBMTP_album_t *albuminfo;
00164 int ret;
00165
00166 printf("Sending track %s to %s\n",from_path,to_path);
00167
00168 trackmeta = LIBMTP_new_track_t();
00169 albuminfo = LIBMTP_new_album_t();
00170
00171 parent = dirname(to_path);
00172 filename = basename(to_path);
00173 parent_id = parse_path (parent,files,folders);
00174 if (parent_id == -1) {
00175 printf("Parent folder could not be found, skipping\n");
00176 return 1;
00177 }
00178
00179 #ifdef __USE_LARGEFILE64
00180 if ( stat64(from_path, &sb) == -1 ) {
00181 #else
00182 if ( stat(from_path, &sb) == -1 ) {
00183 #endif
00184 fprintf(stderr, "%s: ", from_path);
00185 perror("stat");
00186 return 1;
00187 } else if (S_ISREG (sb.st_mode)) {
00188 #ifdef __USE_LARGEFILE64
00189 filesize = sb.st_size;
00190 #else
00191 filesize = (uint64_t) sb.st_size;
00192 #endif
00193 trackmeta->filetype = find_filetype (from_path);
00194 if ((trackmeta->filetype != LIBMTP_FILETYPE_MP3)
00195 && (trackmeta->filetype != LIBMTP_FILETYPE_WAV)
00196 && (trackmeta->filetype != LIBMTP_FILETYPE_OGG)
00197 && (trackmeta->filetype != LIBMTP_FILETYPE_MP4)
00198 && (trackmeta->filetype != LIBMTP_FILETYPE_AAC)
00199 && (trackmeta->filetype != LIBMTP_FILETYPE_M4A)
00200 && (trackmeta->filetype != LIBMTP_FILETYPE_FLAC)
00201 && (trackmeta->filetype != LIBMTP_FILETYPE_WMA)) {
00202 printf("Not a valid codec: \"%s\"\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
00203 printf("Supported formats: MP3, WAV, OGG, MP4, AAC, M4A, FLAC, WMA\n");
00204 return 1;
00205 }
00206
00207 if (ptitle == NULL) {
00208 ptitle = prompt("Title", title, 80, 0);
00209 }
00210 if (!strlen(ptitle))
00211 ptitle = NULL;
00212
00213 if (palbum == NULL) {
00214 palbum = prompt("Album", album, 80, 0);
00215 }
00216 if (!strlen(palbum))
00217 palbum = NULL;
00218
00219 if (partist == NULL) {
00220 partist = prompt("Artist", artist, 80, 0);
00221 }
00222 if (!strlen(partist))
00223 partist = NULL;
00224
00225 if (pgenre == NULL) {
00226 pgenre = prompt("Genre", genre, 80, 0);
00227 }
00228 if (!strlen(pgenre))
00229 pgenre = NULL;
00230
00231 if (tracknum == 0) {
00232 char *pnum;
00233 if ( (pnum = prompt("Track number", num, 80, 0)) == NULL )
00234 tracknum = 0;
00235 if ( strlen(pnum) ) {
00236 tracknum = strtoul(pnum, 0, 10);
00237 } else {
00238 tracknum = 0;
00239 }
00240 }
00241
00242 if (year == 0) {
00243 char *pnum;
00244 if ( (pnum = prompt("Year", num, 80, 0)) == NULL )
00245 year = 0;
00246 if ( strlen(pnum) ) {
00247 year = strtoul(pnum, 0, 10);
00248 } else {
00249 year = 0;
00250 }
00251 }
00252
00253 if (length == 0) {
00254 char *pnum;
00255 if ( (pnum = prompt("Length", num, 80, 0)) == NULL )
00256 length = 0;
00257 if ( strlen(pnum) ) {
00258 length = strtoul(pnum, 0, 10);
00259 } else {
00260 length = 0;
00261 }
00262 }
00263
00264 printf("Sending track:\n");
00265 printf("Codec: %s\n", LIBMTP_Get_Filetype_Description(trackmeta->filetype));
00266 if (ptitle) {
00267 printf("Title: %s\n", ptitle);
00268 trackmeta->title = strdup(ptitle);
00269 }
00270 if (palbum) {
00271 printf("Album: %s\n", palbum);
00272 trackmeta->album = strdup(palbum);
00273 albuminfo->name = strdup(palbum);
00274 }
00275 if (partist) {
00276 printf("Artist: %s\n", partist);
00277 trackmeta->artist = strdup(partist);
00278 albuminfo->artist = strdup(partist);
00279 }
00280 if (pgenre) {
00281 printf("Genre: %s\n", pgenre);
00282 trackmeta->genre = strdup(pgenre);
00283 albuminfo->genre = strdup(pgenre);
00284 }
00285 if (year > 0) {
00286 char tmp[80];
00287 printf("Year: %d\n", year);
00288 snprintf(tmp, sizeof(tmp)-1, "%4d0101T0000.0", year);
00289 tmp[sizeof(tmp)-1] = '\0';
00290 trackmeta->date = strdup(tmp);
00291 }
00292 if (tracknum > 0) {
00293 printf("Track no: %d\n", tracknum);
00294 trackmeta->tracknumber = tracknum;
00295 }
00296 if (length > 0) {
00297 printf("Length: %d\n", length);
00298
00299 trackmeta->duration = length * 1000;
00300 }
00301
00302 if (filename != NULL) {
00303 trackmeta->filename = strdup(filename);
00304 }
00305 trackmeta->filesize = filesize;
00306
00307 printf("Sending track...\n");
00308 ret = LIBMTP_Send_Track_From_File(device, from_path, trackmeta, progress, NULL, parent_id);
00309 printf("\n");
00310 if (ret != 0) {
00311 printf("Error sending track.\n");
00312 LIBMTP_Dump_Errorstack(device);
00313 LIBMTP_Clear_Errorstack(device);
00314 } else {
00315 printf("New track ID: %d\n", trackmeta->item_id);
00316 }
00317
00318 LIBMTP_destroy_album_t(albuminfo);
00319 LIBMTP_destroy_track_t(trackmeta);
00320
00321 return 0;
00322 }
00323 return 0;
00324 }
00325
00326 void sendtrack_command (int argc, char **argv) {
00327 int opt;
00328 extern int optind;
00329 extern char *optarg;
00330 char *partist = NULL;
00331 char *ptitle = NULL;
00332 char *pgenre = NULL;
00333 char *pcodec = NULL;
00334 char *palbum = NULL;
00335 uint16_t tracknum = 0;
00336 uint16_t length = 0;
00337 uint16_t year = 0;
00338 uint16_t quiet = 0;
00339 char *lang;
00340 while ( (opt = getopt(argc, argv, "qD:t:a:l:c:g:n:d:y:")) != -1 ) {
00341 switch (opt) {
00342 case 't':
00343 ptitle = strdup(optarg);
00344 break;
00345 case 'a':
00346 partist = strdup(optarg);
00347 break;
00348 case 'l':
00349 palbum = strdup(optarg);
00350 break;
00351 case 'c':
00352 pcodec = strdup(optarg);
00353 break;
00354 case 'g':
00355 pgenre = strdup(optarg);
00356 break;
00357 case 'n':
00358 tracknum = atoi(optarg);
00359 break;
00360 case 'd':
00361 length = atoi(optarg);
00362 break;
00363 case 'y':
00364 year = atoi(optarg);
00365 break;
00366 case 'q':
00367 quiet = 1;
00368 break;
00369 default:
00370 sendtrack_usage();
00371 }
00372 }
00373 argc -= optind;
00374 argv += optind;
00375
00376 if ( argc != 2 ) {
00377 printf("You need to pass a filename and destination.\n");
00378 sendtrack_usage();
00379 }
00380
00381
00382
00383
00384 lang = getenv("LANG");
00385 if (lang != NULL) {
00386 if (strlen(lang) > 5) {
00387 char *langsuff = &lang[strlen(lang)-5];
00388 if (strcmp(langsuff, "UTF-8")) {
00389 printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);
00390 printf("If you want to have support for diacritics and Unicode characters,\n");
00391 printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");
00392 }
00393 }
00394 }
00395
00396 printf("%s,%s,%s,%s,%s,%s,%d%d,%d\n",argv[0],argv[1],partist,ptitle,pgenre,palbum,tracknum, length, year);
00397 sendtrack_function(argv[0],argv[1],partist,ptitle,pgenre,palbum, tracknum, length, year);
00398 }