Mastodonを支えるgems

  • 50
    いいね
  • 1
    コメント

Mastodonのコードを読んでみることにしました。

知らないgemが一杯あったのでまずは調べてみることにしました。標準添付ライブラリ、Railsにデフォルトで含まれているものは除きます。また、group :developmentとか、group指定ありのは疲れたのでまた今度。

今回確認したGemfile

実際のコードに目を通しながら調べましたが、勘違いなどあればご指摘頂けるとうれしいです。

hamlit-rails

hamlit-rails provides generators for Rails 4.

Railsのジェネレータが生成するビューテンプレートをHaml化するhaml-railshamlit版のようです。Hamlという点では同じですがhaml gemへの依存をなくせますね。

pg

Pg is the Ruby interface to the PostgreSQL RDBMS.

RubyのPostgreSQLインタフェース。

pghero

A performance dashboard for Postgres

スロークエリのチェックやインデックスの状態などPostgreSQLの管理に役立つダッシュボードを提供するEngineのようです。
mastodonではDeviseのauthenticated routesを使ってマウントすることで管理者がアクセスできるようにしているようですね。
https://github.com/tootsuite/mastodon/blob/fe1ddc3b9614380367fa55f13df033e21c96747e/config/routes.rb#L11

authenticate :user, lambda { |u| u.admin? } do
  mount Sidekiq::Web, at: 'sidekiq', as: :sidekiq
  mount PgHero::Engine, at: 'pghero', as: :pghero
end

dotenv-rails

Autoload dotenv in Rails.

.env ファイルに環境変数を書いておくと自動的に環境変数ENV に読み込んでくれるようです。読み込みのタイミングはbefore_configurationなので、configで使いたいときはそれより前にDotenv::Railtie.load とする必要があるようです。
https://github.com/tootsuite/mastodon/blob/fe1ddc3b9614380367fa55f13df033e21c96747e/config/application.rb#L13

Dotenv::Railtie.load

font-awesome-rails

I like font-awesome. I like the asset pipeline. I like semantic versioning. If you do too, you're welcome.

font-awesomeとAsset Pipelineとセマンティック・バージョニングが好きな人に。

best_in_place

A RESTful unobtrusive jQuery Inplace-Editor and a helper as a Rails Gem

編集したいところをページ遷移なしにそのまま編集できる機能を簡単に実現できるようにするEngineのようです。mastodonでは管理画面のサイト設定で使っているようです・・・が、そのうち無くなる気がします。
https://github.com/tootsuite/mastodon/blob/d90d23699ca611f05d8def40109505251507fa46/app/views/admin/settings/index.html.haml#L15

%td= best_in_place @settings['site_contact_username'], :value, url: admin_setting_path(@settings['site_contact_username']), place_holder: t('admin.settings.contact_information.username')

paperclip

Easy upload management for ActiveRecord

RailsのActiveRecordでファイルアップロード機能を書くのによく使われるgem
。最近はshrineなど後発のものに押されてる感ありますがよく見ますね。
https://github.com/tootsuite/mastodon/blob/e09ab2c0bdc0822886fa98b0019d4a447a2ee0d6/app/models/account.rb#L15

# Avatar upload
has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' }

paperclip-av-transcoder

Audio/Video Transcoder for Paperclip using FFMPEG/Avconv

Paperclipでアップロードした動画をFFmpegやlibav(avconv)を使って変換するためのようです。
mastodonではContent-Typeをみて使うprocessorを切り換えるようにして使っていました。
https://github.com/tootsuite/mastodon/blob/bfbc2ca0d8dcef47f8581585b42f13b6b4c933d9/lib/paperclip/video_transcoder.rb
https://github.com/tootsuite/mastodon/blob/bfbc2ca0d8dcef47f8581585b42f13b6b4c933d9/app/models/media_attachment.rb#L88

def file_processors(f)
  if f.file_content_type == 'image/gif'
    [:gif_transcoder]
  elsif VIDEO_MIME_TYPES.include? f.file_content_type
    [:video_transcoder]
  else
    [:thumbnail]
  end
