-/*
- * FAPG
- */
-#define VERSION "0.35"
/*
* FAPG means Fast Audio Playlist Generator.
* It is a tool to generate list of audio files (Wav, MP3, Ogg, etc)
#include <assert.h>
#include "genres.h"
+#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 */
// 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 = '/';
void usage()
{
fprintf(stderr,
- "Usage >> fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss] [-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);
}
#define mywebputchar(x) { fputs(iso2web[(unsigned char)winorunix[(unsigned char)x]], stdout); }
#define myputchar(x) { putchar(basemap[(unsigned char)winorunix[(unsigned char)x]]); }
+/* #define myplaputchar(x) { putchar(basemap[(unsigned char)winorunix[(unsigned char)x]]);putchar('\0');} */
+void myplaputchar(const char x)
+{
+ putchar(basemap[(unsigned char)winorunix[(unsigned char)x]]);
+ putchar('\0');
+}
void mywebputstr(const char *c)
{
}
}
+void myplaputstr(const char *c)
+{
+ while(*c != 0) {
+ if(*c == '/')
+ myplaputchar('\\'); /* translate slash to backslash */
+ else
+ myplaputchar(*c);
+ c++;
+ /* remove multiple slashes "//" when parsing a directory ending with a "/" */
+ while(*c == '/' && c[1] == '/')
+ 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] == '/')
}
}
+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;
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'},
{"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'}
};
format = 2;
else if(strcmp(optarg, "rss") == 0)
format = 3;
+ else if(strcmp(optarg, "pla") == 0)
+ format = 4;
+ else if(strcmp(optarg, "txx") == 0)
+ format = 5;
else
usage();
break;
}
}
break;
+ case 's':
+ fromstdin = 1;
+ break;
default:
usage();
}
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;
strcpy(artist, ++c);
// arbitrarily use the first '-'
// to separate artist and title
*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);
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;
printf("\t</item>%s", eol);
}
break;
+ case 4: // printing output for Sansa players
+ myplaputstr("HARP, ");
+ myplaputstr(newpath);
+ myplaputstr(eol);
+ break;
+ case 5: //t-series playlist
+ txxputstr(newpath);
+ break;
}
}
}
winorunix = one2one;
basemap = one2one;
parse_options(argc, argv);
- if(optind == argc)
+ if(optind == argc && !fromstdin)
usage();
switch (format) {
case 0:
basemap = noand;
}
break;
+ case 4:
+ {
+ eol = "\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);
case 3:
printf(" </channel>%s</rss>%s", eol, eol);
break;
+ case 5:
+ txxputcounter(counter);
+ break;
}
if(genrelist)
free(genrelist);