public static IMediaFileInfo ParseMediaInfo(FileInfo file)
 {
     //Open the path for reading by the MediaInfo library
     MediaInfo mi = new MediaInfo();
     mi.Open(file.Path);
     if (file.SuperType.ToLower() == "video")
         return ParseVideo(mi);
     if (file.SuperType.ToLower() == "audio")
         return ParseAudio(mi);
     else
     {
         return null;
     }
 }
        //Will delegate actions on a file based on rules for that filetype
        private static void ProcessFileInfo(FileInfo file)
        {
            //Holds all rules that apply to the type, without consideration for conditions
            List<TypeAction> actions = Rules.Get(file.SuperType);

            //Placeholder noop in case no rules are defined
            TypeAction action = new TypeAction {Action = "ignore", Destination = "", FileType = file.SuperType};

            //Grab the first rule defined for any non-AV files, as conditions not implemented
            if (actions.Count > 0 && file.MediaInfo == null)
                action = actions[0];

            //Process the condition to find the matching rule
            else if (file.MediaInfo != null && actions.Count > 0)
            {
                action = GetActionWithMatchingCondition(file, actions, action);
            }

            try
            {

                string destination = GetDestination(file, action);
                //Use ToLower because:
                //1. Never trust a user
                //2. JSON deserialization doesn't take care of this during storage, nor any validation (could fix; haven't)
                switch (action?.Action.ToLower())
                {
                    case "delete":
                        FileManipulator.DeleteFile(file.Path);
                        break;
                    case "move":
                        FileManipulator.MoveFile(file.Path, destination);
                        break;
                    case "copy":
                        FileManipulator.CopyFile(file.Path, destination);
                        break;
                }
            }
                //Catch exceptions at this level so that when running in aggregate,
                //the whole thing isn't brought down by a single file
            catch (Exception e)
            {
                Debug.WriteLine($"Couldn't {action?.Action.ToLower()} {file.Path}");
                Debug.WriteLine(e);
            }
        }
 private static string GetDestination(FileInfo file, TypeAction action)
 {
     string destination;
     if (action.Condition != null && action.Condition.GroupByName)
     {
         if (action.Destination.EndsWith("/") || action.Destination.EndsWith("\\"))
             destination = action.Destination + file.ParsedGroupName + "/";
         else
         {
             destination = action.Destination + "/" + file.ParsedGroupName + "/";
         }
     }
     else
     {
         destination = action.Destination;
     }
     return destination;
 }
 private static TypeAction GetActionWithMatchingCondition(FileInfo file, List<TypeAction> actions, TypeAction action)
 {
     foreach (TypeAction typeAction in actions)
     {
         if (typeAction.Condition != null)
         {
             if (MediaComparer.Compare(file, typeAction.Condition))
             {
                 action = typeAction;
                 break;
             }
         }
         else
         {
             //Store an Action without a condition here if encountered in case no conditions match
             action = typeAction;
         }
     }
     return action;
 }
 public static bool Compare(FileInfo info, MediaCondition condition)
 {
     try
     {
         PropertyInfo property = GetPropertyInfo(info.MediaInfo, condition.Property.ToLower());
         if (property.Name.ToLower().Equals("duration"))
         {
             switch (condition.Comparator)
             {
                 case ">":
                     return (TimeSpan) property.GetValue(info.MediaInfo, null) > condition.Duration;
                 case "<":
                     return (TimeSpan) property.GetValue(info.MediaInfo, null) < condition.Duration;
                 case "=":
                     return (TimeSpan) property.GetValue(info.MediaInfo, null) == condition.Duration;
                 case "!=":
                     return (TimeSpan) property.GetValue(info.MediaInfo, null) != condition.Duration;
             }
         }
         else
         {
             switch (condition.Comparator)
             {
                 case ">":
                     return (int) property.GetValue(info.MediaInfo, null) > condition.Value;
                 case "<":
                     return (int) property.GetValue(info.MediaInfo, null) < condition.Value;
                 case "=":
                     return (int) property.GetValue(info.MediaInfo, null) == condition.Value;
                 case "!=":
                     return (int) property.GetValue(info.MediaInfo, null) != condition.Value;
             }
         }
     }
     catch (Exception ex)
     {
         Debug.WriteLine("Uh-oh. That comparison didn't work quite right\r\n"+ex);
     }
     return false;
 }