mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-01 10:13:45 -04:00
[filescanner] More alignment of iTunes scanner with the playlist scanner
I.e. use transactions and don't scan unmodified files
This commit is contained in:
parent
bf8fa1c3f0
commit
2d54d0d8fe
@ -391,7 +391,7 @@ process_playlist(char *file, time_t mtime, int dir_id)
|
|||||||
scan_playlist(file, mtime, dir_id);
|
scan_playlist(file, mtime, dir_id);
|
||||||
#ifdef ITUNES
|
#ifdef ITUNES
|
||||||
else if (ft == FILE_ITUNES)
|
else if (ft == FILE_ITUNES)
|
||||||
scan_itunes_itml(file);
|
scan_itunes_itml(file, mtime, dir_id);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ scan_smartpl(const char *file, time_t mtime, int dir_id);
|
|||||||
|
|
||||||
#ifdef ITUNES
|
#ifdef ITUNES
|
||||||
void
|
void
|
||||||
scan_itunes_itml(const char *file);
|
scan_itunes_itml(const char *file, time_t mtime, int dir_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -550,6 +550,8 @@ process_tracks(plist_t tracks)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db_transaction_begin();
|
||||||
|
|
||||||
ntracks = 0;
|
ntracks = 0;
|
||||||
|
|
||||||
iter = NULL;
|
iter = NULL;
|
||||||
@ -621,6 +623,12 @@ process_tracks(plist_t tracks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ntracks++;
|
ntracks++;
|
||||||
|
if (ntracks % 200 == 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "Processed %d tracks...\n", ntracks);
|
||||||
|
db_transaction_end();
|
||||||
|
db_transaction_begin();
|
||||||
|
}
|
||||||
|
|
||||||
ret = id_map_add(trk_id, mfi_id);
|
ret = id_map_add(trk_id, mfi_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -631,20 +639,27 @@ process_tracks(plist_t tracks)
|
|||||||
|
|
||||||
free(iter);
|
free(iter);
|
||||||
|
|
||||||
|
db_transaction_end();
|
||||||
|
|
||||||
return ntracks;
|
return ntracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_pl_items(plist_t items, int pl_id)
|
process_pl_items(plist_t items, int pl_id, const char *name)
|
||||||
{
|
{
|
||||||
plist_t trk;
|
plist_t trk;
|
||||||
uint64_t itml_id;
|
uint64_t itml_id;
|
||||||
uint32_t db_id;
|
uint32_t db_id;
|
||||||
uint32_t alen;
|
uint32_t alen;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
int ntracks;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
db_transaction_begin();
|
||||||
|
|
||||||
|
ntracks = 0;
|
||||||
|
|
||||||
alen = plist_array_get_size(items);
|
alen = plist_array_get_size(items);
|
||||||
for (i = 0; i < alen; i++)
|
for (i = 0; i < alen; i++)
|
||||||
{
|
{
|
||||||
@ -667,14 +682,24 @@ process_pl_items(plist_t items, int pl_id)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ntracks++;
|
||||||
|
if (ntracks % 200 == 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "Processed %d tracks from playlist '%s'...\n", ntracks, name);
|
||||||
|
db_transaction_end();
|
||||||
|
db_transaction_begin();
|
||||||
|
}
|
||||||
|
|
||||||
ret = db_pl_add_item_byid(pl_id, db_id);
|
ret = db_pl_add_item_byid(pl_id, db_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
DPRINTF(E_WARN, L_SCAN, "Could not add ID %d to playlist\n", db_id);
|
DPRINTF(E_WARN, L_SCAN, "Could not add ID %d to playlist\n", db_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db_transaction_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ignore_pl(plist_t pl, char *name)
|
ignore_pl(plist_t pl, const char *name)
|
||||||
{
|
{
|
||||||
uint64_t kind;
|
uint64_t kind;
|
||||||
int smart;
|
int smart;
|
||||||
@ -802,24 +827,69 @@ process_pls(plist_t playlists, const char *file)
|
|||||||
DPRINTF(E_INFO, L_SCAN, "Added playlist as id %d\n", pl_id);
|
DPRINTF(E_INFO, L_SCAN, "Added playlist as id %d\n", pl_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(name);
|
process_pl_items(items, pl_id, name);
|
||||||
|
|
||||||
process_pl_items(items, pl_id);
|
free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
scan_itunes_itml(const char *file)
|
scan_itunes_itml(const char *file, time_t mtime, int dir_id)
|
||||||
{
|
{
|
||||||
|
struct playlist_info *pli;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
char buf[PATH_MAX];
|
||||||
char *itml_xml;
|
char *itml_xml;
|
||||||
plist_t itml;
|
plist_t itml;
|
||||||
plist_t node;
|
plist_t node;
|
||||||
int fd;
|
int fd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Processing iTunes library: %s\n", file);
|
// This is special playlist that is disabled and only used for saving a timestamp
|
||||||
|
pli = db_pl_fetch_bytitlepath(file, file);
|
||||||
|
if (pli)
|
||||||
|
{
|
||||||
|
db_pl_ping(pli->id);
|
||||||
|
db_pl_disable_bypath(file, "", 0);
|
||||||
|
|
||||||
|
if (mtime && (pli->db_timestamp >= mtime))
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "Unchanged iTunes XML found, not processing '%s'\n", file);
|
||||||
|
|
||||||
|
// TODO Protect the radio stations from purge after scan
|
||||||
|
free_pli(pli, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "Modified iTunes XML found, processing '%s'\n", file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "New iTunes XML found, processing: '%s'\n", file);
|
||||||
|
|
||||||
|
CHECK_NULL(L_SCAN, pli = calloc(1, sizeof(struct playlist_info)));
|
||||||
|
|
||||||
|
pli->type = PL_PLAIN;
|
||||||
|
pli->title = strdup(file);
|
||||||
|
pli->path = strdup(file);
|
||||||
|
snprintf(buf, sizeof(buf), "/file:%s", file);
|
||||||
|
pli->virtual_path = strip_extension(buf);
|
||||||
|
pli->directory_id = dir_id;
|
||||||
|
|
||||||
|
ret = db_pl_add(pli, (int *)&pli->id);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SCAN, "Error adding iTunes XML playlist '%s'\n", file);
|
||||||
|
|
||||||
|
free_pli(pli, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db_pl_disable_bypath(file, "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_pli(pli, 0);
|
||||||
|
|
||||||
fd = open(file, O_RDONLY);
|
fd = open(file, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -841,7 +911,7 @@ scan_itunes_itml(const char *file)
|
|||||||
itml_xml = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
itml_xml = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
if (itml_xml == MAP_FAILED)
|
if (itml_xml == MAP_FAILED)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not map iTunes library: %s\n", strerror(errno));
|
DPRINTF(E_LOG, L_SCAN, "Could not map iTunes library '%s': %s\n", file, strerror(errno));
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return;
|
return;
|
||||||
@ -852,7 +922,7 @@ scan_itunes_itml(const char *file)
|
|||||||
|
|
||||||
ret = munmap(itml_xml, sb.st_size);
|
ret = munmap(itml_xml, sb.st_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not unmap iTunes library: %s\n", strerror(errno));
|
DPRINTF(E_LOG, L_SCAN, "Could not unmap iTunes library '%s': %s\n", file, strerror(errno));
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@ -883,7 +953,7 @@ scan_itunes_itml(const char *file)
|
|||||||
ret = get_dictval_dict_from_key(itml, "Tracks", &node);
|
ret = get_dictval_dict_from_key(itml, "Tracks", &node);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not find Tracks dict\n");
|
DPRINTF(E_LOG, L_SCAN, "Could not find Tracks dict in '%s'\n", file);
|
||||||
|
|
||||||
plist_free(itml);
|
plist_free(itml);
|
||||||
return;
|
return;
|
||||||
@ -901,20 +971,20 @@ scan_itunes_itml(const char *file)
|
|||||||
ret = process_tracks(node);
|
ret = process_tracks(node);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "No tracks loaded\n");
|
DPRINTF(E_LOG, L_SCAN, "No tracks loaded from iTunes XML '%s'\n", file);
|
||||||
|
|
||||||
id_map_free();
|
id_map_free();
|
||||||
plist_free(itml);
|
plist_free(itml);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_INFO, L_SCAN, "Loaded %d tracks from iTunes library\n", ret);
|
DPRINTF(E_LOG, L_SCAN, "Loaded %d tracks from iTunes XML '%s'\n", ret, file);
|
||||||
|
|
||||||
/* Playlists */
|
/* Playlists */
|
||||||
ret = get_dictval_array_from_key(itml, "Playlists", &node);
|
ret = get_dictval_array_from_key(itml, "Playlists", &node);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not find Playlists dict\n");
|
DPRINTF(E_LOG, L_SCAN, "Could not find Playlists dict in '%s'\n", file);
|
||||||
|
|
||||||
id_map_free();
|
id_map_free();
|
||||||
plist_free(itml);
|
plist_free(itml);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user