swish 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,6 +17,7 @@ tmtags
17
17
  coverage
18
18
  rdoc
19
19
  pkg
20
+ .rvmrc
20
21
 
21
22
  ## PROJECT::SPECIFIC
22
23
  swish*.gem
data/README.rdoc CHANGED
@@ -11,6 +11,7 @@ Swish is just a Ruby gem:
11
11
  Not playing in the Ruby league? Here are the others we know of so far:
12
12
 
13
13
  * AS3: http://github.com/markstar/StarDribbbleLib
14
+ * C#/.NET: http://github.com/superlogical/dribbble-dotnet (I would have called it "Nothing but .NET")
14
15
  * ExpressionEngine 1.6.8+: http://ninefour.co.uk/labs/dribbble
15
16
  * ExpressionEngine 2: http://olivierbon.com/projects/dreebbble
16
17
  * PHP: http://github.com/martinbean/dribbble-php
@@ -33,18 +34,11 @@ Not playing in the Ruby league? Here are the others we know of so far:
33
34
  shot.comments_count
34
35
  shot.rebounds_count
35
36
 
36
-
37
37
  # Find more shots
38
38
  inspiring = Dribbble::Shot.popular
39
39
  call_the_police = Dribbble::Shot.everyone
40
40
  yay_noobs = Dribbble::Shot.debuts
41
41
 
42
- # Paginate through shots (default is 15 per page, max 30)
43
- Dribbble::Shot.popular(:page => 2, :per_page => 3)
44
- Dribbble::Shot.everyone(:page => 10, :per_page => 5)
45
- Dribbble::Shot.debuts(:page => 5, :per_page => 30)
46
-
47
-
48
42
  # Find a player
49
43
  player = Dribbble::Player.find('jeremy')
50
44
 
@@ -64,11 +58,9 @@ Not playing in the Ruby league? Here are the others we know of so far:
64
58
 
65
59
  # List a player's shots
66
60
  player.shots
67
- player.shots(:page => 2, :per_page => 10)
68
61
 
69
- # List shots by player's that this player follows
62
+ # List shots by players that this player follows
70
63
  player.shots_following
71
- player.shots_following(:page => 5, :per_page => 30)
72
64
 
73
65
  # List a player's draftees
74
66
  player.draftees
@@ -79,6 +71,41 @@ Not playing in the Ruby league? Here are the others we know of so far:
79
71
  # List the players who a player is following
80
72
  player.following
81
73
 
74
+ == Pagination
75
+
76
+ The Dribbble API returns paginated lists, with a default page size of 15 items. Swish makes it easy to traverse the pages of any list.
77
+
78
+ # Get the second page of popular shots, with 30 shots per page
79
+ shots = Dribbble::Shot.popular(:page => 2, :per_page => 30)
80
+
81
+ # Some useful stats for rendering pagination links
82
+ shots.page # => current page number
83
+ shots.per_page # => number of items per page
84
+ shots.total # => total number of items on all pages
85
+ shots.pages # => total number of pages
86
+
87
+ # Try it with other lists
88
+ Dribbble::Player.find('jeremy').shots(:per_page => 5)
89
+ Dribbble::Player.find('jeremy').shots_following(:page => 10)
90
+
91
+ See http://dribbble.com/api#pagination for more information.
92
+
93
+ == Who's using Swish?
94
+
95
+ * http://liiikes.com/, "Using statistics to find the best content on Dribbble."
96
+ * http://hooppps.com/, "A free open-source mobile dribbble browser"
97
+
98
+ Email jeremy@weiskotten.com to have your project added to this list.
99
+
100
+ == Thanks
101
+
102
+ Thanks to Dan and Rich for creating Dribbble (and its API!), and to everyone that has contributed to Swish, including:
103
+
104
+ * Jeffrey Chupp
105
+ * Jon Distad
106
+ * Michael Parenteau
107
+
108
+ Email jeremy@weiskotten.com if you should be on this list. Apologies and thanks in advance.
82
109
 
