示例#1
0
func main() {

	// Create new streaming API client
	client := streamingtwitter.NewClient()

	err := client.Authenticate(&streamingtwitter.ClientTokens{
		TokenFile: tokenFile,
	})
	if err != nil {
		log.Fatal(err)
	}

	// Paramaters to send to the API
	args := &url.Values{}
	args.Add("screen_name", "stephenfry,mashable")

	userLookup := &streamingtwitter.TwitterAPIURL{
		AccessMethod: "get",
		URL:          "https://api.twitter.com/1.1/users/lookup.json",
	}

	data := []streamingtwitter.TwitterUser{}
	go client.Rest(&data, userLookup, args)

	select {
	case err := <-client.Errors:
		log.Fatal(err)
	case <-client.Finished:
		fmt.Printf("%+v", data)
	}
}
示例#2
0
func main() {

	// Create new streaming API client
	client := streamingtwitter.NewClient()

	err := client.Authenticate(&streamingtwitter.ClientTokens{
		TokenFile: tokenFile,
	})
	if err != nil {
		log.Fatal(err)
	}

	// Some keywords to track .. see the Twitter Streaming API documentation for more information
	args := &url.Values{}
	args.Add("track", "Norway")

	// Launch the stream
	tweets := make(chan *streamingtwitter.TwitterStatus)
	go client.Stream(tweets, streamingtwitter.Streams["Filter"], args)

	for {
		select {
		// Recieve tweets
		case status := <-tweets:
			fmt.Println(status)
			// Any errors that occured
		case err := <-client.Errors:
			fmt.Printf("ERROR: '%s'\n", err)
			// Stream has finished
		case <-client.Finished:
			return
		}
	}
}
示例#3
0
func main() {
	// Clear terminal screen and move cursor to top left position.
	var clearScreen = func() {
		fmt.Fprintf(os.Stdout, "\033[2J\033[H")
	}

	clearScreen()

	// Splash screen ...
	ticker := time.NewTicker(time.Millisecond * 500)
	go func() {
		i := 1
		dot := "."
		fmt.Fprintf(os.Stdout, "Loading ")
		for _ = range ticker.C {
			if i%4 == 0 {
				fmt.Fprintf(os.Stdout, "\033[3D   \033[3D")
			} else {
				fmt.Fprintf(os.Stdout, "%v", dot)
			}
			i++
		}
		clearScreen()
	}()

	flag.Parse()

	_, ok := streamingtwitter.Streams[stream]
	if ok == false {
		fmt.Fprintf(os.Stderr, "Usage of %v\n", os.Args[0])
		flag.PrintDefaults()
		return
	}

	// Helper function to create a streaming client only when necessary
	var client *streamingtwitter.StreamClient
	var createClient = func() {
		// Create new streaming API client
		client = streamingtwitter.NewClient()

		err := client.Authenticate(&streamingtwitter.ClientTokens{
			TokenFile: tokenFile,
		})
		if err != nil {
			log.Fatal(err)
		}
	}

	// Define arguments to pass to the stream.  (Only required Filter stream options are supported currently)
	// https://dev.twitter.com/docs/streaming-apis/parameters
	args := &url.Values{}
	if stream == "Filter" {
		// At least one of: follow,locations or track must be specified to use the filter stream
		if followUsers == "" && trackKeywords == "" && location == "" {
			fmt.Fprintf(os.Stderr, "Either; -follow, -track, or -location must be specified when using the Filter stream.\n")
			flag.PrintDefaults()
			return
		}

		createClient()

		if followUsers != "" {
			// To track a user, a user ID (and not screen name) must be sent to the stream.
			// To get a user ID we need to query the relevant Twitter REST API.
			users := &url.Values{}
			users.Add("screen_name", followUsers)

			userLookup := &streamingtwitter.TwitterAPIURL{
				AccessMethod: "get",
				URL:          "https://api.twitter.com/1.1/users/lookup.json",
			}

			data := []streamingtwitter.TwitterUser{}
			go client.Rest(&data, userLookup, users)

			select {
			case err := <-client.Errors:
				ticker.Stop()
				clearScreen()
				if err.(*streamingtwitter.TwitterError).ID == 404 {
					log.Fatalf("User %v doesn't exist", followUsers)
				} else {
					log.Fatal(err)
				}
			case <-client.Finished:
				break
			}

			ids := []string{}
			for _, o := range data {
				ids = append(ids, o.ID)
			}

			args.Add("follow", strings.Join(ids, ","))
		}
		if trackKeywords != "" {
			args.Add("track", trackKeywords)
		}
		if location != "" {
			args.Add("locations", location)
		}
	} else {
		createClient()
	}

	wg.Add(1)
	tweets := make(chan *streamingtwitter.TwitterStatus)
	go client.Stream(tweets, streamingtwitter.Streams[stream], args)

	// Wait for all streams to finish and then provide notification
	done := make(chan struct{})
	go func() {
		wg.Wait()
		done <- struct{}{}
	}()

	// Store last X number of tweets for outputting
	tweetList := make([]streamingtwitter.TwitterStatus, tweetListLimit)

	// Push item to the top of the tweetList array and remove the last element if > listsize
	var addToFront = func(v streamingtwitter.TwitterStatus, l []streamingtwitter.TwitterStatus) (t []streamingtwitter.TwitterStatus) {
		t = make([]streamingtwitter.TwitterStatus, cap(l))
		t[0] = v
		for i := 1; i < cap(l); i++ {
			t[i] = l[i-1]
		}
		return
	}

	// Whether or not any tweets have been matched by the age timing criteria
	highlightMatched := false

	// Set the background and foreground colour of tweets matching age timing criteria
	var displayTweets = func(bg int, fg int) {
		clearScreen()

		for k, s := range tweetList {
			// Reset all display attributes
			fmt.Fprintf(os.Stdout, "\033[0m")

			// Default colour for tweet display
			// Clear all terminal formatting
			colourCode := "0"

			// Perphaps the output looks a little more pretty with a blank line at the top!
			if k == 0 {
				fmt.Fprintf(os.Stdout, "\n")
			}

			// Highlight all tweets that are less that X seconds old
			if time.Now().Sub(s.CreatedAt.T).Seconds() <= tweetHighlightAge {
				fmt.Fprintf(os.Stdout, "\033[%vm\033[%vm", bg, fg)
				colourCode = "22"
				highlightMatched = true
			}

			if s.Text != "" {
				fmt.Fprintf(os.Stdout, "\033[1m%v @%v\033[%vm - %v\n> %v\n\n", s.User.Name, s.User.ScreenName, colourCode, s.CreatedAt.T.In(timezone).Format(tweetDateLayout), s.Text)
			}
		}
		// Move cursor to home position (upper left corner)
		fmt.Fprintf(os.Stdout, " \033[H")
	}

	// Whether or not we have received data from a stream
	loaded := false

	// Business end
	for {
		select {
		case status := <-tweets:
			if loaded == false {
				loaded = true
				ticker.Stop()
			}

			tweetList = addToFront(*status, tweetList)

			// Draw tweets
			displayTweets(41, 37)

			// Redraw the tweets if we haven't received one within X seconds (remove highlighting)
		case <-time.After(time.Duration(tweetHighlightAge) * time.Second):
			// Only redraw if tweets have matched the age timing criteria in default colours
			if highlightMatched == true {
				// Perhaps we should only redraw the affected tweets .. :)
				displayTweets(49, 39)
				highlightMatched = false
			}
		case err := <-client.Errors:
			fmt.Fprintf(os.Stderr, "ERROR: '%s'\n", err)
		case <-client.Finished:
			// Notify the waitgroup that a stream has finished
			wg.Done()
		case <-done:
			// All streams are finished so we can exit
			return
		}
	}
}