1
// Copyright 2016 - 2020 The aurora Authors. All rights reserved. Use of this
2
// source code is governed by a MIT license that can be found in the LICENSE
3
// file.
4
//
5
// The aurora is a web-based beanstalkd queue server console written in Go
6
// and works on macOS, Linux and Windows machines. Main idea behind using Go
7
// for backend development is to utilize ability of the compiler to produce
8
// zero-dependency binaries for multiple platforms. aurora was created as an
9
// attempt to build very simple and portable application to work with local or
10
// remote beanstalkd server.
11

12
package main
13

14
import (
15
	"net/url"
16
	"sort"
17
	"strconv"
18
	"strings"
19

20
	"github.com/xuri/aurora/beanstalk"
21
)
22

23
// getServerStatus render a server stats table.
24
func getServerStatus() string {
25 10
	var err error
26 10
	var buf, td, th strings.Builder
27
	for _, addr := range selfConf.Servers {
28 10
		var bstkConn *beanstalk.Conn
29 10
		if bstkConn, err = beanstalk.Dial("tcp", addr); err != nil {
30 10
			td.WriteString(`<tr><td>`)
31 10
			td.WriteString(addr)
32 10
			td.WriteString(`</td><td colspan="`)
33 10
			td.WriteString(strconv.Itoa(len(selfConf.Filter)))
34 10
			td.WriteString(`" class="row-full">&nbsp;</td><td><a class="btn btn-xs btn-danger" title="Remove from list" href="serversRemove?action=serversRemove&removeServer=`)
35 10
			td.WriteString(addr)
36 10
			td.WriteString(`"><span class="glyphicon glyphicon-minus"> </span></a></td></tr>`)
37 10
			continue
38
		}
39 10
		s, _ := bstkConn.Stats()
40 10
		bstkConn.Close()
41 10
		td.WriteString(`<tr><td><a href="server?server=`)
42 10
		td.WriteString(addr)
43 10
		td.WriteString(`">`)
44 10
		td.WriteString(addr)
45 10
		td.WriteString(`</a></td>`)
46
		for _, v := range selfConf.Filter {
47 10
			td.WriteString(`<td>`)
48 10
			td.WriteString(s[v])
49 10
			td.WriteString(`</td>`)
50
		}
51 10
		td.WriteString(`<td><a class="btn btn-xs btn-danger" title="Remove from list" href="serversRemove?action=serversRemove&removeServer=`)
52 10
		td.WriteString(addr)
53 10
		td.WriteString(`"><span class="glyphicon glyphicon-minus"> </span></a></td></tr>`)
54
	}
55
	for _, v := range selfConf.Filter {
56 10
		th.WriteString(`<th>`)
57 10
		th.WriteString(v)
58 10
		th.WriteString(`</th>`)
59
	}
60 10
	buf.WriteString(`<div class="row"><div class="col-sm-12"><table class="table table-striped table-hover" id="servers-index"><thead><tr><th>name</th>`)
61 10
	buf.WriteString(th.String())
62 10
	buf.WriteString(`<th>&nbsp;</th></tr></thead><tbody>`)
63 10
	buf.WriteString(td.String())
64 10
	buf.WriteString(`</tbody></table><a href="#servers-add" role="button" class="btn btn-info" id="addServer">Add server</a></div></div>`)
65 10
	return buf.String()
66
}
67

68
// getServerTubes render a tubes stats table by given server.
69
func getServerTubes(server string) string {
70 10
	var err error
71 10
	var buf, th, tr, td strings.Builder
72 10
	var bstkConn *beanstalk.Conn
73
	for _, v := range selfConf.TubeFilters {
74 10
		th.WriteString(`<th>`)
75 10
		th.WriteString(v)
76 10
		th.WriteString(`</th>`)
77
	}
78 10
	if bstkConn, err = beanstalk.Dial("tcp", server); err != nil {
79 10
		buf.WriteString(`<div id="idAllTubes"><section id="summaryTable"><div class="row"><div class="col-sm-12"><table class="table table-striped table-hover"><thead><tr><th>name</th>`)
80 10
		buf.WriteString(th.String())
81 10
		buf.WriteString(`</tr></thead><tbody></tbody></table></div></div></section></div>`)
82 10
		return buf.String()
83
	}
84 10
	tubes, _ := bstkConn.ListTubes()
85 10
	sort.Strings(tubes)
86
	for _, v := range tubes {
87 10
		tubeStats := &beanstalk.Tube{
88 10
			Conn: bstkConn,
89 10
			Name: v,
90
		}
91 10
		statsMap, err := tubeStats.Stats()
92 10
		if err != nil {
93 0
			continue
94
		}
95
		for _, stats := range selfConf.TubeFilters {
96 10
			td.WriteString(`<td>`)
97 10
			td.WriteString(statsMap[stats])
98 10
			td.WriteString(`</td>`)
99
		}
100 10
		tr.WriteString(`<tr><td><a href="tube?server=`)
101 10
		tr.WriteString(server)
102 10
		tr.WriteString(`&tube=`)
103 10
		tr.WriteString(url.QueryEscape(v))
104 10
		tr.WriteString(`">`)
105 10
		tr.WriteString(v)
106 10
		tr.WriteString(`</a></td>`)
107 10
		tr.WriteString(td.String())
108 10
		tr.WriteString(`</tr>`)
109 10
		td.Reset()
110
	}
111 10
	bstkConn.Close()
112 10
	buf.WriteString(`<div id="idAllTubes"><section id="summaryTable"><div class="row"><div class="col-sm-12"><table class="table table-striped table-hover"><thead><tr><th>name</th>`)
113 10
	buf.WriteString(th.String())
114 10
	buf.WriteString(`</tr></thead><tbody>`)
115 10
	buf.WriteString(tr.String())
116 10
	buf.WriteString(`</tbody></table></div></div></section></div>`)
117 10
	return buf.String()
118
}
119

120
// dropDownServer render a navigation dropdown menu for server list.
121
func dropDownServer(currentServer string) string {
122 10
	var ul strings.Builder
123 10
	if currentServer == "" {
124 10
		currentServer = `All servers`
125
	}
126 10
	ul.WriteString(`<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">`)
127 10
	ul.WriteString(currentServer)
128 10
	ul.WriteString(` <span class="caret"></span></a><ul class="dropdown-menu">`)
129
	for _, addr := range selfConf.Servers {
130 10
		if addr == currentServer {
131 10
			continue
132
		}
133 10
		ul.WriteString(`<li><a href="./server?server=`)
134 10
		ul.WriteString(addr)
135 10
		ul.WriteString(`">`)
136 10
		ul.WriteString(addr)
137 10
		ul.WriteString(`</a></li>`)
138
	}
139 10
	if currentServer != "All servers" {
140 10
		ul.WriteString(`<li><a href="./public">All servers</a></li>`)
141
	}
142 10
	ul.WriteString(`</ul></li>`)
143 10
	return ul.String()
144
}
145

