smtp.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package main
  2. import (
  3. "fmt"
  4. "html"
  5. "io/ioutil"
  6. "os"
  7. "strings"
  8. "time"
  9. "golang-fave/engine/mysqlpool"
  10. "golang-fave/engine/sqlw"
  11. "golang-fave/engine/wrapper/config"
  12. "golang-fave/utils"
  13. )
  14. func smtp_send(host, port, user, pass, subject, msg string, receivers []string) error {
  15. return utils.SMTPSend(host, port, user, pass, subject, msg, receivers)
  16. }
  17. func smtp_prepare(db *sqlw.DB, conf *config.Config) {
  18. rows, err := db.Query(
  19. `SELECT
  20. id,
  21. email,
  22. subject,
  23. message
  24. FROM
  25. notify_mail
  26. WHERE
  27. status = 2
  28. ORDER BY
  29. id ASC
  30. ;`,
  31. )
  32. if err == nil {
  33. defer rows.Close()
  34. values := make([]string, 4)
  35. scan := make([]interface{}, len(values))
  36. for i := range values {
  37. scan[i] = &values[i]
  38. }
  39. for rows.Next() {
  40. err = rows.Scan(scan...)
  41. if err == nil {
  42. if _, err := db.Exec(
  43. `UPDATE notify_mail SET status = 3 WHERE id = ?;`,
  44. utils.StrToInt(string(values[0])),
  45. ); err == nil {
  46. go func(db *sqlw.DB, conf *config.Config, id int, subject, msg string, receivers []string) {
  47. if err := smtp_send(
  48. (*conf).SMTP.Host,
  49. utils.IntToStr((*conf).SMTP.Port),
  50. (*conf).SMTP.Login,
  51. (*conf).SMTP.Password,
  52. subject,
  53. msg,
  54. receivers,
  55. ); err == nil {
  56. if _, err := db.Exec(
  57. `UPDATE notify_mail SET status = 1 WHERE id = ?;`,
  58. id,
  59. ); err != nil {
  60. fmt.Printf("Smtp send error (sql, success): %v\n", err)
  61. }
  62. } else {
  63. if _, err := db.Exec(
  64. `UPDATE notify_mail SET error = ?, status = 0 WHERE id = ?;`,
  65. err.Error(),
  66. id,
  67. ); err != nil {
  68. fmt.Printf("Smtp send error (sql, error): %v\n", err)
  69. }
  70. }
  71. }(
  72. db,
  73. conf,
  74. utils.StrToInt(string(values[0])),
  75. html.EscapeString(string(values[2])),
  76. string(values[3]),
  77. []string{html.EscapeString(string(values[1]))},
  78. )
  79. } else {
  80. fmt.Printf("Smtp send error (sql, update): %v\n", err)
  81. }
  82. }
  83. }
  84. }
  85. }
  86. func smtp_process(dir, host string, mp *mysqlpool.MySqlPool) {
  87. db := mp.Get(host)
  88. if db != nil {
  89. conf := config.ConfigNew()
  90. if err := conf.ConfigRead(strings.Join([]string{dir, "config", "config.json"}, string(os.PathSeparator))); err == nil {
  91. if (*conf).SMTP.Host != "" && (*conf).SMTP.Login != "" && (*conf).SMTP.Password != "" {
  92. if err := db.Ping(); err == nil {
  93. smtp_prepare(db, conf)
  94. }
  95. }
  96. } else {
  97. fmt.Printf("Smtp error (config): %v\n", err)
  98. }
  99. }
  100. }
  101. func smtp_loop(www_dir string, stop chan bool, mp *mysqlpool.MySqlPool) {
  102. dirs, err := ioutil.ReadDir(www_dir)
  103. if err == nil {
  104. for _, dir := range dirs {
  105. select {
  106. case <-stop:
  107. break
  108. default:
  109. if mp != nil {
  110. target_dir := strings.Join([]string{www_dir, dir.Name()}, string(os.PathSeparator))
  111. if utils.IsDirExists(target_dir) {
  112. smtp_process(target_dir, dir.Name(), mp)
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. func smtp_start(www_dir string, mp *mysqlpool.MySqlPool) (chan bool, chan bool) {
  120. ch := make(chan bool)
  121. stop := make(chan bool)
  122. go func() {
  123. for {
  124. select {
  125. case <-time.After(5 * time.Second):
  126. // Run every 5 seconds
  127. smtp_loop(www_dir, stop, mp)
  128. case <-ch:
  129. ch <- true
  130. return
  131. }
  132. }
  133. }()
  134. return ch, stop
  135. }
  136. func smtp_stop(ch, stop chan bool) {
  137. for {
  138. select {
  139. case stop <- true:
  140. case ch <- true:
  141. <-ch
  142. return
  143. case <-time.After(3 * time.Second):
  144. fmt.Println("Smtp error: force exit by timeout after 3 seconds")
  145. return
  146. }
  147. }
  148. }