vendor/github.com/McKael/madon/v3/account.go
changeset 270 df7e9dff1b66
parent 268 4dd196a4ee7c
equal deleted inserted replaced
269:c50e88700432 270:df7e9dff1b66
    11 	"encoding/json"
    11 	"encoding/json"
    12 	"fmt"
    12 	"fmt"
    13 	"mime/multipart"
    13 	"mime/multipart"
    14 	"os"
    14 	"os"
    15 	"path/filepath"
    15 	"path/filepath"
    16 	"strconv"
       
    17 
    16 
    18 	"github.com/pkg/errors"
    17 	"github.com/pkg/errors"
    19 	"github.com/sendgrid/rest"
    18 	"github.com/sendgrid/rest"
    20 )
    19 )
    21 
    20 
    22 // getAccountsOptions contains option fields for POST and DELETE API calls
    21 // getAccountsOptions contains option fields for POST and DELETE API calls
    23 type getAccountsOptions struct {
    22 type getAccountsOptions struct {
    24 	// The ID is used for most commands
    23 	// The ID is used for most commands
    25 	ID int64
    24 	ID ActivityID
    26 
    25 
    27 	// Following can be set to true to limit a search to "following" accounts
    26 	// Following can be set to true to limit a search to "following" accounts
    28 	Following bool
    27 	Following bool
    29 
    28 
    30 	// The Q field (query) is used when searching for accounts
    29 	// The Q field (query) is used when searching for accounts
    47 
    46 
    48 // updateRelationship returns a Relationship entity
    47 // updateRelationship returns a Relationship entity
    49 // The operation 'op' can be "follow", "unfollow", "block", "unblock",
    48 // The operation 'op' can be "follow", "unfollow", "block", "unblock",
    50 // "mute", "unmute".
    49 // "mute", "unmute".
    51 // The id is optional and depends on the operation.
    50 // The id is optional and depends on the operation.
    52 func (mc *Client) updateRelationship(op string, id int64, params apiCallParams) (*Relationship, error) {
    51 func (mc *Client) updateRelationship(op string, id ActivityID, params apiCallParams) (*Relationship, error) {
    53 	var endPoint string
    52 	var endPoint string
    54 	method := rest.Post
    53 	method := rest.Post
    55 	strID := strconv.FormatInt(id, 10)
       
    56 
    54 
    57 	switch op {
    55 	switch op {
    58 	case "follow", "unfollow", "block", "unblock", "mute", "unmute", "pin", "unpin":
    56 	case "follow", "unfollow", "block", "unblock", "mute", "unmute", "pin", "unpin":
    59 		endPoint = "accounts/" + strID + "/" + op
    57 		endPoint = "accounts/" + id + "/" + op
    60 	default:
    58 	default:
    61 		return nil, ErrInvalidParameter
    59 		return nil, ErrInvalidParameter
    62 	}
    60 	}
    63 
    61 
    64 	var rel Relationship
    62 	var rel Relationship
    70 
    68 
    71 // getSingleAccount returns an account entity
    69 // getSingleAccount returns an account entity
    72 // The operation 'op' can be "account", "verify_credentials",
    70 // The operation 'op' can be "account", "verify_credentials",
    73 // "follow_requests/authorize" or // "follow_requests/reject".
    71 // "follow_requests/authorize" or // "follow_requests/reject".
    74 // The id is optional and depends on the operation.
    72 // The id is optional and depends on the operation.
    75 func (mc *Client) getSingleAccount(op string, id int64) (*Account, error) {
    73 func (mc *Client) getSingleAccount(op string, id ActivityID) (*Account, error) {
    76 	var endPoint string
    74 	var endPoint string
    77 	method := rest.Get
    75 	method := rest.Get
    78 	strID := strconv.FormatInt(id, 10)
       
    79 
    76 
    80 	switch op {
    77 	switch op {
    81 	case "account":
    78 	case "account":
    82 		endPoint = "accounts/" + strID
    79 		endPoint = "accounts/" + id
    83 	case "verify_credentials":
    80 	case "verify_credentials":
    84 		endPoint = "accounts/verify_credentials"
    81 		endPoint = "accounts/verify_credentials"
    85 	case "follow_requests/authorize", "follow_requests/reject":
    82 	case "follow_requests/authorize", "follow_requests/reject":
    86 		// The documentation is incorrect, the endpoint actually
    83 		// The documentation is incorrect, the endpoint actually
    87 		// is "follow_requests/:id/{authorize|reject}"
    84 		// is "follow_requests/:id/{authorize|reject}"
    88 		endPoint = op[:16] + strID + "/" + op[16:]
    85 		endPoint = op[:16] + id + "/" + op[16:]
    89 		method = rest.Post
    86 		method = rest.Post
    90 	default:
    87 	default:
    91 		return nil, ErrInvalidParameter
    88 		return nil, ErrInvalidParameter
    92 	}
    89 	}
    93 
    90 
   136 		lopt = opts.Limit
   133 		lopt = opts.Limit
   137 	}
   134 	}
   138 
   135 
   139 	switch op {
   136 	switch op {
   140 	case "followers", "following":
   137 	case "followers", "following":
   141 		if opts == nil || opts.ID < 1 {
   138 		if opts == nil || opts.ID == "" {
   142 			return []Account{}, ErrInvalidID
   139 			return []Account{}, ErrInvalidID
   143 		}
   140 		}
   144 		endPoint = "accounts/" + strconv.FormatInt(opts.ID, 10) + "/" + op
   141 		endPoint = "accounts/" + opts.ID + "/" + op
   145 	case "follow_requests", "blocks", "mutes":
   142 	case "follow_requests", "blocks", "mutes":
   146 		endPoint = op
   143 		endPoint = op
   147 	case "search":
   144 	case "search":
   148 		if opts == nil || opts.Q == "" {
   145 		if opts == nil || opts.Q == "" {
   149 			return []Account{}, ErrInvalidParameter
   146 			return []Account{}, ErrInvalidParameter
   150 		}
   147 		}
   151 		endPoint = "accounts/" + op
   148 		endPoint = "accounts/" + op
   152 	case "reblogged_by", "favourited_by":
   149 	case "reblogged_by", "favourited_by":
   153 		if opts == nil || opts.ID < 1 {
   150 		if opts == nil || opts.ID == "" {
   154 			return []Account{}, ErrInvalidID
   151 			return []Account{}, ErrInvalidID
   155 		}
   152 		}
   156 		endPoint = "statuses/" + strconv.FormatInt(opts.ID, 10) + "/" + op
   153 		endPoint = "statuses/" + opts.ID + "/" + op
   157 	default:
   154 	default:
   158 		return nil, ErrInvalidParameter
   155 		return nil, ErrInvalidParameter
   159 	}
   156 	}
   160 
   157 
   161 	// Handle target-specific query parameters
   158 	// Handle target-specific query parameters
   171 }
   168 }
   172 
   169 
   173 // GetAccount returns an account entity
   170 // GetAccount returns an account entity
   174 // The returned value can be nil if there is an error or if the
   171 // The returned value can be nil if there is an error or if the
   175 // requested ID does not exist.
   172 // requested ID does not exist.
   176 func (mc *Client) GetAccount(accountID int64) (*Account, error) {
   173 func (mc *Client) GetAccount(accountID ActivityID) (*Account, error) {
   177 	account, err := mc.getSingleAccount("account", accountID)
   174 	account, err := mc.getSingleAccount("account", accountID)
   178 	if err != nil {
   175 	if err != nil {
   179 		return nil, err
   176 		return nil, err
   180 	}
   177 	}
   181 	if account != nil && account.ID == 0 {
   178 	if account != nil && account.ID == "" {
   182 		return nil, ErrEntityNotFound
   179 		return nil, ErrEntityNotFound
   183 	}
   180 	}
   184 	return account, nil
   181 	return account, nil
   185 }
   182 }
   186 
   183 
   187 // GetCurrentAccount returns the current user account
   184 // GetCurrentAccount returns the current user account
   188 func (mc *Client) GetCurrentAccount() (*Account, error) {
   185 func (mc *Client) GetCurrentAccount() (*Account, error) {
   189 	account, err := mc.getSingleAccount("verify_credentials", 0)
   186 	account, err := mc.getSingleAccount("verify_credentials", "")
   190 	if err != nil {
   187 	if err != nil {
   191 		return nil, err
   188 		return nil, err
   192 	}
   189 	}
   193 	if account != nil && account.ID == 0 {
   190 	if account != nil && account.ID == "" {
   194 		return nil, ErrEntityNotFound
   191 		return nil, ErrEntityNotFound
   195 	}
   192 	}
   196 	return account, nil
   193 	return account, nil
   197 }
   194 }
   198 
   195 
   199 // GetAccountFollowers returns the list of accounts following a given account
   196 // GetAccountFollowers returns the list of accounts following a given account
   200 func (mc *Client) GetAccountFollowers(accountID int64, lopt *LimitParams) ([]Account, error) {
   197 func (mc *Client) GetAccountFollowers(accountID ActivityID, lopt *LimitParams) ([]Account, error) {
   201 	o := &getAccountsOptions{ID: accountID, Limit: lopt}
   198 	o := &getAccountsOptions{ID: accountID, Limit: lopt}
   202 	return mc.getMultipleAccountsHelper("followers", o)
   199 	return mc.getMultipleAccountsHelper("followers", o)
   203 }
   200 }
   204 
   201 
   205 // GetAccountFollowing returns the list of accounts a given account is following
   202 // GetAccountFollowing returns the list of accounts a given account is following
   206 func (mc *Client) GetAccountFollowing(accountID int64, lopt *LimitParams) ([]Account, error) {
   203 func (mc *Client) GetAccountFollowing(accountID ActivityID, lopt *LimitParams) ([]Account, error) {
   207 	o := &getAccountsOptions{ID: accountID, Limit: lopt}
   204 	o := &getAccountsOptions{ID: accountID, Limit: lopt}
   208 	return mc.getMultipleAccountsHelper("following", o)
   205 	return mc.getMultipleAccountsHelper("following", o)
   209 }
   206 }
   210 
   207 
   211 // FollowAccount follows an account
   208 // FollowAccount follows an account
   212 // 'reblogs' can be used to specify if boots should be displayed or hidden.
   209 // 'reblogs' can be used to specify if boots should be displayed or hidden.
   213 func (mc *Client) FollowAccount(accountID int64, reblogs *bool) (*Relationship, error) {
   210 func (mc *Client) FollowAccount(accountID ActivityID, reblogs *bool) (*Relationship, error) {
   214 	var params apiCallParams
   211 	var params apiCallParams
   215 	if reblogs != nil {
   212 	if reblogs != nil {
   216 		params = make(apiCallParams)
   213 		params = make(apiCallParams)
   217 		if *reblogs {
   214 		if *reblogs {
   218 			params["reblogs"] = "true"
   215 			params["reblogs"] = "true"
   229 	}
   226 	}
   230 	return rel, nil
   227 	return rel, nil
   231 }
   228 }
   232 
   229 
   233 // UnfollowAccount unfollows an account
   230 // UnfollowAccount unfollows an account
   234 func (mc *Client) UnfollowAccount(accountID int64) (*Relationship, error) {
   231 func (mc *Client) UnfollowAccount(accountID ActivityID) (*Relationship, error) {
   235 	rel, err := mc.updateRelationship("unfollow", accountID, nil)
   232 	rel, err := mc.updateRelationship("unfollow", accountID, nil)
   236 	if err != nil {
   233 	if err != nil {
   237 		return nil, err
   234 		return nil, err
   238 	}
   235 	}
   239 	if rel == nil {
   236 	if rel == nil {
   254 
   251 
   255 	var account Account
   252 	var account Account
   256 	if err := mc.apiCall("v1/follows", rest.Post, params, nil, nil, &account); err != nil {
   253 	if err := mc.apiCall("v1/follows", rest.Post, params, nil, nil, &account); err != nil {
   257 		return nil, err
   254 		return nil, err
   258 	}
   255 	}
   259 	if account.ID == 0 {
   256 	if account.ID == "" {
   260 		return nil, ErrEntityNotFound
   257 		return nil, ErrEntityNotFound
   261 	}
   258 	}
   262 	return &account, nil
   259 	return &account, nil
   263 }
   260 }
   264 
   261 
   265 // BlockAccount blocks an account
   262 // BlockAccount blocks an account
   266 func (mc *Client) BlockAccount(accountID int64) (*Relationship, error) {
   263 func (mc *Client) BlockAccount(accountID ActivityID) (*Relationship, error) {
   267 	rel, err := mc.updateRelationship("block", accountID, nil)
   264 	rel, err := mc.updateRelationship("block", accountID, nil)
   268 	if err != nil {
   265 	if err != nil {
   269 		return nil, err
   266 		return nil, err
   270 	}
   267 	}
   271 	if rel == nil {
   268 	if rel == nil {
   273 	}
   270 	}
   274 	return rel, nil
   271 	return rel, nil
   275 }
   272 }
   276 
   273 
   277 // UnblockAccount unblocks an account
   274 // UnblockAccount unblocks an account
   278 func (mc *Client) UnblockAccount(accountID int64) (*Relationship, error) {
   275 func (mc *Client) UnblockAccount(accountID ActivityID) (*Relationship, error) {
   279 	rel, err := mc.updateRelationship("unblock", accountID, nil)
   276 	rel, err := mc.updateRelationship("unblock", accountID, nil)
   280 	if err != nil {
   277 	if err != nil {
   281 		return nil, err
   278 		return nil, err
   282 	}
   279 	}
   283 	if rel == nil {
   280 	if rel == nil {
   287 }
   284 }
   288 
   285 
   289 // MuteAccount mutes an account
   286 // MuteAccount mutes an account
   290 // Note that with current Mastodon API, muteNotifications defaults to true
   287 // Note that with current Mastodon API, muteNotifications defaults to true
   291 // when it is not provided.
   288 // when it is not provided.
   292 func (mc *Client) MuteAccount(accountID int64, muteNotifications *bool) (*Relationship, error) {
   289 func (mc *Client) MuteAccount(accountID ActivityID, muteNotifications *bool) (*Relationship, error) {
   293 	var params apiCallParams
   290 	var params apiCallParams
   294 
   291 
   295 	if muteNotifications != nil {
   292 	if muteNotifications != nil {
   296 		params = make(apiCallParams)
   293 		params = make(apiCallParams)
   297 		if *muteNotifications {
   294 		if *muteNotifications {
   310 	}
   307 	}
   311 	return rel, nil
   308 	return rel, nil
   312 }
   309 }
   313 
   310 
   314 // UnmuteAccount unmutes an account
   311 // UnmuteAccount unmutes an account
   315 func (mc *Client) UnmuteAccount(accountID int64) (*Relationship, error) {
   312 func (mc *Client) UnmuteAccount(accountID ActivityID) (*Relationship, error) {
   316 	rel, err := mc.updateRelationship("unmute", accountID, nil)
   313 	rel, err := mc.updateRelationship("unmute", accountID, nil)
   317 	if err != nil {
   314 	if err != nil {
   318 		return nil, err
   315 		return nil, err
   319 	}
   316 	}
   320 	if rel == nil {
   317 	if rel == nil {
   350 	o := &getAccountsOptions{Limit: lopt}
   347 	o := &getAccountsOptions{Limit: lopt}
   351 	return mc.getMultipleAccountsHelper("follow_requests", o)
   348 	return mc.getMultipleAccountsHelper("follow_requests", o)
   352 }
   349 }
   353 
   350 
   354 // GetAccountRelationships returns a list of relationship entities for the given accounts
   351 // GetAccountRelationships returns a list of relationship entities for the given accounts
   355 func (mc *Client) GetAccountRelationships(accountIDs []int64) ([]Relationship, error) {
   352 func (mc *Client) GetAccountRelationships(accountIDs []ActivityID) ([]Relationship, error) {
   356 	if len(accountIDs) < 1 {
   353 	if len(accountIDs) < 1 {
   357 		return nil, ErrInvalidID
   354 		return nil, ErrInvalidID
   358 	}
   355 	}
   359 
   356 
   360 	params := make(apiCallParams)
   357 	params := make(apiCallParams)
   361 	for i, id := range accountIDs {
   358 	for i, id := range accountIDs {
   362 		if id < 1 {
   359 		if id == "" {
   363 			return nil, ErrInvalidID
   360 			return nil, ErrInvalidID
   364 		}
   361 		}
   365 		qID := fmt.Sprintf("[%d]id", i)
   362 		qID := fmt.Sprintf("[%d]id", i)
   366 		params[qID] = strconv.FormatInt(id, 10)
   363 		params[qID] = id
   367 	}
   364 	}
   368 
   365 
   369 	var rl []Relationship
   366 	var rl []Relationship
   370 	if err := mc.apiCall("v1/accounts/relationships", rest.Get, params, nil, nil, &rl); err != nil {
   367 	if err := mc.apiCall("v1/accounts/relationships", rest.Get, params, nil, nil, &rl); err != nil {
   371 		return nil, err
   368 		return nil, err
   379 // If excludeReplies is true, skip statuses that reply to other statuses.
   376 // If excludeReplies is true, skip statuses that reply to other statuses.
   380 // If lopt.All is true, several requests will be made until the API server
   377 // If lopt.All is true, several requests will be made until the API server
   381 // has nothing to return.
   378 // has nothing to return.
   382 // If lopt.Limit is set (and not All), several queries can be made until the
   379 // If lopt.Limit is set (and not All), several queries can be made until the
   383 // limit is reached.
   380 // limit is reached.
   384 func (mc *Client) GetAccountStatuses(accountID int64, onlyPinned, onlyMedia, excludeReplies bool, lopt *LimitParams) ([]Status, error) {
   381 func (mc *Client) GetAccountStatuses(accountID ActivityID, onlyPinned, onlyMedia, excludeReplies bool, lopt *LimitParams) ([]Status, error) {
   385 	if accountID < 1 {
   382 	if accountID == "" {
   386 		return nil, ErrInvalidID
   383 		return nil, ErrInvalidID
   387 	}
   384 	}
   388 
   385 
   389 	endPoint := "accounts/" + strconv.FormatInt(accountID, 10) + "/" + "statuses"
   386 	endPoint := "accounts/" + accountID + "/" + "statuses"
   390 	params := make(apiCallParams)
   387 	params := make(apiCallParams)
   391 	if onlyMedia {
   388 	if onlyMedia {
   392 		params["only_media"] = "true"
   389 		params["only_media"] = "true"
   393 	}
   390 	}
   394 	if onlyPinned {
   391 	if onlyPinned {
   400 
   397 
   401 	return mc.getMultipleStatuses(endPoint, params, lopt)
   398 	return mc.getMultipleStatuses(endPoint, params, lopt)
   402 }
   399 }
   403 
   400 
   404 // FollowRequestAuthorize authorizes or rejects an account follow-request
   401 // FollowRequestAuthorize authorizes or rejects an account follow-request
   405 func (mc *Client) FollowRequestAuthorize(accountID int64, authorize bool) error {
   402 func (mc *Client) FollowRequestAuthorize(accountID ActivityID, authorize bool) error {
   406 	endPoint := "follow_requests/reject"
   403 	endPoint := "follow_requests/reject"
   407 	if authorize {
   404 	if authorize {
   408 		endPoint = "follow_requests/authorize"
   405 		endPoint = "follow_requests/authorize"
   409 	}
   406 	}
   410 	_, err := mc.getSingleAccount(endPoint, accountID)
   407 	_, err := mc.getSingleAccount(endPoint, accountID)