]> Cypherpunks.ru repositories - nncp.git/blob - src/humanizer.go
Intermediate .nock packets step
[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, err := strconv.ParseUint(le["FullSize"], 10, 64)
248                 if err != nil {
249                         return "", err
250                 }
251                 msg += fmt.Sprintf(
252                         "%s %d%% (%s / %s)",
253                         le["Pkt"],
254                         100*sizeParsed/fullsize,
255                         humanize.IBytes(uint64(sizeParsed)),
256                         humanize.IBytes(uint64(fullsize)),
257                 )
258         case "sp-done":
259                 switch le["XX"] {
260                 case "rx":
261                         msg = fmt.Sprintf("Packet %s is retreived (%s)", le["Pkt"], size)
262                 case "tx":
263                         msg = fmt.Sprintf("Packet %s is sent", le["Pkt"])
264                 default:
265                         return "", errors.New("unknown XX")
266                 }
267         case "nncp-reass":
268                 chunkNum, exists := le["Chunk"]
269                 if exists {
270                         msg = fmt.Sprintf(
271                                 "Reassembling chunked file \"%s\" (chunk %s): %s",
272                                 le["Path"], chunkNum, le["Msg"],
273                         )
274                 } else {
275                         msg = fmt.Sprintf(
276                                 "Reassembling chunked file \"%s\": %s",
277                                 le["Path"], le["Msg"],
278                         )
279                 }
280                 if err, exists := le["Err"]; exists {
281                         msg += ": " + err
282                 }
283         case "lockdir":
284                 msg = fmt.Sprintf("Acquire lock for %s: %s", le["Path"], le["Err"])
285         default:
286                 return "", errors.New("unknown Who")
287         }
288         when, err := time.Parse(time.RFC3339Nano, le["When"])
289         if err != nil {
290                 return "", err
291         }
292         var level string
293         if _, isErr := le["Err"]; isErr {
294                 level = "ERROR "
295         }
296         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg), nil
297 }