social-avatar-proxy 1.1.0 → 1.2.0
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/README.md +13 -2
- data/lib/social_avatar_proxy.rb +1 -0
- data/lib/social_avatar_proxy/app.rb +72 -21
- data/lib/social_avatar_proxy/config.rb +30 -0
- data/lib/social_avatar_proxy/version.rb +1 -1
- data/spec/fixtures/image.jpg +0 -0
- data/spec/social_avatar_proxy/app_spec.rb +13 -1
- data/spec/social_avatar_proxy/config_spec.rb +57 -0
- metadata +6 -1
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
## Usage
|
29
29
|
|
30
|
-
|
30
|
+
### Rails
|
31
31
|
|
32
32
|
In your `config/routes.rb` file:
|
33
33
|
|
@@ -51,7 +51,18 @@ image_tag(facebook_avatar_path("username"))
|
|
51
51
|
image_tag(facebook_avatar_path(12345))
|
52
52
|
```
|
53
53
|
|
54
|
-
|
54
|
+
You might wish to configure a default image which will be rendered if an avatar could not be found, or if the remote service has an error (e.g. times out or has a redirect loop), this is simple with an initializer:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
require "social_avatar_proxy/config"
|
58
|
+
|
59
|
+
# choose our image
|
60
|
+
image_path = Rails.root.join("public", "default_avatar.jpg")
|
61
|
+
# set the config
|
62
|
+
SocialAvatarProxy::Config.default_image = image_path
|
63
|
+
```
|
64
|
+
|
65
|
+
### Rack
|
55
66
|
|
56
67
|
The Rack app is available at: SocialAvatarProxy::App.
|
57
68
|
|
data/lib/social_avatar_proxy.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "social_avatar_proxy/config"
|
1
2
|
require "social_avatar_proxy/facebook_avatar"
|
2
3
|
require "social_avatar_proxy/twitter_avatar"
|
3
4
|
require "social_avatar_proxy/routes"
|
@@ -54,25 +55,13 @@ module SocialAvatarProxy
|
|
54
55
|
if avatar.exist?
|
55
56
|
# render the avatar to the response
|
56
57
|
Rack::Response.new do |response|
|
57
|
-
# set the
|
58
|
-
response["Last-Modified"] = avatar.last_modified
|
59
|
-
# set the content type header
|
60
|
-
response["Content-Type"] = avatar.content_type
|
61
|
-
# if we want to expire in a set time, calculate the header
|
62
|
-
if options[:expires]
|
63
|
-
response["Expires"] = (Time.now + options[:expires]).httpdate
|
64
|
-
end
|
65
|
-
# if we want to set cache control settings
|
66
|
-
if cc = options[:cache_control]
|
67
|
-
directives = []
|
68
|
-
directives << "no-cache" if cc[:no_cache]
|
69
|
-
directives << "max-stale=#{cc[:max_stale]}" if cc[:max_stale]
|
70
|
-
directives << "max-age=#{cc[:max_age]}" if cc[:max_age]
|
71
|
-
directives << (cc[:public] ? "public" : "private")
|
72
|
-
response["Cache-Control"] = directives.join(", ")
|
73
|
-
end
|
74
|
-
# set the data
|
58
|
+
# set the response data
|
75
59
|
response.write(avatar.body)
|
60
|
+
# set the response headers
|
61
|
+
response = set_avatar_headers(response, avatar)
|
62
|
+
response = set_caching_headers(response)
|
63
|
+
# return the response
|
64
|
+
response
|
76
65
|
end
|
77
66
|
# if the avatar doesn't exist
|
78
67
|
else
|
@@ -81,15 +70,39 @@ module SocialAvatarProxy
|
|
81
70
|
end
|
82
71
|
|
83
72
|
def not_found
|
84
|
-
Rack::Response.new(
|
73
|
+
Rack::Response.new([], 404) do |response|
|
74
|
+
# if we have a custom default image
|
75
|
+
if Config.default_image
|
76
|
+
render_default_image(response)
|
77
|
+
# without a default image
|
78
|
+
else
|
79
|
+
response.write "Not Found"
|
80
|
+
end
|
81
|
+
end
|
85
82
|
end
|
86
83
|
|
87
84
|
def timeout
|
88
|
-
Rack::Response.new(
|
85
|
+
Rack::Response.new([], 504) do |response|
|
86
|
+
# if we have a custom default image
|
87
|
+
if Config.default_image
|
88
|
+
render_default_image(response)
|
89
|
+
# without a default image
|
90
|
+
else
|
91
|
+
response.write "Remote server timeout"
|
92
|
+
end
|
93
|
+
end
|
89
94
|
end
|
90
95
|
|
91
96
|
def bad_gateway
|
92
|
-
Rack::Response.new(
|
97
|
+
Rack::Response.new([], 502) do |response|
|
98
|
+
# if we have a custom default image
|
99
|
+
if Config.default_image
|
100
|
+
render_default_image(response)
|
101
|
+
# without a default image
|
102
|
+
else
|
103
|
+
response.write "Bad response from remote server"
|
104
|
+
end
|
105
|
+
end
|
93
106
|
end
|
94
107
|
|
95
108
|
def routes
|
@@ -97,6 +110,44 @@ module SocialAvatarProxy
|
|
97
110
|
end
|
98
111
|
|
99
112
|
private
|
113
|
+
def render_default_image(response)
|
114
|
+
# render the image
|
115
|
+
response.write(Config.default_image_data)
|
116
|
+
# set the content type
|
117
|
+
response["Content-Type"] = Config.default_image_content_type
|
118
|
+
# set expiry
|
119
|
+
response = set_caching_headers(response)
|
120
|
+
# return the response
|
121
|
+
response
|
122
|
+
end
|
123
|
+
|
124
|
+
def set_avatar_headers(response, avatar)
|
125
|
+
# set the last modified header
|
126
|
+
response["Last-Modified"] = avatar.last_modified
|
127
|
+
# set the content type header
|
128
|
+
response["Content-Type"] = avatar.content_type
|
129
|
+
# return the response
|
130
|
+
response
|
131
|
+
end
|
132
|
+
|
133
|
+
def set_caching_headers(response)
|
134
|
+
# if we want to expire in a set time, calculate the header
|
135
|
+
if options[:expires]
|
136
|
+
response["Expires"] = (Time.now + options[:expires]).httpdate
|
137
|
+
end
|
138
|
+
# if we want to set cache control settings
|
139
|
+
if cc = options[:cache_control]
|
140
|
+
directives = []
|
141
|
+
directives << "no-cache" if cc[:no_cache]
|
142
|
+
directives << "max-stale=#{cc[:max_stale]}" if cc[:max_stale]
|
143
|
+
directives << "max-age=#{cc[:max_age]}" if cc[:max_age]
|
144
|
+
directives << (cc[:public] ? "public" : "private")
|
145
|
+
response["Cache-Control"] = directives.join(", ")
|
146
|
+
end
|
147
|
+
# return the response
|
148
|
+
response
|
149
|
+
end
|
150
|
+
|
100
151
|
def load_avatar(service, id)
|
101
152
|
# titleize the service name
|
102
153
|
service = service.gsub(/[\_\-]/, " ").gsub(/\b([a-z])/) do |match|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SocialAvatarProxy
|
2
|
+
class Config
|
3
|
+
class << self
|
4
|
+
attr_accessor :default_image
|
5
|
+
|
6
|
+
def default_image_file
|
7
|
+
default_image && File.new(default_image)
|
8
|
+
end
|
9
|
+
|
10
|
+
def default_image_data
|
11
|
+
default_image_file.read
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_image_content_type
|
15
|
+
case File.extname(default_image).downcase
|
16
|
+
when /^\.jpe?g$/
|
17
|
+
"image/jpeg"
|
18
|
+
when /^\.png$/
|
19
|
+
"image/png"
|
20
|
+
when /^\.gif$/
|
21
|
+
"image/gif"
|
22
|
+
when /^\.svg$/
|
23
|
+
"image/svg+xml"
|
24
|
+
else
|
25
|
+
"application/octet-stream"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
Binary file
|
@@ -57,10 +57,22 @@ describe SocialAvatarProxy::App do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
context "given an invalid path" do
|
60
|
+
let(:path) { "/unknown" }
|
61
|
+
|
60
62
|
it "should return a 404 response" do
|
61
|
-
path = "/unknown"
|
62
63
|
expect(subject.get(path).status).to eq(404)
|
63
64
|
end
|
65
|
+
|
66
|
+
context "with a custom image" do
|
67
|
+
before(:each) do
|
68
|
+
image_path = File.join(File.dirname(__FILE__), "../fixtures/image.jpg")
|
69
|
+
SocialAvatarProxy::Config.default_image = image_path
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should render the image" do
|
73
|
+
expect(subject.get(path)["Content-Type"]).to eq("image/jpeg")
|
74
|
+
end
|
75
|
+
end
|
64
76
|
end
|
65
77
|
|
66
78
|
context "given a valid path" do
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe SocialAvatarProxy::Config do
|
4
|
+
subject { SocialAvatarProxy::Config }
|
5
|
+
|
6
|
+
after(:each) do
|
7
|
+
subject.default_image = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "::default_image" do
|
11
|
+
it "should default to nil" do
|
12
|
+
expect(subject.default_image).to be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should store a path" do
|
16
|
+
subject.default_image = "/test.jpg"
|
17
|
+
expect(subject.default_image).to eq "/test.jpg"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "::default_image_content_type" do
|
22
|
+
context "with a JPEG" do
|
23
|
+
it "should return image/jpeg" do
|
24
|
+
subject.default_image = "/test.JPG"
|
25
|
+
expect(subject.default_image_content_type).to eq "image/jpeg"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with a PNG" do
|
30
|
+
it "should return image/png" do
|
31
|
+
subject.default_image = "/test.png"
|
32
|
+
expect(subject.default_image_content_type).to eq "image/png"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with a GIF" do
|
37
|
+
it "should return image/gif" do
|
38
|
+
subject.default_image = "/test.gif"
|
39
|
+
expect(subject.default_image_content_type).to eq "image/gif"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with a SVG" do
|
44
|
+
it "should return image/svg+xml" do
|
45
|
+
subject.default_image = "/test.svg"
|
46
|
+
expect(subject.default_image_content_type).to eq "image/svg+xml"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with an unknown type" do
|
51
|
+
it "should return application/octet-stream" do
|
52
|
+
subject.default_image = "/test"
|
53
|
+
expect(subject.default_image_content_type).to eq "application/octet-stream"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: social-avatar-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/social_avatar_proxy.rb
|
127
127
|
- lib/social_avatar_proxy/app.rb
|
128
128
|
- lib/social_avatar_proxy/avatar.rb
|
129
|
+
- lib/social_avatar_proxy/config.rb
|
129
130
|
- lib/social_avatar_proxy/engine.rb
|
130
131
|
- lib/social_avatar_proxy/facebook_avatar.rb
|
131
132
|
- lib/social_avatar_proxy/path_helpers.rb
|
@@ -136,9 +137,11 @@ files:
|
|
136
137
|
- lib/social_avatar_proxy/twitter_avatar.rb
|
137
138
|
- lib/social_avatar_proxy/version.rb
|
138
139
|
- social-avatar-proxy.gemspec
|
140
|
+
- spec/fixtures/image.jpg
|
139
141
|
- spec/internal/config/routes.rb
|
140
142
|
- spec/social_avatar_proxy/app_spec.rb
|
141
143
|
- spec/social_avatar_proxy/avatar_spec.rb
|
144
|
+
- spec/social_avatar_proxy/config_spec.rb
|
142
145
|
- spec/social_avatar_proxy/engine_spec.rb
|
143
146
|
- spec/social_avatar_proxy/facebook_avatar_spec.rb
|
144
147
|
- spec/social_avatar_proxy/path_helpers_spec.rb
|
@@ -173,9 +176,11 @@ signing_key:
|
|
173
176
|
specification_version: 3
|
174
177
|
summary: This gem acts as a proxy for avatars on Twitter & Facebook.
|
175
178
|
test_files:
|
179
|
+
- spec/fixtures/image.jpg
|
176
180
|
- spec/internal/config/routes.rb
|
177
181
|
- spec/social_avatar_proxy/app_spec.rb
|
178
182
|
- spec/social_avatar_proxy/avatar_spec.rb
|
183
|
+
- spec/social_avatar_proxy/config_spec.rb
|
179
184
|
- spec/social_avatar_proxy/engine_spec.rb
|
180
185
|
- spec/social_avatar_proxy/facebook_avatar_spec.rb
|
181
186
|
- spec/social_avatar_proxy/path_helpers_spec.rb
|