Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Cached video art updating for Eden->Frodo #1618

Merged
5 commits merged into from

1 participant

@jmarshallnz
Owner

The Oct14 commits are all that matters - depends on #1609.

The current solution for Eden->Frodo art update is a backward compatibility routine that essentially re-downloads (or re-caches if the user has local art) each piece of art. It can screw up if the URLs stored in the video database are stale (e.g. themoviedb.org changes their URL layout a couple years ago).

Also, it places an unreasonable burden on our good friends at thetvdb.org and themoviedb.com.

We thus instead have a threaded updater that goes and grabs the previously cached art for an item (by resurrecting the old thumbnail crc code) and copies that as the cached art for the original artwork (local or online), flagging the image as "don't check for updates".

This is IMO the nicest way we can do it for Eden users updating to Frodo.

The only additional thing we could consider would be also checking the aspect ratio of the image and assigning to poster or banner (for shows). IMO this really isn't needed, as the user is only going to have one or the other, and skins should be falling back to the thumb image anyway.

@cptspiff: This introduces a significant chunk of code, but it is clearly split off from the rest, so will be easy to remove for Frodo+1.

@ghost ghost merged commit d2f4278 into xbmc:master
@jmarshallnz

Only that it broke if I pulled out a random header somewhere ;) I doubt it's too bad actually, as VideoInfoScanner.h is only about 12 files.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 15, 2012
  1. factor out CVideoInfoScanner::GetFanart for re-use

    Jonathan Marshall authored
  2. adds backward compatibility art updater for Eden->Frodo

    Jonathan Marshall authored
  3. remove FileItem.h header requirement from VideoInfoScanner

    Jonathan Marshall authored
  4. remove no longer necessary backward compatibility for video art in th…

    Jonathan Marshall authored
    …e video thumb loader
