feedlr 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +22 -0
  5. data/.yardopts +5 -0
  6. data/Gemfile +32 -0
  7. data/Guardfile +7 -0
  8. data/LICENSE.md +16 -0
  9. data/README.md +85 -0
  10. data/Rakefile +10 -0
  11. data/feedlr.gemspec +27 -0
  12. data/lib/feedlr.rb +34 -0
  13. data/lib/feedlr/base.rb +4 -0
  14. data/lib/feedlr/client.rb +60 -0
  15. data/lib/feedlr/collection.rb +15 -0
  16. data/lib/feedlr/error.rb +79 -0
  17. data/lib/feedlr/gateway/categories.rb +36 -0
  18. data/lib/feedlr/gateway/entries.rb +40 -0
  19. data/lib/feedlr/gateway/evernote.rb +37 -0
  20. data/lib/feedlr/gateway/facebook.rb +28 -0
  21. data/lib/feedlr/gateway/feeds.rb +26 -0
  22. data/lib/feedlr/gateway/markers.rb +195 -0
  23. data/lib/feedlr/gateway/microsoft.rb +30 -0
  24. data/lib/feedlr/gateway/mixes.rb +29 -0
  25. data/lib/feedlr/gateway/opml.rb +26 -0
  26. data/lib/feedlr/gateway/preferences.rb +25 -0
  27. data/lib/feedlr/gateway/profile.rb +25 -0
  28. data/lib/feedlr/gateway/search.rb +41 -0
  29. data/lib/feedlr/gateway/shorten.rb +17 -0
  30. data/lib/feedlr/gateway/streams.rb +42 -0
  31. data/lib/feedlr/gateway/subscriptions.rb +43 -0
  32. data/lib/feedlr/gateway/tags.rb +88 -0
  33. data/lib/feedlr/gateway/topics.rb +43 -0
  34. data/lib/feedlr/gateway/twitter.rb +29 -0
  35. data/lib/feedlr/mapper.rb +25 -0
  36. data/lib/feedlr/rate_limit.rb +21 -0
  37. data/lib/feedlr/request.rb +148 -0
  38. data/lib/feedlr/success.rb +5 -0
  39. data/lib/feedlr/version.rb +15 -0
  40. data/spec/cassettes/Feedlr_Gateway_Categories/_change_category_label/resoponds_with_hashie_object.yml +50 -0
  41. data/spec/cassettes/Feedlr_Gateway_Categories/_delete_category/resoponds_with_hashie_object.yml +50 -0
  42. data/spec/cassettes/Feedlr_Gateway_Categories/_user_categories/resoponds_with_hashie_object.yml +52 -0
  43. data/spec/cassettes/Feedlr_Gateway_Entries/_add_entry/resoponds_with_hashie_object.yml +52 -0
  44. data/spec/cassettes/Feedlr_Gateway_Entries/_user_entries/resoponds_with_hashie_object.yml +337 -0
  45. data/spec/cassettes/Feedlr_Gateway_Evernote/_add_to_evernote/resoponds_with_hashie_object.yml +50 -0
  46. data/spec/cassettes/Feedlr_Gateway_Evernote/_evernote_notebooks/resoponds_with_hashie_object.yml +51 -0
  47. data/spec/cassettes/Feedlr_Gateway_Evernote/_unlink_evernote/resoponds_with_hashie_object.yml +50 -0
  48. data/spec/cassettes/Feedlr_Gateway_Facebook/_facebook_suggestions/resoponds_with_hashie_object.yml +52 -0
  49. data/spec/cassettes/Feedlr_Gateway_Facebook/_unlink_facebook/resoponds_with_hashie_object.yml +50 -0
  50. data/spec/cassettes/Feedlr_Gateway_Feeds/_feeds/resoponds_with_hashie_object.yml +51 -0
  51. data/spec/cassettes/Feedlr_Gateway_Markers/_lastest_tagged_entries/resoponds_with_hashie_object.yml +52 -0
  52. data/spec/cassettes/Feedlr_Gateway_Markers/_mark_articles_as_read/resoponds_with_hashie_object.yml +50 -0
  53. data/spec/cassettes/Feedlr_Gateway_Markers/_mark_articles_as_unread/resoponds_with_hashie_object.yml +50 -0
  54. data/spec/cassettes/Feedlr_Gateway_Markers/_mark_categories_as_read/with_asOf_param/resoponds_with_hashie_object.yml +50 -0
  55. data/spec/cassettes/Feedlr_Gateway_Markers/_mark_categories_as_read/with_lastReadEntryId_param/resoponds_with_hashie_object.yml +50 -0
  56. data/spec/cassettes/Feedlr_Gateway_Markers/_mark_feeds_as_read/with_asOf_param/resoponds_with_hashie_object.yml +50 -0
  57. data/spec/cassettes/Feedlr_Gateway_Markers/_mark_feeds_as_read/with_lastReadEntryId_param/resoponds_with_hashie_object.yml +50 -0
  58. data/spec/cassettes/Feedlr_Gateway_Markers/_sync_read_counts/resoponds_with_hashie_object.yml +52 -0
  59. data/spec/cassettes/Feedlr_Gateway_Markers/_undo_mark_categories_as_read/resoponds_with_hashie_object.yml +50 -0
  60. data/spec/cassettes/Feedlr_Gateway_Markers/_undo_mark_feeds_as_read/resoponds_with_hashie_object.yml +50 -0
  61. data/spec/cassettes/Feedlr_Gateway_Markers/_user_unread_counts/resoponds_with_hashie_object.yml +52 -0
  62. data/spec/cassettes/Feedlr_Gateway_Microsoft/_add_to_onenote/resoponds_with_hashie_object.yml +52 -0
  63. data/spec/cassettes/Feedlr_Gateway_Microsoft/_unlink_microsoft/resoponds_with_hashie_object.yml +50 -0
  64. data/spec/cassettes/Feedlr_Gateway_Mixes/_stream_most_engaging/resoponds_with_hashie_object.yml +102 -0
  65. data/spec/cassettes/Feedlr_Gateway_Opml/_import_opml/resoponds_with_hashie_object.yml +63 -0
  66. data/spec/cassettes/Feedlr_Gateway_Opml/_user_opml/resoponds_with_hashie_object.yml +80 -0
  67. data/spec/cassettes/Feedlr_Gateway_Preferences/_preferences/resoponds_with_hashie_object.yml +52 -0
  68. data/spec/cassettes/Feedlr_Gateway_Preferences/_update_preferences/resoponds_with_hashie_object.yml +50 -0
  69. data/spec/cassettes/Feedlr_Gateway_Profile/_get_profile/resoponds_with_hashie_object.yml +54 -0
  70. data/spec/cassettes/Feedlr_Gateway_Profile/_profile/resoponds_with_hashie_object.yml +54 -0
  71. data/spec/cassettes/Feedlr_Gateway_Profile/_update_profile/resoponds_with_hashie_object.yml +54 -0
  72. data/spec/cassettes/Feedlr_Gateway_Search/_search_feeds/resoponds_with_hashie_object.yml +303 -0
  73. data/spec/cassettes/Feedlr_Gateway_Search/_search_stream/resoponds_with_hashie_object.yml +1941 -0
  74. data/spec/cassettes/Feedlr_Gateway_Shorten/_shorten/resoponds_with_hashie_object.yml +51 -0
  75. data/spec/cassettes/Feedlr_Gateway_Streams/_stream_entries_contents/resoponds_with_hashie_object.yml +1150 -0
  76. data/spec/cassettes/Feedlr_Gateway_Streams/_stream_entries_ids/resoponds_with_hashie_object.yml +51 -0
  77. data/spec/cassettes/Feedlr_Gateway_Subscriptions/_add_subscription/resoponds_with_hashie_object.yml +53 -0
  78. data/spec/cassettes/Feedlr_Gateway_Subscriptions/_create_subscription/resoponds_with_hashie_object.yml +51 -0
  79. data/spec/cassettes/Feedlr_Gateway_Subscriptions/_delete_subscription/resoponds_with_hashie_object.yml +50 -0
  80. data/spec/cassettes/Feedlr_Gateway_Subscriptions/_update_subscription/resoponds_with_hashie_object.yml +51 -0
  81. data/spec/cassettes/Feedlr_Gateway_Subscriptions/_user_subscriptions/resoponds_with_hashie_object.yml +57 -0
  82. data/spec/cassettes/Feedlr_Gateway_Tags/_change_tag_label/resoponds_with_hashie_object.yml +50 -0
  83. data/spec/cassettes/Feedlr_Gateway_Tags/_delete_tags/resoponds_with_hashie_object.yml +50 -0
  84. data/spec/cassettes/Feedlr_Gateway_Tags/_get_tags/resoponds_with_hashie_object.yml +50 -0
  85. data/spec/cassettes/Feedlr_Gateway_Tags/_tag_entries/resoponds_with_hashie_object.yml +50 -0
  86. data/spec/cassettes/Feedlr_Gateway_Tags/_untag_entries/resoponds_with_hashie_object.yml +50 -0
  87. data/spec/cassettes/Feedlr_Gateway_Tags/_user_tags/resoponds_with_hashie_object.yml +50 -0
  88. data/spec/cassettes/Feedlr_Gateway_Topics/_add_topic/resoponds_with_hashie_object.yml +50 -0
  89. data/spec/cassettes/Feedlr_Gateway_Topics/_delete_topic/resoponds_with_hashie_object.yml +50 -0
  90. data/spec/cassettes/Feedlr_Gateway_Topics/_update_topic/resoponds_with_hashie_object.yml +50 -0
  91. data/spec/cassettes/Feedlr_Gateway_Topics/_user_topics/resoponds_with_hashie_object.yml +50 -0
  92. data/spec/cassettes/Feedlr_Gateway_Twitter/_twitter_suggestions/resoponds_with_hashie_object.yml +50 -0
  93. data/spec/cassettes/Feedlr_Gateway_Twitter/_unlink_twitter/resoponds_with_hashie_object.yml +50 -0
  94. data/spec/feedly/base_spec.rb +10 -0
  95. data/spec/feedly/client_spec.rb +49 -0
  96. data/spec/feedly/collection_spec.rb +21 -0
  97. data/spec/feedly/error_spec.rb +59 -0
  98. data/spec/feedly/feedly_spec.rb +54 -0
  99. data/spec/feedly/gateway/categories_spec.rb +59 -0
  100. data/spec/feedly/gateway/entries_spec.rb +67 -0
  101. data/spec/feedly/gateway/evernote_spec.rb +60 -0
  102. data/spec/feedly/gateway/facebook_spec.rb +36 -0
  103. data/spec/feedly/gateway/feeds_spec.rb +36 -0
  104. data/spec/feedly/gateway/markers_spec.rb +295 -0
  105. data/spec/feedly/gateway/microsoft_spec.rb +40 -0
  106. data/spec/feedly/gateway/mixes_spec.rb +27 -0
  107. data/spec/feedly/gateway/opml_spec.rb +57 -0
  108. data/spec/feedly/gateway/preferences_spec.rb +41 -0
  109. data/spec/feedly/gateway/profile_spec.rb +40 -0
  110. data/spec/feedly/gateway/search_spec.rb +43 -0
  111. data/spec/feedly/gateway/shorten_spec.rb +27 -0
  112. data/spec/feedly/gateway/streams_spec.rb +44 -0
  113. data/spec/feedly/gateway/subscriptions_spec.rb +87 -0
  114. data/spec/feedly/gateway/tags_spec.rb +129 -0
  115. data/spec/feedly/gateway/topics_spec.rb +77 -0
  116. data/spec/feedly/gateway/twitter_spec.rb +37 -0
  117. data/spec/feedly/mapper_spec.rb +25 -0
  118. data/spec/feedly/rate_limit_spec.rb +41 -0
  119. data/spec/feedly/request_spec.rb +74 -0
  120. data/spec/feedly/success_spec.rb +7 -0
  121. data/spec/feedly/version_spec.rb +9 -0
  122. data/spec/helper.rb +52 -0
  123. metadata +319 -0
