Skip to content

Tagging support for tvshows and musicvideos #1400

Merged
merged 3 commits into from Sep 10, 2012
View
5 system/library/video/musicvideos/tags.xml
@@ -0,0 +1,5 @@
+<node order="8" type="folder">
+ <label>20459</label>
+ <path>videodb://3/9</path>
+ <icon>DefaultTags.png</icon>
+</node>
View
5 system/library/video/tvshows/tags.xml
@@ -0,0 +1,5 @@
+<node order="6" type="folder">
+ <label>20459</label>
+ <path>videodb://2/9</path>
+ <icon>DefaultTags.png</icon>
+</node>
View
1 xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
@@ -34,6 +34,7 @@ Node MusicVideoChildren[] = {
{ NODE_TYPE_MUSICVIDEOS_ALBUM, 5, 132 },
{ NODE_TYPE_DIRECTOR, 6, 20348 },
{ NODE_TYPE_STUDIO, 7, 20388 },
+ { NODE_TYPE_TAGS, 9, 20459 }
};
CDirectoryNodeMusicVideosOverview::CDirectoryNodeMusicVideosOverview(const CStdString& strName, CDirectoryNode* pParent)
View
9 xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTags.cpp
@@ -33,7 +33,14 @@ CDirectoryNodeTags::CDirectoryNodeTags(const CStdString& strName, CDirectoryNode
NODE_TYPE CDirectoryNodeTags::GetChildType() const
{
- return NODE_TYPE_TITLE_MOVIES;
+ CQueryParams params;
+ CollectQueryParams(params);
+ if (params.GetContentType() == VIDEODB_CONTENT_MOVIES)
+ return NODE_TYPE_TITLE_MOVIES;
+ if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
+ return NODE_TYPE_TITLE_MUSICVIDEOS;
+
+ return NODE_TYPE_TITLE_TVSHOWS;
}
CStdString CDirectoryNodeTags::GetLocalizedName() const
View
2 xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
@@ -40,7 +40,7 @@ bool CDirectoryNodeTitleMusicVideos::GetContent(CFileItemList& items) const
CQueryParams params;
CollectQueryParams(params);
- bool bSuccess=videodatabase.GetMusicVideosNav(BuildPath(), items, params.GetGenreId(), params.GetYear(), params.GetActorId(), params.GetDirectorId(),params.GetStudioId(),params.GetAlbumId());
+ bool bSuccess=videodatabase.GetMusicVideosNav(BuildPath(), items, params.GetGenreId(), params.GetYear(), params.GetActorId(), params.GetDirectorId(), params.GetStudioId(), params.GetAlbumId(), params.GetTagId());
videodatabase.Close();
View
2 xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
@@ -53,7 +53,7 @@ bool CDirectoryNodeTitleTvShows::GetContent(CFileItemList& items) const
CQueryParams params;
CollectQueryParams(params);
- bool bSuccess=videodatabase.GetTvShowsNav(BuildPath(), items, params.GetGenreId(), params.GetYear(), params.GetActorId(), params.GetDirectorId(), params.GetStudioId());
+ bool bSuccess=videodatabase.GetTvShowsNav(BuildPath(), items, params.GetGenreId(), params.GetYear(), params.GetActorId(), params.GetDirectorId(), params.GetStudioId(), params.GetTagId());
videodatabase.Close();
View
1 xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
@@ -32,6 +32,7 @@ Node TvShowChildren[] = {
{ NODE_TYPE_YEAR, 3, 562 },
{ NODE_TYPE_ACTOR, 4, 344 },
{ NODE_TYPE_STUDIO, 5, 20388 },
+ { NODE_TYPE_TAGS, 9, 20459 }
};
CDirectoryNodeTvShowsOverview::CDirectoryNodeTvShowsOverview(const CStdString& strName, CDirectoryNode* pParent)
View
20 xbmc/interfaces/json-rpc/ServiceDescription.h
@@ -455,7 +455,7 @@ namespace JSONRPC
"\"imdbnumber\", \"premiered\", \"votes\", \"lastplayed\","
"\"fanart\", \"thumbnail\", \"file\", \"originaltitle\","
"\"sorttitle\", \"episodeguide\", \"season\", \"watchedepisodes\","
- "\"dateadded\"]"
+ "\"dateadded\", \"tag\" ]"
"}"
"}",
"\"Video.Fields.Season\": {"
@@ -483,7 +483,7 @@ namespace JSONRPC
"\"enum\": [ \"title\", \"playcount\", \"runtime\", \"director\","
"\"studio\", \"year\", \"plot\", \"album\", \"artist\","
"\"genre\", \"track\", \"streamdetails\", \"lastplayed\","
- "\"fanart\", \"thumbnail\", \"file\", \"resume\", \"dateadded\" ]"
+ "\"fanart\", \"thumbnail\", \"file\", \"resume\", \"dateadded\", \"tag\" ]"
"}"
"}",
"\"Video.Cast\": {"
@@ -629,7 +629,8 @@ namespace JSONRPC
"\"premiered\": { \"type\": \"string\" },"
"\"votes\": { \"type\": \"string\" },"
"\"episodeguide\": { \"type\": \"string\" },"
- "\"season\": { \"type\": \"integer\" }"
+ "\"season\": { \"type\": \"integer\" },"
+ "\"tag\": { \"$ref\": \"Array.String\" }"
"}"
"}",
"\"Video.Details.Season\": {"
@@ -668,7 +669,8 @@ namespace JSONRPC
"\"album\": { \"type\": \"string\" },"
"\"artist\": { \"$ref\": \"Array.String\" },"
"\"genre\": { \"$ref\": \"Array.String\" },"
- "\"track\": { \"type\": \"integer\" }"
+ "\"track\": { \"type\": \"integer\" },"
+ "\"tag\": { \"$ref\": \"Array.String\" }"
"}"
"}",
"\"Files.Media\": {"
@@ -1382,7 +1384,7 @@ namespace JSONRPC
"\"transport\": \"Response\","
"\"permission\": \"ControlPlayback\","
"\"params\": ["
- "{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true },"
+ "{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true }"
"{ \"name\": \"value\", \"type\": \"string\", \"enum\": [ \"clockwise\", \"counterclockwise\" ], \"default\": \"clockwise\" }"
"],"
"\"returns\": \"string\""
@@ -2116,6 +2118,7 @@ namespace JSONRPC
"{ \"type\": \"object\", \"properties\": { \"year\": { \"type\": \"integer\", \"minimum\": 0, \"required\": true } }, \"additionalProperties\": false },"
"{ \"type\": \"object\", \"properties\": { \"actor\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
"{ \"type\": \"object\", \"properties\": { \"studio\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"tag\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
"{ \"$ref\": \"List.Filter.TVShows\" }"
"]"
"}"
@@ -2227,6 +2230,7 @@ namespace JSONRPC
"{ \"type\": \"object\", \"properties\": { \"year\": { \"type\": \"integer\", \"minimum\": 0, \"required\": true } }, \"additionalProperties\": false },"
"{ \"type\": \"object\", \"properties\": { \"director\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
"{ \"type\": \"object\", \"properties\": { \"studio\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"tag\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
"{ \"$ref\": \"List.Filter.MusicVideos\" }"
"]"
"}"
@@ -2391,7 +2395,8 @@ namespace JSONRPC
"{ \"name\": \"sorttitle\", \"$ref\": \"Optional.String\" },"
"{ \"name\": \"episodeguide\", \"$ref\": \"Optional.String\" },"
"{ \"name\": \"thumbnail\", \"$ref\": \"Optional.String\" },"
- "{ \"name\": \"fanart\", \"$ref\": \"Optional.String\" }"
+ "{ \"name\": \"fanart\", \"$ref\": \"Optional.String\" },"
+ "{ \"name\": \"tag\", \"type\": [ \"null\", { \"$ref\": \"Array.String\", \"required\": true } ], \"default\": null }"
"],"
"\"returns\": \"string\""
"}",
@@ -2441,7 +2446,8 @@ namespace JSONRPC
"{ \"name\": \"track\", \"$ref\": \"Optional.Integer\" },"
"{ \"name\": \"lastplayed\", \"$ref\": \"Optional.String\" },"
"{ \"name\": \"thumbnail\", \"$ref\": \"Optional.String\" },"
- "{ \"name\": \"fanart\", \"$ref\": \"Optional.String\" }"
+ "{ \"name\": \"fanart\", \"$ref\": \"Optional.String\" },"
+ "{ \"name\": \"tag\", \"type\": [ \"null\", { \"$ref\": \"Array.String\", \"required\": true } ], \"default\": null }"
"],"
"\"returns\": \"string\""
"}",
View
10 xbmc/interfaces/json-rpc/VideoLibrary.cpp
@@ -170,6 +170,8 @@ JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLay
videoUrl.AddOption("actor", filter["actor"].asString());
else if (filter.isMember("studio"))
videoUrl.AddOption("studio", filter["studio"].asString());
+ else if (filter.isMember("tag"))
+ videoUrl.AddOption("tag", filter["tag"].asString());
else if (filter.isObject())
{
CStdString xsp;
@@ -180,14 +182,14 @@ JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLay
}
CFileItemList items;
- if (!videodatabase.GetTvShowsNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, sorting))
+ if (!videodatabase.GetTvShowsNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, sorting))
return InvalidParams;
bool additionalInfo = false;
for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
{
CStdString fieldValue = itr->asString();
- if (fieldValue == "cast")
+ if (fieldValue == "cast" || fieldValue == "tag")
additionalInfo = true;
}
@@ -351,6 +353,8 @@ JSONRPC_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITranspor
videoUrl.AddOption("director", filter["director"].asString());
else if (filter.isMember("studio"))
videoUrl.AddOption("studio", filter["studio"].asString());
+ else if (filter.isMember("tag"))
+ videoUrl.AddOption("tag", filter["tag"].asString());
else if (filter.isObject())
{
CStdString xsp;
@@ -361,7 +365,7 @@ JSONRPC_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITranspor
}
CFileItemList items;
- if (!videodatabase.GetMusicVideosNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, sorting))
+ if (!videodatabase.GetMusicVideosNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, -1, sorting))
return InternalError;
return GetAdditionalMusicVideoDetails(parameterObject, items, result, videodatabase, false);
View
8 xbmc/interfaces/json-rpc/methods.json
@@ -1051,6 +1051,7 @@
{ "type": "object", "properties": { "year": { "type": "integer", "minimum": 0, "required": true } }, "additionalProperties": false },
{ "type": "object", "properties": { "actor": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
{ "type": "object", "properties": { "studio": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "tag": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
{ "$ref": "List.Filter.TVShows" }
]
}
@@ -1162,6 +1163,7 @@
{ "type": "object", "properties": { "year": { "type": "integer", "minimum": 0, "required": true } }, "additionalProperties": false },
{ "type": "object", "properties": { "director": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
{ "type": "object", "properties": { "studio": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "tag": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
{ "$ref": "List.Filter.MusicVideos" }
]
}
@@ -1326,7 +1328,8 @@
{ "name": "sorttitle", "$ref": "Optional.String" },
{ "name": "episodeguide", "$ref": "Optional.String" },
{ "name": "thumbnail", "$ref": "Optional.String" },
- { "name": "fanart", "$ref": "Optional.String" }
+ { "name": "fanart", "$ref": "Optional.String" },
+ { "name": "tag", "type": [ "null", { "$ref": "Array.String", "required": true } ], "default": null }
],
"returns": "string"
},
@@ -1376,7 +1379,8 @@
{ "name": "track", "$ref": "Optional.Integer" },
{ "name": "lastplayed", "$ref": "Optional.String" },
{ "name": "thumbnail", "$ref": "Optional.String" },
- { "name": "fanart", "$ref": "Optional.String" }
+ { "name": "fanart", "$ref": "Optional.String" },
+ { "name": "tag", "type": [ "null", { "$ref": "Array.String", "required": true } ], "default": null }
],
"returns": "string"
},
View
10 xbmc/interfaces/json-rpc/types.json
@@ -427,7 +427,7 @@
"imdbnumber", "premiered", "votes", "lastplayed",
"fanart", "thumbnail", "file", "originaltitle",
"sorttitle", "episodeguide", "season", "watchedepisodes",
- "dateadded"]
+ "dateadded", "tag" ]
}
},
"Video.Fields.Season": {
@@ -455,7 +455,7 @@
"enum": [ "title", "playcount", "runtime", "director",
"studio", "year", "plot", "album", "artist",
"genre", "track", "streamdetails", "lastplayed",
- "fanart", "thumbnail", "file", "resume", "dateadded" ]
+ "fanart", "thumbnail", "file", "resume", "dateadded", "tag" ]
}
},
"Video.Cast": {
@@ -601,7 +601,8 @@
"premiered": { "type": "string" },
"votes": { "type": "string" },
"episodeguide": { "type": "string" },
- "season": { "type": "integer" }
+ "season": { "type": "integer" },
+ "tag": { "$ref": "Array.String" }
}
},
"Video.Details.Season": {
@@ -640,7 +641,8 @@
"album": { "type": "string" },
"artist": { "$ref": "Array.String" },
"genre": { "$ref": "Array.String" },
- "track": { "type": "integer" }
+ "track": { "type": "integer" },
+ "tag": { "$ref": "Array.String" }
}
},
"Files.Media": {
View
90 xbmc/video/VideoDatabase.cpp
@@ -2077,6 +2077,13 @@ int CVideoDatabase::SetDetailsForTvShow(const CStdString& strPath, const CVideoI
for (i = 0; i < vecStudios.size(); ++i)
AddStudioToTvShow(idTvShow, vecStudios[i]);
+ // add tags...
+ for (unsigned int i = 0; i < details.m_tags.size(); i++)
+ {
+ int idTag = AddTag(details.m_tags[i]);
+ AddTagToItem(idTvShow, idTag, "tvshow");
+ }
+
// add "all seasons" - the rest are added in SetDetailsForEpisode
AddSeason(idTvShow, -1);
@@ -2255,6 +2262,13 @@ int CVideoDatabase::SetDetailsForMusicVideo(const CStdString& strFilenameAndPath
AddStudioToMusicVideo(idMVideo, vecStudios[i]);
}
+ // add tags...
+ for (unsigned int i = 0; i < details.m_tags.size(); i++)
+ {
+ int idTag = AddTag(details.m_tags[i]);
+ AddTagToItem(idMVideo, idTag, "musicvideo");
+ }
+
if (details.HasStreamDetails())
SetStreamDetailsForFileId(details.m_streamDetails, GetFileId(strFilenameAndPath));
@@ -2939,15 +2953,25 @@ void CVideoDatabase::DeleteSet(int idSet)
}
}
-void CVideoDatabase::DeleteTag(int idTag, const std::string &mediaType)
+void CVideoDatabase::DeleteTag(int idTag, VIDEODB_CONTENT_TYPE mediaType)
{
try
{
if (m_pDB.get() == NULL || m_pDS.get() == NULL)
return;
+ std::string type;
+ if (mediaType == VIDEODB_CONTENT_MOVIES)
+ type = "movie";
+ else if (mediaType == VIDEODB_CONTENT_TVSHOWS)
+ type = "tvshow";
+ else if (mediaType == VIDEODB_CONTENT_MUSICVIDEOS)
+ type = "musicvideo";
+ else
+ return;
+
CStdString strSQL;
- strSQL = PrepareSQL("DELETE FROM taglinks WHERE idTag = %i AND media_type = '%s'", idTag, mediaType.c_str());
+ strSQL = PrepareSQL("DELETE FROM taglinks WHERE idTag = %i AND media_type = '%s'", idTag, type.c_str());
m_pDS->exec(strSQL.c_str());
// check if the tag is used for another media type as well before deleting it completely
@@ -3242,6 +3266,15 @@ CVideoInfoTag CVideoDatabase::GetDetailsForTvShow(const dbiplus::sql_record* con
{
GetCast("tvshow", "idShow", details.m_iDbId, details.m_cast);
+ // get tags
+ CStdString strSQL = PrepareSQL("SELECT tag.strTag FROM tag, taglinks WHERE taglinks.idMedia = %i AND taglinks.media_type = 'tvshow' AND taglinks.idTag = tag.idTag ORDER BY tag.idTag", idTvShow);
+ m_pDS2->query(strSQL.c_str());
+ while (!m_pDS2->eof())
+ {
+ details.m_tags.push_back(m_pDS2->fv("tag.strTag").get_asString());
+ m_pDS2->next();
+ }
+
castTime += XbmcThreads::SystemClockMillis() - time; time = XbmcThreads::SystemClockMillis();
details.m_strPictureURL.Parse();
}
@@ -3313,10 +3346,10 @@ CVideoInfoTag CVideoDatabase::GetDetailsForMusicVideo(const dbiplus::sql_record*
CVideoInfoTag details;
unsigned int time = XbmcThreads::SystemClockMillis();
- int idMovie = record->at(0).get_asInt();
+ int idMVideo = record->at(0).get_asInt();
GetDetailsFromDB(record, VIDEODB_ID_MUSICVIDEO_MIN, VIDEODB_ID_MUSICVIDEO_MAX, DbMusicVideoOffsets, details);
- details.m_iDbId = idMovie;
+ details.m_iDbId = idMVideo;
details.m_type = "musicvideo";
details.m_iFileId = record->at(VIDEODB_DETAILS_FILEID).get_asInt();
@@ -3332,6 +3365,15 @@ CVideoInfoTag CVideoDatabase::GetDetailsForMusicVideo(const dbiplus::sql_record*
movieTime += XbmcThreads::SystemClockMillis() - time; time = XbmcThreads::SystemClockMillis();
+ // get tags
+ CStdString strSQL = PrepareSQL("SELECT tag.strTag FROM tag, taglinks WHERE taglinks.idMedia = %i AND taglinks.media_type = 'musicvideo' AND taglinks.idTag = tag.idTag ORDER BY tag.idTag", idMVideo);
+ m_pDS2->query(strSQL.c_str());
+ while (!m_pDS2->eof())
+ {
+ details.m_tags.push_back(m_pDS2->fv("tag.strTag").get_asString());
+ m_pDS2->next();
+ }
+
details.m_strPictureURL.Parse();
return details;
}
@@ -4550,6 +4592,10 @@ bool CVideoDatabase::GetTagsNav(const CStdString& strBaseDir, CFileItemList& ite
CStdString mediaType;
if (idContent == VIDEODB_CONTENT_MOVIES)
mediaType = "movie";
+ else if (idContent == VIDEODB_CONTENT_TVSHOWS)
+ mediaType = "tvshow";
+ else if (idContent == VIDEODB_CONTENT_MUSICVIDEOS)
+ mediaType = "musicvideo";
else
return false;
@@ -5657,7 +5703,7 @@ bool CVideoDatabase::GetMoviesByWhere(const CStdString& strBaseDir, const Filter
}
bool CVideoDatabase::GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items,
- int idGenre /* = -1 */, int idYear /* = -1 */, int idActor /* = -1 */, int idDirector /* = -1 */, int idStudio /* = -1 */,
+ int idGenre /* = -1 */, int idYear /* = -1 */, int idActor /* = -1 */, int idDirector /* = -1 */, int idStudio /* = -1 */, int idTag /* = -1 */,
const SortDescription &sortDescription /* = SortDescription() */)
{
CVideoDbUrl videoUrl;
@@ -5674,6 +5720,8 @@ bool CVideoDatabase::GetTvShowsNav(const CStdString& strBaseDir, CFileItemList&
videoUrl.AddOption("year", idYear);
else if (idActor != -1)
videoUrl.AddOption("actorid", idActor);
+ else if (idTag != -1)
+ videoUrl.AddOption("tagid", idTag);
Filter filter;
return GetTvShowsByWhere(videoUrl.ToString(), filter, items, sortDescription);
@@ -6079,7 +6127,7 @@ bool CVideoDatabase::GetEpisodesByWhere(const CStdString& strBaseDir, const Filt
return false;
}
-bool CVideoDatabase::GetMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre, int idYear, int idArtist, int idDirector, int idStudio, int idAlbum, const SortDescription &sortDescription /* = SortDescription() */)
+bool CVideoDatabase::GetMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre, int idYear, int idArtist, int idDirector, int idStudio, int idAlbum, int idTag /* = -1 */, const SortDescription &sortDescription /* = SortDescription() */)
{
CVideoDbUrl videoUrl;
if (!videoUrl.FromString(strBaseDir))
@@ -6095,6 +6143,8 @@ bool CVideoDatabase::GetMusicVideosNav(const CStdString& strBaseDir, CFileItemLi
videoUrl.AddOption("year", idYear);
else if (idArtist != -1)
videoUrl.AddOption("artistid", idArtist);
+ else if (idTag != -1)
+ videoUrl.AddOption("tagid", idTag);
if (idAlbum != -1)
videoUrl.AddOption("albumid", idAlbum);
@@ -8994,6 +9044,20 @@ bool CVideoDatabase::GetFilter(const CDbUrl &videoUrl, Filter &filter)
filter.AppendJoin(PrepareSQL("join actorlinktvshow on actorlinktvshow.idShow = tvshowview.idShow join actors on actors.idActor = actorlinktvshow.idActor"));
filter.AppendWhere(PrepareSQL("actors.strActor like '%s'", option->second.asString().c_str()));
}
+
+ option = options.find("tagid");
+ if (option != options.end())
+ {
+ filter.AppendJoin(PrepareSQL("join taglinks on taglinks.idMedia = tvshowview.idShow AND taglinks.media_type = 'tvshow'"));
+ filter.AppendWhere(PrepareSQL("taglinks.idTag = %i", (int)option->second.asInteger()));
+ }
+
+ option = options.find("tag");
+ if (option != options.end())
+ {
+ filter.AppendJoin(PrepareSQL("join taglinks on taglinks.idMedia = tvshowview.idShow AND taglinks.media_type = 'tvshow' join tag on tag.idTag = taglinks.idTag"));
+ filter.AppendWhere(PrepareSQL("tag.strTag like '%s'", option->second.asString().c_str()));
+ }
}
else if (itemType == "seasons")
{
@@ -9195,6 +9259,20 @@ bool CVideoDatabase::GetFilter(const CDbUrl &videoUrl, Filter &filter)
option = options.find("albumid");
if (option != options.end())
filter.AppendWhere(PrepareSQL("musicvideoview.c%02d = (select c%02d from musicvideo where idMVideo = %i)", VIDEODB_ID_MUSICVIDEO_ALBUM, VIDEODB_ID_MUSICVIDEO_ALBUM, (int)option->second.asInteger()));
+
+ option = options.find("tagid");
+ if (option != options.end())
+ {
+ filter.AppendJoin(PrepareSQL("join taglinks on taglinks.idMedia = musicvideoview.idMVideo AND taglinks.media_type = 'musicvideo'"));
+ filter.AppendWhere(PrepareSQL("taglinks.idTag = %i", (int)option->second.asInteger()));
+ }
+
+ option = options.find("tag");
+ if (option != options.end())
+ {
+ filter.AppendJoin(PrepareSQL("join taglinks on taglinks.idMedia = musicvideoview.idMVideo AND taglinks.media_type = 'musicvideo' join tag on tag.idTag = taglinks.idTag"));
+ filter.AppendWhere(PrepareSQL("tag.strTag like '%s'", option->second.asString().c_str()));
+ }
}
else
return false;
View
6 xbmc/video/VideoDatabase.h
@@ -459,7 +459,7 @@ class CVideoDatabase : public CDatabase
void RemoveContentForPath(const CStdString& strPath,CGUIDialogProgress *progress = NULL);
void UpdateFanart(const CFileItem &item, VIDEODB_CONTENT_TYPE type);
void DeleteSet(int idSet);
- void DeleteTag(int idTag, const std::string &mediaType);
+ void DeleteTag(int idTag, VIDEODB_CONTENT_TYPE mediaType);
// per-file video settings
bool GetVideoSettings(const CStdString &strFilenameAndPath, CVideoSettings &settings);
@@ -589,10 +589,10 @@ class CVideoDatabase : public CDatabase
bool GetMusicVideoAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, int idArtist, const Filter &filter = Filter());
bool GetMoviesNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1, int idCountry=-1, int idSet=-1, int idTag=-1, const SortDescription &sortDescription = SortDescription());
- bool GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1, const SortDescription &sortDescription = SortDescription());
+ bool GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1, int idTag=-1, const SortDescription &sortDescription = SortDescription());
bool GetSeasonsNav(const CStdString& strBaseDir, CFileItemList& items, int idActor=-1, int idDirector=-1, int idGenre=-1, int idYear=-1, int idShow=-1);
bool GetEpisodesNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idShow=-1, int idSeason=-1, const SortDescription &sortDescription = SortDescription());
- bool GetMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idArtist=-1, int idDirector=-1, int idStudio=-1, int idAlbum=-1, const SortDescription &sortDescription = SortDescription());
+ bool GetMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idArtist=-1, int idDirector=-1, int idStudio=-1, int idAlbum=-1, int idTag=-1, const SortDescription &sortDescription = SortDescription());
bool GetRecentlyAddedMoviesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
bool GetRecentlyAddedEpisodesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
View
119 xbmc/video/windows/GUIWindowVideoNav.cpp
@@ -227,6 +227,8 @@ CStdString CGUIWindowVideoNav::GetQuickpathName(const CStdString& strPath) const
return "TvShowYears";
else if (strPath.Equals("videodb://2/4/"))
return "TvShowActors";
+ else if (strPath.Equals("videodb://2/9/"))
+ return "TvShowTags";
else if (strPath.Equals("videodb://2/"))
return "TvShows";
else if (strPath.Equals("videodb://3/1/"))
@@ -239,6 +241,8 @@ CStdString CGUIWindowVideoNav::GetQuickpathName(const CStdString& strPath) const
return "MusicVideoArtists";
else if (strPath.Equals("videodb://3/5/"))
return "MusicVideoDirectors";
+ else if (strPath.Equals("videodb://3/9/"))
+ return "MusicVideoTags";
else if (strPath.Equals("videodb://3/"))
return "MusicVideos";
else if (strPath.Equals("videodb://4/"))
@@ -365,9 +369,11 @@ bool CGUIWindowVideoNav::GetDirectory(const CStdString &strDirectory, CFileItemL
LoadVideoInfo(items);
}
- if (items.GetPath() == "videodb://1/9/" && !items.Contains("newtag://movie"))
+ CVideoDbUrl videoUrl;
+ if (videoUrl.FromString(items.GetPath()) && items.GetContent() == "tags" &&
+ !items.Contains("newtag://" + videoUrl.GetType()))
{
- CFileItemPtr newTag(new CFileItem("newtag://movie", false));
+ CFileItemPtr newTag(new CFileItem("newtag://" + videoUrl.GetType(), false));
newTag->SetLabel(g_localizeStrings.Get(20462));
newTag->SetLabelPreformated(true);
newTag->SetSpecialSort(SortSpecialOnTop);
@@ -672,22 +678,22 @@ void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
m_database.DeleteSet(params.GetSetId());
}
}
- else if (pItem->GetPath().Left(14).Equals("videodb://1/9/") &&
+ else if (m_vecItems->GetContent() == "tags" &&
pItem->GetPath().size() > 14 && pItem->m_bIsFolder)
{
CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
pDialog->SetHeading(432);
CStdString strLabel;
- strLabel.Format(g_localizeStrings.Get(433),pItem->GetLabel());
+ strLabel.Format(g_localizeStrings.Get(433), pItem->GetLabel());
pDialog->SetLine(1, strLabel);
- pDialog->SetLine(2, "");;
+ pDialog->SetLine(2, "");
pDialog->DoModal();
if (pDialog->IsConfirmed())
{
CVideoDatabaseDirectory dir;
CQueryParams params;
dir.GetQueryParams(pItem->GetPath(), params);
- m_database.DeleteTag(params.GetTagId(), "movie");
+ m_database.DeleteTag(params.GetTagId(), (VIDEODB_CONTENT_TYPE)params.GetContentType());
}
}
else if (m_vecItems->GetPath().Equals(CUtil::VideoPlaylistsLocation()) ||
@@ -966,13 +972,19 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
buttons.Add(CONTEXT_BUTTON_DELETE, 646);
}
- if (item->GetPath().Left(14).Equals("videodb://1/9/") && item->GetPath().size() > 14 && item->m_bIsFolder) // tags
+ if (m_vecItems->GetContent() == "tags" && item->GetPath().size() > 14 && item->m_bIsFolder) // tags
{
- CStdString strLabelAdd; strLabelAdd.Format(g_localizeStrings.Get(20460), g_localizeStrings.Get(20342).c_str());
- CStdString strLabelRemove; strLabelRemove.Format(g_localizeStrings.Get(20461), g_localizeStrings.Get(20342).c_str());
- buttons.Add(CONTEXT_BUTTON_TAGS_ADD_ITEMS, strLabelAdd);
- buttons.Add(CONTEXT_BUTTON_TAGS_REMOVE_ITEMS, strLabelRemove);
- buttons.Add(CONTEXT_BUTTON_DELETE, 646);
+ CVideoDbUrl videoUrl;
+ if (videoUrl.FromString(item->GetPath()))
+ {
+ std::string mediaType = videoUrl.GetItemType();
+
+ CStdString strLabelAdd; strLabelAdd.Format(g_localizeStrings.Get(20460), GetLocalizedType(videoUrl.GetItemType()).c_str());
+ CStdString strLabelRemove; strLabelRemove.Format(g_localizeStrings.Get(20461), GetLocalizedType(videoUrl.GetItemType()).c_str());
+ buttons.Add(CONTEXT_BUTTON_TAGS_ADD_ITEMS, strLabelAdd);
+ buttons.Add(CONTEXT_BUTTON_TAGS_REMOVE_ITEMS, strLabelRemove);
+ buttons.Add(CONTEXT_BUTTON_DELETE, 646);
+ }
}
if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder)
@@ -1248,14 +1260,12 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
}
case CONTEXT_BUTTON_TAGS_ADD_ITEMS:
{
- if (!item->GetPath().Left(10).Equals("videodb://"))
+ CVideoDbUrl videoUrl;
+ if (!videoUrl.FromString(item->GetPath()))
return false;
- std::string mediaType;
- if (item->GetPath().Mid(9, 3).Equals("/1/"))
- mediaType = "movie";
- else
- return false;
+ std::string mediaType = videoUrl.GetItemType();
+ mediaType = mediaType.substr(0, mediaType.length() - 1);
CFileItemList items;
CStdString localizedType = GetLocalizedType(mediaType);
@@ -1282,14 +1292,12 @@ bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
}
case CONTEXT_BUTTON_TAGS_REMOVE_ITEMS:
{
- if (!item->GetPath().Left(10).Equals("videodb://"))
+ CVideoDbUrl videoUrl;
+ if (!videoUrl.FromString(item->GetPath()))
return false;
- std::string mediaType;
- if (item->GetPath().Mid(9, 3).Equals("/1/"))
- mediaType = "movie";
- else
- return false;
+ std::string mediaType = videoUrl.GetItemType();
+ mediaType = mediaType.substr(0, mediaType.length() - 1);
CFileItemList items;
CStdString localizedType = GetLocalizedType(mediaType);
@@ -1469,15 +1477,17 @@ bool CGUIWindowVideoNav::OnClick(int iItem)
if (!videodb.Open())
return true;
+ // get the media type and convert from plural to singular (by removing the trailing "s")
CStdString mediaType = item->GetPath().Mid(9);
+ mediaType = mediaType.Left(mediaType.size() - 1);
CStdString localizedType = GetLocalizedType(mediaType);
if (localizedType.empty())
return true;
if (!videodb.GetSingleValue("tag", "tag.idTag", videodb.PrepareSQL("tag.strTag = '%s' AND tag.idTag IN (SELECT taglinks.idTag FROM taglinks WHERE taglinks.media_type = '%s')", strTag.c_str(), mediaType.c_str())).empty())
{
CStdString strError; strError.Format(g_localizeStrings.Get(20463), strTag.c_str());
- CGUIDialogOK::ShowAndGetInput(20462, strError, "", "");
+ CGUIDialogOK::ShowAndGetInput(20462, "", strError, "");
return true;
}
@@ -1535,6 +1545,8 @@ CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
return "videodb://2/4/";
else if (dir.Equals("TvShowStudios"))
return "videodb://2/5/";
+ else if (dir.Equals("TvShowTags"))
+ return "videodb://2/9/";
else if (dir.Equals("TvShows"))
return "videodb://2/";
else if (dir.Equals("MusicVideoGenres"))
@@ -1551,6 +1563,8 @@ CStdString CGUIWindowVideoNav::GetStartFolder(const CStdString &dir)
return "videodb://3/6/";
else if (dir.Equals("MusicVideoStudios"))
return "videodb://3/7/";
+ else if (dir.Equals("MusicVideoTags"))
+ return "videodb://3/9/";
else if (dir.Equals("MusicVideos"))
return "videodb://3/";
else if (dir.Equals("RecentlyAddedMovies"))
@@ -1635,23 +1649,44 @@ bool CGUIWindowVideoNav::GetItemsForTag(const CStdString &strHeading, const std:
if (!videodb.Open())
return false;
- CFileItemList listItems;
- bool result = false;
- if (idTag <= 0)
- result = videodb.GetMoviesNav("videodb://1/2/", listItems);
- else
+ MediaType mediaType;
+ std::string baseDir = "videodb://";
+ std::string idColumn;
+ if (type.compare("movie") == 0)
{
- if (showAll)
- {
- CVideoDatabase::Filter filter;
- filter.where = videodb.PrepareSQL("movieview.idMovie NOT IN (SELECT taglinks.idMedia FROM taglinks WHERE taglinks.idTag = %d AND taglinks.media_type = '%s')", idTag, type.c_str());
- result = videodb.GetMoviesByWhere("videodb://1/2/", filter, listItems);
- }
+ mediaType = MediaTypeMovie;
+ baseDir += "1";
+ idColumn = "idMovie";
+ }
+ else if (type.compare("tvshow") == 0)
+ {
+ mediaType = MediaTypeTvShow;
+ baseDir += "2";
+ idColumn = "idShow";
+ }
+ else if (type.compare("musicvideo") == 0)
+ {
+ mediaType = MediaTypeMusicVideo;
+ baseDir += "3";
+ idColumn = "idMVideo";
+ }
+
+ baseDir += "/2/";
+ CVideoDbUrl videoUrl;
+ if (!videoUrl.FromString(baseDir))
+ return false;
+
+ CVideoDatabase::Filter filter;
+ if (idTag > 0)
+ {
+ if (!showAll)
+ videoUrl.AddOption("tagid", idTag);
else
- result = videodb.GetMoviesNav("videodb://1/9/", listItems, -1, -1, -1, -1, -1, -1, -1, idTag);
+ filter.where = videodb.PrepareSQL("%sview.%s NOT IN (SELECT taglinks.idMedia FROM taglinks WHERE taglinks.idTag = %d AND taglinks.media_type = '%s')", type.c_str(), idColumn.c_str(), idTag, type.c_str());
}
- if (!result || listItems.Size() <= 0)
+ CFileItemList listItems;
+ if (!videodb.GetSortedVideos(mediaType, videoUrl.ToString(), SortDescription(), listItems, filter) || listItems.Size() <= 0)
return false;
CGUIDialogSelect *dialog = (CGUIDialogSelect *)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
@@ -1673,13 +1708,13 @@ bool CGUIWindowVideoNav::GetItemsForTag(const CStdString &strHeading, const std:
CStdString CGUIWindowVideoNav::GetLocalizedType(const std::string &strType)
{
- if (strType == "movie")
+ if (strType == "movie" || strType == "movies")
return g_localizeStrings.Get(20342);
- else if (strType == "tvshow")
+ else if (strType == "tvshow" || strType == "tvshows")
return g_localizeStrings.Get(20343);
- else if (strType == "episode")
+ else if (strType == "episode" || strType == "episodes")
return g_localizeStrings.Get(20359);
- else if (strType == "musicvideo")
+ else if (strType == "musicvideo" || strType == "musicvideos")
return g_localizeStrings.Get(20391);
else
return "";
Something went wrong with that request. Please try again.