void LibraryScanner::scan ( const QString & directory ) { QString path = directory; if ( path == NULL ) path = LibraryPath; qDebug() << "LibraryScanner::scan(path=\"" + path + "\")"; QDirIterator library ( path, QDirIterator::Subdirectories ); // FIXME: Handle symlinks recursively while ( library.hasNext() ) { QString file(library.next()); qDebug() << file; QFileInfo info(file); if ( info.isSymLink() ) { file = info.symLinkTarget(); qDebug() << "symlink"; } QFileInfo realinfo(file); if ( realinfo.isDir() ) { qDebug() << "Directory, ignoring"; } else { qDebug() << "Attempting to process"; readtags ( file ); } } }
static void readconfig () { const char* homedir = getenv("HOME"); const char* relconfig = ".config/dwm/config.json"; char* rulesFile = calloc(strlen(homedir) + strlen(relconfig) + 2, sizeof(char)); char* content; const nx_json *json, *js; strcpy(rulesFile, homedir); strcat(rulesFile, "/"); strcat(rulesFile, relconfig); content = load_file(rulesFile); if (content) { json = nx_json_parse_utf8(content); for (js = json->child; js; js = js->next) { if (!strcmp(js->key, "rules")) readjsonrules(js); else if (!strcmp(js->key, "tags")) readtags(js); else if (!strcmp(js->key, "font")) readfont(js); } nx_json_free(json); free(content); } if (!font) { font = calloc(strlen(fallbackfont) + 1, sizeof(char)); strcpy(font, fallbackfont); } }
bool istream::readtags(string& s, const string& tag) { char buf[8192]; s.clear(); while (!eof()) { size_t size = sizeof(buf); if (readtags(buf, &size, tag.c_str(), tag.length()) == true) { if (size > 0) s.append(buf, size); return true; } if (size > 0) s.append(buf, size); } return false; }
int64_t GetAudioMetadata(const char *path, char *name) { char type[4]; static char lang[6] = { '\0' }; struct stat file; int64_t ret; char *esc_tag; int i; int64_t album_art = 0; struct song_metadata song; metadata_t m; uint32_t free_flags = FLAG_MIME|FLAG_DURATION|FLAG_DLNA_PN|FLAG_DATE; memset(&m, '\0', sizeof(metadata_t)); if ( stat(path, &file) != 0 ) return 0; strip_ext(name); if( ends_with(path, ".mp3") ) { strcpy(type, "mp3"); m.mime = strdup("audio/mpeg"); } else if( ends_with(path, ".m4a") || ends_with(path, ".mp4") || ends_with(path, ".aac") || ends_with(path, ".m4p") ) { strcpy(type, "aac"); m.mime = strdup("audio/mp4"); } else if( ends_with(path, ".3gp") ) { strcpy(type, "aac"); m.mime = strdup("audio/3gpp"); } else if( ends_with(path, ".wma") || ends_with(path, ".asf") ) { strcpy(type, "asf"); m.mime = strdup("audio/x-ms-wma"); } else if( ends_with(path, ".flac") || ends_with(path, ".fla") || ends_with(path, ".flc") ) { strcpy(type, "flc"); m.mime = strdup("audio/x-flac"); } else if( ends_with(path, ".wav") ) { strcpy(type, "wav"); m.mime = strdup("audio/x-wav"); } else if( ends_with(path, ".ogg") || ends_with(path, ".oga") ) { strcpy(type, "ogg"); m.mime = strdup("audio/ogg"); } else if( ends_with(path, ".pcm") ) { strcpy(type, "pcm"); m.mime = strdup("audio/L16"); } else { DPRINTF(E_WARN, L_GENERAL, "Unhandled file extension on %s\n", path); return 0; } if( !(*lang) ) { if( !getenv("LANG") ) strcpy(lang, "en_US"); else strncpyt(lang, getenv("LANG"), sizeof(lang)); } if( readtags((char *)path, &song, &file, lang, type) != 0 ) { DPRINTF(E_WARN, L_GENERAL, "Cannot extract tags from %s!\n", path); freetags(&song); free_metadata(&m, free_flags); return 0; } if( song.dlna_pn ) m.dlna_pn = strdup(song.dlna_pn); if( song.year ) xasprintf(&m.date, "%04d-01-01", song.year); xasprintf(&m.duration, "%d:%02d:%02d.%03d", (song.song_length/3600000), (song.song_length/60000%60), (song.song_length/1000%60), (song.song_length%1000)); if( song.title && *song.title ) { m.title = trim(song.title); if( (esc_tag = escape_tag(m.title, 0)) ) { free_flags |= FLAG_TITLE; m.title = esc_tag; } } else { m.title = name; } for( i=ROLE_START; i<N_ROLE; i++ ) { if( song.contributor[i] && *song.contributor[i] ) { m.creator = trim(song.contributor[i]); if( strlen(m.creator) > 48 ) { m.creator = strdup("Various Artists"); free_flags |= FLAG_CREATOR; } else if( (esc_tag = escape_tag(m.creator, 0)) ) { m.creator = esc_tag; free_flags |= FLAG_CREATOR; } m.artist = m.creator; break; } } /* If there is a band associated with the album, use it for virtual containers. */ if( (i != ROLE_BAND) && (i != ROLE_ALBUMARTIST) ) { if( song.contributor[ROLE_BAND] && *song.contributor[ROLE_BAND] ) { i = ROLE_BAND; m.artist = trim(song.contributor[i]); if( strlen(m.artist) > 48 ) { m.artist = strdup("Various Artists"); free_flags |= FLAG_ARTIST; } else if( (esc_tag = escape_tag(m.artist, 0)) ) { m.artist = esc_tag; free_flags |= FLAG_ARTIST; } } } if( song.album && *song.album ) { m.album = trim(song.album); if( (esc_tag = escape_tag(m.album, 0)) ) { free_flags |= FLAG_ALBUM; m.album = esc_tag; } } if( song.genre && *song.genre ) { m.genre = trim(song.genre); if( (esc_tag = escape_tag(m.genre, 0)) ) { free_flags |= FLAG_GENRE; m.genre = esc_tag; } } if( song.comment && *song.comment ) { m.comment = trim(song.comment); if( (esc_tag = escape_tag(m.comment, 0)) ) { free_flags |= FLAG_COMMENT; m.comment = esc_tag; } } album_art = find_album_art(path, song.image, song.image_size); ret = sql_exec(db, "INSERT into DETAILS" " (PATH, SIZE, TIMESTAMP, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE," " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, DISC, TRACK, DLNA_PN, MIME, ALBUM_ART) " "VALUES" " (%Q, %lld, %ld, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, %d, %Q, '%s', %lld);", path, (long long)file.st_size, file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date, m.title, m.creator, m.artist, m.album, m.genre, m.comment, song.disc, song.track, m.dlna_pn, song.mime?song.mime:m.mime, album_art); if( ret != SQLITE_OK ) { fprintf(stderr, "Error inserting details for '%s'!\n", path); ret = 0; } else { ret = sqlite3_last_insert_rowid(db); } freetags(&song); free_metadata(&m, free_flags); return ret; }
bool istream::readtags(string* s, const string& tag) { acl_assert(s); return readtags(*s, tag); }
int64_t GetAudioMetadata(const char *path, char *name) { char type[4]; static char lang[6] = { '\0' }; struct stat file; int64_t ret; char *esc_tag; int i; int64_t album_art = 0; struct song_metadata song; metadata_t m; uint32_t free_flags = FLAG_MIME|FLAG_DURATION|FLAG_DLNA_PN|FLAG_DATE; memset(&m, '\0', sizeof(metadata_t)); if ( stat(path, &file) != 0 ) return 0; strip_ext(name); if( ends_with(path, ".mp3") ) { strcpy(type, "mp3"); m.mime = strdup("audio/mpeg"); } else if( ends_with(path, ".m4a") || ends_with(path, ".mp4") || ends_with(path, ".aac") || ends_with(path, ".m4p") ) { strcpy(type, "aac"); m.mime = strdup("audio/mp4"); } else if( ends_with(path, ".3gp") ) { strcpy(type, "aac"); m.mime = strdup("audio/3gpp"); } else if( ends_with(path, ".wma") || ends_with(path, ".asf") ) { strcpy(type, "asf"); m.mime = strdup("audio/x-ms-wma"); } else if( ends_with(path, ".flac") || ends_with(path, ".fla") || ends_with(path, ".flc") ) { strcpy(type, "flc"); m.mime = strdup("audio/x-flac"); } else if( ends_with(path, ".wav") ) { strcpy(type, "wav"); m.mime = strdup("audio/x-wav"); } else if( ends_with(path,".oga") || ends_with(path,".ogg")) { /* The .ogg/.oga file extensions present something of a problem. * ".ogg" has been deprecated in favor of ".oga" for some time, but * many applications still only recognize ".ogg". * * This examines the file and causes .ogg to be presented for any naked * Vorbis file (MIME type audio/ogg; codecs=vorbis) and .oga * (audio/ogg) to be used for everything else. This is in line with * the official ogg naming conventions and, hopefully, makes for a * resonable compromise. */ uint8_t oggtestbuf[35]; FILE *oggfile = fopen (path, "rb"); if (oggfile == (FILE *)NULL) { DPRINTF(E_ERROR, L_METADATA, "Error opening %s\n", path); return 0; } if (fread (oggtestbuf, 1, 35, oggfile) != 35) { DPRINTF(E_WARN, L_METADATA, "Premature EOF on %s\n", path); fclose (oggfile); return 0; } fclose (oggfile); if (memcmp (&oggtestbuf[28], "\x01vorbis", 7)) m.mime = strdup ("audio/ogg"); else m.mime = strdup ("audio/ogg; codecs=vorbis"); strcpy(type, "ogg"); } else if ( ends_with(path, ".opus") ) { strcpy(type,"ops"); m.mime = strdup("audio/ogg; codecs=opus"); } #if 0 /* Not supported yet, and probably won't be. */ else if( ends_with(path, ".ogx") ) { strcpy(type, "ogx"); m.mime = strdup("application/ogg"); } #endif else if( ends_with(path, ".pcm") ) { strcpy(type, "pcm"); m.mime = strdup("audio/L16"); } else { DPRINTF(E_WARN, L_METADATA, "Unhandled file extension on %s\n", path); return 0; } if( !(*lang) ) { if( !getenv("LANG") ) strcpy(lang, "en_US"); else strncpyt(lang, getenv("LANG"), sizeof(lang)); } if( readtags((char *)path, &song, &file, lang, type) != 0 ) { DPRINTF(E_WARN, L_METADATA, "Cannot extract tags from %s!\n", path); freetags(&song); free_metadata(&m, free_flags); return 0; } if( song.dlna_pn ) m.dlna_pn = strdup(song.dlna_pn); if( song.year ) xasprintf(&m.date, "%04d-01-01", song.year); xasprintf(&m.duration, "%d:%02d:%02d.%03d", (song.song_length/3600000), (song.song_length/60000%60), (song.song_length/1000%60), (song.song_length%1000)); if( song.title && *song.title ) { m.title = trim(song.title); if( (esc_tag = escape_tag(m.title, 0)) ) { free_flags |= FLAG_TITLE; m.title = esc_tag; } } else { m.title = name; } for( i = ROLE_START; i < N_ROLE; i++ ) { if( song.contributor[i] && *song.contributor[i] ) { m.creator = trim(song.contributor[i]); if( strlen(m.creator) > 48 ) { m.creator = strdup("Various Artists"); free_flags |= FLAG_CREATOR; } else if( (esc_tag = escape_tag(m.creator, 0)) ) { m.creator = esc_tag; free_flags |= FLAG_CREATOR; } m.artist = m.creator; break; } } /* If there is a album artist or band associated with the album, use it for virtual containers. */ if( i < ROLE_ALBUMARTIST ) { for( i = ROLE_ALBUMARTIST; i <= ROLE_BAND; i++ ) { if( song.contributor[i] && *song.contributor[i] ) break; } if( i <= ROLE_BAND ) { m.artist = trim(song.contributor[i]); if( strlen(m.artist) > 48 ) { m.artist = strdup("Various Artists"); free_flags |= FLAG_ARTIST; } else if( (esc_tag = escape_tag(m.artist, 0)) ) { m.artist = esc_tag; free_flags |= FLAG_ARTIST; } } } if( song.album && *song.album ) { m.album = trim(song.album); if( (esc_tag = escape_tag(m.album, 0)) ) { free_flags |= FLAG_ALBUM; m.album = esc_tag; } } if( song.genre && *song.genre ) { m.genre = trim(song.genre); if( (esc_tag = escape_tag(m.genre, 0)) ) { free_flags |= FLAG_GENRE; m.genre = esc_tag; } } if( song.comment && *song.comment ) { m.comment = trim(song.comment); if( (esc_tag = escape_tag(m.comment, 0)) ) { free_flags |= FLAG_COMMENT; m.comment = esc_tag; } } album_art = find_album_art(path, song.image, song.image_size); ret = sql_exec(db, "INSERT into DETAILS" " (PATH, SIZE, TIMESTAMP, DURATION, CHANNELS, BITRATE, SAMPLERATE, DATE," " TITLE, CREATOR, ARTIST, ALBUM, GENRE, COMMENT, DISC, TRACK, DLNA_PN, MIME, ALBUM_ART) " "VALUES" " (%Q, %lld, %lld, '%s', %d, %d, %d, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %d, %d, %Q, '%s', %lld);", path, (long long)file.st_size, (long long)file.st_mtime, m.duration, song.channels, song.bitrate, song.samplerate, m.date, m.title, m.creator, m.artist, m.album, m.genre, m.comment, song.disc, song.track, m.dlna_pn, song.mime?song.mime:m.mime, album_art); if( ret != SQLITE_OK ) { DPRINTF(E_ERROR, L_METADATA, "Error inserting details for '%s'!\n", path); ret = 0; } else { ret = sqlite3_last_insert_rowid(db); } freetags(&song); free_metadata(&m, free_flags); return ret; }