Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
VideoLAN
medialibrary
Commits
c6ba8ad5
Commit
c6ba8ad5
authored
Jun 01, 2018
by
Hugo Beauzée-Luyssen
Browse files
MetadataParser: Properly handle playlist rescan
parent
3ed4e89f
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/MediaLibrary.cpp
View file @
c6ba8ad5
...
...
@@ -1292,7 +1292,7 @@ void MediaLibrary::forceRescan()
Show
::
deleteAll
(
this
);
VideoTrack
::
deleteAll
(
this
);
AudioTrack
::
deleteAll
(
this
);
Playlist
::
deleteAllExternal
(
this
);
Playlist
::
clearExternalPlaylistContent
(
this
);
parser
::
Task
::
resetParsing
(
this
);
clearCache
();
Artist
::
createDefaultArtists
(
getConn
()
);
...
...
src/Playlist.cpp
View file @
c6ba8ad5
...
...
@@ -278,10 +278,15 @@ Query<IPlaylist> Playlist::listAll( MediaLibraryPtr ml, SortingCriteria sort, bo
return
make_query
<
Playlist
,
IPlaylist
>
(
ml
,
"*"
,
req
);
}
void
Playlist
::
deleteAllExternal
(
MediaLibraryPtr
ml
)
void
Playlist
::
clearExternalPlaylistContent
(
MediaLibraryPtr
ml
)
{
const
std
::
string
req
=
"DELETE FROM "
+
policy
::
PlaylistTable
::
Name
+
" WHERE file_id IS NOT NULL"
;
// We can't delete all external playlist as such, since this would cause the
// deletion of the associated task through the Task.playlist_id Playlist.id_playlist
// foreign key, and therefor they wouldn't be rescanned.
// Instead, flush the playlist content.
const
std
::
string
req
=
"DELETE FROM PlaylistMediaRelation WHERE playlist_id IN ("
"SELECT id_playlist FROM "
+
policy
::
PlaylistTable
::
Name
+
" WHERE "
"file_id IS NOT NULL)"
;
sqlite
::
Tools
::
executeDelete
(
ml
->
getConn
(),
req
);
}
...
...
src/Playlist.h
View file @
c6ba8ad5
...
...
@@ -78,7 +78,7 @@ public:
* that were parsed from playlist files.
* Playlist manually added by the user are untouched
*/
static
void
deleteAllExternal
(
MediaLibraryPtr
ml
);
static
void
clearExternalPlaylistContent
(
MediaLibraryPtr
ml
);
private:
static
std
::
string
sortRequest
(
SortingCriteria
sort
,
bool
desc
);
...
...
src/metadata_services/MetadataParser.cpp
View file @
c6ba8ad5
...
...
@@ -235,28 +235,54 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
bool
MetadataParser
::
addPlaylistMedias
(
parser
::
Task
&
task
)
const
{
auto
t
=
m_ml
->
getConn
()
->
newTransaction
();
const
auto
&
mrl
=
task
.
item
().
mrl
();
LOG_INFO
(
"Try to import "
,
mrl
,
" as a playlist"
);
auto
playlistName
=
task
.
item
().
meta
(
parser
::
Task
::
Item
::
Metadata
::
Title
);
if
(
playlistName
.
empty
()
==
true
)
playlistName
=
utils
::
url
::
decode
(
utils
::
file
::
fileName
(
mrl
)
);
auto
playlistPtr
=
Playlist
::
create
(
m_ml
,
playlistName
);
if
(
playlistPtr
==
nullptr
)
{
LOG_ERROR
(
"Failed to create playlist "
,
mrl
,
" to the media library"
);
return
false
;
std
::
shared_ptr
<
Playlist
>
playlistPtr
;
if
(
task
.
item
().
file
()
!=
nullptr
)
{
// We are most likely re-scanning a file representing a playlist.
// If a task has a file, it means the playlist & the associated file have
// been created.
std
::
string
req
=
"SELECT * FROM "
+
policy
::
PlaylistTable
::
Name
+
" WHERE file_id = ?"
;
playlistPtr
=
Playlist
::
fetch
(
m_ml
,
req
,
task
.
item
().
file
()
->
id
()
);
if
(
playlistPtr
==
nullptr
)
{
// The playlist had to be created, something is very wrong, give up
// FIXME: Check that the task will be deleted.
assert
(
false
);
return
false
;
}
}
auto
file
=
playlistPtr
->
addFile
(
*
task
.
item
().
fileFs
(),
task
.
item
().
parentFolder
()
->
id
(),
task
.
item
().
parentFolderFs
()
->
device
()
->
isRemovable
()
);
if
(
file
==
nullptr
)
else
{
LOG_ERROR
(
"Failed to add playlist file "
,
mrl
);
return
false
;
auto
playlistName
=
task
.
item
().
meta
(
parser
::
Task
::
Item
::
Metadata
::
Title
);
if
(
playlistName
.
empty
()
==
true
)
playlistName
=
utils
::
url
::
decode
(
utils
::
file
::
fileName
(
mrl
)
);
auto
t
=
m_ml
->
getConn
()
->
newTransaction
();
playlistPtr
=
Playlist
::
create
(
m_ml
,
playlistName
);
if
(
playlistPtr
==
nullptr
)
{
LOG_ERROR
(
"Failed to create playlist "
,
mrl
,
" to the media library"
);
return
false
;
}
auto
file
=
playlistPtr
->
addFile
(
*
task
.
item
().
fileFs
(),
task
.
item
().
parentFolder
()
->
id
(),
task
.
item
().
parentFolderFs
()
->
device
()
->
isRemovable
()
);
if
(
file
==
nullptr
)
{
LOG_ERROR
(
"Failed to add playlist file "
,
mrl
);
return
false
;
}
task
.
item
().
setFile
(
std
::
move
(
file
)
);
t
->
commit
();
}
task
.
item
().
setFile
(
std
::
move
(
file
)
);
t
->
commit
();
// Now regardless of if the playlist is re-scanned or discovered from the
// first time, just schedule all members for insertion. media & files will
// be recreated if need be, and appropriate entries in PlaylistMediaRelation
// table will be recreated to link things together.
auto
subitems
=
task
.
item
().
subItems
();
for
(
const
auto
&
subItem
:
subitems
)
// FIXME: Interrupt loop if paused
addPlaylistElement
(
task
,
playlistPtr
,
subItem
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment