Permalink
Browse files

TvDB Linking Rewrite!

  • Loading branch information...
da3dsoul committed Apr 14, 2018
1 parent 286ee3f commit aa94979d17fd4296920ebfd7a135aafbee1e9479
Showing with 1,223 additions and 783 deletions.
  1. +1 −1 Shoko.Commons
  2. +26 −32 ....Server/API/v1/Implementations/ShokoServiceImplementation/ShokoServiceImplementation_Providers.cs
  3. +16 −185 Shoko.Server/API/v1/Implementations/ShokoServiceImplementationMetro.cs
  4. +24 −0 Shoko.Server/API/v2/Modules/Core.cs
  5. +2 −1 Shoko.Server/Commands/AniDB/CommandRequest_SyncMyList.cs
  6. +1 −0 Shoko.Server/Commands/Import/CommandRequest_ProcessFile.cs
  7. +4 −4 Shoko.Server/Commands/Trakt/CommandRequest_TraktSearchAnime.cs
  8. +4 −24 Shoko.Server/Commands/TvDB/CommandRequest_LinkAniDBTvDB.cs
  9. +24 −53 Shoko.Server/Commands/TvDB/CommandRequest_TvDBSearchAnime.cs
  10. +3 −4 Shoko.Server/Commands/TvDB/CommandRequest_TvDBUpdateEpisode.cs
  11. +5 −4 Shoko.Server/Commands/WebCache/CommandRequest_WebCacheSendXRefAniDBTvDB.cs
  12. +77 −0 Shoko.Server/Databases/DatabaseFixes.cs
  13. +14 −1 Shoko.Server/Databases/MySQL.cs
  14. +14 −1 Shoko.Server/Databases/SQLServer.cs
  15. +42 −1 Shoko.Server/Databases/SQLite.cs
  16. +1 −8 Shoko.Server/Enums.cs
  17. +9 −2 Shoko.Server/Extensions/ModelDatabase.cs
  18. +47 −0 Shoko.Server/Extensions/ModelProviders.cs
  19. +7 −1 Shoko.Server/Extensions/Utils.cs
  20. +20 −0 Shoko.Server/Mappings/CrossRef_AniDB_TvDBMap.cs
  21. +0 −26 Shoko.Server/Mappings/CrossRef_AniDB_TvDBV2Map.cs
  22. +3 −2 Shoko.Server/Mappings/CrossRef_AniDB_TvDB_EpisodeMap.cs
  23. +18 −0 Shoko.Server/Mappings/CrossRef_AniDB_TvDB_Episode_OverrideMap.cs
  24. +7 −7 Shoko.Server/Models/SVR_AniDB_Anime.cs
  25. +2 −1 Shoko.Server/Models/SVR_AniDB_File.cs
  26. +6 −53 Shoko.Server/Models/SVR_AnimeEpisode.cs
  27. +3 −3 Shoko.Server/Models/SVR_AnimeGroup.cs
  28. +14 −18 Shoko.Server/Models/SVR_AnimeSeries.cs
  29. +5 −5 Shoko.Server/Models/SVR_GroupFilter.cs
  30. +5 −97 Shoko.Server/PlexAndKodi/Helper.cs
  31. +1 −1 Shoko.Server/Providers/MovieDB/MovieDBHelper.cs
  32. +0 −45 Shoko.Server/Providers/TraktTV/TraktTVHelper.cs
  33. +30 −76 Shoko.Server/Providers/TvDB/TvDBApiHelper.cs
  34. +540 −0 Shoko.Server/Providers/TvDB/TvDBLinkingHelper.cs
  35. +12 −12 Shoko.Server/Providers/TvDB/TvDBSummary.cs
  36. +2 −0 Shoko.Server/Repositories/Cached/AniDB_AnimeRepository.cs
  37. +138 −0 Shoko.Server/Repositories/Cached/CrossRef_AniDB_TvDBRepository.cs
  38. +0 −101 Shoko.Server/Repositories/Cached/CrossRef_AniDB_TvDBV2Repository.cs
  39. +13 −4 Shoko.Server/Repositories/Cached/CrossRef_AniDB_TvDB_EpisodeRepository.cs
  40. +64 −0 Shoko.Server/Repositories/Cached/CrossRef_AniDB_TvDB_Episode_OverrideRepository.cs
  41. +5 −0 Shoko.Server/Repositories/Cached/TvDB_EpisodeRepository.cs
  42. +7 −7 Shoko.Server/Repositories/Cached/TvDB_SeriesRepository.cs
  43. +2 −1 Shoko.Server/Repositories/RepoFactory.cs
  44. +5 −2 Shoko.Server/Shoko.Server.csproj
Submodule Shoko.Commons updated 1 files
+1 −1 Shoko.Models
@@ -56,11 +56,10 @@ public CL_AniDB_AnimeCrossRefs GetCrossRefDetails(int animeID)
SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(animeID);
if (anime == null) return result;

var xrefs = anime.GetCrossRefTvDBV2().ToList();
var xrefs = RepoFactory.CrossRef_AniDB_TvDB.GetV2LinksFromAnime(animeID);

// TvDB
foreach (CrossRef_AniDB_TvDBV2 xref in xrefs)
result.CrossRef_AniDB_TvDB.Add(xref);
result.CrossRef_AniDB_TvDB = xrefs;

foreach (TvDB_Episode ep in anime.GetTvDBEpisodes())
result.TvDBEpisodes.Add(ep);
@@ -229,7 +228,7 @@ public string UseMyTvDBLinksWebCache(int animeID)
try
{
// Get all the links for this user and anime
List<CrossRef_AniDB_TvDBV2> xrefs = RepoFactory.CrossRef_AniDB_TvDBV2.GetByAnimeID(animeID);
List<CrossRef_AniDB_TvDB> xrefs = RepoFactory.CrossRef_AniDB_TvDB.GetByAnimeID(animeID);
if (xrefs == null) return "No Links found to use";

SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(animeID);
@@ -254,9 +253,9 @@ public string UseMyTvDBLinksWebCache(int animeID)
if (foundLinks) return "Links already exist, please approve them instead";

// send the links to the web cache
foreach (CrossRef_AniDB_TvDBV2 xref in xrefs)
foreach (CrossRef_AniDB_TvDB xref in xrefs)
{
AzureWebAPI.Send_CrossRefAniDBTvDB(xref, anime.MainTitle);
AzureWebAPI.Send_CrossRefAniDBTvDB(xref.ToV2Model(), anime.MainTitle);
}

// now get the links back from the cache and approve them
@@ -445,7 +444,7 @@ public List<CrossRef_AniDB_TvDBV2> GetTVDBCrossRefV2(int animeID)
{
try
{
return RepoFactory.CrossRef_AniDB_TvDBV2.GetByAnimeID(animeID).Cast<CrossRef_AniDB_TvDBV2>().ToList();
return RepoFactory.CrossRef_AniDB_TvDB.GetV2LinksFromAnime(animeID);
}
catch (Exception ex)
{
@@ -454,11 +453,11 @@ public List<CrossRef_AniDB_TvDBV2> GetTVDBCrossRefV2(int animeID)
}
}

public List<CrossRef_AniDB_TvDB_Episode> GetTVDBCrossRefEpisode(int animeID)
public List<CrossRef_AniDB_TvDB_Episode_Override> GetTVDBCrossRefEpisode(int animeID)
{
try
{
return RepoFactory.CrossRef_AniDB_TvDB_Episode.GetByAnimeID(animeID).ToList();
return RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAnimeID(animeID).ToList();
}
catch (Exception ex)
{
@@ -505,24 +504,21 @@ public string LinkAniDBTvDB(CrossRef_AniDB_TvDBV2 link)
{
try
{
CrossRef_AniDB_TvDBV2 xref = RepoFactory.CrossRef_AniDB_TvDBV2.GetByTvDBID(link.TvDBID,
link.TvDBSeasonNumber, link.TvDBStartEpisodeNumber, link.AnimeID, link.AniDBStartEpisodeType,
link.AniDBStartEpisodeNumber);
CrossRef_AniDB_TvDB xref = RepoFactory.CrossRef_AniDB_TvDB.GetByAniDBAndTvDBID(link.AnimeID, link.TvDBID);

if (xref != null && link.IsAdditive)
{
string msg = $"You have already linked Anime ID {xref.AnimeID} to this TvDB show/season/ep";
SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(xref.AnimeID);
string msg = $"You have already linked Anime ID {xref.AniDBID} to this TvDB show/season/ep";
SVR_AniDB_Anime anime = RepoFactory.AniDB_Anime.GetByAnimeID(xref.AniDBID);
if (anime != null)
msg =
$"You have already linked Anime {anime.MainTitle} ({xref.AnimeID}) to this TvDB show/season/ep";
$"You have already linked Anime {anime.MainTitle} ({xref.AniDBID}) to this TvDB show/season/ep";
return msg;
}

// we don't need to proactively remove the link here anymore, as all links are removed when it is not marked as additive
CommandRequest_LinkAniDBTvDB cmdRequest = new CommandRequest_LinkAniDBTvDB(link.AnimeID,
(EpisodeType) link.AniDBStartEpisodeType, link.AniDBStartEpisodeNumber, link.TvDBID,
link.TvDBSeasonNumber, link.TvDBStartEpisodeNumber, false, link.IsAdditive);
CommandRequest_LinkAniDBTvDB cmdRequest =
new CommandRequest_LinkAniDBTvDB(link.AnimeID, link.TvDBID, link.IsAdditive);
cmdRequest.Save();

return string.Empty;
@@ -534,11 +530,11 @@ public string LinkAniDBTvDB(CrossRef_AniDB_TvDBV2 link)
}
}

public string LinkAniDBTvDBEpisode(int aniDBID, int tvDBID, int animeID)
public string LinkAniDBTvDBEpisode(int aniDBID, int tvDBID)
{
try
{
TvDBApiHelper.LinkAniDBTvDBEpisode(aniDBID, tvDBID, animeID);
TvDBApiHelper.LinkAniDBTvDBEpisode(aniDBID, tvDBID);

return string.Empty;
}
@@ -562,10 +558,10 @@ public string RemoveLinkAniDBTvDBForAnime(int animeID)

if (ser == null) return "Could not find Series for Anime!";

List<CrossRef_AniDB_TvDBV2> xrefs = RepoFactory.CrossRef_AniDB_TvDBV2.GetByAnimeID(animeID);
List<CrossRef_AniDB_TvDB> xrefs = RepoFactory.CrossRef_AniDB_TvDB.GetByAnimeID(animeID);
if (xrefs == null) return string.Empty;

foreach (CrossRef_AniDB_TvDBV2 xref in xrefs)
foreach (CrossRef_AniDB_TvDB xref in xrefs)
{
// check if there are default images used associated
List<AniDB_Anime_DefaultImage> images = RepoFactory.AniDB_Anime_DefaultImage.GetByAnimeID(animeID);
@@ -580,9 +576,7 @@ public string RemoveLinkAniDBTvDBForAnime(int animeID)
}
}

TvDBApiHelper.RemoveLinkAniDBTvDB(xref.AnimeID, (EpisodeType) xref.AniDBStartEpisodeType,
xref.AniDBStartEpisodeNumber,
xref.TvDBID, xref.TvDBSeasonNumber, xref.TvDBStartEpisodeNumber);
TvDBApiHelper.RemoveLinkAniDBTvDB(xref.AniDBID, xref.TvDBID);
}

return string.Empty;
@@ -615,8 +609,7 @@ public string RemoveLinkAniDBTvDB(CrossRef_AniDB_TvDBV2 link)
}
}

TvDBApiHelper.RemoveLinkAniDBTvDB(link.AnimeID, (EpisodeType) link.AniDBStartEpisodeType,
link.AniDBStartEpisodeNumber, link.TvDBID, link.TvDBSeasonNumber, link.TvDBStartEpisodeNumber);
TvDBApiHelper.RemoveLinkAniDBTvDB(link.AnimeID, link.TvDBID);

return string.Empty;
}
@@ -627,20 +620,21 @@ public string RemoveLinkAniDBTvDB(CrossRef_AniDB_TvDBV2 link)
}
}

public string RemoveLinkAniDBTvDBEpisode(int aniDBEpisodeID)
public string RemoveLinkAniDBTvDBEpisode(int aniDBEpisodeID, int tvDBEpisodeID)
{
try
{
AniDB_Episode ep = RepoFactory.AniDB_Episode.GetByEpisodeID(aniDBEpisodeID);

if (ep == null) return "Could not find Episode";

CrossRef_AniDB_TvDB_Episode xref =
RepoFactory.CrossRef_AniDB_TvDB_Episode.GetByAniDBEpisodeID(aniDBEpisodeID);
CrossRef_AniDB_TvDB_Episode_Override xref =
RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAniDBAndTvDBEpisodeIDs(aniDBEpisodeID,
tvDBEpisodeID);
if (xref == null) return "Could not find Link!";


RepoFactory.CrossRef_AniDB_TvDB_Episode.Delete(xref.CrossRef_AniDB_TvDB_EpisodeID);
RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.Delete(xref.CrossRef_AniDB_TvDB_Episode_OverrideID);

return string.Empty;
}
@@ -1464,4 +1458,4 @@ public string UpdateMovieDBData(int movieD)

#endregion
}
}
}
@@ -113,7 +113,7 @@ public Metro_CommunityLinks GetCommunityLinks(int animeID)
}

// TvDB
List<CrossRef_AniDB_TvDBV2> tvdbRef = anime.GetCrossRefTvDBV2();
List<CrossRef_AniDB_TvDB> tvdbRef = anime.GetCrossRefTvDB();
if (tvdbRef != null && tvdbRef.Count > 0)
{
contract.TvDB_ID = tvdbRef[0].TvDBID.ToString();
@@ -860,195 +860,26 @@ public static void SetTvDBInfo(int anidbid, AniDB_Episode ep, ref Metro_Anime_Ep

public static void SetTvDBInfo(TvDBSummary tvSummary, AniDB_Episode ep, ref Metro_Anime_Episode contract)
{
#region episode override

// check if this episode has a direct tvdb over-ride
if (tvSummary.DictTvDBCrossRefEpisodes.ContainsKey(ep.EpisodeID))
{
foreach (TvDB_Episode tvep in tvSummary.DictTvDBEpisodes.Values)
{
if (tvSummary.DictTvDBCrossRefEpisodes[ep.EpisodeID] == tvep.Id)
{
if (string.IsNullOrEmpty(tvep.Overview))
contract.EpisodeOverview = "Episode Overview Not Available";
else
contract.EpisodeOverview = tvep.Overview;

if (string.IsNullOrEmpty(tvep.GetFullImagePath()) || !File.Exists(tvep.GetFullImagePath()))
{
contract.ImageType = 0;
contract.ImageID = 0;
}
else
{
contract.ImageType = (int) ImageEntityType.TvDB_Episode;
contract.ImageID = tvep.TvDB_EpisodeID;
}

if (ServerSettings.EpisodeTitleSource == DataSourceType.TheTvDB &&
!string.IsNullOrEmpty(tvep.EpisodeName))
contract.EpisodeName = tvep.EpisodeName;

return;
}
}
}

#endregion

#region normal episodes

// now do stuff to improve performance
if (ep.GetEpisodeTypeEnum() == EpisodeType.Episode)
var override_link = RepoFactory.CrossRef_AniDB_TvDB_Episode_Override.GetByAniDBEpisodeID(ep.EpisodeID);
if (override_link.Any(a => a != null))
{
if (tvSummary.CrossRefTvDBV2 != null && tvSummary.CrossRefTvDBV2.Count > 0)
{
// find the xref that is right
// relies on the xref's being sorted by season number and then episode number (desc)
List<CrossRef_AniDB_TvDBV2> tvDBCrossRef = tvSummary.CrossRefTvDBV2
.OrderByDescending(a => a.AniDBStartEpisodeNumber)
.ToList();


bool foundStartingPoint = false;
CrossRef_AniDB_TvDBV2 xrefBase = null;
foreach (CrossRef_AniDB_TvDBV2 xrefTV in tvDBCrossRef)
{
if (xrefTV.AniDBStartEpisodeType != (int) EpisodeType.Episode) continue;
if (ep.EpisodeNumber >= xrefTV.AniDBStartEpisodeNumber)
{
foundStartingPoint = true;
xrefBase = xrefTV;
break;
}
}

// we have found the starting epiosde numbder from AniDB
// now let's check that the TvDB Season and Episode Number exist
if (foundStartingPoint)
{
Dictionary<int, int> dictTvDBSeasons = null;
Dictionary<int, TvDB_Episode> dictTvDBEpisodes = null;
foreach (TvDBDetails det in tvSummary.TvDetails.Values)
{
if (det.TvDBID == xrefBase.TvDBID)
{
dictTvDBSeasons = det.DictTvDBSeasons;
dictTvDBEpisodes = det.DictTvDBEpisodes;
break;
}
}

if (dictTvDBSeasons.ContainsKey(xrefBase.TvDBSeasonNumber))
{
int episodeNumber = dictTvDBSeasons[xrefBase.TvDBSeasonNumber] +
(ep.EpisodeNumber + xrefBase.TvDBStartEpisodeNumber - 2) -
(xrefBase.AniDBStartEpisodeNumber - 1);
if (dictTvDBEpisodes.ContainsKey(episodeNumber))
{
TvDB_Episode tvep = dictTvDBEpisodes[episodeNumber];
if (string.IsNullOrEmpty(tvep.Overview))
contract.EpisodeOverview = "Episode Overview Not Available";
else
contract.EpisodeOverview = tvep.Overview;

if (string.IsNullOrEmpty(tvep.GetFullImagePath()) ||
!File.Exists(tvep.GetFullImagePath()))
{
contract.ImageType = 0;
contract.ImageID = 0;
}
else
{
contract.ImageType = (int) ImageEntityType.TvDB_Episode;
contract.ImageID = tvep.TvDB_EpisodeID;
}

if (ServerSettings.EpisodeTitleSource == DataSourceType.TheTvDB &&
!string.IsNullOrEmpty(tvep.EpisodeName))
contract.EpisodeName = tvep.EpisodeName;
}
}
}
}
var tvep = RepoFactory.TvDB_Episode.GetByTvDBID(override_link.FirstOrDefault().TvDBEpisodeID);
contract.EpisodeName = tvep.EpisodeName;
contract.EpisodeOverview = tvep.Overview;
contract.ImageID = tvep.Id;
contract.ImageType = (int) ImageEntityType.TvDB_Episode;
return;
}

#endregion

#region special episodes

if (ep.GetEpisodeTypeEnum() == EpisodeType.Special)
var link = RepoFactory.CrossRef_AniDB_TvDB_Episode.GetByAniDBEpisodeID(ep.EpisodeID);
if (link.Any(a => a != null))
{
// find the xref that is right
// relies on the xref's being sorted by season number and then episode number (desc)

List<CrossRef_AniDB_TvDBV2> tvDBCrossRef = tvSummary.CrossRefTvDBV2
.OrderByDescending(a => a.AniDBStartEpisodeNumber)
.ToList();

bool foundStartingPoint = false;
CrossRef_AniDB_TvDBV2 xrefBase = null;
foreach (CrossRef_AniDB_TvDBV2 xrefTV in tvDBCrossRef)
{
if (xrefTV.AniDBStartEpisodeType != (int) EpisodeType.Special) continue;
if (ep.EpisodeNumber >= xrefTV.AniDBStartEpisodeNumber)
{
foundStartingPoint = true;
xrefBase = xrefTV;
break;
}
}

if (tvSummary != null && tvSummary.CrossRefTvDBV2 != null && tvSummary.CrossRefTvDBV2.Count > 0)
{
// we have found the starting epiosde numbder from AniDB
// now let's check that the TvDB Season and Episode Number exist
if (foundStartingPoint)
{
Dictionary<int, int> dictTvDBSeasons = null;
Dictionary<int, TvDB_Episode> dictTvDBEpisodes = null;
foreach (TvDBDetails det in tvSummary.TvDetails.Values)
{
if (det.TvDBID == xrefBase.TvDBID)
{
dictTvDBSeasons = det.DictTvDBSeasons;
dictTvDBEpisodes = det.DictTvDBEpisodes;
break;
}
}

if (dictTvDBSeasons.ContainsKey(xrefBase.TvDBSeasonNumber))
{
int episodeNumber = dictTvDBSeasons[xrefBase.TvDBSeasonNumber] +
(ep.EpisodeNumber + xrefBase.TvDBStartEpisodeNumber - 2) -
(xrefBase.AniDBStartEpisodeNumber - 1);
if (dictTvDBEpisodes.ContainsKey(episodeNumber))
{
TvDB_Episode tvep = dictTvDBEpisodes[episodeNumber];
contract.EpisodeOverview = tvep.Overview;

if (string.IsNullOrEmpty(tvep.GetFullImagePath()) ||
!File.Exists(tvep.GetFullImagePath()))
{
contract.ImageType = 0;
contract.ImageID = 0;
}
else
{
contract.ImageType = (int) ImageEntityType.TvDB_Episode;
contract.ImageID = tvep.TvDB_EpisodeID;
}

if (ServerSettings.EpisodeTitleSource == DataSourceType.TheTvDB &&
!string.IsNullOrEmpty(tvep.EpisodeName))
contract.EpisodeName = tvep.EpisodeName;
}
}
}
}
var tvep = RepoFactory.TvDB_Episode.GetByTvDBID(link.FirstOrDefault().TvDBEpisodeID);
contract.EpisodeName = tvep.EpisodeName;
contract.EpisodeOverview = tvep.Overview;
contract.ImageID = tvep.Id;
contract.ImageType = (int) ImageEntityType.TvDB_Episode;
}

#endregion
}

public List<Metro_AniDB_Character> GetCharactersForAnime(int animeID, int maxRecords)
Oops, something went wrong.

0 comments on commit aa94979

Please sign in to comment.