]> Cypherpunks.ru repositories - nncp.git/blob - src/cypherpunks.ru/nncp/humanizer.go
Initial
[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 (nice %s): %s",
80                                 sds["src"], size, nodeS, sds["dst"], sds["nice"], rem,
81                         )
82                 case "freq":
83                         msg = fmt.Sprintf(
84                                 "File request from %s:%s to %s (nice %s): %s",
85                                 nodeS, sds["src"], sds["dst"], sds["nice"], rem,
86                         )
87                 case "mail":
88                         msg = fmt.Sprintf(
89                                 "Mail to %s@%s (%s) (nice %s): %s",
90                                 nodeS, strings.Replace(sds["dst"], " ", ",", -1), size, sds["nice"], 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 "toss-check":
131                 msg = fmt.Sprintf(
132                         "Integrity check: %s/%s/%s %s",
133                         sds["node"], sds["xx"], sds["pkt"], sds["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 "daemon":
154                 msg = fmt.Sprintf("Daemon listening on %s", sds["bind"])
155         case "call-start":
156                 msg = fmt.Sprintf("Connected to %s", nodeS)
157         case "call-finish":
158                 rx, err := strconv.ParseUint(sds["rxbytes"], 10, 64)
159                 if err != nil {
160                         return s
161                 }
162                 rxs, err := strconv.ParseUint(sds["rxspeed"], 10, 64)
163                 if err != nil {
164                         return s
165                 }
166                 tx, err := strconv.ParseUint(sds["txbytes"], 10, 64)
167                 if err != nil {
168                         return s
169                 }
170                 txs, err := strconv.ParseUint(sds["txspeed"], 10, 64)
171                 if err != nil {
172                         return s
173                 }
174                 msg = fmt.Sprintf(
175                         "Finished call with %s: %s received (%s/sec), %s transferred (%s/sec)",
176                         nodeS,
177                         humanize.IBytes(uint64(rx)), humanize.IBytes(uint64(rxs)),
178                         humanize.IBytes(uint64(tx)), humanize.IBytes(uint64(txs)),
179                 )
180         case "llp-infos":
181                 switch sds["xx"] {
182                 case "rx":
183                         msg = fmt.Sprintf("We have got for %s: ", nodeS)
184                 case "tx":
185                         msg = fmt.Sprintf("%s has got for us: ", nodeS)
186                 default:
187                         return s
188                 }
189                 msg += fmt.Sprintf("%s packets, %s", sds["pkts"], size)
190         case "llp-file":
191                 switch sds["xx"] {
192                 case "rx":
193                         msg = "Got file "
194                 case "tx":
195                         msg = "Sent file "
196                 default:
197                         return s
198                 }
199                 fullsize, err := strconv.ParseUint(sds["fullsize"], 10, 64)
200                 if err != nil {
201                         return s
202                 }
203                 sizeParsed, err := strconv.ParseUint(sds["size"], 10, 64)
204                 if err != nil {
205                         return s
206                 }
207                 msg += fmt.Sprintf(
208                         "%s %d%% (%s / %s)",
209                         sds["hash"],
210                         100*sizeParsed/fullsize,
211                         humanize.IBytes(uint64(sizeParsed)),
212                         humanize.IBytes(uint64(fullsize)),
213                 )
214         case "llp-done":
215                 switch sds["xx"] {
216                 case "rx":
217                         msg = fmt.Sprintf("File %s is retreived (%s)", sds["hash"], size)
218                 case "tx":
219                         msg = fmt.Sprintf("File %s is sent (%s)", sds["hash"], size)
220                 default:
221                         return s
222                 }
223         default:
224                 return s
225         }
226         return fmt.Sprintf("%s %s%s", when.Format(time.RFC3339), level, msg)
227 }