|
|
- package main
-
- import (
- "crypto/tls"
- "flag"
- "fmt"
- "goqdpmbot/events_alerter"
- "goqdpmbot/works"
- "os"
- "path"
- "path/filepath"
-
- // "runtime"
- // "strconv"
- "strings"
- "sync"
- "time"
-
- "github.com/mattn/go-xmpp"
- "gopkg.in/ini.v1"
- )
-
- type cfgStruct struct {
- srv string
- usr string
- pwd string
- dest string
- notls bool
- }
-
- type commandMsg struct {
- remote string
- message string
- }
-
- func serverName(host string) string {
- return strings.Split(host, ":")[0]
- }
-
- func cfgRead(CfgFile string) cfgStruct {
- dir, dir_err := filepath.Abs(filepath.Dir(os.Args[0]))
- var ret cfgStruct
- if dir_err != nil {
- fmt.Printf("fail to open dir: %v", dir_err)
- }
- cfg, cfg_err := ini.Load(path.Join(dir, CfgFile))
- if cfg_err != nil {
- fmt.Printf("Fail to read file: %v", cfg_err)
- os.Exit(1)
- }
- cfg_notls, _ := cfg.Section("").Key("notls").Bool()
- ret.srv = cfg.Section("").Key("server").String()
- ret.usr = cfg.Section("").Key("username").String()
- ret.pwd = cfg.Section("").Key("password").String()
- ret.notls = cfg_notls
- ret.dest = cfg.Section("").Key("dest").String()
- return ret
- }
-
- func jabberClient(cfg cfgStruct) *xmpp.Client {
- var server = flag.String("server", cfg.srv, "server")
- var username = flag.String("username", cfg.usr, "username")
- var password = flag.String("password", cfg.pwd, "password")
- var status = flag.String("status", "xa", "status")
- var statusMessage = flag.String("status-msg", "", "")
- var notls = flag.Bool("notls", cfg.notls, "No TLS")
- var debug = flag.Bool("debug", false, "debug output")
- var session = flag.Bool("session", false, "use server session")
-
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, "usage: example [options]\n")
- flag.PrintDefaults()
- os.Exit(2)
- }
- flag.Parse()
- if *username == "" || *password == "" {
- if *debug && *username == "" && *password == "" {
- fmt.Fprintf(os.Stderr, "no username or password were given; attempting ANONYMOUS auth\n")
- } else if *username != "" || *password != "" {
- flag.Usage()
- }
- }
-
- if !*notls {
- xmpp.DefaultConfig = tls.Config{
- ServerName: serverName(*server),
- InsecureSkipVerify: false,
- }
- }
-
- var talk *xmpp.Client
- var err error
- options := xmpp.Options{Host: *server,
- User: *username,
- Password: *password,
- NoTLS: *notls,
- Debug: *debug,
- Session: *session,
- Status: *status,
- StatusMessage: *statusMessage,
- }
-
- talk, err = options.NewClient()
- if err != nil {
- fmt.Println(err)
- }
- return talk
- }
-
- // читаем из джаббера и отправляем в канал
- func jabberReader(talk *xmpp.Client, command chan<- commandMsg, in <-chan int) {
- for {
- chat, err := talk.Recv()
- if err != nil {
- fmt.Println(err)
- }
- switch v := chat.(type) {
- case xmpp.Chat:
- com := commandMsg{remote: v.Remote, message: v.Text}
- command <- com
- //case xmpp.Presence:
- // com := commandMsg{remote: v.From, message: v.Show}
- // command <- com
- }
- }
- }
-
- // отправляем ответы из канала
- func jabberSender(talk *xmpp.Client, msgChan <-chan commandMsg) {
- for {
- msg := <-msgChan
- remote := strings.Split(msg.remote, "/")[0]
- talk.Send(xmpp.Chat{Remote: remote, Type: "chat", Text: msg.message})
- }
- }
-
- // воркер
- func worker(workerNum int, msgChan <-chan commandMsg, readerClose chan int, ansChan chan<- commandMsg) {
- for {
- message := <-msgChan
- fmt.Println("Worker = ", workerNum, "message= ", message.message)
- cmd := strings.Split(message.message, " ")
- workMap := works.Works()
- _, workExists := workMap[cmd[0]]
- if workExists {
- work, _ := workMap[cmd[0]]
- ans, err := work.(func(...string) (string, error))(cmd[1:]...)
- if err != nil {
- ansChan <- commandMsg{remote: message.remote, message: err.Error()}
- } else {
- ansChan <- commandMsg{remote: message.remote, message: ans}
- }
- } else if len(message.message) > 0 {
- ans := "неизвестная комманда"
- ansChan <- commandMsg{remote: message.remote, message: ans}
- }
- }
- }
-
- //нопоминальщик
- func reminder(readerClose chan int, ansChan chan<- commandMsg) {
- for {
- msgSl := events_alerter.BuildAlert()
- fmt.Println("alerter works")
- fmt.Println(msgSl)
- for _, msgInt := range msgSl {
- tmpMsg := commandMsg{remote: msgInt.Remote(), message: msgInt.Message()}
- fmt.Println(tmpMsg)
- ansChan <- tmpMsg
- }
- time.Sleep(60 * time.Second)
- }
- }
-
- func main() {
- cfg := cfgRead("goqdpmbot.ini") // читаем конфигу
-
- goroutinesNum := 5 // количество потоков
- wg := &sync.WaitGroup{} // ожидаем интеррапта
- signal_channel := make(chan os.Signal, 1)
- readerClose := make(chan int, 1) // для закрытия всего зоопарка воркеров
- // каналы обмена инфой
- comChan := make(chan commandMsg, 5)
- ansChan := make(chan commandMsg, 5)
- // запускаем клиента
- talk := jabberClient(cfg)
- go jabberReader(talk, comChan, readerClose)
- go jabberSender(talk, ansChan)
- // и воркеров
- for i := 0; i < goroutinesNum; i++ {
- go worker(i, comChan, readerClose, ansChan)
- fmt.Println("worker started", i)
- }
- go reminder(readerClose, ansChan)
- // ожидаем выхода
- wg.Add(1)
- go func() {
- <-signal_channel
- wg.Done()
- }()
- wg.Wait()
- close(readerClose)
- time.Sleep(1 * time.Second)
- fmt.Println("interrupt")
- talk.Close()
- }
|