Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Tagging support for tvshows and musicvideos #1400

Merged
merged 3 commits into from

2 participants

@Montellese
Owner

A while ago I added tags for movies as a replacement for sets as we added a limitation that every movie can only be part of one set. This PR extends the tagging support to tvshows and musicvideos and includes some refactoring of the code in CGUIWindowVideoNav to make it more general (i.e. work for movies, tvshows and musicvideos).

@jmarshallnz
Owner

There's an unrelated gnu address change there but otherwise all good.

@Montellese
Owner

@jmarshallnz Thanks for the hint. I removed it as it's already in master anyway.

@Montellese Montellese was assigned
@Montellese Montellese merged commit 9f0b31c into from
@tru tru referenced this pull request from a commit in plexinc/plex-home-theater-public
@tru tru Default to the current use in the switch user dialog.
Fixes #1400
730d283
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
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,7 +1477,9 @@ 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;
@@ -1477,7 +1487,7 @@ bool CGUIWindowVideoNav::OnClick(int iItem)
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.