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
594810da
Commit
594810da
authored
May 31, 2018
by
Hugo Beauzée-Luyssen
Browse files
Task: Store the mrl in the item
parent
85c191ec
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/MediaLibrary.cpp
View file @
594810da
...
...
@@ -1006,8 +1006,8 @@ void MediaLibrary::migrateModel10to11()
auto
t
=
getConn
()
->
newTransaction
();
for
(
const
auto
&
t
:
tasks
)
{
auto
newMrl
=
utils
::
url
::
encode
(
utils
::
url
::
decode
(
t
->
mrl
)
);
LOG_INFO
(
"Converting task mrl: "
,
t
->
mrl
,
" to "
,
newMrl
);
auto
newMrl
=
utils
::
url
::
encode
(
utils
::
url
::
decode
(
t
->
item
().
mrl
()
)
);
LOG_INFO
(
"Converting task mrl: "
,
t
->
item
().
mrl
()
,
" to "
,
newMrl
);
t
->
setMrl
(
std
::
move
(
newMrl
)
);
}
for
(
const
auto
&
f
:
folders
)
...
...
src/metadata_services/MetadataParser.cpp
View file @
594810da
...
...
@@ -109,14 +109,15 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
{
assert
(
task
.
media
==
nullptr
);
// Try to create Media & File
auto
mrl
=
task
.
item
().
mrl
();
try
{
auto
t
=
m_ml
->
getConn
()
->
newTransaction
();
LOG_INFO
(
"Adding "
,
task
.
mrl
);
task
.
media
=
Media
::
create
(
m_ml
,
IMedia
::
Type
::
Unknown
,
utils
::
file
::
fileName
(
task
.
mrl
)
);
LOG_INFO
(
"Adding "
,
mrl
);
task
.
media
=
Media
::
create
(
m_ml
,
IMedia
::
Type
::
Unknown
,
utils
::
file
::
fileName
(
mrl
)
);
if
(
task
.
media
==
nullptr
)
{
LOG_ERROR
(
"Failed to add media "
,
task
.
mrl
,
" to the media library"
);
LOG_ERROR
(
"Failed to add media "
,
mrl
,
" to the media library"
);
return
parser
::
Task
::
Status
::
Fatal
;
}
// For now, assume all media are made of a single file
...
...
@@ -125,7 +126,7 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
File
::
Type
::
Main
);
if
(
task
.
file
==
nullptr
)
{
LOG_ERROR
(
"Failed to add file "
,
task
.
mrl
,
" to media #"
,
task
.
media
->
id
()
);
LOG_ERROR
(
"Failed to add file "
,
mrl
,
" to media #"
,
task
.
media
->
id
()
);
return
parser
::
Task
::
Status
::
Fatal
;
}
task
.
updateFileId
();
...
...
@@ -137,10 +138,10 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
LOG_INFO
(
"Creation of Media & File failed because "
,
ex
.
what
(),
". Assuming this task is a duplicate"
);
// Try to retrieve file & Media from database
auto
fileInDB
=
File
::
fromMrl
(
m_ml
,
task
.
mrl
);
auto
fileInDB
=
File
::
fromMrl
(
m_ml
,
mrl
);
if
(
fileInDB
==
nullptr
)
// The file is no longer present in DB, gracefully delete task
{
LOG_ERROR
(
"File "
,
task
.
mrl
,
" no longer present in DB, aborting"
);
LOG_ERROR
(
"File "
,
mrl
,
" no longer present in DB, aborting"
);
return
parser
::
Task
::
Status
::
Fatal
;
}
task
.
file
=
fileInDB
;
...
...
@@ -229,20 +230,21 @@ parser::Task::Status MetadataParser::run( parser::Task& task )
bool
MetadataParser
::
addPlaylistMedias
(
parser
::
Task
&
task
,
int
nbSubitem
)
const
{
auto
t
=
m_ml
->
getConn
()
->
newTransaction
();
LOG_INFO
(
"Try to import "
,
task
.
mrl
,
" as a playlist"
);
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
(
task
.
mrl
)
);
playlistName
=
utils
::
url
::
decode
(
utils
::
file
::
fileName
(
mrl
)
);
auto
playlistPtr
=
Playlist
::
create
(
m_ml
,
playlistName
);
if
(
playlistPtr
==
nullptr
)
{
LOG_ERROR
(
"Failed to create playlist "
,
task
.
mrl
,
" to the media library"
);
LOG_ERROR
(
"Failed to create playlist "
,
mrl
,
" to the media library"
);
return
false
;
}
task
.
file
=
playlistPtr
->
addFile
(
*
task
.
fileFs
,
task
.
parentFolder
->
id
(),
task
.
parentFolderFs
->
device
()
->
isRemovable
()
);
if
(
task
.
file
==
nullptr
)
{
LOG_ERROR
(
"Failed to add playlist file "
,
task
.
mrl
);
LOG_ERROR
(
"Failed to add playlist file "
,
mrl
);
return
false
;
}
t
->
commit
();
...
...
@@ -259,11 +261,11 @@ void MetadataParser::addPlaylistElement( parser::Task& task, const std::shared_p
if
(
subitem
==
nullptr
)
return
;
const
auto
&
mrl
=
subitem
->
mrl
();
LOG_INFO
(
"Try to add "
,
mrl
,
" to the playlist "
,
task
.
mrl
);
LOG_INFO
(
"Try to add "
,
mrl
,
" to the playlist "
,
mrl
);
auto
media
=
m_ml
->
media
(
mrl
);
if
(
media
!=
nullptr
)
{
LOG_INFO
(
"Media for "
,
mrl
,
" already exists, adding it to the playlist "
,
task
.
mrl
);
LOG_INFO
(
"Media for "
,
mrl
,
" already exists, adding it to the playlist "
,
mrl
);
playlistPtr
->
add
(
media
->
id
(),
index
);
return
;
}
...
...
@@ -277,13 +279,13 @@ void MetadataParser::addPlaylistElement( parser::Task& task, const std::shared_p
subitem
->
meta
(
libvlc_meta_Title
)
)
);
if
(
externalMedia
==
nullptr
)
{
LOG_ERROR
(
"Failed to create external media for "
,
mrl
,
" in the playlist "
,
task
.
mrl
);
LOG_ERROR
(
"Failed to create external media for "
,
subitem
->
mrl
()
,
" in the playlist "
,
mrl
);
return
;
}
// Assuming that external mrl present in playlist file is a main media resource
auto
externalFile
=
externalMedia
->
addExternalMrl
(
mrl
,
IFile
::
Type
::
Main
);
if
(
externalFile
==
nullptr
)
LOG_ERROR
(
"Failed to create external file for "
,
mrl
,
" in the playlist "
,
task
.
mrl
);
LOG_ERROR
(
"Failed to create external file for "
,
subitem
->
mrl
()
,
" in the playlist "
,
mrl
);
playlistPtr
->
add
(
externalMedia
->
id
(),
index
);
t2
->
commit
();
return
;
...
...
@@ -298,7 +300,7 @@ void MetadataParser::addPlaylistElement( parser::Task& task, const std::shared_p
LOG_ERROR
(
ex
.
what
()
);
return
;
}
LOG_INFO
(
"Importing "
,
isDirectory
?
"folder "
:
"file "
,
mrl
,
" in the playlist "
,
task
.
mrl
);
LOG_INFO
(
"Importing "
,
isDirectory
?
"folder "
:
"file "
,
subitem
->
mrl
()
,
" in the playlist "
,
mrl
);
auto
directoryMrl
=
utils
::
file
::
directory
(
mrl
);
auto
parentFolder
=
Folder
::
fromMrl
(
m_ml
,
directoryMrl
);
bool
parentKnown
=
parentFolder
!=
nullptr
;
...
...
src/metadata_services/vlc/VLCMetadataService.cpp
View file @
594810da
...
...
@@ -49,7 +49,7 @@ bool VLCMetadataService::initialize( MediaLibrary* ml )
parser
::
Task
::
Status
VLCMetadataService
::
run
(
parser
::
Task
&
task
)
{
auto
mrl
=
task
.
mrl
;
auto
mrl
=
task
.
item
().
mrl
()
;
LOG_INFO
(
"Parsing "
,
mrl
);
// Having a valid media means we're re-executing this parser after the thumbnailer,
...
...
src/parser/ParserWorker.cpp
View file @
594810da
...
...
@@ -164,14 +164,14 @@ void ParserWorker::mainloop()
}
if
(
m_service
->
isCompleted
(
*
task
)
==
true
)
{
LOG_INFO
(
"Skipping completed task ["
,
serviceName
,
"] on "
,
task
->
mrl
);
LOG_INFO
(
"Skipping completed task ["
,
serviceName
,
"] on "
,
task
->
item
().
mrl
()
);
m_parserCb
->
done
(
std
::
move
(
task
),
parser
::
Task
::
Status
::
Success
);
continue
;
}
parser
::
Task
::
Status
status
;
try
{
LOG_INFO
(
"Executing "
,
serviceName
,
" task on "
,
task
->
mrl
);
LOG_INFO
(
"Executing "
,
serviceName
,
" task on "
,
task
->
item
().
mrl
()
);
auto
chrono
=
std
::
chrono
::
steady_clock
::
now
();
if
(
(
task
->
file
!=
nullptr
&&
task
->
file
->
isDeleted
()
)
||
(
task
->
media
!=
nullptr
&&
task
->
media
->
isDeleted
()
)
)
...
...
@@ -181,13 +181,13 @@ void ParserWorker::mainloop()
task
->
startParserStep
();
status
=
m_service
->
run
(
*
task
);
auto
duration
=
std
::
chrono
::
steady_clock
::
now
()
-
chrono
;
LOG_INFO
(
"Done executing "
,
serviceName
,
" task on "
,
task
->
mrl
,
" in "
,
LOG_INFO
(
"Done executing "
,
serviceName
,
" task on "
,
task
->
item
().
mrl
()
,
" in "
,
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
duration
).
count
(),
"ms"
);
}
}
catch
(
const
std
::
exception
&
ex
)
{
LOG_ERROR
(
"Caught an exception during "
,
task
->
mrl
,
" ["
,
serviceName
,
"] parsing: "
,
ex
.
what
()
);
LOG_ERROR
(
"Caught an exception during "
,
task
->
item
().
mrl
()
,
" ["
,
serviceName
,
"] parsing: "
,
ex
.
what
()
);
status
=
parser
::
Task
::
Status
::
Fatal
;
}
m_parserCb
->
done
(
std
::
move
(
task
),
status
);
...
...
src/parser/Task.cpp
View file @
594810da
...
...
@@ -50,6 +50,7 @@ Task::Task( MediaLibraryPtr ml, sqlite::Row& row )
:
currentService
(
0
)
,
m_ml
(
ml
)
{
std
::
string
mrl
;
row
>>
m_id
>>
m_step
>>
m_retryCount
...
...
@@ -58,6 +59,7 @@ Task::Task( MediaLibraryPtr ml, sqlite::Row& row )
>>
m_parentFolderId
>>
m_parentPlaylistId
>>
parentPlaylistIndex
;
m_item
=
Item
{
std
::
move
(
mrl
)
};
}
Task
::
Task
(
MediaLibraryPtr
ml
,
std
::
shared_ptr
<
fs
::
IFile
>
fileFs
,
...
...
@@ -70,11 +72,11 @@ Task::Task( MediaLibraryPtr ml, std::shared_ptr<fs::IFile> fileFs,
,
parentFolderFs
(
std
::
move
(
parentFolderFs
)
)
,
parentPlaylist
(
std
::
move
(
parentPlaylist
)
)
,
parentPlaylistIndex
(
parentPlaylistIndex
)
,
mrl
(
this
->
fileFs
->
mrl
()
)
,
currentService
(
0
)
,
m_ml
(
ml
)
,
m_step
(
ParserStep
::
None
)
,
m_fileId
(
0
)
,
m_item
(
this
->
fileFs
->
mrl
()
)
{
}
...
...
@@ -135,6 +137,11 @@ Task::Item& Task::item()
return
m_item
;
}
Task
::
Item
::
Item
(
std
::
string
mrl
)
:
m_mrl
(
std
::
move
(
mrl
)
)
{
}
std
::
string
Task
::
Item
::
meta
(
Task
::
Item
::
Metadata
type
)
const
{
auto
it
=
m_metadata
.
find
(
type
);
...
...
@@ -148,12 +155,17 @@ void Task::Item::setMeta( Task::Item::Metadata type, std::string value )
m_metadata
[
type
]
=
std
::
move
(
value
);
}
const
std
::
string
&
Task
::
Item
::
mrl
()
const
{
return
m_mrl
;
}
bool
Task
::
restoreLinkedEntities
()
{
LOG_INFO
(
"Restoring linked entities of task "
,
m_id
);
// MRL will be empty if the task has been resumed from unparsed files
// parentFolderId == 0 indicates an external file
if
(
m
rl
.
empty
()
==
true
&&
m_parentFolderId
==
0
)
if
(
m
_item
.
mrl
()
.
empty
()
==
true
&&
m_parentFolderId
==
0
)
{
LOG_WARN
(
"Aborting & removing external file task (#"
,
m_id
,
')'
);
destroy
(
m_ml
,
m_id
);
...
...
@@ -166,7 +178,7 @@ bool Task::restoreLinkedEntities()
// We might re-create tasks without mrl to ease the handling of files on
// external storage.
if
(
m
rl
.
empty
()
==
true
)
if
(
m
_item
.
mrl
()
.
empty
()
==
true
)
{
// but we expect those to be created from an existing file after a
// partial/failed migration. If we don't have a file nor an mrl, we
...
...
@@ -193,13 +205,13 @@ bool Task::restoreLinkedEntities()
}
setMrl
(
file
->
mrl
()
);
}
auto
fsFactory
=
m_ml
->
fsFactoryForMrl
(
m
rl
);
auto
fsFactory
=
m_ml
->
fsFactoryForMrl
(
m
_item
.
mrl
()
);
if
(
fsFactory
==
nullptr
)
return
false
;
try
{
parentFolderFs
=
fsFactory
->
createDirectory
(
utils
::
file
::
directory
(
m
rl
)
);
parentFolderFs
=
fsFactory
->
createDirectory
(
utils
::
file
::
directory
(
m
_item
.
mrl
()
)
);
}
catch
(
const
std
::
system_error
&
ex
)
{
...
...
@@ -211,11 +223,11 @@ bool Task::restoreLinkedEntities()
{
auto
files
=
parentFolderFs
->
files
();
auto
it
=
std
::
find_if
(
begin
(
files
),
end
(
files
),
[
this
](
std
::
shared_ptr
<
fs
::
IFile
>
f
)
{
return
f
->
mrl
()
==
m
rl
;
return
f
->
mrl
()
==
m
_item
.
mrl
()
;
});
if
(
it
==
end
(
files
)
)
{
LOG_ERROR
(
"Failed to restore fs::IFile associated with "
,
m
rl
);
LOG_ERROR
(
"Failed to restore fs::IFile associated with "
,
m
_item
.
mrl
()
);
return
false
;
}
fileFs
=
*
it
;
...
...
@@ -226,7 +238,7 @@ bool Task::restoreLinkedEntities()
// recreated upon next discovery
if
(
file
==
nullptr
)
{
LOG_WARN
(
"Failed to restore file system instances for mrl "
,
m
rl
,
"."
LOG_WARN
(
"Failed to restore file system instances for mrl "
,
m
_item
.
mrl
()
,
"."
" Removing the task until it gets detected again."
);
destroy
(
m_ml
,
m_id
);
}
...
...
@@ -236,7 +248,7 @@ bool Task::restoreLinkedEntities()
// detect that the file is now missing, and we won't try to restore
// this task until it comes back (since the task restoration request
// includes the file.is_present flag)
LOG_WARN
(
"Failed to restore file system instances for mrl "
,
m
rl
,
"."
LOG_WARN
(
"Failed to restore file system instances for mrl "
,
m
_item
.
mrl
()
,
"."
" Postponing the task."
);
}
return
false
;
...
...
@@ -254,13 +266,13 @@ bool Task::restoreLinkedEntities()
void
Task
::
setMrl
(
std
::
string
newMrl
)
{
if
(
m
rl
==
newMrl
)
if
(
m
_item
.
mrl
()
==
newMrl
)
return
;
static
const
std
::
string
req
=
"UPDATE "
+
policy
::
TaskTable
::
Name
+
" SET "
"mrl = ? WHERE id_task = ?"
;
if
(
sqlite
::
Tools
::
executeUpdate
(
m_ml
->
getConn
(),
req
,
newMrl
,
m_id
)
==
false
)
return
;
m
rl
=
std
::
move
(
newMrl
);
m
_item
=
Item
{
std
::
move
(
newMrl
)
}
;
}
void
Task
::
createTable
(
sqlite
::
Connection
*
dbConnection
)
...
...
@@ -321,7 +333,7 @@ Task::create( MediaLibraryPtr ml, std::shared_ptr<fs::IFile> fileFs,
const
std
::
string
req
=
"INSERT INTO "
+
policy
::
TaskTable
::
Name
+
"(mrl, parent_folder_id, parent_playlist_id, parent_playlist_index) "
"VALUES(?, ?, ?, ?)"
;
if
(
insert
(
ml
,
self
,
req
,
self
->
m
rl
,
self
->
parentFolder
->
id
(),
sqlite
::
ForeignKey
(
if
(
insert
(
ml
,
self
,
req
,
self
->
m
_item
.
mrl
()
,
self
->
parentFolder
->
id
(),
sqlite
::
ForeignKey
(
self
->
parentPlaylist
?
self
->
parentPlaylist
->
id
()
:
0
),
self
->
parentPlaylistIndex
)
==
false
)
return
nullptr
;
...
...
src/parser/Task.h
View file @
594810da
...
...
@@ -92,6 +92,8 @@ public:
class
Item
{
public:
Item
()
=
default
;
Item
(
std
::
string
mrl
);
enum
class
Metadata
:
uint8_t
{
Title
,
...
...
@@ -110,7 +112,10 @@ public:
std
::
string
meta
(
Metadata
type
)
const
;
void
setMeta
(
Metadata
type
,
std
::
string
value
);
const
std
::
string
&
mrl
()
const
;
private:
std
::
string
m_mrl
;
std
::
unordered_map
<
Metadata
,
std
::
string
>
m_metadata
;
};
...
...
@@ -159,7 +164,6 @@ public:
std
::
shared_ptr
<
fs
::
IDirectory
>
parentFolderFs
;
std
::
shared_ptr
<
Playlist
>
parentPlaylist
;
unsigned
int
parentPlaylistIndex
;
std
::
string
mrl
;
VLC
::
Media
vlcMedia
;
unsigned
int
currentService
;
...
...
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