private static void CreateInitialUsers() { JMMUserRepository repUsers = new JMMUserRepository(); if (repUsers.GetAll().Count() > 0) { return; } JMMUser defaultUser = new JMMUser(); defaultUser.CanEditServerSettings = 1; defaultUser.HideCategories = ""; defaultUser.IsAdmin = 1; defaultUser.IsAniDBUser = 1; defaultUser.IsTraktUser = 1; defaultUser.Password = ""; defaultUser.Username = "******"; repUsers.Save(defaultUser); JMMUser familyUser = new JMMUser(); familyUser.CanEditServerSettings = 1; familyUser.HideCategories = "Ecchi,Nudity,Sex,Sexual Abuse,Horror,Erotic Game,Incest,18 Restricted"; familyUser.IsAdmin = 1; familyUser.IsAniDBUser = 1; familyUser.IsTraktUser = 1; familyUser.Password = ""; familyUser.Username = "******"; repUsers.Save(familyUser); }
private static void CreateInitialUsers() { JMMUserRepository repUsers = new JMMUserRepository(); if (repUsers.GetAll().Count() > 0) { return; } Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(ServerSettings.Culture); JMMUser defaultUser = new JMMUser(); defaultUser.CanEditServerSettings = 1; defaultUser.HideCategories = ""; defaultUser.IsAdmin = 1; defaultUser.IsAniDBUser = 1; defaultUser.IsTraktUser = 1; defaultUser.Password = ""; defaultUser.Username = JMMServer.Properties.Resources.Users_Default; repUsers.Save(defaultUser, true); JMMUser familyUser = new JMMUser(); familyUser.CanEditServerSettings = 1; familyUser.HideCategories = "ecchi,nudity,sex,sexual abuse,horror,erotic game,incest,18 restricted"; familyUser.IsAdmin = 1; familyUser.IsAniDBUser = 1; familyUser.IsTraktUser = 1; familyUser.Password = ""; familyUser.Username = JMMServer.Properties.Resources.Users_FamilyFriendly; repUsers.Save(familyUser, true); }
public static JMMUser GetJMMUser(string userid) { JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> allusers = repUsers.GetAll(); int id = 0; int.TryParse(userid, out id); return(allusers.FirstOrDefault(a => a.JMMUserID == id) ?? allusers.FirstOrDefault(a => a.IsAdmin == 1) ?? allusers.FirstOrDefault(a => a.Username == "Default") ?? allusers.First()); }
public void UpdateGroupFilter(HashSet <GroupFilterConditionType> types) { AnimeSeriesRepository repo = new AnimeSeriesRepository(); JMMUserRepository repouser = new JMMUserRepository(); AnimeSeries ser = repo.GetByID(AnimeSeriesID); JMMUser usr = repouser.GetByID(JMMUserID); if (ser != null && usr != null) { ser.UpdateGroupFilters(types, usr); } }
public static JMMUser GetUser(string UserId) { int userId = -1; if (!string.IsNullOrEmpty(UserId)) { int.TryParse(UserId, out userId); } JMMUserRepository repUsers = new JMMUserRepository(); return(userId != 0 ? repUsers.GetByID(userId) : repUsers.GetAll().FirstOrDefault(a => a.Username == "Default")); }
public static JMMUser GetUser(string userid) { JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> allusers = repUsers.GetAll(); foreach (JMMUser n in allusers) { if (userid.FindIn(n?.Contract?.PlexUsers)) { return(n); } } return(allusers.FirstOrDefault(a => a.IsAdmin == 1) ?? allusers.FirstOrDefault(a => a.Username == "Default") ?? allusers.First()); }
private static void InitCache(this IDatabase db) { JMMUserRepository.InitCache(); AniDB_AnimeRepository.InitCache(); VideoInfoRepository.InitCache(); VideoLocalRepository.InitCache(); VideoLocal_UserRepository.InitCache(); List <GroupFilter> recalc = GroupFilterRepository.InitCache(); AnimeEpisodeRepository.InitCache(); AnimeEpisode_UserRepository.InitCache(); AnimeSeriesRepository.InitCache(); AnimeSeries_UserRepository.InitCache(); AnimeGroupRepository.InitCache(); AnimeGroup_UserRepository.InitCache(); GroupFilterRepository.InitCacheSecondPart(recalc); DatabaseFixes.ExecuteDatabaseFixes(); db.CleanUpMemory(); }
public static JMMUser GetUser(string UserId) { JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> allusers = repUsers.GetAll(); foreach (JMMUser n in allusers) { if (!string.IsNullOrEmpty(n.PlexUsers)) { string[] users = n.PlexUsers.Split(','); foreach (string m in users) { if (m.Trim().ToLower() == UserId.ToLower()) { return(n); } } } } return(allusers.FirstOrDefault(a => a.IsAdmin == 1) ?? allusers.FirstOrDefault(a => a.Username == "Default") ?? allusers.First()); }
public System.IO.Stream GetUsers() { KodiContract_Users gfs = new KodiContract_Users(); try { gfs.Users = new List <KodiContract_User>(); JMMUserRepository repUsers = new JMMUserRepository(); foreach (JMMUser us in repUsers.GetAll()) { KodiContract_User p = new KodiContract_User(); p.id = us.JMMUserID.ToString(); p.name = us.Username; gfs.Users.Add(p); } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } return(KodiHelper.GetStreamFromXmlObject(gfs)); }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_AddFileToMyList: {0}", Hash); try { VideoLocalRepository repVids = new VideoLocalRepository(); AnimeEpisodeRepository repEpisodes = new AnimeEpisodeRepository(); vid = repVids.GetByHash(this.Hash); List <AnimeEpisode> animeEpisodes = new List <AnimeEpisode>(); if (vid != null) { animeEpisodes = vid.GetAnimeEpisodes(); } if (vid != null) { // when adding a file via the API, newWatchedStatus will return with current watched status on AniDB // if the file is already on the user's list bool isManualLink = false; List <CrossRef_File_Episode> xrefs = vid.EpisodeCrossRefs; if (xrefs.Count > 0) { isManualLink = xrefs[0].CrossRefSource != (int)CrossRefSource.AniDB; } // mark the video file as watched DateTime?watchedDate = null; bool newWatchedStatus = false; if (isManualLink) { newWatchedStatus = JMMService.AnidbProcessor.AddFileToMyList(xrefs[0].AnimeID, xrefs[0].Episode.EpisodeNumber, ref watchedDate); } else { newWatchedStatus = JMMService.AnidbProcessor.AddFileToMyList(vid, ref watchedDate); } // do for all AniDB users JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); if (aniDBUsers.Count > 0) { JMMUser juser = aniDBUsers[0]; vid.ToggleWatchedStatus(newWatchedStatus, false, watchedDate, false, false, juser.JMMUserID, false, true); logger.Info("Adding file to list: {0} - {1}", vid.ToString(), watchedDate); // if the the episode is watched we may want to set the file to watched as well if (ServerSettings.Import_UseExistingFileWatchedStatus && !newWatchedStatus) { if (animeEpisodes.Count > 0) { AnimeEpisode ep = animeEpisodes[0]; AnimeEpisode_User epUser = null; foreach (JMMUser tempuser in aniDBUsers) { // only find the first user who watched this if (epUser == null) { epUser = ep.GetUserRecord(tempuser.JMMUserID); } } if (epUser != null) { logger.Info("Setting file as watched, because episode was already watched: {0} - user: {1}", vid.ToString(), juser.Username); vid.ToggleWatchedStatus(true, true, epUser.WatchedDate, false, false, epUser.JMMUserID, false, true); } } } } AnimeSeries ser = animeEpisodes[0].GetAnimeSeries(); // all the eps should belong to the same anime ser.QueueUpdateStats(); //StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); // lets also try adding to the users trakt collecion if (ser != null && ServerSettings.Trakt_IsEnabled && !string.IsNullOrEmpty(ServerSettings.Trakt_AuthToken)) { foreach (AnimeEpisode aep in animeEpisodes) { CommandRequest_TraktCollectionEpisode cmdSyncTrakt = new CommandRequest_TraktCollectionEpisode(aep.AnimeEpisodeID, TraktSyncAction.Add); cmdSyncTrakt.Save(); } } // sync the series on MAL if (ser != null && !string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password)) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_AddFileToMyList: {0} - {1}", Hash, ex.ToString()); return; } }
public static UserInfo GetUserInfoData(string dashType = "", string vidPlayer = "") { try { if (string.IsNullOrEmpty(ServerSettings.AniDB_Username)) { return(null); } UserInfo uinfo = new UserInfo(); uinfo.DateTimeUpdated = DateTime.Now; uinfo.DateTimeUpdatedUTC = 0; // Optional JMM Desktop data uinfo.DashboardType = null; uinfo.VideoPlayer = vidPlayer; System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); try { if (a != null) { uinfo.JMMServerVersion = Utils.GetApplicationVersion(a); } } catch { } uinfo.UsernameHash = Utils.GetMd5Hash(ServerSettings.AniDB_Username); uinfo.DatabaseType = ServerSettings.DatabaseType; uinfo.WindowsVersion = Utils.GetOSInfo(); uinfo.TraktEnabled = ServerSettings.Trakt_IsEnabled ? 1 : 0; uinfo.MALEnabled = string.IsNullOrEmpty(ServerSettings.MAL_Username) ? 0 : 1; uinfo.CountryLocation = ""; // this field is not actually used uinfo.LastEpisodeWatchedAsDate = DateTime.Now.AddDays(-5); JMMUserRepository repUsers = new JMMUserRepository(); uinfo.LocalUserCount = (int)repUsers.GetTotalRecordCount(); VideoLocalRepository repVids = new VideoLocalRepository(); uinfo.FileCount = repVids.GetTotalRecordCount(); AnimeEpisode_UserRepository repEps = new AnimeEpisode_UserRepository(); AnimeEpisode_User rec = repEps.GetLastWatchedEpisode(); uinfo.LastEpisodeWatched = 0; if (rec != null) { uinfo.LastEpisodeWatched = Utils.GetAniDBDateAsSeconds(rec.WatchedDate); } return(uinfo); } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); return(null); } }
public override void ProcessCommand() { logger.Info("Processing CommandRequest_MALDownloadStatusFromMAL"); try { if (string.IsNullOrEmpty(ServerSettings.MAL_Username) || string.IsNullOrEmpty(ServerSettings.MAL_Password)) { return; } // find the latest eps to update AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository(); myanimelist mal = MALHelper.GetMALAnimeList(); if (mal == null) { return; } if (mal.anime == null) { return; } CrossRef_AniDB_MALRepository repCrossRef = new CrossRef_AniDB_MALRepository(); AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); AnimeEpisodeRepository repEp = new AnimeEpisodeRepository(); // find the anidb user JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); if (aniDBUsers.Count == 0) { return; } JMMUser user = aniDBUsers[0]; foreach (myanimelistAnime malAnime in mal.anime) { // look up the anime CrossRef_AniDB_MAL xref = repCrossRef.GetByMALID(malAnime.series_animedb_id); if (xref == null) { continue; } if (malAnime.series_animedb_id == 8107 || malAnime.series_animedb_id == 10737) { Console.Write(""); } // check if this anime has any other links List <CrossRef_AniDB_MAL> allXrefs = repCrossRef.GetByAnimeID(xref.AnimeID); if (allXrefs.Count == 0) { continue; } // find the range of watched episodes that this applies to int startEpNumber = xref.StartEpisodeNumber; int endEpNumber = GetUpperEpisodeLimit(allXrefs, xref); List <AniDB_Episode> aniEps = repAniEps.GetByAnimeID(xref.AnimeID); foreach (AniDB_Episode aniep in aniEps) { if (aniep.EpisodeType != xref.StartEpisodeType) { continue; } AnimeEpisode ep = repEp.GetByAniDBEpisodeID(aniep.EpisodeID); if (ep == null) { continue; } int adjustedWatchedEps = malAnime.my_watched_episodes + xref.StartEpisodeNumber - 1; int epNum = aniep.EpisodeNumber; if (epNum < startEpNumber || epNum > endEpNumber) { continue; } AnimeEpisode_User usrRec = ep.GetUserRecord(user.JMMUserID); if (epNum <= adjustedWatchedEps) { // update if the user doesn't have a record (means not watched) // or it is currently un-watched bool update = false; if (usrRec == null) { update = true; } else { if (!usrRec.WatchedDate.HasValue) { update = true; } } if (update) { ep.ToggleWatchedStatus(true, true, DateTime.Now, user.JMMUserID, false); } } else { bool update = false; if (usrRec != null) { if (usrRec.WatchedDate.HasValue) { update = true; } } if (update) { ep.ToggleWatchedStatus(false, true, DateTime.Now, user.JMMUserID, false); } } } } } catch (Exception ex) { logger.Error("Error processing CommandRequest_MALDownloadStatusFromMAL: {0}", ex.ToString()); return; } }
/// <summary> /// Update the stats for this group based on the child series /// Assumes that all the AnimeSeries have had their stats updated already /// </summary> public void UpdateStats(bool watchedStats, bool missingEpsStats) { List <AnimeSeries> seriesList = GetAllSeries(); JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> allUsers = repUsers.GetAll(); if (watchedStats) { foreach (JMMUser juser in allUsers) { AnimeGroup_User userRecord = GetUserRecord(juser.JMMUserID); if (userRecord == null) { userRecord = new AnimeGroup_User(juser.JMMUserID, this.AnimeGroupID); } // reset stats userRecord.WatchedCount = 0; userRecord.UnwatchedEpisodeCount = 0; userRecord.PlayedCount = 0; userRecord.StoppedCount = 0; userRecord.WatchedEpisodeCount = 0; userRecord.WatchedDate = null; foreach (AnimeSeries ser in seriesList) { AnimeSeries_User serUserRecord = ser.GetUserRecord(juser.JMMUserID); if (serUserRecord != null) { userRecord.WatchedCount += serUserRecord.WatchedCount; userRecord.UnwatchedEpisodeCount += serUserRecord.UnwatchedEpisodeCount; userRecord.PlayedCount += serUserRecord.PlayedCount; userRecord.StoppedCount += serUserRecord.StoppedCount; userRecord.WatchedEpisodeCount += serUserRecord.WatchedEpisodeCount; if (serUserRecord.WatchedDate.HasValue) { if (userRecord.WatchedDate.HasValue) { if (serUserRecord.WatchedDate > userRecord.WatchedDate) { userRecord.WatchedDate = serUserRecord.WatchedDate; } } else { userRecord.WatchedDate = serUserRecord.WatchedDate; } } } } // now update the stats for the groups logger.Trace("Updating stats for {0}", this.ToString()); AnimeGroup_UserRepository rep = new AnimeGroup_UserRepository(); rep.Save(userRecord); } } if (missingEpsStats) { this.MissingEpisodeCount = 0; this.MissingEpisodeCountGroups = 0; foreach (AnimeSeries ser in seriesList) { this.MissingEpisodeCount += ser.MissingEpisodeCount; this.MissingEpisodeCountGroups += ser.MissingEpisodeCountGroups; } AnimeGroupRepository repGrp = new AnimeGroupRepository(); repGrp.Save(this); } }
public void ToggleWatchedStatus(bool watched, bool updateOnline, DateTime?watchedDate, bool updateStats, bool updateStatsCache, int userID, bool scrobbleTrakt, bool updateWatchedDate) { VideoLocalRepository repVids = new VideoLocalRepository(); AnimeEpisodeRepository repEpisodes = new AnimeEpisodeRepository(); AniDB_FileRepository repAniFile = new AniDB_FileRepository(); CrossRef_File_EpisodeRepository repCross = new CrossRef_File_EpisodeRepository(); VideoLocal_UserRepository repVidUsers = new VideoLocal_UserRepository(); JMMUserRepository repUsers = new JMMUserRepository(); AnimeEpisode_UserRepository repEpisodeUsers = new AnimeEpisode_UserRepository(); JMMUser user = repUsers.GetByID(userID); if (user == null) { return; } List <JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); // update the video file to watched int mywatched = watched ? 1 : 0; if (user.IsAniDBUser == 0) { SaveWatchedStatus(watched, userID, watchedDate, updateWatchedDate); } else { // if the user is AniDB user we also want to update any other AniDB // users to keep them in sync foreach (JMMUser juser in aniDBUsers) { if (juser.IsAniDBUser == 1) { SaveWatchedStatus(watched, juser.JMMUserID, watchedDate, updateWatchedDate); } } } // now lets find all the associated AniDB_File record if there is one if (user.IsAniDBUser == 1) { AniDB_File aniFile = repAniFile.GetByHash(this.Hash); if (aniFile != null) { aniFile.IsWatched = mywatched; if (watched) { if (watchedDate.HasValue) { aniFile.WatchedDate = watchedDate; } else { aniFile.WatchedDate = DateTime.Now; } } else { aniFile.WatchedDate = null; } repAniFile.Save(aniFile, false); } if (updateOnline) { if ((watched && ServerSettings.AniDB_MyList_SetWatched) || (!watched && ServerSettings.AniDB_MyList_SetUnwatched)) { CommandRequest_UpdateMyListFileStatus cmd = new CommandRequest_UpdateMyListFileStatus(this.Hash, watched, false, watchedDate.HasValue ? Utils.GetAniDBDateAsSeconds(watchedDate) : 0); cmd.Save(); } } } // now find all the episode records associated with this video file // but we also need to check if theer are any other files attached to this episode with a watched // status, AnimeSeries ser = null; // get all files associated with this episode List <CrossRef_File_Episode> xrefs = repCross.GetByHash(this.Hash); if (watched) { // find the total watched percentage // eg one file can have a % = 100 // or if 2 files make up one episodes they will each have a % = 50 foreach (CrossRef_File_Episode xref in xrefs) { // get the episode for this file AnimeEpisode ep = repEpisodes.GetByAniDBEpisodeID(xref.EpisodeID); if (ep == null) { continue; } // get all the files for this episode int epPercentWatched = 0; foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs) { VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID); if (vidUser != null) { // if not null means it is watched epPercentWatched += filexref.Percentage; } if (epPercentWatched > 95) { break; } } if (epPercentWatched > 95) { ser = ep.GetAnimeSeries(); if (user.IsAniDBUser == 0) { ep.SaveWatchedStatus(true, userID, watchedDate, updateWatchedDate); } else { // if the user is AniDB user we also want to update any other AniDB // users to keep them in sync foreach (JMMUser juser in aniDBUsers) { if (juser.IsAniDBUser == 1) { ep.SaveWatchedStatus(true, juser.JMMUserID, watchedDate, updateWatchedDate); } } } if (scrobbleTrakt && !string.IsNullOrEmpty(ServerSettings.Trakt_Username) && !string.IsNullOrEmpty(ServerSettings.Trakt_Password)) { CommandRequest_TraktShowScrobble cmdScrobble = new CommandRequest_TraktShowScrobble(ep.AnimeEpisodeID); cmdScrobble.Save(); } if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password)) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } } } } else { // if setting a file to unwatched only set the episode unwatched, if ALL the files are unwatched foreach (CrossRef_File_Episode xrefEp in xrefs) { AnimeEpisode ep = repEpisodes.GetByAniDBEpisodeID(xrefEp.EpisodeID); if (ep == null) { continue; } ser = ep.GetAnimeSeries(); // get all the files for this episode int epPercentWatched = 0; foreach (CrossRef_File_Episode filexref in ep.FileCrossRefs) { VideoLocal_User vidUser = filexref.GetVideoLocalUserRecord(userID); if (vidUser != null) { epPercentWatched += filexref.Percentage; } if (epPercentWatched > 95) { break; } } if (epPercentWatched < 95) { if (user.IsAniDBUser == 0) { ep.SaveWatchedStatus(false, userID, watchedDate, true); } else { // if the user is AniDB user we also want to update any other AniDB // users to keep them in sync foreach (JMMUser juser in aniDBUsers) { if (juser.IsAniDBUser == 1) { ep.SaveWatchedStatus(false, juser.JMMUserID, watchedDate, true); } } } CommandRequest_TraktShowEpisodeUnseen cmdUnseen = new CommandRequest_TraktShowEpisodeUnseen(ep.AnimeEpisodeID); cmdUnseen.Save(); } } if (!string.IsNullOrEmpty(ServerSettings.MAL_Username) && !string.IsNullOrEmpty(ServerSettings.MAL_Password)) { CommandRequest_MALUpdatedWatchedStatus cmdMAL = new CommandRequest_MALUpdatedWatchedStatus(ser.AniDB_ID); cmdMAL.Save(); } } // update stats for groups and series if (ser != null && updateStats) { // update all the groups above this series in the heirarchy ser.UpdateStats(true, true, true); //ser.TopLevelAnimeGroup.UpdateStatsFromTopLevel(true, true, true); } if (ser != null && updateStatsCache) { StatsCache.Instance.UpdateUsingSeries(ser.AnimeSeriesID); } }
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 static void UpdateWatchedStatus(int animeID, enEpisodeType epType, int lastWatchedEpNumber) * { * try * { * if (string.IsNullOrEmpty(ServerSettings.MAL_Username) || string.IsNullOrEmpty(ServerSettings.MAL_Password)) * return; * * AniDB_EpisodeRepository repAniEps = new AniDB_EpisodeRepository(); * List<AniDB_Episode> aniEps = repAniEps.GetByAnimeIDAndEpisodeTypeNumber(animeID, epType, lastWatchedEpNumber); * if (aniEps.Count == 0) return; * * AnimeEpisodeRepository repEp = new AnimeEpisodeRepository(); * AnimeEpisode ep = repEp.GetByAniDBEpisodeID(aniEps[0].EpisodeID); * if (ep == null) return; * * MALHelper.UpdateMAL(ep); * } * catch (Exception ex) * { * logger.ErrorException(ex.ToString(), ex); * } * }*/ public static void UpdateMALSeries(AnimeSeries ser) { try { if (string.IsNullOrEmpty(ServerSettings.MAL_Username) || string.IsNullOrEmpty(ServerSettings.MAL_Password)) { return; } // Populate MAL animelist hashtable if isNeverDecreaseWatched set Hashtable animeListHashtable = new Hashtable(); if (ServerSettings.MAL_NeverDecreaseWatchedNums) //if set, check watched number before update: take some time, as user anime list must be loaded { myanimelist malAnimeList = GetMALAnimeList(); if (malAnimeList != null && malAnimeList.anime != null) { for (int i = 0; i < malAnimeList.anime.Length; i++) { animeListHashtable.Add(malAnimeList.anime[i].series_animedb_id, malAnimeList.anime[i]); } } } // look for MAL Links List <CrossRef_AniDB_MAL> crossRefs = ser.GetAnime().GetCrossRefMAL(); if (crossRefs == null || crossRefs.Count == 0) { logger.Warn("Could not find MAL link for : {0} ({1})", ser.GetAnime().GetFormattedTitle(), ser.GetAnime().AnimeID); return; } AnimeEpisodeRepository repEps = new AnimeEpisodeRepository(); AniDB_FileRepository repFiles = new AniDB_FileRepository(); List <AnimeEpisode> eps = ser.GetAnimeEpisodes(); // find the anidb user JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> aniDBUsers = repUsers.GetAniDBUsers(); if (aniDBUsers.Count == 0) { return; } JMMUser user = aniDBUsers[0]; int score = 0; if (ser.GetAnime().UserVote != null) { score = (int)(ser.GetAnime().UserVote.VoteValue / 100); } // e.g. // AniDB - Code Geass R2 // MAL Equivalent = AniDB Normal Eps 1 - 25 / Code Geass: Hangyaku no Lelouch R2 / hxxp://myanimelist.net/anime/2904/Code_Geass:_Hangyaku_no_Lelouch_R2 // MAL Equivalent = AniDB Special Eps 1 - 9 / Code Geass: Hangyaku no Lelouch R2 Picture Drama / hxxp://myanimelist.net/anime/5163/Code_Geass:_Hangyaku_no_Lelouch_R2_Picture_Drama // MAL Equivalent = AniDB Special Eps 9 - 18 / Code Geass: Hangyaku no Lelouch R2: Flash Specials / hxxp://myanimelist.net/anime/9591/Code_Geass:_Hangyaku_no_Lelouch_R2:_Flash_Specials // MAL Equivalent = AniDB Special Eps 20 / Code Geass: Hangyaku no Lelouch - Kiseki no Birthday Picture Drama / hxxp://myanimelist.net/anime/8728/Code_Geass:_Hangyaku_no_Lelouch_-_Kiseki_no_Birthday_Picture_Drama foreach (CrossRef_AniDB_MAL xref in crossRefs) { // look for the right MAL id int malID = -1; int epNumber = -1; int totalEpCount = -1; List <string> fanSubGroups = new List <string>(); // for each cross ref (which is a series on MAL) we need to update the data // so find all the episodes which apply to this cross ref int lastWatchedEpNumber = 0; int downloadedEps = 0; foreach (AnimeEpisode ep in eps) { int epNum = ep.AniDB_Episode.EpisodeNumber; if (xref.StartEpisodeType == (int)ep.EpisodeTypeEnum && epNum >= xref.StartEpisodeNumber && epNum <= GetUpperEpisodeLimit(crossRefs, xref)) { malID = xref.MALID; epNumber = epNum - xref.StartEpisodeNumber + 1; // find the total episode count if (totalEpCount < 0) { if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Episode) { totalEpCount = ser.GetAnime().EpisodeCountNormal; } if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Special) { totalEpCount = ser.GetAnime().EpisodeCountSpecial; } totalEpCount = totalEpCount - xref.StartEpisodeNumber + 1; } // any episodes here belong to the MAL series // find the latest watched episod enumber AnimeEpisode_User usrRecord = ep.GetUserRecord(user.JMMUserID); if (usrRecord != null && usrRecord.WatchedDate.HasValue && epNum > lastWatchedEpNumber) { lastWatchedEpNumber = epNum; } List <Contract_VideoDetailed> contracts = ep.GetVideoDetailedContracts(user.JMMUserID); // find the latest episode number in the collection if (contracts.Count > 0) { downloadedEps++; } foreach (Contract_VideoDetailed contract in contracts) { if (!string.IsNullOrEmpty(contract.AniDB_Anime_GroupNameShort) && !fanSubGroups.Contains(contract.AniDB_Anime_GroupNameShort)) { fanSubGroups.Add(contract.AniDB_Anime_GroupNameShort); } } } } string fanSubs = ""; foreach (string fgrp in fanSubGroups) { if (!string.IsNullOrEmpty(fanSubs)) { fanSubs += ","; } fanSubs += fgrp; } // determine status int status = 1; //watching if (animeListHashtable.ContainsKey(malID)) { myanimelistAnime animeInList = (myanimelistAnime)animeListHashtable[malID]; status = animeInList.my_status; } // over-ride is user has watched an episode // don't override on hold (3) or dropped (4) but do override plan to watch (6) if (status == 6 && lastWatchedEpNumber > 0) { status = 1; //watching } if (lastWatchedEpNumber == totalEpCount) { status = 2; //completed } if (lastWatchedEpNumber > totalEpCount) { logger.Error("updateMAL, episode number > matching anime episode total : {0} ({1}) / {2}", ser.GetAnime().GetFormattedTitle(), ser.GetAnime().AnimeID, epNumber); continue; } if (malID <= 0 || totalEpCount <= 0) { logger.Warn("Could not find MAL link for : {0} ({1})", ser.GetAnime().GetFormattedTitle(), ser.GetAnime().AnimeID); continue; } else { bool res = UpdateAnime(malID, lastWatchedEpNumber, status, score, downloadedEps, fanSubs); string confirmationMessage = string.Format("MAL successfully updated, mal id: {0}, ep: {1}, score: {2}", malID, lastWatchedEpNumber, score); if (res) { logger.Trace(confirmationMessage); } } } } catch (Exception ex) { logger.ErrorException(ex.ToString(), ex); } }
public void UpdateStats(bool watchedStats, bool missingEpsStats, bool updateAllGroupsAbove) { DateTime start = DateTime.Now; DateTime startOverall = DateTime.Now; logger.Info("Starting Updating STATS for SERIES {0} ({1} - {2} - {3})", this.ToString(), watchedStats, missingEpsStats, updateAllGroupsAbove); AnimeSeries_UserRepository repSeriesUser = new AnimeSeries_UserRepository(); AnimeEpisode_UserRepository repEpisodeUser = new AnimeEpisode_UserRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); CrossRef_File_EpisodeRepository repXrefs = new CrossRef_File_EpisodeRepository(); JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> allUsers = repUsers.GetAll(); DateTime startEps = DateTime.Now; List <AnimeEpisode> eps = GetAnimeEpisodes(); TimeSpan tsEps = DateTime.Now - startEps; logger.Trace("Got episodes for SERIES {0} in {1}ms", this.ToString(), tsEps.TotalMilliseconds); DateTime startVids = DateTime.Now; List <VideoLocal> vidsTemp = repVids.GetByAniDBAnimeID(this.AniDB_ID); List <CrossRef_File_Episode> crossRefs = repXrefs.GetByAnimeID(this.AniDB_ID); Dictionary <int, List <CrossRef_File_Episode> > dictCrossRefs = new Dictionary <int, List <CrossRef_File_Episode> >(); foreach (CrossRef_File_Episode xref in crossRefs) { if (!dictCrossRefs.ContainsKey(xref.EpisodeID)) { dictCrossRefs[xref.EpisodeID] = new List <CrossRef_File_Episode>(); } dictCrossRefs[xref.EpisodeID].Add(xref); } Dictionary <string, VideoLocal> dictVids = new Dictionary <string, VideoLocal>(); foreach (VideoLocal vid in vidsTemp) { dictVids[vid.Hash] = vid; } TimeSpan tsVids = DateTime.Now - startVids; logger.Trace("Got video locals for SERIES {0} in {1}ms", this.ToString(), tsVids.TotalMilliseconds); if (watchedStats) { foreach (JMMUser juser in allUsers) { //this.WatchedCount = 0; AnimeSeries_User userRecord = GetUserRecord(juser.JMMUserID); if (userRecord == null) { userRecord = new AnimeSeries_User(juser.JMMUserID, this.AnimeSeriesID); } // reset stats userRecord.UnwatchedEpisodeCount = 0; userRecord.WatchedEpisodeCount = 0; userRecord.WatchedCount = 0; userRecord.WatchedDate = null; DateTime startUser = DateTime.Now; List <AnimeEpisode_User> epUserRecords = repEpisodeUser.GetByUserID(juser.JMMUserID); Dictionary <int, AnimeEpisode_User> dictUserRecords = new Dictionary <int, AnimeEpisode_User>(); foreach (AnimeEpisode_User usrec in epUserRecords) { dictUserRecords[usrec.AnimeEpisodeID] = usrec; } TimeSpan tsUser = DateTime.Now - startUser; logger.Trace("Got user records for SERIES {0}/{1} in {2}ms", this.ToString(), juser.Username, tsUser.TotalMilliseconds); foreach (AnimeEpisode ep in eps) { // if the episode doesn't have any files then it won't count towards watched/unwatched counts List <VideoLocal> epVids = new List <VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) { epVids.Add(dictVids[xref.Hash]); } } } } if (epVids.Count == 0) { continue; } if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Episode || ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Special) { AnimeEpisode_User epUserRecord = null; if (dictUserRecords.ContainsKey(ep.AnimeEpisodeID)) { epUserRecord = dictUserRecords[ep.AnimeEpisodeID]; } if (epUserRecord != null && epUserRecord.WatchedDate.HasValue) { userRecord.WatchedEpisodeCount++; } else { userRecord.UnwatchedEpisodeCount++; } if (epUserRecord != null) { if (userRecord.WatchedDate.HasValue) { if (epUserRecord.WatchedDate > userRecord.WatchedDate) { userRecord.WatchedDate = epUserRecord.WatchedDate; } } else { userRecord.WatchedDate = epUserRecord.WatchedDate; } userRecord.WatchedCount += epUserRecord.WatchedCount; } } } repSeriesUser.Save(userRecord); } } TimeSpan ts = DateTime.Now - start; logger.Trace("Updated WATCHED stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds); start = DateTime.Now; if (missingEpsStats) { enAnimeType animeType = enAnimeType.TVSeries; AniDB_Anime aniDB_Anime = this.GetAnime(); if (aniDB_Anime != null) { animeType = aniDB_Anime.AnimeTypeEnum; } MissingEpisodeCount = 0; MissingEpisodeCountGroups = 0; // get all the group status records AniDB_GroupStatusRepository repGrpStat = new AniDB_GroupStatusRepository(); List <AniDB_GroupStatus> grpStatuses = repGrpStat.GetByAnimeID(this.AniDB_ID); // find all the episodes for which the user has a file // from this we can determine what their latest episode number is // find out which groups the user is collecting List <int> userReleaseGroups = new List <int>(); foreach (AnimeEpisode ep in eps) { List <VideoLocal> vids = new List <VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) { vids.Add(dictVids[xref.Hash]); } } } } //List<VideoLocal> vids = ep.VideoLocals; foreach (VideoLocal vid in vids) { AniDB_File anifile = vid.GetAniDBFile(); if (anifile != null) { if (!userReleaseGroups.Contains(anifile.GroupID)) { userReleaseGroups.Add(anifile.GroupID); } } } } int latestLocalEpNumber = 0; EpisodeList epReleasedList = new EpisodeList(animeType); EpisodeList epGroupReleasedList = new EpisodeList(animeType); foreach (AnimeEpisode ep in eps) { //List<VideoLocal> vids = ep.VideoLocals; if (ep.EpisodeTypeEnum != AniDBAPI.enEpisodeType.Episode) { continue; } List <VideoLocal> vids = new List <VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) { vids.Add(dictVids[xref.Hash]); } } } } AniDB_Episode aniEp = ep.AniDB_Episode; int thisEpNum = aniEp.EpisodeNumber; if (thisEpNum > latestLocalEpNumber && vids.Count > 0) { latestLocalEpNumber = thisEpNum; } // does this episode have a file released // does this episode have a file released by the group the user is collecting bool epReleased = false; bool epReleasedGroup = false; foreach (AniDB_GroupStatus gs in grpStatuses) { if (gs.LastEpisodeNumber >= thisEpNum) { epReleased = true; } if (userReleaseGroups.Contains(gs.GroupID) && gs.HasGroupReleasedEpisode(thisEpNum)) { epReleasedGroup = true; } } try { epReleasedList.Add(ep, (!epReleased || vids.Count != 0)); epGroupReleasedList.Add(ep, (!epReleasedGroup || vids.Count != 0)); } catch (Exception e) { logger.Trace("Error {0}", e.ToString()); throw; } } foreach (EpisodeList.StatEpisodes eplst in epReleasedList) { if (!eplst.Available) { MissingEpisodeCount++; } } foreach (EpisodeList.StatEpisodes eplst in epGroupReleasedList) { if (!eplst.Available) { MissingEpisodeCountGroups++; } } this.LatestLocalEpisodeNumber = latestLocalEpNumber; } ts = DateTime.Now - start; logger.Trace("Updated MISSING EPS stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds); start = DateTime.Now; AnimeSeriesRepository rep = new AnimeSeriesRepository(); rep.Save(this); if (updateAllGroupsAbove) { foreach (AnimeGroup grp in AllGroupsAbove) { grp.UpdateStats(watchedStats, missingEpsStats); } } ts = DateTime.Now - start; logger.Trace("Updated GROUPS ABOVE stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds); start = DateTime.Now; TimeSpan tsOverall = DateTime.Now - startOverall; logger.Info("Finished Updating STATS for SERIES {0} in {1}ms ({2} - {3} - {4})", this.ToString(), tsOverall.TotalMilliseconds, watchedStats, missingEpsStats, updateAllGroupsAbove); }