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.

main.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "github.com/deckarep/golang-set"
  6. "github.com/fsnotify/fsnotify"
  7. "github.com/irccloud/irccat/httplistener"
  8. "github.com/irccloud/irccat/tcplistener"
  9. "github.com/juju/loggo"
  10. "github.com/spf13/viper"
  11. "github.com/thoj/go-ircevent"
  12. "os"
  13. "os/signal"
  14. "strings"
  15. "syscall"
  16. )
  17. var log = loggo.GetLogger("main")
  18. var branch string
  19. var revision string
  20. var CONFIG_FILE_LOCATIONS = []string{
  21. "/etc",
  22. "/run/secrets",
  23. ".",
  24. }
  25. type IRCCat struct {
  26. auth_channel string
  27. channels mapset.Set
  28. auth_users map[string]bool
  29. irc *irc.Connection
  30. tcp *tcplistener.TCPListener
  31. signals chan os.Signal
  32. }
  33. func main() {
  34. debug := flag.Bool("debug", false, "Print raw IRC lines")
  35. configFile := flag.String("config", "", "Path to config file to use")
  36. flag.Parse()
  37. loggo.ConfigureLoggers("<root>=INFO")
  38. log.Infof("IRCCat %s (%s) starting...", branch, revision)
  39. if *configFile != "" {
  40. viper.SetConfigFile(*configFile)
  41. } else {
  42. viper.SetConfigName("irccat")
  43. for _, p := range CONFIG_FILE_LOCATIONS {
  44. viper.AddConfigPath(p)
  45. }
  46. }
  47. var err error
  48. err = viper.ReadInConfig()
  49. if err != nil {
  50. log.Errorf("Error reading config file - exiting. I'm looking for irccat.[json|yaml|toml|hcl] in one of %s", strings.Join(CONFIG_FILE_LOCATIONS, ", "))
  51. return
  52. }
  53. irccat := IRCCat{auth_users: map[string]bool{},
  54. signals: make(chan os.Signal, 1),
  55. channels: mapset.NewSet(),
  56. auth_channel: viper.GetString("commands.auth_channel")}
  57. viper.WatchConfig()
  58. viper.OnConfigChange(irccat.handleConfigChange)
  59. signal.Notify(irccat.signals, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
  60. go irccat.signalHandler()
  61. if viper.IsSet("tcp.listen") {
  62. irccat.tcp, err = tcplistener.New()
  63. if err != nil {
  64. log.Criticalf("Error starting TCP listener: %s", err)
  65. return
  66. }
  67. irccat.tcp.Run(irccat.irc)
  68. }
  69. err = irccat.connectIRC(*debug)
  70. if err != nil {
  71. log.Criticalf("Error connecting to IRC server: %s", err)
  72. return
  73. }
  74. if viper.IsSet("http") {
  75. httplistener.New(irccat.irc)
  76. }
  77. irccat.irc.Loop()
  78. }
  79. func (i *IRCCat) signalHandler() {
  80. sig := <-i.signals
  81. log.Infof("Exiting on %s", sig)
  82. i.irc.QuitMessage = fmt.Sprintf("Exiting on %s", sig)
  83. i.irc.Quit()
  84. }
  85. func (i *IRCCat) handleConfigChange(e fsnotify.Event) {
  86. log.Infof("Reloaded config")
  87. new_channels := mapset.NewSet()
  88. for _, channel := range viper.GetStringSlice("irc.channels") {
  89. new_channels.Add(channel)
  90. if !i.channels.Contains(channel) {
  91. log.Infof("Joining new channel %s", channel)
  92. i.irc.Join(channel)
  93. i.channels.Add(channel)
  94. }
  95. }
  96. it := i.channels.Difference(new_channels).Iterator()
  97. for channel := range it.C {
  98. log.Infof("Leaving channel %s", channel)
  99. i.irc.Part(channel.(string))
  100. i.channels.Remove(channel)
  101. }
  102. }