Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
galeone committed Apr 24, 2017
1 parent 5120085 commit f3dcc34
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 51 deletions.
4 changes: 1 addition & 3 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ Examples
If you already have the access token (and secret) for your user (Twitter provides this for your own account on the developer portal), creating the client is simple:

````go
anaconda.SetConsumerKey("your-consumer-key")
anaconda.SetConsumerSecret("your-consumer-secret")
api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret")
api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret")
````

### Queries
Expand Down
11 changes: 3 additions & 8 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,12 @@ import (
// Initialize an client library for a given user.
// This only needs to be done *once* per user
func ExampleTwitterApi_InitializeClient() {
anaconda.SetConsumerKey("your-consumer-key")
anaconda.SetConsumerSecret("your-consumer-secret")
api := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
api := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, "your-consumer-key", "your-consumer-secret")
fmt.Println(*api.Credentials)
}

func ExampleTwitterApi_GetSearch() {

anaconda.SetConsumerKey("your-consumer-key")
anaconda.SetConsumerSecret("your-consumer-secret")
api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret")
api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret")
search_result, err := api.GetSearch("golang", nil)
if err != nil {
panic(err)
Expand All @@ -32,7 +27,7 @@ func ExampleTwitterApi_GetSearch() {

// Throttling queries can easily be handled in the background, automatically
func ExampleTwitterApi_Throttling() {
api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret")
api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret")
api.EnableThrottling(10*time.Second, 5)

// These queries will execute in order
Expand Down
2 changes: 1 addition & 1 deletion oembed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func TestOEmbed(t *testing.T) {
// It is the only one that can be tested without auth
// However, it is still rate-limited
api := anaconda.NewTwitterApi("", "")
api := anaconda.NewTwitterApi("", "", "", "")
api.SetBaseUrl(testBase)
o, err := api.GetOEmbed(url.Values{"id": []string{"99530515043983360"}})
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions streaming.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ func jsonToKnownType(j []byte) interface{} {
func (s *Stream) requestStream(urlStr string, v url.Values, method int) (resp *http.Response, err error) {
switch method {
case _GET:
return oauthClient.Get(s.api.HttpClient, s.api.Credentials, urlStr, v)
return s.api.oauthClient.Get(s.api.HttpClient, s.api.Credentials, urlStr, v)
case _POST:
return oauthClient.Post(s.api.HttpClient, s.api.Credentials, urlStr, v)
return s.api.oauthClient.Post(s.api.HttpClient, s.api.Credentials, urlStr, v)
default:
}
return nil, fmt.Errorf("HTTP method not yet supported")
Expand Down
50 changes: 19 additions & 31 deletions twitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
//
//If you already have the access token (and secret) for your user (Twitter provides this for your own account on the developer portal), creating the client is simple:
//
// anaconda.SetConsumerKey("your-consumer-key")
// anaconda.SetConsumerSecret("your-consumer-secret")
// api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret")
//
// api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret")
//
//Queries
//
Expand Down Expand Up @@ -60,13 +57,8 @@ const (
UploadBaseUrl = "https://upload.twitter.com/1.1"
)

var oauthClient = oauth.Client{
TemporaryCredentialRequestURI: "https://api.twitter.com/oauth/request_token",
ResourceOwnerAuthorizationURI: "https://api.twitter.com/oauth/authenticate",
TokenRequestURI: "https://api.twitter.com/oauth/access_token",
}

type TwitterApi struct {
oauthClient oauth.Client
Credentials *oauth.Credentials
queryQueue chan query
bucket *tokenbucket.Bucket
Expand Down Expand Up @@ -101,11 +93,20 @@ const DEFAULT_CAPACITY = 5

//NewTwitterApi takes an user-specific access token and secret and returns a TwitterApi struct for that user.
//The TwitterApi struct can be used for accessing any of the endpoints available.
func NewTwitterApi(access_token string, access_token_secret string) *TwitterApi {
func NewTwitterApi(access_token, access_token_secret, consumer_key, consumer_secret string) *TwitterApi {
//TODO figure out how much to buffer this channel
//A non-buffered channel will cause blocking when multiple queries are made at the same time
queue := make(chan query)
c := &TwitterApi{
oauthClient: oauth.Client{
TemporaryCredentialRequestURI: "https://api.twitter.com/oauth/request_token",
ResourceOwnerAuthorizationURI: "https://api.twitter.com/oauth/authenticate",
TokenRequestURI: "https://api.twitter.com/oauth/access_token",
Credentials: oauth.Credentials{
Token: consumer_key,
Secret: consumer_secret,
},
},
Credentials: &oauth.Credentials{
Token: access_token,
Secret: access_token_secret,
Expand All @@ -121,18 +122,6 @@ func NewTwitterApi(access_token string, access_token_secret string) *TwitterApi
return c
}

//SetConsumerKey will set the application-specific consumer_key used in the initial OAuth process
//This key is listed on https://dev.twitter.com/apps/YOUR_APP_ID/show
func SetConsumerKey(consumer_key string) {
oauthClient.Credentials.Token = consumer_key
}

//SetConsumerSecret will set the application-specific secret used in the initial OAuth process
//This secret is listed on https://dev.twitter.com/apps/YOUR_APP_ID/show
func SetConsumerSecret(consumer_secret string) {
oauthClient.Credentials.Secret = consumer_secret
}

// ReturnRateLimitError specifies behavior when the Twitter API returns a rate-limit error.
// If set to true, the query will fail and return the error instead of automatically queuing and
// retrying the query when the rate limit expires
Expand Down Expand Up @@ -167,17 +156,16 @@ func (c *TwitterApi) SetBaseUrl(baseUrl string) {

//AuthorizationURL generates the authorization URL for the first part of the OAuth handshake.
//Redirect the user to this URL.
//This assumes that the consumer key has already been set (using SetConsumerKey).
func AuthorizationURL(callback string) (string, *oauth.Credentials, error) {
tempCred, err := oauthClient.RequestTemporaryCredentials(http.DefaultClient, callback, nil)
func (c *TwitterApi) AuthorizationURL(callback string) (string, *oauth.Credentials, error) {
tempCred, err := c.oauthClient.RequestTemporaryCredentials(http.DefaultClient, callback, nil)
if err != nil {
return "", nil, err
}
return oauthClient.AuthorizationURL(tempCred, nil), tempCred, nil
return c.oauthClient.AuthorizationURL(tempCred, nil), tempCred, nil
}

func GetCredentials(tempCred *oauth.Credentials, verifier string) (*oauth.Credentials, url.Values, error) {
return oauthClient.RequestToken(http.DefaultClient, tempCred, verifier)
func (c *TwitterApi) GetCredentials(tempCred *oauth.Credentials, verifier string) (*oauth.Credentials, url.Values, error) {
return c.oauthClient.RequestToken(http.DefaultClient, tempCred, verifier)
}

func cleanValues(v url.Values) url.Values {
Expand All @@ -189,7 +177,7 @@ func cleanValues(v url.Values) url.Values {

// apiGet issues a GET request to the Twitter API and decodes the response JSON to data.
func (c TwitterApi) apiGet(urlStr string, form url.Values, data interface{}) error {
resp, err := oauthClient.Get(c.HttpClient, c.Credentials, urlStr, form)
resp, err := c.oauthClient.Get(c.HttpClient, c.Credentials, urlStr, form)
if err != nil {
return err
}
Expand All @@ -199,7 +187,7 @@ func (c TwitterApi) apiGet(urlStr string, form url.Values, data interface{}) err

// apiPost issues a POST request to the Twitter API and decodes the response JSON to data.
func (c TwitterApi) apiPost(urlStr string, form url.Values, data interface{}) error {
resp, err := oauthClient.Post(c.HttpClient, c.Credentials, urlStr, form)
resp, err := c.oauthClient.Post(c.HttpClient, c.Credentials, urlStr, form)
if err != nil {
return err
}
Expand Down
8 changes: 2 additions & 6 deletions twitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ var testBase string

func init() {
// Initialize api so it can be used even when invidual tests are run in isolation
anaconda.SetConsumerKey(CONSUMER_KEY)
anaconda.SetConsumerSecret(CONSUMER_SECRET)
api = anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
api = anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET)

if CONSUMER_KEY != "" && CONSUMER_SECRET != "" && ACCESS_TOKEN != "" && ACCESS_TOKEN_SECRET != "" {
return
Expand Down Expand Up @@ -115,9 +113,7 @@ func Test_TwitterCredentials(t *testing.T) {

// Test that creating a TwitterApi client creates a client with non-empty OAuth credentials
func Test_TwitterApi_NewTwitterApi(t *testing.T) {
anaconda.SetConsumerKey(CONSUMER_KEY)
anaconda.SetConsumerSecret(CONSUMER_SECRET)
apiLocal := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
apiLocal := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET)

if apiLocal.Credentials == nil {
t.Fatalf("Twitter Api client has empty (nil) credentials")
Expand Down

0 comments on commit f3dcc34

Please sign in to comment.