Skip to content

Nirzak/logchecker-go

Repository files navigation

Logchecker (Go Edition)

A CD rip logchecker, used for analyzing the generated logs for any problems that would potentially indicate a non-perfect rip was produced. Of course, just because a log doesn't score a perfect 100% does not mean that the produced rip isn't bit perfect, it's just less likely.

This project is a pure Go rewrite of the original PHP Logchecker.

Unlike the original PHP version which required external Python scripts to validate EAC and XLD checksums, this Go version has all checksum verification built-in via native Go libraries (github.com/Nirzak/eac-logchecker and github.com/Nirzak/xld-logchecker).

Go Report Card Go Reference

Requirements

  • Go 1.25.0+ (Only for build and development. No runtime required for prebuilt binaries)

Standalone CLI

Installation

Download from github releases : https://github.com/Nirzak/logchecker-go/releases

Install via go install:

go install github.com/Nirzak/logchecker-go/cmd/logchecker@latest

Alternatively, you can build it from source:

git clone https://github.com/Nirzak/logchecker-go.git
cd logchecker-go
go build -o logchecker cmd/logchecker/main.go

Usage

$ logchecker version
Logchecker 1.14.4

Usage:
  logchecker analyze  [--html] [--no_text] [--ids] <file> [out_file] [details_json]
  logchecker analyse  (alias of analyze)
  logchecker decode   <file>
  logchecker translate [-l lang] <file>
  logchecker version

Main usage is through the analyze command, e.g.:

$ logchecker analyze path/to/file.log
Ripper  : EAC
Version : 1.0 beta 3
Language: en
Score   : 59
Checksum: checksum_ok
Details :
    Could not verify gap handling (-10 points)
    Could not verify id3 tag setting (-1 point)
    Range rip detected (-30 points)

Disc IDs (--ids)

analyze --ids prints the disc identifiers (AccurateRip, MusicBrainz, CTDB, FreeDB/CDDB) with their lookup URLs, then exits without dumping the log text. The AccurateRip ID is taken from the log when embedded (dBpoweramp); the rest are computed from the parsed TOC. Lines are omitted when the log has no TOC.

