コード例 #1
0
 public OrgItemEditorWindow(OrgItem item)
 {
     InitializeComponent();
     viewModel = new OrgItemEditorWindowViewModel(item);
     this.DataContext = viewModel;
     viewModel.ResultsSet += viewModel_ResultsSet;
 }
コード例 #2
0
ファイル: TvFolderScan.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Run through all TV shows all looks for episodes that may need to be renamed and for missing episodes.
        /// For missing episodes it attempts to match them to files from the search directories.
        /// </summary>
        /// <param name="shows">Shows to scan</param>
        /// <param name="queuedItems">Items currently in queue (to be skipped)</param>
        /// <returns></returns>
        public List<OrgItem> RunScan(List<ContentRootFolder> folders, List<OrgItem> queuedItems, bool fast)
        {
            // Set running flag
            scanRunning = true;
            cancelRequested = false;

            // Convert all TV folder to scan folders so we can do a scan of them
            List<OrgFolder> tvFoldersAsOrgFolders = new List<OrgFolder>();
            foreach (ContentRootFolder tvFolder in folders)
            {
                OrgFolder orgFolder = new OrgFolder(tvFolder.FullPath, false, false, false, false);
                tvFoldersAsOrgFolders.Add(orgFolder);
            }

            // Do directory scan on all TV folders
            DirectoryScan dirScan = new DirectoryScan(false);
            dirScan.ProgressChange += dirScan_ProgressChange;
            dirScan.RunScan(tvFoldersAsOrgFolders, queuedItems, 90, true, false, fast, true);
            List<OrgItem> results = dirScan.Items;

            // Check if show folder needs to be renamed!
            int number = results.Count;
            foreach (ContentRootFolder tvFolder in folders)
                for (int i = 0; i < Organization.Shows.Count; i++)
                {
                    TvShow show = (TvShow)Organization.Shows[i];

                    if (show.Id <= 0 || show.RootFolder != tvFolder.FullPath)
                        continue;

                    string builtFolder = Path.Combine(show.RootFolder, FileHelper.GetSafeFileName(show.DatabaseName));
                    if (show.Path != builtFolder)
                    {
                        OrgItem newItem = new OrgItem(OrgStatus.Organization, OrgAction.Rename, show.Path, builtFolder, new TvEpisode("", show, -1, -1, "", ""), null, FileCategory.Folder, null);
                        newItem.Enable = true;
                        newItem.Number = number++;
                        results.Add(newItem);
                    }
                }

            // Update progress
            OnProgressChange(ScanProcess.TvFolder, string.Empty, 100);

            // Clear flags
            scanRunning = false;

            // Return results
            return results;
        }
コード例 #3
0
        public OrgItemEditorWindowViewModel(OrgItem item)
        {
            this.OriginalItem = item;
            this.Item = new OrgItem(item);
            this.Item.PropertyChanged += Item_PropertyChanged;
            this.SourceEditingAllowed = string.IsNullOrEmpty(this.Item.SourcePath);

            // Set path for movie to item source path (for filling in search box)
            if (string.IsNullOrEmpty(this.Item.Movie.Path))
                this.Item.Movie.Path = System.IO.Path.GetFileNameWithoutExtension(item.SourcePath);

            // Create view model for movie content editor
            this.MovieViewModel = new ContentEditorControlViewModel(this.Item.Movie, true);
            this.MovieViewModel.Content.PropertyChanged += ItemSubProperty_PropertyChanged;
            ContentRootFolder movieFolder;
            if (string.IsNullOrEmpty(this.Item.Movie.RootFolder) && Settings.GetMovieFolderForContent(this.Item.Movie, out movieFolder))
                this.Item.Movie.RootFolder = movieFolder.FullPath;

            // tv number update
            int season, episode1, episode2;
            if (this.Item.TvEpisode.DatabaseNumber == -1 && FileHelper.GetEpisodeInfo(item.SourcePath, string.Empty, out season, out episode1, out episode2))
            {
                this.Item.TvEpisode.Season = season;
                this.Item.TvEpisode.DatabaseNumber = episode1;
                this.Item.TvEpisode2.Season = season;
                this.Item.TvEpisode2.DatabaseNumber = episode2;
            }

            // Setup avilable shows
            this.Shows = new ObservableCollection<TvShow>();
            foreach (TvShow show in Organization.Shows)
                this.Shows.Add(show);
            if (string.IsNullOrEmpty(this.Item.TvEpisode.Show.DatabaseName) && this.Shows.Count > 0)
                this.Item.TvEpisode.Show = this.Shows[0];
            if (!string.IsNullOrEmpty(this.Item.TvEpisode.Show.DatabaseName) && !this.Shows.Contains(this.Item.TvEpisode.Show))
                this.Shows.Add(this.Item.TvEpisode.Show);
            this.Item.TvEpisode.PropertyChanged += ItemSubProperty_PropertyChanged;
        }
コード例 #4
0
        public bool BuildFileMoveItem(string filePath, OrgFolder scanDir, out OrgItem item)
        {
            item = null;
            foreach (string fileType in this.FileTypes)
                if (FileHelper.FileTypeMatch(fileType, filePath))
                {
                    item = new OrgItem(filePath, this, scanDir, false);

                    if (File.Exists(item.DestinationPath))
                    {
                        item.Action = OrgAction.AlreadyExists;
                        item.Enable = false;
                    }

                    return true;
                }
            return false;
        }
