Social Cards Part 2 (#2188)
* Social Cards Part 2 This is a follow up to part 1: https://github.com/thepracticaldev/dev.to/pull/2090. This PR updates the og:image URLs to use the new social_preview.png urls added in Part 1. So that the already generated/cached images do not need to be recreated, this sets a MIGRATION_DATETIME. Any object that has been updated after that date will generate a new image Objects from before that date will not. They will use the new url. * Fix weird change made by rubocop autocorrect * Handle organizations + users * Run CI * Use time with zone to be explicit about timezone * Simplify branching in user_social_image_url method * Fix param alignment + bump migration date
This commit is contained in:
parent
44b06ea442
commit
4c9959f0ff
10 changed files with 124 additions and 34 deletions
|
|
@ -120,25 +120,6 @@ module ApplicationHelper
|
|||
sign_url: true)
|
||||
end
|
||||
|
||||
def cloud_social_image(article)
|
||||
cache_key = "article-social-img-#{article}-#{article.updated_at}-#{article.comments_count}"
|
||||
|
||||
Rails.cache.fetch(cache_key, expires_in: 1.hour) do
|
||||
src = GeneratedImage.new(article).social_image
|
||||
return src if src.start_with? "https://res.cloudinary.com/"
|
||||
|
||||
cl_image_path(src,
|
||||
type: "fetch",
|
||||
width: "1000",
|
||||
height: "500",
|
||||
crop: "imagga_scale",
|
||||
quality: "auto",
|
||||
flags: "progressive",
|
||||
fetch_format: "auto",
|
||||
sign_url: true)
|
||||
end
|
||||
end
|
||||
|
||||
def tag_colors(tag)
|
||||
Rails.cache.fetch("view-helper-#{tag}/tag_colors", expires_in: 5.hours) do
|
||||
if (found_tag = Tag.select(%i[bg_color_hex text_color_hex]).find_by(name: tag))
|
||||
|
|
|
|||
56
app/helpers/social_image_helper.rb
Normal file
56
app/helpers/social_image_helper.rb
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
module SocialImageHelper
|
||||
# After this date we use SocialPreview controller directly rather than passing to URL2PNG.
|
||||
# Keeping old URLs around since they are already generated.
|
||||
SOCIAL_PREVIEW_MIGRATION_DATETIME = Time.zone.parse("2019-04-22T00:00:00Z")
|
||||
|
||||
def user_social_image_url(user)
|
||||
return GeneratedImage.new(user).social_image unless use_new_social_url?(user)
|
||||
|
||||
if user.is_a?(Organization)
|
||||
organization_social_preview_url(user, format: :png)
|
||||
else
|
||||
user_social_preview_url(user, format: :png)
|
||||
end
|
||||
end
|
||||
|
||||
def article_social_image_url(article)
|
||||
return legacy_article_social_image(article) unless use_new_social_url?(article)
|
||||
|
||||
if (image = article.social_image || article.main_image || article.video_thumbnail_url)
|
||||
return cl_image_path(image,
|
||||
type: "fetch",
|
||||
width: "1000",
|
||||
height: "500",
|
||||
crop: "imagga_scale",
|
||||
quality: "auto",
|
||||
flags: "progressive",
|
||||
fetch_format: "auto",
|
||||
sign_url: true)
|
||||
end
|
||||
|
||||
article_social_preview_url(article, format: :png)
|
||||
end
|
||||
|
||||
def legacy_article_social_image(article)
|
||||
cache_key = "article-social-img-#{article}-#{article.updated_at}-#{article.comments_count}"
|
||||
|
||||
Rails.cache.fetch(cache_key, expires_in: 1.hour) do
|
||||
src = GeneratedImage.new(article).social_image
|
||||
return src if src.start_with? "https://res.cloudinary.com/"
|
||||
|
||||
cl_image_path(src,
|
||||
type: "fetch",
|
||||
width: "1000",
|
||||
height: "500",
|
||||
crop: "imagga_scale",
|
||||
quality: "auto",
|
||||
flags: "progressive",
|
||||
fetch_format: "auto",
|
||||
sign_url: true)
|
||||
end
|
||||
end
|
||||
|
||||
def use_new_social_url?(resource)
|
||||
resource.updated_at > SOCIAL_PREVIEW_MIGRATION_DATETIME
|
||||
end
|
||||
end
|
||||
|
|
@ -583,7 +583,6 @@ class Article < ApplicationRecord
|
|||
|
||||
def async_bust
|
||||
CacheBuster.new.bust_article(self)
|
||||
HTTParty.get GeneratedImage.new(self).social_image if published
|
||||
end
|
||||
handle_asynchronously :async_bust
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ json.description @article.description
|
|||
json.cover_image cloud_cover_url @article.main_image
|
||||
json.published_at @article.published_at
|
||||
json.readable_publish_date @article.readable_publish_date
|
||||
json.social_image cloud_social_image(@article)
|
||||
json.social_image article_social_image_url(@article)
|
||||
json.tag_list @article.cached_tag_list
|
||||
json.slug @article.slug
|
||||
json.path @article.path
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@
|
|||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:widgets:new-embed-design" content="on">
|
||||
<% if @article.published %>
|
||||
<meta property="og:image" content="<%= cloud_social_image(@article) %>" />
|
||||
<meta name="twitter:image:src" content="<%= cloud_social_image(@article) %>">
|
||||
<meta property="og:image" content="<%= article_social_image_url(@article) %>" />
|
||||
<meta name="twitter:image:src" content="<%= article_social_image_url(@article) %>">
|
||||
<% end %>
|
||||
<% if !@article.published || (@article.positive_reactions_count < 7 && @article.user.comments_count < 1 && !@article.featured) ||
|
||||
@article.featured_number.to_i < 1500000000 || @article.score < -10 %>
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
<% end %>
|
||||
<article itemscope itemtype="http://schema.org/Article" itemprop="mainEntityOfPage">
|
||||
<meta itemprop="url" content="https://dev.to<%= @article.path %>">
|
||||
<meta itemprop="image" content="<%= cloud_social_image(@article) %>">
|
||||
<meta itemprop="image" content="<%= article_social_image_url(@article) %>">
|
||||
<div itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
|
||||
<div itemprop="logo" itemscope itemtype="https://schema.org/ImageObject">
|
||||
<meta itemprop="url" content="<%= asset_path "android-icon-192x192.png" %>">
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
<% if @tag_model %>
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="og:image" content="<%= GeneratedImage.new(@tag_model).social_image %>">
|
||||
<meta name="twitter:image:src" content="<%= GeneratedImage.new(@tag_model).social_image %>">
|
||||
<meta property="og:image" content="<%= tag_social_preview_url(@tag_model, format: :png) %>">
|
||||
<meta name="twitter:image:src" content="<%= tag_social_preview_url(@tag_model, format: :png) %>">
|
||||
<% else %>
|
||||
<meta property="og:image" content="https://thepracticaldev.s3.amazonaws.com/i/g355ol6qsrg0j2mhngz9.png">
|
||||
<meta name="twitter:image:src" content="https://thepracticaldev.s3.amazonaws.com/i/g355ol6qsrg0j2mhngz9.png">
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
<meta name="twitter:title" content="[Discussion] <%= @commentable.title %> — DEV">
|
||||
<% end %>
|
||||
<% if @commentable.class.name == "Article" %>
|
||||
<meta property="og:image" content="<%= cloud_social_image(@commentable) %>" />
|
||||
<meta name="twitter:image:src" content="<%= cloud_social_image(@commentable) %>">
|
||||
<meta property="og:image" content="<%= article_social_image_url(@commentable) %>" />
|
||||
<meta name="twitter:image:src" content="<%= article_social_image_url(@commentable) %>">
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://dev.to/<%= @user.username %>" />
|
||||
<meta property="og:title" content="<%= @user.name %> — DEV Profile" />
|
||||
<meta property="og:image" content="<%= GeneratedImage.new(@user).social_image %>">
|
||||
<meta property="og:image" content="<%= user_social_image_url(@user) %>">
|
||||
<meta property="og:description" content="<%= @user.summary %>" />
|
||||
<meta property="og:site_name" content="The DEV Community" />
|
||||
|
||||
|
|
@ -14,5 +14,5 @@
|
|||
<meta name="twitter:creator" content="@<%= @user.twitter_username %>">
|
||||
<meta name="twitter:title" content="<%= @user.name %> — DEV Profile">
|
||||
<meta name="twitter:description" content="<%= @user.summary %>">
|
||||
<meta name="twitter:image:src" content="<%= GeneratedImage.new(@user).social_image %>">
|
||||
<meta name="twitter:image:src" content="<%= user_social_image_url(@user) %>">
|
||||
<%= auto_discovery_link_tag(:rss, "https://dev.to/feed/#{@user.username}", title: "The Practical Dev RSS Feed") %>
|
||||
|
|
|
|||
|
|
@ -160,10 +160,10 @@ Rails.application.routes.draw do
|
|||
|
||||
post "/pusher/auth" => "pusher#auth"
|
||||
|
||||
get "/social_previews/article/:id" => "social_previews#article"
|
||||
get "/social_previews/user/:id" => "social_previews#user"
|
||||
get "/social_previews/organization/:id" => "social_previews#organization"
|
||||
get "/social_previews/tag/:id" => "social_previews#tag"
|
||||
get "/social_previews/article/:id" => "social_previews#article", as: :article_social_preview
|
||||
get "/social_previews/user/:id" => "social_previews#user", as: :user_social_preview
|
||||
get "/social_previews/organization/:id" => "social_previews#organization", as: :organization_social_preview
|
||||
get "/social_previews/tag/:id" => "social_previews#tag", as: :tag_social_preview
|
||||
|
||||
### Subscription vanity url
|
||||
post "membership-action" => "stripe_subscriptions#create"
|
||||
|
|
|
|||
54
spec/helpers/social_image_helper_spec.rb
Normal file
54
spec/helpers/social_image_helper_spec.rb
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
require "rails_helper"
|
||||
|
||||
describe SocialImageHelper do
|
||||
let(:user) { create(:user) }
|
||||
let(:article) { create(:article, main_image: nil) }
|
||||
|
||||
describe ".user_social_image_url" do
|
||||
it "returns social preview path for newer users" do
|
||||
url = helper.user_social_image_url(user)
|
||||
|
||||
expect(url).to eq user_social_preview_url(user, format: :png)
|
||||
end
|
||||
|
||||
it "returns Organization social preview path for Orgs" do
|
||||
organization = create(:organization)
|
||||
|
||||
url = helper.user_social_image_url(organization)
|
||||
|
||||
expect(url).to eq organization_social_preview_url(organization, format: :png)
|
||||
end
|
||||
|
||||
it "returns older url2png image if already generated" do
|
||||
user.updated_at = SocialImageHelper::SOCIAL_PREVIEW_MIGRATION_DATETIME - 1.week
|
||||
|
||||
url = helper.user_social_image_url(user)
|
||||
|
||||
expect(url).to eq GeneratedImage.new(user).social_image
|
||||
end
|
||||
end
|
||||
|
||||
describe ".article_social_image_url" do
|
||||
it "returns social preview path for newer articles" do
|
||||
url = helper.article_social_image_url(article)
|
||||
|
||||
expect(url).to eq article_social_preview_url(article, format: :png)
|
||||
end
|
||||
|
||||
it "returns the main image if set" do
|
||||
article.main_image = Faker::CryptoCoin.url_logo
|
||||
|
||||
url = helper.article_social_image_url(article)
|
||||
|
||||
expect(url).to match(/#{article.main_image}/)
|
||||
end
|
||||
|
||||
it "returns older url2png image if already generated" do
|
||||
article.updated_at = SocialImageHelper::SOCIAL_PREVIEW_MIGRATION_DATETIME - 1.week
|
||||
|
||||
url = helper.article_social_image_url(article)
|
||||
|
||||
expect(url).to eq GeneratedImage.new(article).social_image
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue