Commit 3173b06a417a52edf5649e2234eaf09359a768f1

Authored by Marko Tikvić
1 parent a8f0d5a63e
Exists in master

SplitString()

Showing 2 changed files with 22 additions and 0 deletions   Show diff stats
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "fmt" 5 "fmt"
6 "net/http" 6 "net/http"
7 ) 7 )
8 8
9 // StatusRecorder ... 9 // StatusRecorder ...
10 type StatusRecorder struct { 10 type StatusRecorder struct {
11 writer http.ResponseWriter 11 writer http.ResponseWriter
12 status int 12 status int
13 size int 13 size int
14 } 14 }
15 15
16 // NewStatusRecorder ... 16 // NewStatusRecorder ...
17 func NewStatusRecorder(w http.ResponseWriter) *StatusRecorder { 17 func NewStatusRecorder(w http.ResponseWriter) *StatusRecorder {
18 return &StatusRecorder{ 18 return &StatusRecorder{
19 writer: w, 19 writer: w,
20 status: 0, 20 status: 0,
21 size: 0, 21 size: 0,
22 } 22 }
23 } 23 }
24 24
25 // WriteHeader is a wrapper http.ResponseWriter interface 25 // WriteHeader is a wrapper http.ResponseWriter interface
26 func (r *StatusRecorder) WriteHeader(code int) { 26 func (r *StatusRecorder) WriteHeader(code int) {
27 r.status = code 27 r.status = code
28 r.writer.WriteHeader(code) 28 r.writer.WriteHeader(code)
29 } 29 }
30 30
31 // Write is a wrapper for http.ResponseWriter interface 31 // Write is a wrapper for http.ResponseWriter interface
32 func (r *StatusRecorder) Write(in []byte) (int, error) { 32 func (r *StatusRecorder) Write(in []byte) (int, error) {
33 r.size = len(in) 33 r.size = len(in)
34 return r.writer.Write(in) 34 return r.writer.Write(in)
35 } 35 }
36 36
37 // Header is a wrapper for http.ResponseWriter interface 37 // Header is a wrapper for http.ResponseWriter interface
38 func (r *StatusRecorder) Header() http.Header { 38 func (r *StatusRecorder) Header() http.Header {
39 return r.writer.Header() 39 return r.writer.Header()
40 } 40 }
41 41
42 // Status ... 42 // Status ...
43 func (r *StatusRecorder) Status() int { 43 func (r *StatusRecorder) Status() int {
44 return r.status 44 return r.status
45 } 45 }
46 46
47 // Size ... 47 // Size ...
48 func (r *StatusRecorder) Size() int { 48 func (r *StatusRecorder) Size() int {
49 return r.size 49 return r.size
50 } 50 }
51 51
52 // NotFoundHandlerFunc writes HTTP error 404 to w. 52 // NotFoundHandlerFunc writes HTTP error 404 to w.
53 func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) { 53 func NotFoundHandlerFunc(w http.ResponseWriter, req *http.Request) {
54 SetAccessControlHeaders(w) 54 SetAccessControlHeaders(w)
55 SetContentType(w, "application/json") 55 SetContentType(w, "application/json")
56 NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String())) 56 NotFound(w, req, fmt.Sprintf("Resource you requested was not found: %s", req.URL.String()))
57 } 57 }
58 58
59 // SetContentType must be called before SetResponseStatus (w.WriteHeader) (?) 59 // SetContentType must be called before SetResponseStatus (w.WriteHeader) (?)
60 func SetContentType(w http.ResponseWriter, ctype string) { 60 func SetContentType(w http.ResponseWriter, ctype string) {
61 w.Header().Set("Content-Type", ctype) 61 w.Header().Set("Content-Type", ctype)
62 } 62 }
63 63
64 // SetResponseStatus ... 64 // SetResponseStatus ...
65 func SetResponseStatus(w http.ResponseWriter, status int) { 65 func SetResponseStatus(w http.ResponseWriter, status int) {
66 w.WriteHeader(status) 66 w.WriteHeader(status)
67 } 67 }
68 68
69 // WriteResponse ... 69 // WriteResponse ...
70 func WriteResponse(w http.ResponseWriter, content []byte) { 70 func WriteResponse(w http.ResponseWriter, content []byte) {
71 w.Write(content) 71 w.Write(content)
72 } 72 }
73 73
74 // SetAccessControlHeaders set's default headers for an HTTP response. 74 // SetAccessControlHeaders set's default headers for an HTTP response.
75 func SetAccessControlHeaders(w http.ResponseWriter) { 75 func SetAccessControlHeaders(w http.ResponseWriter) {
76 w.Header().Set("Access-Control-Allow-Origin", "*") 76 w.Header().Set("Access-Control-Allow-Origin", "*")
77 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS") 77 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
78 w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") 78 w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
79 } 79 }
80 80
81 // GetLocale ... 81 // GetLocale ...
82 func GetLocale(req *http.Request, dflt string) string { 82 func GetLocale(req *http.Request, dflt string) string {
83 loc := req.FormValue("locale") 83 loc := req.FormValue("locale")
84 if loc == "" { 84 if loc == "" {
85 return dflt 85 return dflt
86 } 86 }
87 return loc 87 return loc
88 } 88 }
89 89
90 // Success ... 90 // Success ...
91 func Success(w http.ResponseWriter, payload interface{}, code int) { 91 func Success(w http.ResponseWriter, payload interface{}, code int) {
92 w.WriteHeader(code) 92 w.WriteHeader(code)
93 if payload != nil { 93 if payload != nil {
94 json.NewEncoder(w).Encode(payload) 94 json.NewEncoder(w).Encode(payload)
95 } 95 }
96 } 96 }
97 97
98 // OK ... 98 // OK ...
99 func OK(w http.ResponseWriter, payload interface{}) { 99 func OK(w http.ResponseWriter, payload interface{}) {
100 SetContentType(w, "application/json") 100 SetContentType(w, "application/json")
101 Success(w, payload, http.StatusOK) 101 Success(w, payload, http.StatusOK)
102 } 102 }
103 103
104 // Created ... 104 // Created ...
105 func Created(w http.ResponseWriter, payload interface{}) { 105 func Created(w http.ResponseWriter, payload interface{}) {
106 SetContentType(w, "application/json") 106 SetContentType(w, "application/json")
107 Success(w, payload, http.StatusCreated) 107 Success(w, payload, http.StatusCreated)
108 } 108 }
109 109
110 type weberror struct { 110 type weberror struct {
111 Request string `json:"request"` 111 Request string `json:"request"`
112 Error string `json:"error"` 112 Error string `json:"error"`
113 } 113 }
114 114
115 // Error ... 115 // Error ...
116 func Error(w http.ResponseWriter, r *http.Request, code int, err string) { 116 func Error(w http.ResponseWriter, r *http.Request, code int, err string) {
117 werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI} 117 werr := weberror{Error: err, Request: r.Method + " " + r.RequestURI}
118 w.WriteHeader(code) 118 w.WriteHeader(code)
119 json.NewEncoder(w).Encode(werr) 119 json.NewEncoder(w).Encode(werr)
120 } 120 }
121 121
122 // BadRequest ... 122 // BadRequest ...
123 func BadRequest(w http.ResponseWriter, r *http.Request, err string) { 123 func BadRequest(w http.ResponseWriter, r *http.Request, err string) {
124 SetContentType(w, "application/json") 124 SetContentType(w, "application/json")
125 Error(w, r, http.StatusBadRequest, err) 125 Error(w, r, http.StatusBadRequest, err)
126 } 126 }
127 127
128 // Unauthorized ... 128 // Unauthorized ...
129 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) { 129 func Unauthorized(w http.ResponseWriter, r *http.Request, err string) {
130 SetContentType(w, "application/json") 130 SetContentType(w, "application/json")
131 Error(w, r, http.StatusUnauthorized, err) 131 Error(w, r, http.StatusUnauthorized, err)
132 } 132 }
133 133
134 // Forbidden ... 134 // Forbidden ...
135 func Forbidden(w http.ResponseWriter, r *http.Request, err string) { 135 func Forbidden(w http.ResponseWriter, r *http.Request, err string) {
136 SetContentType(w, "application/json") 136 SetContentType(w, "application/json")
137 Error(w, r, http.StatusForbidden, err) 137 Error(w, r, http.StatusForbidden, err)
138 } 138 }
139 139
140 // NotFound ... 140 // NotFound ...
141 func NotFound(w http.ResponseWriter, r *http.Request, err string) { 141 func NotFound(w http.ResponseWriter, r *http.Request, err string) {
142 SetContentType(w, "application/json") 142 SetContentType(w, "application/json")
143 Error(w, r, http.StatusNotFound, err) 143 Error(w, r, http.StatusNotFound, err)
144 } 144 }
145 145
146 // Conflict ... 146 // Conflict ...
147 func Conflict(w http.ResponseWriter, r *http.Request, err string) { 147 func Conflict(w http.ResponseWriter, r *http.Request, err string) {
148 SetContentType(w, "application/json") 148 SetContentType(w, "application/json")
149 Error(w, r, http.StatusConflict, err) 149 Error(w, r, http.StatusConflict, err)
150 } 150 }
151 151
152 // InternalServerError ... 152 // InternalServerError ...
153 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) { 153 func InternalServerError(w http.ResponseWriter, r *http.Request, err string) {
154 SetContentType(w, "application/json") 154 SetContentType(w, "application/json")
155 Error(w, r, http.StatusInternalServerError, err) 155 Error(w, r, http.StatusInternalServerError, err)
156 } 156 }
157
158 func SetHeader(r *http.Request, key, val string) {
159 r.Header.Set(key, val)
160 }
161
162 func AddHeader(r *http.Request, key, val string) {
163 r.Header.Add(key, val)
164 }
165
166 func GetHeader(r *http.Request, key string) string {
167 return r.Header.Get(key)
168 }
157 169
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "strconv" 5 "strconv"
6 "strings" 6 "strings"
7 "unicode" 7 "unicode"
8 ) 8 )
9 9
10 const sanitisationPatern = "\"';&*<>=\\`:" 10 const sanitisationPatern = "\"';&*<>=\\`:"
11 11
12 // SanitiseString removes characters from s found in patern and returns new modified string. 12 // SanitiseString removes characters from s found in patern and returns new modified string.
13 func SanitiseString(s string) string { 13 func SanitiseString(s string) string {
14 return ReplaceAny(s, sanitisationPatern, "") 14 return ReplaceAny(s, sanitisationPatern, "")
15 } 15 }
16 16
17 // IsWrappedWith ... 17 // IsWrappedWith ...
18 func IsWrappedWith(src, begin, end string) bool { 18 func IsWrappedWith(src, begin, end string) bool {
19 return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end) 19 return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end)
20 } 20 }
21 21
22 // ParseInt64Arr ... 22 // ParseInt64Arr ...
23 func ParseInt64Arr(s, sep string) (arr []int64) { 23 func ParseInt64Arr(s, sep string) (arr []int64) {
24 s = strings.TrimSpace(s) 24 s = strings.TrimSpace(s)
25 if s != "" { 25 if s != "" {
26 parts := strings.Split(s, sep) 26 parts := strings.Split(s, sep)
27 arr = make([]int64, len(parts)) 27 arr = make([]int64, len(parts))
28 for i, p := range parts { 28 for i, p := range parts {
29 num := StringToInt64(p) 29 num := StringToInt64(p)
30 arr[i] = num 30 arr[i] = num
31 } 31 }
32 } 32 }
33 33
34 return arr 34 return arr
35 } 35 }
36 36
37 // Int64SliceToString ... 37 // Int64SliceToString ...
38 func Int64SliceToString(arr []int64) (s string) { 38 func Int64SliceToString(arr []int64) (s string) {
39 if len(arr) == 0 { 39 if len(arr) == 0 {
40 return "" 40 return ""
41 } 41 }
42 42
43 s += fmt.Sprintf("%d", arr[0]) 43 s += fmt.Sprintf("%d", arr[0])
44 for i := 1; i < len(arr); i++ { 44 for i := 1; i < len(arr); i++ {
45 s += fmt.Sprintf(",%d", arr[i]) 45 s += fmt.Sprintf(",%d", arr[i])
46 } 46 }
47 47
48 return s 48 return s
49 } 49 }
50 50
51 // CombineStrings ... 51 // CombineStrings ...
52 func CombineStrings(s1, s2, s3 string) string { 52 func CombineStrings(s1, s2, s3 string) string {
53 s1 = strings.TrimSpace(s1) 53 s1 = strings.TrimSpace(s1)
54 s2 = strings.TrimSpace(s2) 54 s2 = strings.TrimSpace(s2)
55 55
56 if s1 != "" && s2 != "" { 56 if s1 != "" && s2 != "" {
57 s1 += s3 + s2 57 s1 += s3 + s2
58 } else { 58 } else {
59 s1 += s2 59 s1 += s2
60 } 60 }
61 61
62 return s1 62 return s1
63 } 63 }
64 64
65 // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string. 65 // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string.
66 func ReplaceAny(s, patern, r string) (n string) { 66 func ReplaceAny(s, patern, r string) (n string) {
67 n = s 67 n = s
68 for _, c := range patern { 68 for _, c := range patern {
69 n = strings.Replace(n, string(c), r, -1) 69 n = strings.Replace(n, string(c), r, -1)
70 } 70 }
71 return n 71 return n
72 } 72 }
73 73
74 // StringToBool ... 74 // StringToBool ...
75 func StringToBool(s string) bool { 75 func StringToBool(s string) bool {
76 res, _ := strconv.ParseBool(s) 76 res, _ := strconv.ParseBool(s)
77 return res 77 return res
78 } 78 }
79 79
80 // BoolToString ... 80 // BoolToString ...
81 func BoolToString(b bool) string { 81 func BoolToString(b bool) string {
82 return fmt.Sprintf("%b", b) 82 return fmt.Sprintf("%b", b)
83 } 83 }
84 84
85 // StringSliceContains ... 85 // StringSliceContains ...
86 func StringSliceContains(slice []string, s string) bool { 86 func StringSliceContains(slice []string, s string) bool {
87 for i := range slice { 87 for i := range slice {
88 if slice[i] == s { 88 if slice[i] == s {
89 return true 89 return true
90 } 90 }
91 } 91 }
92 return false 92 return false
93 } 93 }
94 94
95 func SplitString(s, sep string) (res []string) {
96 parts := strings.Split(s, sep)
97 for _, p := range parts {
98 if p != "" {
99 res = append(res, p)
100 }
101 }
102 return res
103 }
104
95 // StringAt ... 105 // StringAt ...
96 func StringAt(s string, index int) string { 106 func StringAt(s string, index int) string {
97 if len(s)-1 < index || index < 0 { 107 if len(s)-1 < index || index < 0 {
98 return "" 108 return ""
99 } 109 }
100 110
101 return string(s[index]) 111 return string(s[index])
102 } 112 }
103 113
104 // SplitText ... 114 // SplitText ...
105 func SplitText(s string, maxLen int) (lines []string) { 115 func SplitText(s string, maxLen int) (lines []string) {
106 runes := []rune(s) 116 runes := []rune(s)
107 117
108 i, start, sep, l := 0, 0, 0, 0 118 i, start, sep, l := 0, 0, 0, 0
109 for i = 0; i < len(runes); i++ { 119 for i = 0; i < len(runes); i++ {
110 c := runes[i] 120 c := runes[i]
111 121
112 if unicode.IsSpace(c) { 122 if unicode.IsSpace(c) {
113 sep = i 123 sep = i
114 } 124 }
115 125
116 if c == '\n' { 126 if c == '\n' {
117 if start != sep { 127 if start != sep {
118 lines = append(lines, string(runes[start:sep])) 128 lines = append(lines, string(runes[start:sep]))
119 } 129 }
120 start = i 130 start = i
121 sep = i 131 sep = i
122 l = 0 132 l = 0
123 } else if l >= maxLen { 133 } else if l >= maxLen {
124 if start != sep { 134 if start != sep {
125 lines = append(lines, string(runes[start:sep])) 135 lines = append(lines, string(runes[start:sep]))
126 sep = i 136 sep = i
127 start = i - 1 137 start = i - 1
128 l = 0 138 l = 0
129 } 139 }
130 } else { 140 } else {
131 l++ 141 l++
132 } 142 }
133 } 143 }
134 if start != i-1 { 144 if start != i-1 {
135 lines = append(lines, string(runes[start:i-1])) 145 lines = append(lines, string(runes[start:i-1]))
136 } 146 }
137 147
138 return lines 148 return lines
139 } 149 }
140 150
141 const threeDots = "\u2056\u2056\u2056" 151 const threeDots = "\u2056\u2056\u2056"
142 152
143 func LimitTextWithThreeDots(txt string, maxLen int) string { 153 func LimitTextWithThreeDots(txt string, maxLen int) string {
144 if len(txt) <= maxLen { 154 if len(txt) <= maxLen {
145 return txt 155 return txt
146 } 156 }
147 157
148 return txt[:maxLen] + threeDots 158 return txt[:maxLen] + threeDots
149 } 159 }
150 160
151 // SplitStringAtWholeWords ... 161 // SplitStringAtWholeWords ...
152 func SplitStringAtWholeWords(s string, maxLen int) (res []string) { 162 func SplitStringAtWholeWords(s string, maxLen int) (res []string) {
153 parts := strings.Split(s, " ") 163 parts := strings.Split(s, " ")
154 164
155 res = append(res, parts[0]) 165 res = append(res, parts[0])
156 i := 0 166 i := 0
157 for j := 1; j < len(parts); j++ { 167 for j := 1; j < len(parts); j++ {
158 p := strings.TrimSpace(parts[j]) 168 p := strings.TrimSpace(parts[j])
159 if len(p) > maxLen { 169 if len(p) > maxLen {
160 // TODO(marko): check if maxLen is >= 3 170 // TODO(marko): check if maxLen is >= 3
161 p = p[0 : maxLen-3] 171 p = p[0 : maxLen-3]
162 p += "..." 172 p += "..."
163 } 173 }
164 if len(res[i])+len(p)+1 <= maxLen { 174 if len(res[i])+len(p)+1 <= maxLen {
165 res[i] += " " + p 175 res[i] += " " + p
166 } else { 176 } else {
167 res = append(res, p) 177 res = append(res, p)
168 i++ 178 i++
169 } 179 }
170 } 180 }
171 181
172 return res 182 return res
173 } 183 }
174 184