friends_followers.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package anaconda
  2. import (
  3. "net/url"
  4. "strconv"
  5. )
  6. type Cursor struct {
  7. Previous_cursor int64
  8. Previous_cursor_str string
  9. Ids []int64
  10. Next_cursor int64
  11. Next_cursor_str string
  12. }
  13. type UserCursor struct {
  14. Previous_cursor int64
  15. Previous_cursor_str string
  16. Next_cursor int64
  17. Next_cursor_str string
  18. Users []User
  19. }
  20. type FriendsIdsCursor struct {
  21. Previous_cursor int64
  22. Previous_cursor_str string
  23. Next_cursor int64
  24. Next_cursor_str string
  25. Ids []int64
  26. }
  27. type FriendsIdsPage struct {
  28. Ids []int64
  29. Error error
  30. }
  31. type Friendship struct {
  32. Name string
  33. Id_str string
  34. Id int64
  35. Connections []string
  36. Screen_name string
  37. }
  38. type FollowersPage struct {
  39. Followers []User
  40. Error error
  41. }
  42. type FriendsPage struct {
  43. Friends []User
  44. Error error
  45. }
  46. // FIXME: Might want to consolidate this with FriendsIdsPage and just
  47. // have "UserIdsPage".
  48. type FollowersIdsPage struct {
  49. Ids []int64
  50. Error error
  51. }
  52. // GetFriendshipsNoRetweets returns a collection of user_ids that the currently authenticated user does not want to receive retweets from.
  53. // It does not currently support the stringify_ids parameter.
  54. func (a TwitterApi) GetFriendshipsNoRetweets() (ids []int64, err error) {
  55. response_ch := make(chan response)
  56. a.queryQueue <- query{a.baseUrl + "/friendships/no_retweets/ids.json", nil, &ids, _GET, response_ch}
  57. return ids, (<-response_ch).err
  58. }
  59. func (a TwitterApi) GetFollowersIds(v url.Values) (c Cursor, err error) {
  60. err = a.apiGet(a.baseUrl+"/followers/ids.json", v, &c)
  61. return
  62. }
  63. // Like GetFollowersIds, but returns a channel instead of a cursor and pre-fetches the remaining results
  64. // This channel is closed once all values have been fetched
  65. func (a TwitterApi) GetFollowersIdsAll(v url.Values) (result chan FollowersIdsPage) {
  66. result = make(chan FollowersIdsPage)
  67. v = cleanValues(v)
  68. go func(a TwitterApi, v url.Values, result chan FollowersIdsPage) {
  69. // Cursor defaults to the first page ("-1")
  70. next_cursor := "-1"
  71. for {
  72. v.Set("cursor", next_cursor)
  73. c, err := a.GetFollowersIds(v)
  74. // throttledQuery() handles all rate-limiting errors
  75. // if GetFollowersList() returns an error, it must be a different kind of error
  76. result <- FollowersIdsPage{c.Ids, err}
  77. next_cursor = c.Next_cursor_str
  78. if err != nil || next_cursor == "0" {
  79. close(result)
  80. break
  81. }
  82. }
  83. }(a, v, result)
  84. return result
  85. }
  86. func (a TwitterApi) GetFriendsIds(v url.Values) (c Cursor, err error) {
  87. response_ch := make(chan response)
  88. a.queryQueue <- query{a.baseUrl + "/friends/ids.json", v, &c, _GET, response_ch}
  89. return c, (<-response_ch).err
  90. }
  91. func (a TwitterApi) GetFriendshipsLookup(v url.Values) (friendships []Friendship, err error) {
  92. response_ch := make(chan response)
  93. a.queryQueue <- query{a.baseUrl + "/friendships/lookup.json", v, &friendships, _GET, response_ch}
  94. return friendships, (<-response_ch).err
  95. }
  96. func (a TwitterApi) GetFriendshipsIncoming(v url.Values) (c Cursor, err error) {
  97. response_ch := make(chan response)
  98. a.queryQueue <- query{a.baseUrl + "/friendships/incoming.json", v, &c, _GET, response_ch}
  99. return c, (<-response_ch).err
  100. }
  101. func (a TwitterApi) GetFriendshipsOutgoing(v url.Values) (c Cursor, err error) {
  102. response_ch := make(chan response)
  103. a.queryQueue <- query{a.baseUrl + "/friendships/outgoing.json", v, &c, _GET, response_ch}
  104. return c, (<-response_ch).err
  105. }
  106. func (a TwitterApi) GetFollowersList(v url.Values) (c UserCursor, err error) {
  107. response_ch := make(chan response)
  108. a.queryQueue <- query{a.baseUrl + "/followers/list.json", v, &c, _GET, response_ch}
  109. return c, (<-response_ch).err
  110. }
  111. func (a TwitterApi) GetFriendsList(v url.Values) (c UserCursor, err error) {
  112. response_ch := make(chan response)
  113. a.queryQueue <- query{a.baseUrl + "/friends/list.json", v, &c, _GET, response_ch}
  114. return c, (<-response_ch).err
  115. }
  116. // Like GetFriendsList, but returns a channel instead of a cursor and pre-fetches the remaining results
  117. // This channel is closed once all values have been fetched
  118. func (a TwitterApi) GetFriendsListAll(v url.Values) (result chan FriendsPage) {
  119. result = make(chan FriendsPage)
  120. v = cleanValues(v)
  121. go func(a TwitterApi, v url.Values, result chan FriendsPage) {
  122. // Cursor defaults to the first page ("-1")
  123. next_cursor := "-1"
  124. for {
  125. v.Set("cursor", next_cursor)
  126. c, err := a.GetFriendsList(v)
  127. // throttledQuery() handles all rate-limiting errors
  128. // if GetFriendsListAll() returns an error, it must be a different kind of error
  129. result <- FriendsPage{c.Users, err}
  130. next_cursor = c.Next_cursor_str
  131. if err != nil || next_cursor == "0" {
  132. close(result)
  133. break
  134. }
  135. }
  136. }(a, v, result)
  137. return result
  138. }
  139. // Like GetFollowersList, but returns a channel instead of a cursor and pre-fetches the remaining results
  140. // This channel is closed once all values have been fetched
  141. func (a TwitterApi) GetFollowersListAll(v url.Values) (result chan FollowersPage) {
  142. result = make(chan FollowersPage)
  143. v = cleanValues(v)
  144. go func(a TwitterApi, v url.Values, result chan FollowersPage) {
  145. // Cursor defaults to the first page ("-1")
  146. next_cursor := "-1"
  147. for {
  148. v.Set("cursor", next_cursor)
  149. c, err := a.GetFollowersList(v)
  150. // throttledQuery() handles all rate-limiting errors
  151. // if GetFollowersList() returns an error, it must be a different kind of error
  152. result <- FollowersPage{c.Users, err}
  153. next_cursor = c.Next_cursor_str
  154. if err != nil || next_cursor == "0" {
  155. close(result)
  156. break
  157. }
  158. }
  159. }(a, v, result)
  160. return result
  161. }
  162. func (a TwitterApi) GetFollowersUser(id int64, v url.Values) (c Cursor, err error) {
  163. v = cleanValues(v)
  164. v.Set("user_id", strconv.FormatInt(id, 10))
  165. response_ch := make(chan response)
  166. a.queryQueue <- query{a.baseUrl + "/followers/ids.json", v, &c, _GET, response_ch}
  167. return c, (<-response_ch).err
  168. }
  169. // Like GetFriendsIds, but returns a channel instead of a cursor and pre-fetches the remaining results
  170. // This channel is closed once all values have been fetched
  171. func (a TwitterApi) GetFriendsIdsAll(v url.Values) (result chan FriendsIdsPage) {
  172. result = make(chan FriendsIdsPage)
  173. v = cleanValues(v)
  174. go func(a TwitterApi, v url.Values, result chan FriendsIdsPage) {
  175. // Cursor defaults to the first page ("-1")
  176. next_cursor := "-1"
  177. for {
  178. v.Set("cursor", next_cursor)
  179. c, err := a.GetFriendsIds(v)
  180. // throttledQuery() handles all rate-limiting errors
  181. // if GetFollowersList() returns an error, it must be a different kind of error
  182. result <- FriendsIdsPage{c.Ids, err}
  183. next_cursor = c.Next_cursor_str
  184. if err != nil || next_cursor == "0" {
  185. close(result)
  186. break
  187. }
  188. }
  189. }(a, v, result)
  190. return result
  191. }
  192. func (a TwitterApi) GetFriendsUser(id int64, v url.Values) (c Cursor, err error) {
  193. v = cleanValues(v)
  194. v.Set("user_id", strconv.FormatInt(id, 10))
  195. response_ch := make(chan response)
  196. a.queryQueue <- query{a.baseUrl + "/friends/ids.json", v, &c, _GET, response_ch}
  197. return c, (<-response_ch).err
  198. }
  199. // FollowUserId follows the user with the specified userId.
  200. // This implements the /friendships/create endpoint, though the function name
  201. // uses the terminology 'follow' as this is most consistent with colloquial Twitter terminology.
  202. func (a TwitterApi) FollowUserId(userId int64, v url.Values) (user User, err error) {
  203. v = cleanValues(v)
  204. v.Set("user_id", strconv.FormatInt(userId, 10))
  205. return a.postFriendshipsCreateImpl(v)
  206. }
  207. // FollowUserId follows the user with the specified screenname (username).
  208. // This implements the /friendships/create endpoint, though the function name
  209. // uses the terminology 'follow' as this is most consistent with colloquial Twitter terminology.
  210. func (a TwitterApi) FollowUser(screenName string) (user User, err error) {
  211. v := url.Values{}
  212. v.Set("screen_name", screenName)
  213. return a.postFriendshipsCreateImpl(v)
  214. }
  215. func (a TwitterApi) postFriendshipsCreateImpl(v url.Values) (user User, err error) {
  216. response_ch := make(chan response)
  217. a.queryQueue <- query{a.baseUrl + "/friendships/create.json", v, &user, _POST, response_ch}
  218. return user, (<-response_ch).err
  219. }
  220. // UnfollowUserId unfollows the user with the specified userId.
  221. // This implements the /friendships/destroy endpoint, though the function name
  222. // uses the terminology 'unfollow' as this is most consistent with colloquial Twitter terminology.
  223. func (a TwitterApi) UnfollowUserId(userId int64) (u User, err error) {
  224. v := url.Values{}
  225. v.Set("user_id", strconv.FormatInt(userId, 10))
  226. // Set other values before calling this method:
  227. // page, count, include_entities
  228. response_ch := make(chan response)
  229. a.queryQueue <- query{a.baseUrl + "/friendships/destroy.json", v, &u, _POST, response_ch}
  230. return u, (<-response_ch).err
  231. }
  232. // UnfollowUser unfollows the user with the specified screenname (username)
  233. // This implements the /friendships/destroy endpoint, though the function name
  234. // uses the terminology 'unfollow' as this is most consistent with colloquial Twitter terminology.
  235. func (a TwitterApi) UnfollowUser(screenname string) (u User, err error) {
  236. v := url.Values{}
  237. v.Set("screen_name", screenname)
  238. // Set other values before calling this method:
  239. // page, count, include_entities
  240. response_ch := make(chan response)
  241. a.queryQueue <- query{a.baseUrl + "/friendships/destroy.json", v, &u, _POST, response_ch}
  242. return u, (<-response_ch).err
  243. }