public override void ProcessCommand() { logger.Info("Processing CommandRequest_MALUpdatedWatchedStatus: {0}", AnimeID); try { // find the latest eps to update AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(AnimeID); if (anime == null) return; List<CrossRef_AniDB_MAL> crossRefs = anime.GetCrossRefMAL(); if (crossRefs == null || crossRefs.Count == 0) return; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(AnimeID); if (ser == null) return; MALHelper.UpdateMALSeries(ser); } catch (Exception ex) { logger.Error("Error processing CommandRequest_MALUpdatedWatchedStatus: {0} - {1}", AnimeID, ex.ToString()); return; } }
public override void ProcessCommand() { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(AnimeID); if (ser!=null) ser.UpdateStats(true, true, true); }
public override void ProcessCommand() { logger.Info("Get AniDB episode info: {0}", EpisodeID); try { // we don't use this command to update episode info // we actually use it to update the cross ref info instead // and we only use it for the "Other Episodes" section of the FILE command // because that field doesn't tell you what anime it belongs to CrossRef_File_EpisodeRepository repCrossRefs = new CrossRef_File_EpisodeRepository(); List<CrossRef_File_Episode> xrefs = repCrossRefs.GetByEpisodeID(EpisodeID); if (xrefs.Count == 0) return; Raw_AniDB_Episode epInfo = JMMService.AnidbProcessor.GetEpisodeInfo(EpisodeID); if (epInfo != null) { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); foreach (CrossRef_File_Episode xref in xrefs) { int oldAnimeID = xref.AnimeID; xref.AnimeID = epInfo.AnimeID; repCrossRefs.Save(xref); AnimeSeries ser = repSeries.GetByAnimeID(oldAnimeID); if (ser != null) ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingAnime(oldAnimeID); ser = repSeries.GetByAnimeID(epInfo.AnimeID); if (ser != null) ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingAnime(epInfo.AnimeID); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetEpisode: {0} - {1}", EpisodeID, ex.ToString()); return; } }
public List<Contract_AnimeSearch> OnlineAnimeTitleSearch(string titleQuery) { List<Contract_AnimeSearch> retTitles = new List<Contract_AnimeSearch>(); try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); List<JMMServer.Providers.Azure.AnimeIDTitle> titles = JMMServer.Providers.Azure.AzureWebAPI.Get_AnimeTitle(titleQuery); using (var session = JMMService.SessionFactory.OpenSession()) { foreach (JMMServer.Providers.Azure.AnimeIDTitle tit in titles) { Contract_AnimeSearch res = new Contract_AnimeSearch(); res.AnimeID = tit.AnimeID; res.MainTitle = tit.MainTitle; res.Titles = tit.Titles; // check for existing series and group details AnimeSeries ser = repSeries.GetByAnimeID(tit.AnimeID); if (ser != null) { res.SeriesExists = true; res.AnimeSeriesID = ser.AnimeSeriesID; res.AnimeSeriesName = ser.GetAnime(session).GetFormattedTitle(session); } else { res.SeriesExists = false; } retTitles.Add(res); } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retTitles; }
private void ProcessFile_AniDB(VideoLocal vidLocal) { logger.Trace("Checking for AniDB_File record for: {0} --- {1}", vidLocal.Hash, vidLocal.FilePath); // check if we already have this AniDB_File info in the database AniDB_FileRepository repAniFile = new AniDB_FileRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); VideoLocalRepository repVidLocals = new VideoLocalRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); CrossRef_File_EpisodeRepository repXrefFE = new CrossRef_File_EpisodeRepository(); AniDB_File aniFile = null; if (!ForceAniDB) { aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) logger.Trace("AniDB_File record not found"); } int animeID = 0; if (aniFile == null) { // get info from AniDB logger.Debug("Getting AniDB_File record from AniDB...."); Raw_AniDB_File fileInfo = JMMService.AnidbProcessor.GetFileInfo(vidLocal); if (fileInfo != null) { // check if we already have a record aniFile = repAniFile.GetByHashAndFileSize(vidLocal.Hash, vlocal.FileSize); if (aniFile == null) aniFile = new AniDB_File(); aniFile.Populate(fileInfo); //overwrite with local file name string localFileName = Path.GetFileName(vidLocal.FilePath); aniFile.FileName = localFileName; repAniFile.Save(aniFile, false); aniFile.CreateLanguages(); aniFile.CreateCrossEpisodes(localFileName); if (!string.IsNullOrEmpty(fileInfo.OtherEpisodesRAW)) { string[] epIDs = fileInfo.OtherEpisodesRAW.Split(','); foreach (string epid in epIDs) { int id = 0; if (int.TryParse(epid, out id)) { CommandRequest_GetEpisode cmdEp = new CommandRequest_GetEpisode(id); cmdEp.Save(); } } } animeID = aniFile.AnimeID; } } bool missingEpisodes = false; // if we still haven't got the AniDB_File Info we try the web cache or local records if (aniFile == null) { // check if we have any records from previous imports List<CrossRef_File_Episode> crossRefs = repXrefFE.GetByHash(vidLocal.Hash); if (crossRefs == null || crossRefs.Count == 0) { // lets see if we can find the episode/anime info from the web cache if (ServerSettings.WebCache_XRefFileEpisode_Get) { crossRefs = XMLService.Get_CrossRef_File_Episode(vidLocal); if (crossRefs == null || crossRefs.Count == 0) { logger.Debug("Cannot find AniDB_File record or get cross ref from web cache record so exiting: {0}", vidLocal.ED2KHash); return; } else { foreach (CrossRef_File_Episode xref in crossRefs) { // in this case we need to save the cross refs manually as AniDB did not provide them repXrefFE.Save(xref); } } } else { logger.Debug("Cannot get AniDB_File record so exiting: {0}", vidLocal.ED2KHash); return; } } // we assume that all episodes belong to the same anime foreach (CrossRef_File_Episode xref in crossRefs) { animeID = xref.AnimeID; AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; } } else { // check if we have the episode info // if we don't, we will need to re-download the anime info (which also has episode info) if (aniFile.EpisodeCrossRefs.Count == 0) { animeID = aniFile.AnimeID; // if we have the anidb file, but no cross refs it means something has been broken logger.Debug("Could not find any cross ref records for: {0}", vidLocal.ED2KHash); missingEpisodes = true; } else { foreach (CrossRef_File_Episode xref in aniFile.EpisodeCrossRefs) { AniDB_Episode ep = repAniEps.GetByEpisodeID(xref.EpisodeID); if (ep == null) missingEpisodes = true; animeID = xref.AnimeID; } } } // get from DB AniDB_Anime anime = repAniAnime.GetByAnimeID(animeID); bool animeRecentlyUpdated = false; if (anime != null) { TimeSpan ts = DateTime.Now - anime.DateTimeUpdated; if (ts.TotalHours < 4) animeRecentlyUpdated = true; } // even if we are missing episode info, don't get data more than once every 4 hours // this is to prevent banning if (missingEpisodes && !animeRecentlyUpdated) { logger.Debug("Getting Anime record from AniDB...."); // try using the cache first using (var session = JMMService.SessionFactory.OpenSession()) { anime = JMMService.AnidbProcessor.GetAnimeInfoHTTPFromCache(session, animeID, ServerSettings.AutoGroupSeries); } // if not in cache try from AniDB if (anime == null) anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries); } // create the group/series/episode records if needed AnimeSeries ser = null; if (anime != null) { logger.Debug("Creating groups, series and episodes...."); // check if there is an AnimeSeries Record associated with this AnimeID ser = repSeries.GetByAnimeID(animeID); if (ser == null) { // create a new AnimeSeries record ser = anime.CreateAnimeSeriesAndGroup(); } ser.CreateAnimeEpisodes(); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } } vidLocal.RenameIfRequired(); vidLocal.MoveFileIfRequired(); // update stats for groups and series if (ser != null) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); } // Add this file to the users list if (ServerSettings.AniDB_MyList_AddFiles) { CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vidLocal.ED2KHash); cmd.Save(); } // lets also try adding to the users trakt collecion by sync'ing the series if (ser != null) { CommandRequest_TraktSyncCollectionSeries cmdTrakt = new CommandRequest_TraktSyncCollectionSeries(ser.AnimeSeriesID, ser.GetAnime().MainTitle); cmdTrakt.Save(); } // sync the series on MAL if (ser != null) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_GetUpdated"); try { List<int> animeIDsToUpdate = new List<int>(); ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); // check the automated update table to see when the last time we ran this command ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBUpdates); if (sched != null) { int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_Anime_UpdateFrequency); // if we have run this in the last 12 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) return; } } long webUpdateTime = 0; long webUpdateTimeNew = 0; if (sched == null) { // if this is the first time, lets ask for last 3 days DateTime localTime = DateTime.Now.AddDays(-3); DateTime utcTime = localTime.ToUniversalTime(); webUpdateTime = long.Parse(Utils.AniDBDate(utcTime)); webUpdateTimeNew = long.Parse(Utils.AniDBDate(DateTime.Now.ToUniversalTime())); sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AniDBUpdates; } else { logger.Trace("Last anidb info update was : {0}", sched.UpdateDetails); webUpdateTime = long.Parse(sched.UpdateDetails); webUpdateTimeNew = long.Parse(Utils.AniDBDate(DateTime.Now.ToUniversalTime())); DateTime timeNow = DateTime.Now.ToUniversalTime(); logger.Info(string.Format("{0} since last UPDATED command", Utils.FormatSecondsToDisplayTime(int.Parse((webUpdateTimeNew - webUpdateTime).ToString())))); } // get a list of updates from AniDB // startTime will contain the date/time from which the updates apply to JMMService.AnidbProcessor.GetUpdated(ref animeIDsToUpdate, ref webUpdateTime); // now save the update time from AniDB // we will use this next time as a starting point when querying the web cache sched.LastUpdate = DateTime.Now; sched.UpdateDetails = webUpdateTimeNew.ToString(); repSched.Save(sched); if (animeIDsToUpdate.Count == 0) { logger.Info("No anime to be updated"); return; } int countAnime = 0; int countSeries = 0; foreach (int animeID in animeIDsToUpdate) { // update the anime from HTTP AniDB_Anime anime = repAnime.GetByAnimeID(animeID); if (anime == null) { logger.Trace("No local record found for Anime ID: {0}, so skipping...", animeID); continue; } logger.Info("Updating CommandRequest_GetUpdated: {0} ", animeID); // but only if it hasn't been recently updated TimeSpan ts = DateTime.Now - anime.DateTimeUpdated; if (ts.TotalHours > 4) { CommandRequest_GetAnimeHTTP cmdAnime = new CommandRequest_GetAnimeHTTP(animeID, true, false); cmdAnime.Save(); countAnime++; } // update the group status // this will allow us to determine which anime has missing episodes // so we wonly get by an amime where we also have an associated series AnimeSeries ser = repSeries.GetByAnimeID(animeID); if (ser != null) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(animeID, true); cmdStatus.Save(); countSeries++; } } logger.Info("Updating {0} anime records, and {1} group status records", countAnime, countSeries); } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetUpdated: {0}", ex.ToString()); return; } }
/// <summary> /// Removes all tvdb links for one anime /// </summary> /// <param name="animeID"></param> /// <returns></returns> public string RemoveLinkAniDBTvDBForAnime(int animeID) { try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(animeID); if (ser == null) return "Could not find Series for Anime!"; CrossRef_AniDB_TvDBV2Repository repCrossRef= new CrossRef_AniDB_TvDBV2Repository(); List<CrossRef_AniDB_TvDBV2> xrefs = repCrossRef.GetByAnimeID(animeID); if (xrefs == null) return ""; AniDB_Anime_DefaultImageRepository repDefaults = new AniDB_Anime_DefaultImageRepository(); foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) { // check if there are default images used associated List<AniDB_Anime_DefaultImage> images = repDefaults.GetByAnimeID(animeID); foreach (AniDB_Anime_DefaultImage image in images) { if (image.ImageParentType == (int)JMMImageType.TvDB_Banner || image.ImageParentType == (int)JMMImageType.TvDB_Cover || image.ImageParentType == (int)JMMImageType.TvDB_FanArt) { if (image.ImageParentID == xref.TvDBID) repDefaults.Delete(image.AniDB_Anime_DefaultImageID); } } TvDBHelper.RemoveLinkAniDBTvDB(xref.AnimeID, (enEpisodeType)xref.AniDBStartEpisodeType, xref.AniDBStartEpisodeNumber, xref.TvDBID, xref.TvDBSeasonNumber, xref.TvDBStartEpisodeNumber); } return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return ex.Message; } }
public string RemoveLinkAniDBTraktForAnime(int animeID) { try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(animeID); if (ser == null) return "Could not find Series for Anime!"; // check if there are default images used associated AniDB_Anime_DefaultImageRepository repDefaults = new AniDB_Anime_DefaultImageRepository(); List<AniDB_Anime_DefaultImage> images = repDefaults.GetByAnimeID(animeID); foreach (AniDB_Anime_DefaultImage image in images) { if (image.ImageParentType == (int)JMMImageType.Trakt_Fanart || image.ImageParentType == (int)JMMImageType.Trakt_Poster) { repDefaults.Delete(image.AniDB_Anime_DefaultImageID); } } CrossRef_AniDB_TraktV2Repository repXrefTrakt = new CrossRef_AniDB_TraktV2Repository(); foreach (CrossRef_AniDB_TraktV2 xref in repXrefTrakt.GetByAnimeID(animeID)) { TraktTVHelper.RemoveLinkAniDBTrakt(animeID, (enEpisodeType)xref.AniDBStartEpisodeType, xref.AniDBStartEpisodeNumber, xref.TraktID, xref.TraktSeasonNumber, xref.TraktStartEpisodeNumber); } return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return ex.Message; } }
public List<Contract_AniDB_Anime_Similar> GetSimilarAnimeLinks(int animeID, int userID) { List<Contract_AniDB_Anime_Similar> links = new List<Contract_AniDB_Anime_Similar>(); try { AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(animeID); if (anime == null) return links; JMMUserRepository repUsers = new JMMUserRepository(); JMMUser juser = repUsers.GetByID(userID); if (juser == null) return links; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); foreach (AniDB_Anime_Similar link in anime.GetSimilarAnime()) { AniDB_Anime animeLink = repAnime.GetByAnimeID(link.SimilarAnimeID); if (animeLink != null) { if (!juser.AllowedAnime(animeLink)) continue; } // check if this anime has a series AnimeSeries ser = repSeries.GetByAnimeID(link.SimilarAnimeID); links.Add(link.ToContract(animeLink, ser, userID)); } return links; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return links; } }
public List<MetroContract_Anime_Summary> SearchAnime(int jmmuserID, string queryText, int maxRecords) { List<MetroContract_Anime_Summary> retAnime = new List<MetroContract_Anime_Summary>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); JMMUserRepository repUsers = new JMMUserRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); JMMUser user = repUsers.GetByID(session, jmmuserID); if (user == null) return retAnime; List<AniDB_Anime> animes = repAnime.SearchByName(session, queryText); foreach (AniDB_Anime anidb_anime in animes) { if (!user.AllowedAnime(anidb_anime)) continue; AnimeSeries ser = repSeries.GetByAnimeID(anidb_anime.AnimeID); MetroContract_Anime_Summary summ = new MetroContract_Anime_Summary(); summ.AirDateAsSeconds = anidb_anime.AirDateAsSeconds; summ.AnimeID = anidb_anime.AnimeID; if (ser != null) { summ.AnimeName = ser.GetSeriesName(session); summ.AnimeSeriesID = ser.AnimeSeriesID; } else { summ.AnimeName = anidb_anime.MainTitle; summ.AnimeSeriesID = 0; } summ.BeginYear = anidb_anime.BeginYear; summ.EndYear = anidb_anime.EndYear; summ.PosterName = anidb_anime.GetDefaultPosterPathNoBlanks(session); ImageDetails imgDet = anidb_anime.GetDefaultPosterDetailsNoBlanks(session); summ.ImageType = (int)imgDet.ImageType; summ.ImageID = imgDet.ImageID; retAnime.Add(summ); if (retAnime.Count == maxRecords) break; } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retAnime; }
public List<MetroContract_Anime_Summary> GetSimilarAnimeForAnime(int animeID, int maxRecords, int jmmuserID) { List<Contract_AniDB_Anime_Similar> links = new List<Contract_AniDB_Anime_Similar>(); List<MetroContract_Anime_Summary> retAnime = new List<MetroContract_Anime_Summary>(); try { using (var session = JMMService.SessionFactory.OpenSession()) { AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) return retAnime; JMMUserRepository repUsers = new JMMUserRepository(); JMMUser juser = repUsers.GetByID(session, jmmuserID); if (juser == null) return retAnime; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); // first get the related anime foreach (AniDB_Anime_Relation link in anime.GetRelatedAnime()) { AniDB_Anime animeLink = repAnime.GetByAnimeID(link.RelatedAnimeID); if (animeLink == null) { // try getting it from anidb now animeLink = JMMService.AnidbProcessor.GetAnimeInfoHTTP(session, link.RelatedAnimeID, false, false); } if (animeLink == null) continue; if (!juser.AllowedAnime(animeLink)) continue; // check if this anime has a series AnimeSeries ser = repSeries.GetByAnimeID(link.RelatedAnimeID); MetroContract_Anime_Summary summ = new MetroContract_Anime_Summary(); summ.AnimeID = animeLink.AnimeID; summ.AnimeName = animeLink.MainTitle; summ.AnimeSeriesID = 0; summ.BeginYear = animeLink.BeginYear; summ.EndYear = animeLink.EndYear; //summ.PosterName = animeLink.GetDefaultPosterPathNoBlanks(session); summ.RelationshipType = link.RelationType; ImageDetails imgDet = animeLink.GetDefaultPosterDetailsNoBlanks(session); summ.ImageType = (int)imgDet.ImageType; summ.ImageID = imgDet.ImageID; if (ser != null) { summ.AnimeName = ser.GetSeriesName(session); summ.AnimeSeriesID = ser.AnimeSeriesID; } retAnime.Add(summ); } // now get similar anime foreach (AniDB_Anime_Similar link in anime.GetSimilarAnime(session)) { AniDB_Anime animeLink = repAnime.GetByAnimeID(session, link.SimilarAnimeID); if (animeLink == null) { // try getting it from anidb now animeLink = JMMService.AnidbProcessor.GetAnimeInfoHTTP(session, link.SimilarAnimeID, false, false); } if (animeLink == null) continue; if (!juser.AllowedAnime(animeLink)) continue; // check if this anime has a series AnimeSeries ser = repSeries.GetByAnimeID(session, link.SimilarAnimeID); MetroContract_Anime_Summary summ = new MetroContract_Anime_Summary(); summ.AnimeID = animeLink.AnimeID; summ.AnimeName = animeLink.MainTitle; summ.AnimeSeriesID = 0; summ.BeginYear = animeLink.BeginYear; summ.EndYear = animeLink.EndYear; //summ.PosterName = animeLink.GetDefaultPosterPathNoBlanks(session); summ.RelationshipType = "Recommendation"; ImageDetails imgDet = animeLink.GetDefaultPosterDetailsNoBlanks(session); summ.ImageType = (int)imgDet.ImageType; summ.ImageID = imgDet.ImageID; if (ser != null) { summ.AnimeName = ser.GetSeriesName(session); summ.AnimeSeriesID = ser.AnimeSeriesID; } retAnime.Add(summ); if (retAnime.Count == maxRecords) break; } return retAnime; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return retAnime; } }
public void MoveFileIfRequired() { // check if this file is in the drop folder // otherwise we don't need to move it if (this.ImportFolder.IsDropSource == 0) return; if (!File.Exists(this.FullServerPath)) return; // find the default destination ImportFolder destFolder = null; ImportFolderRepository repFolders = new ImportFolderRepository(); foreach (ImportFolder fldr in repFolders.GetAll()) { if (fldr.IsDropDestination == 1) { destFolder = fldr; break; } } if (destFolder == null) return; if (!Directory.Exists(destFolder.ImportFolderLocation)) return; // we can only move the file if it has an anime associated with it List<CrossRef_File_Episode> xrefs = this.EpisodeCrossRefs; if (xrefs.Count == 0) return; CrossRef_File_Episode xref = xrefs[0]; // find the series associated with this episode AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries series = repSeries.GetByAnimeID(xref.AnimeID); if (series == null) return; // find where the other files are stored for this series // if there are no other files except for this one, it means we need to create a new location bool foundLocation = false; string newFullPath = ""; // sort the episodes by air date, so that we will move the file to the location of the latest episode List<AnimeEpisode> allEps = series.GetAnimeEpisodes(); List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("AniDB_EpisodeID", true, SortType.eInteger)); allEps = Sorting.MultiSort<AnimeEpisode>(allEps, sortCriteria); foreach (AnimeEpisode ep in allEps) { foreach (VideoLocal vid in ep.GetVideoLocals()) { if (vid.VideoLocalID != this.VideoLocalID) { // make sure this folder is not the drop source if (vid.ImportFolder.IsDropSource == 1) continue; string thisFileName = vid.FullServerPath; string folderName = Path.GetDirectoryName(thisFileName); if (Directory.Exists(folderName)) { newFullPath = folderName; foundLocation = true; break; } } } if (foundLocation) break; } if (!foundLocation) { // we need to create a new folder string newFolderName = Utils.RemoveInvalidFolderNameCharacters(series.GetAnime().MainTitle); newFullPath = Path.Combine(destFolder.ImportFolderLocation, newFolderName); if (!Directory.Exists(newFullPath)) Directory.CreateDirectory(newFullPath); } int newFolderID = 0; string newPartialPath = ""; string newFullServerPath = Path.Combine(newFullPath, Path.GetFileName(this.FullServerPath)); DataAccessHelper.GetShareAndPath(newFullServerPath, repFolders.GetAll(), ref newFolderID, ref newPartialPath); logger.Info("Moving file from {0} to {1}", this.FullServerPath, newFullServerPath); if (File.Exists(newFullServerPath)) { // if the file already exists, we can just delete the source file instead // this is safer than deleting and moving File.Delete(this.FullServerPath); this.ImportFolderID = newFolderID; this.FilePath = newPartialPath; VideoLocalRepository repVids = new VideoLocalRepository(); repVids.Save(this); } else { string originalFileName = this.FullServerPath; FileInfo fi = new FileInfo(originalFileName); // now move the file File.Move(this.FullServerPath, newFullServerPath); this.ImportFolderID = newFolderID; this.FilePath = newPartialPath; VideoLocalRepository repVids = new VideoLocalRepository(); repVids.Save(this); try { // move any subtitle files foreach (string subtitleFile in Utils.GetPossibleSubtitleFiles(originalFileName)) { if (File.Exists(subtitleFile)) { FileInfo fiSub = new FileInfo(subtitleFile); string newSubPath = Path.Combine(Path.GetDirectoryName(newFullServerPath), fiSub.Name); if (File.Exists(newSubPath)) { // if the file already exists, we can just delete the source file instead // this is safer than deleting and moving File.Delete(newSubPath); } else File.Move(subtitleFile, newSubPath); } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } // check for any empty folders in drop folder // only for the drop folder if (this.ImportFolder.IsDropSource == 1) { foreach (string folderName in Directory.GetDirectories(this.ImportFolder.ImportFolderLocation, "*", SearchOption.AllDirectories)) { if (Directory.Exists(folderName)) { if (Directory.GetFiles(folderName, "*", SearchOption.AllDirectories).Length == 0) { try { Directory.Delete(folderName, true); } /*catch (IOException) { Thread.Sleep(0); Directory.Delete(folderName, false); }*/ catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } } } } } } }
public static List<AnimeGroup> GetRelatedGroupsFromAnimeID(ISession session, int animeid) { // TODO we need to recusrive list at all relations and not just the first one AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeGroupRepository repGroups = new AnimeGroupRepository(); List<AnimeGroup> grps = new List<AnimeGroup>(); AniDB_Anime anime = repAniAnime.GetByAnimeID(session, animeid); if (anime == null) return grps; // first check for groups which are directly related List<AniDB_Anime_Relation> relations = anime.GetRelatedAnime(session); foreach (AniDB_Anime_Relation rel in relations) { string relationtype = rel.RelationType.ToLower(); if ((relationtype == "same setting") || (relationtype == "alternative setting") || (relationtype == "character") || (relationtype == "other")) { //Filter these relations these will fix messes, like Gundam , Clamp, etc. continue; } // we actually need to get the series, because it might have been added to another group already AnimeSeries ser = repSeries.GetByAnimeID(session, rel.RelatedAnimeID); if (ser != null) { AnimeGroup grp = repGroups.GetByID(session, ser.AnimeGroupID); if (grp != null) grps.Add(grp); } } if (grps.Count > 0) return grps; // if nothing found check by all related anime List<AniDB_Anime> relatedAnime = anime.GetAllRelatedAnime(session); foreach (AniDB_Anime rel in relatedAnime) { // we actually need to get the series, because it might have been added to another group already AnimeSeries ser = repSeries.GetByAnimeID(session, rel.AnimeID); if (ser != null) { AnimeGroup grp = repGroups.GetByID(session, ser.AnimeGroupID); if (grp != null) grps.Add(grp); } } return grps; }
public void UpdateUsingAnime(ISession session, int animeID) { try { AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) return; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(session, animeID); if (ser == null) return; UpdateUsingSeries(session, ser.AnimeSeriesID); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
public bool GetSeriesExistingForAnime(int animeID) { AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); try { AnimeSeries series = repAnimeSer.GetByAnimeID(animeID); if (series == null) return false; return true; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return true; }
public MetroContract_Anime_Detail GetAnimeDetail(int animeID, int jmmuserID, int maxEpisodeRecords) { try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) return null; AnimeSeries ser = repSeries.GetByAnimeID(session, animeID); MetroContract_Anime_Detail ret = new MetroContract_Anime_Detail(); ret.AnimeID = anime.AnimeID; if (ser != null) ret.AnimeName = ser.GetSeriesName(session); else ret.AnimeName = anime.MainTitle; if (ser != null) ret.AnimeSeriesID = ser.AnimeSeriesID; else ret.AnimeSeriesID = 0; ret.BeginYear = anime.BeginYear; ret.EndYear = anime.EndYear; ImageDetails imgDet = anime.GetDefaultPosterDetailsNoBlanks(session); ret.PosterImageType = (int)imgDet.ImageType; ret.PosterImageID = imgDet.ImageID; ImageDetails imgDetFan = anime.GetDefaultFanartDetailsNoBlanks(session); if (imgDetFan != null) { ret.FanartImageType = (int)imgDetFan.ImageType; ret.FanartImageID = imgDetFan.ImageID; } else { ret.FanartImageType = 0; ret.FanartImageID = 0; } ret.AnimeType = anime.AnimeTypeDescription; ret.Description = anime.Description; ret.EpisodeCountNormal = anime.EpisodeCountNormal; ret.EpisodeCountSpecial = anime.EpisodeCountSpecial; ret.AirDate = anime.AirDate; ret.EndDate = anime.EndDate; ret.OverallRating = anime.AniDBRating; ret.TotalVotes = anime.AniDBTotalVotes; ret.AllTags = anime.TagsString; ret.NextEpisodesToWatch = new List<MetroContract_Anime_Episode>(); if (ser != null) { AnimeSeries_User serUserRec = ser.GetUserRecord(session, jmmuserID); if (ser != null) ret.UnwatchedEpisodeCount = serUserRec.UnwatchedEpisodeCount; else ret.UnwatchedEpisodeCount = 0; AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeEpisode_UserRepository repEpUser = new AnimeEpisode_UserRepository(); List<AnimeEpisode> epList = new List<AnimeEpisode>(); Dictionary<int, AnimeEpisode_User> dictEpUsers = new Dictionary<int, AnimeEpisode_User>(); foreach (AnimeEpisode_User userRecord in repEpUser.GetByUserIDAndSeriesID(session, jmmuserID, ser.AnimeSeriesID)) dictEpUsers[userRecord.AnimeEpisodeID] = userRecord; foreach (AnimeEpisode animeep in repEps.GetBySeriesID(session, ser.AnimeSeriesID)) { if (!dictEpUsers.ContainsKey(animeep.AnimeEpisodeID)) { epList.Add(animeep); continue; } AnimeEpisode_User usrRec = dictEpUsers[animeep.AnimeEpisodeID]; if (usrRec.WatchedCount == 0 || !usrRec.WatchedDate.HasValue) epList.Add(animeep); } AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); List<AniDB_Episode> aniEpList = repAniEps.GetByAnimeID(session, ser.AniDB_ID); Dictionary<int, AniDB_Episode> dictAniEps = new Dictionary<int, AniDB_Episode>(); foreach (AniDB_Episode aniep in aniEpList) dictAniEps[aniep.EpisodeID] = aniep; List<Contract_AnimeEpisode> candidateEps = new List<Contract_AnimeEpisode>(); foreach (AnimeEpisode ep in epList) { if (dictAniEps.ContainsKey(ep.AniDB_EpisodeID)) { AniDB_Episode anidbep = dictAniEps[ep.AniDB_EpisodeID]; if (anidbep.EpisodeType == (int)enEpisodeType.Episode || anidbep.EpisodeType == (int)enEpisodeType.Special) { AnimeEpisode_User userRecord = null; if (dictEpUsers.ContainsKey(ep.AnimeEpisodeID)) userRecord = dictEpUsers[ep.AnimeEpisodeID]; Contract_AnimeEpisode epContract = ep.ToContract(anidbep, new List<VideoLocal>(), userRecord, serUserRec); candidateEps.Add(epContract); } } } if (candidateEps.Count > 0) { TvDBSummary tvSummary = new TvDBSummary(); tvSummary.Populate(ser.AniDB_ID); // sort by episode type and number to find the next episode List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeType", false, SortType.eInteger)); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeNumber", false, SortType.eInteger)); candidateEps = Sorting.MultiSort<Contract_AnimeEpisode>(candidateEps, sortCriteria); // this will generate a lot of queries when the user doesn have files // for these episodes int cnt = 0; foreach (Contract_AnimeEpisode canEp in candidateEps) { if (dictAniEps.ContainsKey(canEp.AniDB_EpisodeID)) { AniDB_Episode anidbep = dictAniEps[canEp.AniDB_EpisodeID]; AnimeEpisode_User userEpRecord = null; if (dictEpUsers.ContainsKey(canEp.AnimeEpisodeID)) userEpRecord = dictEpUsers[canEp.AnimeEpisodeID]; // now refresh from the database to get file count AnimeEpisode epFresh = repEps.GetByID(session, canEp.AnimeEpisodeID); int fileCount = epFresh.GetVideoLocals(session).Count; if (fileCount > 0) { MetroContract_Anime_Episode contract = new MetroContract_Anime_Episode(); contract.AnimeEpisodeID = epFresh.AnimeEpisodeID; contract.LocalFileCount = fileCount; if (userEpRecord == null) contract.IsWatched = false; else contract.IsWatched = userEpRecord.WatchedCount > 0; // anidb contract.EpisodeNumber = anidbep.EpisodeNumber; contract.EpisodeName = anidbep.RomajiName; if (!string.IsNullOrEmpty(anidbep.EnglishName)) contract.EpisodeName = anidbep.EnglishName; contract.EpisodeType = anidbep.EpisodeType; contract.LengthSeconds = anidbep.LengthSeconds; contract.AirDate = anidbep.AirDateFormatted; // tvdb SetTvDBInfo(tvSummary, anidbep, ref contract); ret.NextEpisodesToWatch.Add(contract); cnt++; } } if (cnt == maxEpisodeRecords) break; } } } return ret; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return null; } }
public Contract_AnimeSeries GetSeriesForAnime(int animeID, int userID) { AnimeSeriesRepository repAnimeSer = new AnimeSeriesRepository(); try { AnimeSeries series = repAnimeSer.GetByAnimeID(animeID); if (series == null) return null; AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(series.AniDB_ID); if (anime == null) return null; List<CrossRef_AniDB_TvDBV2> xrefs = series.GetCrossRefTvDBV2(); List<CrossRef_AniDB_MAL> xrefMAL = series.CrossRefMAL; List<TvDB_Series> sers = new List<TvDB_Series>(); foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) sers.Add(xref.GetTvDBSeries()); CrossRef_AniDB_Other xrefMovie = series.CrossRefMovieDB; MovieDB_Movie movie = null; if (xrefMovie != null) movie = xrefMovie.GetMovieDB_Movie(); return series.ToContract(anime, xrefs, xrefMovie, series.GetUserRecord(userID), sers, xrefMAL, false, null, null, null, null, movie); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return null; }
public MetroContract_Anime_Summary GetAnimeSummary(int animeID) { try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) return null; AnimeSeries ser = repSeries.GetByAnimeID(session, animeID); MetroContract_Anime_Summary summ = new MetroContract_Anime_Summary(); summ.AnimeID = anime.AnimeID; summ.AnimeName = anime.MainTitle; summ.AnimeSeriesID = 0; summ.BeginYear = anime.BeginYear; summ.EndYear = anime.EndYear; summ.PosterName = anime.GetDefaultPosterPathNoBlanks(session); ImageDetails imgDet = anime.GetDefaultPosterDetailsNoBlanks(session); summ.ImageType = (int)imgDet.ImageType; summ.ImageID = imgDet.ImageID; if (ser != null) { summ.AnimeName = ser.GetSeriesName(session); summ.AnimeSeriesID = ser.AnimeSeriesID; } return summ; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return null; }
public List<Contract_AnimeSearch> OnlineAnimeTitleSearch(string titleQuery) { List<Contract_AnimeSearch> retTitles = new List<Contract_AnimeSearch>(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); try { // check if it is a title search or an ID search int aid = 0; if (int.TryParse(titleQuery, out aid)) { // user is direct entering the anime id // try the local database first // if not download the data from AniDB now AniDB_Anime anime = anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(aid, false, ServerSettings.AniDB_DownloadRelatedAnime); if (anime != null) { Contract_AnimeSearch res = new Contract_AnimeSearch(); res.AnimeID = anime.AnimeID; res.MainTitle = anime.MainTitle; res.Titles = anime.AllTitles; // check for existing series and group details AnimeSeries ser = repSeries.GetByAnimeID(anime.AnimeID); if (ser != null) { res.SeriesExists = true; res.AnimeSeriesID = ser.AnimeSeriesID; res.AnimeSeriesName = anime.GetFormattedTitle(); } else { res.SeriesExists = false; } retTitles.Add(res); } } else { // title search so look at the web cache List<JMMServer.Providers.Azure.AnimeIDTitle> titles = JMMServer.Providers.Azure.AzureWebAPI.Get_AnimeTitle(titleQuery); using (var session = JMMService.SessionFactory.OpenSession()) { foreach (JMMServer.Providers.Azure.AnimeIDTitle tit in titles) { Contract_AnimeSearch res = new Contract_AnimeSearch(); res.AnimeID = tit.AnimeID; res.MainTitle = tit.MainTitle; res.Titles = tit.Titles; // check for existing series and group details AnimeSeries ser = repSeries.GetByAnimeID(tit.AnimeID); if (ser != null) { res.SeriesExists = true; res.AnimeSeriesID = ser.AnimeSeriesID; res.AnimeSeriesName = ser.GetAnime(session).GetFormattedTitle(session); } else { res.SeriesExists = false; } retTitles.Add(res); } } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return retTitles; }
public Contract_AnimeSeries_SaveResponse CreateSeriesFromAnime(int animeID, int? animeGroupID, int userID) { Contract_AnimeSeries_SaveResponse response = new Contract_AnimeSeries_SaveResponse(); response.AnimeSeries = null; response.ErrorMessage = ""; try { using (var session = JMMService.SessionFactory.OpenSession()) { AnimeGroupRepository repGroups = new AnimeGroupRepository(); if (animeGroupID.HasValue) { AnimeGroup grp = repGroups.GetByID(session, animeGroupID.Value); if (grp == null) { response.ErrorMessage = "Could not find the specified group"; return response; } } // make sure a series doesn't already exists for this anime AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(session, animeID); if (ser != null) { response.ErrorMessage = "A series already exists for this anime"; return response; } // make sure the anime exists first AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(session, animeID); if (anime == null) anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(session, animeID, false, false); if (anime == null) { response.ErrorMessage = "Could not get anime information from AniDB"; return response; } if (animeGroupID.HasValue) { ser = new AnimeSeries(); ser.Populate(anime); ser.AnimeGroupID = animeGroupID.Value; repSeries.Save(ser); } else { ser = anime.CreateAnimeSeriesAndGroup(session); } ser.CreateAnimeEpisodes(session); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(session); } ser.QueueUpdateStats(); // check for TvDB associations CommandRequest_TvDBSearchAnime cmd = new CommandRequest_TvDBSearchAnime(anime.AnimeID, false); cmd.Save(session); if (ServerSettings.Trakt_IsEnabled && !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) { // check for Trakt associations CommandRequest_TraktSearchAnime cmd2 = new CommandRequest_TraktSearchAnime(anime.AnimeID, false); cmd2.Save(session); } List<CrossRef_AniDB_TvDBV2> xrefs = ser.GetCrossRefTvDBV2(); List<CrossRef_AniDB_MAL> xrefMAL = ser.CrossRefMAL; List<TvDB_Series> sers = new List<TvDB_Series>(); foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) sers.Add(xref.GetTvDBSeries()); CrossRef_AniDB_Other xrefMovie = ser.CrossRefMovieDB; MovieDB_Movie movie = null; if (xrefMovie != null) movie = xrefMovie.GetMovieDB_Movie(); response.AnimeSeries = ser.ToContract(anime, xrefs, xrefMovie, ser.GetUserRecord(userID), sers, xrefMAL, false, null, null, null, null,movie); return response; } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); response.ErrorMessage = ex.Message; } return response; }
public string RemoveLinkAniDBTvDB(int animeID, int aniEpType, int aniEpNumber, int tvDBID, int tvSeasonNumber, int tvEpNumber) { try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(animeID); if (ser == null) return "Could not find Series for Anime!"; // check if there are default images used associated AniDB_Anime_DefaultImageRepository repDefaults = new AniDB_Anime_DefaultImageRepository(); List<AniDB_Anime_DefaultImage> images = repDefaults.GetByAnimeID(animeID); foreach (AniDB_Anime_DefaultImage image in images) { if (image.ImageParentType == (int)JMMImageType.TvDB_Banner || image.ImageParentType == (int)JMMImageType.TvDB_Cover || image.ImageParentType == (int)JMMImageType.TvDB_FanArt) { if (image.ImageParentID == tvDBID) repDefaults.Delete(image.AniDB_Anime_DefaultImageID); } } TvDBHelper.RemoveLinkAniDBTvDB(animeID, (enEpisodeType)aniEpType, aniEpNumber, tvDBID, tvSeasonNumber, tvEpNumber); return ""; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return ex.Message; } }
public List<Contract_MissingFile> GetMyListFilesForRemoval(int userID) { List<Contract_MissingFile> contracts = new List<Contract_MissingFile>(); /*Contract_MissingFile missingFile2 = new Contract_MissingFile(); missingFile2.AnimeID = 1; missingFile2.AnimeTitle = "Gundam Age"; missingFile2.EpisodeID = 2; missingFile2.EpisodeNumber = 7; missingFile2.FileID = 8; missingFile2.AnimeSeries = null; contracts.Add(missingFile2); Thread.Sleep(5000); return contracts;*/ AniDB_FileRepository repAniFile = new AniDB_FileRepository(); CrossRef_File_EpisodeRepository repFileEp = new CrossRef_File_EpisodeRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_EpisodeRepository repEpisodes = new AniDB_EpisodeRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); Dictionary<int, AniDB_Anime> animeCache = new Dictionary<int, AniDB_Anime>(); Dictionary<int, AnimeSeries> animeSeriesCache = new Dictionary<int, AnimeSeries>(); try { AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList(); cmd.Init(ServerSettings.AniDB_Username, ServerSettings.AniDB_Password); enHelperActivityType ev = cmd.Process(); if (ev == enHelperActivityType.GotMyListHTTP) { foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) { // let's check if the file on AniDB actually exists in the user's local collection string hash = string.Empty; AniDB_File anifile = repAniFile.GetByFileID(myitem.FileID); if (anifile != null) hash = anifile.Hash; else { // look for manually linked files List<CrossRef_File_Episode> xrefs = repFileEp.GetByEpisodeID(myitem.EpisodeID); foreach (CrossRef_File_Episode xref in xrefs) { if (xref.CrossRefSource != (int)CrossRefSource.AniDB) { hash = xref.Hash; break; } } } bool fileMissing = false; if (string.IsNullOrEmpty(hash)) fileMissing = true; else { // now check if the file actually exists on disk VideoLocal vid = repVids.GetByHash(hash); if (vid != null && !File.Exists(vid.FullServerPath)) fileMissing = true; } if (fileMissing) { // this means we can't find the file AniDB_Anime anime = null; if (animeCache.ContainsKey(myitem.AnimeID)) anime = animeCache[myitem.AnimeID]; else { anime = repAnime.GetByAnimeID(myitem.AnimeID); animeCache[myitem.AnimeID] = anime; } AnimeSeries ser = null; if (animeSeriesCache.ContainsKey(myitem.AnimeID)) ser = animeSeriesCache[myitem.AnimeID]; else { ser = repSeries.GetByAnimeID(myitem.AnimeID); animeSeriesCache[myitem.AnimeID] = ser; } Contract_MissingFile missingFile = new Contract_MissingFile(); missingFile.AnimeID = myitem.AnimeID; missingFile.AnimeTitle = "Data Missing"; if (anime != null) missingFile.AnimeTitle = anime.MainTitle; missingFile.EpisodeID = myitem.EpisodeID; AniDB_Episode ep = repEpisodes.GetByEpisodeID(myitem.EpisodeID); missingFile.EpisodeNumber = -1; missingFile.EpisodeType = 1; if (ep != null) { missingFile.EpisodeNumber = ep.EpisodeNumber; missingFile.EpisodeType = ep.EpisodeType; } missingFile.FileID = myitem.FileID; if (ser == null) missingFile.AnimeSeries = null; else missingFile.AnimeSeries = ser.ToContract(ser.GetUserRecord(userID)); contracts.Add(missingFile); } } } if (contracts.Count > 0) { List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("AnimeTitle", false, SortType.eString)); sortCriteria.Add(new SortPropOrFieldAndDirection("EpisodeID", false, SortType.eInteger)); contracts = Sorting.MultiSort<Contract_MissingFile>(contracts, sortCriteria); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return contracts; }
public string SyncTraktSeries(int animeID) { try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries ser = repSeries.GetByAnimeID(animeID); if (ser == null) return "Could not find Anime Series"; CommandRequest_TraktSyncCollectionSeries cmd = new CommandRequest_TraktSyncCollectionSeries(ser.AnimeSeriesID, ser.GetSeriesName()); cmd.Save(); return string.Empty; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return ex.Message; } }
/// <summary> /// Get all the release groups for an episode for which the user is collecting /// </summary> /// <param name="aniDBEpisodeID"></param> /// <returns></returns> public List<Contract_AniDBReleaseGroup> GetMyReleaseGroupsForAniDBEpisode(int aniDBEpisodeID) { DateTime start = DateTime.Now; List<Contract_AniDBReleaseGroup> relGroups = new List<Contract_AniDBReleaseGroup>(); try { AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_Episode aniEp = repAniEps.GetByEpisodeID(aniDBEpisodeID); if (aniEp == null) return relGroups; if (aniEp.EpisodeTypeEnum != AniDBAPI.enEpisodeType.Episode) return relGroups; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries series = repSeries.GetByAnimeID(aniEp.AnimeID); if (series == null) return relGroups; // get a list of all the release groups the user is collecting Dictionary<int, int> userReleaseGroups = new Dictionary<int, int>(); foreach (AnimeEpisode ep in series.GetAnimeEpisodes()) { List<VideoLocal> vids = ep.GetVideoLocals(); foreach (VideoLocal vid in vids) { AniDB_File anifile = vid.GetAniDBFile(); if (anifile != null) { if (!userReleaseGroups.ContainsKey(anifile.GroupID)) userReleaseGroups[anifile.GroupID] = 0; userReleaseGroups[anifile.GroupID] = userReleaseGroups[anifile.GroupID] + 1; } } } // get all the release groups for this series AniDB_GroupStatusRepository repGrpStatus = new AniDB_GroupStatusRepository(); List<AniDB_GroupStatus> grpStatuses = repGrpStatus.GetByAnimeID(aniEp.AnimeID); foreach (AniDB_GroupStatus gs in grpStatuses) { if (userReleaseGroups.ContainsKey(gs.GroupID)) { if (gs.HasGroupReleasedEpisode(aniEp.EpisodeNumber)) { Contract_AniDBReleaseGroup contract = new Contract_AniDBReleaseGroup(); contract.GroupID = gs.GroupID; contract.GroupName = gs.GroupName; contract.UserCollecting = true; contract.EpisodeRange = gs.EpisodeRange; contract.FileCount = userReleaseGroups[gs.GroupID]; relGroups.Add(contract); } } } TimeSpan ts = DateTime.Now - start; logger.Info("GetMyReleaseGroupsForAniDBEpisode in {0} ms", ts.TotalMilliseconds); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return relGroups; }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_GetReleaseGroupStatus: {0}", AnimeID); try { // only get group status if we have an associated series AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries series = repSeries.GetByAnimeID(AnimeID); if (series == null) return; AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_Anime anime = repAnime.GetByAnimeID(AnimeID); if (anime == null) return; // don't get group status if the anime has already ended more than 50 days ago bool skip = false; if (!ForceRefresh) { if (anime.EndDate.HasValue) { if (anime.EndDate.Value < DateTime.Now) { TimeSpan ts = DateTime.Now - anime.EndDate.Value; if (ts.TotalDays > 50) { // don't skip if we have never downloaded this info before AniDB_GroupStatusRepository repGrpStatus = new AniDB_GroupStatusRepository(); List<AniDB_GroupStatus> grpStatuses = repGrpStatus.GetByAnimeID(AnimeID); if (grpStatuses != null && grpStatuses.Count > 0) { skip = true; } } } } } if (skip) { logger.Info("Skipping group status command because anime has already ended: {0}", anime.ToString()); return; } GroupStatusCollection grpCol = JMMService.AnidbProcessor.GetReleaseGroupStatusUDP(AnimeID); if (ServerSettings.AniDB_DownloadReleaseGroups) { // save in bulk to improve performance using (var session = JMMService.SessionFactory.OpenSession()) { using (var transaction = session.BeginTransaction()) { foreach (Raw_AniDB_GroupStatus grpStatus in grpCol.Groups) { CommandRequest_GetReleaseGroup cmdRelgrp = new CommandRequest_GetReleaseGroup(grpStatus.GroupID, false); session.SaveOrUpdate(cmdRelgrp); } transaction.Commit(); } } } //} } catch (Exception ex) { logger.Error("Error processing CommandRequest_GetReleaseGroupStatus: {0} - {1}", AnimeID, ex.ToString()); return; } }
/// <summary> /// Returns a list of recommendations based on the users votes /// </summary> /// <param name="maxResults"></param> /// <param name="userID"></param> /// <param name="recommendationType">1 = to watch, 2 = to download</param> public List<Contract_Recommendation> GetRecommendations(int maxResults, int userID, int recommendationType) { List<Contract_Recommendation> recs = new List<Contract_Recommendation>(); try { AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AniDB_VoteRepository repVotes = new AniDB_VoteRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); JMMUserRepository repUsers = new JMMUserRepository(); JMMUser juser = repUsers.GetByID(userID); if (juser == null) return recs; // get all the anime the user has chosen to ignore int ignoreType = 1; switch (recommendationType) { case 1: ignoreType = 1; break; case 2: ignoreType = 2; break; } IgnoreAnimeRepository repIgnore = new IgnoreAnimeRepository(); List<IgnoreAnime> ignored = repIgnore.GetByUserAndType(userID, ignoreType); Dictionary<int, IgnoreAnime> dictIgnored = new Dictionary<int, Entities.IgnoreAnime>(); foreach (IgnoreAnime ign in ignored) dictIgnored[ign.AnimeID] = ign; // find all the series which the user has rated List<AniDB_Vote> allVotes = repVotes.GetAll(); if (allVotes.Count == 0) return recs; // sort by the highest rated List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("VoteValue", true, SortType.eInteger)); allVotes = Sorting.MultiSort<AniDB_Vote>(allVotes, sortCriteria); Dictionary<int, Contract_Recommendation> dictRecs = new Dictionary<int, Contract_Recommendation>(); List<AniDB_Vote> animeVotes = new List<AniDB_Vote>(); foreach (AniDB_Vote vote in allVotes) { if (vote.VoteType != (int)enAniDBVoteType.Anime && vote.VoteType != (int)enAniDBVoteType.AnimeTemp) continue; if (dictIgnored.ContainsKey(vote.EntityID)) continue; // check if the user has this anime AniDB_Anime anime = repAnime.GetByAnimeID(vote.EntityID); if (anime == null) continue; // get similar anime List<AniDB_Anime_Similar> simAnime = anime.GetSimilarAnime(); // sort by the highest approval sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("ApprovalPercentage", true, SortType.eDoubleOrFloat)); simAnime = Sorting.MultiSort<AniDB_Anime_Similar>(simAnime, sortCriteria); foreach (AniDB_Anime_Similar link in simAnime) { if (dictIgnored.ContainsKey(link.SimilarAnimeID)) continue; AniDB_Anime animeLink = repAnime.GetByAnimeID(link.SimilarAnimeID); if (animeLink != null) if (!juser.AllowedAnime(animeLink)) continue; // don't recommend to watch anime that the user doesn't have if (animeLink == null && recommendationType == 1) continue; // don't recommend to watch series that the user doesn't have AnimeSeries ser = repSeries.GetByAnimeID(link.SimilarAnimeID); if (ser == null && recommendationType == 1) continue; if (ser != null) { // don't recommend to watch series that the user has already started watching AnimeSeries_User userRecord = ser.GetUserRecord(userID); if (userRecord != null) { if (userRecord.WatchedEpisodeCount > 0 && recommendationType == 1) continue; } // don't recommend to download anime that the user has files for if (ser.LatestLocalEpisodeNumber > 0 && recommendationType == 2) continue; } Contract_Recommendation rec = new Contract_Recommendation(); rec.BasedOnAnimeID = anime.AnimeID; rec.RecommendedAnimeID = link.SimilarAnimeID; // if we don't have the anime locally. lets assume the anime has a high rating decimal animeRating = 850; if (animeLink != null) animeRating = animeLink.AniDBRating; rec.Score = CalculateRecommendationScore(vote.VoteValue, link.ApprovalPercentage, animeRating); rec.BasedOnVoteValue = vote.VoteValue; rec.RecommendedApproval = link.ApprovalPercentage; // check if we have added this recommendation before // this might happen where animes are recommended based on different votes // and could end up with different scores if (dictRecs.ContainsKey(rec.RecommendedAnimeID)) { if (rec.Score < dictRecs[rec.RecommendedAnimeID].Score) continue; } rec.Recommended_AniDB_Anime = null; if (animeLink != null) rec.Recommended_AniDB_Anime = animeLink.ToContract(); rec.BasedOn_AniDB_Anime = anime.ToContract(); rec.Recommended_AnimeSeries = null; if (ser != null) rec.Recommended_AnimeSeries = ser.ToContract(ser.GetUserRecord(userID)); AnimeSeries serBasedOn = repSeries.GetByAnimeID(anime.AnimeID); if (serBasedOn == null) continue; rec.BasedOn_AnimeSeries = serBasedOn.ToContract(serBasedOn.GetUserRecord(userID)); dictRecs[rec.RecommendedAnimeID] = rec; } } List<Contract_Recommendation> tempRecs = new List<Contract_Recommendation>(); foreach (Contract_Recommendation rec in dictRecs.Values) tempRecs.Add(rec); // sort by the highest score sortCriteria = new List<SortPropOrFieldAndDirection>(); sortCriteria.Add(new SortPropOrFieldAndDirection("Score", true, SortType.eDoubleOrFloat)); tempRecs = Sorting.MultiSort<Contract_Recommendation>(tempRecs, sortCriteria); int numRecs = 0; foreach (Contract_Recommendation rec in tempRecs) { if (numRecs == maxResults) break; recs.Add(rec); numRecs++; } if (recs.Count == 0) return recs; return recs; } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return recs; } }
void workerMyAnime2_DoWork(object sender, DoWorkEventArgs e) { MA2Progress ma2Progress = new MA2Progress(); ma2Progress.CurrentFile = 0; ma2Progress.ErrorMessage = ""; ma2Progress.MigratedFiles = 0; ma2Progress.TotalFiles = 0; try { string databasePath = e.Argument as string; string connString = string.Format(@"data source={0};useutf16encoding=True", databasePath); SQLiteConnection myConn = new SQLiteConnection(connString); myConn.Open(); // get a list of unlinked files VideoLocalRepository repVids = new VideoLocalRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AniDB_AnimeRepository repAniAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); List<VideoLocal> vids = repVids.GetVideosWithoutEpisode(); ma2Progress.TotalFiles = vids.Count; foreach (VideoLocal vid in vids) { ma2Progress.CurrentFile = ma2Progress.CurrentFile + 1; workerMyAnime2.ReportProgress(0, ma2Progress); // search for this file in the XrossRef table in MA2 string sql = string.Format("SELECT AniDB_EpisodeID from CrossRef_Episode_FileHash WHERE Hash = '{0}' AND FileSize = {1}", vid.ED2KHash, vid.FileSize); SQLiteCommand sqCommand = new SQLiteCommand(sql); sqCommand.Connection = myConn; SQLiteDataReader myReader = sqCommand.ExecuteReader(); while (myReader.Read()) { int episodeID = 0; if (!int.TryParse(myReader.GetValue(0).ToString(), out episodeID)) continue; if (episodeID <= 0) continue; sql = string.Format("SELECT AnimeID from AniDB_Episode WHERE EpisodeID = {0}", episodeID); sqCommand = new SQLiteCommand(sql); sqCommand.Connection = myConn; SQLiteDataReader myReader2 = sqCommand.ExecuteReader(); while (myReader2.Read()) { int animeID = myReader2.GetInt32(0); // so now we have all the needed details we can link the file to the episode // as long as wehave the details in JMM AniDB_Anime anime = null; AniDB_Episode ep = repAniEps.GetByEpisodeID(episodeID); if (ep == null) { logger.Debug("Getting Anime record from AniDB...."); anime = JMMService.AnidbProcessor.GetAnimeInfoHTTP(animeID, true, ServerSettings.AutoGroupSeries); } else anime = repAniAnime.GetByAnimeID(animeID); // create the group/series/episode records if needed AnimeSeries ser = null; if (anime == null) continue; logger.Debug("Creating groups, series and episodes...."); // check if there is an AnimeSeries Record associated with this AnimeID ser = repSeries.GetByAnimeID(animeID); if (ser == null) { // create a new AnimeSeries record ser = anime.CreateAnimeSeriesAndGroup(); } ser.CreateAnimeEpisodes(); // check if we have any group status data for this associated anime // if not we will download it now AniDB_GroupStatusRepository repStatus = new AniDB_GroupStatusRepository(); if (repStatus.GetByAnimeID(anime.AnimeID).Count == 0) { CommandRequest_GetReleaseGroupStatus cmdStatus = new CommandRequest_GetReleaseGroupStatus(anime.AnimeID, false); cmdStatus.Save(); } // update stats ser.EpisodeAddedDate = DateTime.Now; repSeries.Save(ser); AnimeGroupRepository repGroups = new AnimeGroupRepository(); foreach (AnimeGroup grp in ser.AllGroupsAbove) { grp.EpisodeAddedDate = DateTime.Now; repGroups.Save(grp); } AnimeEpisode epAnime = repEps.GetByAniDBEpisodeID(episodeID); if (epAnime == null) continue; CrossRef_File_EpisodeRepository repXRefs = new CrossRef_File_EpisodeRepository(); CrossRef_File_Episode xref = new CrossRef_File_Episode(); try { xref.PopulateManually(vid, epAnime); } catch (Exception ex) { string msg = string.Format("Error populating XREF: {0} - {1}", vid.ToStringDetailed(), ex.ToString()); throw; } repXRefs.Save(xref); vid.RenameIfRequired(); vid.MoveFileIfRequired(); // update stats for groups and series if (ser != null) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); } // Add this file to the users list if (ServerSettings.AniDB_MyList_AddFiles) { CommandRequest_AddFileToMyList cmd = new CommandRequest_AddFileToMyList(vid.ED2KHash); cmd.Save(); } ma2Progress.MigratedFiles = ma2Progress.MigratedFiles + 1; workerMyAnime2.ReportProgress(0, ma2Progress); } myReader2.Close(); //Console.WriteLine(myReader.GetString(0)); } myReader.Close(); } myConn.Close(); ma2Progress.CurrentFile = ma2Progress.CurrentFile + 1; workerMyAnime2.ReportProgress(0, ma2Progress); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); ma2Progress.ErrorMessage = ex.Message; workerMyAnime2.ReportProgress(0, ma2Progress); } }
public List<Contract_AniDBReleaseGroup> GetReleaseGroupsForAnime(int animeID) { List<Contract_AniDBReleaseGroup> relGroups = new List<Contract_AniDBReleaseGroup>(); try { AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); AnimeSeries series = repSeries.GetByAnimeID(animeID); if (series == null) return relGroups; // get a list of all the release groups the user is collecting //List<int> userReleaseGroups = new List<int>(); Dictionary<int, int> userReleaseGroups = new Dictionary<int, int>(); foreach (AnimeEpisode ep in series.GetAnimeEpisodes()) { List<VideoLocal> vids = ep.GetVideoLocals(); foreach (VideoLocal vid in vids) { AniDB_File anifile = vid.GetAniDBFile(); if (anifile != null) { if (!userReleaseGroups.ContainsKey(anifile.GroupID)) userReleaseGroups[anifile.GroupID] = 0; userReleaseGroups[anifile.GroupID] = userReleaseGroups[anifile.GroupID] + 1; } } } // get all the release groups for this series AniDB_GroupStatusRepository repGrpStatus = new AniDB_GroupStatusRepository(); List<AniDB_GroupStatus> grpStatuses = repGrpStatus.GetByAnimeID(animeID); foreach (AniDB_GroupStatus gs in grpStatuses) { Contract_AniDBReleaseGroup contract = new Contract_AniDBReleaseGroup(); contract.GroupID = gs.GroupID; contract.GroupName = gs.GroupName; contract.EpisodeRange = gs.EpisodeRange; if (userReleaseGroups.ContainsKey(gs.GroupID)) { contract.UserCollecting = true; contract.FileCount = userReleaseGroups[gs.GroupID]; } else { contract.UserCollecting = false; contract.FileCount = 0; } relGroups.Add(contract); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return relGroups; }
public static void SyncCollectionToTrakt() { try { if (!ServerSettings.Trakt_IsEnabled || string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) return; // check that we have at least one user nominated for Trakt JMMUserRepository repUsers = new JMMUserRepository(); List<JMMUser> traktUsers = repUsers.GetTraktUsers(); if (traktUsers.Count == 0) return; AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); List<AnimeSeries> allSeries = repSeries.GetAll(); // now get the full users collection from Trakt List<TraktV2ShowCollectedResult> collected = new List<TraktV2ShowCollectedResult>(); List<TraktV2ShowWatchedResult> watched = new List<TraktV2ShowWatchedResult>(); if (!GetTraktCollectionInfo(ref collected, ref watched)) return; TraktV2SyncCollectionEpisodesByNumber syncCollectionAdd = new TraktV2SyncCollectionEpisodesByNumber(); TraktV2SyncCollectionEpisodesByNumber syncCollectionRemove = new TraktV2SyncCollectionEpisodesByNumber(); TraktV2SyncWatchedEpisodesByNumber syncHistoryAdd = new TraktV2SyncWatchedEpisodesByNumber(); TraktV2SyncWatchedEpisodesByNumber syncHistoryRemove = new TraktV2SyncWatchedEpisodesByNumber(); #region Local Collection Sync /////////////////////////////////////////////////////////////////////////////////////// // First take a look at our local collection and update on Trakt /////////////////////////////////////////////////////////////////////////////////////// AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); int counter = 0; foreach (AnimeSeries series in allSeries) { counter++; logger.Trace("Syncing check - local collection: {0} / {1} - {2}", counter, allSeries.Count, series.GetSeriesName()); AniDB_Anime anime = repAnime.GetByAnimeID(series.AniDB_ID); if (anime == null) continue; //if (anime.AnimeID != 3427) continue; TraktSummaryContainer traktSummary = new TraktSummaryContainer(); traktSummary.Populate(series.AniDB_ID); if (traktSummary.CrossRefTraktV2 == null || traktSummary.CrossRefTraktV2.Count == 0) continue; // get the current watched records for this series on Trakt foreach (AnimeEpisode ep in series.GetAnimeEpisodes()) { if (ep.EpisodeTypeEnum == enEpisodeType.Episode || ep.EpisodeTypeEnum == enEpisodeType.Special) { EpisodeSyncDetails epsync = ReconSyncTraktEpisode(series, ep, traktSummary, traktUsers, collected, watched, false); if (epsync != null) { switch (epsync.SyncType) { case TraktSyncType.CollectionAdd: syncCollectionAdd.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.CollectionRemove: syncCollectionRemove.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.HistoryAdd: syncHistoryAdd.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.HistoryRemove: syncHistoryRemove.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; } } } } } #endregion // refresh online info, just in case it was chnaged by the last operations if (!GetTraktCollectionInfo(ref collected, ref watched)) return; #region Online Collection Sync /////////////////////////////////////////////////////////////////////////////////////// // Now look at the collection according to Trakt, and remove it if we don't have it locally /////////////////////////////////////////////////////////////////////////////////////// CrossRef_AniDB_TraktV2Repository repCrossRef = new CrossRef_AniDB_TraktV2Repository(); counter = 0; foreach (TraktV2ShowCollectedResult col in collected) { counter++; logger.Trace("Syncing check - Online collection: {0} / {1} - {2}", counter, collected.Count, col.show.Title); //continue; // check if we have this series locally List<CrossRef_AniDB_TraktV2> xrefs = repCrossRef.GetByTraktID(col.show.ids.slug); if (xrefs.Count > 0) { foreach (CrossRef_AniDB_TraktV2 xref in xrefs) { AnimeSeries locSeries = repSeries.GetByAnimeID(xref.AnimeID); if (locSeries == null) continue; TraktSummaryContainer traktSummary = new TraktSummaryContainer(); traktSummary.Populate(locSeries.AniDB_ID); if (traktSummary.CrossRefTraktV2 == null || traktSummary.CrossRefTraktV2.Count == 0) continue; // if we have this series locSeries, let's sync the whole series foreach (AnimeEpisode ep in locSeries.GetAnimeEpisodes()) { if (ep.EpisodeTypeEnum == enEpisodeType.Episode || ep.EpisodeTypeEnum == enEpisodeType.Special) { EpisodeSyncDetails epsync = ReconSyncTraktEpisode(locSeries, ep, traktSummary, traktUsers, collected, watched, false); if (epsync != null) { switch (epsync.SyncType) { case TraktSyncType.CollectionAdd: syncCollectionAdd.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.CollectionRemove: syncCollectionRemove.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.HistoryAdd: syncHistoryAdd.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.HistoryRemove: syncHistoryRemove.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; } } } } } } else { // Actually we can't do this, because the user may have other non Anime series and Movies /* // series doesn't exist locally at all, so let's completely remove it from Trakt foreach (TraktV2CollectedSeason colSeason in col.seasons) { foreach (TraktV2CollectedEpisode colEp in colSeason.episodes) { string msg = string.Format("SYNC ONLINE: Removing from Trakt Collection: Slug: {0} - S:{1} - EP:{2}", col.show.ids.slug, colSeason.number, colEp.number); logger.Trace(msg); SyncEpisodeToTrakt(TraktSyncType.CollectionRemove, col.show.ids.slug, colSeason.number, colEp.number, DateTime.Now, false); } }*/ } } #endregion // refresh online info, just in case it was chnaged by the last operations if (!GetTraktCollectionInfo(ref collected, ref watched)) return; #region Online History (Watched/Unwatched) Sync /////////////////////////////////////////////////////////////////////////////////////// // Now look at the history according to Trakt, and remove it if we don't have it locally /////////////////////////////////////////////////////////////////////////////////////// counter = 0; foreach (TraktV2ShowWatchedResult wtch in watched) { counter++; logger.Trace("Syncing check - Online History: {0} / {1} - {2}", counter, watched.Count, wtch.show.Title); //continue; // check if we have this series locally List<CrossRef_AniDB_TraktV2> xrefs = repCrossRef.GetByTraktID(wtch.show.ids.slug); if (xrefs.Count > 0) { foreach (CrossRef_AniDB_TraktV2 xref in xrefs) { AnimeSeries locSeries = repSeries.GetByAnimeID(xref.AnimeID); if (locSeries == null) continue; TraktSummaryContainer traktSummary = new TraktSummaryContainer(); traktSummary.Populate(locSeries.AniDB_ID); if (traktSummary.CrossRefTraktV2 == null || traktSummary.CrossRefTraktV2.Count == 0) continue; // if we have this series locSeries, let's sync the whole series foreach (AnimeEpisode ep in locSeries.GetAnimeEpisodes()) { if (ep.EpisodeTypeEnum == enEpisodeType.Episode || ep.EpisodeTypeEnum == enEpisodeType.Special) { EpisodeSyncDetails epsync = ReconSyncTraktEpisode(locSeries, ep, traktSummary, traktUsers, collected, watched, false); if (epsync != null) { switch (epsync.SyncType) { case TraktSyncType.CollectionAdd: syncCollectionAdd.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.CollectionRemove: syncCollectionRemove.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.HistoryAdd: syncHistoryAdd.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; case TraktSyncType.HistoryRemove: syncHistoryRemove.AddEpisode(epsync.Slug, epsync.Season, epsync.EpNumber, epsync.EpDate); break; } } } } } } else { // Actually we can't do this, because the user may have other non Anime series and Movies /* // series doesn't exist locally at all, so let's completely remove it from Trakt foreach (TraktV2WatchedSeason wtchSeason in wtch.seasons) { foreach (TraktV2WatchedEpisode wtchEp in wtchSeason.episodes) { string msg = string.Format("SYNC ONLINE: Removing from Trakt History: Slug: {0} - S:{1} - EP:{2}", wtch.show.ids.slug, wtchSeason.number, wtchEp.number); logger.Trace(msg); SyncEpisodeToTrakt(TraktSyncType.HistoryRemove, wtch.show.ids.slug, wtchSeason.number, wtchEp.number, DateTime.Now, false); } }*/ } } #endregion // send the data to Trakt string json = string.Empty; string url = TraktURIs.SyncCollectionAdd; string retData = string.Empty; if (syncCollectionAdd.shows != null && syncCollectionAdd.shows.Count > 0) { json = JSONHelper.Serialize<TraktV2SyncCollectionEpisodesByNumber>(syncCollectionAdd); url = TraktURIs.SyncCollectionAdd; retData = string.Empty; SendData(url, json, "POST", BuildRequestHeaders(), ref retData); } if (syncCollectionRemove.shows != null && syncCollectionRemove.shows.Count > 0) { json = JSONHelper.Serialize<TraktV2SyncCollectionEpisodesByNumber>(syncCollectionRemove); url = TraktURIs.SyncCollectionRemove; retData = string.Empty; SendData(url, json, "POST", BuildRequestHeaders(), ref retData); } if (syncHistoryAdd.shows != null && syncHistoryAdd.shows.Count > 0) { json = JSONHelper.Serialize<TraktV2SyncWatchedEpisodesByNumber>(syncHistoryAdd); url = TraktURIs.SyncHistoryAdd; retData = string.Empty; SendData(url, json, "POST", BuildRequestHeaders(), ref retData); } if (syncHistoryRemove.shows != null && syncHistoryRemove.shows.Count > 0) { json = JSONHelper.Serialize<TraktV2SyncWatchedEpisodesByNumber>(syncHistoryRemove); url = TraktURIs.SyncHistoryRemove; retData = string.Empty; SendData(url, json, "POST", BuildRequestHeaders(), ref retData); } logger.Trace("Test"); } catch (Exception ex) { logger.ErrorException("Error in TraktTVHelper.SyncCollectionToTrakt: " + ex.ToString(), ex); } }
public Contract_Trakt_Activity GetTraktFriendInfo(int maxResults, bool animeOnly, bool getShouts, bool getScrobbles) { CrossRef_AniDB_TraktRepository repXrefTrakt = new CrossRef_AniDB_TraktRepository(); CrossRef_AniDB_TvDBV2Repository repXrefTvDB = new CrossRef_AniDB_TvDBV2Repository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); Trakt_FriendRepository repFriends = new Trakt_FriendRepository(); Trakt_EpisodeRepository repEpisodes = new Trakt_EpisodeRepository(); Trakt_ShowRepository repShows = new Trakt_ShowRepository(); Contract_Trakt_Activity contract = new Contract_Trakt_Activity(); contract.HasTraktAccount = true; if (string.IsNullOrEmpty(ServerSettings.Trakt_Username) || string.IsNullOrEmpty(ServerSettings.Trakt_Password)) contract.HasTraktAccount = false; contract.TraktFriends = new List<Contract_Trakt_Friend>(); contract.TraktFriendRequests = new List<Contract_Trakt_FriendFrequest>(); contract.TraktFriendActivity = new List<Contract_Trakt_FriendActivity>(); try { int i = 1; foreach (TraktTV_Activity act in StatsCache.Instance.TraktFriendActivityInfo) { if (i >= maxResults) break; if (act.ActivityAction == (int)TraktActivityAction.Scrobble && !getScrobbles) continue; if (act.ActivityAction == (int)TraktActivityAction.Shout && !getShouts) continue; Contract_Trakt_FriendActivity contractAct = new Contract_Trakt_FriendActivity(); if (act.show == null) continue; // find the anime and series based on the trakt id int? animeID = null; CrossRef_AniDB_Trakt xref = null; if (act.episode != null) xref = repXrefTrakt.GetByTraktID(act.show.TraktID, int.Parse(act.episode.season)); if (xref != null) animeID = xref.AnimeID; else { // try a rough match // since we won't always do an exact match by season List<CrossRef_AniDB_Trakt> traktXrefs = repXrefTrakt.GetByTraktID(act.show.TraktID); if (traktXrefs.Count > 0) animeID = traktXrefs[0].AnimeID; else { // try the tvdb id instead //TODO /* CrossRef_AniDB_TvDBV2 xrefTvDB = null; if (act.episode != null) xrefTvDB = repXrefTvDB.GetByTvDBID(int.Parse(act.show.tvdb_id), int.Parse(act.episode.season)); if (xrefTvDB != null) animeID = xrefTvDB.AnimeID;*/ } } // skip this activity if we can't find the anime and the user only wants to see anime related stuff if (!animeID.HasValue && animeOnly) { //TODO // however let's try and look it up on the web cache to see if it is an anime // this just might be an anime that user doesn't have in their local database continue; } // activity details contractAct.ActivityAction = act.ActivityAction; contractAct.ActivityType = act.ActivityType; contractAct.ActivityDate = Utils.GetAniDBDateAsDate(act.timestamp); if (act.elapsed != null) { contractAct.Elapsed = act.elapsed.full; contractAct.ElapsedShort = act.elapsed.shortElapsed; } Trakt_Friend traktFriend = repFriends.GetByUsername(act.user.username); if (traktFriend == null) return null; // user details contractAct.User = new Contract_Trakt_User(); contractAct.User.Trakt_FriendID = traktFriend.Trakt_FriendID; contractAct.User.Username = act.user.username; contractAct.User.Full_name = act.user.full_name; contractAct.User.Gender = act.user.gender; contractAct.User.Age = act.user.age; contractAct.User.Location = act.user.location; contractAct.User.About = act.user.about; contractAct.User.Joined = act.user.joined; contractAct.User.Avatar = act.user.avatar; contractAct.User.Url = act.user.url; contractAct.User.JoinedDate = Utils.GetAniDBDateAsDate(act.user.joined); // episode details if (act.ActivityAction == (int)TraktActivityAction.Scrobble && act.episode != null) // scrobble episode { contractAct.Episode = new Contract_Trakt_WatchedEpisode(); contractAct.Episode.AnimeSeriesID = null; contractAct.Episode.Episode_Number = act.episode.number; contractAct.Episode.Episode_Overview = act.episode.overview; contractAct.Episode.Episode_Season = act.episode.season; contractAct.Episode.Episode_Title = act.episode.title; contractAct.Episode.Episode_Url = act.episode.url; contractAct.Episode.Trakt_EpisodeID = -1; if (act.episode.images != null) contractAct.Episode.Episode_Screenshot = act.episode.images.screen; if (act.show != null) { contractAct.Episode.TraktShow = act.show.ToContract(); Trakt_Show show = repShows.GetByTraktID(act.show.TraktID); if (show != null) { Trakt_Episode episode = repEpisodes.GetByShowIDSeasonAndEpisode(show.Trakt_ShowID, int.Parse(act.episode.season), int.Parse(act.episode.number)); if (episode != null) contractAct.Episode.Trakt_EpisodeID = episode.Trakt_EpisodeID; } if (animeID.HasValue) { AnimeSeries ser = repSeries.GetByAnimeID(animeID.Value); if (ser != null) contractAct.Episode.AnimeSeriesID = ser.AnimeSeriesID; AniDB_Anime anime = repAnime.GetByAnimeID(animeID.Value); if (anime != null) contractAct.Episode.Anime = anime.ToContract(true, null); } } } // shout details if (act.ActivityAction == (int)TraktActivityAction.Shout && act.shout != null) // shout { contractAct.Shout = new Contract_Trakt_Shout(); contractAct.Shout.ShoutType = act.ActivityType; // episode or show contractAct.Shout.Text = act.shout.text; contractAct.Shout.Spoiler = act.shout.spoiler; contractAct.Shout.AnimeSeriesID = null; if (act.ActivityType == 1 && act.episode != null) // episode { contractAct.Shout.Episode_Number = act.episode.number; contractAct.Shout.Episode_Overview = act.episode.overview; contractAct.Shout.Episode_Season = act.episode.season; contractAct.Shout.Episode_Title = act.episode.title; contractAct.Shout.Episode_Url = act.episode.url; if (act.episode.images != null) contractAct.Shout.Episode_Screenshot = act.episode.images.screen; } if (act.show != null) // episode or show { if (act.episode == null) contractAct.Shout.Episode_Screenshot = act.show.images.fanart; contractAct.Shout.TraktShow = act.show.ToContract(); if (animeID.HasValue) { AnimeSeries ser = repSeries.GetByAnimeID(animeID.Value); if (ser != null) contractAct.Shout.AnimeSeriesID = ser.AnimeSeriesID; AniDB_Anime anime = repAnime.GetByAnimeID(animeID.Value); if (anime != null) contractAct.Shout.Anime = anime.ToContract(true, null); } } } contract.TraktFriendActivity.Add(contractAct); i++; } foreach (TraktTVFriendRequest req in StatsCache.Instance.TraktFriendRequests) { Contract_Trakt_FriendFrequest contractReq = req.ToContract(); contract.TraktFriendRequests.Add(contractReq); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return contract; }