For FreeDB/CDDB, the tool additionally queries the gnudb database online to resolve the disc to an authoritative entry (the calculated CDDB ID and the database's stored ID can differ in the track-count byte). On a match the gnudb ID is used for the URL; if the lookup fails — no internet, timeout, or no match — it falls back to the calculated ID. The fallback is automatic; the command never blocks beyond a 15-second network timeout and always prints a usable URL.

$ logchecker analyze --ids path/to/file.log
Ripper  : EAC
AccurateRip : 011-00164217-00beabe7-9d0bf70b
  AR URL    : http://www.accuraterip.com/accuraterip/7/1/2/dBAR-011-00164217-00beabe7-9d0bf70b.bin
MusicBrainz : lXlcau748FItWbittqBtRd3VYPU-
  MB URL    : https://musicbrainz.org/cdtoc/attach?toc=...&tracks=11&id=...
CTDB        : ReQ9rI.mtYl1ofdDtzJxoEbiZUU-
  CTDB URL  : https://db.cuetools.net/ui/?tocid=ReQ9rI.mtYl1ofdDtzJxoEbiZUU-
FreeDB/CDDB : 9d0bf70b
  gnudb     : matched 9d0bf789 — Various Artists / Aashiqui 2
  FreeDB URL: https://gnudb.org/cd/9d0bf789

When offline or unmatched the last two lines instead read:

  gnudb     : no match; using calculated ID
  FreeDB URL: https://gnudb.org/cd/9d0bf70b

Library Usage

Installation

go get github.com/Nirzak/logchecker-go

Usage

package main

import (
    "fmt"
    "github.com/Nirzak/logchecker-go/logchecker"
)

func main() {
    lc := logchecker.New()
    
    // Load and parse the file
    err := lc.NewFile("/path/to/log/file.log")
    if err != nil {
        panic(err)
    }
    lc.Parse()
    
    // Output results
    fmt.Printf("Ripper   : %s\n", lc.GetRipper())
    fmt.Printf("Version  : %s\n", lc.GetRipperVersion())
    fmt.Printf("Score    : %d\n", lc.GetScore())
    fmt.Printf("Checksum : %s\n", lc.GetChecksumState())
    fmt.Printf("\nDetails:\n")
    for _, detail := range lc.GetDetails() {
        fmt.Printf("  %s\n", detail)
    }
}

Public API Reference

lc.Parse()              // Run analysis

lc.GetRipper()          // string: "EAC" | "XLD" | "whipper" | "dBpoweramp" | "unknown"
lc.GetRipperVersion()   // string
lc.GetScore()           // int 0–100
lc.GetChecksumState()   // "checksum_ok" | "checksum_invalid" | "checksum_missing"
lc.GetDetails()         // []string — human-readable list of deductions / notices
lc.GetLanguage()        // string language code, e.g. "en", "ru"
lc.GetLog()             // string — HTML-annotated log text (span-tagged)
lc.IsCombinedLog()      // bool — true when the file holds multiple rip sessions

// Disc identifiers
lc.GetTOC()             // *toc.TOC — parsed Table of Contents, or nil if absent
lc.GetAccurateRipID()   // string — AccurateRip ID (embedded if present, else computed)

// Control
lc.ValidateChecksum(false) // Disable external checksum validation

The value returned by GetTOC() exposes the disc-ID computations (all pure, no network I/O):

t := lc.GetTOC()
if t != nil {
    t.MusicBrainzDiscID()   // string
    t.MusicBrainzLookupURL()
    t.FreeDBDiscID()        // string (8-char hex CDDB ID)
    t.FreeDBLookupURL()
    t.CTDBDiscID()          // string (CUETools Database TOC ID)
    t.CTDBLookupURL()
    t.AccurateRipID()       // string "NNN-ID1-ID2-CDDB"
    t.AccurateRipURL()      // string — AccurateRip .bin lookup URL
}

AccurateRip database verification (accuraterip)

The core logchecker library performs no network I/O. To verify a disc against the AccurateRip database, use the separate accuraterip package, passing the TOC from GetTOC():

import "github.com/Nirzak/logchecker-go/accuraterip"

res, err := accuraterip.Lookup(lc.GetTOC())   // or LookupWithContext(ctx, toc)
if err != nil {
    // network / parse error
}
switch res.Status {
case accuraterip.StatusFound:    // res.Pressings holds per-track Confidence/CRCv1/CRCv2
case accuraterip.StatusNotFound: // disc absent from the database
case accuraterip.StatusError:
}

gnudb disc-ID resolution (gnudb)

The locally-computed FreeDB/CDDB ID and gnudb's stored ID can differ in the track-count byte. The gnudb package resolves a TOC to gnudb's authoritative entry over its CDDB CGI protocol, falling back to the calculated ID on any failure (no internet, timeout, or no match). Like accuraterip, it performs network I/O and is kept out of the pure core — call it explicitly:

import "github.com/Nirzak/logchecker-go/gnudb"

res, err := gnudb.Resolve(lc.GetTOC())   // or ResolveWithContext(ctx, toc)
if err != nil {
    // offline / timeout / http error — res still holds the calculated fallback
}
res.DiscID  // gnudb ID if matched, else the calculated CDDB ID
res.URL     // https://gnudb.org/cd/<DiscID>
res.Matched // true if gnudb returned an entry
res.Title   // "Artist / Album" from the match, if any

Resolve never blocks beyond a 15-second timeout, and res is always usable even on error. The CLI's --ids flag uses this internally.

For the pure, offline calculated URL (no network), use GetTOC().FreeDBLookupURL().

Testing

To run the test suite:

go test -v ./...

About

Orpheus's PHP based gazelle logchecker re-implemented in golang with additional functionalities. Currently supported log formats: EAC, XLD, dBpoweramp & Whipper

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages