cameraplus 0.0.1
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.
- data/.gitignore +9 -0
- data/.rvmrc +55 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +227 -0
- data/Rakefile +2 -0
- data/cameraplus.gemspec +25 -0
- data/lib/cameraplus.rb +18 -0
- data/lib/cameraplus/api/page.rb +17 -0
- data/lib/cameraplus/api/request.rb +45 -0
- data/lib/cameraplus/api/search.rb +25 -0
- data/lib/cameraplus/api/user.rb +17 -0
- data/lib/cameraplus/comment.rb +14 -0
- data/lib/cameraplus/exceptions.rb +7 -0
- data/lib/cameraplus/page.rb +34 -0
- data/lib/cameraplus/page_metadata.rb +73 -0
- data/lib/cameraplus/photo.rb +49 -0
- data/lib/cameraplus/photo_exif.rb +13 -0
- data/lib/cameraplus/photo_recipe.rb +12 -0
- data/lib/cameraplus/search.rb +45 -0
- data/lib/cameraplus/user.rb +72 -0
- data/lib/cameraplus/version.rb +3 -0
- data/lib/core_ext/hash.rb +13 -0
- data/spec/cameraplus/api/page_spec.rb +17 -0
- data/spec/cameraplus/api/request_spec.rb +47 -0
- data/spec/cameraplus/api/search_spec.rb +37 -0
- data/spec/cameraplus/api/user_spec.rb +17 -0
- data/spec/cameraplus/comment_spec.rb +32 -0
- data/spec/cameraplus/page_metadata_spec.rb +117 -0
- data/spec/cameraplus/page_spec.rb +84 -0
- data/spec/cameraplus/photo_exif_spec.rb +23 -0
- data/spec/cameraplus/photo_recipe_spec.rb +19 -0
- data/spec/cameraplus/photo_spec.rb +82 -0
- data/spec/cameraplus/search_spec.rb +51 -0
- data/spec/cameraplus/user_spec.rb +82 -0
- data/spec/core_ext/hash_spec.rb +53 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/vcr_cassettes/api_request_invalid.yml +56 -0
- data/spec/vcr_cassettes/api_request_valid.yml +78 -0
- data/spec/vcr_cassettes/more_results.yml +369 -0
- data/spec/vcr_cassettes/page.yml +58 -0
- data/spec/vcr_cassettes/search.yml +55 -0
- data/spec/vcr_cassettes/user.yml +78 -0
- data/spec/vcr_config.rb +7 -0
- metadata +177 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module Cameraplus
|
2
|
+
class Page
|
3
|
+
|
4
|
+
attr_reader :url, :created_at, :location, :location_name, :tweet_text, :tweet_id, :view_count, :comment_count, :photos
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@data = data
|
8
|
+
parse
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def parse
|
14
|
+
parse_page
|
15
|
+
parse_photos
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_page
|
19
|
+
@url = @data.url
|
20
|
+
@created_at = DateTime.parse @data.timestamp
|
21
|
+
@location = @data.location
|
22
|
+
@location_name = @data.locationname
|
23
|
+
@tweet_text = @data.tweettext
|
24
|
+
@tweet_id = @data.tweetid.to_i
|
25
|
+
@view_count = @data.views
|
26
|
+
@comment_count = @data.comments.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_photos
|
30
|
+
@photos ||= @data.images.map { |image| Photo.new image }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Cameraplus
|
2
|
+
class PageMetadata
|
3
|
+
|
4
|
+
attr_reader :url, :created_at, :location, :location_name, :tweet_text, :tweet_id, :view_count, :comment_count, :user, :photos, :comments
|
5
|
+
|
6
|
+
def self.find(identifier, options = {})
|
7
|
+
new Cameraplus::API::Page.find(identifier, options), identifier
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(data, identifier)
|
11
|
+
@data = data
|
12
|
+
@identifier = identifier
|
13
|
+
parse
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def parse
|
19
|
+
parse_metadata
|
20
|
+
parse_user
|
21
|
+
parse_photos
|
22
|
+
parse_comments
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_metadata
|
26
|
+
@url = parsed_url
|
27
|
+
@created_at = parsed_created_at
|
28
|
+
@location = parsed_location
|
29
|
+
@location_name = parsed_location_name
|
30
|
+
@tweet_text = @data.page.tweet.text
|
31
|
+
@tweet_id = @data.page.tweet.id.to_i
|
32
|
+
@view_count = @data.page.views
|
33
|
+
@comment_count = @data.page.comments.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_user
|
37
|
+
@user ||= Cameraplus::User.new user: @data.page.tweet
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_photos
|
41
|
+
@photos ||= @data.pictures.map { |photo| Photo.new photo }
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_comments
|
45
|
+
@comments ||= @data.comments.map { |comment| Comment.new comment }
|
46
|
+
end
|
47
|
+
|
48
|
+
def parsed_url
|
49
|
+
"#{Cameraplus::API::Request.base_uri}/#{@identifier}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def parsed_created_at
|
53
|
+
DateTime.parse @data.page.timestamp if has_timestamp?
|
54
|
+
end
|
55
|
+
|
56
|
+
def parsed_location
|
57
|
+
@data.page.location.coords if has_location?
|
58
|
+
end
|
59
|
+
|
60
|
+
def parsed_location_name
|
61
|
+
@data.page.location.name if has_location?
|
62
|
+
end
|
63
|
+
|
64
|
+
def has_timestamp?
|
65
|
+
@data.page.has_key? "timestamp"
|
66
|
+
end
|
67
|
+
|
68
|
+
def has_location?
|
69
|
+
@data.page.has_key? "location"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Cameraplus
|
2
|
+
class Photo
|
3
|
+
|
4
|
+
attr_reader :small, :medium, :large, :width, :height, :location, :recipes, :exif
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@data = data
|
8
|
+
parse
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def parse
|
14
|
+
parse_photo
|
15
|
+
parse_recipes if has_recipes?
|
16
|
+
parse_exif if has_exif?
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse_photo
|
20
|
+
@small = @data["120px"]
|
21
|
+
@medium = @data["480px"]
|
22
|
+
@large = @data["800px"]
|
23
|
+
@width = @data.fullwidth.to_i
|
24
|
+
@height = @data.fullheight.to_i
|
25
|
+
@location = @data.location if has_location?
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_recipes
|
29
|
+
@recipes ||= @data.recipe.map { |recipe| PhotoRecipe.new recipe }
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_exif
|
33
|
+
@exif ||= @data.exifdata.map { |exif| PhotoExif.new exif }
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_recipes?
|
37
|
+
@data.has_key? "recipe"
|
38
|
+
end
|
39
|
+
|
40
|
+
def has_exif?
|
41
|
+
@data.has_key? "exifdata"
|
42
|
+
end
|
43
|
+
|
44
|
+
def has_location?
|
45
|
+
@data.has_key? "location"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Cameraplus
|
2
|
+
class Search
|
3
|
+
|
4
|
+
attr_reader :page, :user, :photos
|
5
|
+
|
6
|
+
def self.find(filters)
|
7
|
+
results = Cameraplus::API::Search.find filters
|
8
|
+
results.map { |result| new result }
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(result)
|
12
|
+
@result ||= result
|
13
|
+
parse
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def parse
|
19
|
+
parse_page
|
20
|
+
parse_user if has_user?
|
21
|
+
parse_photos if has_photos?
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_page
|
25
|
+
@page ||= Page.new @result
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_user
|
29
|
+
@user ||= User.new @result
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_photos
|
33
|
+
@photos ||= @result.images.map { |photo| Photo.new photo }
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_user?
|
37
|
+
@result.has_key? "user"
|
38
|
+
end
|
39
|
+
|
40
|
+
def has_photos?
|
41
|
+
@result.has_key? "images"
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Cameraplus
|
2
|
+
class User
|
3
|
+
|
4
|
+
attr_reader :id, :username, :name, :avatar, :page_count, :photo_count, :pages
|
5
|
+
|
6
|
+
def self.find(identifier, options = {})
|
7
|
+
new Cameraplus::API::User.find(identifier, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(data)
|
11
|
+
@data = data
|
12
|
+
parse
|
13
|
+
end
|
14
|
+
|
15
|
+
def more_results
|
16
|
+
@more_results ||= User.find(username, continue: next_page_id) if has_more_pages?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def parse
|
22
|
+
parse_user
|
23
|
+
parse_pages if has_pages?
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_user
|
27
|
+
@id = @data.user.userid.to_i
|
28
|
+
@username = @data.user.username
|
29
|
+
@name = @data.user.realname
|
30
|
+
@avatar = @data.user.avatar
|
31
|
+
@page_count = parsed_page_count
|
32
|
+
@photo_count = parsed_photo_count
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_pages
|
36
|
+
@pages ||= @data.pages.map { |page| Page.new page }
|
37
|
+
end
|
38
|
+
|
39
|
+
def parsed_page_count
|
40
|
+
@data.user.pages.to_i if has_page_count?
|
41
|
+
end
|
42
|
+
|
43
|
+
def parsed_photo_count
|
44
|
+
@data.user.pictures.to_i if has_photo_count?
|
45
|
+
end
|
46
|
+
|
47
|
+
def next_page_id
|
48
|
+
@data.next.match(next_page_regex).to_a.last
|
49
|
+
end
|
50
|
+
|
51
|
+
def next_page_regex
|
52
|
+
/http:\/\/camerapl.us\/user\/#{username}:pages\?continue=(.*)/
|
53
|
+
end
|
54
|
+
|
55
|
+
def has_pages?
|
56
|
+
@data.has_key? "pages"
|
57
|
+
end
|
58
|
+
|
59
|
+
def has_more_pages?
|
60
|
+
@data.has_key? "next"
|
61
|
+
end
|
62
|
+
|
63
|
+
def has_page_count?
|
64
|
+
@data.user.has_key? "pages"
|
65
|
+
end
|
66
|
+
|
67
|
+
def has_photo_count?
|
68
|
+
@data.user.has_key? "pictures"
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Cameraplus::API::Page do
|
4
|
+
|
5
|
+
use_vcr_cassette :page
|
6
|
+
|
7
|
+
it "should receive a Hash" do
|
8
|
+
response = Cameraplus::API::Page.find "b72Z"
|
9
|
+
response.should be_a Hash
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should make a request to the Camera+ API" do
|
13
|
+
Cameraplus::API::Request.should_receive(:call).with "/b72Z:info", {}
|
14
|
+
Cameraplus::API::Page.find "b72Z"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Cameraplus::API::Request do
|
4
|
+
|
5
|
+
subject { Cameraplus::API::Request }
|
6
|
+
|
7
|
+
context "configuration" do
|
8
|
+
|
9
|
+
it "should know it's base URI" do
|
10
|
+
subject.base_uri.should eq "http://camerapl.us"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
context "connecting with the api" do
|
16
|
+
|
17
|
+
use_vcr_cassette :api_request_valid
|
18
|
+
|
19
|
+
let(:response) { subject.call "/user/mostlylisa:pages" }
|
20
|
+
|
21
|
+
it "should have a response" do
|
22
|
+
response.should_not be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should contain user data" do
|
26
|
+
response.should have_key "user"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should contain user pages" do
|
30
|
+
response.should have_key "pages"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context "connecting with an invalid api call" do
|
36
|
+
|
37
|
+
use_vcr_cassette :api_request_invalid
|
38
|
+
|
39
|
+
let(:response) { subject.call "/non-existing-page" }
|
40
|
+
|
41
|
+
it "should raise an error" do
|
42
|
+
expect { response }.to raise_error Cameraplus::InvalidResponseError
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Cameraplus::API::Search do
|
4
|
+
|
5
|
+
context "with a valid argument" do
|
6
|
+
|
7
|
+
use_vcr_cassette :search
|
8
|
+
|
9
|
+
it "should receive an Array" do
|
10
|
+
response = Cameraplus::API::Search.find username: "mostlylisa"
|
11
|
+
response.should be_a Array
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should make a request to the Camera+ API" do
|
15
|
+
Cameraplus::API::Request.should_receive(:call).with "/search", { username: "mostlylisa" }
|
16
|
+
Cameraplus::API::Search.find username: "mostlylisa"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with an invalid argument" do
|
22
|
+
|
23
|
+
it "when searching for an non-existing argument should raise an error" do
|
24
|
+
expect { Cameraplus::API::Search.find foo: "bar" }.to raise_error Cameraplus::InvalidArgumentError
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with no arguments" do
|
30
|
+
|
31
|
+
it "should raise an argument error" do
|
32
|
+
expect { Cameraplus::API::Search.find() }.to raise_error ArgumentError
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|