SocialBot full gist
!!!
%html(prefix="og: http://ogp.me/ns#")
%head
%meta(http-equiv='Content-Type' content='text/html')
%meta(charset='utf-8')
- if ENV['analytics_yandex_verification']
%meta(name="yandex-verification" content="#{ENV['analytics_yandex_verification']}")
%title= @meta['title']+@meta['title_sufix']
%meta(name='description' content="#{@meta['description']}")
%meta(name="author" content="#{@meta['author']}")
%meta(property="og:title" content="#{@meta['og:title']}")
%meta(property="og:description" content="#{@meta['og:description']}")
%meta(property="og:image" content="#{@meta['og:image']}")
%meta(property="og:url" content="#{@meta['og:url']}")
%meta(property='og:locale:locale' content='ru_ru')
%meta(name='twitter:card' content="#{@meta['twitter:card']}")
%meta(name='twitter:domain' content="#{ENV['root_domain']}")
%meta(name='twitter:site_name' content="#{@meta['og:title']}")
%meta(name='twitter:site' content="#{@meta['twitter:site']}")
%meta(name='twitter:creator' content="#{@meta['twitter:site']}")
%meta(name='twitter:description' content="#{@meta['twitter:creator']}")
%meta(name='twitter:image:src' content="#{@meta['og:image']}")
%meta(property='vk:description' content="#{@meta['og:description']}")
%meta(property='vk:title' content="#{@meta['og:title']}")
%link(rel='image_src' href="#{@meta['og:image']}")
%body
module BaseSiteTheme
module Rack
class SocialBot
require 'net/http'
require 'active_support'
require 'haml'
def initialize(app)
Rails.logger.debug 'Init SocialBot'
@crawler_user_agents = ['rambler', 'googlebot', 'aport', 'yahoo', 'msnbot', 'turtle', 'mail.ru', 'omsktele',
'yetibot', 'picsearch', 'sape.bot', 'sape_context', 'gigabot', 'snapbot', 'alexa.com',
'megadownload.net', 'askpeter.info', 'igde.ru', 'ask.com', 'qwartabot', 'yanga.co.uk',
'scoutjet', 'similarpages', 'oozbot', 'shrinktheweb.com', 'aboutusbot', 'followsite.com',
'dataparksearch', 'google-sitemaps', 'appEngine-google', 'feedfetcher-google',
'liveinternet.ru', 'xml-sitemaps.com', 'agama', 'metadatalabs.com', 'h1.hrn.ru',
'googlealert.com', 'seo-rus.com', 'yaDirectBot', 'yandeG', 'yandex', 'yandexSomething',
'Copyscape.com', 'AdsBot-Google', 'domaintools.com', 'Nigma.ru', 'bing.com', 'dotnetdotcom',
'baiduspider', 'facebookexternalhit', 'twitterbot', 'rogerbot', 'linkedinbot', 'embedly',
'bufferbot', 'quora link preview', 'showyoubot', 'outbrain', 'pinterest',
'developers.google.com/+/web/snippet', 'slackbot', 'vkShare', 'W3C_Validator', 'redditbot',
'Applebot', 'OdklBot', 'Bingbot', 'SkypeUriPreview']
@extensions_to_ignore = %w(.js .css .xml .less .png .jpg .jpeg .gif .pdf .doc .txt .ico .rss .zip .mp3 .rar .json
.exe .wmv .doc .avi .ppt .mpg .mpeg .tif .wav .mov .psd .ai .xls .mp4 .m4a .swf .dat .dmg .iso .flv .m4v .torrent /api/)
@app = app
end
def call(env)
if should_show_bot_page(env)
static_render(env)
else
@app.call(env)
end
end
def should_show_bot_page(env)
user_agent = env['HTTP_USER_AGENT']
buffer_agent = env['X-BUFFERBOT']
is_requesting_prerendered_page = false
return false unless user_agent
return false if env['REQUEST_METHOD'] != 'GET'
request = ::Rack::Request.new(env)
is_requesting_prerendered_page = true if ::Rack::Utils.parse_query(request.query_string).has_key?('_escaped_fragment_')
is_requesting_prerendered_page = true if @crawler_user_agents.any? { |crawler_user_agent| user_agent.downcase.include?(crawler_user_agent.downcase) }
is_requesting_prerendered_page = true if buffer_agent
return false if @extensions_to_ignore.any? { |extension| request.fullpath.include? extension }
return is_requesting_prerendered_page
end
def static_render(env)
@meta = default_meta(env).merge!(detected_meta(env))
template = File.read(File.join(File.dirname(__FILE__), '../../..', 'app', 'views', 'layouts', 'static.html.haml'))
haml_engine = Haml::Engine.new(template)
output = haml_engine.render(binding)
[200, {'Content-Type' => 'text/html'}, ["#{output}"]]
end
def default_meta(env)
{
'title_sufix' => " | #{I18n.t('site.title_suffix')}",
'title' => I18n.t('site.title'),
'description' => I18n.t('site.description'),
'author' => I18n.t('site.author'),
'og:title' => I18n.t('site.og_title'),
'og:description' => I18n.t('site.og_description'),
'og:image' => ActionController::Base.helpers.image_url(ENV['SEO_default_img']),
'og:url' => "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['REQUEST_PATH']}",
'twitter:card' => 'summary_large_image',
'twitter:site' => I18n.t('site.twitter_site'),
'twitter:creator' => I18n.t('site.twitter_creator')
}
end
def detected_meta(env)
path = env['REQUEST_PATH']
resource_klass, resource_id = case path
when /posts\/(.+)$/
[Blog::Post, $1]
when /mneniya\/(.+)$/
[Opinion::Post, $1]
when /smi-o-nas\/(.+)$/
[MassMedia::Post, $1]
when /page\/(.+)$/
[Site::Page, $1]
when /videos\/(.+)$/
[Video, $1]
else
[]
end
if resource_klass && (resource = resource_klass.find(resource_id).try(:decorate)).present?
resource.seo_meta
else
{}
end
end
end
end
end