utils.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package utils
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "fmt"
  6. "html/template"
  7. "net/http"
  8. "os"
  9. "regexp"
  10. "strconv"
  11. "strings"
  12. "time"
  13. "unicode/utf16"
  14. "golang-fave/assets"
  15. "golang-fave/consts"
  16. )
  17. func IsFileExists(filename string) bool {
  18. if _, err := os.Stat(filename); !os.IsNotExist(err) {
  19. if err == nil {
  20. return true
  21. }
  22. }
  23. return false
  24. }
  25. func IsDir(filename string) bool {
  26. if st, err := os.Stat(filename); !os.IsNotExist(err) {
  27. if err == nil {
  28. if st.Mode().IsDir() {
  29. return true
  30. }
  31. }
  32. }
  33. return false
  34. }
  35. func IsDirExists(path string) bool {
  36. if IsFileExists(path) && IsDir(path) {
  37. return true
  38. }
  39. return false
  40. }
  41. func IsNumeric(str string) bool {
  42. if _, err := strconv.Atoi(str); err == nil {
  43. return true
  44. }
  45. return false
  46. }
  47. func IsValidEmail(email string) bool {
  48. regexpe := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
  49. return regexpe.MatchString(email)
  50. }
  51. func IsValidAlias(alias string) bool {
  52. // Control panel
  53. regexpeCP := regexp.MustCompile(`^\/cp\/`)
  54. if alias == "/cp" || regexpeCP.MatchString(alias) {
  55. return false
  56. }
  57. // Blog module
  58. regexpeBlog := regexp.MustCompile(`^\/blog\/`)
  59. if alias == "/blog" || regexpeBlog.MatchString(alias) {
  60. return false
  61. }
  62. regexpeSlash := regexp.MustCompile(`[\/]{2,}`)
  63. regexpeChars := regexp.MustCompile(`^\/([a-zA-Z0-9\/\-_\.]+)\/?$`)
  64. return (!regexpeSlash.MatchString(alias) && regexpeChars.MatchString(alias)) || alias == "/"
  65. }
  66. func IsValidSingleAlias(alias string) bool {
  67. regexpeChars := regexp.MustCompile(`^([a-zA-Z0-9\-_]{1,})$`)
  68. return regexpeChars.MatchString(alias)
  69. }
  70. func FixPath(path string) string {
  71. newPath := strings.TrimSpace(path)
  72. if len(newPath) <= 0 {
  73. return newPath
  74. }
  75. if newPath[len(newPath)-1] == '/' || newPath[len(newPath)-1] == '\\' {
  76. newPath = newPath[0 : len(newPath)-1]
  77. }
  78. return newPath
  79. }
  80. func ExtractHostPort(host string, https bool) (string, string) {
  81. h := host
  82. p := "80"
  83. if https {
  84. p = "443"
  85. }
  86. i := strings.Index(h, ":")
  87. if i > -1 {
  88. p = h[i+1:]
  89. h = h[0:i]
  90. }
  91. return h, p
  92. }
  93. func GetAssetsUrl(filename string) string {
  94. return "/" + filename + "?v=" + consts.AssetsVersion
  95. }
  96. func GetTmplSystemData() consts.TmplSystem {
  97. return consts.TmplSystem{
  98. PathIcoFav: GetAssetsUrl(consts.AssetsSysFaveIco),
  99. PathSvgLogo: GetAssetsUrl(consts.AssetsSysLogoSvg),
  100. PathCssStyles: GetAssetsUrl(consts.AssetsSysStylesCss),
  101. PathCssCpStyles: GetAssetsUrl(consts.AssetsCpStylesCss),
  102. PathCssBootstrap: GetAssetsUrl(consts.AssetsBootstrapCss),
  103. PathCssCpWysiwygPell: GetAssetsUrl(consts.AssetsCpWysiwygPellCss),
  104. PathJsJquery: GetAssetsUrl(consts.AssetsJqueryJs),
  105. PathJsPopper: GetAssetsUrl(consts.AssetsPopperJs),
  106. PathJsBootstrap: GetAssetsUrl(consts.AssetsBootstrapJs),
  107. PathJsCpScripts: GetAssetsUrl(consts.AssetsCpScriptsJs),
  108. PathJsCpWysiwygPell: GetAssetsUrl(consts.AssetsCpWysiwygPellJs),
  109. PathThemeStyles: "/assets/theme/styles.css",
  110. PathThemeScripts: "/assets/theme/scripts.js",
  111. InfoVersion: consts.ServerVersion,
  112. }
  113. }
  114. func GetTmplError(err error) consts.TmplError {
  115. return consts.TmplError{
  116. ErrorMessage: err.Error(),
  117. }
  118. }
  119. func GetMd5(str string) string {
  120. hasher := md5.New()
  121. hasher.Write([]byte(str))
  122. return hex.EncodeToString(hasher.Sum(nil))
  123. }
  124. func GetCurrentUnixTimestamp() int64 {
  125. return int64(time.Now().Unix())
  126. }
  127. func SystemRenderTemplate(w http.ResponseWriter, c []byte, d interface{}) {
  128. tmpl, err := template.New("template").Parse(string(c))
  129. if err != nil {
  130. SystemErrorPageEngine(w, err)
  131. return
  132. }
  133. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  134. w.Header().Set("Content-Type", "text/html")
  135. tmpl.Execute(w, consts.TmplData{
  136. System: GetTmplSystemData(),
  137. Data: d,
  138. })
  139. }
  140. func SystemErrorPageEngine(w http.ResponseWriter, err error) {
  141. if tmpl, e := template.New("template").Parse(string(assets.TmplPageErrorEngine)); e == nil {
  142. w.WriteHeader(http.StatusInternalServerError)
  143. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  144. w.Header().Set("Content-Type", "text/html")
  145. tmpl.Execute(w, consts.TmplData{
  146. System: GetTmplSystemData(),
  147. Data: GetTmplError(err),
  148. })
  149. return
  150. }
  151. w.WriteHeader(http.StatusInternalServerError)
  152. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  153. w.Header().Set("Content-Type", "text/html")
  154. w.Write([]byte("<h1>Critical engine error</h1>"))
  155. w.Write([]byte("<h2>" + err.Error() + "</h2>"))
  156. }
  157. func SystemErrorPageTemplate(w http.ResponseWriter, err error) {
  158. if tmpl, e := template.New("template").Parse(string(assets.TmplPageErrorTmpl)); e == nil {
  159. w.WriteHeader(http.StatusInternalServerError)
  160. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  161. w.Header().Set("Content-Type", "text/html")
  162. tmpl.Execute(w, consts.TmplData{
  163. System: GetTmplSystemData(),
  164. Data: GetTmplError(err),
  165. })
  166. return
  167. }
  168. w.WriteHeader(http.StatusInternalServerError)
  169. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  170. w.Header().Set("Content-Type", "text/html")
  171. w.Write([]byte("<h1>Critical engine error</h1>"))
  172. w.Write([]byte("<h2>" + err.Error() + "</h2>"))
  173. }
  174. func SystemErrorPage404(w http.ResponseWriter) {
  175. tmpl, err := template.New("template").Parse(string(assets.TmplPageError404))
  176. if err != nil {
  177. SystemErrorPageEngine(w, err)
  178. return
  179. }
  180. w.WriteHeader(http.StatusNotFound)
  181. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  182. w.Header().Set("Content-Type", "text/html")
  183. tmpl.Execute(w, consts.TmplData{
  184. System: GetTmplSystemData(),
  185. Data: nil,
  186. })
  187. }
  188. func UrlToArray(url string) []string {
  189. url_buff := url
  190. // Remove GET parameters
  191. i := strings.Index(url_buff, "?")
  192. if i > -1 {
  193. url_buff = url_buff[:i]
  194. }
  195. // Cut slashes
  196. if len(url_buff) >= 1 && url_buff[:1] == "/" {
  197. url_buff = url_buff[1:]
  198. }
  199. if len(url_buff) >= 1 && url_buff[len(url_buff)-1:] == "/" {
  200. url_buff = url_buff[:len(url_buff)-1]
  201. }
  202. // Explode
  203. if url_buff == "" {
  204. return []string{}
  205. } else {
  206. return strings.Split(url_buff, "/")
  207. }
  208. }
  209. func IntToStr(num int) string {
  210. return fmt.Sprintf("%d", num)
  211. }
  212. func Int64ToStr(num int64) string {
  213. return fmt.Sprintf("%d", num)
  214. }
  215. func StrToInt(str string) int {
  216. num, err := strconv.Atoi(str)
  217. if err == nil {
  218. return num
  219. }
  220. return 0
  221. }
  222. func GenerateAlias(str string) string {
  223. if str == "" {
  224. return ""
  225. }
  226. strc := utf16.Encode([]rune(str))
  227. lat := []string{"EH", "I", "i", "#", "eh", "A", "B", "V", "G", "D", "E", "JO", "ZH", "Z", "I", "JJ", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "F", "KH", "C", "CH", "SH", "SHH", "'", "Y", "", "EH", "YU", "YA", "a", "b", "v", "g", "d", "e", "jo", "zh", "z", "i", "jj", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "kh", "c", "ch", "sh", "shh", "", "y", "", "eh", "yu", "ya", "", "", "-", "-", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "-", "-", ":", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M"}
  228. cyr := []string{"Є", "І", "і", "№", "є", "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я", "а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я", "«", "»", "—", " ", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "", "", "a", "s", "d", "f", "g", "h", "j", "k", "l", "", "", "z", "x", "c", "v", "b", "n", "m", "", "", "", "(", ")", "", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M"}
  229. var alias string = ""
  230. for i := 0; i < len(strc); i++ {
  231. for j := 0; j < len(cyr); j++ {
  232. if string(strc[i]) == cyr[j] {
  233. alias += lat[j]
  234. }
  235. }
  236. }
  237. alias = strings.ToLower(alias)
  238. // Cut repeated chars "-"
  239. if reg, err := regexp.Compile("[\\-]+"); err == nil {
  240. alias = strings.Trim(reg.ReplaceAllString(alias, "-"), "-")
  241. }
  242. alias = "/" + alias + "/"
  243. // Cut repeated chars "/"
  244. if reg, err := regexp.Compile("[/]+"); err == nil {
  245. alias = reg.ReplaceAllString(alias, "/")
  246. }
  247. return alias
  248. }
  249. func GenerateSingleAlias(str string) string {
  250. alias := GenerateAlias(str)
  251. if len(alias) > 1 && alias[0] == '/' {
  252. alias = alias[1:]
  253. }
  254. if len(alias) > 1 && alias[len(alias)-1] == '/' {
  255. alias = alias[:len(alias)-1]
  256. }
  257. return alias
  258. }
  259. func UnixTimestampToMySqlDateTime(sec int64) string {
  260. return time.Unix(sec, 0).Format("2006-01-02 15:04:05")
  261. }
  262. func UnixTimestampToFormat(sec int64, format string) string {
  263. return time.Unix(sec, 0).Format(format)
  264. }
  265. func ExtractGetParams(str string) string {
  266. i := strings.Index(str, "?")
  267. if i == -1 {
  268. return ""
  269. }
  270. return "?" + str[i+1:]
  271. }
  272. func JavaScriptVarValue(str string) string {
  273. return strings.Replace(
  274. strings.Replace(str, `'`, `&rsquo;`, -1),
  275. `"`,
  276. `&rdquo;`,
  277. -1,
  278. )
  279. }
  280. func InArrayInt(slice []int, value int) bool {
  281. for _, item := range slice {
  282. if item == value {
  283. return true
  284. }
  285. }
  286. return false
  287. }
  288. func InArrayString(slice []string, value string) bool {
  289. for _, item := range slice {
  290. if item == value {
  291. return true
  292. }
  293. }
  294. return false
  295. }
  296. func GetPostArrayInt(name string, r *http.Request) []int {
  297. var ids []int
  298. if arr, ok := r.PostForm[name]; ok {
  299. for _, el := range arr {
  300. if IsNumeric(el) {
  301. if !InArrayInt(ids, StrToInt(el)) {
  302. ids = append(ids, StrToInt(el))
  303. }
  304. }
  305. }
  306. }
  307. return ids
  308. }
  309. func GetPostArrayString(name string, r *http.Request) []string {
  310. var ids []string
  311. if arr, ok := r.PostForm[name]; ok {
  312. for _, el := range arr {
  313. if !InArrayString(ids, el) {
  314. ids = append(ids, el)
  315. }
  316. }
  317. }
  318. return ids
  319. }
  320. func ArrayOfIntToArrayOfString(arr []int) []string {
  321. var res []string
  322. for _, el := range arr {
  323. res = append(res, IntToStr(el))
  324. }
  325. return res
  326. }
  327. func ArrayOfStringToArrayOfInt(arr []string) []int {
  328. var res []int
  329. for _, el := range arr {
  330. if IsNumeric(el) {
  331. res = append(res, StrToInt(el))
  332. }
  333. }
  334. return res
  335. }