end

aws-sdk

The official AWS SDK for Ruby. Provides both resource oriented interfaces and API clients for AWS services.

公式のRuby AWS SDKですね。
mastodonではアップロードファイルの保管先としてS3を使うときぐらいでしょうか。
https://github.com/tootsuite/mastodon/blob/6c83fec9715340bd178de0a8ba595bb4ad10eb1a/config/initializers/paperclip.rb#L10

addressable

Addressable is a replacement for the URI implementation that is part of Ruby's standard library.

標準ライブラリのURIのようにパースしたり、名前解決を行ってくれたり、正規化したりしてくれるようです。
mastodonではURLのバリデーションに使っているようです。
https://github.com/tootsuite/mastodon/blob/b330d1f000ef354a856c43aeaa27e079c89fc822/app/validators/url_validator.rb#L11

def compliant?(url)
  parsed_url = Addressable::URI.parse(url)
  !parsed_url.nil? && %w(http https).include?(parsed_url.scheme) && parsed_url.host
end

devise

Flexible authentication solution for Rails with Warden

認証機能の手抜きによく使われる(僕もよく使ってしまう)そしてブラックボックスが嫌われがちなgemです。手早く一般的な機能を実装するのには便利だと思います。

devise-two-factor

Barebones two-factor authentication with Devise

Deviseで二段階認証(二要素認証)に対応する最小限の実装とのことです。Google Authenticatorなどに簡単に対応できるそうです。
https://github.com/tootsuite/mastodon/blob/93c13fe691750e8c7f0c90091bca2564b97ccba7/app/models/user.rb#L8

doorkeeper

Doorkeeper is an OAuth 2 provider for Rails and Grape.

OAuth2プロバイダの実装のようで、このあたりの記事が参考になりそうです。
mastodonのAPI認可に利用しているようです。
Search: doorkeeper

fast_blank

Provides a C-optimized method for determining if a string is blank

Cで書かれた高速なString#blank? で置き換えるようです。

goldfinger

A Webfinger utility for Ruby

WebFingerクライアントのRuby実装のようです。
mastodonでは別のサーバー(mastodonインスタンス)のアカウントのフォローに利用しているようです。
https://github.com/tootsuite/mastodon/blob/0687ab8ae3c2573ba2aa1d37f62e3583d0c7ab01/app/controllers/remote_follow_controller.rb#L18

if @remote_follow.valid?
  resource          = Goldfinger.finger("acct:#{@remote_follow.acct}")
  redirect_url_link = resource&.link('http://ostatus.org/schema/1.0/subscribe')

hiredis

Ruby wrapper for hiredis (protocol serialization/deserialization and blocking I/O)

RedisのCクライアントhiredisのRubyラッパーライブラリのようで、これ単体でも利用できるようですが、redis-rbとあわせて使うことでredis-rbの高速化が望めるようです。

htmlentities

A module for encoding and decoding (X)HTML entities.

文字実体参照や数値文字参照のエンコード・デコードができます。

http_accept_language

Find out which locale the user preferes by reading the languages they specified in their browser

ブラウザが送出したAccept-Languageヘッダーの扱いを簡単にします。リストアップした中から互換性のある言語を取り出したりできます。
mastodonではI18n.available_locales の中から使えそうなlocaleを選ぶのに使っています。
https://github.com/tootsuite/mastodon/blob/f5cd1383231af6922dbab4f54b7d29eacfec9d9e/app/controllers/concerns/localized.rb#L35

def user_supplied_locale
  http_accept_language.language_region_compatible_from(I18n.available_locales)
end

httplog

Log outgoing HTTP requests made from your application.

アプリケーションからの外部HTTP通信のログを記録してくれるので、たとえばAPI呼び出しの追跡などに役立つようです。

kaminari

Kaminari is a Scope & Engine based, clean, powerful, agnostic, customizable and sophisticated paginator for Rails 4+

ページネーションを実装する時にはまず使う、そんなgemです。
ActiveRecordだけでなく、Arrayなども同じようにページングできるのもよいです。

