wrapper.go 6.9 KB

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