示例#1
0
        //Ensures that all placeholders in the pattern refer to existing tag frame properties.
        //Then it attempts to mapping dictionary between the frame name and the corresponding frame
        //property, so that multiple renames can be done fast.
        private static Dictionary <string, PropertyInfo> ValidatePatternAndBuildMapping(string pattern)
        {
            //Find all placeholders within the pattern. If there are none, throw an exception.
            MatchCollection framePlaceholderMatches = FramePlaceholderPattern.Matches(pattern);

            if (framePlaceholderMatches.Count == 0)
            {
                throw new ArgumentException(string.Format(Id3FileMessages.MissingPlaceholdersInPattern, pattern));
            }

            //Get all public properties in the tag that derive from Id3Frame.
            PropertyInfo[] frameProperties =
                typeof(Id3Tag).GetProperties().Where(prop => prop.PropertyType.IsSubclassOf(typeof(Id3Frame))).ToArray();

            //Iterate through each placeholder and find the corresponding frame property. If such a
            //property does not exist, throw an exception; otherwise add a mapping from the frame name
            //to the property.
            var mapping = new Dictionary <string, PropertyInfo>(framePlaceholderMatches.Count);

            foreach (Match match in framePlaceholderMatches)
            {
                string       matchedFrameName      = match.Groups[1].Value.ToLowerInvariant();
                PropertyInfo matchingFrameProperty =
                    frameProperties.FirstOrDefault(frame => frame.Name.Equals(matchedFrameName, StringComparison.InvariantCultureIgnoreCase));
                if (matchingFrameProperty == null)
                {
                    throw new ArgumentException(string.Format(Id3FileMessages.MissingTagProperty, matchedFrameName));
                }
                if (!mapping.ContainsKey(matchedFrameName))
                {
                    mapping.Add(matchedFrameName, matchingFrameProperty);
                }
            }
            return(mapping);
        }
示例#2
0
        /// <summary>
        ///     Ensures that all placeholders in the pattern refer to existing tag frame properties. Then it attempts to mapping
        ///     dictionary between the frame name and the corresponding frame property, so that multiple renames can be done fast.
        /// </summary>
        /// <param name="patterns">The pattern to validate</param>
        /// <returns>A mapping of placeholder name to property info of the correspoding frame in <see cref="Id3Tag" /></returns>
        /// <exception cref="ArgumentException">Thrown if any pattern contains invalid placeholders.</exception>
        private static void ValidatePatterns(IEnumerable <string> patterns)
        {
            // Get all distinct placeholder names in all the patterns and check whether any of them
            // do not appear as a key in the _mappings dictionary. If so, throw an exception.
            string[] invalidPlaceholders = patterns
                                           .SelectMany(pattern => {
                MatchCollection matches = FramePlaceholderPattern.Matches(pattern);
                if (matches.Count == 0)
                {
                    throw new ArgumentException(string.Format(FileNamerMessages.MissingPlaceholdersInPattern,
                                                              pattern));
                }
                return(matches.Cast <Match>().Select(m => m.Groups[1].Value));
            })
                                           .Distinct(StringComparer.OrdinalIgnoreCase)
                                           .Where(ph => !_mapping.ContainsKey(ph))
                                           .ToArray();
            if (invalidPlaceholders.Length <= 0)
            {
                return;
            }

            //Build detailed exception and throw it.
            string invalidPlaceholderNames = string.Join(", ", invalidPlaceholders);
            string allowedPlaceholderNames = string.Join(", ", _allowedFrames);
            string exceptionMessage        = "The following placeholders are not allowed in the file naming patterns:" + Environment.NewLine +
                                             Environment.NewLine +
                                             invalidPlaceholderNames + Environment.NewLine +
                                             Environment.NewLine +
                                             "Only these placeholders are allowed:" + Environment.NewLine +
                                             Environment.NewLine +
                                             allowedPlaceholderNames;

            throw new ArgumentException(exceptionMessage, nameof(patterns));
        }