link_header

Converts conforming link headers to and from text, LinkHeader objects and corresponding (JSON-friendly) Array representations, also HTML link elements.

HTTPのLinkヘッダのパースや生成を簡単にするgemのようです。
mastodonではAPIでページネーションを実装するにあたり、前後のパスをクライアントに伝える際などに使っているようです。
https://github.com/tootsuite/mastodon/blob/e2a1b574ab4ec5dd07dbc5c317bcc3718f13c19b/app/controllers/api_controller.rb#L63

def set_pagination_headers(next_path = nil, prev_path = nil)
  links = []
  links << [next_path, [%w(rel next)]] if next_path
  links << [prev_path, [%w(rel prev)]] if prev_path
  response.headers['Link'] = LinkHeader.new(links)
end

nokogiri

Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser.

XMLビルダー、パーサーを提供します。
mastodonではどちらの用途としても使っているようです。
https://github.com/tootsuite/mastodon/blob/137100dcf38c0da0fe7044a4c92aa06eae02c420/app/views/well_known/webfinger/show.xml.ruby#L1

Nokogiri::XML::Builder.new do |xml|
  xml.XRD(xmlns: 'http://docs.oasis-open.org/ns/xri/xrd-1.0') do
    xml.Subject @canonical_account_uri
    xml.Alias TagManager.instance.url_for(@account)
    xml.Link(rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: TagManager.instance.url_for(@account))
    xml.Link(rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom'))
    xml.Link(rel: 'salmon', href: api_salmon_url(@account.id))
    xml.Link(rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}")
    xml.Link(rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}")
  end
end.to_xml

https://github.com/tootsuite/mastodon/blob/08faeedff7838e339488cfcddf02d95241557ffb/app/services/fetch_remote_resource_service.rb

xml = Nokogiri::XML(body)
xml.encoding = 'utf-8'

if xml.root.name == 'feed'

oj

The fastest JSON parser and object serializer.

高速なJSONライブラリ。

ostatus2

Toolset for interacting with the OStatus2 suite of protocols

PubSubHubbubを使ってフィードの更新通知したり、Salmon(サーモン)Protocolでフィードにコメントを付けたりするのに使えるようです。
コメント分散問題は“サーモン・プロトコル”で解決!? - @IT
Mastodon OStatus API の叩き方
mastodonではgoldfingerとあわせて別のサーバー(mastodonインスタンス)のユーザーのfollow/unfollow/like/unlikeなどの実装に使っているようです。
https://github.com/tootsuite/mastodon/blob/6d6a429af8fe4bd92ed497f401676353fdc603e0/app/services/favourite_service.rb#L16
https://github.com/tootsuite/mastodon/blob/f722bd2387df9163760014e9555928ec487ae95f/app/workers/notification_worker.rb#L9
https://github.com/tootsuite/mastodon/blob/50660d54e8cabd08fee649a6abc26f35a8d7a82c/app/services/send_interaction_service.rb

# Send an Atom representation of an interaction to a remote Salmon endpoint
# @param [String] Entry XML
# @param [Account] source_account
# @param [Account] target_account
def call(xml, source_account, target_account)
  envelope = salmon.pack(xml, source_account.keypair)
  salmon.post(target_account.salmon_url, envelope)
end

ox

A fast XML parser and object serializer that uses only standard C lib.

Cだけで書かれたlibxmlなどに依存しない、高速なXMLパーサ&オブジェクトシリアライザのようです。
XMLパーサとしてNokogiriより2倍以上高速で、&オブジェクトシリアライザとしてMarshal.dumpより最大6倍高速で、SAXではNokogiriよりも40倍、LibXMLよりも13倍高速という謳い文句です。
mastodonではAtomの生成に利用しているようです。
https://github.com/tootsuite/mastodon/blob/15ec4ae07b17821625bd2ca1088a7573a7ed128c/app/lib/atom_serializer.rb#L8

document = Ox::Document.new(version: '1.0')
document << element
('<?xml version="1.0"?>' + Ox.dump(element, effort: :tolerant)).force_encoding('UTF-8')

rabl

General ruby templating with json, bson, xml and msgpack support

API応答をDSLで柔軟に書けるというテンプレートシステムのようです。JSONだけでなくXML、MessagePackなど複数のフォーマットに対応しています。
mastodonでもAPI応答など利用されています。
Search: extension:rabl

rack-attack

A rack middleware for throttling and blocking abusive requests

ミドルウェアレベルでセーフリスト、ブラックリスト、スロットリングなど不正なリクエストからの防御を実装できるようです。
mastodonではAPIや、ログイン、ユーザー登録などのレート制限の実装に利用しているようです。
https://github.com/tootsuite/mastodon/blob/ff5baa5349ca7a5391cfa9e283d2f5e653f876ee/config/initializers/rack_attack.rb

# Rate limits for the API
throttle('api', limit: 300, period: 5.minutes) do |req|
  req.ip if req.path =~ /\A\/api\/v/
end

# Rate limit logins
throttle('login', limit: 5, period: 5.minutes) do |req|
  req.ip if req.path == '/auth/sign_in' && req.post?
end

https://github.com/tootsuite/mastodon/blob/e2a1b574ab4ec5dd07dbc5c317bcc3718f13c19b/app/controllers/api_controller.rb#L52

now        = Time.now.utc
match_data = request.env['rack.attack.throttle_data']['api']

response.headers['X-RateLimit-Limit']     = match_data[:limit].to_s
response.headers['X-RateLimit-Remaining'] = (match_data[:limit] - match_data[:count]).to_s
response.headers['X-RateLimit-Reset']     = (now + (match_data[:period] - now.to_i % match_data[:period])).iso8601(6)

rack-cors

Middleware that will make Rack-based apps CORS compatible.

ミドルウェアレベルでHTTPアクセス制御(CORS: Cross-Origin Resource Sharing)を実装できるようです。
mastodonではAPIのクロスオリジンアクセスの許可や、ヘッダのホワイトリストの指定などに利用しているようです。
https://github.com/tootsuite/mastodon/blob/0a1b0246003e19e80241d8711276db790a88235d/config/application.rb#L58

config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins  '*'

    resource '/api/*',       headers: :any, methods: [:post, :put, :delete, :get, :options], credentials: false, expose: ['Link', 'X-RateLimit-Reset', 'X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-Request-Id']
    resource '/oauth/token', headers: :any, methods: [:post], credentials: false
  end
end

rack-timeout

Rack middleware which aborts requests that have been running for longer than a specified timeout.

ミドルウェアレベルでリクエストを受け取ってから結果を返すまでの待機時間や、POSTデータを受け取る際の受信待ち時間などを設定できるようです。
mastodonではproductionでのみサービスタイムアウトを設定しているようで、これにより長時間応答が返せない場合に処理を中断することができます。
https://github.com/tootsuite/mastodon/blob/5b12624847f6a599e1bbb3b24fc87c3b222e6716/config/initializers/timeout.rb#L5

Rack::Timeout::Logger.disable
Rack::Timeout.service_timeout = false

if Rails.env.production?
  Rack::Timeout.service_timeout = 90
end

rails-i18n

A set of common locale data and translations to internationalize and/or localize your Rails applications.

Railsのデフォルト文字列を翻訳した辞書一式のようです。使いたい言語だけを選ぶこともできます。

rails-settings-cached

This is improved from rails-settings, added caching.

アプリケーション設定をドットファイルなどではなくデータベースに記録し、変更できるようにしたいとき簡単に実装できるgemです。
mastodonでは「サイト名」や「自由にユーザー登録できるようにするか」などの設定に利用しているようです。
https://github.com/tootsuite/mastodon/blob/d87ee1167e0f11d94a20e70e9228a3398e202bc8/app/controllers/auth/registrations_controller.rb#L32

redis

A Ruby client library for Redis

Key-Value StoreのひとつRedisのRubyクライアントライブラリで、Redis APIと1対1で対応するようです。hiredisと組み合わせて使うことで高速化するようです。
mastodonではsidekiqのバックエンドとして非同期処理の他、ActionCable(これは設定だけかも)、Node.jsによるStreaming APIなどに利用しているようです。
https://github.com/tootsuite/mastodon/blob/323671a653e22704f0d50be13d67bf6fe6ee3a2a/app/services/fan_out_on_write_service.rb#L61

def deliver_to_hashtags(status)
  Rails.logger.debug "Delivering status #{status.id} to hashtags"

  status.tags.pluck(:name).each do |hashtag|
    Redis.current.publish("timeline:hashtag:#{hashtag}", @payload)
    Redis.current.publish("timeline:hashtag:#{hashtag}:local", @payload) if status.local?
  end
end

rqrcode

rQRCode is a library for encoding QR Codes.

QRコード生成のライブラリのようです。
mastodonでは二段階認証(二要素認証)の際にスマートフォンに読み取らせるQRコードを生成するのに利用しているようです。
https://github.com/tootsuite/mastodon/blob/a8e1afc30a1f843943bb29e7385b8611ea3c29f4/app/controllers/settings/two_factor_auths_controller.rb#L50

ruby-oembed

oEmbed for Ruby

URLから埋め込み用コードを取得できるoEmbedという仕様のRuby実装のようです。oEmbedクライアントとしては、任意のoEmbedプロバイダのURLを指定するだけで、サムネイルや埋め込み用HTMLなどを取得できるようです。また、独自のoEmbedプロバイダを作るのにも使えるようです。
mastodonでは現在のところGemfileにはあるものの使われていなさそうでした。
個別のトゥートページのLinkタグで示されるapplication/json+oembed はありますが、
https://github.com/tootsuite/mastodon/blob/389f8f824909d60b7560248465416bd4bed92b6b/app/views/stream_entries/show.html.haml#L3

- content_for :header_tags do
  %link{ rel: 'alternate', type: 'application/atom+xml', href: account_stream_entry_url(@account, @stream_entry, format: 'atom') }/
  %link{ rel: 'alternate', type: 'application/json+oembed', href: api_oembed_url(url: account_stream_entry_url(@account, @stream_entry), format: 'json') }/

その実装は、rablで書かれていました。
https://github.com/tootsuite/mastodon/blob/389f8f824909d60b7560248465416bd4bed92b6b/app/views/api/oembed/show.json.rabl

# frozen_string_literal: true
object @stream_entry

node(:type) { 'rich' }
node(:version) { '1.0' }
node(:title, &:title)
node(:author_name) { |entry| entry.account.display_name.blank? ? entry.account.username : entry.account.display_name }
node(:author_url) { |entry| account_url(entry.account) }
node(:provider_name) { site_hostname }
node(:provider_url) { root_url }
node(:cache_age) { 86_400 }
node(:html) { |entry| "<iframe src=\"#{embed_account_stream_entry_url(entry.account, entry)}\" style=\"width: 100%; overflow: hidden\" frameborder=\"0\" width=\"#{@width}\" height=\"#{@height}\" scrolling=\"no\"></iframe>" }
node(:width) { @width }
node(:height) { @height }

これによりoEmbedに対応したサービスでmastodonのトゥートのURLを貼り付けると、特別な設定をせずとも埋め込み表示されます。
たとえばはてなブログなどは対応しています。

sidekiq

Simple, efficient background processing for Ruby.

非同期処理を実現するgemです。
Rails 4.2以上ではActive Jobというフレームワークが導入され、Sidekiqもそのバックエンドとして選択できるという扱いになりましたが、mastodonの場合はSidekiqをそのまま利用しているようです。
https://github.com/tootsuite/mastodon/blob/389f8f824909d60b7560248465416bd4bed92b6b/app/workers/after_remote_follow_request_worker.rb#L4

class AfterRemoteFollowRequestWorker
  include Sidekiq::Worker

  sidekiq_options queue: 'pull', retry: 5

  def perform(follow_request_id)
    follow_request  = FollowRequest.find(follow_request_id)
    updated_account = FetchRemoteAccountService.new.call(follow_request.target_account.remote_url)

https://github.com/tootsuite/mastodon/blob/6d6a429af8fe4bd92ed497f401676353fdc603e0/app/services/follow_service.rb#L31

if target_account.local?
  NotifyService.new.call(target_account, follow_request)
else
  NotificationWorker.perform_async(build_follow_request_xml(follow_request), source_account.id, target_account.id)
  AfterRemoteFollowRequestWorker.perform_async(follow_request.id)
end

sidekiq-unique-jobs

Handles various types of unique jobs for Sidekiq

Sidekiqで同じジョブが同時に複数実行されないようにできるようです。
mastdonの場合は、2週間ぶりにログインしたユーザーのメンションをDBから探すという重めの処理について1回だけ実行したい、ということで利用しているようです。
https://github.com/tootsuite/mastodon/blob/5d710b1139b34f2ed6bd556f448fa7248354e758/app/controllers/application_controller.rb#L44

# If the sign in is after a two week break, we need to regenerate their feed
RegenerationWorker.perform_async(current_user.account_id) if current_user.last_sign_in_at < 14.days.ago

https://github.com/tootsuite/mastodon/blob/82aaedec467815c2947a11651d5216bb88ce4038/app/workers/regeneration_worker.rb#L6

class RegenerationWorker
  include Sidekiq::Worker

  sidekiq_options queue: 'pull', backtrace: true, unique: :until_executed

simple-navigation

A ruby gem for creating navigations (with multiple levels) for your Rails, Sinatra or Padrino applications. Render your navigation as html list, link list or breadcrumbs.

ナビゲーションやパンくずリストを簡単に作れるgemのようです。
mastodonでは管理画面のナビゲーションに利用しているようです。
https://github.com/tootsuite/mastodon/blob/55e150352204bc790345cf81ef02bfcb1d7e0594/config/navigation.rb
https://github.com/tootsuite/mastodon/blob/0d83569899155e5d5c17fff0c69e533df2f34d42/app/views/layouts/admin.html.haml#L11

simple_form

Forms made easy!

Railsのフォームをスッキリ書けるDSLを提供するgemのようです。
mastodonではログインページ等各種フォームで利用しているようです。
https://github.com/tootsuite/mastodon/blob/23b997ae55655ccae6a9a9e424a3596c9165a481/app/views/auth/sessions/new.html.haml#L4

= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
  = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password') }

  .actions
    = f.button :button, t('auth.login'), type: :submit

statsd-instrument

A StatsD client for Ruby apps.

StatsDののRubyクライアントで、アプリケーションのメトリクスの取得と計測を行えるようです。
mastodonではActiveSupport::Notificationsを使ってActionControllerの処理を時間を計測しているようです。
https://github.com/tootsuite/mastodon/blob/f6a5977f0b2986b15ca8254123053e1a59647cd1/config/initializers/statsd.rb

    ActiveSupport::Notifications.subscribe(/performance/) do |name, _start, _finish, _id, payload|
      action      = payload[:action] || :increment
      measurement = payload[:measurement]
      value       = payload[:value]
      key_name    = clean_name("#{name}.#{measurement}")

      StatsD.send(action.to_s, key_name, (value || 1))
    end

https://github.com/tootsuite/mastodon/blob/d567f21d4f4c3feb09a08443cf75eb583904093b/config/initializers/instrumentation.rb#L14

ActiveSupport::Notifications.subscribe(/process_action.action_controller/) do |*args|
  event      = ActiveSupport::Notifications::Event.new(*args)
  # (snip)

  ActiveSupport::Notifications.instrument :performance, action: :measure, measurement: "#{key}.total_duration", value: event.duration
  ActiveSupport::Notifications.instrument :performance, action: :measure, measurement: "#{key}.db_time", value: event.payload[:db_runtime]
  ActiveSupport::Notifications.instrument :performance, action: :measure, measurement: "#{key}.view_time", value: event.payload[:view_runtime]
  ActiveSupport::Notifications.instrument :performance, measurement: "#{key}.status.#{status}"
end

twitter-text

A gem that provides text handling for Twitter

TwitterにツイートするテキストのURL自動リンク、文字数の正確なカウントなどの面倒をみてくれるようです。
mastodonではトゥートの自動リンクに利用しているようです。
https://github.com/tootsuite/mastodon/blob/70891a99a97bc1ca14a8ded13a5cd45b648b92b3/app/lib/formatter.rb
https://github.com/tootsuite/mastodon/blob/70891a99a97bc1ca14a8ded13a5cd45b648b92b3/spec/lib/formatter_spec.rb

whatlanguage

WhatLanguage rapidly detects the language of a sample of text

文字列からどの言語で書かれているか検出できるそうです。
mastodonではトゥートの内容から言語を検出するのに利用しているようです。
https://github.com/tootsuite/mastodon/blob/297c11dba2864b20992cd3f98282f5ce35d5d144/app/lib/language_detector.rb#L12

def to_iso_s
  WhatLanguage.new(:all).language_iso(text) || default_locale.to_sym
end

https://github.com/tootsuite/mastodon/blob/297c11dba2864b20992cd3f98282f5ce35d5d144/app/services/post_status_service.rb#L22
https://github.com/tootsuite/mastodon/blob/297c11dba2864b20992cd3f98282f5ce35d5d144/app/services/post_status_service.rb#L56

def call(account, text, in_reply_to = nil, options = {})
  media  = validate_media!(options[:media_ids])
  status = account.statuses.create!(text: text,
                                    thread: in_reply_to,
                                    sensitive: options[:sensitive],
                                    spoiler_text: options[:spoiler_text] || '',
                                    visibility: options[:visibility],
                                    language: detect_language_for(text, account),
                                    application: options[:application])
  # (snip)
end


def detect_language_for(text, account)
  LanguageDetector.new(text, account).to_iso_s
end

react-rails

Render components in views or controller actions.

RailsのViewとReact Componentの橋渡しをしてくれます。
mastodonでは、app/assets/javascripts/components/containers/mastodon.jsxをホームのViewに置くことでRails View内にTweetDeckっぽいSPAを置いています。react-rails単体でもJSXのプリコンパイルも対応しているはずですが、それについてはbrowserify-railsで行っているようです。
https://github.com/tootsuite/mastodon/blob/0d83569899155e5d5c17fff0c69e533df2f34d42/app/views/home/index.html.haml#L6

- content_for :header_tags do
  %script#initial-state{:type => 'application/json'}!= json_escape(render(file: 'home/initial_state', formats: :json))

  = javascript_include_tag 'application', integrity: true, crossorigin: 'anonymous'

= react_component 'Mastodon', default_props, class: 'app-holder', prerender: false

browserify-rails

Browserify + Rails = CommonJS Heaven

SprocketsでCommonJSを使えるようにする方法の1つです。
mastodonではBabelifyと組み合わせてBabelのes2015とreactのプリセットを利用しているようです。
https://github.com/tootsuite/mastodon/blob/0a1b0246003e19e80241d8711276db790a88235d/config/application.rb#L71

config.browserify_rails.source_map_environments << 'development'
config.browserify_rails.commandline_options   = '--transform [ babelify --presets [ es2015 react ] ] --extension=".jsx"'
config.browserify_rails.evaluate_node_modules = true

https://github.com/tootsuite/mastodon/blob/a3486e0543f76581441380fdf2975d596a6be1c6/app/assets/javascripts/components/containers/mastodon.jsx

const Mastodon = React.createClass({
  # (snip)
});

export default Mastodon;

https://github.com/tootsuite/mastodon/blob/0a1b0246003e19e80241d8711276db790a88235d/app/assets/javascripts/components.js#L15

//= require_tree ./components

window.Mastodon = require('./components/containers/mastodon');

autoprefixer-rails

Parse CSS and add vendor prefixes to CSS rules using values from the Can I Use website.

CSSベンダープレフィックスを付与してくれるAutoprefixerを、Sprocketsで使ってくれるようになるようです。