kippt 2.0.1 → 3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +1 -4
  3. data/CHANGELOG.md +24 -0
  4. data/Gemfile +4 -0
  5. data/README.md +14 -4
  6. data/TODO.md +16 -0
  7. data/lib/kippt.rb +8 -3
  8. data/lib/kippt/client.rb +6 -6
  9. data/lib/kippt/clip.rb +17 -9
  10. data/lib/kippt/clip_collection.rb +2 -2
  11. data/lib/kippt/clip_likes.rb +29 -0
  12. data/lib/kippt/clips.rb +8 -37
  13. data/lib/kippt/collection.rb +1 -2
  14. data/lib/kippt/collection_resource.rb +39 -55
  15. data/lib/kippt/comment.rb +2 -4
  16. data/lib/kippt/comment_collection.rb +1 -2
  17. data/lib/kippt/comments.rb +5 -3
  18. data/lib/kippt/connection.rb +7 -3
  19. data/lib/kippt/favorite.rb +46 -0
  20. data/lib/kippt/favorites.rb +20 -0
  21. data/lib/kippt/followers.rb +6 -4
  22. data/lib/kippt/following.rb +6 -4
  23. data/lib/kippt/helpers.rb +17 -0
  24. data/lib/kippt/like.rb +4 -6
  25. data/lib/kippt/like_collection.rb +11 -0
  26. data/lib/kippt/likes.rb +2 -30
  27. data/lib/kippt/list.rb +8 -2
  28. data/lib/kippt/list_collection.rb +2 -2
  29. data/lib/kippt/lists.rb +2 -4
  30. data/lib/kippt/read_collection_resource.rb +43 -0
  31. data/lib/kippt/root_clips.rb +39 -0
  32. data/lib/kippt/saves.rb +4 -3
  33. data/lib/kippt/user.rb +10 -6
  34. data/lib/kippt/user_clips.rb +6 -26
  35. data/lib/kippt/user_collection.rb +0 -3
  36. data/lib/kippt/user_likes.rb +29 -0
  37. data/lib/kippt/user_lists.rb +0 -5
  38. data/lib/kippt/users.rb +3 -8
  39. data/lib/kippt/version.rb +1 -1
  40. data/spec/kippt/client_spec.rb +36 -2
  41. data/spec/kippt/clip_likes_spec.rb +14 -0
  42. data/spec/kippt/clip_spec.rb +89 -3
  43. data/spec/kippt/clips_spec.rb +27 -5
  44. data/spec/kippt/comment_spec.rb +1 -1
  45. data/spec/kippt/comments_spec.rb +30 -5
  46. data/spec/kippt/favorite_spec.rb +38 -0
  47. data/spec/kippt/favorites_spec.rb +18 -0
  48. data/spec/kippt/follow_relationship_spec.rb +30 -0
  49. data/spec/kippt/followers_spec.rb +6 -9
  50. data/spec/kippt/following_spec.rb +6 -9
  51. data/spec/kippt/like_spec.rb +38 -0
  52. data/spec/kippt/likes_spec.rb +21 -0
  53. data/spec/kippt/list_spec.rb +43 -10
  54. data/spec/kippt/lists_spec.rb +12 -0
  55. data/spec/kippt/saves_spec.rb +3 -3
  56. data/spec/kippt/user_clips_spec.rb +14 -2
  57. data/spec/kippt/user_likes_spec.rb +14 -0
  58. data/spec/kippt/user_lists_spec.rb +12 -0
  59. data/spec/kippt/user_spec.rb +11 -0
  60. data/spec/kippt/users_spec.rb +2 -1
  61. data/spec/shared_examples/collection.rb +117 -0
  62. data/spec/shared_examples/collection_resource.rb +13 -0
  63. data/spec/shared_examples/read_collection_resource.rb +77 -0
  64. data/spec/shared_examples/resource.rb +80 -0
  65. data/spec/spec_helper.rb +2 -298
  66. metadata +33 -26
  67. data/lib/core_ext/open_struct.rb +0 -5
@@ -1,6 +1,4 @@
1
- require "kippt/resource"
2
- require "kippt/user"
3
- require "kippt/clip"
1
+ require_relative "comments"
4
2
 
5
3
  class Kippt::Comment
6
4
  include Kippt::Resource
@@ -12,7 +10,7 @@ class Kippt::Comment
12
10
 
13
11
  attr_reader :clip
14
12
 
