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;
			}
		}
示例#2
0
        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 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;
			}
		}
示例#4
0
		public void MoveFileIfRequired()
		{
            try
            {
                logger.Trace("Attempting to move file: {0}", this.FullServerPath);

                // check if this file is in the drop folder
                // otherwise we don't need to move it
                if (this.ImportFolder.IsDropSource == 0)
                {
                    logger.Trace("Not moving file as it is NOT in the drop folder: {0}", this.FullServerPath);
                    return;
                }

                if (!File.Exists(this.FullServerPath))
                {
                    logger.Error("Could not find the file to move: {0}", 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;

                // keep the original drop folder for later (take a copy, not a reference)
                ImportFolder dropFolder = this.ImportFolder;

                // 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);

                AniDB_AnimeRepository repAnime = new AniDB_AnimeRepository();
                CrossRef_File_EpisodeRepository repFileEpXref = new CrossRef_File_EpisodeRepository();

                foreach (AnimeEpisode ep in allEps)
                {
                    // check if this episode belongs to more than one anime
                    // if it does we will ignore it
                    List<CrossRef_File_Episode> fileEpXrefs = repFileEpXref.GetByEpisodeID(ep.AniDB_EpisodeID);
                    int? animeID = null;
                    bool crossOver = false;
                    foreach (CrossRef_File_Episode fileEpXref in fileEpXrefs)
                    {
                        if (!animeID.HasValue)
                            animeID = fileEpXref.AnimeID;
                        else
                        {
                            if (animeID.Value != fileEpXref.AnimeID)
                                crossOver = true;
                        }
                    }
                    if (crossOver) continue;

                    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))
                {
                    logger.Trace("Not moving file as it already exists at the new location, deleting source file instead: {0} --- {1}", 
                        this.FullServerPath, 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 (dropFolder.IsDropSource == 1)
                    {
                        foreach (string folderName in Directory.GetDirectories(dropFolder.ImportFolderLocation, "*", SearchOption.AllDirectories))
                        {
                            if (Directory.Exists(folderName))
                            {
                                if (Directory.GetFiles(folderName, "*", SearchOption.AllDirectories).Length == 0)
                                {
                                    try
                                    {
                                        Directory.Delete(folderName, true);
                                    }
                                    catch (Exception ex)
                                    {
                                        logger.ErrorException(ex.ToString(), ex);
                                    }
                                }
                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                string msg = string.Format("Could not move file: {0} -- {1}", this.FullServerPath, ex.ToString());
                logger.ErrorException(msg, ex);
            }

        }