summaryrefslogtreecommitdiffstats
path: root/xbmc/NfoFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/NfoFile.cpp')
-rw-r--r--xbmc/NfoFile.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/xbmc/NfoFile.cpp b/xbmc/NfoFile.cpp
new file mode 100644
index 0000000..98a49b5
--- /dev/null
+++ b/xbmc/NfoFile.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+// NfoFile.cpp: implementation of the CNfoFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "NfoFile.h"
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "addons/AddonManager.h"
+#include "addons/AddonSystemSettings.h"
+#include "addons/addoninfo/AddonType.h"
+#include "filesystem/File.h"
+#include "music/Album.h"
+#include "music/Artist.h"
+#include "video/VideoInfoDownloader.h"
+
+#include <string>
+#include <vector>
+
+using namespace XFILE;
+using namespace ADDON;
+
+CInfoScanner::INFO_TYPE CNfoFile::Create(const std::string& strPath,
+ const ScraperPtr& info, int episode)
+{
+ m_info = info; // assume we can use these settings
+ m_type = ScraperTypeFromContent(info->Content());
+ if (Load(strPath) != 0)
+ return CInfoScanner::NO_NFO;
+
+ CFileItemList items;
+ bool bNfo=false;
+
+ if (m_type == AddonType::SCRAPER_ALBUMS)
+ {
+ CAlbum album;
+ bNfo = GetDetails(album);
+ }
+ else if (m_type == AddonType::SCRAPER_ARTISTS)
+ {
+ CArtist artist;
+ bNfo = GetDetails(artist);
+ }
+ else if (m_type == AddonType::SCRAPER_TVSHOWS || m_type == AddonType::SCRAPER_MOVIES ||
+ m_type == AddonType::SCRAPER_MUSICVIDEOS)
+ {
+ // first check if it's an XML file with the info we need
+ CVideoInfoTag details;
+ bNfo = GetDetails(details);
+ if (episode > -1 && bNfo && m_type == AddonType::SCRAPER_TVSHOWS)
+ {
+ int infos=0;
+ while (m_headPos != std::string::npos && details.m_iEpisode != episode)
+ {
+ m_headPos = m_doc.find("<episodedetails", m_headPos + 1);
+ if (m_headPos == std::string::npos)
+ break;
+
+ bNfo = GetDetails(details);
+ infos++;
+ }
+ if (details.m_iEpisode != episode)
+ {
+ bNfo = false;
+ details.Reset();
+ m_headPos = 0;
+ if (infos == 1) // still allow differing nfo/file numbers for single ep nfo's
+ bNfo = GetDetails(details);
+ }
+ }
+ }
+
+ std::vector<ScraperPtr> vecScrapers = GetScrapers(m_type, m_info);
+
+ // search ..
+ int res = -1;
+ for (unsigned int i=0; i<vecScrapers.size(); ++i)
+ if ((res = Scrape(vecScrapers[i], m_scurl, m_doc)) == 0 || res == 2)
+ break;
+
+ if (res == 2)
+ return CInfoScanner::ERROR_NFO;
+ if (bNfo)
+ {
+ if (!m_scurl.HasUrls())
+ {
+ if (m_doc.find("[scrape url]") != std::string::npos)
+ return CInfoScanner::OVERRIDE_NFO;
+ else
+ return CInfoScanner::FULL_NFO;
+ }
+ else
+ return CInfoScanner::COMBINED_NFO;
+ }
+ return m_scurl.HasUrls() ? CInfoScanner::URL_NFO : CInfoScanner::NO_NFO;
+}
+
+// return value: 0 - success; 1 - no result; skip; 2 - error
+int CNfoFile::Scrape(ScraperPtr& scraper, CScraperUrl& url,
+ const std::string& content)
+{
+ if (scraper->IsNoop())
+ {
+ url = CScraperUrl();
+ return 0;
+ }
+
+ scraper->ClearCache();
+
+ try
+ {
+ url = scraper->NfoUrl(content);
+ }
+ catch (const CScraperError &sce)
+ {
+ CVideoInfoDownloader::ShowErrorDialog(sce);
+ if (!sce.FAborted())
+ return 2;
+ }
+
+ return url.HasUrls() ? 0 : 1;
+}
+
+int CNfoFile::Load(const std::string& strFile)
+{
+ Close();
+ XFILE::CFile file;
+ std::vector<uint8_t> buf;
+ if (file.LoadFile(strFile, buf) > 0)
+ {
+ m_doc.assign(reinterpret_cast<char*>(buf.data()), buf.size());
+ m_headPos = 0;
+ return 0;
+ }
+ m_doc.clear();
+ return 1;
+}
+
+void CNfoFile::Close()
+{
+ m_doc.clear();
+ m_headPos = 0;
+ m_scurl.Clear();
+}
+
+std::vector<ScraperPtr> CNfoFile::GetScrapers(AddonType type, const ScraperPtr& selectedScraper)
+{
+ AddonPtr addon;
+ ScraperPtr defaultScraper;
+ if (CAddonSystemSettings::GetInstance().GetActive(type, addon))
+ defaultScraper = std::dynamic_pointer_cast<CScraper>(addon);
+
+ std::vector<ScraperPtr> vecScrapers;
+
+ // add selected scraper - first priority
+ if (selectedScraper)
+ vecScrapers.push_back(selectedScraper);
+
+ // Add all scrapers except selected and default
+ VECADDONS addons;
+ CServiceBroker::GetAddonMgr().GetAddons(addons, type);
+
+ for (auto& addon : addons)
+ {
+ ScraperPtr scraper = std::dynamic_pointer_cast<CScraper>(addon);
+
+ // skip if scraper requires settings and there's nothing set yet
+ if (scraper->RequiresSettings() && !scraper->HasUserSettings())
+ continue;
+
+ if ((!selectedScraper || selectedScraper->ID() != scraper->ID()) &&
+ (!defaultScraper || defaultScraper->ID() != scraper->ID()))
+ vecScrapers.push_back(scraper);
+ }
+
+ // add default scraper - not user selectable so it's last priority
+ if (defaultScraper && (!selectedScraper ||
+ selectedScraper->ID() != defaultScraper->ID()) &&
+ (!defaultScraper->RequiresSettings() || defaultScraper->HasUserSettings()))
+ vecScrapers.push_back(defaultScraper);
+
+ return vecScrapers;
+}