]> Cypherpunks.ru repositories - nncp.git/blob - src/humanizer.go
Do not fail during hasher deletion
[nncp.git] / src / humanizer.go
1 /*
2 NNCP -- Node to Node copy
3 Copyright (C) 2016-2021 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         "errors"
22         "fmt"
23         "strconv"
24         "strings"
25         "time"
26
27         "github.com/dustin/go-humanize"
28         "go.cypherpunks.ru/recfile"
29 )
30
31 func (ctx *Ctx) HumanizeRec(rec string) string {
32         r := recfile.NewReader(strings.NewReader(rec))
33         le, err := r.NextMap()
34         if err != nil {
35                 return rec
36         }
37         humanized, err := ctx.Humanize(le)
38         if err != nil {
39                 return fmt.Sprintf("Can not humanize: %s\n%s", err, rec)
40         }
41         return humanized
42 }
43
44 func (ctx *Ctx) Humanize(le map[string]string) (string, error) {
45         nodeS := le["Node"]
46         node, err := ctx.FindNode(nodeS)
47         if err == nil {
48                 nodeS = node.Name
49         }
50         var sizeParsed uint64
51         var size string
52         if sizeRaw, exists := le["Size"]; exists {
53                 sizeParsed, err = strconv.ParseUint(sizeRaw, 10, 64)
54                 if err != nil {
55                         return "", err
56                 }
57                 size = humanize.IBytes(sizeParsed)
58         }
59
60         var msg string
61         switch le["Who"] {
62         case "tx":
63                 switch le["Type"] {
64                 case "file":
65                         msg = fmt.Sprintf(
66                                 "File %s (%s) transfer to %s:%s: %s",
67                                 le["Src"], size, nodeS, le["Dst"], le["Msg"],
68                         )
69                 case "freq":
70                         msg = fmt.Sprintf(
71                                 "File request from %s:%s to %s: %s",
72                                 nodeS, le["Src"], le["Dst"], le["Msg"],
73                         )
74                 case "exec":
75                         msg = fmt.Sprintf(
76                                 "Exec to %s@%s (%s): %s",
77                                 nodeS, le["Dst"], size, le["Msg"],
78                         )
79                 case "trns":
80                         msg = fmt.Sprintf(
81                                 "Transitional packet to %s (%s) (nice %s): %s",
82                                 nodeS, size, le["Nice"], le["Msg"],
83                         )
84                 default:
85                         return "", errors.New("unknown \"tx\" type")
86                 }
87                 if err, exists := le["Err"]; exists {
88                         msg += ": " + err
89                 }
90         case "rx":
91                 switch le["Type"] {
92                 case "exec":
93                         msg = fmt.Sprintf("Got exec from %s to %s (%s)", nodeS, le["Dst"], size)
94                 case "file":
95                         msg = fmt.Sprintf("Got file %s (%s) from %s", le["Dst"], size, nodeS)
96                 case "freq":
97                         msg = fmt.Sprintf("Got file request %s to %s", le["Src"], nodeS)
98                 case "trns":
99                         nodeT := le["Dst"]
100                         node, err := ctx.FindNode(nodeT)
101                         if err == nil {
102                                 nodeT = node.Name
103                         }
104                         msg = fmt.Sprintf(
105                                 "Got transitional packet from %s to %s (%s)",
106                                 nodeS, nodeT, size,
107                         )
108                 default:
109                         return "", errors.New("unknown \"rx\" type")
110                 }
111                 if err, exists := le["Err"]; exists {
112                         msg += ": " + err
113                 }
114         case "check":
115                 msg = fmt.Sprintf("Checking: %s/%s/%s", le["Node"], le["XX"], le["Pkt"])
116                 if err, exists := le["Err"]; exists {
117                         msg += fmt.Sprintf(" %s", err)
118                 }
119         case "nncp-xfer":
120                 switch le["XX"] {
121                 case "rx":
122                         msg = "Packet transfer, received from"
123                 case "tx":
124                         msg = "Packet transfer, sent to"
125                 default:
126                         return "", errors.New("unknown XX")
127                 }
128                 if nodeS != "" {
129                         msg += " node " + nodeS
130                 }
131                 if size != "" {
132                         msg += fmt.Sprintf(" (%s)", size)
133                 }
134                 if err, exists := le["Err"]; exists {
135                         msg += ": " + err
136                 } else {
137                         msg += " " + le["Msg"]
138                 }
139         case "nncp-bundle":
140                 switch le["XX"] {
141                 case "rx":
142                         msg = "Bundle transfer, received from"
143                 case "tx":
144                         msg = "Bundle transfer, sent to"
145                 default:
146                         return "", errors.New("unknown XX")
147                 }
148                 if nodeS != "" {
149                         msg += " node " + nodeS
150                 }
151                 msg += " " + le["Pkt"]
152                 if size != "" {
153                         msg += fmt.Sprintf(" (%s)", size)
154                 }
155                 if err, exists := le["Err"]; exists {
156                         msg += ": " + err
157                 }
158         case "nncp-rm":
159                 msg += "removing " + le["File"]
160         case "call-start":
161                 msg = fmt.Sprintf("Connection to %s", nodeS)
162                 if err, exists := le["Err"]; exists {
163                         msg += ": " + err
164                 }
165         case "call-finish":
166                 rx, err := strconv.ParseUint(le["RxBytes"], 10, 64)
167                 if err != nil {
168                         return "", err
169                 }
170                 rxs, err := strconv.ParseUint(le["RxSpeed"], 10, 64)
171                 if err != nil {
172                         return "", err
173                 }
174                 tx, err := strconv.ParseUint(le["TxBytes"], 10, 64)
175                 if err != nil {
176                         return "", err
177                 }
178                 txs, err := strconv.ParseUint(le["TxSpeed"], 10, 64)
179                 if err != nil {
180                         return "", err
181                 }
182                 msg = fmt.Sprintf(
183                         "Finished call with %s: %s received (%s/sec), %s transferred (%s/sec)",
184                         nodeS,
185                         humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
186                         humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
187                 )
188         case "sp-start":
189                 if nodeS == "" {
190                         msg += "SP"
191                         if peer, exists := le["Peer"]; exists {
192                                 msg += fmt.Sprintf(": %s", peer)
193                         }
194                 } else {
195                         nice, err := NicenessParse(le["Nice"])
196                         if err != nil {
197                                 return "", err
198                         }
199                         msg += fmt.Sprintf("SP with %s (nice %s)", nodeS, NicenessFmt(nice))
200                 }
201                 if m, exists := le["Msg"]; exists {
202                         msg += ": " + m
203                 }
204                 if err, exists := le["Err"]; exists {
205                         msg += ": " + err
206                 }
207         case "sp-info":
208                 nice, err := NicenessParse(le["Nice"])
209                 if err != nil {
210                         return "", err
211                 }
212                 msg = fmt.Sprintf(
213                         "Packet %s (%s) (nice %s)",
214                         le["Pkt"], size, NicenessFmt(nice),
215                 )
216                 if offset := le["Offset"]; offset != "" {
217                         offsetParsed, err := strconv.ParseUint(offset, 10, 64)
218                         if err != nil {
219                                 return "", err
220                         }
221                         msg += fmt.Sprintf(": %d%%", 100*offsetParsed/sizeParsed)
222                 }
223                 if m, exists := le["Msg"]; exists {
224                         msg += ": " + m
225                 }
226         case "sp-infos":
227                 switch le["XX"] {
228                 case "rx":
229                         msg = fmt.Sprintf("%s has got for us: ", nodeS)
230                 case "tx":
231                         msg = fmt.Sprintf("We have got for %s: ", nodeS)
232                 default:
233                         return "", errors.New("unknown XX")
234                 }
235                 msg += fmt.Sprintf("%s packets, %s", le["Pkts"], size)
236         case "sp-process":
237                 msg = fmt.Sprintf("%s has %s (%s): %s", nodeS, le["Pkt"], size, le["Msg"])
238         case "sp-file":
239                 switch le["XX"] {
240                 case "rx":
241                         msg = "Got packet "
242                 case "tx":
243                         msg = "Sent packet "
244                 default:
245                         return "", errors.New("unknown XX")
246                 }
247                 fullsize := uint64(1)
248                 if raw, exists := le["FullSize"]; exists {
249                         fullsize, err = strconv.ParseUint(raw, 10, 64)
250                         if err != nil {
251                                 return "", err
252                         }
253                 }
254                 msg += fmt.Sprintf(
255                         "%s %d%% (%s / %s)",
256                         le["Pkt"],
257                         100*sizeParsed/fullsize,
258                         humanize.IBytes(uint64(sizeParsed)),
259                         humanize.IBytes(uint64(fullsize)),
260                 )
261                 if m, exists := le["Msg"]; exists {
262                         msg += ": " + m
263                 }
264                 if err, exists := le["Err"]; exists {
265                         msg += ": " + err
266                 }
267         case "sp-done":
268                 switch le["XX"] {
269                 case "rx":
270                         msg = fmt.Sprintf("Packet %s is retreived (%s)", le["Pkt"], size)
271                 case "tx":
272                         msg = fmt.Sprintf("Packet %s is sent", le["Pkt"])
273                 default:
274                         return "", errors.New("unknown XX")
275                 }
276         case "nncp-reass":
277                 chunkNum, exists := le["Chunk"]
278                 if exists {
279                         msg = fmt.Sprintf(
280                                 "Reassembling chunked file \"%s\" (chunk %s): %s",
281                                 le["Path"], chunkNum, le["Msg"],
282                         )
283                 } else {
284                         msg = fmt.Sprintf(
285                                 "Reassembling chunked file \"%s\": %s",
286                                 le["Path"], le["Msg"],
287                         )
288                 }
289                 if err, exists := le["Err"]; exists {
290                         msg += ": " + err
291                 }
292         case "lockdir":
293                 msg = fmt.Sprintf("Acquire lock for %s: %s", le["Path"], le["Err"])
294         default:
295                 return "", errors.New("unknown Who")
296         }
297         when, err := time.Parse(time.RFC3339Nano, le["When"])
298         if err != nil {
299                 return "", err
300         }
301         var level string
302         if _, isErr := le["Err"]; isErr {
303                 level = "ERROR "
304         }
305         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg), nil
306 }