コード例 #5
0
ファイル: DirectoryScan.cs プロジェクト: Garreye/meticumedia
        private OrgItem UpdateItemFromPrevious(OrgPath orgPath, OrgItem reuseItem, bool threaded, bool fast, bool skipMatching)
        {
            switch (reuseItem.Action)
            {
                case OrgAction.Delete:
                    OrgItem copyItem = new OrgItem(reuseItem);
                    copyItem.SourcePath = orgPath.Path;
                    copyItem.BuildDestination();
                    return copyItem;
                case OrgAction.Move:
                case OrgAction.Copy:
                    if (reuseItem.Category == FileCategory.MovieVideo)
                    {
                        OrgItem item;
                        CreateMovieAction(orgPath, orgPath.Path, out item, threaded, fast, skipMatching, reuseItem.Movie);

                        return item;
                    }
                    else if (reuseItem.Category == FileCategory.TvVideo)
                    {
                        if (!Organization.Shows.Contains(reuseItem.TvEpisode.Show) && !temporaryShows.Contains(reuseItem.TvEpisode.Show))
                            lock (directoryScanLock)
                                temporaryShows.Add(reuseItem.TvEpisode.Show);
                    }
                    break;
                default:
                    break;
            }

            return null;
        }
コード例 #6
0
ファイル: DirectoryScan.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Tries to create a movie action item for a scan from a file.
        /// </summary>
        /// <param name="file">The file to create movie action from</param>
        /// <param name="item">The resulting movie action</param>
        /// <returns>Whether the file was matched to a movie</returns>
        private bool CreateMovieAction(OrgPath file, string matchString, out OrgItem item, bool threaded, bool fast, bool skipMatching, Movie knownMovie)
        {
            // Initialize item
            item = new OrgItem(OrgAction.None, file.Path, FileCategory.MovieVideo, file.OrgFolder);

            // Check if sample!
            if (matchString.ToLower().Contains("sample"))
            {
                item.Action = OrgAction.Delete;
                return false;
            }

            // Try to match file to movie
            string search = Path.GetFileNameWithoutExtension(matchString);

            // Search for match to movie
            Movie searchResult = null;
            bool searchSucess = false;
            if (!skipMatching)
                searchSucess = SearchHelper.MovieSearch.ContentMatch(search, string.Empty, string.Empty, fast, threaded, out searchResult, knownMovie);

            // Add closest match item
            if (searchSucess)
            {
                // Get root folder
                ContentRootFolder rootFolder;
                string path;
                if (Settings.GetMovieFolderForContent(searchResult, out rootFolder))
                    searchResult.RootFolder = rootFolder.FullPath;
                else
                {
                    searchResult.RootFolder = NO_MOVIE_FOLDER;
                    item.Action = OrgAction.NoRootFolder;
                }

                if (item.Action != OrgAction.NoRootFolder)
                    item.Action = file.Copy ? OrgAction.Copy : OrgAction.Move;
                item.DestinationPath = searchResult.BuildFilePath(file.Path);
                if (File.Exists(item.DestinationPath))
                    item.Action = OrgAction.AlreadyExists;
                searchResult.Path = searchResult.BuildFolderPath();
                item.Movie = searchResult;
                if (item.Action == OrgAction.AlreadyExists || item.Action == OrgAction.NoRootFolder)
                    item.Enable = false;
                else
                    item.Enable = true;
                return true;
            }

            return false;
        }