@@ -0,0 +1,25 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Preferences API
4
+ #
5
+ # @see http://developer.feedly.com/v3/preferences/
6
+ module Preferences
7
+ # Get the preferences of the user
8
+ #
9
+ # @see http://developer.feedly.com/v3/preferences/#get-the-preferences-of-the-user
10
+ # @return [Feedlr::Base]
11
+ def preferences
12
+ build_object(:get , '/preferences')
13
+ end
14
+
15
+ # Update the preferences of the user
16
+ #
17
+ # @see http://developer.feedly.com/v3/preferences/#update-the-preferences-of-the-user
18
+ # @param preferences [Hash]
19
+ # @return [Feedlr::Base]
20
+ def update_preferences(preferences)
21
+ build_object(:post , '/preferences' , preferences)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Profile API
4
+ #
5
+ # @see http://developer.feedly.com/v3/profile/
6
+ module Profile
7
+ # Get the profile of the user
8
+ #
9
+ # @see http://developer.feedly.com/v3/profile/#get-the-profile-of-the-user
10
+ # @return [Feedlr::Base]
11
+ def user_profile
12
+ build_object(:get , '/profile')
13
+ end
14
+
15
+ # Update the profile of the user
16
+ #
17
+ # @see http://developer.feedly.com/v3/profile/#update-the-profile-of-the-user
18
+ # @param profile [Hash]
19
+ # @return [Feedlr::Base]
20
+ def update_profile(profile)
21
+ build_object(:post , '/profile' , profile)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Search API
4
+ #
5
+ # @see http://developer.feedly.com/v3/search/
6
+ module Search
7
+ # Find feeds based on title , url or #topic
8
+ #
9
+ # @see http://developer.feedly.com/v3/search/#find-feeds-based-on-title-url-or-topic
10
+ # @param query [String]
11
+ # @param options [Hash]
12
+ # @option options [String] :n number of results. default value is 20
13
+ # @option options [String] :locale hint the search engine
14
+ # to return feeds in that locale (e.g. "pt" , "fr_FR")
15
+ # @return [Feedlr::Base]
16
+ def search_feeds(query , options = {})
17
+ build_object(:get , '/search/feeds' , { q: query }.merge(options))
18
+ end
19
+
20
+ # Search the content of a stream (Pro only)
21
+ #
22
+ # @see http://developer.feedly.com/v3/search/#search-the-content-of-a-stream-pro-only
23
+ # @param stream_id [String]
24
+ # @param query [String]
25
+ # @param options [Hash]
26
+ # @option options [String] :count number of entries to return
27
+ # @option options [String] :newerThan timestamp in ms
28
+ # @option options [String] :continuation a continuation id is used
29
+ # to page through the content
30
+ # @option options [String] :unreadOnly boolean , default is false
31
+ # @option options [String] :fields a comma-separated list of fields
32
+ # @option options [String] :minMatches minimum number of
33
+ # search terms to match before
34
+ # @return [Feedlr::Base]
35
+ def search_stream(stream_id , query , options = {})
36
+ build_object(:get , '/search/contents',
37
+ { q: query , streamId: stream_id }.merge(options))
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Shorten API
4
+ #
5
+ # @see http://developer.feedly.com/v3/shorten/
6
+ module Shorten
7
+ # Create a shortened URL for an entry
8
+ #
9
+ # @see http://developer.feedly.com/v3/shorten/#create-a-shortened-url-for-an-entry
10
+ # @param entry_id [String]
11
+ # @return [String]
12
+ def shorten_entry(entry_id)
13
+ build_object(:get , "/shorten/entries/#{CGI.escape(entry_id) }")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Streams API
4
+ #
5
+ # @see http://developer.feedly.com/v3/streams/
6
+ module Streams
7
+ # Get a list of entry ids for a specific stream
8
+ #
9
+ # @see http://developer.feedly.com/v3/streams/#get-a-list-of-entry-ids-for-a-specific-stream
10
+ # @param stream_id [String]
11
+ # @param options [Hash]
12
+ # @option options [String] :count mber of entry ids to return.
13
+ # default is 20. max is 10,000
14
+ # @option options [String] :ranked newest or oldest. default is newest
15
+ # @option options [String] :unreadOnly boolean default value is false
16
+ # @option options [String] :newerThan timestamp in ms
17
+ # @option options [String] :continuation a continuation id is
18
+ # used to page through the entry ids
19
+ # @return [Feedlr::Base]
20
+ def stream_entries_ids(stream_id , options = {})
21
+ build_object(:get , "/streams/#{CGI.escape(stream_id) }/ids" , options)
22
+ end
23
+ # Get the content of a stream
24
+ #
25
+ # @see http://developer.feedly.com/v3/streams/#get-the-content-of-a-stream
26
+ # @param stream_id [String]
27
+ # @param options [Hash]
28
+ # @option options [String] :count mber of entry ids to return.
29
+ # default is 20. max is 10 , 000
30
+ # @option options [String] :ranked newest or oldest. default is newest
31
+ # @option options [String] :unreadOnly boolean default value is false
32
+ # @option options [String] :newerThan timestamp in ms
33
+ # @option options [String] :continuation a continuation id
34
+ # is used to page through the entry ids
35
+ # @return [Feedlr::Base]
36
+ def stream_entries_contents(stream_id , options = {})
37
+ build_object(:get, "/streams/#{CGI.escape(stream_id)}/contents",
38
+ options)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Subscriptions API
4
+ #
5
+ # @see http://developer.feedly.com/v3/subscriptions/
6
+ module Subscriptions
7
+ # Get the user's subscriptions
8
+ #
9
+ # @see http://developer.feedly.com/v3/subscriptions/#get-the-users-subscriptions
10
+ # @return [Feedlr::Collection]
11
+ def user_subscriptions
12
+ build_object(:get , '/subscriptions')
13
+ end
14
+
15
+ # Subscribe to a feed
16
+ #
17
+ # @see http://developer.feedly.com/v3/subscriptions/#subscribe-to-a-feed
18
+ # @param subscription [Hash]
19
+ # @return [Feedlr::Base]
20
+ def add_subscription(subscription)
21
+ build_object(:post , '/subscriptions' , subscription)
22
+ end
23
+
24
+ # Update an existing subscription
25
+ #
26
+ # @see http://developer.feedly.com/v3/subscriptions/#update-an-existing-subscription
27
+ # @param subscription [Hash]
28
+ # @return [Feedlr::Success]
29
+ def update_subscription(subscription)
30
+ add_subscription(subscription)
31
+ end
32
+
33
+ # Unsubscribe from a feed
34
+ #
35
+ # @see http://developer.feedly.com/v3/subscriptions/#unsubscribe-from-a-feed
36
+ # @param subscription_id [String]
37
+ # @return [Feedlr::Success]
38
+ def delete_subscription(subscription_id)
39
+ build_object(:delete , "/subscriptions/#{CGI.escape(subscription_id) }")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,88 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Tags API
4
+ #
5
+ # @see http://developer.feedly.com/v3/tags/
6
+ module Tags
7
+ # Get the list of tags created by the user
8
+ #
9
+ # @see http://developer.feedly.com/v3/tags/#get-the-list-of-tags-created-by-the-user
10
+ # @return [Feedlr::Collection]
11
+ def user_tags
12
+ build_object(:get , '/tags')
13
+ end
14
+
15
+ # Tag an existing entry
16
+ #
17
+ # @see tag_entries
18
+ # @param entry_id [String]
19
+ # @param tags_ids [Array] list of tags ids
20
+ # @return [Feedlr::Success]
21
+ def tag_entry(entry_id , tags_ids)
22
+ tag_entries([entry_id] , tags_ids)
23
+ end
24
+
25
+ # Tag multiple entries
26
+ #
27
+ # @see http://developer.feedly.com/v3/tags/#tag-multiple-entries
28
+ # @param entries_ids [Array] list of entries ids
29
+ # @param tags_ids [Array] list of tags ids
30
+ # @return [Feedlr::Success]
31
+ def tag_entries(entries_ids , tags_ids)
32
+ tags_query = tags_ids.map { |t| CGI.escape(t) }.join(',')
33
+ build_object(:put , "/tags/#{tags_query}" , entryIds: entries_ids)
34
+ end
35
+
36
+ # Untag an existing entry
37
+ #
38
+ # @see untag_entries
39
+ # @param entry_id [String]
40
+ # @param tags_ids [Array] list of tags ids
41
+ # @return [Feedlr::Success]
42
+ def untag_entry(entry_id , tags_ids)
43
+ untag_entries([entry_id] , tags_ids)
44
+ end
45
+
46
+ # Untag multiple entries
47
+ #
48
+ # @see http://developer.feedly.com/v3/tags/#untag-multiple-entries
49
+ # @param entries_ids [Array] list of entries ids
50
+ # @param tags_ids [Array] list of tags ids
51
+ # @return [Feedlr::Success]
52
+ def untag_entries(entries_ids , tags_ids)
53
+ tags_query = tags_ids.map { |t| CGI.escape(t) }.join(',')
54
+ entries_query = entries_ids.map { |t| CGI.escape(t) }.join(',')
55
+ build_object(:delete , "/tags/#{tags_query}/#{entries_query}")
56
+ end
57
+
58
+ # Change a tag label
59
+ #
60
+ # @see http://developer.feedly.com/v3/tags/#change-a-tag-label
61
+ # @param tag_id [String]
62
+ # @param new_value [String] label's new value
63
+ # @return [Feedlr::Success]
64
+ def change_tag_label(tag_id , new_value)
65
+ build_object(:post , "/tags/#{CGI.escape(tag_id) }" , label: new_value)
66
+ end
67
+
68
+ # Delete a tag
69
+ #
70
+ # @see delete_tags
71
+ # @param tag_id [String]
72
+ # @return [Feedlr::Success]
73
+ def delete_tag(tag_id)
74
+ delete_tags([tag_id])
75
+ end
76
+
77
+ # Delete tags
78
+ #
79
+ # @see http://developer.feedly.com/v3/tags/#delete-tags
80
+ # @param tags_ids [Array] list of ids
81
+ # @return [Feedlr::Success]
82
+ def delete_tags(tags_ids)
83
+ tags_query = tags_ids.map { |t| CGI.escape(t) }.join(',')
84
+ build_object(:delete , "/tags/#{tags_query }")
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,43 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Topics API
4
+ #
5
+ # @see http://developer.feedly.com/v3/topics/
6
+ module Topics
7
+ # Get the list of topics the user has added to their feedly
8
+ #
9
+ # @see http://developer.feedly.com/v3/topics/#get-the-list-of-topics-the-user-has-added-to-their-feedly
10
+ # @return [Feedlr::Collection]
11
+ def user_topics
12
+ build_object(:get , '/topics')
13
+ end
14
+
15
+ # Add a topic to the user feedly account
16
+ #
17
+ # @see http://developer.feedly.com/v3/topics/#add-a-topic-to-the-user-feedly-account
18
+ # @param topic [Hash]
19
+ # @return [Feedlr::Success]
20
+ def add_topic(topic)
21
+ build_object(:post , '/topics' , topic)
22
+ end
23
+
24
+ # Update an existing topic
25
+ #
26
+ # @see http://developer.feedly.com/v3/topics/#update-an-existing-topic
27
+ # @param topic [Hash]
28
+ # @return [Feedlr::Success]
29
+ def update_topic(topic)
30
+ build_object(:post , '/topics' , topic)
31
+ end
32
+
33
+ # Remove a topic from a feedly account
34
+ #
35
+ # @see http://developer.feedly.com/v3/topics/#remove-a-topic-from-a-feedly-account
36
+ # @param topic_id [String]
37
+ # @return [Feedlr::Success]
38
+ def delete_topic(topic_id)
39
+ build_object(:delete , "/topics/#{CGI.escape(topic_id) }")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ module Feedlr
2
+ module Gateway
3
+ # Twitter API
4
+ #
5
+ # @see http://developer.feedly.com/v3/twitter/
6
+ # The following API actions do not have corresponding methods in
7
+ # this module:
8
+ #
9
+ # * Link Twitter account
10
+ # * Get suggested feeds (alternate version)
11
+ module Twitter
12
+ # Unlink Twitter account
13
+ #
14
+ # @see http://developer.feedly.com/v3/twitter/#unlink-twitter-account
15
+ # @return [Feedlr::Success]
16
+ def unlink_twitter
17
+ build_object(:delete , '/twitter/auth')
18
+ end
19
+
20
+ # Get suggested feeds
21
+ #
22
+ # @see http://developer.feedly.com/v3/twitter/#get-suggested-feeds
23
+ # @return [Feedlr::Collection]
24
+ def twitter_suggestions
25
+ build_object(:get , '/twitter/suggestions')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ require 'hashie'
2
+ require 'multi_json'
3
+ require_relative 'base'
4
+ require_relative 'collection'
5
+ require_relative 'success'
6
+
7
+ module Feedlr
8
+ # The generalized pseudo-object that is returned for all query
9
+ # requests.
10
+ # http://martinfowler.com/eaaCatalog/dataMapper.html
11
+ class Mapper
12
+ # Build the proper object depending on the response
13
+ # @return [Feedlr::Base, Feedlr::Success, Feedlr::Collection]
14
+ def self.build(data)
15
+ case data
16
+ when Hash
17
+ (data.size > 0) ? Feedlr::Base.new(data) : Feedlr::Success.new
18
+ when Array
19
+ Feedlr::Collection.new(data)
20
+ else
21
+ Feedlr::Success.new
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module Feedlr
2
+ # Rate limiting object associated with responses
3
+ class RateLimit
4
+ attr_reader :count, :limit, :remaining
5
+ # Initializes a new object
6
+ #
7
+ # @param attrs [Hash]
8
+ # @option attrs [String] :x-ratelimit-count
9
+ # @option attrs [String] :x-ratelimit-limit
10
+ # @option attrs [String] :x-ratelimit-remaining
11
+ # @return [Feedlr::RateLimit]
12
+ def initialize(attrs = {})
13
+ @count =
14
+ attrs['x-ratelimit-count'].to_i if attrs['x-ratelimit-count']
15
+ @limit =
16
+ attrs['x-ratelimit-limit'].to_i if attrs['x-ratelimit-limit']
17
+ @remaining =
18
+ attrs['x-ratelimit-remaining'].to_i if attrs['x-ratelimit-remaining']
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,148 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require_relative 'mapper'
4
+ require_relative 'error'
5
+
6
+ module Feedlr
7
+ # Do all http requests and call the mapper
8
+ module Request
9
+ ENDPOINT = 'http://cloud.feedly.com'
10
+ SANDBOX_ENDPOINT = 'http://sandbox.feedly.com'
11
+ API_VERSION = '/v3'
12
+
13
+ private
14
+
15
+ # Run an HTTP request and map the response to a domain class
16
+ # @param method [String] HTTP method
17
+ # @param path [String]
18
+ # @param params [Hash]
19
+ # @param headers [Hash]
20
+ # @return [Faraday::Response]
21
+ def build_object(method, path, params = nil, headers = nil)
22
+ response = send(method, path, params, headers)
23
+ Mapper.build(response.body)
24
+ end
25
+
26
+ %w(post put).each do |method|
27
+ class_eval <<-RUBY , __FILE__ , __LINE__ + 1
28
+ def #{method}(path, params, headers)
29
+ request(:#{method}, path, headers) do |request|
30
+ if !headers || headers[:"Content-Type"].nil?
31
+ params = MultiJson.dump(params)
32
+ end
33
+ request.body = params if params
34
+ end
35
+ end
36
+ RUBY
37
+ end
38
+
39
+ %w(get delete).each do |method|
40
+ class_eval <<-RUBY , __FILE__ , __LINE__ + 1
41
+ def #{method}(path, params, headers)
42
+ request(:#{method}, path, headers) do |request|
43
+ request.params.update(params) if params
44
+ end
45
+ end
46
+ RUBY
47
+ end
48
+
49
+ # Initiate and memoize the HTTP connection object
50
+ # @return [Faraday::Connection]
51
+ def connection
52
+ @connection ||= Faraday.new(end_point, connection_options)
53
+ end
54
+
55
+ # Build and memoize the connection options
56
+ # @return [Hash]
57
+ def connection_options
58
+ @connection_options ||= {
59
+ builder: middleware,
60
+ headers: request_headers,
61
+ request: {
62
+ open_timeout: 10,
63
+ timeout: 30
64
+ }
65
+ }
66
+ end
67
+
68
+ # Build and memoize the rack middleware for the requests
69
+ # @return [Faraday::RackBuilder]
70
+ def middleware
71
+ @middleware ||= Faraday::RackBuilder.new do |faraday|
72
+ faraday.request :url_encoded
73
+ # Add logging
74
+ faraday.response(:logger, logger) unless logger.nil?
75
+ # Parse XML
76
+ faraday.response :xml, content_type: /\bxml$/
77
+ # Parse JSON
78
+ faraday.response :json, content_type: /\bjson$/
79
+
80
+ faraday.adapter :net_http
81
+ end
82
+ end
83
+
84
+ # Run the desired HTTP request, verifies it, raise excpetions in
85
+ # case of failure, otherwise return the response
86
+ # @param method [String] HTTP method
87
+ # @param path [String]
88
+ # @param headers [Hash]
89
+ # @return [Faraday::Response]
90
+ def request(method, path, headers, &block)
91
+ response = run_request(method, path, headers, &block)
92
+ logger.debug(response.inspect) unless logger.nil?
93
+ verify_success(response)
94
+ response
95
+ rescue Faraday::Error::TimeoutError, Timeout::Error => error
96
+ raise(Feedlr::Error::RequestTimeout.new, error.message)
97
+ rescue Faraday::Error::ClientError, JSON::ParserError => error
98
+ raise(Feedlr::Error.new, error.message)
99
+ end
100
+
101
+ # Run the actual request
102
+ # @param method [String] HTTP method
103
+ # @param path [String]
104
+ # @param headers [Hash]
105
+ # @return [Faraday::Response]
106
+ def run_request(method, path, headers)
107
+ connection.send(method) do |request|
108
+ request.url(API_VERSION + path)
109
+ request.headers.update(headers) if headers
110
+ yield(request) if block_given?
111
+ end
112
+ end
113
+
114
+ # Check the response code and raise exceptions if needed
115
+ # param response [Faraday::Response]
116
+ # @return [void]
117
+ def verify_success(response)
118
+ status_code = response.status.to_i
119
+ klass = Feedlr::Error.errors[status_code]
120
+ fail(klass.from_response(response)) if klass
121
+ end
122
+
123
+ # Build and memoize the initial request headers
124
+ # @return [Hash]
125
+ def request_headers
126
+ return unless @headers.nil?
127
+ @headers = { :"Accept" => 'application/json',
128
+ :"Content-Type" => 'application/json',
129
+ :user_agent => user_agent
130
+ }
131
+ @headers[:Authorization] =
132
+ "OAuth #{oauth_access_token}" if oauth_access_token
133
+ @headers
134
+ end
135
+
136
+ # Build and memoize the user agent
137
+ # @return [String]
138
+ def user_agent
139
+ @user_agent ||= "Feedlr Ruby Gem #{Feedlr::Version}"
140
+ end
141
+
142
+ # Build and memoize the endpoint
143
+ # @return [String]
144
+ def end_point
145
+ @end_point ||= (sandbox ? SANDBOX_ENDPOINT : ENDPOINT)
146
+ end
147
+ end
148
+ end