You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
5.2 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package main
  2. import (
  3. "crypto/tls"
  4. "flag"
  5. "fmt"
  6. "goqdpmbot/events_alerter"
  7. "goqdpmbot/works"
  8. "os"
  9. "path"
  10. "path/filepath"
  11. // "runtime"
  12. // "strconv"
  13. "strings"
  14. "sync"
  15. "time"
  16. "github.com/mattn/go-xmpp"
  17. "gopkg.in/ini.v1"
  18. )
  19. type cfgStruct struct {
  20. srv string
  21. usr string
  22. pwd string
  23. dest string
  24. notls bool
  25. }
  26. type commandMsg struct {
  27. remote string
  28. message string
  29. }
  30. func serverName(host string) string {
  31. return strings.Split(host, ":")[0]
  32. }
  33. func cfgRead(CfgFile string) cfgStruct {
  34. dir, dir_err := filepath.Abs(filepath.Dir(os.Args[0]))
  35. var ret cfgStruct
  36. if dir_err != nil {
  37. fmt.Printf("fail to open dir: %v", dir_err)
  38. }
  39. cfg, cfg_err := ini.Load(path.Join(dir, CfgFile))
  40. if cfg_err != nil {
  41. fmt.Printf("Fail to read file: %v", cfg_err)
  42. os.Exit(1)
  43. }
  44. cfg_notls, _ := cfg.Section("").Key("notls").Bool()
  45. ret.srv = cfg.Section("").Key("server").String()
  46. ret.usr = cfg.Section("").Key("username").String()
  47. ret.pwd = cfg.Section("").Key("password").String()
  48. ret.notls = cfg_notls
  49. ret.dest = cfg.Section("").Key("dest").String()
  50. return ret
  51. }
  52. func jabberClient(cfg cfgStruct) *xmpp.Client {
  53. var server = flag.String("server", cfg.srv, "server")
  54. var username = flag.String("username", cfg.usr, "username")
  55. var password = flag.String("password", cfg.pwd, "password")
  56. var status = flag.String("status", "xa", "status")
  57. var statusMessage = flag.String("status-msg", "", "")
  58. var notls = flag.Bool("notls", cfg.notls, "No TLS")
  59. var debug = flag.Bool("debug", false, "debug output")
  60. var session = flag.Bool("session", false, "use server session")
  61. flag.Usage = func() {
  62. fmt.Fprintf(os.Stderr, "usage: example [options]\n")
  63. flag.PrintDefaults()
  64. os.Exit(2)
  65. }
  66. flag.Parse()
  67. if *username == "" || *password == "" {
  68. if *debug && *username == "" && *password == "" {
  69. fmt.Fprintf(os.Stderr, "no username or password were given; attempting ANONYMOUS auth\n")
  70. } else if *username != "" || *password != "" {
  71. flag.Usage()
  72. }
  73. }
  74. if !*notls {
  75. xmpp.DefaultConfig = tls.Config{
  76. ServerName: serverName(*server),
  77. InsecureSkipVerify: false,
  78. }
  79. }
  80. var talk *xmpp.Client
  81. var err error
  82. options := xmpp.Options{Host: *server,
  83. User: *username,
  84. Password: *password,
  85. NoTLS: *notls,
  86. Debug: *debug,
  87. Session: *session,
  88. Status: *status,
  89. StatusMessage: *statusMessage,
  90. }
  91. talk, err = options.NewClient()
  92. if err != nil {
  93. fmt.Println(err)
  94. }
  95. return talk
  96. }
  97. // читаем из джаббера и отправляем в канал
  98. func jabberReader(talk *xmpp.Client, command chan<- commandMsg, in <-chan int) {
  99. for {
  100. chat, err := talk.Recv()
  101. if err != nil {
  102. fmt.Println(err)
  103. }
  104. switch v := chat.(type) {
  105. case xmpp.Chat:
  106. com := commandMsg{remote: v.Remote, message: v.Text}
  107. command <- com
  108. //case xmpp.Presence:
  109. // com := commandMsg{remote: v.From, message: v.Show}
  110. // command <- com
  111. }
  112. }
  113. }
  114. // отправляем ответы из канала
  115. func jabberSender(talk *xmpp.Client, msgChan <-chan commandMsg) {
  116. for {
  117. msg := <-msgChan
  118. remote := strings.Split(msg.remote, "/")[0]
  119. talk.Send(xmpp.Chat{Remote: remote, Type: "chat", Text: msg.message})
  120. }
  121. }
  122. // воркер
  123. func worker(workerNum int, msgChan <-chan commandMsg, readerClose chan int, ansChan chan<- commandMsg) {
  124. for {
  125. message := <-msgChan
  126. fmt.Println("Worker = ", workerNum, "message= ", message.message)
  127. cmd := strings.Split(message.message, " ")
  128. workMap := works.Works()
  129. _, workExists := workMap[cmd[0]]
  130. if workExists {
  131. work, _ := workMap[cmd[0]]
  132. ans, err := work.(func(...string) (string, error))(cmd[1:]...)
  133. if err != nil {
  134. ansChan <- commandMsg{remote: message.remote, message: err.Error()}
  135. } else {
  136. ansChan <- commandMsg{remote: message.remote, message: ans}
  137. }
  138. } else if len(message.message) > 0 {
  139. ans := "неизвестная комманда"
  140. ansChan <- commandMsg{remote: message.remote, message: ans}
  141. }
  142. }
  143. }
  144. //нопоминальщик
  145. func reminder(readerClose chan int, ansChan chan<- commandMsg) {
  146. for {
  147. msgSl := events_alerter.BuildAlert()
  148. fmt.Println("alerter works")
  149. fmt.Println(msgSl)
  150. for _, msgInt := range msgSl {
  151. tmpMsg := commandMsg{remote: msgInt.Remote(), message: msgInt.Message()}
  152. fmt.Println(tmpMsg)
  153. ansChan <- tmpMsg
  154. }
  155. time.Sleep(60 * time.Second)
  156. }
  157. }
  158. func main() {
  159. cfg := cfgRead("goqdpmbot.ini") // читаем конфигу
  160. goroutinesNum := 5 // количество потоков
  161. wg := &sync.WaitGroup{} // ожидаем интеррапта
  162. signal_channel := make(chan os.Signal, 1)
  163. readerClose := make(chan int, 1) // для закрытия всего зоопарка воркеров
  164. // каналы обмена инфой
  165. comChan := make(chan commandMsg, 5)
  166. ansChan := make(chan commandMsg, 5)
  167. // запускаем клиента
  168. talk := jabberClient(cfg)
  169. go jabberReader(talk, comChan, readerClose)
  170. go jabberSender(talk, ansChan)
  171. // и воркеров
  172. for i := 0; i < goroutinesNum; i++ {
  173. go worker(i, comChan, readerClose, ansChan)
  174. fmt.Println("worker started", i)
  175. }
  176. go reminder(readerClose, ansChan)
  177. // ожидаем выхода
  178. wg.Add(1)
  179. go func() {
  180. <-signal_channel
  181. wg.Done()
  182. }()
  183. wg.Wait()
  184. close(readerClose)
  185. time.Sleep(1 * time.Second)
  186. fmt.Println("interrupt")
  187. talk.Close()
  188. }

Powered by TurnKey Linux.