Rails で Base64 エンコードされた文字を Carrierwave で保存する最も良い方法

File クラスを使うと、ストレージの読み書きが発生し、速度が落ちるため、メモリ上だけで処理を行う方針。
File クラスと同じ処理をするため、メソッドを定義する。

class StringFileIO < StringIO

  def self.create_from_canvas_base64 str
    return nil if str.nil?

    head, data = str.split ",", 2

    return nil if data.nil?

    _, mime_type = head.split /:|;/

    bin = Base64.decode64 data

    self.new bin, mime_type
  end

  def initialize blob, content_type
    super(blob)
    @content_type = content_type
    self
  end

  def original_filename
    "image"
  end

  def content_type
    @content_type
  end

end


あとは、代入するのみ

class User
  def image_str= str
    self.image = StringFileIO.create_from_canvas_base64(str)
  end
end

Wordpress で visual editor の タブが表示されないとき

  • 原因不明だが、'wp-includes/js/tinymce' フォルダを、再ダウンロードしたファイルで置き換える
  • User > Your Profile ページの Visual Editor にチェックが入っている
  • nginx などで、user agent に、empty の文字列を渡している

というのありえるようだ。

CloudFront 使用時、scheme を取得する

CloudFront を使用時、https での通信でも、nginx の $scheme に http が入ってしまっている。

CloudFront-Forwarded-Proto ヘッダーに、original の scheme が入っているので、それを利用する。

CloudFront

Whitelist Headers に、CloudFront-Forwarded-Proto を追加。ホワイトリストというよりも、ヘッダーの追加。

Nginx

http_cloudfront_forwarded_proto が https であれば、 scheme を上書きして、次に流す。

location / {

    set $proto $scheme;
    if ($http_cloudfront_forwarded_proto = "https")  { set $proto "https"; }

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $proto;
    proxy_set_header Host $http_host;
    proxy_pass http://app_sock;
}

ActiveAdmin で、belongs_to, accepts_nested_attributes_for を設定したmodelも同時に表示・編集する

ActiveAdmin で、belongs_to, accepts_nested_attributes_for を設定したmodelも同時に表示・編集する

ActiveAdmin.register UserLogin do

  # ... 

  form do |f|

    f.inputs nil, for: [:user, f.object.user || User.new] do |fc|
      fc.input :icon
      fc.input :full_name
      fc.input :is_deleted
    end

    f.inputs nil do
      f.input :email
      f.input :password
      f.input :password_confirmation
      f.input :is_deleted
    end

    f.actions
  end

  show do |f|

    panel I18n.t("active_admin.details", model: User.model_name.human) do
      attributes_table_for f.user do
        row :icon
        row :full_name
        row :is_deleted
        row :created_at
        row :updated_at
      end
    end

    attributes_table do
      row :id
      row :email
      row :is_deleted
      row :created_at
      row :updated_at
    end

    active_admin_comments if active_admin_config.comments?
  end

Twitter card type player を 使う

Twitter card には、いくつかの種類があるが、

dev.twitter.com

player というのが実はかなり高機能で、
自分の好きな html を iframe で twitter に埋め込むことが出来る仕組みになっています。

だが、使用するには card validater を使い、審査をしてもらう必要があります。
審査は、ドメイン単位で良いので、一つのカードさえ審査にとおれば、他のパスもすべて許可された状態になります。
https://cards-dev.twitter.com/validator

審査にかかる時間

リジェクトされた場合は、許可されるまで永遠に審査をしなければならないですが、
今のところ最短は、6時間程度で審査が通りました。

Your Twitter card is ready!

We've activated the player card for 申請したドメイン名.
If you want to use other kinds of Twitter cards (and we know you do), please make another request.

審査で必要な情報

審査時にログインしているアカウント

何でも良い。

screen_name などその他項目

何でも良い。公式アカウントを入れると、エラーが出て送信できない。

審査項目

PCサイト, スマートホンサイトと、スマホアプリ で動くようにする必要があるのですが、
スマートホンサイトではそもそも表示されない、スマホアプリでは WebView で 別ページとして表示する
という仕様のため、それほど難易度は高くないです。

申請時の player は、再生されない不具合がある状態でしたが、審査が通りました。
どうやらここ数ヶ月は、かなり審査が甘くなっているようで、htmlのチェックしかしていない気がします。

mp3を申請したときは、再生時間が長いとリジェクトされましたが、最近再度同じものを申請したところ、許可されました。

注意点

<meta content="https://自分が使用するプレイヤーのパス" name="twitter:player" />
  • player に指定するURLは、htmlの場合、https である必要がある。mp3 の場合は、http で出来た。
  • X-Frame-Options SAMEORIGIN を設定してはいけない。Rails であれば、自動でつきます。
  • playerのサイズ指定は、ノウハウが必要

mod-wsgi を python3.5.0 + pyenv + Apache2 で、AmazonLinux 上に構築

mod-wsgi は、python と1:1で紐付いているため、apacheに1つまでしか追加できない。

pyenv を入れる

公式に書いてあるとおり。
yyuu/pyenv · GitHub

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
・・・

python3 を入れる

このときに、オプションを付ける必要があります。
global にしても、しなくてもよいです。

$ CFLAGS="-fPIC"  pyenv install 3.5.0
$ pyenv global 3.5.0

apache2 を入れる

$ sudo aptitude install httpd
$ sudo aptitude install httpd-devel

mod_wsgi を入れる

以下の方法でインストールしてしまうと、system の python がつかわれる。

$ sudo aptitude install libapache2-mod-wsgi-py3 

*1

mod_wsgi.tar.gz をダウンロード

公式からダウンロード

install

python のパスを指定します。

$ tar zxvf mod_wsgi.tar.gz
$ cd mod_wsgi
$ ./configure --with-python=/home/username/.pyenv/versions/3.5.0/bin/python
$ make
$ sudo make install

apache2 設定

<VirtualHost *:80>

  ServerName   hoge.test
  ServerAdmin  server-mail@hoge.test
  DocumentRoot /hoge/public

  WSGIScriptReloading On
  WSGIDaemonProcess  my_name python-path=/home/username/.pyenv/versions/3.5.0/lib/python3.5/site-packages python-home=/home/username/.pyenv/versions/3.5.0  user=apache group=apache processes=2 threads=25
  WSGIProcessGroup   my_name
  WSGIScriptAlias    /  /hoge/app.wsgi

  <Directory "/hoge/">
    Order deny,allow
  </Directory>
</VirtualHost>

追加で、
LoadModule による wsgi のロードと、の設定が必要。
WSGISocketPrefix /var/run/wsgi

トラブルシューティング

Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encoding'

python-home、 python-path が間違っている可能性があります。

python-home は、python コンパイルオプションの、prefix と同じにします。
確認方法は以下。

$ python
>>> import sysconfig
>>> sysconfig.get_config_vars('CONFIG_ARGS')

python-path は、site-packages までのパスを設定します。

/home/username にアクセス出来ていない可能性があります。
chmod 755 /home/username

pyenv のインストール先を変更するのでも良いと思います。

(13)Permission denied: mod_wsgi (pid=23797): Unable to connect to WSGI daemon process '***' on '/etc/httpd/logs/wsgi.12880.0.1.sock' after multiple attempts., referer: http://dummy.test

socket ファイルにアクセス出来ていない可能性があります

WSGISocketPrefix の設定を変更する

*1:ただし、pyenv で管理しているの system python は、python (version2) で、 python3 を使う場合は、3を付けます。