]> Cypherpunks.ru repositories - nncp.git/blob - src/humanizer.go
14b615fbfdcc8369872aed37183d71d72c25b003
[nncp.git] / src / humanizer.go
1 /*
2 NNCP -- Node to Node copy
3 Copyright (C) 2016-2019 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, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package nncp
19
20 import (
21         "fmt"
22         "regexp"
23         "strconv"
24         "strings"
25         "time"
26
27         "github.com/dustin/go-humanize"
28 )
29
30 func (ctx *Ctx) Humanize(s string) string {
31         s = strings.TrimRight(s, "\n")
32         splitted := strings.SplitN(s, " ", 4)
33         if len(splitted) != 4 {
34                 return s
35         }
36         var level string
37         if splitted[0] == "E" {
38                 level = "ERROR "
39         }
40         when, err := time.Parse(time.RFC3339Nano, splitted[1])
41         if err != nil {
42                 return s
43         }
44         who := splitted[2][1:]
45         closingBracket := strings.LastIndex(splitted[3], "]")
46         if closingBracket == -1 {
47                 return s
48         }
49         rem := strings.Trim(splitted[3][closingBracket+1:], " ")
50         sds := make(map[string]string)
51
52         re := regexp.MustCompile(`\w+="[^"]+"`)
53         for _, pair := range re.FindAllString(splitted[3][:closingBracket+1], -1) {
54                 sep := strings.Index(pair, "=")
55                 sds[pair[:sep]] = pair[sep+2 : len(pair)-1]
56         }
57
58         nodeS := sds["node"]
59         node, err := ctx.FindNode(nodeS)
60         if err == nil {
61                 nodeS = node.Name
62         }
63         var size string
64         if sizeRaw, exists := sds["size"]; exists {
65                 sp, err := strconv.ParseUint(sizeRaw, 10, 64)
66                 if err != nil {
67                         return s
68                 }
69                 size = humanize.IBytes(uint64(sp))
70         }
71
72         var msg string
73         switch who {
74         case "tx":
75                 switch sds["type"] {
76                 case "file":
77                         msg = fmt.Sprintf(
78                                 "File %s (%s) transfer to %s:%s: %s",
79                                 sds["src"], size, nodeS, sds["dst"], rem,
80                         )
81                 case "freq":
82                         msg = fmt.Sprintf(
83                                 "File request from %s:%s to %s: %s",
84                                 nodeS, sds["src"], sds["dst"], rem,
85                         )
86                 case "exec":
87                         msg = fmt.Sprintf(
88                                 "Exec to %s@%s (%s): %s",
89                                 nodeS, sds["dst"], size, rem,
90                         )
91                 case "trns":
92                         msg = fmt.Sprintf(
93                                 "Transitional packet to %s (%s) (nice %s): %s",
94                                 nodeS, size, sds["nice"], rem,
95                         )
96                 default:
97                         return s
98                 }
99                 if err, exists := sds["err"]; exists {
100                         msg += ": " + err
101                 }
102         case "rx":
103                 switch sds["type"] {
104                 case "exec":
105                         msg = fmt.Sprintf(
106                                 "Got exec from %s to %s (%s)",
107                                 nodeS, sds["dst"], size,
108                         )
109                 case "file":
110                         msg = fmt.Sprintf("Got file %s (%s) from %s", sds["dst"], size, nodeS)
111                 case "freq":
112                         msg = fmt.Sprintf("Got file request %s to %s", sds["src"], nodeS)
113                 case "trns":
114                         nodeT := sds["dst"]
115                         node, err := ctx.FindNode(nodeT)
116                         if err == nil {
117                                 nodeT = node.Name
118                         }
119                         msg = fmt.Sprintf(
120                                 "Got transitional packet from %s to %s (%s)",
121                                 nodeS, nodeT, size,
122                         )
123                 default:
124                         return s
125                 }
126                 if err, exists := sds["err"]; exists {
127                         msg += ": " + err
128                 }
129         case "check":
130                 msg = fmt.Sprintf("Checking: %s/%s/%s", sds["node"], sds["xx"], sds["pkt"])
131                 if err, exists := sds["err"]; exists {
132                         msg += fmt.Sprintf(" %s", err)
133                 }
134         case "nncp-xfer":
135                 switch sds["xx"] {
136                 case "rx":
137                         msg = "Packet transfer, received from"
138                 case "tx":
139                         msg = "Packet transfer, sent to"
140                 default:
141                         return s
142                 }
143                 if nodeS != "" {
144                         msg += " node " + nodeS
145                 }
146                 if size != "" {
147                         msg += fmt.Sprintf(" (%s)", size)
148                 }
149                 if err, exists := sds["err"]; exists {
150                         msg += ": " + err
151                 } else {
152                         msg += " " + rem
153                 }
154         case "nncp-bundle":
155                 switch sds["xx"] {
156                 case "rx":
157                         msg = "Bundle transfer, received from"
158                 case "tx":
159                         msg = "Bundle transfer, sent to"
160                 default:
161                         return s
162                 }
163                 if nodeS != "" {
164                         msg += " node " + nodeS
165                 }
166                 msg += " " + sds["pkt"]
167                 if size != "" {
168                         msg += fmt.Sprintf(" (%s)", size)
169                 }
170                 if err, exists := sds["err"]; exists {
171                         msg += ": " + err
172                 }
173         case "nncp-rm":
174                 msg += "removing " + sds["file"]
175         case "call-start":
176                 msg = fmt.Sprintf("Connection to %s", nodeS)
177                 if err, exists := sds["err"]; exists {
178                         msg += ": " + err
179                 }
180         case "call-finish":
181                 rx, err := strconv.ParseUint(sds["rxbytes"], 10, 64)
182                 if err != nil {
183                         return s
184                 }
185                 rxs, err := strconv.ParseUint(sds["rxspeed"], 10, 64)
186                 if err != nil {
187                         return s
188                 }
189                 tx, err := strconv.ParseUint(sds["txbytes"], 10, 64)
190                 if err != nil {
191                         return s
192                 }
193                 txs, err := strconv.ParseUint(sds["txspeed"], 10, 64)
194                 if err != nil {
195                         return s
196                 }
197                 msg = fmt.Sprintf(
198                         "Finished call with %s: %s received (%s/sec), %s transferred (%s/sec)",
199                         nodeS,
200                         humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
201                         humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
202                 )
203         case "sp-start":
204                 if nodeS == "" {
205                         msg += "SP"
206                         if peer, exists := sds["peer"]; exists {
207                                 msg += fmt.Sprintf(": %s", peer)
208                         }
209                 } else {
210                         nice, err := NicenessParse(sds["nice"])
211                         if err != nil {
212                                 return s
213                         }
214                         msg += fmt.Sprintf("SP with %s (nice %s)", nodeS, NicenessFmt(nice))
215                 }
216                 if len(rem) > 0 {
217                         msg += ": " + rem
218                 }
219                 if err, exists := sds["err"]; exists {
220                         msg += ": " + err
221                 }
222
223         case "sp-info":
224                 nice, err := NicenessParse(sds["nice"])
225                 if err != nil {
226                         return s
227                 }
228                 msg = fmt.Sprintf(
229                         "Packet %s (%s) (nice %s)",
230                         sds["hash"],
231                         size,
232                         NicenessFmt(nice),
233                 )
234                 offsetParsed, err := strconv.ParseUint(sds["offset"], 10, 64)
235                 if err != nil {
236                         return s
237                 }
238                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
239                 if err != nil {
240                         return s
241                 }
242                 msg += fmt.Sprintf(": %d%%", 100*offsetParsed/sizeParsed)
243                 if len(rem) > 0 {
244                         msg += ": " + rem
245                 }
246         case "sp-infos":
247                 switch sds["xx"] {
248                 case "rx":
249                         msg = fmt.Sprintf("%s has got for us: ", nodeS)
250                 case "tx":
251                         msg = fmt.Sprintf("We have got for %s: ", nodeS)
252                 default:
253                         return s
254                 }
255                 msg += fmt.Sprintf("%s packets, %s", sds["pkts"], size)
256         case "sp-process":
257                 msg = fmt.Sprintf("%s has %s (%s): %s", nodeS, sds["hash"], size, rem)
258         case "sp-file":
259                 switch sds["xx"] {
260                 case "rx":
261                         msg = "Got packet "
262                 case "tx":
263                         msg = "Sent packet "
264                 default:
265                         return s
266                 }
267                 fullsize, err := strconv.ParseUint(sds["fullsize"], 10, 64)
268                 if err != nil {
269                         return s
270                 }
271                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
272                 if err != nil {
273                         return s
274                 }
275                 msg += fmt.Sprintf(
276                         "%s %d%% (%s / %s)",
277                         sds["hash"],
278                         100*sizeParsed/fullsize,
279                         humanize.IBytes(uint64(sizeParsed)),
280                         humanize.IBytes(uint64(fullsize)),
281                 )
282         case "sp-done":
283                 switch sds["xx"] {
284                 case "rx":
285                         msg = fmt.Sprintf("Packet %s is retreived (%s)", sds["hash"], size)
286                 case "tx":
287                         msg = fmt.Sprintf("Packet %s is sent", sds["hash"])
288                 default:
289                         return s
290                 }
291         case "nncp-reass":
292                 chunkNum, exists := sds["chunk"]
293                 if exists {
294                         msg = fmt.Sprintf(
295                                 "Reassembling chunked file \"%s\" (chunk %s): %s",
296                                 sds["path"],
297                                 chunkNum,
298                                 rem,
299                         )
300                 } else {
301                         msg = fmt.Sprintf(
302                                 "Reassembling chunked file \"%s\": %s",
303                                 sds["path"],
304                                 rem,
305                         )
306                 }
307                 if err, exists := sds["err"]; exists {
308                         msg += ": " + err
309                 }
310         case "lockdir":
311                 msg = fmt.Sprintf("Acquire lock for %s: %s", sds["path"], sds["err"])
312         default:
313                 return s
314         }
315         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg)
316 }