]> Cypherpunks.ru repositories - nncp.git/blob - src/cypherpunks.ru/nncp/humanizer.go
7abfcab0aec30113aa18d4f5a91fdef533037d4e
[nncp.git] / src / cypherpunks.ru / nncp / humanizer.go
1 /*
2 NNCP -- Node to Node copy
3 Copyright (C) 2016-2017 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package nncp
20
21 import (
22         "fmt"
23         "regexp"
24         "strconv"
25         "strings"
26         "time"
27
28         "github.com/dustin/go-humanize"
29 )
30
31 func (ctx *Ctx) Humanize(s string) string {
32         s = strings.TrimRight(s, "\n")
33         splitted := strings.SplitN(s, " ", 4)
34         if len(splitted) != 4 {
35                 return s
36         }
37         var level string
38         if splitted[0] == "E" {
39                 level = "ERROR "
40         }
41         when, err := time.Parse(time.RFC3339Nano, splitted[1])
42         if err != nil {
43                 return s
44         }
45         who := splitted[2][1:]
46         closingBracket := strings.LastIndex(splitted[3], "]")
47         if closingBracket == -1 {
48                 return s
49         }
50         rem := strings.Trim(splitted[3][closingBracket+1:], " ")
51         sds := make(map[string]string)
52
53         re := regexp.MustCompile(`\w+="[^"]+"`)
54         for _, pair := range re.FindAllString(splitted[3][:closingBracket+1], -1) {
55                 sep := strings.Index(pair, "=")
56                 sds[pair[:sep]] = pair[sep+2 : len(pair)-1]
57         }
58
59         nodeS := sds["node"]
60         node, err := ctx.FindNode(nodeS)
61         if err == nil {
62                 nodeS = node.Name
63         }
64         var size string
65         if sizeRaw, exists := sds["size"]; exists {
66                 sp, err := strconv.ParseUint(sizeRaw, 10, 64)
67                 if err != nil {
68                         return s
69                 }
70                 size = humanize.IBytes(uint64(sp))
71         }
72
73         var msg string
74         switch who {
75         case "tx":
76                 switch sds["type"] {
77                 case "file":
78                         msg = fmt.Sprintf(
79                                 "File %s (%s) transfer to %s:%s: %s",
80                                 sds["src"], size, nodeS, sds["dst"], rem,
81                         )
82                 case "freq":
83                         msg = fmt.Sprintf(
84                                 "File request from %s:%s to %s: %s",
85                                 nodeS, sds["src"], sds["dst"], rem,
86                         )
87                 case "mail":
88                         msg = fmt.Sprintf(
89                                 "Mail to %s@%s (%s): %s",
90                                 nodeS, strings.Replace(sds["dst"], " ", ",", -1), size, rem,
91                         )
92                 case "trns":
93                         msg = fmt.Sprintf(
94                                 "Transitional packet to %s (%s) (nice %s): %s",
95                                 nodeS, size, sds["nice"], rem,
96                         )
97                 default:
98                         return s
99                 }
100                 if err, exists := sds["err"]; exists {
101                         msg += ": " + err
102                 }
103         case "rx":
104                 switch sds["type"] {
105                 case "mail":
106                         msg = fmt.Sprintf(
107                                 "Got mail from %s to %s (%s)",
108                                 nodeS, strings.Replace(sds["dst"], " ", ",", -1), size,
109                         )
110                 case "file":
111                         msg = fmt.Sprintf("Got file %s (%s) from %s", sds["dst"], size, nodeS)
112                 case "freq":
113                         msg = fmt.Sprintf("Got file request %s to %s", sds["src"], nodeS)
114                 case "trns":
115                         nodeT := sds["dst"]
116                         node, err := ctx.FindNode(nodeT)
117                         if err == nil {
118                                 nodeT = node.Name
119                         }
120                         msg = fmt.Sprintf(
121                                 "Got transitional packet from %s to %s (%s)",
122                                 nodeS, nodeT, size,
123                         )
124                 default:
125                         return s
126                 }
127                 if err, exists := sds["err"]; exists {
128                         msg += ": " + err
129                 }
130         case "check":
131                 msg = fmt.Sprintf("Checking: %s/%s/%s", sds["node"], sds["xx"], sds["pkt"])
132                 if err, exists := sds["err"]; exists {
133                         msg += fmt.Sprintf(" %s", err)
134                 }
135         case "nncp-xfer":
136                 switch sds["xx"] {
137                 case "rx":
138                         msg = "Packet transfer, received from"
139                 case "tx":
140                         msg = "Packet transfer, sent to"
141                 default:
142                         return s
143                 }
144                 if nodeS != "" {
145                         msg += " node " + nodeS
146                 }
147                 if size != "" {
148                         msg += fmt.Sprintf(" (%s)", size)
149                 }
150                 if err, exists := sds["err"]; exists {
151                         msg += ": " + err
152                 }
153         case "call-start":
154                 msg = fmt.Sprintf("Connected to %s", nodeS)
155         case "call-finish":
156                 rx, err := strconv.ParseUint(sds["rxbytes"], 10, 64)
157                 if err != nil {
158                         return s
159                 }
160                 rxs, err := strconv.ParseUint(sds["rxspeed"], 10, 64)
161                 if err != nil {
162                         return s
163                 }
164                 tx, err := strconv.ParseUint(sds["txbytes"], 10, 64)
165                 if err != nil {
166                         return s
167                 }
168                 txs, err := strconv.ParseUint(sds["txspeed"], 10, 64)
169                 if err != nil {
170                         return s
171                 }
172                 msg = fmt.Sprintf(
173                         "Finished call with %s: %s received (%s/sec), %s transferred (%s/sec)",
174                         nodeS,
175                         humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
176                         humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
177                 )
178         case "sp-infos":
179                 switch sds["xx"] {
180                 case "rx":
181                         msg = fmt.Sprintf("%s has got for us: ", nodeS)
182                 case "tx":
183                         msg = fmt.Sprintf("We have got for %s: ", nodeS)
184                 default:
185                         return s
186                 }
187                 msg += fmt.Sprintf("%s packets, %s", sds["pkts"], size)
188         case "sp-file":
189                 switch sds["xx"] {
190                 case "rx":
191                         msg = "Got packet "
192                 case "tx":
193                         msg = "Sent packet "
194                 default:
195                         return s
196                 }
197                 fullsize, err := strconv.ParseUint(sds["fullsize"], 10, 64)
198                 if err != nil {
199                         return s
200                 }
201                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
202                 if err != nil {
203                         return s
204                 }
205                 msg += fmt.Sprintf(
206                         "%s %d%% (%s / %s)",
207                         sds["hash"],
208                         100*sizeParsed/fullsize,
209                         humanize.IBytes(uint64(sizeParsed)),
210                         humanize.IBytes(uint64(fullsize)),
211                 )
212         case "sp-done":
213                 switch sds["xx"] {
214                 case "rx":
215                         msg = fmt.Sprintf("Packet %s is retreived (%s)", sds["hash"], size)
216                 case "tx":
217                         msg = fmt.Sprintf("Packet %s is sent", sds["hash"])
218                 default:
219                         return s
220                 }
221         case "nncp-reass":
222                 chunkNum, exists := sds["chunk"]
223                 if exists {
224                         msg = fmt.Sprintf(
225                                 "Reassembling chunked file \"%s\" (chunk %s): %s",
226                                 sds["path"],
227                                 chunkNum,
228                                 rem,
229                         )
230                 } else {
231                         msg = fmt.Sprintf(
232                                 "Reassembling chunked file \"%s\": %s",
233                                 sds["path"],
234                                 rem,
235                         )
236                 }
237                 if err, exists := sds["err"]; exists {
238                         msg += ": " + err
239                 }
240         case "lockdir":
241                 msg = fmt.Sprintf("Acquire lock for %s: %s", sds["path"], sds["err"])
242         default:
243                 return s
244         }
245         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg)
246 }