version 0.38 (by Jonny Bijlsma)
[FAPG] / fapg.c
diff --git a/fapg.c b/fapg.c
index 0ec3835..a72d4e7 100644 (file)
--- a/fapg.c
+++ b/fapg.c
@@ -38,7 +38,7 @@
 #include <assert.h>
 #include "genres.h"
 
-#define VERSION "0.36"
+#define VERSION "0.38"
 #define MP3_BASE 1024
 #define OGG_BASE 1024*10
 #define MAX 1024*200            /* 200ko for ID3 with JPEG images in it */
@@ -53,6 +53,7 @@ unsigned char *hostname = "fritzserver.de";
 // unsigned char *referal="/usr/local/bin/fapg-rss.sh";
 unsigned char *referal = NULL;
 //int windows=0;
+int fromstdin = 0;
 int recursive = 0;
 int avoidhlinked = 0;
 int separator = '/';
@@ -217,7 +218,7 @@ unsigned char *iso2web[256] = {
 void usage()
 {
     fprintf(stderr,
-            "Usage >> fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss|pla] [-g|--genre=#:#:...] [-n|--nohardlink] [-o|--output=/path/to/file.m3u] [-p|--prefix=/the/prefix] [-r|--recursive] [-w|--windows] [-c|--command=<intern|....>] [-x|--exclude=#:#:...] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...]\n");
+            "Usage >> fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss|pla|txx] [-g|--genre=#:#:...] [-n|--nohardlink] [-o|--output=/path/to/file.m3u] [-p|--prefix=/the/prefix] [-r|--recursive] [-w|--windows] [-c|--command=<intern|...>] [-x|--exclude=#:#:...] [-s|--stdin] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...]\n");
     exit(1);
 }
 
@@ -241,7 +242,7 @@ void mywebputstr(const char *c)
 void myplaputstr(const char *c)
 {
     while(*c != 0) {
-        if( *c == '/')
+        if(*c == '/')
             myplaputchar('\\'); /* translate slash to backslash */
         else
             myplaputchar(*c);
@@ -255,7 +256,10 @@ void myplaputstr(const char *c)
 void myputstr(const char *c)
 {
     while(*c != 0) {
-        myputchar(*c);
+        if(*c == '/')
+            putchar(separator);
+        else
+            myputchar(*c);
         c++;
         /* remove multiple slashes "//" when parsing a directory ending with a "/" */
         while(*c == '/' && c[1] == '/')
@@ -263,6 +267,140 @@ void myputstr(const char *c)
     }
 }
 
+void txxputheader(const char *c)
+{
+    int cnt = 0;
+
+    while(*c != 0) {
+        myputchar(*c);
+        cnt++;
+        c++;
+    }
+
+    while(cnt < 512) {
+        putchar('\0');
+        cnt++;
+    }
+}
+
+void txxputnameoffset(const char *c)
+{
+    int pos = 0;
+    int cnt = 0;
+    char b;
+    unsigned char *prefx;
+
+    prefx = prefix;
+
+    if(*prefx != 0) {
+        while(*prefx != 0) {
+            if(*prefx == '/') {
+                pos = cnt;
+            }
+            cnt++;
+            prefx++;
+        }
+
+        cnt--;                  // skip the leading dot of the filepath
+    }
+
+    while(*c != 0) {
+        if(*c == '/') {
+            pos = cnt;
+        }
+        cnt++;
+        c++;
+    }
+
+    pos += 2;
+
+    b = (pos & 0xFF00) >> 8;
+    putchar(b);
+    b = (pos & 0x00FF);
+    putchar(b);
+}
+
+void txxputstr(const char *c)
+{
+    int cnt = 0;
+    int pos;
+    unsigned char *prefx;
+
+    txxputnameoffset(c);
+
+    prefx = prefix;
+    fprintf(stderr, "prefix: '%s'\n", prefx);
+
+    if(*prefx != 0) {
+        while(*prefx != 0) {
+            myputchar('\0');
+            cnt++;
+
+            if(*prefx == '/')
+                putchar(separator);
+            else
+                myputchar(*prefx);
+            cnt++;
+
+            prefx++;
+        }
+
+        c++;                    // skip the leading dot
+    }
+
+    while(*c != 0) {
+        myputchar('\0');
+        cnt++;
+
+        if(*c == '/')
+            putchar(separator);
+        else
+            myputchar(*c);
+        cnt++;
+
+        c++;
+    }
+
+    while(cnt < 510) {
+        myputchar('\0');
+        cnt++;
+    }
+}
+
+void txxputcounter(int c)
+{
+    int b;
+
+    rewind(stdout);
+
+    b = (c & 0xFF000000) >> 24;
+    putchar(b);
+    b = (c & 0x00FF0000) >> 16;
+    putchar(b);
+    b = (c & 0x0000FF00) >> 8;
+    putchar(b);
+    b = (c & 0x000000FF);
+    putchar(b);
+}
+
+/* remove spaces at beginning and end of string */
+void trim(char *c)
+{
+    char *p;
+    /* remove spaces at beginning ... */
+    while(*c == ' ') {
+        p = c;
+        while(*p != '\0') {
+            *p = *(p + 1);
+            p++;
+        }
+    }
+    /* ... and end of string */
+    p = c + strlen(c);
+    while(--p > c && *p == ' ')
+        *p = '\0';
+}
+
 void print_webpath(const char *path)
 {
     const char *c = path;
@@ -356,10 +494,10 @@ void reference(const char *title)
 
 void parse_options(int argc, char **argv)
 {
-    static char const short_options[] = "c:bdf:g:lo:np:ruwx:";
+    static char const short_options[] = "bc:df:g:lo:np:rsuwx:";
     static struct option long_options[] = {
         {"backslash", no_argument, NULL, 'b'},
-        {"command", required_argument, NULL, 'b'},
+        {"command", required_argument, NULL, 'c'},
         {"debug", no_argument, NULL, 'd'},
         {"format", required_argument, NULL, 'f'},
         {"genre", required_argument, NULL, 'g'},
@@ -367,6 +505,7 @@ void parse_options(int argc, char **argv)
         {"output", required_argument, NULL, 'o'},
         {"prefix", required_argument, NULL, 'p'},
         {"recursive", no_argument, NULL, 'r'},
+        {"stdin", no_argument, NULL, 's'},
         {"windows", no_argument, NULL, 'w'},
         {"exclude", required_argument, NULL, 'x'}
     };
@@ -400,6 +539,8 @@ void parse_options(int argc, char **argv)
                 format = 3;
             else if(strcmp(optarg, "pla") == 0)
                 format = 4;
+            else if(strcmp(optarg, "txx") == 0)
+                format = 5;
             else
                 usage();
             break;
@@ -482,6 +623,9 @@ void parse_options(int argc, char **argv)
                 }
             }
             break;
+        case 's':
+            fromstdin = 1;
+            break;
         default:
             usage();
         }
@@ -934,12 +1078,13 @@ void parse_file(unsigned char *newpath)
         duration = -1;          /* parse_wav(newpath); */
         encoding = WAVENC;
     }