15
- def initialize(attributes = {}, client = nil, clip = nil)
13
+ def initialize(attributes = {}, clip = nil, client = nil)
16
14
  super(attributes, client)
17
15
  @clip = clip
18
16
  end
@@ -1,5 +1,4 @@
1
- require "kippt/collection"
2
- require "kippt/comment"
1
+ require_relative "comment"
3
2
 
4
3
  class Kippt::CommentCollection
5
4
  include Kippt::Collection
@@ -1,5 +1,5 @@
1
- require "kippt/comment_collection"
2
- require "kippt/comment"
1
+ require_relative "comment_collection"
2
+ require_relative "comment"
3
3
 
4
4
  class Kippt::Comments
5
5
  include Kippt::CollectionResource
@@ -27,7 +27,7 @@ class Kippt::Comments
27
27
  "clips/#{clip.id}/comments"
28
28
  end
29
29
 
30
- def all(options = {})
30
+ def fetch(options = {})
31
31
  validate_collection_options(options)
32
32
 
33
33
  if options.empty? && @clip.all_comments_embedded?
@@ -37,6 +37,8 @@ class Kippt::Comments
37
37
  end
38
38
  end
39
39
 
40
+ alias all fetch
41
+
40
42
  def build(attributes = {})
41
43
  object_class.new(attributes, client, clip)
42
44
  end
@@ -9,7 +9,7 @@ module Kippt::Connection
9
9
  begin
10
10
  MultiJson.load(body) unless body.strip.empty?
11
11
  rescue MultiJson::DecodeError
12
- nil
12
+ body
13
13
  end
14
14
  end
15
15
  end
@@ -63,8 +63,12 @@ module Kippt::Connection
63
63
  end
64
64
  end
65
65
 
66
- if response.status == 401
67
- raise Kippt::APIError.new(response.body["message"])
66
+ if response.status == 401 || (500..599).include?(response.status)
67
+ if response.body && response.body["message"]
68
+ raise Kippt::APIError.new(response.body["message"])
69
+ else
70
+ raise Kippt::APIError.new("Unknown response from Kippt: #{response.body}")
71
+ end
68
72
  end
69
73
 
70
74
  response
@@ -0,0 +1,46 @@
1
+ require_relative "favorites"
2
+
3
+ class Kippt::Favorite
4
+ attr_reader :clip, :errors
5
+
6
+ def initialize(clip, client)
7
+ @client = client
8
+ @errors = []
9
+ @clip = clip
10
+ end
11
+
12
+ def id
13
+ nil
14
+ end
15
+
16
+ def collection_resource_class
17
+ Kippt::Favorites
18
+ end
19
+
20
+ def writable_attributes_hash
21
+ nil
22
+ end
23
+
24
+ def save
25
+ @errors = []
26
+ response = collection_resource.save_resource(self)
27
+ if response[:error_message]
28
+ errors << response[:error_message]
29
+ end
30
+ response[:success]
31
+ end
32
+
33
+ def destroy
34
+ collection_resource.destroy_resource(self)
35
+ end
36
+
37
+ private
38
+
39
+ def collection_resource
40
+ @collection_resource ||= client.collection_resource_for(collection_resource_class, clip)
41
+ end
42
+
43
+ def client
44
+ @client
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ # This class is only meant to be used by Kippt::Favorite class for favoriting
2
+ # and unfavoriting clips.
3
+ class Kippt::Favorites
4
+ include Kippt::CollectionResource
5
+
6
+ attr_reader :clip
7
+
8
+ def initialize(client, clip)
9
+ @client = client
10
+ @clip = clip
11
+ end
12
+
13
+ def base_uri
14
+ "clips/#{clip.id}/favorites"
15
+ end
16
+
17
+ def destroy_resource(resource)
18
+ client.delete(base_uri).success?
19
+ end
20
+ end
@@ -1,12 +1,14 @@
1
- require "kippt/collection_resource"
2
- require "kippt/user_collection"
3
- require "kippt/user"
1
+ require_relative "user_collection"
4
2
 
5
3
  class Kippt::Followers
6
- include Kippt::CollectionResource
4
+ include Kippt::ReadCollectionResource
7
5
 
8
6
  attr_reader :user
9
7
 
8
+ def self.valid_filter_parameters
9
+ [:limit, :offset]
10
+ end
11
+
10
12
  def initialize(client, user)
11
13
  @client = client
12
14
  @user = user
