Skip to content

Commit

Permalink
Merge pull request #105 from betacraft/fix_twitter_profile_images
Browse files Browse the repository at this point in the history
Fix twitter profile images
  • Loading branch information
harunkumars authored Aug 26, 2023
2 parents cdf7a92 + 67c8a71 commit 8a34a2c
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 11 deletions.
26 changes: 24 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
module ApplicationHelper
def get_twitter_image(twitter_handle)
image_tag "https://res.cloudinary.com/#{ENV['CLOUDINARY_HANDLE']}/image/twitter_name/#{twitter_handle}.jpg", onerror: 'this.error=null;this.src="https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png"'
def get_twitter_image(user)
image_tag image_for_twitter_handle(user), onerror: 'this.error=null;this.src="https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png"'
end

private

RubyConfIndia2023 = Date.parse('2023-08-26')

def image_for_twitter_handle(user)
if user.updated_at.after?(RubyConfIndia2023) && user.image.present?
# this is a quick workaround for being unable to fetch images via Cloudinary for new twitter sign_ins due to Twitter API policy changes.
# one problem with continuing to use this long term would be:
# - if a user changes their profile picture, the url saved on our model will become invalid
# we do have a fallback to default image in place, but it's not ideal
# - As an improvement, we can try to cache it (more like a permanent snapshot until their next login)
# - But a proper solution would be to fetch their current profile picture via a service or to periodically refresh it ourself
user.image
else
cloudinary_image_url(user.twitter_handle)
end
end

def cloudinary_image_url(twitter_handle)
"https://res.cloudinary.com/#{ENV['CLOUDINARY_HANDLE']}/image/twitter_name/#{twitter_handle}.jpg"
end
end
4 changes: 4 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def find_for_twitter_oauth(auth)
user = User.where(uid: auth.uid, provider: auth.provider).first

if user
profile_image_url = auth["info"]["image"]
user.update(image: profile_image_url) if profile_image_url.present?

# TODO: handle exceptions later. For now, continue to sign in the user, regardless of whether image url is saved
user
else
User.create(
Expand Down
2 changes: 1 addition & 1 deletion app/views/home/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
= time_ago_in_words letter.created_at
ago
.pull-right.thumbnail.imageWrapper{ style: 'max-height: 50px; max-width: 50px' }
= get_twitter_image(letter.user.twitter_handle)
= get_twitter_image(letter.user)

-# TODO refactor this
- unless letter.user_id == 43
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/application.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
%tr
%td
.thumbnail.pull-left{ style: 'max-height: 50px; max-width: 50px' }
= get_twitter_image(l.user.twitter_handle)
= get_twitter_image(l.user)
.info.pull-left
= truncate("#{l.user.name} (#{l.user.twitter_handle})", length: 27)
%br
Expand Down
2 changes: 1 addition & 1 deletion app/views/letters/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
= time_ago_in_words @letter.created_at
ago
.pull-right.thumbnail.imageWrapper{ style: 'max-height: 50px; max-width: 50px' }
= get_twitter_image(@letter.user.twitter_handle)
= get_twitter_image(@letter.user)
= markdown(@letter.description)
%br
%div
Expand Down
4 changes: 2 additions & 2 deletions config/initializers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET']
config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'],
{ secure_image_url: 'true', image_size: 'original' }


# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or
# change the failure app, you can configure them inside the config.warden block.
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
end
end

get 'profile_picture/twitter/:twitter_handle', to: 'profile_picture#twitter', as: :twitter_image

root 'home#index'

# The priority is based upon order of creation:
Expand Down
27 changes: 23 additions & 4 deletions spec/helpers/application_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,30 @@
# end
# end
RSpec.describe ApplicationHelper, type: :helper do
describe 'application heler' do
context 'get_twitter_image method' do
describe 'application helper' do
# actual context: We realized just in time before RubyConfIndia2023 that due to Twitter API changes
# we are unable to retrieve profile pictures for new twitter sign_ups through Cloudinary

context 'get_twitter_image for User who last signed in before RubyIndiaConf 2023' do
it 'should render image tag with the twitter handle' do
twitter_handle = 'foobar'
expect(helper.get_twitter_image(twitter_handle)).to match("#{twitter_handle}\.jpg")
user = User.new(twitter_handle: 'my_twitter_handle', updated_at: Date.parse('2022-12-31').end_of_day)
expect(helper.get_twitter_image(user)).to match("cloudinary.*my_twitter_handle\.jpg")
end
end
context 'get_twitter_image for User who last signed in after RubyIndiaConf 2023' do
it 'should render image tag with twitter handle (in the unlikely case, our User model does not contain the image url)' do
user = User.new(twitter_handle: 'my_twitter_handle', updated_at: Date.parse('2024-01-01').end_of_day)
expect(helper.get_twitter_image(user)).to match("cloudinary.*my_twitter_handle\.jpg")
end
it 'should render image tag using the URL saved on the User model' do
user = User.new(
twitter_handle: 'my_twitter_handle',
image: 'https://pbs.twimg.com/profile_images/123456789/my_selfie.jpg',
updated_at: Date.parse('2024-01-01').end_of_day
)
image_url = helper.get_twitter_image(user)
expect(image_url).to_not match("my_twitter_handle\.jpg")
expect(image_url).to match("my_selfie\.jpg")
end
end
end
Expand Down

0 comments on commit 8a34a2c

Please sign in to comment.