main.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "os"
  6. "os/signal"
  7. "syscall"
  8. "github.com/ChimeraCoder/anaconda"
  9. "github.com/baobabus/gcfg"
  10. "github.com/cryptix/go/logging"
  11. )
  12. var log = logging.Logger("twitClone")
  13. var cfgFile = flag.String("config", "my.cfg", "which config file to use")
  14. type Config struct {
  15. Anaconda struct {
  16. ConsumerKey string
  17. ConsumerSecret string
  18. AccessToken string
  19. AccessTokenSecret string
  20. }
  21. Config struct {
  22. Email string
  23. UpdateInterval string
  24. Debug bool
  25. }
  26. }
  27. func main() {
  28. logging.SetupLogging(nil)
  29. // setup config
  30. var cfg Config
  31. logging.CheckFatal(gcfg.ReadFileInto(&cfg, *cfgFile))
  32. // setup anaconda
  33. anaconda.SetConsumerKey(cfg.Anaconda.ConsumerKey)
  34. anaconda.SetConsumerSecret(cfg.Anaconda.ConsumerSecret)
  35. api := anaconda.NewTwitterApi(cfg.Anaconda.AccessToken, cfg.Anaconda.AccessTokenSecret)
  36. //api.SetLogger(anaconda.BasicLogger)
  37. ok, err := api.VerifyCredentials()
  38. logging.CheckFatal(err)
  39. log.Info("Credentials:", ok)
  40. // Mechanical stuff
  41. //rand.Seed(time.Now().UnixNano())
  42. //root := context.Background()
  43. errc := make(chan error)
  44. go func() {
  45. errc <- interrupt()
  46. }()
  47. // Pull: my feed
  48. //go func() {
  49. //dur, err := time.ParseDuration(cfg.Config.UpdateInterval)
  50. //logging.CheckFatal(err)
  51. // t := time.Tick(dur)
  52. // for now := range t {
  53. // // pulls MY timeline
  54. // tweets, err := api.GetUserTimeline(nil)
  55. // if err != nil {
  56. // errc <- err
  57. // return
  58. // }
  59. // logging.CheckFatal(err)
  60. // for _, tweet := range tweets {
  61. // log.WithFields(map[string]interface{}{
  62. // "user": tweet.User.ScreenName,
  63. // "userid": tweet.User.Id,
  64. // "tweetid": tweet.Id,
  65. // }).Infof("[tweet] %s", tweet.Text)
  66. // }
  67. // log.WithFields(map[string]interface{}{
  68. // "cnt": len(tweets),
  69. // "took": time.Since(now),
  70. // }).Info("cycle done")
  71. // }
  72. //}()
  73. // Stream: my timeline
  74. //go cloneStream("site", api.SiteStream(nil), errc)
  75. go cloneStream("user", api.UserStream(nil), errc)
  76. log.Fatal("global error:", <-errc)
  77. }
  78. func cloneStream(name string, s anaconda.Stream, errc chan<- error) {
  79. go func() {
  80. v := <-s.Quit
  81. errc <- fmt.Errorf("stream[%s] quit: %v", name, v)
  82. }()
  83. for msg := range s.C {
  84. switch t := msg.(type) {
  85. case anaconda.FriendsList:
  86. log.WithField("count", len(t)).Infof("friends[%s]", name)
  87. case anaconda.Tweet:
  88. log.WithFields(map[string]interface{}{
  89. "user": t.User.ScreenName,
  90. "userid": t.User.Id,
  91. "tweetid": t.Id,
  92. }).Infof("tweet[%s] %s", name, t.Text)
  93. case anaconda.EventTweet:
  94. var tweet anaconda.Tweet = *t.TargetObject
  95. log.WithFields(map[string]interface{}{
  96. "user": tweet.User.ScreenName,
  97. "userid": tweet.User.Id,
  98. "tweetid": tweet.Id,
  99. }).Infof("Eventtweet[%s] %s", name, tweet.Text)
  100. case anaconda.StatusDeletionNotice:
  101. log.WithFields(map[string]interface{}{
  102. "userid": t.UserId,
  103. "tweetid": t.Id,
  104. }).Warningf("tweet[%s] deleted", name)
  105. default:
  106. log.Error("uncased msg %T %+v", t, msg)
  107. }
  108. }
  109. }
  110. func interrupt() error {
  111. c := make(chan os.Signal)
  112. signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
  113. return fmt.Errorf("%s", <-c)
  114. }