コード例 #7
0
ファイル: DirectoryScan.cs プロジェクト: Garreye/meticumedia
        public OrgItem ProcessPath(OrgPath orgPath, bool tvOnlyCheck, bool skipMatching, bool fast, bool threaded, int procNumber, bool allowFromLog, out bool fromLog)
        {
            fromLog = false;
            FileCategory fileCat = FileHelper.CategorizeFile(orgPath, orgPath.Path);

            // Search through dir scan log for matching source
            if(allowFromLog)
                for (int i = 0; i < Organization.DirScanLog.Count; i++)
                {
                    if (Organization.DirScanLog[i].SourcePath == orgPath.Path)
                    {
                        fromLog = true;

                        if (fileCat != Organization.DirScanLog[i].Category)
                            break;

                        OrgItem newItem = UpdateItemFromPrevious(orgPath, Organization.DirScanLog[i], threaded, false, false);
                        if (newItem != null && newItem.Action != OrgAction.None)
                        {
                            if (newItem.CanEnable)
                                newItem.Enable = true;
                            return newItem;
                        }
                    }
                }

            // If similar to earlier item, wait for it to complete before continuing
            while (!skipMatching && orgPath.SimilarTo >= 0 && orgPath.SimilarTo < this.Items.Count && (this.Items[orgPath.SimilarTo].Action == OrgAction.TBD || this.Items[orgPath.SimilarTo].Action == OrgAction.Processing))
            {
                // Check for cancellation
                if (scanCanceled || procNumber < scanNumber)
                    return null;

                Thread.Sleep(50);
            }

            // If similar to earlier item, check if we can use it's info
            if (orgPath.SimilarTo > 0 && orgPath.SimilarTo < this.Items.Count)
            {
                OrgItem newItem = UpdateItemFromPrevious(orgPath, this.Items[orgPath.SimilarTo], threaded, fast, skipMatching);
                if (newItem != null)
                    return newItem;
            }

            // Create default none item
            OrgItem noneItem = new OrgItem(OrgAction.None, orgPath.Path, fileCat, orgPath.OrgFolder);

            // Setup match to filename and folder name (if it's in a folder inside of downloads)
            string pathBase;
            if (!string.IsNullOrEmpty(orgPath.OrgFolder.FolderPath))
                pathBase = orgPath.Path.Replace(orgPath.OrgFolder.FolderPath, "");
            else
                pathBase = orgPath.Path;
            string[] pathSplit;
            if (!string.IsNullOrEmpty(orgPath.OrgFolder.FolderPath))
                pathSplit = pathBase.Split('\\');
            else
                pathSplit = orgPath.Path.Split('\\');
            pathSplit[pathSplit.Length - 1] = Path.GetFileNameWithoutExtension(pathSplit[pathSplit.Length - 1]);

            List<string> possibleMatchPaths = new List<string>();

            // Looking to remove dummy video files by rip (e.g. "ERTG.mp4" inside "The Matrix 1999 hd ERGT rip/" folder)
            List<string> validSplits = new List<string>();
            for (int i = pathSplit.Length - 1; i > 0; i--)
            {
                if (string.IsNullOrWhiteSpace(pathSplit[i]))
                    continue;

                bool containedInOther = false;
                for (int j = i - 1; j > 0; j--)
                {
                    if (pathSplit[j].Length > pathSplit[i].Length && pathSplit[j].ToLower().Contains(pathSplit[i].ToLower()))
                    {
                        containedInOther = true;
                        break;
                    }
                }

                if (!containedInOther)
                {
                    validSplits.Add(pathSplit[i]);
                    possibleMatchPaths.Add(pathSplit[i] + Path.GetExtension(orgPath.Path));
                }
            }

            for (int i = validSplits.Count - 1; i >= 0; i--)
            {
                string build = string.Empty;
                for (int j = validSplits.Count - 1; j >=i ; j--)
                    build += validSplits[j] + " ";

                build = build.Trim();

                build += Path.GetExtension(orgPath.Path);
                if (!possibleMatchPaths.Contains(build))
                    possibleMatchPaths.Add(build);
            }

            // Try to match to each string
            foreach (string matchString in possibleMatchPaths)
            {
                OnDebugNotificationd("Attempting to match to path: \" " + matchString + "\"");

                // Get simple file name
                string simpleFile = FileHelper.BasicSimplify(Path.GetFileNameWithoutExtension(matchString), false);
                OnDebugNotificationd("Simplifies to:  \" " + simpleFile + "\"");

                // Categorize current match string
                FileCategory matchFileCat = FileHelper.CategorizeFile(orgPath, matchString);
                OnDebugNotificationd("Classified as: " + matchFileCat);

                // Check tv
                if (tvOnlyCheck && matchFileCat != FileCategory.TvVideo)
                    continue;

                // Check for cancellation
                if (scanCanceled || procNumber < scanNumber)
                    return null;

                // Set whether item is for new show
                bool newShow = false;

                // Check for cancellation
                if (scanCanceled || procNumber < scanNumber)
                    return null;

                // Add appropriate action based on file category
                switch (matchFileCat)
                {
                    // TV item
                    case FileCategory.TvVideo:

                        // Try to match file to existing show
                        Dictionary<TvShow, MatchCollection> matches = new Dictionary<TvShow, MatchCollection>();
                        for (int j = 0; j < Organization.Shows.Count; j++)
                        {
                            MatchCollection match = Organization.Shows[j].MatchFileToContent(matchString);
                            if (match != null && match.Count > 0)
                                matches.Add((TvShow)Organization.Shows[j], match);
                        }

                        // Try to match to temporary show
                        lock (directoryScanLock)
                            foreach (TvShow show in temporaryShows)
                            {
                                MatchCollection match = show.MatchFileToContent(matchString);
                                if (match != null && match.Count > 0 && !matches.ContainsKey(show))
                                    matches.Add(show, match);
                            }

                        // Debug notification for show matches
                        string matchNotification = "Show name matches found: ";
                        if (matches.Count == 0)
                            matchNotification += "NONE";
                        else
                        {
                            foreach (TvShow match in matches.Keys)
                                matchNotification += match.DisplayName + ", ";
                            matchNotification = matchNotification.Substring(0, matchNotification.Length - 2);
                        }
                        OnDebugNotificationd(matchNotification);

                        // Check for matches to existing show
                        TvShow bestMatch = null;
                        if (matches.Count > 0)
                        {
                            // Find best match, based on length
                            int longestMatch = 2; // minimum of 3 letters must match (acronym)
                            foreach (KeyValuePair<TvShow, MatchCollection> match in matches)
                                foreach (Match m in match.Value)
                                {
                                    // Check that match is not part of a word
                                    int matchWordCnt = 0;
                                    for (int l = m.Index; l < simpleFile.Length; l++)
                                    {
                                        if (simpleFile[l] == ' ')
                                            break;
                                        else
                                            ++matchWordCnt;
                                    }

                                    if (m.Value.Trim().Length > longestMatch && m.Length >= matchWordCnt)
                                    {
                                        longestMatch = m.Length;
                                        bestMatch = match.Key;
                                    }
                                }
                            if (bestMatch != null)
                                OnDebugNotificationd("Matched to show " + bestMatch.DisplayName);
                        }

                        // Episode not matched to a TV show, search database!
                        if (bestMatch == null && !skipMatching)
                        {
                            OnDebugNotificationd("Not matched to existing show; searching database.");

                            // Setup search string
                            string showFile = Path.GetFileNameWithoutExtension(matchString);

                            // Perform search for matching TV show
                            if (SearchHelper.TvShowSearch.ContentMatch(showFile, string.Empty, string.Empty, fast, threaded, out bestMatch))
                            {
                                ContentRootFolder defaultTvFolder;
                                string path = NO_TV_FOLDER;
                                if (Settings.GetTvFolderForContent(bestMatch, out defaultTvFolder))
                                    path = defaultTvFolder.FullPath;

                                bestMatch.RootFolder = path;
                                bestMatch.Path = bestMatch.BuildFolderPath();

                                // Save show in temporary shows list (in case there are more files that may match to it during scan)
                                lock (directoryScanLock)
                                    if (!temporaryShows.Contains(bestMatch))
                                        temporaryShows.Add(bestMatch);
                                newShow = true;
                            }
                            else
                                bestMatch = null;
                        }
                        else if (temporaryShows.Contains(bestMatch))
                            newShow = true;

                        // Episode has been matched to a TV show
                        if (bestMatch != null)
                        {
                            // Try to get episode information from file
                            int seasonNum, episodeNum1, episodeNum2;
                            if (FileHelper.GetEpisodeInfo(matchString, bestMatch.DatabaseName, out seasonNum, out episodeNum1, out episodeNum2))
                            {
                                // No season match means file only had episode number, allow this for single season shows
                                if (seasonNum == -1)
                                {
                                    int maxSeason = 0;
                                    foreach (int season in bestMatch.Seasons)
                                        if (season > maxSeason)
                                            maxSeason = season;

                                    if (maxSeason == 1)
                                        seasonNum = 1;
                                }

                                // Try to get the episode from the show
                                TvEpisode episode1, episode2 = null;
                                if (bestMatch.FindEpisode(seasonNum, episodeNum1, false, out episode1))
                                {
                                    if (episodeNum2 != -1)
                                        bestMatch.FindEpisode(seasonNum, episodeNum2, false, out episode2);

                                    OrgAction action = orgPath.Copy ? OrgAction.Copy : OrgAction.Move;

                                    // If item episode already exists set action to duplicate
                                    if (episode1.Missing == MissingStatus.Located)
                                        action = OrgAction.AlreadyExists;

                                    // Build action and add it to results
                                    string destination = bestMatch.BuildFilePath(episode1, episode2, Path.GetExtension(orgPath.Path));
                                    OrgItem newItem = new OrgItem(action, orgPath.Path, destination, episode1, episode2, fileCat, orgPath.OrgFolder);
                                    if (destination.StartsWith(NO_TV_FOLDER))
                                        newItem.Action = OrgAction.NoRootFolder;
                                    if (newItem.Action == OrgAction.AlreadyExists || newItem.Action == OrgAction.NoRootFolder)
                                        newItem.Enable = false;
                                    else
                                        newItem.Enable = true;
                                    newItem.Category = matchFileCat;
                                    newItem.IsNewShow = newShow;
                                    return newItem;
                                }
                                else
                                    OnDebugNotificationd("Couldn't find episode for season " + seasonNum + " episods " + episodeNum1);
                            }
                        }

                        // No match to TV show
                        if (!tvOnlyCheck && !fast)
                        {
                            // Try to match to a movie
                            OrgItem movieItem;
                            if (CreateMovieAction(orgPath, matchString, out movieItem, threaded, fast, skipMatching, null))
                                noneItem.Clone(movieItem);
                        }

                        break;

                    // Movie item
                    case FileCategory.MovieVideo:
                        // Create action
                        OrgItem item;
                        CreateMovieAction(orgPath, matchString, out item, threaded, fast, skipMatching, null);

                        // If delete action created (for sample file)
                        if (item.Action == OrgAction.Delete)
                            return BuildDeleteAction(orgPath, fileCat);
                        else if (item.Action != OrgAction.None)
                            return item;
                        break;

                    // Trash
                    case FileCategory.Trash:
                        return BuildDeleteAction(orgPath, matchFileCat);
                    // Ignore
                    case FileCategory.Ignored:
                        return new OrgItem(OrgAction.None, orgPath.Path, matchFileCat, orgPath.OrgFolder);
                    // Unknown
                    default:
                        return new OrgItem(OrgAction.None, orgPath.Path, matchFileCat, orgPath.OrgFolder);
                }

                // Check for cancellation
                if (scanCanceled || procNumber < scanNumber)
                    return noneItem;
            }

            // If no match on anything set none action
            return noneItem;
        }