@@ -1,12 +1,14 @@
1
- require "kippt/collection_resource"
2
- require "kippt/user_collection"
3
- require "kippt/user"
1
+ require_relative "user_collection"
4
2
 
5
3
  class Kippt::Following
6
- include Kippt::CollectionResource
4
+ include Kippt::ReadCollectionResource
7
5
 
8
6
  attr_reader :user
9
7
 
8
+ def self.valid_filter_parameters
9
+ [:limit, :offset]
10
+ end
11
+
10
12
  def initialize(client, user)
11
13
  @client = client
12
14
  @user = user
@@ -0,0 +1,17 @@
1
+ module Kippt::Helpers
2
+ private
3
+
4
+ def assert_valid_keys(hash, *valid_keys)
5
+ valid_keys.flatten!
6
+ hash.each_key do |k|
7
+ raise ArgumentError.new("Unrecognized argument: #{k}") unless valid_keys.include?(k)
8
+ end
9
+ end
10
+
11
+ def symbolize_keys! hash
12
+ hash.keys.each do |key|
13
+ hash[(key.to_sym rescue key) || key] = hash.delete(key)
14
+ end
15
+ hash
16
+ end
17
+ end
@@ -1,7 +1,9 @@
1
- require "kippt/users"
1
+ require_relative "likes"
2
2
 
3
3
  class Kippt::Like
4
- def initialize(client, clip)
4
+ attr_reader :clip, :errors
5
+
6
+ def initialize(clip, client)
5
7
  @client = client
6
8
  @errors = []
7
9
  @clip = clip
@@ -41,8 +43,4 @@ class Kippt::Like
41
43
  def client
42
44
  @client
43
45
  end
44
-
45
- def clip
46
- @clip
47
- end
48
46
  end
@@ -0,0 +1,11 @@
1
+ class Kippt::LikeCollection
2
+ include Kippt::Collection
3
+
4
+ def object_class
5
+ Kippt::Like
6
+ end
7
+
8
+ def collection_resource_class
9
+ Kippt::Likes
10
+ end
11
+ end
@@ -1,7 +1,5 @@
1
- require "kippt/user_collection"
2
- require "kippt/user"
3
- require "kippt/like"
4
-
1
+ # This class is only meant to be used by Kippt::Like class for liking and
2
+ # unliking clips.
5
3
  class Kippt::Likes
6
4
  include Kippt::CollectionResource
7
5
 
@@ -12,36 +10,10 @@ class Kippt::Likes
12
10
  @clip = clip
13
11
  end
14
12
 
15
- def self.valid_filter_parameters
16
- []
17
- end
18
-
19
- def object_class
20
- Kippt::User
21
- end
22
-
23
- def collection_class
24
- Kippt::UserCollection
25
- end
26
-
27
13
  def base_uri
28
14
  "clips/#{clip.id}/likes"
29
15
  end
30
16
 
31
- def all(options = {})
32
- validate_collection_options(options)
33
-
34
- if options.empty? && @clip.all_likes_embedded?
35
- collection_class.new({"objects" => @clip.likes_data}, client)
36
- else
37
- collection_class.new(client.get(base_uri, options).body, client)
38
- end
39
- end
40
-
41
- def build
42
- Kippt::Like.new(client, clip)
43
- end
44
-
45
17
  def destroy_resource(resource)
46
18
  client.delete(base_uri).success?
47
19
  end
@@ -1,4 +1,4 @@
1
- require "kippt/user"
1
+ require_relative "clips"
2
2
 
3
3
  class Kippt::List
4
4
  include Kippt::Resource
@@ -22,7 +22,13 @@ class Kippt::List
22
22
  end
23
23
 
24
24
  def clips
25
- Kippt::ClipCollection.new(client.get("lists/#{id}/clips").body, client)
25
+ Kippt::Clips.new(client, "lists/#{id}/clips")
26
+ end
27
+
28
+ def following?
29
+ response = client.get("#{resource_uri}relationship")
30
+ raise Kippt::APIError.new("There was an error with the request: #{response.body["message"]}") unless response.success?
31
+ response.body["following"]
26
32
  end
27
33
 
28
34
  def follow
@@ -1,5 +1,5 @@
1
- require "kippt/collection"
2
- require "kippt/list"
1
+ require_relative "lists"
2
+ require_relative "list"
3
3
 
4
4
  class Kippt::ListCollection
5
5
  include Kippt::Collection
