Beispiel #1
0
                public Issue Add(string message, Severity severity = Severity.Error, IssueTags tag = IssueTags.None,
                                 string prompt = null, Func <bool, string> repairer = null, bool isFinalRepairer = false)
                {
                    System.Diagnostics.Debug.Assert((prompt == null) == (repairer == null));

                    if (repairer != null)
                    {
                        // Force Warning as minimum for repairables.
                        if (severity < Severity.Warning)
                        {
                            severity = Severity.Warning;
                        }
                        ++Data.RepairableCount;
                    }

                    var issue = new Issue(this, message, severity, tag, prompt, repairer, isFinalRepairer);

                    Data.items.Add(issue);

                    Severity level = issue.Level;

                    if (Data.MaxSeverity < level)
                    {
                        Data.MaxSeverity = level;
                        Data.Severest    = issue;
                    }

                    Data.NotifyPropertyChanged(nameof(FixedMessage));
                    return(issue);
                }
Beispiel #2
0
 private Vector(IssueTags warnEscalator = IssueTags.None, IssueTags errEscalator = IssueTags.None)
 {
     this.items         = new ObservableCollection <Issue>();
     this.Items         = new ReadOnlyObservableCollection <Issue> (this.items);
     this.MaxSeverity   = Severity.NoIssue;
     this.WarnEscalator = warnEscalator;
     this.ErrEscalator  = errEscalator;
 }
Beispiel #3
0
 public Model(string root, string filter = null, string exclusion                 = null,
              Interaction action         = Interaction.None, Granularity scope    = Granularity.Summary,
              IssueTags warnEscalator    = IssueTags.None, IssueTags errEscalator = IssueTags.None)
     : this()
 {
     this._data         = new Diags(this);
     Data.Root          = root;
     Data.Filter        = filter;
     Data.Exclusion     = exclusion;
     Data.Response      = action;
     Data.Scope         = scope;
     Data.WarnEscalator = warnEscalator;
     Data.ErrEscalator  = errEscalator;
 }
Beispiel #4
0
                public void Escalate(IssueTags warnEscalator, IssueTags errEscalator)
                {
                    // Accumulate escalations.
                    Data.WarnEscalator |= warnEscalator;
                    Data.ErrEscalator  |= errEscalator;

                    foreach (var issue in Data.items)
                    {
                        Severity level = Data.GetLevel(issue.BaseLevel, issue.Tag);
                        if (Data.MaxSeverity < level)
                        {
                            Data.MaxSeverity = level;
                        }
                    }
                }
Beispiel #5
0
                public void Escalate(IssueTags warnEscalator, IssueTags errEscalator)
                {
                    // Accumulate escalations.
                    Data.WarnEscalator |= warnEscalator;
                    Data.ErrEscalator  |= errEscalator;

                    foreach (var issue in Data.items)
                    {
                        Severity level = issue.Level;
                        if (Data.MaxSeverity < level)
                        {
                            Data.MaxSeverity = level;
                            Data.Severest    = issue;
                        }
                    }
                }
Beispiel #6
0
            public Severity MaxLevelWhereAny(IssueTags tags)
            {
                var result = Severity.NoIssue;

                foreach (Issue issue in items)
                {
                    if ((issue.Tag & tags) != 0)
                    {
                        Severity level = GetLevel(issue.BaseLevel, issue.Tag);
                        if (result < level)
                        {
                            result = level;
                        }
                    }
                }
                return(result);
            }
Beispiel #7
0
 public Severity GetLevel(Severity baseLevel, IssueTags tags)
 {
     if (baseLevel < Severity.Warning)
     {
         if ((tags & ErrEscalator) != 0)
         {
             return(Severity.Error);
         }
         if ((tags & WarnEscalator) != 0)
         {
             return(Severity.Warning);
         }
     }
     else if (baseLevel == Severity.Warning && (tags & (ErrEscalator)) != 0)
     {
         return(Severity.Error);
     }
     return(baseLevel);
 }