83
110
  == Note on Patches/Pull Requests
84
111
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.7.0
data/lib/dribbble/base.rb CHANGED
@@ -1,20 +1,24 @@
1
1
  module Dribbble
2
2
  class Base
3
3
  include HTTParty
4
- extend HTTParty
5
4
 
6
5
  base_uri 'api.dribbble.com'
7
6
 
8
- attr_accessor :created_at
9
-
10
- def initialize(attributes={})
7
+ def initialize(attributes=nil)
11
8
  attributes ||= {}
12
- attributes.each do |key, value|
13
- setter = "#{key}="
14
- self.send setter, value if self.respond_to?(setter)
9
+ @created_at = attributes.delete('created_at')
10
+ attributes.each do |(attr, val)|
11
+ instance_variable_set("@#{attr}", val)
12
+ instance_eval "def #{attr}() @#{attr} end"
15
13
  end
14
+ end
16
15
 
17
- after_initialize(attributes)
16
+ def get(*args, &block)
17
+ self.class.get *args, &block
18
+ end
19
+
20
+ def created_at
21
+ parse_time(@created_at)
18
22
  end
19
23
 
20
24
  def ==(other)
@@ -26,28 +30,18 @@ module Dribbble
26
30
  self == other
27
31
  end
28
32
 
29
- def created_at=(timestamp)
30
- @created_at = parse_time(timestamp)
33
+ def self.paginated_list(results)
34
+ Dribbble::PaginatedList.new(results)
31
35
  end
32
36
 
33
- protected
34
-
35
- def after_initialize(attributes)
36
- # no-op, can be overridden
37
+ def paginated_list(results)
38
+ self.class.paginated_list(results)
37
39
  end
38
40
 
39
- def self.paginated_list(result, list_key='shots')
40
- # result['total']
41
- # result['page']
42
- # result['pages']
43
- # result['per_page']
44
- result[list_key].map do |attributes|
45
- new(attributes)
46
- end
47
- end
41
+ protected
48
42
 
49
43
  def parse_time(time_string)
50
- Time.parse(time_string)
44
+ Time.parse(time_string) if time_string
51
45
  end
52
46
  end
53
47
  end
@@ -0,0 +1,9 @@
1
+ module Dribbble
2
+ class Comment < Base
3
+ attr_reader :player
4
+ def initialize(attributes={})
5
+ @player = Dribbble::Player.new(attributes.delete('player')) if attributes['player']
6
+ super
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module Dribbble
2
+ class PaginatedList < ::Array
3
+ attr_reader :total, :pages, :per_page, :page
4
+ def initialize(results)
5
+ @total = results['total']
6
+ @pages = results['pages']
7
+ @per_page = results['per_page']
8
+ @page = results['page']
9
+
10
+ result_key, result_class =
11
+ if results.has_key?('shots')
12
+ ['shots', Dribbble::Shot]
13
+ elsif results.has_key?('players')
14
+ ['players', Dribbble::Player]
15
+ else
16
+ ['comments', Dribbble::Comment]
17
+ end
18
+
19
+ super((results[result_key] || []).map { |attrs| result_class.new attrs })
20
+ end
21
+
22
+ def inspect
23
+ ivar_str = instance_variables.map {|iv| "#{iv}=#{instance_variable_get(iv).inspect}"}.join(", ")
24
+ "#<#{self.class.inspect} #{ivar_str}, @contents=#{super}>"
25
+ end
26
+ end
27
+ end
@@ -1,9 +1,5 @@
1
1
  module Dribbble
2
2
  class Player < Base
3
- attr_accessor :id, :name, :url, :avatar_url, :location, :twitter_screen_name, :drafted_by_player_id, :website_url,
4
- :shots_count, :draftees_count, :followers_count, :following_count,
5
- :comments_count, :comments_received_count, :likes_count, :likes_received_count, :rebounds_count, :rebounds_received_count
6
-
7
3
  def self.find(id)
