3838var (
3939 refMap = make (map [string ]* List )
4040 plMap = make (map [string ]* ParsedList )
41- finalMap = make (map [string ]* List )
41+ finalMap = make (map [string ][] Entry )
4242 cirIncMap = make (map [string ]bool ) // Used for circular inclusion detection
4343)
4444
@@ -65,27 +65,11 @@ type ParsedList struct {
6565 Entry []Entry
6666}
6767
68- func (l * List ) toPlainText () error {
69- var entryBytes []byte
70- for _ , entry := range l .Entry {
71- var attrString string
72- if entry .Attrs != nil {
73- attrString = ":@" + strings .Join (entry .Attrs , ",@" )
74- }
75- // Entry output format is: type:domain.tld:@attr1,@attr2
76- entryBytes = append (entryBytes , []byte (entry .Type + ":" + entry .Value + attrString + "\n " )... )
77- }
78- if err := os .WriteFile (filepath .Join (* outputDir , strings .ToLower (l .Name ) + ".txt" ), entryBytes , 0644 ); err != nil {
79- return err
80- }
81- return nil
82- }
83-
84- func (l * List ) toProto () (* router.GeoSite , error ) {
68+ func makeProtoList (listName string , entries []Entry ) (* router.GeoSite , error ) {
8569 site := & router.GeoSite {
86- CountryCode : l . Name ,
70+ CountryCode : listName ,
8771 }
88- for _ , entry := range l . Entry {
72+ for _ , entry := range entries {
8973 pdomain := & router.Domain {Value : entry .Value }
9074 for _ , attr := range entry .Attrs {
9175 pdomain .Attribute = append (pdomain .Attribute , & router.Domain_Attribute {
@@ -109,16 +93,26 @@ func (l *List) toProto() (*router.GeoSite, error) {
10993 return site , nil
11094}
11195
112- func exportPlainTextList (exportFiles []string , entryList * List ) {
113- for _ , exportfilename := range exportFiles {
114- if strings .EqualFold (entryList .Name , exportfilename ) {
115- if err := entryList .toPlainText (); err != nil {
116- fmt .Println ("Failed to exportPlainTextList:" , err )
117- continue
118- }
119- fmt .Printf ("'%s' has been generated successfully.\n " , exportfilename )
96+ func writePlainList (exportedName string ) error {
97+ targetList , exist := finalMap [strings .ToUpper (exportedName )]
98+ if ! exist || len (targetList ) == 0 {
99+ return fmt .Errorf ("'%s' list does not exist or is empty." , exportedName )
100+ }
101+ file , err := os .Create (filepath .Join (* outputDir , strings .ToLower (exportedName ) + ".txt" ))
102+ if err != nil {
103+ return err
104+ }
105+ defer file .Close ()
106+ w := bufio .NewWriter (file )
107+ for _ , entry := range targetList {
108+ // Entry output format is: type:domain.tld:@attr1,@attr2
109+ var attrString string
110+ if entry .Attrs != nil {
111+ attrString = ":@" + strings .Join (entry .Attrs , ",@" )
120112 }
113+ fmt .Fprintln (w , entry .Type + ":" + entry .Value + attrString )
121114 }
115+ return w .Flush ()
122116}
123117
124118func parseEntry (line string ) (Entry , error ) {
@@ -254,23 +248,23 @@ func ResolveList(pl *ParsedList) error {
254248 }
255249
256250 bscDupMap := make (map [string ]bool ) // Used for basic duplicates detection
257- finalList := & List { Name : pl . Name }
251+ var finalList [] Entry
258252 for _ , dentry := range pl .Entry {
259253 if dstring := entry2String (dentry ); ! bscDupMap [dstring ] {
260254 bscDupMap [dstring ] = true
261- finalList . Entry = append (finalList . Entry , dentry )
255+ finalList = append (finalList , dentry )
262256 }
263257 }
264258
265259 for _ , inc := range pl .Inclusions {
266260 if err := ResolveList (plMap [inc .Source ]); err != nil {
267261 return err
268262 }
269- for _ , ientry := range finalMap [inc .Source ]. Entry {
263+ for _ , ientry := range finalMap [inc .Source ] {
270264 if isMatchAttrFilters (ientry , inc ) {
271265 if istring := entry2String (ientry ); ! bscDupMap [istring ] {
272266 bscDupMap [istring ] = true
273- finalList . Entry = append (finalList . Entry , ientry )
267+ finalList = append (finalList , ientry )
274268 }
275269 }
276270 }
@@ -329,38 +323,28 @@ func main() {
329323 }
330324 }
331325
326+ // Export plaintext list
327+ if * exportLists != "" {
328+ exportedListSlice := strings .Split (* exportLists , "," )
329+ for _ , exportedList := range exportedListSlice {
330+ if err := writePlainList (exportedList ); err != nil {
331+ fmt .Println ("Failed to write list:" , err )
332+ continue
333+ }
334+ fmt .Printf ("list: '%s' has been generated successfully.\n " , exportedList )
335+ }
336+ }
337+
338+ // Generate dat file
332339 protoList := new (router.GeoSiteList )
333- var existList []string
334- for _ , siteEntries := range finalMap {
335- site , err := siteEntries .toProto ()
340+ for siteName , siteEntries := range finalMap {
341+ site , err := makeProtoList (siteName , siteEntries )
336342 if err != nil {
337343 fmt .Println ("Failed:" , err )
338344 os .Exit (1 )
339345 }
340346 protoList .Entry = append (protoList .Entry , site )
341-
342- // Flatten and export plaintext list
343- if * exportLists != "" {
344- if existList != nil {
345- exportPlainTextList (existList , siteEntries )
346- } else {
347- exportedListSlice := strings .Split (* exportLists , "," )
348- for _ , exportedListName := range exportedListSlice {
349- fileName := filepath .Join (dir , exportedListName )
350- _ , err := os .Stat (fileName )
351- if err == nil || os .IsExist (err ) {
352- existList = append (existList , exportedListName )
353- } else {
354- fmt .Printf ("'%s' list does not exist in '%s' directory.\n " , exportedListName , dir )
355- }
356- }
357- if existList != nil {
358- exportPlainTextList (existList , siteEntries )
359- }
360- }
361- }
362347 }
363-
364348 // Sort protoList so the marshaled list is reproducible
365349 sort .SliceStable (protoList .Entry , func (i , j int ) bool {
366350 return protoList .Entry [i ].CountryCode < protoList .Entry [j ].CountryCode
0 commit comments