-
Notifications
You must be signed in to change notification settings - Fork 95
/
main.go
133 lines (121 loc) · 4.13 KB
/
main.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
126
127
128
129
130
131
132
133
package main
import (
"encoding/base64"
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"google.golang.org/protobuf/proto"
)
var (
dataPath = flag.String("datapath", filepath.Join("./", "data"), "Path to your custom 'data' directory")
datName = flag.String("datname", "geosite.dat", "Name of the generated dat file")
outputPath = flag.String("outputpath", "./publish", "Output path to the generated files")
exportLists = flag.String("exportlists", "category-ads-all,tld-cn,cn,geolocation-cn,tld-!cn,geolocation-!cn,private,apple,icloud,google,steam", "Lists to be exported in plaintext format, separated by ',' comma")
excludeAttrs = flag.String("excludeattrs", "cn@!cn@ads,geolocation-cn@!cn@ads,geolocation-!cn@cn@ads", "Exclude rules with certain attributes in certain lists, seperated by ',' comma, support multiple attributes in one list. Example: geolocation-!cn@cn@ads,geolocation-cn@!cn")
toGFWList = flag.String("togfwlist", "geolocation-!cn", "List to be exported in GFWList format")
)
func main() {
flag.Parse()
dir := GetDataDir()
listInfoMap := make(ListInfoMap)
if err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if err := listInfoMap.Marshal(path); err != nil {
return err
}
return nil
}); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
}
if err := listInfoMap.FlattenAndGenUniqueDomainList(); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
}
// Process and split *excludeRules
excludeAttrsInFile := make(map[fileName]map[attribute]bool)
if *excludeAttrs != "" {
exFilenameAttrSlice := strings.Split(*excludeAttrs, ",")
for _, exFilenameAttr := range exFilenameAttrSlice {
exFilenameAttr = strings.TrimSpace(exFilenameAttr)
exFilenameAttrMap := strings.Split(exFilenameAttr, "@")
filename := fileName(strings.ToUpper(strings.TrimSpace(exFilenameAttrMap[0])))
excludeAttrsInFile[filename] = make(map[attribute]bool)
for _, attr := range exFilenameAttrMap[1:] {
attr = strings.TrimSpace(attr)
if len(attr) > 0 {
excludeAttrsInFile[filename][attribute(attr)] = true
}
}
}
}
// Process and split *exportLists
var exportListsSlice []string
if *exportLists != "" {
tempSlice := strings.Split(*exportLists, ",")
for _, exportList := range tempSlice {
exportList = strings.TrimSpace(exportList)
if len(exportList) > 0 {
exportListsSlice = append(exportListsSlice, exportList)
}
}
}
// Generate dlc.dat
if geositeList := listInfoMap.ToProto(excludeAttrsInFile); geositeList != nil {
protoBytes, err := proto.Marshal(geositeList)
if err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
}
if err := os.MkdirAll(*outputPath, 0755); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
}
if err := os.WriteFile(filepath.Join(*outputPath, *datName), protoBytes, 0644); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
} else {
fmt.Printf("%s has been generated successfully in '%s'.\n", *datName, *outputPath)
}
}
// Generate plaintext list files
if filePlainTextBytesMap, err := listInfoMap.ToPlainText(exportListsSlice); err == nil {
for filename, plaintextBytes := range filePlainTextBytesMap {
filename += ".txt"
if err := os.WriteFile(filepath.Join(*outputPath, filename), plaintextBytes, 0644); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
} else {
fmt.Printf("%s has been generated successfully in '%s'.\n", filename, *outputPath)
}
}
} else {
fmt.Println("Failed:", err)
os.Exit(1)
}
// Generate gfwlist.txt
if gfwlistBytes, err := listInfoMap.ToGFWList(*toGFWList); err == nil {
if f, err := os.OpenFile(filepath.Join(*outputPath, "gfwlist.txt"), os.O_RDWR|os.O_CREATE, 0644); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
} else {
encoder := base64.NewEncoder(base64.StdEncoding, f)
defer encoder.Close()
if _, err := encoder.Write(gfwlistBytes); err != nil {
fmt.Println("Failed:", err)
os.Exit(1)
}
fmt.Printf("gfwlist.txt has been generated successfully in '%s'.\n", *outputPath)
}
} else {
fmt.Println("Failed:", err)
os.Exit(1)
}
}