wrapper.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package wrapper
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "html/template"
  7. "net/http"
  8. "os"
  9. "path/filepath"
  10. "strconv"
  11. "strings"
  12. "time"
  13. "golang-fave/cblocks"
  14. "golang-fave/consts"
  15. "golang-fave/engine/mysqlpool"
  16. "golang-fave/engine/sqlw"
  17. "golang-fave/logger"
  18. "golang-fave/utils"
  19. "github.com/vladimirok5959/golang-server-sessions/session"
  20. )
  21. type Tx = sqlw.Tx
  22. var ErrNoRows = sqlw.ErrNoRows
  23. type Wrapper struct {
  24. l *logger.Logger
  25. W http.ResponseWriter
  26. R *http.Request
  27. S *session.Session
  28. c *cblocks.CacheBlocks
  29. Host string
  30. Port string
  31. CurrHost string
  32. DConfig string
  33. DHtdocs string
  34. DLogs string
  35. DTemplate string
  36. DTmp string
  37. IsBackend bool
  38. ConfMysqlExists bool
  39. UrlArgs []string
  40. CurrModule string
  41. CurrSubModule string
  42. MSPool *mysqlpool.MySqlPool
  43. Config *Config
  44. DB *sqlw.DB
  45. User *utils.MySql_user
  46. }
  47. func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, c *cblocks.CacheBlocks, host, port, chost, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string, mp *mysqlpool.MySqlPool) *Wrapper {
  48. conf := configNew()
  49. if err := conf.configRead(dirConfig + string(os.PathSeparator) + "config.json"); err != nil {
  50. l.Log("Host config file: %s", r, true, err.Error())
  51. }
  52. return &Wrapper{
  53. l: l,
  54. W: w,
  55. R: r,
  56. S: s,
  57. c: c,
  58. Host: host,
  59. Port: port,
  60. CurrHost: chost,
  61. DConfig: dirConfig,
  62. DHtdocs: dirHtdocs,
  63. DLogs: dirLogs,
  64. DTemplate: dirTemplate,
  65. DTmp: dirTmp,
  66. UrlArgs: []string{},
  67. CurrModule: "",
  68. CurrSubModule: "",
  69. MSPool: mp,
  70. Config: conf,
  71. }
  72. }
  73. func (this *Wrapper) LogAccess(msg string, vars ...interface{}) {
  74. this.l.Log(msg, this.R, false, vars...)
  75. }
  76. func (this *Wrapper) LogError(msg string, vars ...interface{}) {
  77. this.l.Log(msg, this.R, true, vars...)
  78. }
  79. func (this *Wrapper) dbReconnect() error {
  80. if !utils.IsMySqlConfigExists(this.DConfig + string(os.PathSeparator) + "mysql.json") {
  81. return errors.New("can't read database configuration file")
  82. }
  83. mc, err := utils.MySqlConfigRead(this.DConfig + string(os.PathSeparator) + "mysql.json")
  84. if err != nil {
  85. return err
  86. }
  87. this.DB, err = sqlw.Open("mysql", mc.User+":"+mc.Password+"@tcp("+mc.Host+":"+mc.Port+")/"+mc.Name)
  88. if err != nil {
  89. return err
  90. }
  91. this.MSPool.Set(this.CurrHost, this.DB)
  92. return nil
  93. }
  94. func (this *Wrapper) UseDatabase() error {
  95. this.DB = this.MSPool.Get(this.CurrHost)
  96. if this.DB == nil {
  97. if err := this.dbReconnect(); err != nil {
  98. return err
  99. }
  100. }
  101. if err := this.DB.Ping(); err != nil {
  102. this.DB.Close()
  103. if err := this.dbReconnect(); err != nil {
  104. return err
  105. }
  106. if err := this.DB.Ping(); err != nil {
  107. this.DB.Close()
  108. return err
  109. }
  110. }
  111. // Max 60 minutes and max 2 connection per host
  112. this.DB.SetConnMaxLifetime(time.Minute * 60)
  113. this.DB.SetMaxIdleConns(2)
  114. this.DB.SetMaxOpenConns(2)
  115. return nil
  116. }
  117. func (this *Wrapper) LoadSessionUser() bool {
  118. if this.S.GetInt("UserId", 0) <= 0 {
  119. return false
  120. }
  121. if this.DB == nil {
  122. return false
  123. }
  124. user := &utils.MySql_user{}
  125. err := this.DB.QueryRow(`
  126. SELECT
  127. id,
  128. first_name,
  129. last_name,
  130. email,
  131. password,
  132. admin,
  133. active
  134. FROM
  135. users
  136. WHERE
  137. id = ?
  138. LIMIT 1;`,
  139. this.S.GetInt("UserId", 0),
  140. ).Scan(
  141. &user.A_id,
  142. &user.A_first_name,
  143. &user.A_last_name,
  144. &user.A_email,
  145. &user.A_password,
  146. &user.A_admin,
  147. &user.A_active,
  148. )
  149. if err != nil {
  150. return false
  151. }
  152. if user.A_id != this.S.GetInt("UserId", 0) {
  153. return false
  154. }
  155. this.User = user
  156. return true
  157. }
  158. func (this *Wrapper) Write(data string) {
  159. this.W.Write([]byte(data))
  160. }
  161. func (this *Wrapper) MsgSuccess(msg string) {
  162. this.Write(fmt.Sprintf(
  163. `fave.ShowMsgSuccess('Success!', '%s', false);`,
  164. utils.JavaScriptVarValue(msg)))
  165. }
  166. func (this *Wrapper) MsgError(msg string) {
  167. this.Write(fmt.Sprintf(
  168. `fave.ShowMsgError('Error!', '%s', true);`,
  169. utils.JavaScriptVarValue(msg)))
  170. }
  171. func (this *Wrapper) RenderToString(tcont []byte, data interface{}) string {
  172. tmpl, err := template.New("template").Parse(string(tcont))
  173. if err != nil {
  174. return err.Error()
  175. }
  176. var tpl bytes.Buffer
  177. if err := tmpl.Execute(&tpl, data); err != nil {
  178. return err.Error()
  179. }
  180. return tpl.String()
  181. }
  182. func (this *Wrapper) RenderFrontEnd(tname string, data interface{}, status int) {
  183. tmpl, err := template.New(tname+".html").Funcs(utils.TemplateAdditionalFuncs()).ParseFiles(
  184. this.DTemplate+string(os.PathSeparator)+tname+".html",
  185. this.DTemplate+string(os.PathSeparator)+"header.html",
  186. this.DTemplate+string(os.PathSeparator)+"sidebar-left.html",
  187. this.DTemplate+string(os.PathSeparator)+"sidebar-right.html",
  188. this.DTemplate+string(os.PathSeparator)+"footer.html",
  189. )
  190. if err != nil {
  191. utils.SystemErrorPageTemplate(this.W, err)
  192. return
  193. }
  194. var tpl bytes.Buffer
  195. err = tmpl.Execute(&tpl, consts.TmplData{
  196. System: utils.GetTmplSystemData("", ""),
  197. Data: data,
  198. })
  199. if err != nil {
  200. utils.SystemErrorPageTemplate(this.W, err)
  201. return
  202. }
  203. this.W.WriteHeader(status)
  204. this.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  205. this.W.Header().Set("Content-Type", "text/html; charset=utf-8")
  206. this.W.Write(tpl.Bytes())
  207. }
  208. func (this *Wrapper) RenderBackEnd(tcont []byte, data interface{}) {
  209. tmpl, err := template.New("template").Parse(string(tcont))
  210. if err != nil {
  211. utils.SystemErrorPageEngine(this.W, err)
  212. return
  213. }
  214. this.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  215. this.W.Header().Set("Content-Type", "text/html; charset=utf-8")
  216. var tpl bytes.Buffer
  217. err = tmpl.Execute(this.W, consts.TmplData{
  218. System: utils.GetTmplSystemData(this.CurrModule, this.CurrSubModule),
  219. Data: data,
  220. })
  221. if err != nil {
  222. utils.SystemErrorPageEngine(this.W, err)
  223. return
  224. }
  225. this.W.Write(tpl.Bytes())
  226. }
  227. func (this *Wrapper) GetCurrentPage(max int) int {
  228. curr := 1
  229. page := this.R.URL.Query().Get("p")
  230. if page != "" {
  231. if i, err := strconv.Atoi(page); err == nil {
  232. if i < 1 {
  233. curr = 1
  234. } else if i > max {
  235. curr = max
  236. } else {
  237. curr = i
  238. }
  239. }
  240. }
  241. return curr
  242. }
  243. func (this *Wrapper) ConfigSave() error {
  244. return this.Config.configWrite(this.DConfig + string(os.PathSeparator) + "config.json")
  245. }
  246. func (this *Wrapper) RemoveProductImageThumbnails(product_id, filename string) error {
  247. pattern := this.DHtdocs + string(os.PathSeparator) + strings.Join([]string{"products", "images", product_id, filename}, string(os.PathSeparator))
  248. if files, err := filepath.Glob(pattern); err != nil {
  249. return err
  250. } else {
  251. for _, file := range files {
  252. if err := os.Remove(file); err != nil {
  253. return errors.New(fmt.Sprintf("[upload delete] Thumbnail file (%s) delete error: %s", file, err.Error()))
  254. }
  255. }
  256. }
  257. return nil
  258. }
  259. func (this *Wrapper) RemoveProductXmlCacheFile() error {
  260. return os.Remove(this.DHtdocs + string(os.PathSeparator) + "products.xml")
  261. }