gs_graph 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. data/.document +5 -0
  2. data/.gitattributes +22 -0
  3. data/.gitignore +26 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +3 -0
  6. data/Gemfile +11 -0
  7. data/Gemfile.lock +95 -0
  8. data/LICENSE +20 -0
  9. data/README.rdoc +314 -0
  10. data/Rakefile +25 -0
  11. data/VERSION +1 -0
  12. data/assets/fb_graph.ai +1726 -6
  13. data/assets/fb_graph.png +0 -0
  14. data/gs_graph.gemspec +28 -0
  15. data/lib/gs_graph.rb +174 -0
  16. data/lib/gs_graph/achievement.rb +44 -0
  17. data/lib/gs_graph/action.rb +12 -0
  18. data/lib/gs_graph/ad_account.rb +51 -0
  19. data/lib/gs_graph/ad_campaign.rb +39 -0
  20. data/lib/gs_graph/ad_campaign_stat.rb +22 -0
  21. data/lib/gs_graph/ad_connection_object.rb +53 -0
  22. data/lib/gs_graph/ad_creative.rb +44 -0
  23. data/lib/gs_graph/ad_group.rb +51 -0
  24. data/lib/gs_graph/ad_group_stat.rb +22 -0
  25. data/lib/gs_graph/ad_keyword.rb +20 -0
  26. data/lib/gs_graph/ad_keyword_suggestion.rb +8 -0
  27. data/lib/gs_graph/ad_keyword_valid.rb +23 -0
  28. data/lib/gs_graph/ad_preview.rb +10 -0
  29. data/lib/gs_graph/ad_user.rb +58 -0
  30. data/lib/gs_graph/age_range.rb +12 -0
  31. data/lib/gs_graph/album.rb +59 -0
  32. data/lib/gs_graph/app_request.rb +24 -0
  33. data/lib/gs_graph/application.rb +119 -0
  34. data/lib/gs_graph/auth.rb +88 -0
  35. data/lib/gs_graph/auth/cookie.rb +20 -0
  36. data/lib/gs_graph/auth/signed_request.rb +44 -0
  37. data/lib/gs_graph/broad_targeting_category.rb +13 -0
  38. data/lib/gs_graph/checkin.rb +51 -0
  39. data/lib/gs_graph/collection.rb +55 -0
  40. data/lib/gs_graph/comment.rb +24 -0
  41. data/lib/gs_graph/comparison.rb +13 -0
  42. data/lib/gs_graph/connection.rb +37 -0
  43. data/lib/gs_graph/connections.rb +3 -0
  44. data/lib/gs_graph/connections/accounts.rb +23 -0
  45. data/lib/gs_graph/connections/achievements.rb +21 -0
  46. data/lib/gs_graph/connections/activities.rb +14 -0
  47. data/lib/gs_graph/connections/ad_accounts.rb +15 -0
  48. data/lib/gs_graph/connections/ad_campaign_stats.rb +22 -0
  49. data/lib/gs_graph/connections/ad_campaigns.rb +30 -0
  50. data/lib/gs_graph/connections/ad_connection_objects.rb +14 -0
  51. data/lib/gs_graph/connections/ad_creatives.rb +14 -0
  52. data/lib/gs_graph/connections/ad_group_stats.rb +22 -0
  53. data/lib/gs_graph/connections/ad_groups.rb +35 -0
  54. data/lib/gs_graph/connections/ad_previews.rb +10 -0
  55. data/lib/gs_graph/connections/admins.rb +10 -0
  56. data/lib/gs_graph/connections/albums.rb +21 -0
  57. data/lib/gs_graph/connections/app_notifications.rb +10 -0
  58. data/lib/gs_graph/connections/app_requests.rb +21 -0
  59. data/lib/gs_graph/connections/attending.rb +26 -0
  60. data/lib/gs_graph/connections/banned.rb +31 -0
  61. data/lib/gs_graph/connections/blocked.rb +36 -0
  62. data/lib/gs_graph/connections/books.rb +14 -0
  63. data/lib/gs_graph/connections/broad_targeting_categories.rb +14 -0
  64. data/lib/gs_graph/connections/checkins.rb +21 -0
  65. data/lib/gs_graph/connections/comments.rb +21 -0
  66. data/lib/gs_graph/connections/conversations.rb +14 -0
  67. data/lib/gs_graph/connections/declined.rb +25 -0
  68. data/lib/gs_graph/connections/docs.rb +14 -0
  69. data/lib/gs_graph/connections/events.rb +21 -0
  70. data/lib/gs_graph/connections/family.rb +14 -0
  71. data/lib/gs_graph/connections/feed.rb +21 -0
  72. data/lib/gs_graph/connections/former_participants.rb +14 -0
  73. data/lib/gs_graph/connections/friend_lists.rb +21 -0
  74. data/lib/gs_graph/connections/friend_requests.rb +12 -0
  75. data/lib/gs_graph/connections/friends.rb +14 -0
  76. data/lib/gs_graph/connections/games.rb +14 -0
  77. data/lib/gs_graph/connections/groups.rb +14 -0
  78. data/lib/gs_graph/connections/home.rb +14 -0
  79. data/lib/gs_graph/connections/inbox.rb +20 -0
  80. data/lib/gs_graph/connections/insights.rb +27 -0
  81. data/lib/gs_graph/connections/interests.rb +14 -0
  82. data/lib/gs_graph/connections/invited.rb +36 -0
  83. data/lib/gs_graph/connections/likes.rb +29 -0
  84. data/lib/gs_graph/connections/links.rb +21 -0
  85. data/lib/gs_graph/connections/maybe.rb +25 -0
  86. data/lib/gs_graph/connections/members.rb +22 -0
  87. data/lib/gs_graph/connections/messages.rb +22 -0
  88. data/lib/gs_graph/connections/milestones.rb +21 -0
  89. data/lib/gs_graph/connections/movies.rb +14 -0
  90. data/lib/gs_graph/connections/music.rb +14 -0
  91. data/lib/gs_graph/connections/mutual_friends.rb +26 -0
  92. data/lib/gs_graph/connections/noreply.rb +23 -0
  93. data/lib/gs_graph/connections/notes.rb +21 -0
  94. data/lib/gs_graph/connections/notifications.rb +18 -0
  95. data/lib/gs_graph/connections/offers.rb +22 -0
  96. data/lib/gs_graph/connections/outbox.rb +20 -0
  97. data/lib/gs_graph/connections/participants.rb +14 -0
  98. data/lib/gs_graph/connections/payments.rb +14 -0
  99. data/lib/gs_graph/connections/permissions.rb +16 -0
  100. data/lib/gs_graph/connections/photos.rb +21 -0
  101. data/lib/gs_graph/connections/picture.rb +39 -0
  102. data/lib/gs_graph/connections/pokes.rb +12 -0
  103. data/lib/gs_graph/connections/posts.rb +14 -0
  104. data/lib/gs_graph/connections/promotable_posts.rb +14 -0
  105. data/lib/gs_graph/connections/question_options.rb +14 -0
  106. data/lib/gs_graph/connections/questions.rb +22 -0
  107. data/lib/gs_graph/connections/reach_estimates.rb +12 -0
  108. data/lib/gs_graph/connections/roles.rb +36 -0
  109. data/lib/gs_graph/connections/scores.rb +22 -0
  110. data/lib/gs_graph/connections/senders.rb +14 -0
  111. data/lib/gs_graph/connections/settings.rb +65 -0
  112. data/lib/gs_graph/connections/statuses.rb +14 -0
  113. data/lib/gs_graph/connections/subscribed_to.rb +14 -0
  114. data/lib/gs_graph/connections/subscribers.rb +14 -0
  115. data/lib/gs_graph/connections/subscriptions.rb +53 -0
  116. data/lib/gs_graph/connections/tabs.rb +23 -0
  117. data/lib/gs_graph/connections/tagged.rb +14 -0
  118. data/lib/gs_graph/connections/tags.rb +23 -0
  119. data/lib/gs_graph/connections/television.rb +14 -0
  120. data/lib/gs_graph/connections/test_users.rb +19 -0
  121. data/lib/gs_graph/connections/threads.rb +14 -0
  122. data/lib/gs_graph/connections/user_achievements.rb +22 -0
  123. data/lib/gs_graph/connections/user_likes.rb +19 -0
  124. data/lib/gs_graph/connections/videos.rb +21 -0
  125. data/lib/gs_graph/connections/votes.rb +9 -0
  126. data/lib/gs_graph/cover.rb +10 -0
  127. data/lib/gs_graph/debugger.rb +28 -0
  128. data/lib/gs_graph/device.rb +11 -0
  129. data/lib/gs_graph/doc.rb +18 -0
  130. data/lib/gs_graph/domain.rb +32 -0
  131. data/lib/gs_graph/education.rb +32 -0
  132. data/lib/gs_graph/event.rb +52 -0
  133. data/lib/gs_graph/exception.rb +139 -0
  134. data/lib/gs_graph/friend_list.rb +13 -0
  135. data/lib/gs_graph/friend_request.rb +14 -0
  136. data/lib/gs_graph/group.rb +29 -0
  137. data/lib/gs_graph/image.rb +11 -0
  138. data/lib/gs_graph/insight.rb +13 -0
  139. data/lib/gs_graph/klass.rb +31 -0
  140. data/lib/gs_graph/link.rb +32 -0
  141. data/lib/gs_graph/location.rb +20 -0
  142. data/lib/gs_graph/message.rb +30 -0
  143. data/lib/gs_graph/milestone.rb +26 -0
  144. data/lib/gs_graph/node.rb +149 -0
  145. data/lib/gs_graph/note.rb +32 -0
  146. data/lib/gs_graph/notification.rb +32 -0
  147. data/lib/gs_graph/offer.rb +33 -0
  148. data/lib/gs_graph/open_graph.rb +3 -0
  149. data/lib/gs_graph/open_graph/action.rb +42 -0
  150. data/lib/gs_graph/open_graph/application_context.rb +10 -0
  151. data/lib/gs_graph/open_graph/object.rb +29 -0
  152. data/lib/gs_graph/open_graph/user_context.rb +21 -0
  153. data/lib/gs_graph/order.rb +55 -0
  154. data/lib/gs_graph/page.rb +57 -0
  155. data/lib/gs_graph/page/category_attributes.rb +117 -0
  156. data/lib/gs_graph/photo.rb +48 -0
  157. data/lib/gs_graph/picture.rb +14 -0
  158. data/lib/gs_graph/place.rb +7 -0
  159. data/lib/gs_graph/poke.rb +19 -0
  160. data/lib/gs_graph/post.rb +117 -0
  161. data/lib/gs_graph/privacy.rb +27 -0
  162. data/lib/gs_graph/project.rb +4 -0
  163. data/lib/gs_graph/promotable_post.rb +34 -0
  164. data/lib/gs_graph/property.rb +13 -0
  165. data/lib/gs_graph/query.rb +47 -0
  166. data/lib/gs_graph/question.rb +26 -0
  167. data/lib/gs_graph/question_option.rb +22 -0
  168. data/lib/gs_graph/reach_estimate.rb +22 -0
  169. data/lib/gs_graph/role.rb +13 -0
  170. data/lib/gs_graph/score.rb +16 -0
  171. data/lib/gs_graph/searchable.rb +33 -0
  172. data/lib/gs_graph/searchable/result.rb +31 -0
  173. data/lib/gs_graph/serialization.rb +19 -0
  174. data/lib/gs_graph/status.rb +27 -0
  175. data/lib/gs_graph/subscription.rb +14 -0
  176. data/lib/gs_graph/tab.rb +17 -0
  177. data/lib/gs_graph/tag.rb +30 -0
  178. data/lib/gs_graph/tagged_object.rb +23 -0
  179. data/lib/gs_graph/targeting.rb +23 -0
  180. data/lib/gs_graph/test_user.rb +24 -0
  181. data/lib/gs_graph/thread.rb +71 -0
  182. data/lib/gs_graph/user.rb +153 -0
  183. data/lib/gs_graph/user_achievement.rb +35 -0
  184. data/lib/gs_graph/venue.rb +14 -0
  185. data/lib/gs_graph/video.rb +41 -0
  186. data/lib/gs_graph/work.rb +48 -0
  187. data/lib/patch/rack/oauth2/access_token.rb +11 -0
  188. data/lib/patch/rack/oauth2/access_token/introspectable.rb +37 -0
  189. data/lib/patch/rack/oauth2/client.rb +13 -0
  190. data/lib/patch/rack/oauth2/grant/fb_exchange_token.rb +11 -0
  191. data/lib/patch/rack/oauth2/util.rb +14 -0
  192. data/spec/gs_graph/achievement_spec.rb +59 -0
  193. data/spec/gs_graph/ad_account_spec.rb +124 -0
  194. data/spec/gs_graph/ad_campaign_spec.rb +99 -0
  195. data/spec/gs_graph/ad_connection_object_spec.rb +71 -0
  196. data/spec/gs_graph/ad_creative_spec.rb +87 -0
  197. data/spec/gs_graph/ad_group_spec.rb +95 -0
  198. data/spec/gs_graph/ad_keyword_spec.rb +27 -0
  199. data/spec/gs_graph/ad_keyword_suggestion_spec.rb +17 -0
  200. data/spec/gs_graph/ad_keyword_valid_spec.rb +19 -0
  201. data/spec/gs_graph/ad_user_spec.rb +67 -0
  202. data/spec/gs_graph/album_spec.rb +93 -0
  203. data/spec/gs_graph/app_request_spec.rb +40 -0
  204. data/spec/gs_graph/application_spec.rb +251 -0
  205. data/spec/gs_graph/auth/cookie_spec.rb +29 -0
  206. data/spec/gs_graph/auth/signed_request_spec.rb +22 -0
  207. data/spec/gs_graph/auth_spec.rb +223 -0
  208. data/spec/gs_graph/broad_targeting_category_spec.rb +17 -0
  209. data/spec/gs_graph/checkin_spec.rb +42 -0
  210. data/spec/gs_graph/collection_spec.rb +50 -0
  211. data/spec/gs_graph/comment_spec.rb +31 -0
  212. data/spec/gs_graph/connection_spec.rb +42 -0
  213. data/spec/gs_graph/connections/accounts_spec.rb +78 -0
  214. data/spec/gs_graph/connections/achievements_spec.rb +27 -0
  215. data/spec/gs_graph/connections/activities_spec.rb +34 -0
  216. data/spec/gs_graph/connections/ad_accounts_spec.rb +28 -0
  217. data/spec/gs_graph/connections/ad_campaign_stat_spec.rb +35 -0
  218. data/spec/gs_graph/connections/ad_campaigns_spec.rb +36 -0
  219. data/spec/gs_graph/connections/ad_connection_objects_spec.rb +20 -0
  220. data/spec/gs_graph/connections/ad_creatives_spec.rb +29 -0
  221. data/spec/gs_graph/connections/ad_group_stat_spec.rb +54 -0
  222. data/spec/gs_graph/connections/ad_groups_spec.rb +92 -0
  223. data/spec/gs_graph/connections/ad_previews_spec.rb +18 -0
  224. data/spec/gs_graph/connections/admins_spec.rb +20 -0
  225. data/spec/gs_graph/connections/albums_spec.rb +63 -0
  226. data/spec/gs_graph/connections/app_notifications_spec.rb +23 -0
  227. data/spec/gs_graph/connections/app_requests_spec.rb +28 -0
  228. data/spec/gs_graph/connections/attending_spec.rb +47 -0
  229. data/spec/gs_graph/connections/banned_spec.rb +63 -0
  230. data/spec/gs_graph/connections/blocked_spec.rb +56 -0
  231. data/spec/gs_graph/connections/books_spec.rb +32 -0
  232. data/spec/gs_graph/connections/broad_targeting_categories_spec.rb +18 -0
  233. data/spec/gs_graph/connections/checkins_spec.rb +153 -0
  234. data/spec/gs_graph/connections/comments_spec.rb +75 -0
  235. data/spec/gs_graph/connections/conversations_spec.rb +19 -0
  236. data/spec/gs_graph/connections/declined_spec.rb +47 -0
  237. data/spec/gs_graph/connections/docs_spec.rb +14 -0
  238. data/spec/gs_graph/connections/events_spec.rb +52 -0
  239. data/spec/gs_graph/connections/family_spec.rb +32 -0
  240. data/spec/gs_graph/connections/feed_spec.rb +124 -0
  241. data/spec/gs_graph/connections/former_participants_spec.rb +44 -0
  242. data/spec/gs_graph/connections/friend_lists_spec.rb +26 -0
  243. data/spec/gs_graph/connections/friend_requests_spec.rb +16 -0
  244. data/spec/gs_graph/connections/friends_spec.rb +51 -0
  245. data/spec/gs_graph/connections/games_spec.rb +20 -0
  246. data/spec/gs_graph/connections/groups_spec.rb +31 -0
  247. data/spec/gs_graph/connections/home_spec.rb +62 -0
  248. data/spec/gs_graph/connections/inbox_spec.rb +16 -0
  249. data/spec/gs_graph/connections/insights_spec.rb +104 -0
  250. data/spec/gs_graph/connections/interests_spec.rb +12 -0
  251. data/spec/gs_graph/connections/invited_spec.rb +84 -0
  252. data/spec/gs_graph/connections/likes_spec.rb +127 -0
  253. data/spec/gs_graph/connections/links_spec.rb +31 -0
  254. data/spec/gs_graph/connections/maybe_spec.rb +47 -0
  255. data/spec/gs_graph/connections/members_spec.rb +57 -0
  256. data/spec/gs_graph/connections/messages_spec.rb +58 -0
  257. data/spec/gs_graph/connections/milestones_spec.rb +40 -0
  258. data/spec/gs_graph/connections/movies_spec.rb +12 -0
  259. data/spec/gs_graph/connections/music_spec.rb +12 -0
  260. data/spec/gs_graph/connections/mutual_friends_spec.rb +28 -0
  261. data/spec/gs_graph/connections/noreply_spec.rb +39 -0
  262. data/spec/gs_graph/connections/notes_spec.rb +31 -0
  263. data/spec/gs_graph/connections/notifications_spec.rb +30 -0
  264. data/spec/gs_graph/connections/outbox_spec.rb +16 -0
  265. data/spec/gs_graph/connections/participants_spec.rb +42 -0
  266. data/spec/gs_graph/connections/payments_spec.rb +17 -0
  267. data/spec/gs_graph/connections/permissions_spec.rb +44 -0
  268. data/spec/gs_graph/connections/photos_spec.rb +39 -0
  269. data/spec/gs_graph/connections/picture_spec.rb +92 -0
  270. data/spec/gs_graph/connections/pokes_spec.rb +16 -0
  271. data/spec/gs_graph/connections/posts_spec.rb +34 -0
  272. data/spec/gs_graph/connections/promotable_posts_spec.rb +24 -0
  273. data/spec/gs_graph/connections/question_options_spec.rb +14 -0
  274. data/spec/gs_graph/connections/questions_spec.rb +31 -0
  275. data/spec/gs_graph/connections/reach_estimates_spec.rb +18 -0
  276. data/spec/gs_graph/connections/roles_spec.rb +59 -0
  277. data/spec/gs_graph/connections/scores_spec.rb +40 -0
  278. data/spec/gs_graph/connections/senders_spec.rb +42 -0
  279. data/spec/gs_graph/connections/settings_spec.rb +62 -0
  280. data/spec/gs_graph/connections/statuses_spec.rb +72 -0
  281. data/spec/gs_graph/connections/subscribed_to_spec.rb +12 -0
  282. data/spec/gs_graph/connections/subscribers_spec.rb +12 -0
  283. data/spec/gs_graph/connections/subscriptions_spec.rb +47 -0
  284. data/spec/gs_graph/connections/tabs_spec.rb +47 -0
  285. data/spec/gs_graph/connections/tagged_spec.rb +42 -0
  286. data/spec/gs_graph/connections/tags_spec.rb +30 -0
  287. data/spec/gs_graph/connections/television_spec.rb +12 -0
  288. data/spec/gs_graph/connections/test_users_spec.rb +65 -0
  289. data/spec/gs_graph/connections/threads_spec.rb +12 -0
  290. data/spec/gs_graph/connections/user_achievements_spec.rb +37 -0
  291. data/spec/gs_graph/connections/user_likes_spec.rb +55 -0
  292. data/spec/gs_graph/connections/videos_spec.rb +27 -0
  293. data/spec/gs_graph/connections/votes_spec.rb +15 -0
  294. data/spec/gs_graph/debugger_spec.rb +33 -0
  295. data/spec/gs_graph/doc_spec.rb +27 -0
  296. data/spec/gs_graph/domain_spec.rb +23 -0
  297. data/spec/gs_graph/education_spec.rb +61 -0
  298. data/spec/gs_graph/event_spec.rb +70 -0
  299. data/spec/gs_graph/exception_spec.rb +310 -0
  300. data/spec/gs_graph/friend_list_spec.rb +22 -0
  301. data/spec/gs_graph/group_spec.rb +28 -0
  302. data/spec/gs_graph/image_spec.rb +16 -0
  303. data/spec/gs_graph/insight_spec.rb +18 -0
  304. data/spec/gs_graph/link_spec.rb +41 -0
  305. data/spec/gs_graph/location_spec.rb +28 -0
  306. data/spec/gs_graph/message_spec.rb +47 -0
  307. data/spec/gs_graph/node_spec.rb +91 -0
  308. data/spec/gs_graph/note_spec.rb +37 -0
  309. data/spec/gs_graph/notification_spec.rb +59 -0
  310. data/spec/gs_graph/offer_spec.rb +30 -0
  311. data/spec/gs_graph/open_graph/action_spec.rb +112 -0
  312. data/spec/gs_graph/open_graph/application_context_spec.rb +28 -0
  313. data/spec/gs_graph/open_graph/object_spec.rb +76 -0
  314. data/spec/gs_graph/open_graph/user_context_spec.rb +33 -0
  315. data/spec/gs_graph/order_spec.rb +66 -0
  316. data/spec/gs_graph/page/local_business_spec.rb +88 -0
  317. data/spec/gs_graph/page/movie_spec.rb +25 -0
  318. data/spec/gs_graph/page/music_spec.rb +25 -0
  319. data/spec/gs_graph/page/person_spec.rb +23 -0
  320. data/spec/gs_graph/page/product_spec.rb +36 -0
  321. data/spec/gs_graph/page_spec.rb +81 -0
  322. data/spec/gs_graph/photo_spec.rb +85 -0
  323. data/spec/gs_graph/place_spec.rb +8 -0
  324. data/spec/gs_graph/post_spec.rb +238 -0
  325. data/spec/gs_graph/privacy_spec.rb +33 -0
  326. data/spec/gs_graph/project_spec.rb +46 -0
  327. data/spec/gs_graph/promotable_post_spec.rb +57 -0
  328. data/spec/gs_graph/qeustion_option_spec.rb +35 -0
  329. data/spec/gs_graph/query_spec.rb +73 -0
  330. data/spec/gs_graph/question_spec.rb +73 -0
  331. data/spec/gs_graph/reach_estimate_spec.rb +48 -0
  332. data/spec/gs_graph/searchable_spec.rb +47 -0
  333. data/spec/gs_graph/seriarization_spec.rb +29 -0
  334. data/spec/gs_graph/status_spec.rb +31 -0
  335. data/spec/gs_graph/subscription_spec.rb +5 -0
  336. data/spec/gs_graph/tag_spec.rb +34 -0
  337. data/spec/gs_graph/tagged_object_spec.rb +45 -0
  338. data/spec/gs_graph/targeting_spec.rb +34 -0
  339. data/spec/gs_graph/test_user_spec.rb +50 -0
  340. data/spec/gs_graph/thread_spec.rb +86 -0
  341. data/spec/gs_graph/user_achievement_spec.rb +53 -0
  342. data/spec/gs_graph/user_spec.rb +185 -0
  343. data/spec/gs_graph/venue_spec.rb +23 -0
  344. data/spec/gs_graph/video_spec.rb +31 -0
  345. data/spec/gs_graph/work_spec.rb +101 -0
  346. data/spec/gs_graph_spec.rb +57 -0
  347. data/spec/spec_helper.rb +9 -0
  348. metadata +538 -0
