Code Serendipity

Keyword: Ruby, Python, javascript, RoR, heroku, AWS...

Code Serendipity

Keyword: Ruby, Python, wordpress, javascript, AWS...

Deviseで管理者が承認したらユーザーのアカウントをアクティベートする実装【Rails】

f:id:serendipity4u:20170417172047p:plain

userカラムにapprovedを足す

class AddApprovedToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :approved, :boolean, :default => false, :null => false
    add_index  :users, :approved
  end

  def self.down
    remove_index  :users, :approved
    remove_column :users, :approved
  end
end

続きを読む

私のSanDisk16GBが唐突に壊れて思い出の写真が消えたがMini_Tool_Recoveryのおかげで復旧できた話

f:id:serendipity4u:20170417174925p:plain

意気揚々と、SDカードをmacに入れた私。

だがしかし、「なんか読みとれないよ」的な文章が現れる。 macの「写真」アプリも起動しない。

一眼レフにセットした状態ではプレビューできるのにな〜と思い、 もう一度カメラに入れて見ようとしたところ…

「画像がありません」

の文字。

絶望。

しかし、あるはずだ!解決策!

続きを読む

女子大学生が法人設立(LLC)をしてきたので感想・苦労したことをまとめます

f:id:serendipity4u:20170120201624j:plain

フリーランスとして請けていたweb制作ですが、だんだん規模が大きくなってきたのと、個人で開発しているウェブサービスもより本格的に運用していきたいとの思いから、法人化を行うことにしました。

続きを読む

letsencryptの更新が上手く行かなかった時のメモ。自動化までの道のり【rails, nginx,AWS,capistrano環境】

既存のletsencryptディレクトリを消しやり直す

letsencryptの更新が上手く行かなかった時のメモ。

新しく認証し直す。 まず /etc/letsencrypt/ ディレクトリを削除。

sudo git clone https://github.com/letsencrypt/letsencrypt /usr/local/letsencrypt

sudo /usr/local/letsencrypt/letsencrypt-auto --help --debug

sudo service nginx stop 

nginxを止めないと"Could not bind TCP port 443 because it is already in use by another process on this system (such as a web server). Please stop the program in question and then try again.“というメッセージが出る。

sudo /usr/local/letsencrypt/letsencrypt-auto certonly --standalone -d example.com -d www.example.com --agree-tos

で、

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will
   expire on 2017-05-08. To obtain a new or tweaked version of this
   certificate in the future, simply run letsencrypt-auto again. To
   non-interactively renew *all* of your certificates, run
   "letsencrypt-auto renew"

上手くいった。

自動化する

sudo vi /etc/cron.daily/letsencrypt
sudo chmod +x /etc/cron.daily/letsencrypt

/etc/cron.daily/letsencrypt の内容。

#!/bin/sh

LE_HOME=/usr/local/letsencrypt
WEBROOT=/var/www/rails/example/current/public #capistranoを使っているのでcurrentディレクトリを挟む
DOMAIN=example.com
SUBDOMAIN=www.example.com
LOG=/var/log/letsencrypt/renew.log

$LE_HOME/letsencrypt-auto certonly --debug --non-interactive --keep-until-expiring --webroot -w $WEBROOT -d $DOMAIN -d $SUBDOMAIN >> $LOG 2>&1
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    echo Automated renewal failed:
    exit 1
fi
service nginx reload

nginx設定ファイルで正しく証明書の場所が示されていることを確認。

/etc/nginx/conf.d/example.conf

