]> Sergey Matveev's repositories - rutrackerer.git/blob - cmd/index/main.go
Initial commit
[rutrackerer.git] / cmd / index / main.go
1 package main
2
3 import (
4         "bufio"
5         "bytes"
6         "crypto/sha1"
7         "encoding/gob"
8         "encoding/hex"
9         "encoding/xml"
10         "flag"
11         "fmt"
12         "io"
13         "os"
14         "strconv"
15         "time"
16
17         "go.stargrave.org/rutrackerer"
18 )
19
20 func main() {
21         doCSV := flag.Bool("csv", false, "Output CSV instead of gob")
22         flag.Parse()
23         br := bufio.NewReader(os.Stdin)
24         d := xml.NewDecoder(br)
25         var t xml.Token
26         var err error
27         var e xml.StartElement
28         var ok bool
29         for {
30                 t, err = d.Token()
31                 if err != nil {
32                         panic(err)
33                 }
34                 e, ok = t.(xml.StartElement)
35                 if ok && e.Name.Local == "torrents" {
36                         break
37                 }
38         }
39         var gobEnc *gob.Encoder
40         bufStdout := bufio.NewWriter(os.Stdout)
41         if !*doCSV {
42                 gobEnc = gob.NewEncoder(bufStdout)
43         }
44         emptyHash := make([]byte, sha1.Size)
45         var torrent *rutrackerer.Torrent
46         var c xml.CharData
47         var attr xml.Attr
48         for {
49                 t, err = d.Token()
50                 if err != nil {
51                         if err == io.EOF {
52                                 break
53                         }
54                         panic(err)
55                 }
56                 e, ok = t.(xml.StartElement)
57                 if !ok {
58                         continue
59                 }
60                 switch e.Name.Local {
61                 case "title":
62                         t, err = d.Token()
63                         if err != nil {
64                                 panic(err)
65                         }
66                         c, ok = t.(xml.CharData)
67                         if !ok {
68                                 panic("non-character data after title")
69                         }
70                         torrent.Title = string(c)
71                 case "torrent":
72                         if len(e.Attr) < 3 {
73                                 for _, attr = range e.Attr {
74                                         if attr.Name.Local != "hash" {
75                                                 continue
76                                         }
77                                         if len(attr.Value) != sha1.Size*2 {
78                                                 panic("bad hash size")
79                                         }
80                                         _, err = hex.Decode(torrent.Hash[:], []byte(attr.Value))
81                                         if err != nil {
82                                                 panic(err)
83                                         }
84                                 }
85                                 continue
86                         }
87                         if torrent != nil {
88                                 if torrent.Title == "" {
89                                         panic("empty title")
90                                 }
91                                 if torrent.Id == 0 {
92                                         panic("empty id")
93                                 }
94                                 if torrent.Size == 0 {
95                                         panic("empty size")
96                                 }
97                                 if bytes.Compare(torrent.Hash[:], emptyHash) == 0 {
98                                         panic("empty hash")
99                                 }
100                                 if *doCSV {
101                                         fmt.Println(torrent.CSV())
102                                 } else {
103                                         if err = gobEnc.Encode(torrent); err != nil {
104                                                 panic(err)
105                                         }
106                                 }
107                         }
108                         torrent = new(rutrackerer.Torrent)
109                         for _, attr = range e.Attr {
110                                 switch attr.Name.Local {
111                                 case "id":
112                                         torrent.Id, err = strconv.ParseInt(attr.Value, 10, 64)
113                                         if err != nil {
114                                                 panic(err)
115                                         }
116                                         torrent.Offset = d.InputOffset()
117                                 case "registred_at":
118                                         torrent.Registered, err = time.Parse(
119                                                 "2006.01.02 15:04:05", attr.Value,
120                                         )
121                                         if err != nil {
122                                                 panic(err)
123                                         }
124                                 case "size":
125                                         torrent.Size, err = strconv.ParseInt(attr.Value, 10, 64)
126                                         if err != nil {
127                                                 panic(err)
128                                         }
129                                 }
130                         }
131                 }
132         }
133         if !*doCSV {
134                 if err = bufStdout.Flush(); err != nil {
135                         panic(err)
136                 }
137         }
138 }