Beispiel #8
0
            private void GetDiagnostics()
            {
                if (Data.Header.BitRate == null)
                {
                    IssueModel.Add("Invalid bit rate.");
                }

                if (Data.Header.ChannelMode != Mp3ChannelMode.JointStereo)
                {
                    IssueTags tags = Data.Header.ChannelMode == Mp3ChannelMode.Stereo? IssueTags.Overstandard : IssueTags.Substandard;
                    IssueModel.Add($"Channel mode is {Data.Header.ChannelMode}.", Severity.Advisory, tags);
                }

                if (Data.Header.SampleRate < 44100)
                {
                    IssueModel.Add($"Frequency is {Data.Header.SampleRate} Hz (expecting 44100 or better)", Severity.Advisory, IssueTags.Substandard);
                }
                else if (Data.Header.SampleRate > 44100)
                {
                    IssueModel.Add($"Frequency is {Data.Header.SampleRate}", Severity.Advisory, IssueTags.Overstandard);
                }

                if (Data.Xing != null)
                {
                    if (Data.Header.CrcProtectedBit == 0)
                    {
                        IssueModel.Add("Header not flagged for CRC protection.", Severity.Noise);
                    }

                    if (!Data.Xing.HasFrameCount)
                    {
                        IssueModel.Add("Missing XING frame count.");
                    }

                    if (!Data.Xing.HasSize)
                    {
                        IssueModel.Add("Missing XING file size.");
                    }

                    if (!Data.Xing.HasTableOfContents)
                    {
                        IssueModel.Add("Missing XING table of contents.");
                    }
                    else
                    if (Data.Xing.IsTocCorrupt())
                    {
                        IssueModel.Add("XING table of contents is corrupt.");
                    }

                    if (Data.Xing.HasQualityIndicator)
                    {
                        var qi = Data.Xing.QualityIndicator;
                        if (qi < 0 || qi > 100)
                        {
                            IssueModel.Add($"Quality indicator of {qi} is out of range.");
                        }
                        else
                        if (Data.Lame != null && Data.Lame.IsVbr && qi < 78)
                        {
                            IssueModel.Add($"VBR quality of {qi} is substandard.", Severity.Advisory, IssueTags.Substandard);
                        }
                    }
                }

                if (Data.Lame == null)
                {
                    IssueModel.Add("Not a LAME encoding.", Severity.Advisory, IssueTags.Substandard);
                }
                else
                {
                    var isBlessed = blessedLames.Any(item => item == Data.Lame.LameVersion);
                    if (!isBlessed)
                    {
                        IssueModel.Add("LAME version is not favored.", Severity.Advisory, IssueTags.Substandard);
                    }

                    if (Data.Lame.LameSize != Data.MediaCount)
                    {
                        IssueModel.Add("Indicated LAME audio size incorrect or unrecognized tag block.", Severity.Warning);
                    }

                    if (Data.Lame.TagRevision == 0xF)
                    {
                        IssueModel.Add($"Tag revision {Data.Lame.TagRevision} invalid.");
                    }

                    if (Data.Lame.BitrateMethod == 0 || Data.Lame.BitrateMethod == 0xF)
                    {
                        IssueModel.Add($"Bitrate method {Data.Lame.BitrateMethod} invalid.");
                    }

                    if (Data.Lame.IsAbr)
                    {
                        IssueModel.Add("ABR encoding method is obsolete.", Severity.Advisory, IssueTags.Substandard);
                    }

                    if (Data.Lame.AudiophileReplayGain != 0)
                    {
                        IssueModel.Add($"Audiophile ReplayGain ({Data.Lame.AudiophileReplayGain}) usage is obsolete.", Severity.Advisory, IssueTags.Substandard);
                    }

                    if (Data.Lame.IsCbr && Mp3Header.IsBadCbr(Data.Header.MpegVersionBits, Data.Lame.MinBitRate))
                    {
                        IssueModel.Add($"Minimum bit rate of {Data.Lame.MinBitRate} not valid.", Severity.Advisory, IssueTags.Substandard);
                    }
                }

                if (Data.HasId3v1)
                {
                    if (Data.HasId3v1Phantom)
                    {
                        IssueModel.Add("Has phantom ID3v1 tag block.",
                                       Severity.Warning, IssueTags.Fussy | IssueTags.HasId3v1,
                                       "Remove phantom ID3v1 tag block", RepairPhantomTag);
                    }
                    else
                    {
                        var      minor = GetMinorOfV1(Data.id3v1Block);
                        Severity sev   = minor == 0? Severity.Warning : Severity.Noise;
                        IssueModel.Add($"Has ID3v1.{minor} tags.", sev, IssueTags.HasId3v1);
                    }
                }

                if (!Data.HasId3v2)
                {
                    IssueModel.Add("Missing ID3v2 tags.", Severity.Trivia, IssueTags.Fussy | IssueTags.Substandard);
                }
                else
                {
                    switch (Data.Id3v2Major)
                    {
                    case 2:
                        IssueModel.Add("Has obsolete ID3v2.2 tags.", Severity.Warning, IssueTags.Fussy | IssueTags.Substandard);
                        break;

                    case 3:
                        // Hunky dory!
                        break;

                    case 4:
                        IssueModel.Add("Has jumped-the-shark ID3v2.4 tags.", Severity.Trivia);
                        break;

                    default:
                        IssueModel.Add("Has ID3 tags of unknown version 2." + Data.Id3v2Major);
                        break;
                    }

                    if (Data.Id3v2TagRepair != null)
                    {
                        IssueModel.Add($"ID3v2 tag size over by 1 (repair with {Data.Id3v2TagRepair}).",
                                       Severity.Warning, IssueTags.Fussy,
                                       "Patch EAC induced ID3v2 tag size error", RepairId3v2OffBy1);
                    }
                }

                if (Data.HasApe)
                {
                    IssueModel.Add("Has APE tags.", Severity.Trivia, IssueTags.HasApe);
                }

                if (Data.HasLyrics3)
                {
                    IssueModel.Add("Has obsolete Lyrics3v2 block.", Severity.Advisory);
                }

                if (Data.DeadBytes != 0)
                {
                    IssueModel.Add($"Dead space preceeds audio, size={Data.DeadBytes}", Severity.Warning, IssueTags.Substandard);
                }
            }