示例#3
0
        private string GetNewName(Id3Tag tag, string originalName, out string missingFrameName)
        {
            missingFrameName = null;
            string missingFrame = null;

            //Make two passes of the patterns.
            //In the first pass, we try to find the perfect match without resorting to the
            //ResolveMissingData event.
            //If we still don't have a match, in the second pass, we use the ResolveMissingData event.
            for (var i = 0; i < 2; i++)
            {
                foreach (string pattern in _patterns)
                {
                    var hasMissingFrames = false;

                    int    iteration = i;
                    string newName   = FramePlaceholderPattern.Replace(pattern, match => {
                        //If this pattern already has missing frames, don't proces anything
                        if (hasMissingFrames)
                        {
                            return(string.Empty);
                        }

                        string frameName           = match.Groups[1].Value;
                        PropertyInfo frameProperty = _mapping[frameName];

                        //Because all frame properties in Id3Tag are lazily-loaded, this will never be null
                        var frame = (Id3Frame)frameProperty.GetValue(tag, null);

                        if (frame.IsAssigned)
                        {
                            return(frame.ToString());
                        }

                        if (iteration == 1)
                        {
                            string frameValue = FireResolveMissingDataEvent(tag, frame, originalName);
                            if (!string.IsNullOrWhiteSpace(frameValue))
                            {
                                return(frameValue);
                            }
                        }
                        hasMissingFrames = true;
                        missingFrame     = frameName;
                        return(string.Empty);
                    });

                    if (!hasMissingFrames)
                    {
                        return(newName);
                    }
                }
            }

            missingFrameName = missingFrame;
            return(null);
        }
示例#4
0
        private IEnumerable <T> RenameOrSuggest <T>(IEnumerable <string> filePaths)
            where T : RenameAction, new()
        {
            foreach (string filePath in filePaths)
            {
                if (string.IsNullOrWhiteSpace(filePath))
                {
                    yield return(new T {
                        Directory = filePath,
                        OriginalName = filePath,
                        Status = RenameStatus.Error,
                        ErrorMessage = Id3FileMessages.InvalidFilePath
                    });

                    continue;
                }

                if (!File.Exists(filePath))
                {
                    yield return(new T {
                        Directory = filePath,
                        OriginalName = filePath,
                        Status = RenameStatus.Error,
                        ErrorMessage = Id3FileMessages.MissingFile
                    });

                    continue;
                }

                var result = new T {
                    Directory    = Path.GetDirectoryName(filePath),
                    OriginalName = Path.GetFileName(filePath)
                };

                using (var mp3 = new Mp3File(filePath))
                {
                    Id3Tag tag = mp3.GetTag(2, 3);
                    if (tag == null)
                    {
                        result.Status       = RenameStatus.Error;
                        result.ErrorMessage = Id3FileMessages.MissingId3v23TagInFile;
                        yield return(result);

                        continue;
                    }

                    string missingFrameName = null;
                    string newName          = FramePlaceholderPattern.Replace(_pattern, match => {
                        string frameName           = match.Groups[1].Value;
                        string frameNameKey        = frameName.ToLowerInvariant();
                        PropertyInfo frameProperty = _mapping[frameNameKey];
                        var frame         = (Id3Frame)frameProperty.GetValue(tag, null);
                        string frameValue = frame.IsAssigned ? frame.ToString() : FireResolveMissingDataEvent(tag, frame, result.OriginalName);
                        if (string.IsNullOrEmpty(frameValue))
                        {
                            missingFrameName = frameName;
                        }
                        return(frameValue);
                    });

                    if (missingFrameName != null)
                    {
                        result.Status       = RenameStatus.Error;
                        result.ErrorMessage = string.Format(Id3FileMessages.MissingDataForFrame, missingFrameName);
                        yield return(result);

                        continue;
                    }

                    result.NewName = newName + ".mp3";
                    RenamingEventArgs renamingEventResult = FireRenamingEvent(tag, result.OriginalName, result.NewName);
                    if (renamingEventResult.Cancel)
                    {
                        result.Status = RenameStatus.Cancelled;
                    }
                    else
                    {
                        result.NewName = renamingEventResult.NewName;
                    }
                    if (result.OriginalName.Equals(result.NewName, StringComparison.Ordinal))
                    {
                        result.Status = RenameStatus.CorrectlyNamed;
                    }
                    yield return(result);
                }
            }
        }