server {
        listen 443 ssl;
        server_name xx.xx.xx.xx; #アプリのElastic IPに変更してください
        ssl_certificate      /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key  /etc/letsencrypt/live/example.com/privkey.pem;
        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_timeout 1d;
        root /var/www/rails/example/current/public; #自分のアプリケーション
...

参考

qiita.com

君が22歳なら、人生の7割はもう終わっている【ジャネーの法則】

思うところがあったので、きょうは技術メモ以外のトピックを書く。

私は死に焦りを持たない若い人が苦手だ。

人間が時間を測る基準なんで、年といった単位に特に意味はなくて、究極的には体感でしか測ることができない。1000年の重みを私たちは 1生、知ることができない。

今まで生きてきた時間と比べることでしか時間を測れない。

だから、人生の時間は均等ではない。0歳の子どもが過ごす1年と、と19歳の人間が1年過ごす1年は、

1/1 : 1/20 で20倍も違う。

なんて考えてて、ちょっとオリジナルじゃね、って思って生きてきたのだが、ググったら名前がついていて、「ジャネーの法則」というらしくて。

まあどっかで聞きかじってたのかもしれない。ごめんジャネー。

22歳で、80歳まで生きるという仮定のもと、ジャネーの法則では人生の何%過ごしてきたかを算出すると、

(1 + ½ + … 1/22) / ( 1 + ½ + /1/3 … 1/80)

で 体感余命は残り15年程度、 既に体感時間の7割以上が過ぎていることがわかった。

私は死への焦りはかなり持っているほうで、それは肉親の思わぬ死とか、街を歩いていて自分の真上を見上げたら、まさに飛び降りしようとしている人がいて、それをスマホで撮影する沢山の人々が輪になっていて、その真ん中から咄嗟にどいてしまった後に「自分がどいたせいであの人が死んだらどうしよう」と恐れてビルに駆け上がってその人と警察を交えて話した昔の出来事とか、たくさん飼っていた生き物のこととか、そういうのが影響しているんだと思うけど、

いい意味で自分に常に疑問を投げかけてるんじゃないかと思う。 「いま、なぜ生きるのか」 という理由がないと自分は生きれないめんどくさい人間で、

だってそうじゃないか、とも思う。だって死ぬとき、肉体的な痛みはあるけどそれは生に伴うものであって死そのものに伴うものじゃない。 死は無であり、死んでしまったら残した人たちに対する気持ちも何もない。何も感じない。だから悪く生きることが怖くても、死じたいは怖くない。 忘れられて悲しいとか、そう思う主体すらない。

だから自分たちには、そんな価値基準のない「ゼロ」である死を選ばないなら理由があるべきだと思う。しかしその理由が「幸せ」である必要はなくて、怒りとか、憎しみとかでも良いと思う。そういう感情を味わい尽くす意義ってすごいあると思う。なんで楽しいとか美味しいは肯定されて辛いとか苦しいはマイナスの価値を付与されるんだろうと思う。人間の偉大な発明はみんなそういう"マイナスの"価値を持つ感情が生み出したと思う。プラスをマイナスが生み出してるならマイナスだってプラスだろ。

と思っていたら、ビートたけしさんが良いことを言っていて、

人生に幸せなんて求めること自体勘違いなんだよ。世間じゃよくどうせ死ぬんだから楽しく生きようなんて言うけど、オイラは逆でどうせ死んで身軽になるんだから、生きてるうちにひどい目に会おう、辛く生きようと思ってる。

私の好きな映画は、「ファイトクラブ」なんだけど、 それはまさにメメント・モリな映画で、 銃口を口に突きつけて「今からお前は死ぬ!お前の本当にしたかったことは何だ!」とタイラーが言う。 やりたい気持ちを押さえ込んで、やれないことに対する辛さにも鈍感になって、感情を持たないで日々を過ごす人々を「ぶっ生き返す」映画。

死に焦りがないと私が思う風景は、 自分が関与しない所にある人間の話/モノにひたすら興ずる人々、 ルールを変えようとしないでそのルールを所与のものとして、つまらないって思いながら生きる人々。

だけど、そもそも「理由がないと何かをしないのもおかしくないか」とも思う。 ふつうに生きるでいいと思う。理由なんてなく。でもそのあり方を忘れてしまったら、私みたいにどうしても理由を考えてしまうなら、こう考えて欲しいと思って書いた。

Railsアプリで自動でURLが含まれたテキストのURLにリンクを貼ってくれるようにしたい

正規表現でやろうかと思いきやセキュリティ的にアレだったりするのかもしれないしgemを利用することにした。

gem で解決

がある。

<%= raw Rinku.auto_link(h(some_text)) %>

参考

ria10.hatenablog.com

qa.atmarkit.co.jp

railsからfacebookにnotification APIで通知を送る

http://media02.hongkiat.com/quicktips/unfollow-post-comments-facebook.jpg

頻繁にユーザーが見るfacebookに通知を送る方法。

jp.techcrunch.com

https://graph.facebook.com/{recipient_userid}/notifications?access_token={application_access_token}&template={Your_Message}&href={URL_to_your_app_or_request}

にPOSTする。

2つのgem

でやる方法がある。 コードをテストするまえに、facebook developperで「プラットフォーム」に「fbキャンバス」を追加しておくこと。 じゃないと

FbGraph::Unauthorized (OAuthException :: (#200) Only web canvas apps can send app notifications):

というエラーが出てしまうので。

koaraを使う

require 'koala'
require 'net/http'
require "net/https"
...

fb_url = "#{fb_id}/notifications?access_token=#{app_access_token}&href=#{FB_CALLBACK_URL}&template=You have a new score! See your results now!"
uri = URI.encode("https://graph.facebook.com/#{fb_url}")
uri = URI.parse(uri)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

fb_req = Net::HTTP::Post.new(uri.request_uri)
fb_response = http.request(fb_req)

fb_graphを使う

uid = hogehoge # facebookのユーザーuid

fb_user = FbGraph::User.new(uid)
app = FbGraph::Application.new(APP_ID, :secret => APP_SECRET)
app.notify!(
      fb_user,
      :href => 'http://www.example.com', #通知をクリックした時のリンク先
      :template => "お知らせがあります") #通知として表示される文字

参考

Using NET::HTTP in Rails to send Facebook App Notifications (Example)

stpanisush.hatenablog.com

NOTE

  • ブラウザには出ても、facebook アプリだと通知がない気がする
  • POST “/” になるので、最初エラーが出る

herokuをletsencrypt使って無料で簡単にSSL化しよう

https://www.upcloud.com/support/wp-content/uploads/2016/01/Lets-Encrypt-1024x410.png

heroku のSSL化の記事はたくさんあるが、とにかく正確な「最新」の日本語情報がすくない。あとローカルでやる作業か否かがわかりにくい。なので、需要あるかと思い記事にします。

※ heroku でSSLを使用するには$20/month のアドオンSSL endpointを使わなくてはいけなかったが、 現在は、Freeプラン以外のプラン(hobby $7 ~ )で、SSL使用が無料になった。

certbotのインストール(ローカル環境)

これはいくらでもやり方が出てくるのでそれで入れるだけ。macならbrewとか ( brew install certbot)

Let's EncryptをHerokuにあるRailsアプリに適用する(2016/9月版) - Qiita

証明書をletsencryptで発行(ローカル環境)

config/routes.rb で/.well-known/acme-challenge/:idで指定されたテキストを返すページに行くようにルートを設定。

Rails.application.routes.draw do
  get '/.well-known/acme-challenge/:id' => 'static_pages#certbot'

 
end

コントローラで

def certbot
    id = ENV['LETS_ENCRYPT_ID']
    secret = ENV['LETS_ENCRYPT_SECRET']

    if id.nil? || secret.nil?
      render_404 and return
    end

    unless id == params[:id]
      render_404 and return
    end

    render text: "#{id}.#{secret}"
  end

これをgit push heroku … .で反映させる。

(heroku config:set でセットできるよう)環境変数にしておくと、3ヶ月ごとの更新のときいちいちgit push しなくていいので便利。

この環境変数に入る値は、あとでcertbotから指定される。

用意ができたら

mkdir certbot
certbot certonly --manual -d www.example.com --logs-dir certbot --config-dir certbot --work-dir certbot

を実行して、 * email(更新通知などが来る) や

を質問に答えながら指定していくと、 最後にこのURLにアクセスしたらこの変数を返せ、というのが表示されるのでそれを

ENV['LETS_ENCRYPT_ID']
ENV['LETS_ENCRYPT_SECRET']

に設定してあげる(ローカルから出来る)。(BASICやSSL設定を一時的にオフにしてあげるとよい)

うまくいけばその後、証明書を取得できる。

Congratulations!
Generating key /dir/working_dir/certbot/live/www.example.com/fullchain.pem

といったメッセージが表示される。certbot/live/www.example.com/のしたに、 fullchain.pemとprivkey.pemが作られる

herokuに設定(ローカルからできる)

※他のサイトにはあるかもしれないが、heroku SSL はもうbetaでないので、labs:enableといったコマンドを打つ必要はない

heroku certs:add /etc/letsencrypt/live/www.example.com/fullchain.pem /etc/letsencrypt/live/www.example.com/privkey.pem

その後、ドメインDNS設定どうこうが出て来る。 これは説明に従えば良いだけ。CNAME 設定を変える。

Resolving trust chain... done
Adding SSL certificate to ⬢ your-app... done
Certificate details:
Common Name(s): example.com
Expires At:     xxxx-xx-xx xx:xx UTC
Issuer:         /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Starts At:      xxxx-xx-xx xx:xx UTC
Subject:        /CN=www.example.com
SSL certificate is verified by a root authority.

=== Your certificate has been added successfully.  Update your application's DNS settings as follows
Domain                    Record Type  DNS Target
────────────────────────  ───────────  ──────────────────────────────────────
www.example.com               CNAME       www.example.com.herokudns.com

あとはHTTPS監視とかやっておくと良いと思います。

savamoni.com

engineer.crowdworks.jp

更新

certbot/ ディレクトリ配下に移動。ディレクトリ名などは各自の環境に合わせてください。

certbot renew -q --no-self-upgrade --logs-dir certbot --config-dir certbot --work-dir certbot

参考

blog.kakeragames.com

ローカルのmysqlでdumpファイルを作りheroku本番環境に流し込む

AWSからherokuに移行するときに必要だった作業。

ダンプとは、デバッグやデータ修復のために、ファイルやメモリの内容をディスクに出力(記録、あるいは表示)すること。

ダンプをつくる

mysqldump -u ユーザ名 -p DB名 > 出力先ファイル名

で特定データベースのダンプが出来る。

ダンプを流し込む

接続するために、heroku configコマンドで CLEARDB_DATABASE_URLの情報を取得。

mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true’

みたいなのが出てくる

:から@の部分がパスワード。

mysql -u username -p password -h host database_name < dump.sql

でローカルから流し込む。

参考

kiyotakakubo.hatenablog.com

Processing入門 ③キーボードやマウスから値を受け取って操作する、画像を表示してフィルターをかける、合成する

キーボードとマウス

キーボードのアクションといったイベントにトリガーさせられる。

  • keyPressed() :キーが1つでも押されているとtrue。

  • key: 最後に押されたキーを表す文字

  • keyTyped(): キーが押されるたびに呼び出される関数 (CTRLキー等は除く)
  • keyReleased(): キーから指が離れたときに呼び出される関数
  • keyCode: 最後に押されたキーのキーコード

keyCodeなんのこっちゃと言う感じだが、

ASCII 文字と非 ASCII 文字 (矢印キーなど) のことで、前者はコード化されませんが、後者(非 ASCII 文字)の場合はコード化が必要です。コード化された文字に対しては、Processing は key 変数を CODED トークンに設定することによって、keyCode というもう 1 つの特殊な変数を調べるように指示します。 

Processing によるデータ視覚化: 第 2 回 インターフェース、オブジェクト、画像、そしてアプリケーションを使用した、より高度なデータ視覚化

らしい。

キーコードを判定することで、カーソルキーやシフトキーのように、文字に紐付けられていないキーを扱うことができる。キーワードとしてUP、DOWN、LEFT、RIGHT、ALT、CONTROL、SHIFTが用意されている。

void keyPressed()
{
  if (key == CODED) {
    if (keyCode == DOWN) println("Key pressed: Down arrow");
    if (keyCode == SHIFT) println("Key pressed: Shift key");
  } else {
    println("Key pressed: " + key );
  }
}

processingのコンソールみたいなところに表示される。 shiftのkeyCodeは16であることがわかった。 これがわかれば、UPを押したらy座標を上げるプログラムとかゲームっぽいものが作れる。

f:id:serendipity4u:20170129143616p:plain

マウスイベントの関数

  • mousePressed
  • mouseReleased
  • mouseMoved
  • mouseDragged

mouseX および mouseY 変数にはマウスの現在の位置が取り込まれます。マウスが移動する前の位置を (前のフレームから) 取り込むには、 pmouseX 変数 pmouseY 変数を使用します。

画像の使用

  • Processing は、filter 関数を介して、あらかじめ用意されている画像処理機能を提供します。この filter 関数は、フィルターのモードを直接ディスプレイ・ウィンドウに適用する関数です
PImage img1;

void setup(){
  img1 = loadImage("images/woman.jpeg");
  size(1000,600);
  smooth();
  frameRate(1000);

void draw() {
image(img1, 0, 0);
filter(GRAY);
}

これでグレースケールに画像を変更できた。

画像を合成する

合成する画像 (img2) を最初に指定し、その後に合成する画像 (img2) の x 座標、y 座標、幅、高さといった4つのパラメータを設定する。 さらに、合成先の画像 (img1) の左上隅の x 座標、y 座標、幅、高さのパラメーターを続ける。そして最後に定義するのが、モード・パラメーター。

  img1.blend( img2, 0, 0, img1.width, img1.height, 0, 0, img1.width, img1.height, ADD );

f:id:serendipity4u:20170122201524j:plainf:id:serendipity4u:20170129151443j:plain を合成して

f:id:serendipity4u:20170129151417p:plain

ができた。

参考

Processing によるデータ視覚化: 第 2 回 インターフェース、オブジェクト、画像、そしてアプリケーションを使用した、より高度なデータ視覚化Processingクイックリファレンス