8
4
  new(get("/players/#{id}"))
9
5
  end
@@ -11,24 +7,24 @@ module Dribbble
11
7
  # Fetches this player's shots.
12
8
  # Options: :page, :per_page
13
9
  def shots(options={})
14
- Shot.paginated_list(self.class.get("/players/#{@id}/shots", :query => options))
10
+ paginated_list(self.class.get("/players/#{@id}/shots", :query => options))
15
11
  end
16
12
 
17
13
  # Fetches shots by players that this player follows.
18
14
  def shots_following(options={})
19
- Shot.paginated_list(self.class.get("/players/#{@id}/shots/following", :query => options))
15
+ paginated_list(self.class.get("/players/#{@id}/shots/following", :query => options))
20
16
  end
21
17
 
22
18
  def draftees(options={})
23
- Player.paginated_list(self.class.get("/players/#{@id}/draftees", :query => options), 'players')
19
+ paginated_list(self.class.get("/players/#{@id}/draftees", :query => options))
24
20
  end
25
21
 
26
22
  def followers(options={})
27
- Player.paginated_list(self.class.get("/players/#{@id}/followers", :query => options), 'players')
23
+ paginated_list(self.class.get("/players/#{@id}/followers", :query => options))
28
24
  end
29
25
 
30
26
  def following(options={})
31
- Player.paginated_list(self.class.get("/players/#{@id}/following", :query => options), 'players')
27
+ paginated_list(self.class.get("/players/#{@id}/following", :query => options))
32
28
  end
33
29
  end
34
30
  end
data/lib/dribbble/shot.rb CHANGED
@@ -1,16 +1,19 @@
1
1
  module Dribbble
2
2
  class Shot < Base
3
- attr_accessor :id, :title, :url, :image_url, :image_teaser_url, :width, :height, :player,
4
- :views_count, :likes_count, :comments_count, :rebounds_count
5
-
6
- def after_initialize(attributes)
7
- @player = Dribbble::Player.new(attributes['player'])
3
+ attr_reader :player
4
+ def initialize(attributes={})
5
+ @player = Dribbble::Player.new(attributes.delete('player')) if attributes['player']
6
+ super
8
7
  end
9
8
 
10
9
  def self.find(id)
11
10
  new(get("/shots/#{id}"))
12
11
  end
13
12
 
13
+ def comments(options={})
14
+ paginated_list(get("/shots/#{@id}/comments", :query => options))
15
+ end
16
+
14
17
  # Options: :page, :per_page
15
18
  def self.debuts(options={})
16
19
  paginated_list(get("/shots/debuts", :query => options))
@@ -26,4 +29,4 @@ module Dribbble
26
29
  paginated_list(get("/shots/popular", :query => options))
27
30
  end
28
31
  end
29
- end
32
+ end
data/lib/swish.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'httparty'
2
+ require 'dribbble/paginated_list'
2
3
  require 'dribbble/base'
4
+ require 'dribbble/comment'
3
5
  require 'dribbble/shot'
4
- require 'dribbble/player'
6
+ require 'dribbble/player'
data/swish.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{swish}
8
- s.version = "0.6.0"
8
+ s.version = "0.7.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeremy Weiskotten"]
12
- s.date = %q{2010-09-18}
12
+ s.date = %q{2011-02-20}
13
13
  s.description = %q{A Ruby wrapper for the Dribbble API}
14
14
  s.email = %q{jeremy@weiskotten.com}
15
15
  s.extra_rdoc_files = [
@@ -24,11 +24,16 @@ Gem::Specification.new do |s|
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "lib/dribbble/base.rb",
27
+ "lib/dribbble/comment.rb",
28
+ "lib/dribbble/paginated_list.rb",
27
29
  "lib/dribbble/player.rb",
28
30
  "lib/dribbble/shot.rb",
29
31
  "lib/swish.rb",
30
32
  "swish.gemspec",
33
+ "test/base_test.rb",
34
+ "test/comment_test.rb",
31
35
  "test/helper.rb",
36
+ "test/paginated_list_test.rb",
32
37
  "test/player_test.rb",
33
38
  "test/shot_test.rb"
34
39
  ]