@@ -1,7 +1,5 @@
1
- require "kippt/connection"
2
- require "kippt/collection_resource"
3
- require "kippt/list_collection"
4
- require "kippt/list"
1
+ require_relative "list_collection"
2
+ require_relative "list"
5
3
 
6
4
  class Kippt::Lists
7
5
  include Kippt::CollectionResource
@@ -0,0 +1,43 @@
1
+ module Kippt::ReadCollectionResource
2
+ include Kippt::Helpers
3
+
4
+ # For certain objects you can get extra data by giving option `include_data`.
5
+ # For example with clips you can add `include_data: "list,via"`.
6
+ def fetch(options = {})
7
+ validate_collection_options(options)
8
+
9
+ collection_class.new(client.get(base_uri, options).body, client)
10
+ end
11
+
12
+ alias all fetch
13
+
14
+ # For certain objects you can get extra data by giving option `include_data`.
15
+ # For example with clips you can add `include_data: "list,via"`.
16
+ def [](resource_id, options = {})
17
+ response = client.get("#{base_uri}/#{resource_id}", options)
18
+ if response.success?
19
+ object_class.new(response.body, client)
20
+ else
21
+ raise Kippt::APIError.new("Resource could not be loaded: #{response.body["message"]}")
22
+ end
23
+ end
24
+
25
+ alias find []
26
+
27
+ def collection_from_url(url)
28
+ raise ArgumentError.new("The parameter URL can't be blank") if url.nil? || url == ""
29
+
30
+ collection_class.new(client.get(url).body, client)
31
+ end
32
+
33
+ private
34
+
35
+ def validate_collection_options(options)
36
+ symbolize_keys! options
37
+ assert_valid_keys options, self.class.valid_filter_parameters
38
+ end
39
+
40
+ def client
41
+ @client
42
+ end
43
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "clips"
2
+
3
+ # The root "/clips" resource that exposes features like feed, favorites and
4
+ # search.
5
+ class Kippt::RootClips < Kippt::Clips
6
+ VALID_SEARCH_PARAMETERS = [:q, :list, :is_starred]
7
+
8
+ def initialize(client)
9
+ super(client, "clips")
10
+ end
11
+
12
+ def feed
13
+ Kippt::Clips.new(client, "clips/feed")
14
+ end
15
+
16
+ def favorites
17
+ Kippt::Clips.new(client, "clips/favorites")
18
+ end
19
+
20
+ def search(parameters)
21
+ if parameters.is_a?(String)
22
+ search({:q => parameters})
23
+ else
24
+ validate_search_parameters(parameters)
25
+
26
+ Kippt::ClipCollection.new(
27
+ client.get("search/clips", parameters).body,
28
+ client)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def validate_search_parameters(parameters)
35
+ parameters.each do |key, value|
36
+ raise ArgumentError.new("'#{key}' is not a valid search parameter") unless VALID_SEARCH_PARAMETERS.include?(key)
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,4 @@
1
- require "kippt/user_collection"
2
- require "kippt/user"
1
+ require_relative "user_collection"
3
2
 
4
3
  class Kippt::Saves
5
4
  attr_reader :clip
@@ -13,10 +12,12 @@ class Kippt::Saves
13
12
  Kippt::UserCollection
14
13
  end
15
14
 
16
- def all(options = {})
15
+ def fetch(options = {})
17
16
  collection_class.new({"objects" => @clip.saves_data}, client)
18
17
  end
19
18
 
19
+ alias all fetch
20
+
20
21
  private
21
22
 
22
23
  def client
@@ -1,9 +1,9 @@
1
- require "kippt/users"
2
- require "kippt/followers"
3
- require "kippt/following"
4
- require "kippt/follow_relationship"
5
- require "kippt/user_clips"
6
- require "kippt/user_lists"
1
+ require_relative "users"
2
+ require_relative "followers"
3
+ require_relative "following"
4
+ require_relative "follow_relationship"
5
+ require_relative "user_lists"
6
+ require_relative "user_likes"
7
7
 
8
8
  class Kippt::User
9
9
  include Kippt::Resource
@@ -36,6 +36,10 @@ class Kippt::User
36
36
  Kippt::Following.new(client, self)
37
37
  end
38
38
 
39
+ def likes
40
+ Kippt::UserLikes.new(client, self)
41
+ end
42
+
39
43
  # Tells if authenticated user is following the user.
40
44
  def following?
41
45
  Kippt::FollowRelationship.new(client, self).following?