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