[filescanner] Fix and refactor scanning of playlists

This commit is contained in:
chme 2017-03-11 08:14:23 +01:00 committed by ejurgensen
parent f5c65d1eef
commit f4aade7f3a
3 changed files with 140 additions and 105 deletions

View File

@ -162,6 +162,20 @@ static int
filescanner_fullrescan();
const char *
filename_from_path(const char *path)
{
const char *filename;
filename = strrchr(path, '/');
if ((!filename) || (strlen(filename) == 1))
filename = path;
else
filename++;
return filename;
}
static int
push_dir(struct stacked_dir **s, char *path, int parent_id)
{
@ -417,7 +431,7 @@ process_regular_file(char *file, struct stat *sb, int type, int flags, int dir_i
memset(&mfi, 0, sizeof(struct media_file_info));
mfi.id = id;
mfi.fname = strdup(basename(file));
mfi.fname = strdup(filename_from_path(file));
mfi.path = strdup(file);
mfi.time_modified = sb->st_mtime;
@ -1538,7 +1552,7 @@ scan_metadata(const char *path, struct media_file_info *mfi)
{
memset(mfi, 0, sizeof(struct media_file_info));
mfi->path = strdup(path);
mfi->fname = strdup(basename(mfi->path));
mfi->fname = strdup(filename_from_path(mfi->path));
mfi->data_kind = DATA_KIND_HTTP;
mfi->directory_id = DIR_HTTP;

View File

@ -20,4 +20,7 @@ void
scan_itunes_itml(char *file);
#endif
const char *
filename_from_path(const char *path);
#endif /* !__FILESCANNER_H__ */

View File

@ -75,6 +75,112 @@ extinf_get(char *string, struct media_file_info *mfi, int *extinf)
return 1;
}
static int
process_url(const char *path, time_t mtime, int extinf, struct media_file_info *mfi, char **filename)
{
char virtual_path[PATH_MAX];
time_t stamp;
int id;
int ret;
*filename = strdup(path);
db_file_stamp_bypath(path, &stamp, &id);
if (stamp && (stamp >= mtime))
{
db_file_ping(id);
return 0;
}
if (extinf)
DPRINTF(E_INFO, L_SCAN, "Playlist has EXTINF metadata, artist is '%s', title is '%s'\n", mfi->artist, mfi->title);
mfi->id = id;
mfi->path = strdup(path);
mfi->fname = strdup(filename_from_path(path));
mfi->data_kind = DATA_KIND_HTTP;
mfi->time_modified = mtime;
mfi->directory_id = DIR_HTTP;
ret = scan_metadata_ffmpeg(path, mfi);
if (ret < 0)
{
DPRINTF(E_LOG, L_SCAN, "Playlist URL '%s' is unavailable for probe/metadata, assuming MP3 encoding\n", path);
mfi->type = strdup("mp3");
mfi->codectype = strdup("mpeg");
mfi->description = strdup("MPEG audio file");
}
if (!mfi->title)
mfi->title = strdup(mfi->fname);
snprintf(virtual_path, PATH_MAX, "/http:/%s", mfi->title);
mfi->virtual_path = strdup(virtual_path);
library_add_media(mfi);
return 0;
}
int
process_regular_file(char *path, char **filename)
{
int i;
int mfi_id;
char *ptr;
char *entry;
int ret;
/* Playlist might be from Windows so we change backslash to forward slash */
for (i = 0; i < strlen(path); i++)
{
if (path[i] == '\\')
path[i] = '/';
}
/* Now search for the library item where the path has closest match to playlist item */
/* Succes is when we find an unambiguous match, or when we no longer can expand the */
/* the path to refine our search. */
entry = NULL;
do
{
ptr = strrchr(path, '/');
if (entry)
*(entry - 1) = '/';
if (ptr)
{
*ptr = '\0';
entry = ptr + 1;
}
else
entry = path;
DPRINTF(E_SPAM, L_SCAN, "Playlist entry is now %s\n", entry);
ret = db_files_get_count_bymatch(entry);
}
while (ptr && (ret > 1));
if (ret > 0)
{
mfi_id = db_file_id_bymatch(entry);
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);
return -1;
}
}
else
{
DPRINTF(E_DBG, L_SCAN, "No match for playlist entry %s\n", entry);
return -1;
}
return 0;
}
void
scan_playlist(char *file, time_t mtime, int dir_id)
{
@ -84,19 +190,15 @@ scan_playlist(char *file, time_t mtime, int dir_id)
struct stat sb;
char buf[PATH_MAX];
char *path;
char *entry;
char *filename;
const char *filename;
char *ptr;
size_t len;
int extinf;
int pl_id;
int pl_format;
int mfi_id;
int ret;
char virtual_path[PATH_MAX];
int i;
time_t stamp;
int id;
char *plitem_path;
DPRINTF(E_LOG, L_SCAN, "Processing static playlist: %s\n", file);
@ -111,11 +213,7 @@ scan_playlist(char *file, time_t mtime, int dir_id)
else
return;
filename = strrchr(file, '/');
if (!filename)
filename = file;
else
filename++;
filename = filename_from_path(file);
ret = stat(file, &sb);
if (ret < 0)
@ -231,105 +329,25 @@ scan_playlist(char *file, time_t mtime, int dir_id)
{
DPRINTF(E_DBG, L_SCAN, "Playlist contains URL entry: '%s'\n", path);
db_file_stamp_bypath(path, &stamp, &id);
if (stamp && (stamp >= sb.st_mtime))
{
db_file_ping(id);
continue;
}
filename = strdup(path);
if (!filename)
{
DPRINTF(E_LOG, L_SCAN, "Out of memory for playlist filename\n");
continue;
}
if (extinf)
DPRINTF(E_INFO, L_SCAN, "Playlist has EXTINF metadata, artist is '%s', title is '%s'\n", mfi.artist, mfi.title);
mfi.id = id;
mfi.fname = strdup(basename(filename));
mfi.path = strdup(filename);
mfi.data_kind = DATA_KIND_HTTP;
mfi.time_modified = mtime;
mfi.directory_id = DIR_HTTP;
ret = scan_metadata_ffmpeg(path, &mfi);
if (ret < 0)
{
DPRINTF(E_LOG, L_SCAN, "Playlist URL '%s' is unavailable for probe/metadata, assuming MP3 encoding\n", path);
mfi.type = strdup("mp3");
mfi.codectype = strdup("mpeg");
mfi.description = strdup("MPEG audio file");
}
snprintf(virtual_path, PATH_MAX, "/http:/%s", mfi.title); //TODO can title be null at this point?
mfi.virtual_path = strdup(virtual_path);
library_add_media(&mfi);
ret = process_url(path, sb.st_mtime, extinf, &mfi, &plitem_path);
}
/* Regular file, should already be in library */
else
{
/* Playlist might be from Windows so we change backslash to forward slash */
for (i = 0; i < strlen(path); i++)
{
if (path[i] == '\\')
path[i] = '/';
}
/* Now search for the library item where the path has closest match to playlist item */
/* Succes is when we find an unambiguous match, or when we no longer can expand the */
/* the path to refine our search. */
entry = NULL;
do
{
ptr = strrchr(path, '/');
if (entry)
*(entry - 1) = '/';
if (ptr)
{
*ptr = '\0';
entry = ptr + 1;
}
else
entry = path;
DPRINTF(E_SPAM, L_SCAN, "Playlist entry is now %s\n", entry);
ret = db_files_get_count_bymatch(entry);
} while (ptr && (ret > 1));
if (ret > 0)
{
mfi_id = db_file_id_bymatch(entry);
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
{
DPRINTF(E_DBG, L_SCAN, "No match for playlist entry %s\n", entry);
continue;
}
ret = process_regular_file(path, &plitem_path);
}
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);
if (ret == 0)
{
ret = db_pl_add_item_bypath(pl_id, plitem_path);
if (ret < 0)
DPRINTF(E_WARN, L_SCAN, "Could not add %s to playlist\n", plitem_path);
/* Clean up in preparation for next item */
extinf = 0;
free_mfi(&mfi, 1);
free(filename);
/* Clean up in preparation for next item */
extinf = 0;
free_mfi(&mfi, 1);
free(plitem_path);
}
}
/* We had some extinf that we never got to use, free it now */