@@ -38,7 +43,10 @@ Gem::Specification.new do |s|
38
43
  s.rubygems_version = %q{1.3.7}
39
44
  s.summary = %q{A Ruby wrapper for the Dribbble API}
40
45
  s.test_files = [
41
- "test/helper.rb",
46
+ "test/base_test.rb",
47
+ "test/comment_test.rb",
48
+ "test/helper.rb",
49
+ "test/paginated_list_test.rb",
42
50
  "test/player_test.rb",
43
51
  "test/shot_test.rb"
44
52
  ]
data/test/base_test.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'helper'
2
+
3
+ class BaseTest < Test::Unit::TestCase
4
+ def test_attributes_are_methods
5
+ base = Dribbble::Base.new('foo' => 'bar', 'baz' => 'qux')
6
+ assert base.respond_to?(:foo)
7
+ assert base.respond_to?(:baz)
8
+ assert_equal 'bar', base.foo
9
+ assert_equal 'qux', base.baz
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'helper'
2
+
3
+ class CommentTest < Test::Unit::TestCase
4
+
5
+ def test_comment_has_a_player_object
6
+ comment = Dribbble::Comment.new('player' => {})
7
+ assert comment.player.is_a?(Dribbble::Player), "#{comment.player.inspect} is not a Dribbble::Player."
8
+ end
9
+
10
+ end
@@ -0,0 +1,63 @@
1
+ require 'helper'
2
+
3
+ class PaginatedListTest < Test::Unit::TestCase
4
+ def setup
5
+ @shots_results = {
6
+ "total"=>750,
7
+ "shots"=>[{}, {}],
8
+ "page"=>1,
9
+ "pages"=>375,
10
+ "per_page"=>2
11
+ }
12
+ end
13
+
14
+ def test_initialize_gathers_pagination_data
15
+ list = Dribbble::PaginatedList.new(@shots_results)
16
+
17
+ assert_equal 375, list.pages
18
+ assert_equal 750, list.total
19
+ assert_equal 1, list.page
20
+ assert_equal 2, list.per_page
21
+ end
22
+
23
+ def test_list_behaves_as_array
24
+ list = Dribbble::PaginatedList.new(@shots_results)
25
+ assert list.is_a? Array
26
+ assert list.respond_to?(:each)
27
+ assert list.respond_to?(:first)
28
+ end
29
+
30
+ def test_initialize_collects_shots_by_default
31
+ list = Dribbble::PaginatedList.new(@shots_results)
32
+ assert_equal 2, list.size
33
+ list.each { |shot| assert shot.is_a?(Dribbble::Shot), "#{shot.inspect} is not a Dribbble::Shot." }
34
+ end
35
+
36
+ def test_initialize_collecting_players
37
+ player_followers_results = {
38
+ "players"=> [{}, {}],
39
+ "total"=>201,
40
+ "page"=>1,
41
+ "pages"=>101,
42
+ "per_page"=>2
43
+ }
44
+
45
+ list = Dribbble::PaginatedList.new(player_followers_results)
46
+ assert_equal 2, list.size
47
+ list.each { |p| assert p.is_a?(Dribbble::Player), "#{p.inspect} is not a Dribbble::Player" }
48
+ end
49
+
50
+ def test_initialize_collecting_comments
51
+ comments_results = {
52
+ "comments"=> [{}, {}],
53
+ "total"=>201,
54
+ "page"=>1,
55
+ "pages"=>101,
56
+ "per_page"=>2
57
+ }
58
+
59
+ list = Dribbble::PaginatedList.new(comments_results)
60
+ assert_equal 2, list.size
61
+ list.each { |p| assert p.is_a?(Dribbble::Comment), "#{p.inspect} is not a Dribbble::Comment" }
62
+ end
63
+ end
data/test/player_test.rb CHANGED
@@ -5,7 +5,7 @@ class PlayerTest < Test::Unit::TestCase
5
5
  player = Dribbble::Player.find(1)
