account.go
changeset 120 579912e9d0ef
parent 115 0684ac8b6634
child 125 2bbb72b9ebf6
equal deleted inserted replaced
119:22c8c58ad61b 120:579912e9d0ef
     1 package gondole
     1 package gondole
     2 
     2 
     3 import (
     3 import (
     4 	"encoding/json"
       
     5 	"fmt"
     4 	"fmt"
     6 	"strconv"
     5 	"strconv"
     7 
     6 
     8 	"github.com/sendgrid/rest"
     7 	"github.com/sendgrid/rest"
     9 )
     8 )
    17 	Q     string
    16 	Q     string
    18 	Limit int
    17 	Limit int
    19 }
    18 }
    20 
    19 
    21 // getSingleAccount returns an account entity
    20 // getSingleAccount returns an account entity
    22 // The target can be "account", "verify_credentials", "follow", "unfollow",
    21 // The operation 'op' can be "account", "verify_credentials", "follow",
    23 // "block", "unblock", "mute", "unmute", "follow_requests/authorize" or
    22 // "unfollow", "block", "unblock", "mute", "unmute",
    24 // "follow_requests/reject".
    23 // "follow_requests/authorize" or // "follow_requests/reject".
    25 // The id is optional and depends on the target.
    24 // The id is optional and depends on the operation.
    26 func (g *Client) getSingleAccount(target string, id int) (*Account, error) {
    25 func (g *Client) getSingleAccount(op string, id int) (*Account, error) {
    27 	var endPoint string
    26 	var endPoint string
    28 	method := rest.Get
    27 	method := rest.Get
    29 	strID := strconv.Itoa(id)
    28 	strID := strconv.Itoa(id)
    30 
    29 
    31 	switch target {
    30 	switch op {
    32 	case "account":
    31 	case "account":
    33 		endPoint = "accounts/" + strID
    32 		endPoint = "accounts/" + strID
    34 	case "verify_credentials":
    33 	case "verify_credentials":
    35 		endPoint = "accounts/verify_credentials"
    34 		endPoint = "accounts/verify_credentials"
    36 	case "follow", "unfollow", "block", "unblock", "mute", "unmute":
    35 	case "follow", "unfollow", "block", "unblock", "mute", "unmute":
    37 		endPoint = "accounts/" + strID + "/" + target
    36 		endPoint = "accounts/" + strID + "/" + op
    38 		method = rest.Post
    37 		method = rest.Post
    39 	case "follow_requests/authorize", "follow_requests/reject":
    38 	case "follow_requests/authorize", "follow_requests/reject":
    40 		// The documentation is incorrect, the endpoint actually
    39 		// The documentation is incorrect, the endpoint actually
    41 		// is "follow_requests/:id/{authorize|reject}"
    40 		// is "follow_requests/:id/{authorize|reject}"
    42 		endPoint = target[:16] + strID + "/" + target[16:]
    41 		endPoint = op[:16] + strID + "/" + op[16:]
    43 		method = rest.Post
    42 		method = rest.Post
    44 	default:
    43 	default:
    45 		return nil, ErrInvalidParameter
    44 		return nil, ErrInvalidParameter
    46 	}
    45 	}
    47 
    46 
    48 	req := g.prepareRequest(endPoint)
       
    49 	req.Method = method
       
    50 
       
    51 	r, err := rest.API(req)
       
    52 	if err != nil {
       
    53 		return nil, fmt.Errorf("getAccount (%s): %s", target, err.Error())
       
    54 	}
       
    55 
       
    56 	// Check for error reply
       
    57 	var errorResult Error
       
    58 	if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil {
       
    59 		// The empty object is not an error
       
    60 		if errorResult.Text != "" {
       
    61 			return nil, fmt.Errorf("%s", errorResult.Text)
       
    62 		}
       
    63 	}
       
    64 
       
    65 	// Not an error reply; let's unmarshal the data
       
    66 	var account Account
    47 	var account Account
    67 	err = json.Unmarshal([]byte(r.Body), &account)
    48 	if err := g.apiCall(endPoint, method, nil, &account); err != nil {
    68 	if err != nil {
    49 		return nil, err
    69 		return nil, fmt.Errorf("getAccount (%s) API: %s", target, err.Error())
       
    70 	}
    50 	}
    71 	return &account, nil
    51 	return &account, nil
    72 }
    52 }
    73 
    53 
    74 // getMultipleAccounts returns a list of account entities
    54 // getMultipleAccounts returns a list of account entities
    75 // The target can be "followers", "following", "search", "blocks", "mutes",
    55 // The operation 'op' can be "followers", "following", "search", "blocks",
    76 // "follow_requests".
    56 // "mutes", "follow_requests".
    77 // The id is optional and depends on the target.
    57 // The id is optional and depends on the operation.
    78 func (g *Client) getMultipleAccounts(target string, opts *getAccountsOptions) ([]Account, error) {
    58 func (g *Client) getMultipleAccounts(op string, opts *getAccountsOptions) ([]Account, error) {
    79 	var endPoint string
    59 	var endPoint string
    80 	switch target {
    60 
       
    61 	switch op {
    81 	case "followers", "following":
    62 	case "followers", "following":
    82 		if opts == nil || opts.ID < 1 {
    63 		if opts == nil || opts.ID < 1 {
    83 			return []Account{}, ErrInvalidID
    64 			return []Account{}, ErrInvalidID
    84 		}
    65 		}
    85 		endPoint = "accounts/" + strconv.Itoa(opts.ID) + "/" + target
    66 		endPoint = "accounts/" + strconv.Itoa(opts.ID) + "/" + op
    86 	case "follow_requests", "blocks", "mutes":
    67 	case "follow_requests", "blocks", "mutes":
    87 		endPoint = target
    68 		endPoint = op
    88 	case "search":
    69 	case "search":
    89 		if opts == nil || opts.Q == "" {
    70 		if opts == nil || opts.Q == "" {
    90 			return []Account{}, ErrInvalidParameter
    71 			return []Account{}, ErrInvalidParameter
    91 		}
    72 		}
    92 		endPoint = "accounts/" + target
    73 		endPoint = "accounts/" + op
    93 	default:
    74 	default:
    94 		return nil, ErrInvalidParameter
    75 		return nil, ErrInvalidParameter
    95 	}
    76 	}
    96 
    77 
    97 	req := g.prepareRequest(endPoint)
       
    98 
       
    99 	// Handle target-specific query parameters
    78 	// Handle target-specific query parameters
   100 	if target == "search" {
    79 	params := make(apiCallParams)
   101 		req.QueryParams["q"] = opts.Q
    80 	if op == "search" {
       
    81 		params["q"] = opts.Q
   102 		if opts.Limit > 0 {
    82 		if opts.Limit > 0 {
   103 			req.QueryParams["limit"] = strconv.Itoa(opts.Limit)
    83 			params["limit"] = strconv.Itoa(opts.Limit)
   104 		}
    84 		}
   105 	}
    85 	}
   106 
    86 
   107 	r, err := rest.API(req)
       
   108 	if err != nil {
       
   109 		return nil, fmt.Errorf("getAccount (%s): %s", target, err.Error())
       
   110 	}
       
   111 
       
   112 	// Check for error reply
       
   113 	var errorResult Error
       
   114 	if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil {
       
   115 		// The empty object is not an error
       
   116 		if errorResult.Text != "" {
       
   117 			return nil, fmt.Errorf("%s", errorResult.Text)
       
   118 		}
       
   119 	}
       
   120 
       
   121 	// Not an error reply; let's unmarshal the data
       
   122 	var accounts []Account
    87 	var accounts []Account
   123 	err = json.Unmarshal([]byte(r.Body), &accounts)
    88 	if err := g.apiCall(endPoint, rest.Get, params, &accounts); err != nil {
   124 	if err != nil {
    89 		return nil, err
   125 		return nil, fmt.Errorf("getAccount (%s) API: %s", target, err.Error())
       
   126 	}
    90 	}
   127 	return accounts, nil
    91 	return accounts, nil
   128 }
    92 }
   129 
    93 
   130 // GetAccount returns an account entity
    94 // GetAccount returns an account entity
   188 	}
   152 	}
   189 	return nil
   153 	return nil
   190 }
   154 }
   191 
   155 
   192 // FollowRemoteAccount follows a remote account
   156 // FollowRemoteAccount follows a remote account
   193 // The parameter 'id' is a URI (username@domain).
   157 // The parameter 'uri' is a URI (e.g. "username@domain").
   194 func (g *Client) FollowRemoteAccount(id string) (*Account, error) {
   158 func (g *Client) FollowRemoteAccount(uri string) (*Account, error) {
   195 	if id == "" {
   159 	if uri == "" {
   196 		return nil, ErrInvalidID
   160 		return nil, ErrInvalidID
   197 	}
   161 	}
   198 
   162 
   199 	req := g.prepareRequest("follows")
   163 	params := make(apiCallParams)
   200 	req.Method = rest.Post
   164 	params["uri"] = uri
   201 	req.QueryParams["uri"] = id
   165 
   202 	r, err := rest.API(req)
       
   203 	if err != nil {
       
   204 		return nil, fmt.Errorf("FollowRemoteAccount: %s", err.Error())
       
   205 	}
       
   206 
       
   207 	// Check for error reply
       
   208 	var errorResult Error
       
   209 	if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil {
       
   210 		// The empty object is not an error
       
   211 		if errorResult.Text != "" {
       
   212 			return nil, fmt.Errorf("%s", errorResult.Text)
       
   213 		}
       
   214 	}
       
   215 
       
   216 	// Not an error reply; let's unmarshal the data
       
   217 	var account Account
   166 	var account Account
   218 	err = json.Unmarshal([]byte(r.Body), &account)
   167 	if err := g.apiCall("follows", rest.Post, params, &account); err != nil {
   219 	if err != nil {
   168 		return nil, err
   220 		return nil, fmt.Errorf("FollowRemoteAccount API: %s", err.Error())
       
   221 	}
   169 	}
   222 	if account.ID == 0 {
   170 	if account.ID == 0 {
   223 		return nil, ErrEntityNotFound
   171 		return nil, ErrEntityNotFound
   224 	}
   172 	}
   225 	return &account, nil
   173 	return &account, nil
   300 func (g *Client) GetAccountRelationships(accountIDs []int) ([]Relationship, error) {
   248 func (g *Client) GetAccountRelationships(accountIDs []int) ([]Relationship, error) {
   301 	if len(accountIDs) < 1 {
   249 	if len(accountIDs) < 1 {
   302 		return nil, ErrInvalidID
   250 		return nil, ErrInvalidID
   303 	}
   251 	}
   304 
   252 
   305 	req := g.prepareRequest("accounts/relationships")
       
   306 
       
   307 	if len(accountIDs) > 1 { // XXX
   253 	if len(accountIDs) > 1 { // XXX
   308 		return nil, fmt.Errorf("accounts/relationships currently does not work with more than 1 ID")
   254 		return nil, fmt.Errorf("accounts/relationships currently does not work with more than 1 ID")
   309 	}
   255 	}
   310 	req.QueryParams["id"] = strconv.Itoa(accountIDs[0])
   256 
       
   257 	params := make(apiCallParams)
       
   258 	params["id"] = strconv.Itoa(accountIDs[0])
   311 	/*
   259 	/*
   312 		for i, id := range accountIDList {
   260 		for i, id := range accountIDList {
   313 			qID := fmt.Sprintf("id[%d]", i+1)
   261 			qID := fmt.Sprintf("id[%d]", i+1)
   314 			req.QueryParams[qID] = strconv.Itoa(id)
   262 			params[qID] = strconv.Itoa(id)
   315 		}
   263 		}
   316 	*/
   264 	*/
   317 
   265 
   318 	r, err := rest.API(req)
       
   319 	if err != nil {
       
   320 		return nil, fmt.Errorf("GetAccountRelationships: %s", err.Error())
       
   321 	}
       
   322 
       
   323 	// Check for error reply
       
   324 	var errorResult Error
       
   325 	if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil {
       
   326 		// The empty object is not an error
       
   327 		if errorResult.Text != "" {
       
   328 			return nil, fmt.Errorf("%s", errorResult.Text)
       
   329 		}
       
   330 	}
       
   331 
       
   332 	// Not an error reply; let's unmarshal the data
       
   333 	var rl []Relationship
   266 	var rl []Relationship
   334 	err = json.Unmarshal([]byte(r.Body), &rl)
   267 	if err := g.apiCall("accounts/relationships", rest.Get, params, &rl); err != nil {
   335 	if err != nil {
   268 		return nil, err
   336 		return nil, fmt.Errorf("accounts/relationships API: %s", err.Error())
       
   337 	}
   269 	}
   338 	return rl, nil
   270 	return rl, nil
   339 }
   271 }
   340 
   272 
   341 // GetAccountStatuses returns a list of status entities for the given account
   273 // GetAccountStatuses returns a list of status entities for the given account
   345 	if accountID < 1 {
   277 	if accountID < 1 {
   346 		return nil, ErrInvalidID
   278 		return nil, ErrInvalidID
   347 	}
   279 	}
   348 
   280 
   349 	endPoint := "accounts/" + strconv.Itoa(accountID) + "/" + "statuses"
   281 	endPoint := "accounts/" + strconv.Itoa(accountID) + "/" + "statuses"
   350 	req := g.prepareRequest(endPoint)
   282 	params := make(apiCallParams)
   351 
       
   352 	if onlyMedia {
   283 	if onlyMedia {
   353 		req.QueryParams["only_media"] = "true"
   284 		params["only_media"] = "true"
   354 	}
   285 	}
   355 	if excludeReplies {
   286 	if excludeReplies {
   356 		req.QueryParams["exclude_replies"] = "true"
   287 		params["exclude_replies"] = "true"
   357 	}
   288 	}
   358 
   289 
   359 	r, err := rest.API(req)
       
   360 	if err != nil {
       
   361 		return nil, fmt.Errorf("GetAccountStatuses: %s", err.Error())
       
   362 	}
       
   363 
       
   364 	// Check for error reply
       
   365 	var errorResult Error
       
   366 	if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil {
       
   367 		// The empty object is not an error
       
   368 		if errorResult.Text != "" {
       
   369 			return nil, fmt.Errorf("%s", errorResult.Text)
       
   370 		}
       
   371 	}
       
   372 
       
   373 	// Not an error reply; let's unmarshal the data
       
   374 	var sl []Status
   290 	var sl []Status
   375 	err = json.Unmarshal([]byte(r.Body), &sl)
   291 	if err := g.apiCall(endPoint, rest.Get, params, &sl); err != nil {
   376 	if err != nil {
   292 		return nil, err
   377 		return nil, fmt.Errorf("accounts/statuses API: %s", err.Error())
       
   378 	}
   293 	}
   379 	return sl, nil
   294 	return sl, nil
   380 }
   295 }
   381 
   296 
   382 // FollowRequestAuthorize authorizes or rejects an account follow-request
   297 // FollowRequestAuthorize authorizes or rejects an account follow-request