/
GoSFV.go
125 lines (106 loc) · 2.92 KB
/
GoSFV.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"bufio"
"fmt"
"hash/crc32"
"os"
"path/filepath"
"strings"
)
func decimalToHex(decimalChecksum uint32) string {
hexChecksum := fmt.Sprintf("%08x", decimalChecksum)
return hexChecksum
}
func calculateCRC32Checksum(filePath string) (string, error) {
data, err := os.ReadFile(filePath)
if err != nil {
fmt.Printf("Could not open file at %s. Error: %v\n", filePath, err)
return "", err
}
crcHash := crc32.ChecksumIEEE(data)
hexCrcHash := decimalToHex(crcHash)
return hexCrcHash, err
}
func findSFVFileInDirectory(dirPath string) (string, error) {
matches, err := filepath.Glob(filepath.Join(dirPath, "*.sfv"))
if len(matches) == 0 {
fmt.Printf("No .SFV file found at: %v\n", dirPath)
return "", err
}
return matches[0], err
}
func verifySFV(dirPath string) ([]string, error) {
const delimiter = " "
const outputFileName = "failedSFVs.txt"
var failedSFVs []string
var sfvFilePath string
var sfvFolder string
var err error
if strings.HasSuffix(dirPath, ".sfv") {
sfvFilePath = dirPath
sfvFolder = filepath.Dir(dirPath)
} else {
sfvFilePath, err = findSFVFileInDirectory(dirPath)
if err != nil {
return nil, err
}
sfvFolder = filepath.Dir(sfvFilePath)
}
file, err := os.Open(sfvFilePath)
if err != nil {
return nil, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
parts := strings.Split(line, delimiter)
fileName := parts[0]
expectedChecksum := strings.TrimSpace(parts[1])
fullFilePath := filepath.Join(sfvFolder, fileName)
calculatedChecksum, err := calculateCRC32Checksum(fullFilePath)
if err != nil {
fmt.Printf("Failed calculating checksum for %s. Error: %v", fileName, err)
continue
}
if strings.ToLower(expectedChecksum) == calculatedChecksum {
continue
} else {
fmt.Printf("Failed SFV: %v\n", fileName)
failedSFV := fileName + delimiter + calculatedChecksum
failedSFVs = append(failedSFVs, failedSFV)
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("Error reading SFV file: %v\n", err)
return failedSFVs, err
}
if len(failedSFVs) == 0 {
fmt.Print("All files successfully verified.")
return failedSFVs, nil
}
outputFilePath := filepath.Join(sfvFolder, outputFileName)
outputFile, err := os.Create(outputFilePath)
if err != nil {
fmt.Println("Error creating output file:", err)
return failedSFVs, err
}
defer outputFile.Close()
for _, verification := range failedSFVs {
_, err := fmt.Fprintln(outputFile, verification)
if err != nil {
fmt.Println("Error writing to output file:", err)
return failedSFVs, err
}
}
fmt.Println("Saved list of corrupt files to:", outputFilePath)
return failedSFVs, nil
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: GoSFV <path>")
return
}
filePath := os.Args[1]
verifySFV(filePath)
}