Beispiel #9
0
            private void ValidateMp3s(Hashes fileHash)
            {
                Bind.mp3Models = new List <Mp3Format.Model>();
                int id3v1Count = 0, id3v23Count = 0, id3v24Count = 0;

                foreach (FileInfo mp3Info in Bind.mp3Infos)
                {
                    Owner.SetCurrentFile(mp3Info.Name, Granularity.Verbose);
                    using (var ffs = new FileStream(mp3Info.FullName, FileMode.Open, FileAccess.Read))
                    {
                        var             buf      = new byte[0x2C];
                        int             got      = ffs.Read(buf, 0, buf.Length);
                        Mp3Format.Model mp3Model = Mp3Format.CreateModel(ffs, buf, mp3Info.FullName);
                        if (mp3Model == null)
                        {
                            Bind.MaxTrackSeverity = Severity.Error;
                            Owner.ReportLine("Doesn't seem to be a MP3.", Severity.Error, Bind.Signature != null);
                        }
                        else
                        {
                            Mp3Format mp3 = mp3Model.Data;
                            mp3Model.CalcHashes(Hashes.Intrinsic | Owner.Data.HashFlags | fileHash, Owner.Data.ValidationFlags);
                            if (mp3.IsBadHeader)
                            {
                                ++Owner.Data.Mp3Format.TotalHeaderErrors;
                            }
                            if (mp3.IsBadData)
                            {
                                ++Owner.Data.Mp3Format.TotalDataErrors;
                            }

                            if (mp3.Lame != null)
                            {
                                if (Bind.RipProfile == null)
                                {
                                    Bind.RipProfile = mp3.Lame.Profile;
                                }
                                else if (Bind.RipProfile != mp3.Lame.Profile)
                                {
                                    mp3Model.IssueModel.Add($"Profile {mp3.Lame.Profile} inconsistent with rip profile of {Bind.RipProfile}.");
                                }
                            }

                            if (mp3.HasId3v1)
                            {
                                ++id3v1Count;
                            }
                            if (mp3.HasId3v2)
                            {
                                if (mp3.Id3v2Major == 3)
                                {
                                    ++id3v23Count;
                                }
                                else if (mp3.Id3v2Major == 4)
                                {
                                    ++id3v24Count;
                                }
                            }

                            IssueTags tags = Owner.Data.IsFussy? IssueTags.Fussy : IssueTags.None;
                            mp3Model.IssueModel.Escalate(IssueTags.HasApe, tags | IssueTags.Substandard | IssueTags.Overstandard);

                            if (Bind.MaxTrackSeverity < mp3.Issues.MaxSeverity)
                            {
                                Bind.MaxTrackSeverity = mp3.Issues.MaxSeverity;
                            }

                            Bind.mp3Models.Add(mp3Model);
                            Owner.ReportFormat(mp3, Bind.Signature != null);
                        }

                        ++Owner.Data.Mp3Format.TrueTotal;
                        ++Owner.Data.TotalFiles;

                        if (mp3Model != null)
                        {
                            mp3Model.ClearFile();
                        }
                        if (Bind.MaxTrackSeverity >= Severity.Fatal)
                        {
                            return;
                        }
                    }
                }

                if (new string[] { "V2", "V0", "C320" }.Any(x => x == Bind.RipProfile))
                {
                    LogModel.IssueModel.Add($"All tracks profile {Bind.RipProfile}.", Severity.Noise);
                }
                else
                {
                    LogModel.IssueModel.Add($"Profile {Bind.RipProfile} is substandard.", Severity.Error, IssueTags.Substandard);
                }

                if (id3v1Count > 0 && id3v1Count != Bind.mp3Infos.Length)
                {
                    LogModel.IssueModel.Add("Tracks have incomplete ID3v1 tagging.");
                }

                if (id3v23Count > 0 && id3v24Count > 0)
                {
                    LogModel.IssueModel.Add("Tracks inconsistently tagged both ID3v2.3 and ID3v2.4.");
                }
            }
Beispiel #10
0
            private void ValidateDirectory()
            {
                Owner.SetCurrentDirectory(Bind.DirPath);
                try
                {
                    Bind.logInfos  = Bind.Dir.GetFiles("*.log").Where(lf => lf.Name.EndsWith(".log")).ToArray();
                    Bind.mp3Infos  = Bind.Dir.GetFiles("*.mp3").Where(lf => lf.Name.EndsWith(".mp3")).ToArray();
                    Bind.digInfos  = Bind.Dir.GetFiles("*.sha1x");
                    Bind.m3uInfos  = Bind.Dir.GetFiles("*.m3u").Where(lf => lf.Name.EndsWith(".m3u")).ToArray();
                    Bind.m3u8Infos = Bind.Dir.GetFiles("*.m3u8");
                    if (!String.IsNullOrEmpty(Owner.Data.Bypass))
                    {
                        Bind.bypassInfos = Bind.Dir.GetFiles("*" + Owner.Data.Bypass);
                    }
                }
                catch (IOException ex)
                {
                    Owner.ReportLine(ex.Message.Trim(null), Severity.Fatal);
                    Bind.Status = Severity.Fatal;
                    return;
                }

                if (Bind.bypassInfos != null && Bind.bypassInfos.Length > 0)
                {
                    Owner.ReportLine($"Ignoring directory containing file ending with '{Owner.Data.Bypass}'.", Severity.Advisory);
                    return;
                }

                if (Bind.logInfos.Length == 0)
                {
                    if (Bind.mp3Infos.Length > 0)
                    {
                        ++Owner.Data.Mp3Format.TrueTotal;
                        ++Owner.Data.TotalFiles;
                        ++Owner.Data.TotalErrors;
                        ++Owner.Data.LogFormat.TotalMissing;
                        Owner.ReportLine("Found .mp3 file(s) without a .log file in same directory.", Severity.Error, Bind.Signature != null);
                        Bind.Status = Severity.Error;
                    }

                    return;
                }

                if (Bind.logInfos.Length > 1)
                {
                    Owner.Data.LogFormat.TrueTotal += Bind.logInfos.Length;
                    Owner.Data.TotalFiles          += Bind.logInfos.Length;
                    Owner.Data.TotalErrors         += Bind.logInfos.Length - 1;
                    Owner.ReportLine("Directory has more than 1 .log file.", Severity.Error, Bind.Signature != null);
                    Bind.Status = Severity.Error;
                    return;
                }

                if (Bind.mp3Infos.Length == 0)
                {
                    ++Owner.Data.LogFormat.TrueTotal;
                    ++Owner.Data.TotalFiles;
                    ++Owner.Data.TotalErrors;
                    ++Owner.Data.Mp3Format.TotalMissing;
                    Owner.ReportLine("Directory has .log file yet has no .mp3 files.", Severity.Error, Bind.Signature != null);
                    Bind.Status = Severity.Error;
                    return;
                }

                Array.Sort(Bind.mp3Infos, (f1, f2) => f1.Name.CompareTo(f2.Name));
                Owner.Data.ExpectedFiles = 1 + Bind.mp3Infos.Length;
                Bind.LogName             = Bind.logInfos[0].Name;

                if (Bind.digInfos.Length == 0)
                {
                    Bind.WorkName = Path.GetFileNameWithoutExtension(Bind.LogName);
                    if (Bind.LogTagEnabled)
                    {
                        if (Bind.WorkName.EndsWith("." + Bind.RipProfile))
                        {
                            Bind.WorkName = Bind.WorkName.Substring(0, Bind.WorkName.Length - 1 - Bind.RipProfile.Length);
                        }
                        Bind.DigName = Bind.WorkName + "." + Bind.RipProfile;
                    }
                    Bind.DigName = ".LAME." + Bind.Signature + ".sha1x";
                    Bind.DigPath = Bind.DirPath + Bind.DigName;
                }
                else
                {
                    ++Owner.Data.ExpectedFiles;
                    var digRE = new Regex(@"(.+)\.LAME\.(.+)\.sha1x");
                    Bind.DigName = Bind.digInfos[0].Name;
                    Bind.DigPath = Bind.digInfos[0].FullName;
                    Owner.SetCurrentFile(Bind.DigName);

                    MatchCollection digMat = digRE.Matches(Bind.DigName);
                    if (digMat.Count != 1)
                    {
                        Bind.WorkName = Path.GetFileNameWithoutExtension(Bind.LogName);
                    }
                    else
                    {
                        Match m1 = digMat[0];
                        if (m1.Groups.Count != 3)
                        {
                            ++Owner.Data.LogFormat.TrueTotal;
                            ++Owner.Data.TotalFiles;
                            Owner.ReportLine("Too confused by digest name, bailing out.", Severity.Error, Bind.Signature != null);
                            Bind.Status = Severity.Error;
                            return;
                        }
                        else
                        {
                            Bind.WorkName = m1.Groups[1].ToString();
                            Bind.Ripper   = m1.Groups[2].ToString();
                        }
                    }
                }

                using (var logfs = new FileStream(Bind.logInfos[0].FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var hdr = new byte[0x26];
                    int got = logfs.Read(hdr, 0, hdr.Length);
                    LogModel = LogEacFormat.CreateModel(logfs, hdr, Bind.logInfos[0].FullName);
                }

                if (LogModel == null)
                {
                    ++Owner.Data.LogFormat.TrueTotal;
                    ++Owner.Data.TotalFiles;
                    Owner.ReportLine("Invalid EAC log file or unknown layout.", Severity.Error, Bind.Signature != null);
                    Bind.Status = Severity.Error;
                    return;
                }

                LogModel.ClearFile();
                Bind.Log = LogModel.Data;

                if (Bind.Ripper == null && (Owner.Data.HashFlags & Hashes.WebCheck) != 0)
                {
                    LogModel.CalcHashWebCheck();
                }

                if (Bind.mp3Infos.Length != Bind.Log.Tracks.Items.Count)
                {
                    var sb = new StringBuilder("Directory has ");
                    sb.Append(Bind.mp3Infos.Length);
                    sb.Append(" MP3");
                    if (Bind.mp3Infos.Length != 1)
                    {
                        sb.Append("s");
                    }
                    sb.Append(", EAC log has ");
                    sb.Append(Bind.Log.Tracks.Items.Count);
                    sb.Append(" track");
                    sb.Append(Bind.Log.Tracks.Items.Count == 1? "." : "s.");
                    LogModel.TkIssue = LogModel.IssueModel.Add(sb.ToString(), Severity.Error, IssueTags.Failure);
                }

                IssueTags errEscalator = Owner.Data.ErrEscalator;

                if (Owner.Data.WillProve && Bind.Ripper == null)
                {
                    errEscalator |= IssueTags.MissingHash;
                }
                LogModel.IssueModel.Escalate(Owner.Data.WarnEscalator, errEscalator);
            }
        private int ParseArgs(string[] Args)
        {
            if (args.Length == 0 || args[0] == "/?" || args[0] == "/help" || args[0] == "-help")
            {
                ShowUsage();
                return(1);
            }

            for (int an = 0; an < args.Length - 1; ++an)
            {
                bool argOk = false;

                if (args[an] == @"/R")
                {
                    action = Interaction.PromptToRepair;
                    argOk  = true;
                }
                else if (args[an].StartsWith("/f:"))
                {
                    filter = args[an].Substring(3);
                    argOk  = true;
                }
                else if (args[an].StartsWith("/g:"))
                {
                    var arg = Granularity.Summary;
                    argOk = Enum.TryParse <Granularity> (args[an].Substring(3), true, out arg);
                    argOk = argOk && Enum.IsDefined(typeof(Granularity), arg);
                    if (argOk)
                    {
                        scope = arg;
                    }
                }
                else if (args[an].StartsWith("/h:"))
                {
                    argOk = Enum.TryParse <Hashes> (args[an].Substring(3), true, out Hashes arg);
                    argOk = argOk && arg == (arg & (Hashes.WebCheck - 1));
                    if (argOk)
                    {
                        hashes = arg;
                    }
                }
                else if (args[an].StartsWith("/out:"))
                {
                    mirrorName = args[an].Substring(5).Trim(null);
                    argOk      = mirrorName.Length > 0;
                }
                else if (args[an].StartsWith("/v:"))
                {
                    var arg = Validations.None;
                    argOk = Enum.TryParse <Validations> (args[an].Substring(3), true, out arg);
                    if (argOk)
                    {
                        validations = arg;
                    }
                }
                else if (args[an].StartsWith("/w:"))
                {
                    var arg = IssueTags.None;
                    argOk = Enum.TryParse <IssueTags> (args[an].Substring(3), true, out arg);
                    if (argOk)
                    {
                        warnEscalator = arg;
                    }
                }
                else if (args[an].StartsWith("/e:"))
                {
                    var arg = IssueTags.None;
                    argOk = Enum.TryParse <IssueTags> (args[an].Substring(3), true, out arg);
                    if (argOk)
                    {
                        errEscalator = arg;
                    }
                }
                else if (args[an].StartsWith("/p:"))
                {
                    argOk = int.TryParse(args[an].Substring(3), out int arg);
                    if (argOk)
                    {
                        notifyEvery = arg;
                    }
                }
                else if (args[an].StartsWith("/x:"))
                {
                    var arg = args[an].Substring(3);
                    argOk = !String.IsNullOrWhiteSpace(arg);
                    if (argOk)
                    {
                        exclusion = arg;
                    }
                }
                else if (args[an] == "/k")
                {
                    waitForKeyPress = true;
                    argOk           = true;
                }

                if (!argOk)
                {
                    Console.Error.WriteLine("Invalid argument: " + args[an]);
                    return(1);
                }
            }

            return(0);
        }
Beispiel #12
0
                public Issue Add(string message, Severity baseLevel = Severity.Error, IssueTags tags = IssueTags.None,
                                 string prompt = null, Func <bool, string> repairer = null, bool isFinalRepairer = false)
                {
                    System.Diagnostics.Debug.Assert((prompt == null) == (repairer == null));

                    if (repairer != null)
                    {
                        // Force Warning as minimum for repairables.
                        if (baseLevel < Severity.Warning)
                        {
                            baseLevel = Severity.Warning;
                        }
                        ++Data.RepairableCount;
                    }

                    var issue = new Issue(Data, message, baseLevel, tags, prompt, repairer, isFinalRepairer);

                    Data.items.Add(issue);

                    Severity level = Data.GetLevel(issue.BaseLevel, issue.Tag);

                    if (Data.MaxSeverity < level)
                    {
                        Data.MaxSeverity = level;
                    }

                    Data.RaisePropertyChanged(nameof(LongMessage));
                    return(issue);
                }
Beispiel #13
0
 public Model(IssueTags warnEscalator = IssueTags.None, IssueTags errEscalator = IssueTags.None)
 => Data = new Issue.Vector(warnEscalator, errEscalator);
Beispiel #14
0
 private Issue(Vector owner, string message, Severity level = Severity.Advisory, IssueTags tag = IssueTags.None,
               string prompt = null, Func <bool, string> repairer = null, bool isFinalRepairer = false)
 {
     this.vector          = owner;
     this.Index           = owner.Items.Count;
     this.Message         = message;
     this.BaseLevel       = level;
     this.Tag             = tag;
     this.RepairPrompt    = prompt;
     this.Repairer        = repairer;
     this.IsFinalRepairer = isFinalRepairer;
 }
Beispiel #15
0
        private Issue(Vector.Model owner, string message, Severity level = Severity.Advisory, IssueTags tag = IssueTags.None,
                      string prompt = null, Func <bool, string> repairer = null, bool isFinalRepairer = false)
        {
            this.owner           = owner;
            this.Index           = owner.Data.Items.Count;
            this.Message         = message;
            this.BaseLevel       = level;
            this.Tag             = tag;
            this.RepairPrompt    = prompt;
            this.Repairer        = repairer;
            this.IsFinalRepairer = isFinalRepairer;
#if MVVM
            DoRepair = repairer == null ? null : new RelayCommand(() => owner.Repair(Index));
#endif
        }
Beispiel #16
0
            protected override void GetDiagnostics()
            {
                base.GetDiagnostics();

                string OkErr = TracksModel.GetOkDiagnostics();

                if (OkErr != null)
                {
                    Data.OkIssue = IssueModel.Add(OkErr, Severity.Error, IssueTags.Failure);
                }

                string QualErr = TracksModel.GetQualDiagnostics();

                if (QualErr != null)
                {
                    Data.QiIssue = IssueModel.Add(QualErr, Severity.Error, IssueTags.Failure);
                }

                if (String.IsNullOrEmpty(Data.RipArtist))
                {
                    IssueModel.Add("Missing artist", Severity.Warning, IssueTags.Substandard);
                }

                if (String.IsNullOrEmpty(Data.RipAlbum))
                {
                    IssueModel.Add("Missing album", Severity.Warning, IssueTags.Substandard);
                }

                if (String.IsNullOrEmpty(Data.Drive))
                {
                    IssueModel.Add("Missing 'Used drive'.");
                }

                if (String.IsNullOrEmpty(Data.ReadMode))
                {
                    IssueModel.Add("Missing 'Read mode'.");
                }
                else if (Data.ReadMode != "Secure with NO C2, accurate stream, disable cache" &&
                         Data.ReadMode != "Secure with NO C2, accurate stream,  disable cache")
                {
                    if (Data.ReadMode != "Secure")
                    {
                        Data.DsIssue = IssueModel.Add("Nonpreferred drive setting: Read mode: " + Data.ReadMode, Severity.Warning, IssueTags.Substandard);
                    }

                    if (Data.AccurateStream == null || Data.AccurateStream != "Yes")
                    {
                        Data.DsIssue = IssueModel.Add("Missing drive setting: 'Utilize accurate stream: Yes'." + Data.AccurateStream, Severity.Warning, IssueTags.StrictErr);
                    }

                    if (Data.DefeatCache == null || Data.DefeatCache != "Yes")
                    {
                        Data.DsIssue = IssueModel.Add("Missing drive setting: 'Defeat audio cache: Yes'.", Severity.Warning, IssueTags.StrictErr);
                    }

                    if (Data.UseC2 == null || Data.UseC2 != "No")
                    {
                        Data.DsIssue = IssueModel.Add("Missing drive setting: 'Make use of C2 pointers: No'.", Severity.Warning, IssueTags.Substandard);
                    }
                }

                if (String.IsNullOrEmpty(Data.ReadOffset))
                {
                    IssueModel.Add("Missing 'Read offset correction'.", Severity.Trivia, IssueTags.StrictWarn);
                }

                if (Data.FillWithSilence != null && Data.FillWithSilence != "Yes")
                {
                    IssueModel.Add("Missing 'Fill up missing offset samples with silence: Yes'.", Severity.Trivia, IssueTags.StrictWarn);
                }

                if (Data.Quality != null && Data.Quality != "High")
                {
                    IssueModel.Add("Missing 'Quality: High'.", Severity.Advisory, IssueTags.Substandard);
                }

                if (Data.TrimSilence == null || Data.TrimSilence != "No")
                {
                    Data.TsIssue = IssueModel.Add("Missing 'Delete leading and trailing silent blocks: No'.", Severity.Warning, IssueTags.StrictErr);
                }

                if (Data.CalcWithNulls != null && Data.CalcWithNulls != "Yes")
                {
                    IssueModel.Add("Missing 'Null samples used in CRC calculations: Yes'.");
                }

                if (Data.GapHandling != null)
                {
                    if (Data.GapHandling != "Appended to previous track")
                    {
                        IssueTags gapTag = IssueTags.StrictErr;
                        if (Data.GapHandling != "Not detected, thus appended to previous track")
                        {
                            gapTag |= IssueTags.StrictErr;
                        }

                        Data.GpIssue = IssueModel.Add("Gap handling preferred setting is 'Appended to previous track'.", Severity.Advisory, gapTag);
                    }
                }

                if (Data.Id3Tag == "Yes")
                {
                    IssueModel.Add("Append ID3 tags preferred setting is 'No'.", Severity.NoIssue, IssueTags.StrictErr);
                }

                if (Data.ReadOffset == "0" && Data.Drive.Contains("not found in database"))
                {
                    IssueModel.Add("Unknown drive with offset '0'.", Severity.Advisory, IssueTags.StrictErr);
                }

                if (Data.NormalizeTo != null)
                {
                    Data.NzIssue = IssueModel.Add("Use of normalization considered harmful.", Severity.Warning, IssueTags.StrictErr);
                }

                if (Data.SampleFormat != null && Data.SampleFormat != "44.100 Hz; 16 Bit; Stereo")
                {
                    IssueModel.Add("Missing 'Sample format: 44.100 Hz; 16 Bit; Stereo'.", Severity.Warning, IssueTags.Substandard);
                }

                if (Data.IsRangeRip)
                {
                    IssueModel.Add("Range rip detected.", Severity.Advisory, IssueTags.StrictWarn);
                }
                else
                {
                    if (Data.TocTrackCount != null)
                    {
                        int diff = Data.TocTrackCount.Value - Data.Tracks.Items.Count;
                        if (diff != 0)
                        {
                            Severity sev = diff == 1? Severity.Advisory : Severity.Error;
                            IssueModel.Add("Found " + Data.Tracks.Items.Count + " of " + Data.TocTrackCount.Value + " tracks.", sev);
                        }
                    }
                }

                var arTag = IssueTags.None;
                var arSev = Severity.Trivia;

                if (Data.AccurateRipConfidence != null)
                {
                    if (Data.AccurateRipConfidence.Value > 0)
                    {
                        arTag = IssueTags.Success;
                    }
                    else
                    {
                        arSev = Severity.Advisory;
                        if (Data.AccurateRipConfidence.Value < 0)
                        {
                            arTag = IssueTags.Failure;
                        }
                    }
                }
                Data.ArIssue = IssueModel.Add($"AccurateRip verification {Data.AccurateRipText}.", arSev, arTag);

                var ctSev = Severity.Trivia;
                var ctTag = IssueTags.None;

                if (Data.CueToolsConfidence == null)
                {
                    ctTag = IssueTags.StrictErr;
                }
                else if (Data.CueToolsConfidence.Value < 0)
                {
                    ctSev = Severity.Error;
                }
                else if (Data.CueToolsConfidence.Value == 0)
                {
                    ctSev = Severity.Advisory;
                }
                else
                {
                    ctTag = IssueTags.Success;
                }

                Data.CtIssue = IssueModel.Add($"CUETools DB verification {Data.CueToolsText}.", ctSev, ctTag);
            }