146
// dropDownTube render a navigation dropdown menu for tube list.
147
func dropDownTube(server string, currentTube string) string {
148 10
	var ul strings.Builder
149 10
	if currentTube == "" {
150 10
		currentTube = `All tubes`
151
	}
152 10
	ul.WriteString(`<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">`)
153 10
	ul.WriteString(currentTube)
154 10
	ul.WriteString(` <span class="caret"></span></a><ul class="dropdown-menu">`)
155 10
	var bstkConn *beanstalk.Conn
156 10
	var err error
157 10
	if bstkConn, err = beanstalk.Dial("tcp", server); err != nil {
158 10
		if currentTube != "" {
159 10
			ul.WriteString(`<li><a href="./public">All tubes</a></li>`)
160
		}
161 10
		ul.WriteString(`</ul></li>`)
162 10
		return ul.String()
163
	}
164 10
	tubes, _ := bstkConn.ListTubes()
165 10
	sort.Strings(tubes)
166
	for _, v := range tubes {
167 10
		ul.WriteString(`<li><a href="./tube?server=`)
168 10
		ul.WriteString(server)
169 10
		ul.WriteString(`&tube=`)
170 10
		ul.WriteString(url.QueryEscape(v))
171 10
		ul.WriteString(`">`)
172 10
		ul.WriteString(v)
173 10
		ul.WriteString(`</a></li>`)
174
	}
175 10
	bstkConn.Close()
176 10
	if currentTube != "All tubes" {
177 10
		ul.WriteString(`<li><a href="./server?server=`)
178 10
		ul.WriteString(server)
179 10
		ul.WriteString(`">All tubes</a></li>`)
180
	}
181 10
	ul.WriteString(`</ul></li>`)
182 10
	return ul.String()
183
}
184

185
// dropEditSettings render a navigation dropdown menu for set preference.
186
func dropEditSettings() string {
187 10
	var buf strings.Builder
188 10
	var isDisabledJSONDecode, isDisabledJobDataHighlight, isEnabledBase64Decode string
189 10
	if selfConf.IsDisabledJSONDecode != 1 {
190 10
		isDisabledJSONDecode = `checked="checked"`
191
	}
192 10
	if selfConf.IsDisabledJobDataHighlight != 1 {
193 10
		isDisabledJobDataHighlight = `checked="checked"`
194
	}
195 10
	if selfConf.IsEnabledBase64Decode != 0 {
196 10
		isEnabledBase64Decode = `checked="checked"`
197
	}
198 10
	buf.WriteString(`<div id="settings" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="settings-label" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h4 class="modal-title" id="settings-label">Settings</h4></div><div class="modal-body"><fieldset><div class="form-group"><label for="tubePauseSeconds"><b>Tube pause seconds</b> (<i>-1</i> means the default: <i>3600</i>, <i>0</i> is reserved for un-pause)</label><input class="form-control focused" id="tubePauseSeconds" type="number" value="`)
199 10
	buf.WriteString(strconv.Itoa(selfConf.TubePauseSeconds))
200 10
	buf.WriteString(`"></div><div class="form-group"><label><b>Auto-refresh interval in milliseconds</b> (Default: <i>500</i>)</label><input class="form-control focused" id="autoRefreshTimeoutMs" type="number" value="`)
201 10
	buf.WriteString(strconv.Itoa(selfConf.AutoRefreshTimeoutMs))
202 10
	buf.WriteString(`"></div><div class="form-group"><label><b>Search result limits</b> (Default: <i>25</i>)</label><input class="form-control focused" id="searchResultLimit" type="number" value="`)
203 10
	buf.WriteString(strconv.Itoa(selfConf.SearchResultLimit))
204 10
	buf.WriteString(`"></div><div class="form-group"><label><b>Preferred way to deal with job data</b></label><div class="checkbox"><label><input type="checkbox" id="isDisabledJsonDecode" value="1" `)
205 10
	buf.WriteString(isDisabledJSONDecode)
206 10
	buf.WriteString(`>before display: JSON decode</label></div><div class="checkbox"><label><input type="checkbox" id="isEnabledBase64Decode" value="1" `)
207 10
	buf.WriteString(isEnabledBase64Decode)
208 10
	buf.WriteString(`>before display: Base64 decode</label></div><div class="checkbox"><label><input type="checkbox" id="isDisabledJobDataHighlight" value="1" `)
209 10
	buf.WriteString(isDisabledJobDataHighlight)
210 10
	buf.WriteString(`>after display: enable highlight</label></div></div></fieldset></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">Close</button></div></div></div></div>`)
211 10
	return buf.String()
212
}

Read our documentation on viewing source code .

Loading