コード例 #8
0
        /// <summary>
        /// Recursively run a scan on a set of movie folders and their sub-folders
        /// </summary>
        /// <param name="folders">Movie folder to perform scan on</param>
        /// <param name="scanResults">Scan results to build on.</param>
        /// <param name="queuedItems">Items already in the queue</param>
        private void RunScan(List<ContentRootFolder> folders, List<OrgItem> scanResults, List<OrgItem> queuedItems)
        {
            // Get unknown files (files not in content folder) from root folders
            OnProgressChange(ScanProcess.FileCollect, string.Empty, 0);
            List<OrgPath> files = GetUnknownFiles(folders);

            // Initialize item numbering
            int number = 0;

            // Go through unknwon files and try to match each file to a movie
            for (int i = 0; i < files.Count; i++)
            {
                // Check for cancellation
                if (scanCanceled)
                    break;

                // Update progress
                OnProgressChange(ScanProcess.Movie, files[i].Path, (int)Math.Round((double)i / files.Count * 70));

                // Categorize the file
                FileCategory fileCat = FileHelper.CategorizeFile(files[i], files[i].Path);

                // Check that video file (tv is okay, may match incorrectly)
                if (fileCat != FileCategory.MovieVideo && fileCat != FileCategory.TvVideo && fileCat != FileCategory.Trash)
                    continue;

                // Check that file is not already in the queue
                bool alreadyQueued = false;
                foreach (OrgItem queued in queuedItems)
                    if (queued.SourcePath == files[i].Path)
                    {
                        OrgItem newItem = new OrgItem(queued);
                        newItem.Action = OrgAction.Queued;
                        newItem.Number = number++;
                        scanResults.Add(newItem);
                        alreadyQueued = true;
                        break;
                    }
                if (alreadyQueued)
                    continue;

                // Check for trash
                if (fileCat == FileCategory.Trash)
                {
                    OrgItem delItem = new OrgItem(OrgAction.Delete, files[i].Path, fileCat, files[i].OrgFolder);
                    scanResults.Add(delItem);
                    continue;
                }

                // Try to match file to movie
                string search = Path.GetFileNameWithoutExtension(files[i].Path);
                Movie searchResult;
                bool searchSucess = SearchHelper.MovieSearch.ContentMatch(search, files[i].RootFolder.FullPath, string.Empty, false, true, out searchResult, null);

                // Add closest match item
                OrgItem item = new OrgItem(OrgAction.None, files[i].Path, fileCat, files[i].OrgFolder);
                item.Number = number++;
                if (searchSucess && !string.IsNullOrEmpty(searchResult.DatabaseName))
                {
                    item.Action = OrgAction.Move;
                    item.DestinationPath = searchResult.BuildFilePath(files[i].Path);
                    searchResult.Path = searchResult.BuildFolderPath();
                    item.Movie = searchResult;
                    item.Enable = true;
                }
                scanResults.Add(item);
            }

            // Get knwon movie files (files from within content folders)
            files = GetKnownFiles(folders);

            // Go through each known file and check if renaming is needed
            for (int i = 0; i < files.Count; i++)
            {
                // Check for cancellation
                if (scanCanceled)
                    break;

                // Update progress
                OnProgressChange(ScanProcess.Movie, files[i].Path, (int)Math.Round((double)i / files.Count * 20) + 70);

                // Categorize the file
                FileCategory fileCat = FileHelper.CategorizeFile(files[i], files[i].Path);

                // Check that video file (tv is okay, may match incorrectly)
                if (fileCat != FileCategory.MovieVideo && fileCat != FileCategory.TvVideo && fileCat != FileCategory.Trash)
                    continue;

                // Check that movie is valide
                Movie movie = (Movie)files[i].Content;
                if (movie == null || string.IsNullOrEmpty(movie.DatabaseName))
                    continue;

                // Check that file is not already in the queue
                bool alreadyQueued = false;
                foreach (OrgItem queued in queuedItems)
                    if (queued.SourcePath == files[i].Path)
                    {
                        alreadyQueued = true;
                        break;
                    }
                if (alreadyQueued)
                    continue;

                // Check for trash
                if (fileCat == FileCategory.Trash)
                {
                    OrgItem delItem = new OrgItem(OrgAction.Delete, files[i].Path, fileCat, files[i].OrgFolder);
                    scanResults.Add(delItem);
                    continue;
                }

                // Check if file needs to be renamed
                string newPath = movie.BuildFilePathNoFolderChanges(files[i].Path);
                if (newPath != files[i].Path && !File.Exists(newPath))
                {
                    // Add rename to results
                    OrgItem item = new OrgItem(OrgAction.Rename, files[i].Path, FileCategory.MovieVideo, files[i].OrgFolder);
                    item.Number = number++;
                    if (Path.GetDirectoryName(newPath) != Path.GetDirectoryName(files[i].Path))
                        item.Action = OrgAction.Move;

                    item.DestinationPath = newPath;
                    item.Movie = movie;
                    item.Enable = true;
                    scanResults.Add(item);
                }
            }

            // Check if any movie folders need to be renamed!
            foreach (Movie movie in Organization.GetContentFromRootFolders(folders))
            {
                if (!string.IsNullOrEmpty(movie.DatabaseName) && movie.Path != movie.BuildFolderPath())
                {
                    OrgItem item = new OrgItem(OrgAction.Rename, movie.Path, FileCategory.Folder, movie, movie.BuildFolderPath(), null);
                    item.Enable = true;
                    item.Number = number++;
                    scanResults.Add(item);
                }
            }

            // Update progress
            OnProgressChange(ScanProcess.Movie, string.Empty, 100);
        }
