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