]> Cypherpunks.ru repositories - nncp.git/blob - src/cypherpunks.ru/nncp/humanizer.go
Forbid any later GNU GPL versions autousage
[nncp.git] / src / cypherpunks.ru / nncp / 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("Connected to %s", nodeS)
177         case "call-finish":
178                 rx, err := strconv.ParseUint(sds["rxbytes"], 10, 64)
179                 if err != nil {
180                         return s
181                 }
182                 rxs, err := strconv.ParseUint(sds["rxspeed"], 10, 64)
183                 if err != nil {
184                         return s
185                 }
186                 tx, err := strconv.ParseUint(sds["txbytes"], 10, 64)
187                 if err != nil {
188                         return s
189                 }
190                 txs, err := strconv.ParseUint(sds["txspeed"], 10, 64)
191                 if err != nil {
192                         return s
193                 }
194                 msg = fmt.Sprintf(
195                         "Finished call with %s: %s received (%s/sec), %s transferred (%s/sec)",
196                         nodeS,
197                         humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
198                         humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
199                 )
200         case "sp-info":
201                 nice, err := NicenessParse(sds["nice"])
202                 if err != nil {
203                         return s
204                 }
205                 msg = fmt.Sprintf(
206                         "Packet %s (%s) (nice %s)",
207                         sds["hash"],
208                         size,
209                         NicenessFmt(nice),
210                 )
211                 offsetParsed, err := strconv.ParseUint(sds["offset"], 10, 64)
212                 if err != nil {
213                         return s
214                 }
215                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
216                 if err != nil {
217                         return s
218                 }
219                 msg += fmt.Sprintf(": %d%%", 100*offsetParsed/sizeParsed)
220                 if len(rem) > 0 {
221                         msg += ": " + rem
222                 }
223         case "sp-infos":
224                 switch sds["xx"] {
225                 case "rx":
226                         msg = fmt.Sprintf("%s has got for us: ", nodeS)
227                 case "tx":
228                         msg = fmt.Sprintf("We have got for %s: ", nodeS)
229                 default:
230                         return s
231                 }
232                 msg += fmt.Sprintf("%s packets, %s", sds["pkts"], size)
233         case "sp-process":
234                 msg = fmt.Sprintf("%s has %s (%s): %s", nodeS, sds["hash"], size, rem)
235         case "sp-file":
236                 switch sds["xx"] {
237                 case "rx":
238                         msg = "Got packet "
239                 case "tx":
240                         msg = "Sent packet "
241                 default:
242                         return s
243                 }
244                 fullsize, err := strconv.ParseUint(sds["fullsize"], 10, 64)
245                 if err != nil {
246                         return s
247                 }
248                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
249                 if err != nil {
250                         return s
251                 }
252                 msg += fmt.Sprintf(
253                         "%s %d%% (%s / %s)",
254                         sds["hash"],
255                         100*sizeParsed/fullsize,
256                         humanize.IBytes(uint64(sizeParsed)),
257                         humanize.IBytes(uint64(fullsize)),
258                 )
259         case "sp-done":
260                 switch sds["xx"] {
261                 case "rx":
262                         msg = fmt.Sprintf("Packet %s is retreived (%s)", sds["hash"], size)
263                 case "tx":
264                         msg = fmt.Sprintf("Packet %s is sent", sds["hash"])
265                 default:
266                         return s
267                 }
268         case "nncp-reass":
269                 chunkNum, exists := sds["chunk"]
270                 if exists {
271                         msg = fmt.Sprintf(
272                                 "Reassembling chunked file \"%s\" (chunk %s): %s",
273                                 sds["path"],
274                                 chunkNum,
275                                 rem,
276                         )
277                 } else {
278                         msg = fmt.Sprintf(
279                                 "Reassembling chunked file \"%s\": %s",
280                                 sds["path"],
281                                 rem,
282                         )
283                 }
284                 if err, exists := sds["err"]; exists {
285                         msg += ": " + err
286                 }
287         case "lockdir":
288                 msg = fmt.Sprintf("Acquire lock for %s: %s", sds["path"], sds["err"])
289         default:
290                 return s
291         }
292         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg)
293 }