コード例 #9
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the movie
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByMovie(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = Path.GetDirectoryName(x.Movie.DatabaseName).CompareTo(Path.GetDirectoryName(y.Movie.DatabaseName));
            }

            if (sortResult == 0)
                return CompareBySourceFile(x, y);

            return SetSort(sortResult);
        }
コード例 #10
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the tv episode's show name
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByShowName(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = x.TvEpisode.Show.CompareTo(y.TvEpisode.Show);
            }

            if (sortResult == 0)
                return CompareBySeasonNumber(x, y);

            return SetSort(sortResult);
        }
コード例 #11
0
ファイル: Organization.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Action log loading work
        /// </summary>
        private static void LoadActionLog(object sender, DoWorkEventArgs e)
        {
            try
            {
                string path = Path.Combine(GetBasePath(false), ACTION_LOG_XML + ".xml");
                if (File.Exists(path))
                    lock (ActionLogFileLock)
                    {
                        // Load XML
                        XmlTextReader reader = new XmlTextReader(path);
                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.Load(reader);

                        // Load movies data
                        List<OrgItem> loadActionLog = new List<OrgItem>();
                        XmlNodeList logNodes = xmlDoc.DocumentElement.ChildNodes;
                        for (int i = 0; i < logNodes.Count; i++)
                        {
                            OnActionLogLoadProgressChange((int)(((double)i / logNodes.Count) * 100));

                            OrgItem item = new OrgItem();
                            if (item.Load(logNodes[i]))
                                loadActionLog.Add(item);
                        }

                        reader.Close();
                        OnActionLogLoadProgressChange(100);

                        lock (ActionLogLock)
                        {
                            ActionLog.Clear();
                            foreach (OrgItem item in loadActionLog)
                                ActionLog.Add(item);
                        }
                    }
            }
            catch { }

            OnActionLogLoadComplete();
        }