-    /* faketitle() */
+    /* guesstitle() */
     if((strlen(artist) == 0) && (strlen(title) == 0)) {
         // there are no tag infos read
         // use file name to state substitute it
         char *c = strrchr(newpath, separator);
-       if (c == NULL) c = newpath;
+        if(c == NULL)
+            c = newpath;
         strcpy(artist, ++c);
         // arbitrarily use the first '-'
         // to separate artist and title
@@ -960,16 +1105,21 @@ void parse_file(unsigned char *newpath)
             *c = ' ';
         for(c = title; (c = strchr(c, '_')) != NULL; c++)
             *c = ' ';
+        // trim spaces
+        trim(artist);
+        trim(title);
     }
-    /* faketitle() end */
+    /* guesstitle() end */
 
     if(duration != -2 && genrelist[genre]) {    /* is it an audio file ? */
         counter++;
         switch (format) {
         case 0:
             if(duration != -1) {
-                printf("#EXTINF:%d,%s - %s%s", duration, artist, title,
-                       eol);
+                printf("#EXTINF:%d,", duration);
+                if(strlen(artist) != 0)
+                    printf("%s - ", artist);
+                printf("%s%s", title, eol);
             }
             print_path(newpath);
             printf("%s", eol);
@@ -977,8 +1127,10 @@ void parse_file(unsigned char *newpath)
         case 1:
             printf("File%d=", counter);
             print_path(newpath);
-            printf("%sTitle%d=%s - %s%s", eol, counter, artist, title,
-                   eol);
+            printf("%sTitle%d=", eol, counter);
+            if(strlen(artist) != 0)
+                printf("%s - ", artist);
+            printf("%s%s", title, eol);
             if(duration != -1)
                 printf("Length%d=%d%s", counter, duration, eol);
             break;
@@ -1037,11 +1189,14 @@ void parse_file(unsigned char *newpath)
                 printf("\t</item>%s", eol);
             }
             break;
-        case 4: // printing output for Sansa players
+        case 4:                // printing output for Sansa players
             myplaputstr("HARP, ");
             myplaputstr(newpath);
             myplaputstr(eol);
             break;
+        case 5:                //t-series playlist
+            txxputstr(newpath);
+            break;
         }
     }
 }
@@ -1095,7 +1250,7 @@ int main(int argc, char **argv)
     winorunix = one2one;
     basemap = one2one;
     parse_options(argc, argv);
-    if(optind == argc)
+    if(optind == argc && !fromstdin)
         usage();
     switch (format) {
     case 0:
@@ -1138,15 +1293,30 @@ int main(int argc, char **argv)
             basemap = noand;
         }
         break;
-    case 4: 
+    case 4:
         {
             eol = "\r\n";
-            myplaputstr( "PLP PLAYLIST\r\nVERSION 1.20\r\n\r\n" );
+            myplaputstr("PLP PLAYLIST\r\nVERSION 1.20\r\n\r\n");
+        }
+        break;
+    case 5:
+        {
+            txxputheader("    iriver UMS PLA");
         }
     }
-    for(; optind < argc; optind++) {
-        parse_directory(argv[optind]);
-    }
+    if(fromstdin) {
+        unsigned char path[PATH_MAX];
+        int i;
+        while(fgets(path, PATH_MAX, stdin)) {
+            for(i = 0; i < PATH_MAX; i++)
+                if(path[i] == '\r' || path[i] == '\n')
+                    path[i] = '\0';
+            parse_directory(path);
+        }
+    } else
+        for(; optind < argc; optind++) {
+            parse_directory(argv[optind]);
+        }
     switch (format) {
     case 1:
         printf("NumberOfEntries=%d%sVersion=2%s", counter, eol, eol);
@@ -1160,6 +1330,9 @@ int main(int argc, char **argv)
     case 3:
         printf("    </channel>%s</rss>%s", eol, eol);
         break;
+    case 5:
+        txxputcounter(counter);
+        break;
     }
     if(genrelist)
         free(genrelist);