6
6
  assert_equal 1, player.id
7
7
  assert_equal 'Dan Cederholm', player.name
8
- assert_equal 'http://dribbble.com/players/simplebits', player.url
8
+ assert_equal 'http://dribbble.com/simplebits', player.url
9
9
  assert_equal 'http://simplebits.com', player.website_url
10
10
  assert_equal 'Salem, MA', player.location
11
11
  assert_not_nil player.created_at
data/test/shot_test.rb CHANGED
@@ -28,8 +28,8 @@ class ShotTest < Test::Unit::TestCase
28
28
  assert_equal 21603, shot.id
29
29
  assert_equal 'Moon', shot.title
30
30
  assert_equal 'http://dribbble.com/shots/21603-Moon', shot.url
31
- assert_equal 'http://dribbble.com/system/users/1/screenshots/21603/shot_1274474082.png', shot.image_url
32
- assert_equal 'http://dribbble.com/system/users/1/screenshots/21603/shot_1274474082_teaser.png', shot.image_teaser_url
31
+ assert_match /http:\/\/dribbble.com\/system\/users\/1\/screenshots\/21603\/shot_1274474082.png\?\d+/, shot.image_url
32
+ assert_match /http:\/\/dribbble.com\/system\/users\/1\/screenshots\/21603\/shot_1274474082_teaser.png\?\d+/, shot.image_teaser_url
33
33
  assert_equal 400, shot.width
34
34
  assert_equal 300, shot.height
35
35
 
@@ -41,6 +41,13 @@ class ShotTest < Test::Unit::TestCase
41
41
  assert_kind_of Dribbble::Player, shot.player
42
42
  end
43
43
 
44
+ def test_comments
45
+ shot = Dribbble::Shot.find(21603)
46
+ comments = shot.comments
47
+ assert comments.is_a?(Dribbble::PaginatedList), "#{comments.inspect} is not a Dribbble::PaginatedList."
48
+ comments.each { |c| assert c.is_a?(Dribbble::Comment), "#{c.inspect} is not a Dribbble::Comment." }
49
+ end
50
+
44
51
  def test_debuts
45
52
  shots = Dribbble::Shot.debuts
46
53
  assert_kind_of Array, shots
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swish
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 6
8
+ - 7
9
9
  - 0
10
- version: 0.6.0
10
+ version: 0.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Weiskotten
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-18 00:00:00 -04:00
18
+ date: 2011-02-20 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -67,11 +67,16 @@ files:
67
67
  - Rakefile
68
68
  - VERSION
69
69
  - lib/dribbble/base.rb
70
+ - lib/dribbble/comment.rb
71
+ - lib/dribbble/paginated_list.rb
70
72
  - lib/dribbble/player.rb
71
73
  - lib/dribbble/shot.rb
72
74
  - lib/swish.rb
73
75
  - swish.gemspec
76
+ - test/base_test.rb
77
+ - test/comment_test.rb
74
78
  - test/helper.rb
79
+ - test/paginated_list_test.rb
75
80
  - test/player_test.rb
76
81
  - test/shot_test.rb
77
82
  has_rdoc: true
@@ -109,6 +114,9 @@ signing_key:
109
114
  specification_version: 3
110
115
  summary: A Ruby wrapper for the Dribbble API
111
116
  test_files:
117
+ - test/base_test.rb
118
+ - test/comment_test.rb
112
119
  - test/helper.rb
120
+ - test/paginated_list_test.rb
113
121
  - test/player_test.rb
114
122
  - test/shot_test.rb