コード例 #12
0
ファイル: Organization.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Action log loading work
        /// </summary>
        public static void LoadScanDirLog(object sender, DoWorkEventArgs e)
        {
            try
            {
                string path = Path.Combine(GetBasePath(false), DIR_SCAN_LOG_XML + ".xml");
                List<OrgItem> loadScanDirLog = new List<OrgItem>();
                if (File.Exists(path))
                {
                    lock (DirScanLogFileLock)
                    {
                        // Load XML
                        XmlTextReader reader = new XmlTextReader(path);
                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.Load(reader);

                        // Load movies data

                        XmlNodeList logNodes = xmlDoc.DocumentElement.ChildNodes;
                        for (int i = 0; i < logNodes.Count; i++)
                        {
                            OrgItem item = new OrgItem();
                            if (item.Load(logNodes[i]))
                            {
                                if (File.Exists(item.SourcePath))
                                {
                                    for (int j = 0; j < Settings.ScanDirectories.Count; j++)
                                        if (item.sourcePath.ToLower().Contains(Settings.ScanDirectories[j].FolderPath.ToLower()))
                                        {
                                            loadScanDirLog.Add(item);
                                            break;
                                        }
                                }
                            }
                        }

                        reader.Close();
                    }

                    lock (DirScanLogLock)
                    {
                        DirScanLog.Clear();
                        foreach (OrgItem item in loadScanDirLog)
                            DirScanLog.Add(item);
                    }
                }

            }
            catch { }
        }
コード例 #13
0
ファイル: Organization.cs プロジェクト: Garreye/meticumedia
 /// <summary>
 /// Adds item to log.
 /// </summary>
 /// <param name="item"></param>
 public static void AddDirScanLogItem(OrgItem item)
 {
     lock (DirScanLogLock)
         DirScanLog.Insert(0, item);
     SaveDirScanLog();
 }
コード例 #14
0
ファイル: Organization.cs プロジェクト: Garreye/meticumedia
 /// <summary>
 /// Adds item to log.
 /// </summary>
 /// <param name="item"></param>
 public static void AddActionLogItem(OrgItem item)
 {
     lock (ActionLogLock)
         ActionLog.Insert(0, item);
     SaveActionLog();
 }
コード例 #15
0
        public bool BuildFolderMoveItem(string folderPath, OrgFolder scanDir, out OrgItem item)
        {
            item = new OrgItem(folderPath, this, scanDir, true);

            if (!this.MoveFolder)
                return false;

            string[] fileList = Directory.GetFiles(folderPath);
            foreach (string file in fileList)
            {
                OrgItem fileItem;
                if (this.BuildFileMoveItem(file, scanDir, out fileItem))
                    return true;
            }
            string[] subDirs = Directory.GetDirectories(folderPath);
            foreach (string subDir in subDirs)
            {
                OrgItem subItem;
                if (this.BuildFolderMoveItem(subDir, scanDir, out subItem))
                    return true;
            }

            return false;
        }
コード例 #16
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the folder of destination path
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByDestinationFolder(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                {
                    string xStr = "", yStr = "";

                    if (x.DestinationPath != FileHelper.DELETE_DIRECTORY)
                        xStr = Path.GetFileName(x.DestinationPath);
                    else
                        xStr = x.DestinationPath;
                    if (y.DestinationPath != FileHelper.DELETE_DIRECTORY)
                        yStr = Path.GetFileName(y.DestinationPath);
                    else
                        yStr = y.DestinationPath;

                    sortResult = xStr.CompareTo(yStr);
                }
            }

            if (sortResult == 0)
                return CompareByDestinationFile(x, y);

            return SetSort(sortResult);
        }
コード例 #17
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the tv episode's number
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByEpisodeNumber(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = x.TvEpisode.DisplayNumber.CompareTo(y.TvEpisode.DisplayNumber);
            }

            if (sortResult == 0)
                return CompareBySourceFile(x, y);

            return SetSort(sortResult);
        }
コード例 #18
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the source path
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareBySourceFile(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = Path.GetFileName(x.SourcePath).CompareTo(Path.GetFileName(y.SourcePath));
            }

            return SetSort(sortResult);
        }
コード例 #19
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the action
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByNumber(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = x.Number.CompareTo(y.Number);
            }

            return SetSort(sortResult);
        }
コード例 #20
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the folder of source
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareBySourceFolder(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null || string.IsNullOrEmpty(x.SourcePath))
            {
                if (y == null || string.IsNullOrEmpty(y.SourcePath))
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null || string.IsNullOrEmpty(y.SourcePath))
                    sortResult = 1;
                else
                    sortResult = Path.GetDirectoryName(x.SourcePath).CompareTo(Path.GetDirectoryName(y.SourcePath));
            }

            if (sortResult == 0)
                return CompareBySourceFile(x, y);

            return SetSort(sortResult);
        }
コード例 #21
0
 private void DeleteContent()
 {
     if (MessageBox.Show("Are you want to delete the selected items? This operation cannot be undone", "Sure?", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
     {
         List<OrgItem> items = new List<OrgItem>();
         foreach (Content content in this.SelectedContents)
         {
            OrgItem item = new OrgItem(OrgAction.Delete, content.Path, content, null);
            items.Add(item);
         }
         OnItemsToQueue(items);
     }
 }
コード例 #22
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the status
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByStatus(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = x.Status.ToString().CompareTo(y.Status.ToString());
            }

            if (sortResult == 0)
                return CompareByShowName(x, y);

            return SetSort(sortResult);
        }
コード例 #23
0
ファイル: TvEpisode.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Open file dialog so user can locate episode in file directory.
        /// </summary>
        /// <param name="showActionModifer">Whether to display action modifier after path is selected</param>
        /// <param name="copyAction">Whether to copy file, move otherwise</param>
        /// <param name="items">Organization items to add move/copy action to once located</param>
        /// <returns>true if locate was sucessful</returns>
        public bool UserLocate(bool showActionModifer, bool copyAction, out List<OrgItem> items)
        {
            // Initialize org items
            items = new List<OrgItem>();

            // Open file dialog
            VistaOpenFileDialog ofd = new VistaOpenFileDialog();
            ofd.Filter = "All Files|*.*";
            if (!(bool)ofd.ShowDialog())
                return false;

            // Try to get episode information from file
            int fileEpSeason, fileEpNumber1, fileEpNumber2;
            bool fileInfoFound = FileHelper.GetEpisodeInfo(ofd.FileName, this.Show.DatabaseName, out fileEpSeason, out fileEpNumber1, out fileEpNumber2);

            // Assign episodes
            TvEpisode ep1 = this;
            TvEpisode ep2 = null;

            // Locate could be for double episode file, only taken if one of the episode from file matches selected
            if (fileInfoFound && fileEpSeason == this.Season)
            {
                if (fileEpNumber1 == this.DisplayNumber)
                {
                    if (fileEpNumber2 > 0)
                        show.FindEpisode(ep1.Season, fileEpNumber2, false, out ep2);
                    else
                        ep2 = null;
                }
                else if (fileEpNumber2 == this.DisplayNumber)
                {
                    if (fileEpNumber1 > 0 && show.FindEpisode(this.Season, fileEpNumber1, false, out ep1))
                        ep2 = this;
                    else
                        ep1 = this;
                }
            }

            // Build org item
            OrgAction action = copyAction ? OrgAction.Copy : OrgAction.Move;
            string destination = show.BuildFilePath(ep1, ep2, Path.GetExtension(ofd.FileName));
            OrgItem item = new OrgItem(OrgStatus.Found, action, ofd.FileName, destination, ep1, ep2, FileCategory.TvVideo, null);

            // Display modifier
            if (showActionModifer)
            {
                OrgItemEditorWindow editor = new OrgItemEditorWindow(item);
                editor.ShowDialog();

                // Add results if valid
                if (editor.Results == null)
                    return false;

                items.Add(editor.Results);
                return true;
            }

            items.Add(item);
            return true;
        }
コード例 #24
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
 /// <summary>
 /// Update current update from another item's data
 /// </summary>
 /// <param name="item">item to be copied</param>
 public void Clone(OrgItem item)
 {
     this.Status = item.Status;
     this.Progress = 0;
     this.Action = item.Action;
     this.SourcePath = item.SourcePath;
     this.DestinationPath = item.DestinationPath;
     this.TvEpisode = item.TvEpisode;
     this.TvEpisode2 = item.TvEpisode2;
     this.TorrentTvEpisode = item.TorrentTvEpisode;
     this.Category = item.Category;
     this.Enable = item.Enable;
     this.Movie = item.Movie;
     this.ScanDirectory = item.ScanDirectory;
     this.Replace = item.Replace;
     this.Number = item.Number;
     this.QueueStatus = item.QueueStatus;
     this.ActionComplete = item.ActionComplete;
     this.Notes = item.Notes;
     this.ActionTime = item.ActionTime;
 }
コード例 #25
0
ファイル: DirectoryScan.cs プロジェクト: Garreye/meticumedia
 /// <summary>
 /// Creates a delete action for a file.
 /// </summary>
 /// <param name="scanResults">The current scan action list to add action to.</param>
 /// <param name="file">The file to be deleted</param>
 /// <param name="fileCat">The category of the file</param>
 private OrgItem BuildDeleteAction(OrgPath file, FileCategory fileCat)
 {
     OrgItem newItem;
     if (file.AllowDelete)
     {
         newItem = new OrgItem(OrgAction.Delete, file.Path, fileCat, file.OrgFolder);
         newItem.Enable = true;
     }
     else
     {
         newItem = new OrgItem(OrgAction.None, file.Path, fileCat, file.OrgFolder);
     }
     return newItem;
 }
コード例 #26
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
 /// <summary>
 /// Constructor for copying item.
 /// </summary>
 /// <param name="item">item to be copied</param>
 public OrgItem(OrgItem item)
 {
     Clone(item);
 }
コード例 #27
0
ファイル: DirectoryScan.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Directory scan processing method (thread) for a single file path.
        /// </summary>
        /// <param name="orgPath">Organization path instance to be processed</param>
        /// <param name="pathNum">The path's number out of total being processed</param>
        /// <param name="totalPaths">Total number of paths being processed</param>
        /// <param name="updateNumber">The identifier for the OrgProcessing instance</param>
        /// <param name="background">Whether processing is running as a background operation</param>
        /// <param name="subSearch">Whether processing is sub-search(TV only)</param>
        /// <param name="processComplete">Delegate to be called by processing when completed</param>
        /// <param name="numItemsProcessed">Number of paths that have been processed - used for progress updates</param>
        private void ThreadProcess(OrgPath orgPath, int pathNum, int totalPaths, int updateNumber, ref int numItemsProcessed, ref int numItemsStarted, object processSpecificArgs)
        {
            // Process specific arguments
            object[] args = (object[])processSpecificArgs;
            bool tvOnlyCheck = (bool)args[0];
            bool skipMatching = (bool)args[1];
            bool fast = (bool)args[2];
            int procNumber = (int)args[3];
            int pass = (int)args[4];
            bool reuseResults = (bool)args[5];

            // Check if item is already processed
            if (this.Items[pathNum].Action != OrgAction.TBD)
                return;

            // Check if file is in the queue
            bool alreadyQueued = false;
            if (itemsInQueue != null)
                for (int i = 0; i < itemsInQueue.Count; i++)
                    if (itemsInQueue[i].SourcePath == orgPath.Path)
                    {
                        OrgItem newItem = new OrgItem(itemsInQueue[i]);
                        newItem.Action = OrgAction.Queued;
                        newItem.Enable = true;
                        UpdateResult(newItem, pathNum, procNumber);
                        alreadyQueued = true;
                        break;
                    }

            // If item is already in the queue, skip it
            if (alreadyQueued)
                ProcessUpdate(orgPath.Path, totalPaths, pass);
            else
            {
                // Update progress
                lock (directoryScanLock)
                    this.Items[pathNum].Action = OrgAction.Processing;

                // Process path
                bool fromLog;
                OrgItem results = ProcessPath(orgPath, tvOnlyCheck, skipMatching || (!fast && pass == 0), fast || pass == 0, true, procNumber, reuseResults, out fromLog);

                // Update results and progress
                if (results != null && (results.Action != OrgAction.None || results.Category == FileCategory.Ignored || fast || pass == 1))
                {
                    UpdateResult(results, pathNum, procNumber);
                    ProcessUpdate(orgPath.Path, totalPaths, pass);

                    if (!fromLog && (results.Action != OrgAction.None && (results.Category == FileCategory.MovieVideo || results.Category == FileCategory.TvVideo)))
                    {
                        Organization.AddDirScanLogItem(new OrgItem(results));
                    }
                }
                else
                    lock (directoryScanLock)
                        this.Items[pathNum].Action = OrgAction.TBD;

            }
        }
コード例 #28
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the category 
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByCategory(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = x.Category.ToString().CompareTo(y.Category.ToString());
            }

            if (sortResult == 0)
                return CompareBySourceFile(x, y);

            return SetSort(sortResult);
        }
コード例 #29
0
ファイル: DirectoryScan.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Add item to directory scan results list in dictionary. Variables accessed by multiple threads, so controlled.
        /// </summary>
        /// <param name="scanNum">The scan number to add item to</param>
        /// <param name="item">Item to add to results list</param>
        private void UpdateResult(OrgItem item, int pathNum, int procNum)
        {
            if (scanCanceled || procNum < scanNumber)
                return;

            lock (directoryScanLock)
                this.Items[pathNum].Clone(item);
        }
コード例 #30
0
ファイル: OrgItem.cs プロジェクト: Garreye/meticumedia
        /// <summary>
        /// Compares two OrgItem instances by the  date time of action
        /// </summary>
        /// <param name="x">The first item</param>
        /// <param name="y">The second item</param>
        /// <returns>Compare results of two items</returns>
        public static int CompareByDateTime(OrgItem x, OrgItem y)
        {
            int sortResult;
            if (x == null)
            {
                if (y == null)
                    sortResult = 0;
                else
                    sortResult = -1;
            }
            else
            {
                if (y == null)
                    sortResult = 1;
                else
                    sortResult = x.ActionTime.CompareTo(y.ActionTime);
            }

            return SetSort(sortResult);
        }