@@ -0,0 +1,139 @@
1
+ module GSGraph
2
+ class Exception < StandardError
3
+ attr_accessor :code, :type
4
+
5
+ ERROR_HEADER_MATCHERS = {
6
+ /invalid_token/ => "InvalidToken",
7
+ /invalid_request/ => "InvalidRequest"
8
+ }
9
+
10
+ ERROR_EXCEPTION_MATCHERS = {
11
+ /Could\snot\ssave\screative/ => "CreativeNotSaved",
12
+ /QueryLockTimeoutException/ => "QueryLockTimeout",
13
+ /Could\snot\screate\stargeting\sspec/ => "TargetingSpecNotSaved",
14
+ /Could\snot\sfetch\sadgroups/ => "AdgroupFetchFailure",
15
+ /Failed\sto\sopen\sprocess/ => "OpenProcessFailure",
16
+ /Could\snot\scommit\stransaction/ => "TransactionCommitFailure",
17
+ /QueryErrorException/ => "QueryError",
18
+ /QueryConnectionException/ => "QueryConnection",
19
+ /QueryDuplicateKeyException/ => "QueryDuplicateKey"
20
+ }
21
+
22
+ def self.handle_httpclient_error(response, headers)
23
+ return nil unless (response[:error] || response[:error_code] || response[:error_msg])
24
+
25
+ # Sometimes we see an error that does not have the "error" field, but instead has both "error_code" and "error_msg"
26
+ # example: {"error_code":1,"error_msg":"An unknown error occurred"}
27
+ if (response[:error_code] && response[:error_msg] && !response[:error])
28
+ raise InternalServerError.new("#{response[:error_code]} :: #{response[:error_msg]}")
29
+ end
30
+
31
+ # Check the WWW-Authenticate header, since it seems to be more standardized than the response
32
+ # body error information.
33
+ # The complex lookup is needed to follow the HTTP spec - headers should be looked up
34
+ # without regard to case.
35
+ www_authenticate = headers.select do |name, value|
36
+ name.upcase == "WWW-Authenticate".upcase
37
+ end.to_a.flatten.second
38
+ if www_authenticate
39
+ # Session expiration/invalidation is very common. Check for that first.
40
+ if www_authenticate =~ /invalid_token/ && response[:error][:message] =~ /session has been invalidated/
41
+ raise InvalidSession.new("#{response[:error][:type]} :: #{response[:error][:message]}")
42
+ end
43
+
44
+ ERROR_HEADER_MATCHERS.keys.each do |matcher|
45
+ if matcher =~ www_authenticate
46
+ exception_class = GSGraph::const_get(ERROR_HEADER_MATCHERS[matcher])
47
+ raise exception_class.new("#{response[:error][:type]} :: #{response[:error][:message]}")
48
+ end
49
+ end
50
+ end
51
+
52
+ # If we can't match on WWW-Authenticate, use the type
53
+ case response[:error][:type]
54
+ when /OAuth/
55
+ raise Unauthorized.new("#{response[:error][:type]} :: #{response[:error][:message]}")
56
+ else
57
+ exception_class = nil
58
+ ERROR_EXCEPTION_MATCHERS.keys.each do |matcher|
59
+ exception_class = GSGraph::const_get(ERROR_EXCEPTION_MATCHERS[matcher]) if matcher =~ response[:error][:message]
60
+ end
61
+ if exception_class
62
+ raise exception_class.new("#{response[:error][:type]} :: #{response[:error][:message]}")
63
+ else
64
+ raise BadRequest.new("#{response[:error][:type]} :: #{response[:error][:message]}")
65
+ end
66
+ end
67
+ end
68
+
69
+ def self.handle_rack_oauth2_error(e)
70
+ exception = case e.status
71
+ when 400
72
+ BadRequest.new(e.message)
73
+ when 401
74
+ Unauthorized.new(e.message)
75
+ else
76
+ Exception.new(e.status, e.message)
77
+ end
78
+ raise exception
79
+ end
80
+
81
+ def initialize(code, message, body = '')
82
+ @code = code
83
+ if body.present?
84
+ response = MultiJson.load(body).with_indifferent_access
85
+ message = response[:error][:message]
86
+ @type = response[:error][:type]
87
+ end
88
+ super message
89
+ end
90
+ end
91
+
92
+ class BadRequest < Exception
93
+ def initialize(message, body = '')
94
+ super 400, message, body
95
+ end
96
+ end
97
+
98
+ class Unauthorized < Exception
99
+ def initialize(message, body = '')
100
+ super 401, message, body
101
+ end
102
+ end
103
+
104
+ class NotFound < Exception
105
+ def initialize(message, body = '')
106
+ super 404, message, body
107
+ end
108
+ end
109
+
110
+ class InternalServerError < Exception
111
+ def initialize(message, body = '')
112
+ super 500, message, body
113
+ end
114
+ end
115
+
116
+ class InvalidToken < Unauthorized; end
117
+
118
+ class InvalidSession < InvalidToken; end
119
+
120
+ class InvalidRequest < BadRequest; end
121
+
122
+ class CreativeNotSaved < InternalServerError; end
123
+
124
+ class QueryLockTimeout < InternalServerError; end
125
+
126
+ class TargetingSpecNotSaved < InternalServerError; end
127
+
128
+ class AdgroupFetchFailure < InternalServerError; end
129
+
130
+ class OpenProcessFailure < InternalServerError; end
131
+
132
+ class TransactionCommitFailure < InternalServerError; end
133
+
134
+ class QueryError < InternalServerError; end
135
+
136
+ class QueryConnection < InternalServerError; end
137
+
138
+ class QueryDuplicateKey < InternalServerError; end
139
+ end
@@ -0,0 +1,13 @@
1
+ module GSGraph
2
+ class FriendList < Node
3
+ include Connections::Members
4
+
5
+ attr_accessor :name, :list_type
6
+
7
+ def initialize(identifier, attributes = {})
8
+ super
9
+ @name = attributes[:name]
10
+ @list_type = attributes[:list_type]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module GSGraph
2
+ class FriendRequest
3
+ include Comparison
4
+ attr_accessor :from, :to, :created_time, :message, :unread
5
+
6
+ def initialize(attributes = {})
7
+ @from = User.new attributes[:from]
8
+ @to = User.new attributes[:to]
9
+ @created_time = Time.parse attributes[:created_time]
10
+ @message = attributes[:message]
11
+ @unread = attributes[:unread]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module GSGraph
2
+ class Group < Node
3
+ include Connections::Docs
4
+ include Connections::Feed
5
+ include Connections::Members
6
+ include Connections::Picture
7
+ include Connections::Videos
8
+ extend Searchable
9
+
10
+ attr_accessor :owner, :name, :email, :description, :link, :icon, :privacy, :version, :updated_time
11
+
12
+ def initialize(identifier, attributes = {})
13
+ super
14
+ if (owner = attributes[:owner])
15
+ @owner = User.new(owner[:id], owner)
16
+ end
17
+ @name = attributes[:name]
18
+ @email = attributes[:email]
19
+ @description = attributes[:description]
20
+ @link = attributes[:link]
21
+ @icon = attributes[:icon]
22
+ @privacy = attributes[:privacy]
23
+ @version = attributes[:version]
24
+ if attributes[:updated_time]
25
+ @updated_time = Time.parse(attributes[:updated_time]).utc
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ module GSGraph
2
+ class Image
3
+ include Comparison
4
+ attr_accessor :source, :height, :width
5
+ def initialize(attributes = {})
6
+ @source = attributes[:source]
7
+ @height = attributes[:height]
8
+ @width = attributes[:width]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module GSGraph
2
+ class Insight < Node
3
+ attr_accessor :name, :period, :values, :description
4
+
5
+ def initialize(identifier, attributes = {})
6
+ super
7
+ @name = attributes[:name]
8
+ @period = attributes[:period]
9
+ @values = attributes[:values].collect(&:with_indifferent_access)
10
+ @description = attributes[:description]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ module GSGraph
2
+ class Klass < Page
3
+ attr_accessor :with, :start_date, :end_date
4
+
5
+ def initialize(identifier, attributes = {})
6
+ super
7
+ @with = []
8
+ if attributes[:with]
9
+ attributes[:with].each do |user|
10
+ @with << User.new(user[:id], user)
11
+ end
12
+ end
13
+ if attributes[:start_date]
14
+ year, month = attributes[:start_date].split('-').collect(&:to_i)
15
+ @start_date = if month.blank? || month == 0
16
+ Date.new(year)
17
+ else
18
+ Date.new(year, month)
19
+ end
20
+ end
21
+ if attributes[:end_date]
22
+ year, month = attributes[:end_date].split('-').collect(&:to_i)
23
+ @end_date = if month.blank? || month == 0
24
+ Date.new(year)
25
+ else
26
+ Date.new(year, month)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ module GSGraph
2
+ class Link < Node
3
+ include Connections::Comments
4
+ include Connections::Likes
5
+ include Connections::Likes::Likable
6
+
7
+ attr_accessor :from, :link, :name, :description, :icon, :picture, :message, :created_time
8
+
9
+ def initialize(identifier, attributes = {})
10
+ super
11
+ if (from = attributes[:from])
12
+ @from = if from[:category]
13
+ Page.new(from[:id], from)
14
+ else
15
+ User.new(from[:id], from)
16
+ end
17
+ end
18
+ @name = attributes[:name]
19
+ @link = attributes[:link]
20
+ @description = attributes[:description]
21
+ @icon = attributes[:icon]
22
+ @picture = attributes[:picture] # NOTE: this is external image, so isn't connection.
23
+ @message = attributes[:message]
24
+ if attributes[:created_time]
25
+ @created_time = Time.parse(attributes[:created_time]).utc
26
+ end
27
+
28
+ # cached connection
29
+ cache_collection attributes, :comments
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,20 @@
1
+ module GSGraph
2
+ class Location
3
+ include Comparison
4
+ include Serialization
5
+
6
+ attr_accessor :latitude, :longitude
7
+
8
+ def initialize(attributes = {})
9
+ @latitude = attributes[:latitude]
10
+ @longitude = attributes[:longitude]
11
+ end
12
+
13
+ def to_hash(options = {})
14
+ {
15
+ :latitude => self.latitude,
16
+ :longitude => self.longitude
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ module GSGraph
2
+ class Message < Node
3
+ # TODO:
4
+ # include Connections::Attachments
5
+ # include Connections::Shares
6
+ include Connections::Tags
7
+
8
+ attr_accessor :message, :from, :to, :created_time
9
+
10
+ def initialize(identifier, attributes = {})
11
+ super
12
+ @message = attributes[:message]
13
+ if (from = attributes[:from])
14
+ @from = User.new(from[:id], from)
15
+ end
16
+ @to = []
17
+ if attributes[:to]
18
+ Collection.new(attributes[:to]).each do |to|
19
+ @to << User.new(to[:id], to)
20
+ end
21
+ end
22
+ if attributes[:created_time]
23
+ @created_time = Time.parse(attributes[:created_time]).utc
24
+ end
25
+
26
+ # cached connection
27
+ cache_collection attributes, :tags
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module GSGraph
2
+ class Milestone < Node
3
+ attr_accessor :from, :title, :description, :created_time, :updated_time, :start_time, :end_time
4
+
5
+ def initialize(identifier, attributes = {})
6
+ super
7
+ if (from = attributes[:from])
8
+ @from = Page.new from[:id], from
9
+ end
10
+ [:title, :description].each do |key|
11
+ self.send :"#{key}=", attributes[key]
12
+ end
13
+ [:created_time, :updated_time, :start_time, :end_time].each do |key|
14
+ if (value = attributes[key])
15
+ time = case value
16
+ when String
17
+ Time.parse(value)
18
+ else
19
+ value
20
+ end
21
+ self.send :"#{key}=", time
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,149 @@
1
+ require 'tempfile'
2
+
3
+ module GSGraph
4
+ class Node
5
+ include Comparison
6
+
7
+ attr_accessor :identifier, :endpoint, :access_token, :raw_attributes
8
+
9
+ def initialize(identifier, attributes = {})
10
+ @identifier = identifier
11
+ @endpoint = File.join(GSGraph::graph_url, identifier.to_s)
12
+ @access_token = attributes[:access_token]
13
+ @raw_attributes = attributes
14
+ @cached_collections = {}
15
+ end
16
+
17
+ def fetch(options = {})
18
+ options[:access_token] ||= self.access_token if self.access_token
19
+ _fetched_ = get options
20
+ _fetched_[:access_token] ||= options[:access_token]
21
+ self.class.new(_fetched_[:id], _fetched_)
22
+ end
23
+
24
+ def self.fetch(identifier, options = {})
25
+ new(identifier).fetch(options)
26
+ end
27
+
28
+ def connection(connection, options = {})
29
+ Connection.new(
30
+ self,
31
+ connection,
32
+ options.merge(
33
+ :collection => collection_for(connection, options)
34
+ )
35
+ )
36
+ end
37
+
38
+ def update(options = {})
39
+ post options
40
+ end
41
+
42
+ def destroy(options = {})
43
+ delete options
44
+ end
45
+
46
+ protected
47
+
48
+ def get(params = {})
49
+ handle_response do
50
+ http_client.get build_endpoint(params), build_params(params)
51
+ end
52
+ end
53
+
54
+ def post(params = {})
55
+ handle_response do
56
+ http_client.post build_endpoint(params), build_params(params)
57
+ end
58
+ end
59
+
60
+ def delete(params = {})
61
+ _endpoint_, _params_ = build_endpoint(params), build_params(params)
62
+ _endpoint_ = [_endpoint_, _params_.try(:to_query)].compact.join('?')
63
+ handle_response do
64
+ http_client.delete _endpoint_
65
+ end
66
+ end
67
+
68
+ def http_client
69
+ GSGraph.http_client
70
+ end
71
+
72
+ private
73
+
74
+ def collection_for(connection, options = {})
75
+ collection = if @cached_collections.has_key?(connection) && options.blank?
76
+ @cached_collections[connection]
77
+ else
78
+ get options.merge(:connection => connection)
79
+ end
80
+ Collection.new collection
81
+ end
82
+
83
+ def cache_collections(attributes, *connections)
84
+ if (attributes.keys - [:access_token]).present?
85
+ connections.each do |connection|
86
+ @cached_collections[connection] = attributes[connection]
87
+ end
88
+ end
89
+ end
90
+ alias_method :cache_collection, :cache_collections
91
+
92
+ def build_endpoint(params = {})
93
+ File.join([self.endpoint, params.delete(:connection), params.delete(:connection_scope)].compact.collect(&:to_s))
94
+ end
95
+
96
+ def build_params(params)
97
+ _params_ = params.dup
98
+ _params_[:access_token] ||= self.access_token
99
+ _params_.delete_if do |k, v|
100
+ v.blank? &&
101
+ # NOTE: allow "key=false" in params (ex. for test user creation, it supports "installed=false")
102
+ v != false
103
+ end
104
+ _params_.each do |key, value|
105
+ next if value.blank?
106
+ _params_[key] = case value
107
+ when String, Symbol, Numeric, Date, Time, Rack::OAuth2::AccessToken::Legacy
108
+ value.to_s
109
+ when IO, Tempfile
110
+ value
111
+ when defined?(ActionDispatch::Http::UploadedFile) && ActionDispatch::Http::UploadedFile
112
+ # NOTE: for Rails 3.0.6+
113
+ # ref) http://blog.livedoor.jp/idea_and_players/archives/5184702.html
114
+ value.tempfile
115
+ else
116
+ value.to_json
117
+ end
118
+ end
119
+ _params_.blank? ? nil : _params_
120
+ end
121
+
122
+ def handle_response
123
+ response = yield
124
+ case response.body
125
+ when 'true'
126
+ true
127
+ when 'false'
128
+ # NOTE: When the object is not found, Graph API returns
129
+ # - error response (JSON) when the identifier contains alphabet (ex. graph.gamestamper.com/iamnotfound)
130
+ # - false when the identifier is only integer + underbar (ex. graph.gamestamper.com/1234567890, graph.gamestamper.com/12345_67890)
131
+ # This is an undocumented behaviour, so facebook might chaange it without any announcement.
132
+ # I've posted this issue on their forum, so hopefully I'll get a document about Graph API error responses.
133
+ # ref) http://forum.developers.gamestamper.com/viewtopic.php?pid=228256#p228256
134
+ raise NotFound.new('Graph API returned false, so probably it means your requested object is not found.')
135
+ when 'null'
136
+ nil
137
+ else
138
+ _response_ = MultiJson.load(response.body).with_indifferent_access
139
+ if (200...300).include?(response.status)
140
+ _response_
141
+ else
142
+ Exception.handle_httpclient_error(_response_, response.headers)
143
+ end
144
+ end
145
+ rescue MultiJson::DecodeError
146
+ raise Exception.new(response.status, "Unparsable Response: #{response.body}")
147
+ end
148
+ end
149
+ end