public static void UpdateAniDBTitles() { int freqHours = 100; bool process = ServerSettings.AniDB_Username.Equals("jonbaby", StringComparison.InvariantCultureIgnoreCase) || ServerSettings.AniDB_Username.Equals("jmediamanager", StringComparison.InvariantCultureIgnoreCase); if (!process) return; // check for any updated anime info every 100 hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBTitles); if (sched != null) { // if we have run this in the last 100 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) return; } if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AniDBTitles; sched.UpdateDetails = ""; } sched.LastUpdate = DateTime.Now; repSched.Save(sched); CommandRequest_GetAniDBTitles cmd = new CommandRequest_GetAniDBTitles(); cmd.Save(); }
public static void CheckForMALUpdate(bool forceRefresh) { if (ServerSettings.AniDB_Anime_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.MAL_UpdateFrequency); // check for any updated anime info every 12 hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.MALUpdate); if (sched != null) { // 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; } } RunImport_ScanMAL(); if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.MALUpdate; sched.UpdateDetails = ""; } sched.LastUpdate = DateTime.Now; repSched.Save(sched); }
public static void SendUserInfoUpdate(bool forceRefresh) { // update the anonymous user info every 12 hours // we will always assume that an anime was downloaded via http first ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AzureUserInfo); if (sched != null) { // if we have run this in the last 6 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < 6) { if (!forceRefresh) return; } } if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AzureUserInfo; sched.UpdateDetails = ""; } sched.LastUpdate = DateTime.Now; repSched.Save(sched); CommandRequest_Azure_SendUserInfo cmd = new CommandRequest_Azure_SendUserInfo(ServerSettings.AniDB_Username); cmd.Save(); }
public static void CheckForTraktSyncUpdate(bool forceRefresh) { if (ServerSettings.Trakt_SyncFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.Trakt_SyncFrequency); // update the calendar every xxx hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.TraktSync); if (sched != null) { // if we have run this in the last xxx hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; logger.Trace("Last Trakt Sync: {0} minutes ago", tsLastRun.TotalMinutes); if (tsLastRun.TotalHours < freqHours) { if (!forceRefresh) return; } } if (ServerSettings.Trakt_IsEnabled && !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) { CommandRequest_TraktSyncCollection cmd = new CommandRequest_TraktSyncCollection(false); cmd.Save(); } }
private void scheduleUpdate(IEnumerable <MergeRequestKey> keys, DiscussionUpdateType type) { bool isSchedulingGlobalPeriodicUpdate() => keys == null && type == DiscussionUpdateType.PeriodicUpdate; bool isProcessingGlobalPeriodicUpdate() => _scheduledUpdates .Any(item => item.MergeRequests == null && item.Type == DiscussionUpdateType.PeriodicUpdate); if (isSchedulingGlobalPeriodicUpdate() && isProcessingGlobalPeriodicUpdate()) { return; } _scheduledUpdates.Enqueue(new ScheduledUpdate(keys, type)); _timer?.SynchronizingObject.BeginInvoke(new Action(async() => { // To avoid re-entrance in updateDiscussionsAsync() await waitForUpdateCompetion(null); Debug.Assert(!_updating.Any()); if (_scheduledUpdates.Any()) { ScheduledUpdate scheduledUpdate = _scheduledUpdates.Peek(); await processScheduledUpdate(scheduledUpdate); _scheduledUpdates.Dequeue(); } }), null); }
async private Task processScheduledUpdate(ScheduledUpdate scheduledUpdate) { if (scheduledUpdate.MergeRequests == null) { getAllMergeRequests( out IEnumerable <MergeRequestKey> matchingFilter, out IEnumerable <MergeRequestKey> nonMatchingFilter); traceDetailed(String.Format( "Processing scheduled update of discussions for {0}+{1} merge requests (ALL)", matchingFilter.Count(), nonMatchingFilter.Count())); await TaskUtils.RunConcurrentFunctionsAsync(matchingFilter, x => updateDiscussionsSafeAsync(x, scheduledUpdate.Type), () => Constants.DiscussionLoaderMergeRequestBatchLimits, null); await TaskUtils.RunConcurrentFunctionsAsync(nonMatchingFilter, x => updateDiscussionsSafeAsync(x, scheduledUpdate.Type), () => Constants.DiscussionLoaderMergeRequestBatchLimits, null); } else { traceDetailed(String.Format( "Processing scheduled update of discussions for {0} merge requests", scheduledUpdate.MergeRequests.Count())); await TaskUtils.RunConcurrentFunctionsAsync(scheduledUpdate.MergeRequests, x => updateDiscussionsSafeAsync(x, scheduledUpdate.Type), () => Constants.DiscussionLoaderMergeRequestBatchLimits, null); } }
public ScheduledUpdate GetByUpdateType(int uptype) { using (var session = JMMService.SessionFactory.OpenSession()) { ScheduledUpdate cr = session .CreateCriteria(typeof(ScheduledUpdate)) .Add(Restrictions.Eq("UpdateType", uptype)) .UniqueResult <ScheduledUpdate>(); return(cr); } }
public void Save(ScheduledUpdate obj) { using (var session = JMMService.SessionFactory.OpenSession()) { // populate the database using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(obj); transaction.Commit(); } } }
/// <summary> /// Called when the text is changed in the combobox /// </summary> protected override void OnSelectedIndexChanged(EventArgs e) { if (column.reqursionGuard) { return; } if (!Visible) { return; } column.reqursionGuard = true; try { column.ColumnStartedEditing(this); string value = column.comboBox.Text; if (column.IsValueExpressionSelected()) { value = CurrentText; ExpressionForm expressionForm = new ExpressionForm(column._designerHost); expressionForm.Expression = value; IUIService uiService = column._designerHost.GetService(typeof(IUIService)) as IUIService; if (uiService.ShowDialog(expressionForm) == DialogResult.OK) { value = expressionForm.Expression; CurrentText = value; } else { value = (column.cm != null && column.iCurrentRow >= 0) ? column.GetColumnValueAtRow(column.cm, column.iCurrentRow) as string : string.Empty; } this.Focus(); } else if (column.IsValueBlankSelected()) { value = string.Empty; } if (value != null) { CurrentText = value; ScheduledUpdate.ScheduleUpdate(this, value); } } finally { column.reqursionGuard = false; } base.OnSelectedIndexChanged(e); }
public void Delete(int id) { using (var session = JMMService.SessionFactory.OpenSession()) { // populate the database using (var transaction = session.BeginTransaction()) { ScheduledUpdate cr = GetByID(id); if (cr != null) { session.Delete(cr); transaction.Commit(); } } } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_TraktSyncCollection"); try { if (!ServerSettings.Trakt_IsEnabled || string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) { return; } ScheduledUpdate sched = RepoFactory.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.TraktSync); if (sched == null) { sched = new ScheduledUpdate { UpdateType = (int)ScheduledUpdateType.TraktSync, UpdateDetails = "" }; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.Trakt_SyncFrequency); // if we have run this in the last xxx hours then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) { return; } } } sched.LastUpdate = DateTime.Now; RepoFactory.ScheduledUpdate.Save(sched); TraktTVHelper.SyncCollectionToTrakt(); } catch (Exception ex) { logger.Error("Error processing CommandRequest_TraktSyncCollection: {0}", ex.ToString()); return; } }
public static void CheckForTvDBUpdates(bool forceRefresh) { if (ServerSettings.TvDB_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.TvDB_UpdateFrequency); // update tvdb info every 12 hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.TvDBInfo); if (sched != null) { // 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; } } List<int> tvDBIDs = new List<int>(); bool tvDBOnline = false; string serverTime = JMMService.TvdbHelper.IncrementalTvDBUpdate(ref tvDBIDs, ref tvDBOnline); if (tvDBOnline) { foreach (int tvid in tvDBIDs) { // download and update series info, episode info and episode images // will also download fanart, posters and wide banners CommandRequest_TvDBUpdateSeriesAndEpisodes cmdSeriesEps = new CommandRequest_TvDBUpdateSeriesAndEpisodes(tvid, false); cmdSeriesEps.Save(); } } if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.TvDBInfo; } sched.LastUpdate = DateTime.Now; sched.UpdateDetails = serverTime; repSched.Save(sched); TvDBHelper.ScanForMatches(); }
public override void Run(IProgress <ICommand> progress = null) { logger.Info("Processing CommandRequest_UpdateMyListStats"); try { ReportInit(progress); // we will always assume that an anime was downloaded via http first ScheduledUpdate sched = Repo.Instance.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.AniDBMylistStats); ReportUpdate(progress, 30); if (sched != null) { int freqHours = Utils.GetScheduledHours(ServerSettings.Instance.AniDb.MyListStats_UpdateFrequency); // if we have run this in the last 24 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) { ReportFinish(progress); } } } using (var upd = Repo.Instance.ScheduledUpdate.BeginAddOrUpdate(sched, () => new ScheduledUpdate { UpdateType = (int)ScheduledUpdateType.AniDBMylistStats, UpdateDetails = string.Empty } )) { upd.Entity.LastUpdate = DateTime.Now; upd.Commit(); } ReportUpdate(progress, 60); ShokoService.AnidbProcessor.UpdateMyListStats(); ReportFinish(progress); } catch (Exception ex) { ReportError(progress, $"Error processing Command AniDB.UpdateMyListStats: {ex}", ex); } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_TraktUpdateAllSeries"); try { ScheduledUpdate sched = RepoFactory.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.TraktUpdate); if (sched == null) { sched = new ScheduledUpdate { UpdateType = (int)ScheduledUpdateType.TraktUpdate, UpdateDetails = string.Empty }; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.Trakt_UpdateFrequency); // if we have run this in the last xxx hours then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) { return; } } } sched.LastUpdate = DateTime.Now; RepoFactory.ScheduledUpdate.Save(sched); // update all info TraktTVHelper.UpdateAllInfo(); // scan for new matches TraktTVHelper.ScanForMatches(); } catch (Exception ex) { logger.Error("Error processing CommandRequest_TraktUpdateAllSeries: {0}", ex.ToString()); return; } }
public static void CheckForAniDBFileUpdate(bool forceRefresh) { if (ServerSettings.AniDB_File_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_File_UpdateFrequency); // check for any updated anime info every 12 hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBFileUpdates); if (sched != null) { // 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; } } UpdateAniDBFileData(true, false, false); // files which have been hashed, but don't have an associated episode VideoLocalRepository repVidLocals = new VideoLocalRepository(); List<VideoLocal> filesWithoutEpisode = repVidLocals.GetVideosWithoutEpisode(); foreach (VideoLocal vl in filesWithoutEpisode) { CommandRequest_ProcessFile cmd = new CommandRequest_ProcessFile(vl.VideoLocalID, true); cmd.Save(); } // now check for any files which have been manually linked and are less than 30 days old if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AniDBFileUpdates; sched.UpdateDetails = ""; } sched.LastUpdate = DateTime.Now; repSched.Save(sched); }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_UpdateMylistStats"); try { // we will always assume that an anime was downloaded via http first ScheduledUpdate sched = RepoFactory.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.AniDBMylistStats); if (sched == null) { sched = new ScheduledUpdate { UpdateType = (int)ScheduledUpdateType.AniDBMylistStats, UpdateDetails = string.Empty }; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_MyListStats_UpdateFrequency); // if we have run this in the last 24 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) { return; } } } sched.LastUpdate = DateTime.Now; RepoFactory.ScheduledUpdate.Save(sched); ShokoService.AnidbProcessor.UpdateMyListStats(); } catch (Exception ex) { logger.Error("Error processing CommandRequest_UpdateMylistStats: {0}", ex.ToString()); return; } }
async private Task processScheduledUpdate(ScheduledUpdate scheduledUpdate) { if (scheduledUpdate.MergeRequests == null) { getAllMergeRequests( out IEnumerable <MergeRequestKey> matchingFilter, out IEnumerable <MergeRequestKey> nonMatchingFilter); Trace.TraceInformation(String.Format( "[DiscussionManager] Processing scheduled update of discussions for {0}+{1} merge requests (ALL)", matchingFilter.Count(), nonMatchingFilter.Count())); await TaskUtils.RunConcurrentFunctionsAsync(matchingFilter, x => updateDiscussions(x, scheduledUpdate.Type), () => Constants.DiscussionLoaderMergeRequestBatchLimits, () => _reconnect); await TaskUtils.RunConcurrentFunctionsAsync(nonMatchingFilter, x => updateDiscussions(x, scheduledUpdate.Type), () => Constants.DiscussionLoaderMergeRequestBatchLimits, () => _reconnect); } else { Trace.TraceInformation(String.Format( "[DiscussionManager] Processing scheduled update of discussions for {0} merge requests", scheduledUpdate.MergeRequests.Count())); await TaskUtils.RunConcurrentFunctionsAsync(scheduledUpdate.MergeRequests, x => updateDiscussions(x, scheduledUpdate.Type), () => Constants.DiscussionLoaderMergeRequestBatchLimits, () => _reconnect); } if (_reconnect) { Trace.TraceInformation(String.Format( "[DiscussionManager] update loop is cancelled due to _reconnect state")); } }
public static void CheckForMyListStatsUpdate(bool forceRefresh) { if (ServerSettings.AniDB_MyListStats_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_MyListStats_UpdateFrequency); ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBMylistStats); if (sched != null) { // if we have run this in the last 24 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; logger.Trace("Last AniDB MyList Stats Update: {0} minutes ago", tsLastRun.TotalMinutes); if (tsLastRun.TotalHours < freqHours) { if (!forceRefresh) return; } } CommandRequest_UpdateMylistStats cmd = new CommandRequest_UpdateMylistStats(forceRefresh); cmd.Save(); }
protected override void Dispose(bool disposing) { if (isDisposed) { return; } try { if (disposing) { if (scheduledUpdate != null) { scheduledUpdate.Dispose(); scheduledUpdate = null; } } isDisposed = true; } finally { base.Dispose(disposing); } }
public static void CheckForAnimeUpdate(bool forceRefresh) { if (ServerSettings.AniDB_Anime_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_Anime_UpdateFrequency); // check for any updated anime info every 12 hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBUpdates); if (sched != null) { // 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; } } CommandRequest_GetUpdated cmd = new CommandRequest_GetUpdated(true); cmd.Save(); }
private void scheduleUpdate(IEnumerable <MergeRequestKey> keys, DiscussionUpdateType type) { if (type == DiscussionUpdateType.InitialSnapshot) { _reconnect = true; } // make a copy of `keys` just in case _scheduledUpdates.Enqueue(new ScheduledUpdate(keys, type)); _timer?.SynchronizingObject.BeginInvoke(new Action(async() => { // 1. To avoid re-entrance in updateDiscussionsAsync() // 2. Make it before resetting _reconnect flag to allow an ongoing update loop to break await waitForUpdateCompetion(null); Debug.Assert(!_updating.Any()); if (_scheduledUpdates.Any()) { ScheduledUpdate scheduledUpdate = _scheduledUpdates.Dequeue(); if (_reconnect) { if (scheduledUpdate.Type != DiscussionUpdateType.InitialSnapshot) { Trace.TraceInformation("[DiscussionManager] update is skipped due to _reconnect state"); return; } Debug.Assert(!_cachedDiscussions.Any() && !_closed.Any()); _reconnect = false; } await processScheduledUpdate(scheduledUpdate); } }), null); }
public static void CheckForTraktTokenUpdate(bool forceRefresh) { try { // by updating the Trakt token regularly, the user won't need to authorize again int freqHours = 24; // we need to update this daily ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.TraktToken); if (sched != null) { // if we have run this in the last xxx hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; logger.Trace("Last Trakt Token Update: {0} minutes ago", tsLastRun.TotalMinutes); if (tsLastRun.TotalHours < freqHours) { if (!forceRefresh) return; } } TraktTVHelper.RefreshAuthToken(); if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.TraktToken; sched.UpdateDetails = ""; } sched.LastUpdate = DateTime.Now; repSched.Save(sched); } catch (Exception ex) { logger.ErrorException("Error in CheckForTraktTokenUpdate: " + ex.ToString(), ex); } }
public static void CheckForCalendarUpdate(bool forceRefresh) { if (ServerSettings.AniDB_Calendar_UpdateFrequency == ScheduledUpdateFrequency.Never && !forceRefresh) return; int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_Calendar_UpdateFrequency); // update the calendar every 12 hours // we will always assume that an anime was downloaded via http first ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBCalendar); if (sched != null) { // 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; } } CommandRequest_GetCalendar cmd = new CommandRequest_GetCalendar(forceRefresh); cmd.Save(); }
protected void RunUpdate(long ticks) { ApplyChanges(); _ticks += ticks; do { if (_scheduledUpdates.Count == 0) { return; } if (_scheduledUpdates.MinKey() > _ticks) { return; } var test = _scheduledUpdates.RemoveMin(); test.Callback((ulong)(_ticks - test.LastUpdate)); if (test.Interval > 0) { var next = new ScheduledUpdate(test.Callback, _ticks, test.NextUpdate + test.Interval, test.Interval); _scheduledUpdates.Insert(next, next.NextUpdate); } } while (true); }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_GetCalendar"); try { // we will always assume that an anime was downloaded via http first ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBCalendar); if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AniDBCalendar; sched.UpdateDetails = ""; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_Calendar_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; } } } sched.LastUpdate = DateTime.Now; repSched.Save(sched); CalendarCollection colCalendars = JMMService.AnidbProcessor.GetCalendarUDP(); if (colCalendars == null || colCalendars.Calendars == null) { logger.Error("Could not get calendar from AniDB"); return; } foreach (AniDBAPI.Calendar cal in colCalendars.Calendars) { AniDB_Anime anime = repAnime.GetByAnimeID(cal.AnimeID); if (anime != null) { // don't update if the local data is less 2 days old TimeSpan ts = DateTime.Now - anime.DateTimeUpdated; if (ts.TotalDays >= 2) { CommandRequest_GetAnimeHTTP cmdAnime = new CommandRequest_GetAnimeHTTP(cal.AnimeID, true, false); cmdAnime.Save(); } else { // update the release date even if we don't update the anime record if (anime.AirDate != cal.ReleaseDate) { anime.AirDate = cal.ReleaseDate; repAnime.Save(anime); AnimeSeriesRepository srepo = new AnimeSeriesRepository(); AnimeSeries ser = srepo.GetByAnimeID(anime.AnimeID); if (ser != null) { srepo.Save(ser, true, false); } } } } else { CommandRequest_GetAnimeHTTP cmdAnime = new CommandRequest_GetAnimeHTTP(cal.AnimeID, true, false); cmdAnime.Save(); } } } catch (Exception ex) { logger.ErrorException("Error processing CommandRequest_GetCalendar: " + ex.ToString(), ex); return; } }
// ReSharper disable once RedundantAssignment public static string IncrementalTvDBUpdate(ref List <int> tvDBIDs, ref bool tvDBOnline) { // check if we have record of doing an automated update for the TvDB previously // if we have then we have kept a record of the server time and can do a delta update // otherwise we need to do a full update and keep a record of the time List <int> allTvDBIDs = new List <int>(); tvDBIDs = tvDBIDs ?? new List <int>(); tvDBOnline = true; try { // record the tvdb server time when we started // we record the time now instead of after we finish, to include any possible misses string currentTvDBServerTime = CurrentServerTime; if (currentTvDBServerTime.Length == 0) { tvDBOnline = false; return(currentTvDBServerTime); } foreach (SVR_AnimeSeries ser in RepoFactory.AnimeSeries.GetAll()) { List <CrossRef_AniDB_TvDB> xrefs = ser.GetCrossRefTvDB(); if (xrefs == null) { continue; } foreach (CrossRef_AniDB_TvDB xref in xrefs) { if (!allTvDBIDs.Contains(xref.TvDBID)) { allTvDBIDs.Add(xref.TvDBID); } } } // get the time we last did a TvDB update // if this is the first time it will be null // update the anidb info ever 24 hours ScheduledUpdate sched = RepoFactory.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.TvDBInfo); string lastServerTime = string.Empty; if (sched != null) { TimeSpan ts = DateTime.Now - sched.LastUpdate; logger.Trace($"Last tvdb info update was {ts.TotalHours} hours ago"); if (!string.IsNullOrEmpty(sched.UpdateDetails)) { lastServerTime = sched.UpdateDetails; } // the UpdateDetails field for this type will actually contain the last server time from // TheTvDB that a full update was performed } // get a list of updates from TvDB since that time if (lastServerTime.Length > 0) { if (!long.TryParse(lastServerTime, out long lasttimeseconds)) { lasttimeseconds = -1; } if (lasttimeseconds < 0) { tvDBIDs = allTvDBIDs; return(CurrentServerTime); } List <int> seriesList = GetUpdatedSeriesList(lasttimeseconds); logger.Trace($"{seriesList.Count} series have been updated since last download"); logger.Trace($"{allTvDBIDs.Count} TvDB series locally"); foreach (int id in seriesList) { if (allTvDBIDs.Contains(id)) { tvDBIDs.Add(id); } } logger.Trace($"{tvDBIDs.Count} TvDB local series have been updated since last download"); } else { // use the full list tvDBIDs = allTvDBIDs; } return(CurrentServerTime); } catch (Exception ex) { logger.Error(ex, $"IncrementalTvDBUpdate: {ex}"); return(string.Empty); } }
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; } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_SyncMyList"); try { // we will always assume that an anime was downloaded via http first ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); VideoLocalRepository repVidLocals = new VideoLocalRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.AniDBMyListSync); if (sched == null) { sched = new ScheduledUpdate(); sched.UpdateType = (int)ScheduledUpdateType.AniDBMyListSync; sched.UpdateDetails = ""; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.AniDB_MyList_UpdateFrequency); // if we have run this in the last 24 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) { return; } } } AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList(); cmd.Init(ServerSettings.AniDB_Username, ServerSettings.AniDB_Password); enHelperActivityType ev = cmd.Process(); if (ev == enHelperActivityType.GotMyListHTTP && cmd.MyListItems.Count > 1) { int totalItems = 0; int watchedItems = 0; int modifiedItems = 0; double pct = 0; // 2. find files locally for the user, which are not recorded on anidb // and then add them to anidb Dictionary <int, Raw_AniDB_MyListFile> onlineFiles = new Dictionary <int, Raw_AniDB_MyListFile>(); foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) { onlineFiles[myitem.FileID] = myitem; } Dictionary <string, AniDB_File> dictAniFiles = new Dictionary <string, AniDB_File>(); List <AniDB_File> allAniFiles = repAniFile.GetAll(); foreach (AniDB_File anifile in allAniFiles) { dictAniFiles[anifile.Hash] = anifile; } int missingFiles = 0; foreach (VideoLocal vid in repVidLocals.GetAll()) { if (!dictAniFiles.ContainsKey(vid.Hash)) { continue; } int fileID = dictAniFiles[vid.Hash].FileID; if (!onlineFiles.ContainsKey(fileID)) { // means we have found a file in our local collection, which is not recorded online CommandRequest_AddFileToMyList cmdAddFile = new CommandRequest_AddFileToMyList(vid.Hash); cmdAddFile.Save(); missingFiles++; } } logger.Info(string.Format("MYLIST Missing Files: {0} Added to queue for inclusion", missingFiles)); JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); VideoLocal_UserRepository repVidUsers = new VideoLocal_UserRepository(); CrossRef_File_EpisodeRepository repFileEp = new CrossRef_File_EpisodeRepository(); // 1 . sync mylist items foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) { // ignore files mark as deleted by the user if (myitem.State == (int)AniDBFileStatus.Deleted) { continue; } totalItems++; if (myitem.IsWatched) { watchedItems++; } //calculate percentage pct = (double)totalItems / (double)cmd.MyListItems.Count * (double)100; string spct = pct.ToString("#0.0"); 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; } } } if (!string.IsNullOrEmpty(hash)) { // find the video associated with this record VideoLocal vl = repVidLocals.GetByHash(hash); if (vl == null) { continue; } foreach (JMMUser juser in aniDBUsers) { bool localStatus = false; int? jmmUserID = null; // doesn't matter which anidb user we use jmmUserID = juser.JMMUserID; VideoLocal_User userRecord = vl.GetUserRecord(juser.JMMUserID); if (userRecord != null) { localStatus = true; } string action = ""; if (localStatus != myitem.IsWatched) { if (localStatus == true) { // local = watched, anidb = unwatched if (ServerSettings.AniDB_MyList_ReadUnwatched) { modifiedItems++; if (jmmUserID.HasValue) { vl.ToggleWatchedStatus(myitem.IsWatched, false, myitem.WatchedDate, false, false, jmmUserID.Value, false, true); } action = "Used AniDB Status"; } } else { // means local is un-watched, and anidb is watched if (ServerSettings.AniDB_MyList_ReadWatched) { modifiedItems++; if (jmmUserID.HasValue) { vl.ToggleWatchedStatus(true, false, myitem.WatchedDate, false, false, jmmUserID.Value, false, true); } action = "Updated Local record to Watched"; } } string msg = string.Format( "MYLISTDIFF:: File {0} - Local Status = {1}, AniDB Status = {2} --- {3}", vl.FullServerPath, localStatus, myitem.IsWatched, action); logger.Info(msg); } } //string msg = string.Format("MYLIST:: File {0} - Local Status = {1}, AniDB Status = {2} --- {3}", // vl.FullServerPath, localStatus, myitem.IsWatched, action); //logger.Info(msg); } } // now update all stats Importer.UpdateAllStats(); logger.Info("Process MyList: {0} Items, {1} Watched, {2} Modified", totalItems, watchedItems, modifiedItems); sched.LastUpdate = DateTime.Now; repSched.Save(sched); } } catch (Exception ex) { logger.Error("Error processing CommandRequest_SyncMyList: {0} ", ex.ToString()); return; } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_SyncMyList"); try { // we will always assume that an anime was downloaded via http first ScheduledUpdate sched = RepoFactory.ScheduledUpdate.GetByUpdateType((int)ScheduledUpdateType.AniDBMyListSync); if (sched == null) { sched = new ScheduledUpdate { UpdateType = (int)ScheduledUpdateType.AniDBMyListSync, UpdateDetails = string.Empty }; } else { int freqHours = Utils.GetScheduledHours(ServerSettings.Instance.AniDb.MyList_UpdateFrequency); // if we have run this in the last 24 hours and are not forcing it, then exit TimeSpan tsLastRun = DateTime.Now - sched.LastUpdate; if (tsLastRun.TotalHours < freqHours) { if (!ForceRefresh) { return; } } } // Get the list from AniDB AniDBHTTPCommand_GetMyList cmd = new AniDBHTTPCommand_GetMyList(); cmd.Init(ServerSettings.Instance.AniDb.Username, ServerSettings.Instance.AniDb.Password); AniDBUDPResponseCode ev = cmd.Process(); if (ev != AniDBUDPResponseCode.GotMyListHTTP) { logger.Warn("AniDB did not return a successful code: " + ev); return; } int totalItems = 0; int watchedItems = 0; int modifiedItems = 0; // Add missing files on AniDB var onlineFiles = cmd.MyListItems.ToLookup(a => a.FileID); var dictAniFiles = RepoFactory.AniDB_File.GetAll().ToLookup(a => a.Hash); int missingFiles = 0; foreach (SVR_VideoLocal vid in RepoFactory.VideoLocal.GetAll() .Where(a => !string.IsNullOrEmpty(a.Hash)).ToList()) { // Does it have a linked AniFile if (!dictAniFiles.Contains(vid.Hash)) { continue; } int fileID = dictAniFiles[vid.Hash].FirstOrDefault()?.FileID ?? 0; if (fileID == 0) { continue; } // Is it in MyList if (onlineFiles.Contains(fileID)) { Raw_AniDB_MyListFile file = onlineFiles[fileID].FirstOrDefault(a => a != null); if (file != null) { if (vid.MyListID == 0) { vid.MyListID = file.ListID; RepoFactory.VideoLocal.Save(vid); } // Update file state if deleted if (file.State != (int)ServerSettings.Instance.AniDb.MyList_StorageState) { int seconds = Commons.Utils.AniDB.GetAniDBDateAsSeconds(file.WatchedDate); CommandRequest_UpdateMyListFileStatus cmdUpdateFile = new CommandRequest_UpdateMyListFileStatus(vid.Hash, file.WatchedDate.HasValue, false, seconds); cmdUpdateFile.Save(); } continue; } } // means we have found a file in our local collection, which is not recorded online if (ServerSettings.Instance.AniDb.MyList_AddFiles) { CommandRequest_AddFileToMyList cmdAddFile = new CommandRequest_AddFileToMyList(vid.Hash); cmdAddFile.Save(); } missingFiles++; } logger.Info($"MYLIST Missing Files: {missingFiles} Added to queue for inclusion"); List <SVR_JMMUser> aniDBUsers = RepoFactory.JMMUser.GetAniDBUsers(); LinkedHashSet <SVR_AnimeSeries> modifiedSeries = new LinkedHashSet <SVR_AnimeSeries>(); // Remove Missing Files and update watched states (single loop) List <int> filesToRemove = new List <int>(); foreach (Raw_AniDB_MyListFile myitem in cmd.MyListItems) { try { totalItems++; if (myitem.IsWatched) { watchedItems++; } string hash = string.Empty; SVR_AniDB_File anifile = RepoFactory.AniDB_File.GetByFileID(myitem.FileID); if (anifile != null) { hash = anifile.Hash; } else { // look for manually linked files List <CrossRef_File_Episode> xrefs = RepoFactory.CrossRef_File_Episode.GetByEpisodeID(myitem.EpisodeID); foreach (CrossRef_File_Episode xref in xrefs) { if (xref.CrossRefSource == (int)CrossRefSource.AniDB) { continue; } hash = xref.Hash; break; } } // We couldn't evem find a hash, so remove it if (string.IsNullOrEmpty(hash)) { filesToRemove.Add(myitem.ListID); continue; } // If there's no video local, we don't have it SVR_VideoLocal vl = RepoFactory.VideoLocal.GetByHash(hash); if (vl == null) { filesToRemove.Add(myitem.ListID); continue; } foreach (SVR_JMMUser juser in aniDBUsers) { bool localStatus = false; // doesn't matter which anidb user we use int jmmUserID = juser.JMMUserID; VideoLocal_User userRecord = vl.GetUserRecord(juser.JMMUserID); if (userRecord != null) { localStatus = userRecord.WatchedDate.HasValue; } string action = string.Empty; if (localStatus == myitem.IsWatched) { continue; } // localStatus and AniDB Status are different DateTime?watchedDate = myitem.WatchedDate ?? DateTime.Now; if (localStatus) { // local = watched, anidb = unwatched if (ServerSettings.Instance.AniDb.MyList_ReadUnwatched) { modifiedItems++; vl.ToggleWatchedStatus(false, false, watchedDate, false, jmmUserID, false, true); action = "Used AniDB Status"; } else if (ServerSettings.Instance.AniDb.MyList_SetWatched) { vl.ToggleWatchedStatus(true, true, userRecord.WatchedDate, false, jmmUserID, false, true); } } else { // means local is un-watched, and anidb is watched if (ServerSettings.Instance.AniDb.MyList_ReadWatched) { modifiedItems++; vl.ToggleWatchedStatus(true, false, watchedDate, false, jmmUserID, false, true); action = "Updated Local record to Watched"; } else if (ServerSettings.Instance.AniDb.MyList_SetUnwatched) { vl.ToggleWatchedStatus(false, true, watchedDate, false, jmmUserID, false, true); } } vl.GetAnimeEpisodes().Select(a => a.GetAnimeSeries()).Where(a => a != null) .DistinctBy(a => a.AnimeSeriesID).ForEach(a => modifiedSeries.Add(a)); logger.Info( $"MYLISTDIFF:: File {vl.FileName} - Local Status = {localStatus}, AniDB Status = {myitem.IsWatched} --- {action}"); } } catch (Exception ex) { logger.Error($"A MyList Item threw an error while syncing: {ex}"); } } // Actually remove the files if (filesToRemove.Count > 0) { foreach (int listID in filesToRemove) { CommandRequest_DeleteFileFromMyList deleteCommand = new CommandRequest_DeleteFileFromMyList(listID); deleteCommand.Save(); } logger.Info($"MYLIST Missing Files: {filesToRemove.Count} Added to queue for deletion"); } modifiedSeries.ForEach(a => a.QueueUpdateStats()); logger.Info($"Process MyList: {totalItems} Items, {missingFiles} Added, {filesToRemove.Count} Deleted, {watchedItems} Watched, {modifiedItems} Modified"); sched.LastUpdate = DateTime.Now; RepoFactory.ScheduledUpdate.Save(sched); } catch (Exception ex) { logger.Error(ex, "Error processing CommandRequest_SyncMyList: {0} ", ex); } }
/// <summary> /// Used to get a list of TvDB Series ID's that require updating /// </summary> /// <param name="tvDBIDs">The list Of Series ID's that need to be updated. Pass in an empty list</param> /// <returns>The current server time before the update started</returns> public string IncrementalTvDBUpdate(ref List <int> tvDBIDs, ref bool tvDBOnline) { // check if we have record of doing an automated update for the TvDB previously // if we have then we have kept a record of the server time and can do a delta update // otherwise we need to do a full update and keep a record of the time List <int> allTvDBIDs = new List <int>(); tvDBIDs = new List <int>(); tvDBOnline = true; try { CrossRef_AniDB_TvDBRepository repCrossRef = new CrossRef_AniDB_TvDBRepository(); AnimeSeriesRepository repSeries = new AnimeSeriesRepository(); // record the tvdb server time when we started // we record the time now instead of after we finish, to include any possible misses string currentTvDBServerTime = CurrentServerTime; if (currentTvDBServerTime.Length == 0) { tvDBOnline = false; return(currentTvDBServerTime); } foreach (AnimeSeries ser in repSeries.GetAll()) { List <CrossRef_AniDB_TvDBV2> xrefs = ser.GetCrossRefTvDBV2(); if (xrefs == null) { continue; } foreach (CrossRef_AniDB_TvDBV2 xref in xrefs) { if (!allTvDBIDs.Contains(xref.TvDBID)) { allTvDBIDs.Add(xref.TvDBID); } } } // get the time we last did a TvDB update // if this is the first time it will be null // update the anidb info ever 24 hours ScheduledUpdateRepository repSched = new ScheduledUpdateRepository(); ScheduledUpdate sched = repSched.GetByUpdateType((int)ScheduledUpdateType.TvDBInfo); string lastServerTime = ""; if (sched != null) { TimeSpan ts = DateTime.Now - sched.LastUpdate; logger.Trace("Last tvdb info update was {0} hours ago", ts.TotalHours.ToString()); if (!string.IsNullOrEmpty(sched.UpdateDetails)) { lastServerTime = sched.UpdateDetails; } // the UpdateDetails field for this type will actually contain the last server time from // TheTvDB that a full update was performed } // get a list of updates from TvDB since that time if (lastServerTime.Length > 0) { List <int> seriesList = GetUpdatedSeriesList(lastServerTime); logger.Trace("{0} series have been updated since last download", seriesList.Count.ToString()); logger.Trace("{0} TvDB series locally", allTvDBIDs.Count.ToString()); foreach (int id in seriesList) { if (allTvDBIDs.Contains(id)) { tvDBIDs.Add(id); } } logger.Trace("{0} TvDB local series have been updated since last download", tvDBIDs.Count.ToString()); } else { // use the full list tvDBIDs = allTvDBIDs; } return(currentTvDBServerTime); } catch (Exception ex) { logger.ErrorException("IncrementalTvDBUpdate: " + ex.ToString(), ex); return(""); } }