This page is out of date. Refresh to see the latest.
View
6 XBMC-ATV2.xcodeproj/project.pbxproj
@@ -44,6 +44,7 @@
7C99B7AA134072CD00FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7A8134072CD00FC2B16 /* GUIDialogPlayEject.cpp */; };
7CC30DF2162925BE003E7579 /* MusicThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30DF0162925BE003E7579 /* MusicThumbLoader.cpp */; };
7CC30E1A16292627003E7579 /* VideoThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E1816292627003E7579 /* VideoThumbLoader.cpp */; };
+ 7CC3105D162AAF9B003E7579 /* EdenVideoArtUpdater.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC3105B162AAF9B003E7579 /* EdenVideoArtUpdater.cpp */; };
7CCFD9AA1514952700211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD9A81514952700211D82 /* PCMCodec.cpp */; };
7CEE2E6D13D6B7A8000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E6B13D6B7A8000ABF2A /* TimeSmoother.cpp */; };
C807119F135DB842002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C807119D135DB842002F601B /* InputOperations.cpp */; };
@@ -1069,6 +1070,8 @@
7CC30DF1162925BE003E7579 /* MusicThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicThumbLoader.h; sourceTree = "<group>"; };
7CC30E1816292627003E7579 /* VideoThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoThumbLoader.cpp; sourceTree = "<group>"; };
7CC30E1916292627003E7579 /* VideoThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoThumbLoader.h; sourceTree = "<group>"; };
+ 7CC3105B162AAF9B003E7579 /* EdenVideoArtUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdenVideoArtUpdater.cpp; sourceTree = "<group>"; };
+ 7CC3105C162AAF9B003E7579 /* EdenVideoArtUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdenVideoArtUpdater.h; sourceTree = "<group>"; };
7CCFD9A81514952700211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; };
7CCFD9A91514952700211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; };
7CEE2E6B13D6B7A8000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = "<group>"; };
@@ -5680,6 +5683,8 @@
F56C772E131EC154000AD0F6 /* DownloadQueue.h */,
F56C772F131EC154000AD0F6 /* DownloadQueueManager.cpp */,
F56C7730131EC154000AD0F6 /* DownloadQueueManager.h */,
+ 7CC3105B162AAF9B003E7579 /* EdenVideoArtUpdater.cpp */,
+ 7CC3105C162AAF9B003E7579 /* EdenVideoArtUpdater.h */,
F56C7731131EC154000AD0F6 /* EndianSwap.h */,
F56C7732131EC154000AD0F6 /* Fanart.cpp */,
F56C7733131EC154000AD0F6 /* Fanart.h */,
@@ -7564,6 +7569,7 @@
F592D4C2162496620023BCE7 /* NptHash.cpp in Sources */,
7CC30DF2162925BE003E7579 /* MusicThumbLoader.cpp in Sources */,
7CC30E1A16292627003E7579 /* VideoThumbLoader.cpp in Sources */,
+ 7CC3105D162AAF9B003E7579 /* EdenVideoArtUpdater.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
6 XBMC-IOS.xcodeproj/project.pbxproj
@@ -45,6 +45,7 @@
7C99B7BE1340730000FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7BC1340730000FC2B16 /* GUIDialogPlayEject.cpp */; };
7CC30E04162925E6003E7579 /* MusicThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E02162925E6003E7579 /* MusicThumbLoader.cpp */; };
7CC30E0716292601003E7579 /* VideoThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E0516292601003E7579 /* VideoThumbLoader.cpp */; };
+ 7CC3106F162AAFE3003E7579 /* EdenVideoArtUpdater.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC3106D162AAFE3003E7579 /* EdenVideoArtUpdater.cpp */; };
7CCFD9991514950700211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD9971514950700211D82 /* PCMCodec.cpp */; };
7CEE2E7F13D6B7D4000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E7D13D6B7D4000ABF2A /* TimeSmoother.cpp */; };
C80711AD135DB85F002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C80711AB135DB85F002F601B /* InputOperations.cpp */; };
@@ -1071,6 +1072,8 @@
7CC30E03162925E6003E7579 /* MusicThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicThumbLoader.h; sourceTree = "<group>"; };
7CC30E0516292601003E7579 /* VideoThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoThumbLoader.cpp; sourceTree = "<group>"; };
7CC30E0616292601003E7579 /* VideoThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoThumbLoader.h; sourceTree = "<group>"; };
+ 7CC3106D162AAFE3003E7579 /* EdenVideoArtUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdenVideoArtUpdater.cpp; sourceTree = "<group>"; };
+ 7CC3106E162AAFE3003E7579 /* EdenVideoArtUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdenVideoArtUpdater.h; sourceTree = "<group>"; };
7CCFD9971514950700211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; };
7CCFD9981514950700211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; };
7CEE2E7D13D6B7D4000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = "<group>"; };
@@ -6046,6 +6049,8 @@
F56C871D131F42EC000AD0F6 /* DownloadQueue.h */,
F56C871E131F42EC000AD0F6 /* DownloadQueueManager.cpp */,
F56C871F131F42EC000AD0F6 /* DownloadQueueManager.h */,
+ 7CC3106D162AAFE3003E7579 /* EdenVideoArtUpdater.cpp */,
+ 7CC3106E162AAFE3003E7579 /* EdenVideoArtUpdater.h */,
F56C8720131F42EC000AD0F6 /* EndianSwap.h */,
F56C8721131F42EC000AD0F6 /* Fanart.cpp */,
F56C8722131F42EC000AD0F6 /* Fanart.h */,
@@ -7589,6 +7594,7 @@
36A95DAD1624896C00727135 /* GUIDialogMediaFilter.cpp in Sources */,
7CC30E04162925E6003E7579 /* MusicThumbLoader.cpp in Sources */,
7CC30E0716292601003E7579 /* VideoThumbLoader.cpp in Sources */,
+ 7CC3106F162AAFE3003E7579 /* EdenVideoArtUpdater.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
6 XBMC.xcodeproj/project.pbxproj
@@ -286,6 +286,7 @@
7CBEBB8412912BA400431822 /* fstrcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 7CBEBB8212912BA300431822 /* fstrcmp.c */; };
7CC30DB116291A5C003E7579 /* MusicThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30DAF16291A5C003E7579 /* MusicThumbLoader.cpp */; };
7CC30DC016291C2C003E7579 /* VideoThumbLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30DBE16291C2C003E7579 /* VideoThumbLoader.cpp */; };
+ 7CC30E8A16296078003E7579 /* EdenVideoArtUpdater.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC30E8816296078003E7579 /* EdenVideoArtUpdater.cpp */; };
7CCF7E721067643800992676 /* DirectoryNodeSets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7E701067643800992676 /* DirectoryNodeSets.cpp */; };
7CCF7F1D1069F3AE00992676 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7F1B1069F3AE00992676 /* Builtins.cpp */; };
7CCF7FC9106A0DF500992676 /* TimeUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7FC7106A0DF500992676 /* TimeUtils.cpp */; };
@@ -1601,6 +1602,8 @@
7CC30DB016291A5C003E7579 /* MusicThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicThumbLoader.h; sourceTree = "<group>"; };
7CC30DBE16291C2C003E7579 /* VideoThumbLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoThumbLoader.cpp; sourceTree = "<group>"; };
7CC30DBF16291C2C003E7579 /* VideoThumbLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoThumbLoader.h; sourceTree = "<group>"; };
+ 7CC30E8816296078003E7579 /* EdenVideoArtUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdenVideoArtUpdater.cpp; sourceTree = "<group>"; };
+ 7CC30E8916296078003E7579 /* EdenVideoArtUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdenVideoArtUpdater.h; sourceTree = "<group>"; };
7CCF7E701067643800992676 /* DirectoryNodeSets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryNodeSets.cpp; sourceTree = "<group>"; };
7CCF7E711067643800992676 /* DirectoryNodeSets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryNodeSets.h; sourceTree = "<group>"; };
7CCF7F1B1069F3AE00992676 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Builtins.cpp; sourceTree = "<group>"; };
@@ -6080,6 +6083,8 @@
E38E1E320D25F9FD00618676 /* DownloadQueue.h */,
E38E1E330D25F9FD00618676 /* DownloadQueueManager.cpp */,
E38E1E340D25F9FD00618676 /* DownloadQueueManager.h */,
+ 7CC30E8816296078003E7579 /* EdenVideoArtUpdater.cpp */,
+ 7CC30E8916296078003E7579 /* EdenVideoArtUpdater.h */,
436B38F3106628850049AB3B /* EndianSwap.h */,
E36C29E90DA72486001F0C9D /* Fanart.cpp */,
6E97BDC30DA2B620003A2A89 /* Fanart.h */,
@@ -7622,6 +7627,7 @@
36A95DA51624894400727135 /* GUIDialogMediaFilter.cpp in Sources */,
7CC30DB116291A5C003E7579 /* MusicThumbLoader.cpp in Sources */,
7CC30DC016291C2C003E7579 /* VideoThumbLoader.cpp in Sources */,
+ 7CC30E8A16296078003E7579 /* EdenVideoArtUpdater.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
27 language/English/strings.po
@@ -3796,13 +3796,36 @@ msgctxt "#12348"
msgid "Item locked"
msgstr ""
-#empty strings from id 12349 to 12352
+#: xbmc/utils/EdenVideoArtUpdater.cpp
+msgctxt "#12349"
+msgid "Updating video library art"
+msgstr ""
+
+#: xbmc/utils/EdenVideoArtUpdater.cpp
+msgctxt "#12350"
+msgid "Processing %s"
+msgstr ""
+
+#: xbmc/video/windows/GUIWindowVideoBase.cpp
+msgctxt "#12351"
+msgid "The art cache in your video library needs updating."
+msgstr ""
+
+#: xbmc/video/windows/GUIWindowVideoBase.cpp
+msgctxt "#12352"
+msgid "No downloading is needed."
+msgstr ""
msgctxt "#12353"
msgid "Reactivate lock"
msgstr ""
-#empty strings from id 12354 to 12355
+#: xbmc/video/windows/GUIWindowVideoBase.cpp
+msgctxt "#12354"
+msgid "Would you like to update it now?"
+msgstr ""
+
+#empty strings with id 12355
msgctxt "#12356"
msgid "Change lock"
View
2  project/VS2010Express/XBMC.vcxproj
@@ -1220,6 +1220,7 @@
<ClCompile Include="..\..\xbmc\utils\DatabaseUtils.cpp" />
<ClCompile Include="..\..\xbmc\utils\DownloadQueue.cpp" />
<ClCompile Include="..\..\xbmc\utils\DownloadQueueManager.cpp" />
+ <ClCompile Include="..\..\xbmc\utils\EdenVideoArtUpdater.cpp" />
<ClCompile Include="..\..\xbmc\utils\EndianSwap.cpp" />
<ClCompile Include="..\..\xbmc\utils\Fanart.cpp" />
<ClCompile Include="..\..\xbmc\utils\fft.cpp" />
@@ -2371,6 +2372,7 @@
<ClInclude Include="..\..\xbmc\utils\DatabaseUtils.h" />
<ClInclude Include="..\..\xbmc\utils\DownloadQueue.h" />
<ClInclude Include="..\..\xbmc\utils\DownloadQueueManager.h" />
+ <ClInclude Include="..\..\xbmc\utils\EdenVideoArtUpdater.h" />
<ClInclude Include="..\..\xbmc\utils\EndianSwap.h" />
<ClInclude Include="..\..\xbmc\utils\Fanart.h" />
<ClInclude Include="..\..\xbmc\utils\fft.h" />
View
6 project/VS2010Express/XBMC.vcxproj.filters
@@ -2581,6 +2581,9 @@
<ClCompile Include="..\..\xbmc\filesystem\VideoDatabaseDirectory\DirectoryNodeTags.cpp">
<Filter>filesystem\VideoDatabaseDirectory</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\utils\EdenVideoArtUpdater.cpp">
+ <Filter>utils</Filter>
+ </ClCompile>
<ClCompile Include="..\..\xbmc\utils\EndianSwap.cpp">
<Filter>utils</Filter>
</ClCompile>
@@ -4401,6 +4404,9 @@
<ClInclude Include="..\..\xbmc\utils\DownloadQueueManager.h">
<Filter>utils</Filter>
</ClInclude>
+ <ClInclude Include="..\..\xbmc\utils\EdenVideoArtUpdater.h">
+ <Filter>utils</Filter>
+ </ClInclude>
<ClInclude Include="..\..\xbmc\utils\EndianSwap.h">
<Filter>utils</Filter>
</ClInclude>
View
2  xbmc/TextureCacheJob.h
@@ -79,6 +79,8 @@ class CTextureCacheJob : public CJob
CStdString m_oldHash;
CTextureDetails m_details;
private:
+ friend class CEdenVideoArtUpdater;
+
/*! \brief retrieve a hash for the given image
Combines the size, ctime and mtime of the image file into a "unique" hash
\param url location of the image
View
357 xbmc/utils/EdenVideoArtUpdater.cpp
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "EdenVideoArtUpdater.h"
+#include "video/VideoDatabase.h"
+#include "video/VideoInfoScanner.h"
+#include "FileItem.h"
+#include "utils/log.h"
+#include "utils/Crc32.h"
+#include "utils/URIUtils.h"
+#include "utils/ScraperUrl.h"
+#include "utils/StringUtils.h"
+#include "TextureCache.h"
+#include "TextureCacheJob.h"
+#include "pictures/Picture.h"
+#include "settings/GUISettings.h"
+#include "settings/Settings.h"
+#include "settings/AdvancedSettings.h"
+#include "guilib/Texture.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/LocalizeStrings.h"
+#include "filesystem/File.h"
+#include "dialogs/GUIDialogExtendedProgressBar.h"
+
+using namespace std;
+using namespace VIDEO;
+using namespace XFILE;
+
+CEdenVideoArtUpdater::CEdenVideoArtUpdater() : CThread("EdenVideoArtUpdater")
+{
+ m_textureDB.Open();
+}
+
+CEdenVideoArtUpdater::~CEdenVideoArtUpdater()
+{
+ m_textureDB.Close();
+}
+
+void CEdenVideoArtUpdater::Start()
+{
+ CEdenVideoArtUpdater *updater = new CEdenVideoArtUpdater();
+ updater->Create(true); // autodelete
+}
+
+void CEdenVideoArtUpdater::Process()
+{
+ // grab all movies...
+ CVideoDatabase db;
+ if (!db.Open())
+ return;
+
+ CFileItemList items;
+
+ CGUIDialogExtendedProgressBar* dialog =
+ (CGUIDialogExtendedProgressBar*)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS);
+
+ CGUIDialogProgressBarHandle *handle = dialog->GetHandle(g_localizeStrings.Get(314));
+ handle->SetTitle(g_localizeStrings.Get(12349));
+
+ // movies
+ db.GetMoviesByWhere("videodb://1/2/", CDatabase::Filter(), items, false);
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr item = items[i];
+ handle->SetProgress(i, items.Size());
+ handle->SetText(StringUtils::Format(g_localizeStrings.Get(12350).c_str(), item->GetLabel().c_str()));
+ string cachedThumb = GetCachedVideoThumb(*item);
+ string cachedFanart = GetCachedFanart(*item);
+
+ item->SetPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
+ item->GetVideoInfoTag()->m_fanart.Unpack();
+ item->GetVideoInfoTag()->m_strPictureURL.Parse();
+
+ map<string, string> artwork;
+ if (!db.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork))
+ {
+ CStdString art = CVideoInfoScanner::GetImage(item.get(), true, item->GetVideoInfoTag()->m_basePath != item->GetPath(), "thumb");
+ if (!art.empty() && CacheTexture(art, cachedThumb))
+ artwork.insert(make_pair("thumb", art));
+
+ art = CVideoInfoScanner::GetFanart(item.get(), true);
+ if (!art.empty() && CacheTexture(art, cachedFanart))
+ artwork.insert(make_pair("fanart", art));
+
+ if (artwork.empty())
+ artwork.insert(make_pair("thumb", ""));
+ db.SetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork);
+ }
+ }
+ items.Clear();
+
+ // music videos
+ db.GetMusicVideosNav("videodb://3/2/", items, false);
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr item = items[i];
+ handle->SetProgress(i, items.Size());
+ handle->SetText(StringUtils::Format(g_localizeStrings.Get(12350).c_str(), item->GetLabel().c_str()));
+ string cachedThumb = GetCachedVideoThumb(*item);
+ string cachedFanart = GetCachedFanart(*item);
+
+ item->SetPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
+ item->GetVideoInfoTag()->m_fanart.Unpack();
+ item->GetVideoInfoTag()->m_strPictureURL.Parse();
+
+ map<string, string> artwork;
+ if (!db.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork))
+ {
+ CStdString art = CVideoInfoScanner::GetImage(item.get(), true, item->GetVideoInfoTag()->m_basePath != item->GetPath(), "thumb");
+ if (!art.empty() && CacheTexture(art, cachedThumb))
+ artwork.insert(make_pair("thumb", art));
+
+ art = CVideoInfoScanner::GetFanart(item.get(), true);
+ if (!art.empty() && CacheTexture(art, cachedFanart))
+ artwork.insert(make_pair("fanart", art));
+
+ if (artwork.empty())
+ artwork.insert(make_pair("thumb", ""));
+ db.SetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork);
+ }
+ }
+ items.Clear();
+
+ // tvshows
+ // count the number of episodes
+ db.GetTvShowsNav("videodb://3/2/", items);
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr item = items[i];
+ handle->SetText(StringUtils::Format(g_localizeStrings.Get(12350).c_str(), item->GetLabel().c_str()));
+ string cachedThumb = GetCachedVideoThumb(*item);
+ string cachedFanart = GetCachedFanart(*item);
+
+ item->SetPath(item->GetVideoInfoTag()->m_strPath);
+ item->GetVideoInfoTag()->m_fanart.Unpack();
+ item->GetVideoInfoTag()->m_strPictureURL.Parse();
+
+ map<string, string> artwork;
+ if (!db.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork))
+ {
+ CStdString art = CVideoInfoScanner::GetImage(item.get(), true, false, "thumb");
+ if (!art.empty() && CacheTexture(art, cachedThumb))
+ artwork.insert(make_pair("thumb", art));
+
+ art = CVideoInfoScanner::GetFanart(item.get(), true);
+ if (!art.empty() && CacheTexture(art, cachedFanart))
+ artwork.insert(make_pair("fanart", art));
+
+ if (artwork.empty())
+ artwork.insert(make_pair("thumb", ""));
+ db.SetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork);
+ }
+
+ // now season art...
+ map<int, string> seasons;
+ CVideoInfoScanner::GetSeasonThumbs(*item->GetVideoInfoTag(), seasons, true);
+ for (map<int, string>::const_iterator j = seasons.begin(); j != seasons.end(); ++j)
+ {
+ int idSeason = db.AddSeason(item->GetVideoInfoTag()->m_iDbId, j->first);
+ if (!db.GetArtForItem(idSeason, "season", "thumb").empty())
+ {
+ std::string cachedSeason = GetCachedSeasonThumb(j->first, item->GetVideoInfoTag()->m_strPath);
+ if (CacheTexture(j->second, cachedSeason))
+ {
+ if (idSeason > -1)
+ db.SetArtForItem(idSeason, "season", "thumb", j->second);
+ }
+ }
+ }
+
+ // now episodes...
+ CFileItemList items2;
+ db.GetEpisodesByWhere("videodb://2/2/-1/-1/", db.PrepareSQL("episodeview.idShow=%d", item->GetVideoInfoTag()->m_iDbId), items2);
+ for (int j = 0; j < items2.Size(); j++)
+ {
+ handle->SetProgress(j, items2.Size());
+ CFileItemPtr episode = items2[j];
+ string cachedThumb = GetCachedVideoThumb(*episode);
+ episode->SetPath(episode->GetVideoInfoTag()->m_strFileNameAndPath);
+ episode->GetVideoInfoTag()->m_strPictureURL.Parse();
+
+ map<string, string> artwork;
+ if (!db.GetArtForItem(episode->GetVideoInfoTag()->m_iDbId, episode->GetVideoInfoTag()->m_type, artwork))
+ {
+ CStdString art = CVideoInfoScanner::GetImage(episode.get(), true, episode->GetVideoInfoTag()->m_basePath != episode->GetPath(), "thumb");
+ if (!art.empty() && CacheTexture(art, cachedThumb))
+ artwork.insert(make_pair("thumb", art));
+ else
+ artwork.insert(make_pair("thumb", ""));
+ db.SetArtForItem(episode->GetVideoInfoTag()->m_iDbId, episode->GetVideoInfoTag()->m_type, artwork);
+ }
+ }
+ }
+ items.Clear();
+
+ // now sets
+ db.GetSetsNav("videodb://1/7/", items, VIDEODB_CONTENT_MOVIES);
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr item = items[i];
+ handle->SetProgress(i, items.Size());
+ handle->SetText(StringUtils::Format(g_localizeStrings.Get(12350).c_str(), item->GetLabel().c_str()));
+ map<string, string> artwork;
+ if (!db.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork))
+ { // grab the first movie from this set
+ CFileItemList items2;
+ db.GetMoviesNav("videodb://1/2/", items2, -1, -1, -1, -1, -1, -1, item->GetVideoInfoTag()->m_iDbId);
+ if (items2.Size() > 1)
+ {
+ if (db.GetArtForItem(items2[0]->GetVideoInfoTag()->m_iDbId, items2[0]->GetVideoInfoTag()->m_type, artwork))
+ db.SetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork);
+ }
+ }
+ }
+ items.Clear();
+
+ // now actors
+ if (g_guiSettings.GetBool("videolibrary.actorthumbs"))
+ {
+ db.GetActorsNav("videodb://1/2/", items, VIDEODB_CONTENT_MOVIES);
+ db.GetActorsNav("videodb://2/2/", items, VIDEODB_CONTENT_TVSHOWS);
+ db.GetActorsNav("videodb://2/2/", items, VIDEODB_CONTENT_EPISODES);
+ db.GetActorsNav("videodb://3/2/", items, VIDEODB_CONTENT_MUSICVIDEOS);
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr item = items[i];
+ handle->SetProgress(i, items.Size());
+ handle->SetText(StringUtils::Format(g_localizeStrings.Get(12350).c_str(), item->GetLabel().c_str()));
+ map<string, string> artwork;
+ if (!db.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork))
+ {
+ item->GetVideoInfoTag()->m_strPictureURL.Parse();
+ string cachedThumb = GetCachedActorThumb(*item);
+
+ string art = CScraperUrl::GetThumbURL(item->GetVideoInfoTag()->m_strPictureURL.GetFirstThumb());
+ if (!art.empty() && CacheTexture(art, cachedThumb))
+ artwork.insert(make_pair("thumb", art));
+ else
+ artwork.insert(make_pair("thumb", ""));
+ db.SetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artwork);
+ }
+ }
+ }
+ handle->MarkFinished();
+ items.Clear();
+}
+
+bool CEdenVideoArtUpdater::CacheTexture(const std::string &originalUrl, const std::string &cachedFile)
+{
+ if (!CFile::Exists(cachedFile))
+ return false;
+
+ CTextureDetails details;
+ details.updateable = false;;
+ details.hash = "NOHASH";
+
+ CBaseTexture *texture = CTextureCacheJob::LoadImage(cachedFile, 0, 0, "");
+ if (texture)
+ {
+ if (texture->HasAlpha())
+ details.file = CTextureCache::GetCacheFile(originalUrl) + ".png";
+ else
+ details.file = CTextureCache::GetCacheFile(originalUrl) + ".jpg";
+
+ CLog::Log(LOGDEBUG, "Caching image '%s' ('%s') to '%s':", originalUrl.c_str(), cachedFile.c_str(), details.file.c_str());
+
+ uint32_t width = 0, height = 0;
+ if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(details.file)))
+ {
+ details.width = width;
+ details.height = height;
+ delete texture;
+ m_textureDB.AddCachedTexture(originalUrl, details);
+ return true;
+ }
+ }
+ CLog::Log(LOGDEBUG, "Can't cache image '%s' ('%s')", originalUrl.c_str(), cachedFile.c_str());
+ return false;
+}
+
+CStdString CEdenVideoArtUpdater::GetCachedActorThumb(const CFileItem &item)
+{
+ return GetThumb("actor" + item.GetLabel(), g_settings.GetVideoThumbFolder(), true);
+}
+
+CStdString CEdenVideoArtUpdater::GetCachedSeasonThumb(int season, const CStdString &path)
+{
+ CStdString label;
+ if (season == 0)
+ label = g_localizeStrings.Get(20381);
+ else
+ label.Format(g_localizeStrings.Get(20358), season);
+ return GetThumb("season" + path + label, g_settings.GetVideoThumbFolder(), true);
+}
+
+CStdString CEdenVideoArtUpdater::GetCachedEpisodeThumb(const CFileItem &item)
+{
+ // get the locally cached thumb
+ CStdString strCRC;
+ strCRC.Format("%sepisode%i", item.GetVideoInfoTag()->m_strFileNameAndPath.c_str(), item.GetVideoInfoTag()->m_iEpisode);
+ return GetThumb(strCRC, g_settings.GetVideoThumbFolder(), true);
+}
+
+CStdString CEdenVideoArtUpdater::GetCachedVideoThumb(const CFileItem &item)
+{
+ if (item.m_bIsFolder && !item.GetVideoInfoTag()->m_strPath.IsEmpty())
+ return GetThumb(item.GetVideoInfoTag()->m_strPath, g_settings.GetVideoThumbFolder(), true);
+ else if (!item.GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty())
+ return GetThumb(item.GetVideoInfoTag()->m_strFileNameAndPath, g_settings.GetVideoThumbFolder(), true);
+ return GetThumb(item.GetPath(), g_settings.GetVideoThumbFolder(), true);
+}
+
+CStdString CEdenVideoArtUpdater::GetCachedFanart(const CFileItem &item)
+{
+ if (!item.GetVideoInfoTag()->m_artist.empty())
+ return GetThumb(StringUtils::Join(item.GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator), URIUtils::AddFileToFolder(g_settings.GetThumbnailsFolder(), "Music/Fanart/"), false);
+ CStdString path = item.GetVideoInfoTag()->GetPath();
+ if (path.empty())
+ return "";
+ return GetThumb(path, URIUtils::AddFileToFolder(g_settings.GetVideoThumbFolder(), "Fanart/"), false);
+}
+
+CStdString CEdenVideoArtUpdater::GetThumb(const CStdString &path, const CStdString &path2, bool split)
+{
+ // get the locally cached thumb
+ Crc32 crc;
+ crc.ComputeFromLowerCase(path);
+
+ CStdString thumb;
+ if (split)
+ {
+ CStdString hex;
+ hex.Format("%08x", (__int32)crc);
+ thumb.Format("%c\\%08x.tbn", hex[0], (unsigned __int32)crc);
+ }
+ else
+ thumb.Format("%08x.tbn", (unsigned __int32)crc);
+
+ return URIUtils::AddFileToFolder(path2, thumb);
+}
View
53 xbmc/utils/EdenVideoArtUpdater.h
@@ -0,0 +1,53 @@
+#pragma once
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string>
+#include "threads/thread.h"
+#include "TextureDatabase.h"
+
+class CFileItem;
+
+class CEdenVideoArtUpdater : CThread
+{
+public:
+ CEdenVideoArtUpdater();
+ ~CEdenVideoArtUpdater();
+
+ static void Start();
+
+ virtual void Process();
+
+private:
+ /*! \brief Caches the texture from oldCachedFile as if it came from originalUrl into the texture cache.
+ \param originalUrl the url that we think the oldCachedFile came from.
+ \param oldCachedFile the old cached file
+ */
+ bool CacheTexture(const std::string &originalUrl, const std::string &oldCachedFile);
+
+ CStdString GetCachedActorThumb(const CFileItem &item);
+ CStdString GetCachedSeasonThumb(int season, const CStdString &path);
+ CStdString GetCachedEpisodeThumb(const CFileItem &item);
+ CStdString GetCachedVideoThumb(const CFileItem &item);
+ CStdString GetCachedFanart(const CFileItem &item);
+ CStdString GetThumb(const CStdString &path, const CStdString &path2, bool split /* = false */);
+
+ CTextureDatabase m_textureDB;
+};
View
1  xbmc/utils/Makefile
@@ -14,6 +14,7 @@ SRCS=AlarmClock.cpp \
DownloadQueue.cpp \
DownloadQueueManager.cpp \
EndianSwap.cpp \
+ EdenVideoArtUpdater.cpp \
Fanart.cpp \
fastmemcpy.c \
fastmemcpy-arm.S \
View
1  xbmc/video/VideoDatabase.h
@@ -688,6 +688,7 @@ class CVideoDatabase : public CDatabase
virtual bool GetFilter(CDbUrl &videoUrl, Filter &filter);
protected:
+ friend class CEdenVideoArtUpdater;
int GetMovieId(const CStdString& strFilenameAndPath);
int GetMusicVideoId(const CStdString& strFilenameAndPath);
View
75 xbmc/video/VideoInfoScanner.cpp
@@ -414,11 +414,11 @@ namespace VIDEO
INFO_RET ret = INFO_CANCELLED;
if (info2->Content() == CONTENT_TVSHOWS)
- ret = RetrieveInfoForTvShow(pItem, bDirNames, info2, useLocal, pURL, fetchEpisodes, pDlgProgress);
+ ret = RetrieveInfoForTvShow(pItem.get(), bDirNames, info2, useLocal, pURL, fetchEpisodes, pDlgProgress);
else if (info2->Content() == CONTENT_MOVIES)
- ret = RetrieveInfoForMovie(pItem, bDirNames, info2, useLocal, pURL, pDlgProgress);
+ ret = RetrieveInfoForMovie(pItem.get(), bDirNames, info2, useLocal, pURL, pDlgProgress);
else if (info2->Content() == CONTENT_MUSICVIDEOS)
- ret = RetrieveInfoForMusicVideo(pItem, bDirNames, info2, useLocal, pURL, pDlgProgress);
+ ret = RetrieveInfoForMusicVideo(pItem.get(), bDirNames, info2, useLocal, pURL, pDlgProgress);
else
{
CLog::Log(LOGERROR, "VideoInfoScanner: Unknown content type %d (%s)", info2->Content(), pItem->GetPath().c_str());
@@ -458,7 +458,7 @@ namespace VIDEO
return FoundSomeInfo;
}
- INFO_RET CVideoInfoScanner::RetrieveInfoForTvShow(CFileItemPtr pItem, bool bDirNames, ScraperPtr &info2, bool useLocal, CScraperUrl* pURL, bool fetchEpisodes, CGUIDialogProgress* pDlgProgress)
+ INFO_RET CVideoInfoScanner::RetrieveInfoForTvShow(CFileItem *pItem, bool bDirNames, ScraperPtr &info2, bool useLocal, CScraperUrl* pURL, bool fetchEpisodes, CGUIDialogProgress* pDlgProgress)
{
long idTvShow = -1;
if (pItem->m_bIsFolder)
@@ -484,7 +484,7 @@ namespace VIDEO
CScraperUrl scrUrl;
// handle .nfo files
if (useLocal)
- result = CheckForNFOFile(pItem.get(), bDirNames, info2, scrUrl);
+ result = CheckForNFOFile(pItem, bDirNames, info2, scrUrl);
if (result != CNfoFile::NO_NFO && result != CNfoFile::ERROR_NFO)
{ // check for preconfigured scraper; if found, overwrite with interpreted scraper (from Nfofile)
// but keep current scan settings
@@ -497,7 +497,7 @@ namespace VIDEO
pItem->GetVideoInfoTag()->Reset();
m_nfoReader.GetDetails(*pItem->GetVideoInfoTag());
- long lResult = AddVideo(pItem.get(), info2->Content(), bDirNames, useLocal);
+ long lResult = AddVideo(pItem, info2->Content(), bDirNames, useLocal);
if (lResult < 0)
return INFO_ERROR;
if (fetchEpisodes)
@@ -520,9 +520,9 @@ namespace VIDEO
return retVal < 0 ? INFO_CANCELLED : INFO_NOT_FOUND;
long lResult=-1;
- if (GetDetails(pItem.get(), url, info2, result == CNfoFile::COMBINED_NFO ? &m_nfoReader : NULL, pDlgProgress))
+ if (GetDetails(pItem, url, info2, result == CNfoFile::COMBINED_NFO ? &m_nfoReader : NULL, pDlgProgress))
{
- if ((lResult = AddVideo(pItem.get(), info2->Content(), false, useLocal)) < 0)
+ if ((lResult = AddVideo(pItem, info2->Content(), false, useLocal)) < 0)
return INFO_ERROR;
}
if (fetchEpisodes)
@@ -534,7 +534,7 @@ namespace VIDEO
return INFO_ADDED;
}
- INFO_RET CVideoInfoScanner::RetrieveInfoForMovie(CFileItemPtr pItem, bool bDirNames, ScraperPtr &info2, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress)
+ INFO_RET CVideoInfoScanner::RetrieveInfoForMovie(CFileItem *pItem, bool bDirNames, ScraperPtr &info2, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress)
{
if (pItem->m_bIsFolder || !pItem->IsVideo() || pItem->IsNFO() ||
(pItem->IsPlayList() && !URIUtils::GetExtension(pItem->GetPath()).Equals(".strm")))
@@ -550,13 +550,13 @@ namespace VIDEO
CScraperUrl scrUrl;
// handle .nfo files
if (useLocal)
- result = CheckForNFOFile(pItem.get(), bDirNames, info2, scrUrl);
+ result = CheckForNFOFile(pItem, bDirNames, info2, scrUrl);
if (result == CNfoFile::FULL_NFO)
{
pItem->GetVideoInfoTag()->Reset();
m_nfoReader.GetDetails(*pItem->GetVideoInfoTag());
- if (AddVideo(pItem.get(), info2->Content(), bDirNames, true) < 0)
+ if (AddVideo(pItem, info2->Content(), bDirNames, true) < 0)
return INFO_ERROR;
return INFO_ADDED;
}
@@ -570,9 +570,9 @@ namespace VIDEO
else if ((retVal = FindVideo(pItem->GetMovieName(bDirNames), info2, url, pDlgProgress)) <= 0)
return retVal < 0 ? INFO_CANCELLED : INFO_NOT_FOUND;
- if (GetDetails(pItem.get(), url, info2, result == CNfoFile::COMBINED_NFO ? &m_nfoReader : NULL, pDlgProgress))
+ if (GetDetails(pItem, url, info2, result == CNfoFile::COMBINED_NFO ? &m_nfoReader : NULL, pDlgProgress))
{
- if (AddVideo(pItem.get(), info2->Content(), bDirNames, useLocal) < 0)
+ if (AddVideo(pItem, info2->Content(), bDirNames, useLocal) < 0)
return INFO_ERROR;
return INFO_ADDED;
}
@@ -580,7 +580,7 @@ namespace VIDEO
return INFO_NOT_FOUND;
}
- INFO_RET CVideoInfoScanner::RetrieveInfoForMusicVideo(CFileItemPtr pItem, bool bDirNames, ScraperPtr &info2, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress)
+ INFO_RET CVideoInfoScanner::RetrieveInfoForMusicVideo(CFileItem *pItem, bool bDirNames, ScraperPtr &info2, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress)
{
if (pItem->m_bIsFolder || !pItem->IsVideo() || pItem->IsNFO() ||
(pItem->IsPlayList() && !URIUtils::GetExtension(pItem->GetPath()).Equals(".strm")))
@@ -596,13 +596,13 @@ namespace VIDEO
CScraperUrl scrUrl;
// handle .nfo files
if (useLocal)
- result = CheckForNFOFile(pItem.get(), bDirNames, info2, scrUrl);
+ result = CheckForNFOFile(pItem, bDirNames, info2, scrUrl);
if (result == CNfoFile::FULL_NFO)
{
pItem->GetVideoInfoTag()->Reset();
m_nfoReader.GetDetails(*pItem->GetVideoInfoTag());
- if (AddVideo(pItem.get(), info2->Content(), bDirNames, true) < 0)
+ if (AddVideo(pItem, info2->Content(), bDirNames, true) < 0)
return INFO_ERROR;
return INFO_ADDED;
}
@@ -616,9 +616,9 @@ namespace VIDEO
else if ((retVal = FindVideo(pItem->GetMovieName(bDirNames), info2, url, pDlgProgress)) <= 0)
return retVal < 0 ? INFO_CANCELLED : INFO_NOT_FOUND;
- if (GetDetails(pItem.get(), url, info2, result == CNfoFile::COMBINED_NFO ? &m_nfoReader : NULL, pDlgProgress))
+ if (GetDetails(pItem, url, info2, result == CNfoFile::COMBINED_NFO ? &m_nfoReader : NULL, pDlgProgress))
{
- if (AddVideo(pItem.get(), info2->Content(), bDirNames, useLocal) < 0)
+ if (AddVideo(pItem, info2->Content(), bDirNames, useLocal) < 0)
return INFO_ERROR;
return INFO_ADDED;
}
@@ -626,11 +626,11 @@ namespace VIDEO
return INFO_NOT_FOUND;
}
- INFO_RET CVideoInfoScanner::RetrieveInfoForEpisodes(CFileItemPtr item, long showID, const ADDON::ScraperPtr &scraper, bool useLocal, CGUIDialogProgress *progress)
+ INFO_RET CVideoInfoScanner::RetrieveInfoForEpisodes(CFileItem *item, long showID, const ADDON::ScraperPtr &scraper, bool useLocal, CGUIDialogProgress *progress)
{
// enumerate episodes
EPISODELIST files;
- EnumerateSeriesFolder(item.get(), files);
+ EnumerateSeriesFolder(item, files);
if (files.size() == 0) // no update or no files
return INFO_NOT_NEEDED;
@@ -749,10 +749,10 @@ namespace VIDEO
* the VideoInfoTag. If it has, do not try to parse any of them from the file path to avoid
* any false positive matches.
*/
- if (ProcessItemByVideoInfoTag(items[i], episodeList))
+ if (ProcessItemByVideoInfoTag(items[i].get(), episodeList))
continue;
- if (!EnumerateEpisodeItem(items[i], episodeList))
+ if (!EnumerateEpisodeItem(items[i].get(), episodeList))
{
CStdString decode(items[i]->GetPath());
CURL::Decode(decode);
@@ -761,12 +761,12 @@ namespace VIDEO
}
}
- bool CVideoInfoScanner::ProcessItemByVideoInfoTag(const CFileItemPtr item, EPISODELIST &episodeList)
+ bool CVideoInfoScanner::ProcessItemByVideoInfoTag(const CFileItem *item, EPISODELIST &episodeList)
{
if (!item->HasVideoInfoTag())
return false;
- CVideoInfoTag* tag = item->GetVideoInfoTag();
+ const CVideoInfoTag* tag = item->GetVideoInfoTag();
/*
* First check the season and episode number. This takes precedence over the original air
* date and episode title. Must be a valid season and episode number combination.
@@ -846,7 +846,7 @@ namespace VIDEO
return false;
}
- bool CVideoInfoScanner::EnumerateEpisodeItem(const CFileItemPtr item, EPISODELIST& episodeList)
+ bool CVideoInfoScanner::EnumerateEpisodeItem(const CFileItem *item, EPISODELIST& episodeList)
{
SETTINGS_TVSHOWLIST expression = g_advancedSettings.m_tvshowEnumRegExps;
@@ -1097,9 +1097,11 @@ namespace VIDEO
{
if (pItem->m_bIsFolder)
{
- // get season thumbs
+ // get and cache season thumbs
map<int, string> seasonArt;
GetSeasonThumbs(movieDetails, seasonArt);
+ for (map<int, string>::iterator i = seasonArt.begin(); i != seasonArt.end(); ++i)
+ CTextureCache::Get().BackgroundCacheImage(i->second);
lResult = m_database.SetDetailsForTvShow(pItem->GetPath(), movieDetails, art, seasonArt);
movieDetails.m_iDbId = lResult;
movieDetails.m_type = "tvshow";
@@ -1172,12 +1174,8 @@ namespace VIDEO
bool isEpisode = (content == CONTENT_TVSHOWS && !pItem->m_bIsFolder);
if (!isEpisode)
{
- CStdString fanart = pItem->GetArt("fanart");
- if (fanart.empty() && useLocal)
- fanart = pItem->FindLocalArt("fanart.jpg", true);
- if (fanart.IsEmpty())
- fanart = movieDetails.m_fanart.GetImageURL();
- if (!fanart.IsEmpty())
+ string fanart = GetFanart(pItem, useLocal);
+ if (!fanart.empty())
art.insert(make_pair("fanart", fanart));
}
@@ -1230,6 +1228,16 @@ namespace VIDEO
return thumb;
}
+ std::string CVideoInfoScanner::GetFanart(CFileItem *pItem, bool useLocal)
+ {
+ std::string fanart = pItem->GetArt("fanart");
+ if (fanart.empty() && useLocal)
+ fanart = pItem->FindLocalArt("fanart.jpg", true);
+ if (fanart.empty())
+ fanart = pItem->GetVideoInfoTag()->m_fanart.GetImageURL();
+ return fanart;
+ }
+
INFO_RET CVideoInfoScanner::OnProcessSeriesFolder(EPISODELIST& files, const ADDON::ScraperPtr &scraper, bool useLocal, const CVideoInfoTag& showInfo, CGUIDialogProgress* pDlgProgress /* = NULL */)
{
if (pDlgProgress)
@@ -1640,9 +1648,6 @@ namespace VIDEO
}
}
}
- // cache them
- for (map<int, string>::iterator i = art.begin(); i != art.end(); ++i)
- CTextureCache::Get().BackgroundCacheImage(i->second);
}
void CVideoInfoScanner::FetchActorThumbs(vector<SActorInfo>& actors, const CStdString& strPath)
View
15 xbmc/video/VideoInfoScanner.h
@@ -24,6 +24,8 @@
#include "NfoFile.h"
class CRegExp;
+class CFileItem;
+class CFileItemList;
namespace VIDEO
{
@@ -108,15 +110,16 @@ namespace VIDEO
*/
static void GetSeasonThumbs(const CVideoInfoTag &show, std::map<int, std::string> &art, bool useLocal = true);
static std::string GetImage(CFileItem *pItem, bool useLocal, bool bApplyToDir, const std::string &type = "");
+ static std::string GetFanart(CFileItem *pItem, bool useLocal);
protected:
virtual void Process();
bool DoScan(const CStdString& strDirectory);
- INFO_RET RetrieveInfoForTvShow(CFileItemPtr pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, bool fetchEpisodes, CGUIDialogProgress* pDlgProgress);
- INFO_RET RetrieveInfoForMovie(CFileItemPtr pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress);
- INFO_RET RetrieveInfoForMusicVideo(CFileItemPtr pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress);
- INFO_RET RetrieveInfoForEpisodes(CFileItemPtr item, long showID, const ADDON::ScraperPtr &scraper, bool useLocal, CGUIDialogProgress *progress = NULL);
+ INFO_RET RetrieveInfoForTvShow(CFileItem *pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, bool fetchEpisodes, CGUIDialogProgress* pDlgProgress);
+ INFO_RET RetrieveInfoForMovie(CFileItem *pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress);
+ INFO_RET RetrieveInfoForMusicVideo(CFileItem *pItem, bool bDirNames, ADDON::ScraperPtr &scraper, bool useLocal, CScraperUrl* pURL, CGUIDialogProgress* pDlgProgress);
+ INFO_RET RetrieveInfoForEpisodes(CFileItem *item, long showID, const ADDON::ScraperPtr &scraper, bool useLocal, CGUIDialogProgress *progress = NULL);
/*! \brief Update the progress bar with the heading and line and check for cancellation
\param progress CGUIDialogProgress bar
@@ -202,8 +205,8 @@ namespace VIDEO
INFO_RET OnProcessSeriesFolder(EPISODELIST& files, const ADDON::ScraperPtr &scraper, bool useLocal, const CVideoInfoTag& showInfo, CGUIDialogProgress* pDlgProgress = NULL);
void EnumerateSeriesFolder(CFileItem* item, EPISODELIST& episodeList);
- bool EnumerateEpisodeItem(const CFileItemPtr item, EPISODELIST& episodeList);
- bool ProcessItemByVideoInfoTag(const CFileItemPtr item, EPISODELIST &episodeList);
+ bool EnumerateEpisodeItem(const CFileItem *item, EPISODELIST& episodeList);
+ bool ProcessItemByVideoInfoTag(const CFileItem *item, EPISODELIST &episodeList);
CStdString GetnfoFile(CFileItem *item, bool bGrabAny=false) const;
View
62 xbmc/video/VideoThumbLoader.cpp
@@ -308,68 +308,6 @@ bool CVideoThumbLoader::FillLibraryArt(CFileItem &item)
if (database.GetArtForItem(idAlbum, "album", artwork))
item.SetArt(artwork);
}
- else
- {
- if (tag.m_type == "movie" || tag.m_type == "episode" ||
- tag.m_type == "tvshow" || tag.m_type == "musicvideo")
- { // no art in the library, so find it locally and add
- SScanSettings settings;
- ADDON::ScraperPtr info = m_database->GetScraperForPath(tag.m_strPath, settings);
- if (info)
- {
- CFileItem tmpItem(item);
- tmpItem.SetPath(tag.GetPath());
- CVideoInfoScanner scanner;
- scanner.GetArtwork(&tmpItem, info->Content(), tag.m_type != "episode" && settings.parent_name_root, true);
- item.SetArt(tmpItem.GetArt());
- }
- }
- else if (tag.m_type == "set")
- { // no art for a set -> use the first movie for this set for art
- CFileItemList items;
- if (m_database->GetMoviesNav("videodb://1/2/", items, -1, -1, -1, -1, -1, -1, tag.m_iDbId) && items.Size() > 0)
- {
- LoadItem(items[0].get());
- if (!items[0]->GetArt().empty())
- item.SetArt(items[0]->GetArt());
- }
- }
- else if (tag.m_type == "actor" ||
- tag.m_type == "writer" || tag.m_type == "director")
- {
- // We can't realistically get the local thumbs (as we'd need to check every movie that contains this actor)
- // and most users won't have local actor thumbs that are actually different than the scraped ones.
- if (g_guiSettings.GetBool("videolibrary.actorthumbs"))
- {
- tag.m_strPictureURL.Parse();
- CStdString thumb = CScraperUrl::GetThumbURL(tag.m_strPictureURL.GetFirstThumb());
- if (!thumb.IsEmpty())
- item.SetArt("thumb", thumb);
- }
- }
- else if (tag.m_type == "season")
- {
- // season art is fetched on scan from the tvshow root path (m_strPath in the season info tag)
- // or from the show m_strPictureURL member of the tvshow, so grab the tvshow to get this.
- CVideoInfoTag show;
- m_database->GetTvShowInfo(tag.m_strPath, show, tag.m_iIdShow);
- map<int, string> seasons;
- CVideoInfoScanner::GetSeasonThumbs(show, seasons, true);
- map<int, string>::iterator season = seasons.find(tag.m_iSeason);
- if (season != seasons.end())
- item.SetArt("thumb", season->second);
- }
- // add to the database for next time around
- map<string, string> artwork = item.GetArt();
- if (!artwork.empty())
- {
- m_database->SetArtForItem(tag.m_iDbId, tag.m_type, artwork);
- for (map<string, string>::iterator i = artwork.begin(); i != artwork.end(); ++i)
- CTextureCache::Get().BackgroundCacheImage(i->second);
- }
- else // nothing found - set an empty thumb so that next time around we don't hit here again
- m_database->SetArtForItem(tag.m_iDbId, tag.m_type, "thumb", "");
- }
// For episodes and seasons, we want to set fanart for that of the show
if (!item.HasArt("fanart") && tag.m_iIdShow >= 0)
{
View
18 xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -69,6 +69,8 @@
#include "storage/MediaManager.h"
#include "Autorun.h"
#include "URL.h"
+#include "utils/EdenVideoArtUpdater.h"
+#include "GUIInfoManager.h"
using namespace std;
using namespace XFILE;
@@ -2146,3 +2148,19 @@ void CGUIWindowVideoBase::OnAssignContent(const CStdString &path)
g_application.StartVideoScan(path, true);
}
}
+
+void CGUIWindowVideoBase::OnInitWindow()
+{
+ CGUIMediaWindow::OnInitWindow();
+ if (g_settings.m_videoNeedsUpdate == 63 && !g_application.IsVideoScanning() &&
+ g_infoManager.GetLibraryBool(LIBRARY_HAS_VIDEO))
+ {
+ // rescan of video library required
+ if (CGUIDialogYesNo::ShowAndGetInput(799, 12351, 12352, 12354))
+ {
+ CEdenVideoArtUpdater::Start();
+ g_settings.m_videoNeedsUpdate = 0; // once is enough
+ g_settings.Save();
+ }
+ }
+}
View
1  xbmc/video/windows/GUIWindowVideoBase.h
@@ -83,6 +83,7 @@ class CGUIWindowVideoBase : public CGUIMediaWindow, public IBackgroundLoaderObse
protected:
void OnScan(const CStdString& strPath, bool scanAll = false);
+ virtual void OnInitWindow();
virtual void UpdateButtons();
virtual bool Update(const CStdString &strDirectory);
virtual bool GetDirectory(const CStdString &strDirectory, CFileItemList &items);
Something went wrong with that request. Please try again.