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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// This is designed to be a rather simplistic library to help pull information
// from a local steam library
package steam
import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
type Library struct {
Folder string
Games map[string]Game
}
type Game struct {
Name string
LibraryPath string
Size int64
}
func (g Game) Slug() string {
return strings.ReplaceAll(g.Name, " ", "-")
}
func ProcessMultipleLibraries(r []string) ([]*Library, error) {
var libs []*Library
for _, i := range r {
lib := &Library{}
err := lib.ProcessLibrary(i)
if err != nil {
return nil, err
}
libs = append(libs, lib)
}
return libs, nil
}
func NewLibrary(path string) (*Library, error) {
l := &Library{}
err := l.ProcessLibrary(path)
if err != nil {
return nil, err
}
return l, err
}
func NewLibraryMust(path string) *Library {
l, err := NewLibrary(path)
if err != nil {
panic(err)
}
return l
}
// Populate the "Folder" and "Games" fields based on the provided directory
func (s *Library) ProcessLibrary(r string) error {
if !hasCommon(r) {
return errors.New(fmt.Sprintf("No common directory in: %s", r))
}
s.Games = make(map[string]Game)
dirs, err := ioutil.ReadDir(r + "/common")
if err != nil {
return err
}
s.Folder = r
for _, f := range dirs {
if f.IsDir() {
g := &Game{
Name: f.Name(),
LibraryPath: r,
}
g.setSizeInfo()
s.Games[f.Name()] = *g
}
}
return nil
}
// Find the ACF files related to this video game
func FindACF(libraryPath, game string) (string, error) {
if err := os.Chdir(libraryPath); err != nil {
return "", err
}
files, err := filepath.Glob("*.acf")
if err != nil {
return "", err
}
for _, fn := range files {
info, err := os.Lstat(fn)
if err != nil {
return "", err
}
// We don't want it if it's a directory
if info.IsDir() {
continue
}
// Open up the file
f, err := os.Open(fn)
defer f.Close()
if err != nil {
return "", err
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
// Finally check and see if the file has the video game name
if strings.Contains(scanner.Text(), game) {
return fn, nil
// fmt.Printf("%s/%s:%d: %s\n", root, path, i, scanner.Text())
}
}
}
str := "Couldn't find ACF file related to Game: %s"
return "", errors.New(fmt.Sprintf(str, game))
}
// This is automatically called to print out the contents of the struct
// when things like fmt.Println are used
func (s *Library) String() (str string) {
str = fmt.Sprintf("Library: %s\n", s.Folder)
str = str + "----\n"
for _, v := range s.Games {
str = str + fmt.Sprintf("%s\n", v.Name)
}
return
}
func hasCommon(d string) bool {
dirs, err := ioutil.ReadDir(d)
if err != nil {
return false
}
for _, f := range dirs {
if f.Name() == "common" && f.IsDir() {
return true
}
}
return false
}
|