From 6e9cf3a243cfd8accfa16003e6134912fd32189b Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Tue, 20 Aug 2013 21:58:35 +0200 Subject: [PATCH] This makes the scanner more flexible when matching paths in playlists with the library paths. --- src/db.c | 24 +++++++++++++ src/db.h | 3 ++ src/filescanner_m3u.c | 78 ++++++++++++++++++------------------------- 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/db.c b/src/db.c index 3b956cd1..2eacaef3 100644 --- a/src/db.c +++ b/src/db.c @@ -1723,6 +1723,30 @@ db_file_id_bypath(char *path) #undef Q_TMPL } +int +db_file_id_bypathpattern(char *path) +{ +#define Q_TMPL "SELECT f.id FROM files f WHERE f.path LIKE '%%%q';" + char *query; + int ret; + + query = sqlite3_mprintf(Q_TMPL, path); + if (!query) + { + DPRINTF(E_LOG, L_DB, "Out of memory for query string\n"); + + return 0; + } + + ret = db_file_id_byquery(query); + + sqlite3_free(query); + + return ret; + +#undef Q_TMPL +} + int db_file_id_byfilebase(char *filename, char *base) { diff --git a/src/db.h b/src/db.h index b3db97ec..4e96d0e2 100644 --- a/src/db.h +++ b/src/db.h @@ -334,6 +334,9 @@ db_file_path_byid(int id); int db_file_id_bypath(char *path); +int +db_file_id_bypathpattern(char *path); + int db_file_id_byfilebase(char *filename, char *base); diff --git a/src/filescanner_m3u.c b/src/filescanner_m3u.c index b5af40ef..bd90b297 100644 --- a/src/filescanner_m3u.c +++ b/src/filescanner_m3u.c @@ -47,14 +47,14 @@ scan_m3u_playlist(char *file, time_t mtime) struct playlist_info *pli; struct stat sb; char buf[PATH_MAX]; - char rel_entry[PATH_MAX]; - char *pl_base; char *entry; char *filename; char *ptr; size_t len; int pl_id; + int mfi_id; int ret; + int i; DPRINTF(E_INFO, L_SCAN, "Processing static playlist: %s\n", file); @@ -121,25 +121,6 @@ scan_m3u_playlist(char *file, time_t mtime) DPRINTF(E_INFO, L_SCAN, "Added playlist as id %d\n", pl_id); } - ptr = strrchr(file, '/'); - if (!ptr) - { - DPRINTF(E_WARN, L_SCAN, "Could not determine playlist base path\n"); - - return; - } - - *ptr = '\0'; - pl_base = strdup(file); - *ptr = '/'; - - if (!pl_base) - { - DPRINTF(E_WARN, L_SCAN, "Out of memory\n"); - - return; - } - while (fgets(buf, sizeof(buf), fp) != NULL) { len = strlen(buf); @@ -171,38 +152,47 @@ scan_m3u_playlist(char *file, time_t mtime) DPRINTF(E_DBG, L_SCAN, "Playlist contains URL entry\n"); filename = strdup(buf); - process_media_file(filename, mtime, 0, 0, 1); - - goto urlexit; - } - - /* Absolute vs. relative path */ - if (buf[0] == '/') - { - entry = buf; - } - else - { - ret = snprintf(rel_entry, sizeof(rel_entry),"%s/%s", pl_base, buf); - if ((ret < 0) || (ret >= sizeof(rel_entry))) + if (!filename) { - DPRINTF(E_WARN, L_SCAN, "Skipping entry, PATH_MAX exceeded\n"); + DPRINTF(E_LOG, L_SCAN, "Out of memory for playlist filename.\n"); continue; } - entry = rel_entry; + process_media_file(filename, mtime, 0, 0, 1); } - - filename = m_realpath(entry); - if (!filename) + /* Regular file */ + else { - DPRINTF(E_WARN, L_SCAN, "Could not determine real path for '%s': %s\n", entry, strerror(errno)); + /* m3u might be from Windows so we change backslash to forward slash */ + for (i = 0; i < strlen(buf); i++) + { + if (buf[i] == '\\') + buf[i] = '/'; + } - continue; + entry = buf; + while (entry && !(mfi_id = db_file_id_bypathpattern(entry))) + { + DPRINTF(E_DBG, L_SCAN, "Playlist entry is now %s\n", entry); + entry = strchr(entry + 1, '/'); + } + + if (entry && mfi_id > 0) + { + DPRINTF(E_DBG, L_SCAN, "Found playlist entry match, id is %d, entry is %s\n", mfi_id, entry); + filename = db_file_path_byid(mfi_id); + if (!filename) + { + DPRINTF(E_LOG, L_SCAN, "Playlist entry %s matches file id %d, but file path is missing.\n", entry, mfi_id); + + continue; + } + } + else + continue; } - urlexit: ret = db_pl_add_item_bypath(pl_id, filename); if (ret < 0) DPRINTF(E_WARN, L_SCAN, "Could not add %s to playlist\n", filename); @@ -210,8 +200,6 @@ scan_m3u_playlist(char *file, time_t mtime) free(filename); } - free(pl_base); - if (!feof(fp)) { DPRINTF(E_LOG, L_SCAN, "Error reading playlist '%s': %s\n", file, strerror(errno));