読者です 読者をやめる 読者になる 読者になる

おれんじりりぃぶろぐ

きっと何者にもなれないエンジニアのブログ

redcarpetでMarkdown表示

ruby rails

railsでredcarpetを使ってMarkdown記法を出力させた時のメモ。

方法

Gemfileに以下を追記する。

# Use Markdown Notation
gem 'redcarpet'

app/helper配下に以下のヘルパーメソッドを定義する。

markdown_helper.rb

module MarkdownHelper
  def markdown(text)
    unless @markdown
      renderer = Redcarpet::Render::HTML.new
      @markdown = Redcarpet::Markdown.new(renderer)
    end

    @markdown.render(text).html_safe
  end
end

view側では以下のように呼び出せばok.

<%= markdown(text) %>

これでブログとか自作できちゃいますね\(^o^)/

参考

Rails4でカスタムcssやjavascriptを動かす方法

rails ruby javascript

ちょっと嵌ったのでメモに残す。

まず、app/aseet/css,app/aseet/javascript配下にカスタムcss, javascriptファイルを置く。
そして、それらを適応したいviewに以下のリンクタグを追記する。

<%= stylesheet_link_tag "custom.min.css" %>
<%= javascript_include_tag "custom.js", "custom2.js" %>

これで動くはずが動かない(´;ω;`)

config/environments/development.rb中の

config.assets.raise_runtime_errors = false

この部分を

config.assets.raise_runtime_errors = true

に変更する。動きました\(^o^)/

しかし、確かにこの方法でも動きましたが
この後、assetpipelineを有効にすればよいということが判明。

development環境であれば、config/enviroments/development.rbに以下を追記するだけでlinkタグを書かなくてもapp/asset中に置かれたスタイルシートやjsファイルが有効になる。

# Asset pipeline config
  config.assets.enabled = true

YouTube Data API v3を叩いてみる

javascript

暇を持て余しているのでドットインストールの

を視聴し始めたが、動画内ではAPIのバージョンが既にサポートが終了したV2でだったので
今回V3に置き換えてYoutube DataAPIを試してみた時のメモ。

やること

Youtube上の動画の検索、そして検索結果の動画をクリックすると再生を始めるところまで実装を行う。

Google開発キーを発行する

Youtube Data API v3を使用するためには開発キーが必須ぽいので発行作業を行う。今回はユーザー認証など特別な認証は行わないのでOAuthは使用しない。

上記にアクセスし、適当にプロジェクトを作成後、作成したプロジェクトを選択する。
左バーの[API]からYoutube Data API v3を有効にする。
さらに[認証情報]から開発キーの発行を行う。

f:id:orange_lily27:20150726184802p:plain

検索を実装する

まずは検索部分の実装を行う。

index.html

ヘッダ部分

<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="myscript.js"></script>
<script src="https://www.youtube.com/iframe_api"></script>
</head>

フォーム部分

<form id="search" onsubmit="return false;">
<input type="text" id="q" size="40">
<button type="submit" value="検索" class="btn btn-primary"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
</form>

検索結果の表示部分

<p>検索結果</p>
<ul id="list"></ul>

続いて、JavaScript側の実装を行う。

myscript.js

$('#search').submit(function(){
    var url = "https://www.googleapis.com/youtube/v3/search";
    var options = {
      q: $('#q').val(),
      part: 'snippet',
      key: '[MY_KEY]',
      maxResults:10
    };
    // リソースの取得
    $.get(url, options, function(rs){
      console.log(rs);
      $('#list').empty();
      for(var i=0; i<rs.items.length; i++){
        var id = rs.items[i].id.videoId;
        var thumbnails = rs.items[i].snippet.thumbnails.medium.url;
        var title = rs.items[i].snippet.title;
        $('#list').append($('<li class="movie">').append($('<img>').attr('src', thumbnails)).data('video-id', id).data('thumbnail', thumbnails).append('<p>' + title + '</p>').data('video-title', title));
      }
    }, "json");
  });

オプション指定はpartkeyは必須項目。qで検索ワードを指定することができる。maxResultsで検索結果の件数を指定することができる。省略した場合はデフォルトの5が指定されている。
get関数でオプションとurlを渡すと結果はrsに格納される。受けとった動画のサムネイルとタイトル情報をid=list属性に動的に追加している。

*CSSにbootstrapを使用している。

プレイヤーを実装する

検索結果が表示出来るようになったので、続いてプレイヤー部分を実装する。

ここに書いてあるように実行すれば簡単にプレイヤーを実装することができる。

index.html

<div id="player"></div>

myscript.js

プレイヤーの初期化

function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    height: '390',
    width: '640',
    events: {
      'onStateChange': onPlayerStateChange
    }
  });
}

eventsでは任意のタイミングでイベントを実行させることができる。省略することもできる。

$(document).on('click', 'li.movie img', function(){
    var videoId = $('li.pmovie img').$(this).data('video-id');
    player.loadVideoById(videoId);
  });

検索結果のリストのサムネイル画像をクリックすることで動画再生が開始される。

JSでボタンを押すと音が鳴る実装

ボタンを押すと音声が流れるサンプルメモ。

HTML

<!-- ボタンの設置 -->
 <input type="button" value="再生" onclick="ring()">
<!-- 音声ファイルの読み込み -->
<audio id="tts">
    <source src= "audio/sample.mp3" type="audio/mp3">
 </audio>

JavaScript

<script type="text/javascript">
  function ring(){
    document.getElementById("tts").load();
    document.getElementById("tts").play();
  }
</script>

Railsでgemを使わずにファイルをアップロードしてみた

rails ruby

RailsにはCarrierWaveなど画像アップロード用の便利なGemが存在するが
あえて今回はそれを使わずに実装を行った時のメモ。

View#作成

まずはアップロード用のフォームを作成する。今回は音声アップロード用の実装を行ったが、画像でも同じ方法で実装できるはず。

<%= form_for @audio do |f| %>
  <%= f.label "音声新規アップロード", class: 'control-label' %>
  <%= f.file_field :value %>
  <%= f.submit "アップロード" %>
<% end %>

Controller#作成

def create
 @audio = Audio new

 file = params[:audio][:value]
 if !file.nil? 
      name = file.original_filename
      # パスの指定
      @audio.path = 'audio/' + name
      @audio.save

      # ファイル本体のアップロード
      File.open("public/" + @audio.path, "wb"){ |f|
        f.write(file.read)
      }
 end
 redirect_to root_path
end

Controller#削除

def destroy
    @audio = Audio.find(params[:id])
    # 音声ファイル本体の削除
    File.delete("public/" + @quiz.path)
    # modelの削除
    @audio.destroy
    redirect_to root_path
end

まとめ

Gemって便利\(^o^)/

参考

Ansibleを使ってみた

最近では「Infrastructure as Code」というバズワードが流行ってるらしい。

というわけで、今回はAnsibleを使ってみた時の備忘録。

Ansibleとは(・・?)

構成管理ツール。サーバーの状態を記述しておくことで、サーバーの状態をひと目で把握しその通りにサーバーの状態を保つことができる。環境構築からのストレスフリー\(^o^)/

環境

今回は実験的にansibleを試すのでVagrantで2台のubuntuVM(Host, Client)を立てることにする。

Vagrant用のフォルダを作成し複数VMを同時に起動できるようにVagrantfileを書き換える。

mkdir ansible_test
cd ansible_test
vagrant init trusty64(box名)

Vagrantfile

Vagrant.configure(2) do |config|

# config.vm.box = "trusty64" コメントアウトする
# 以下を追加する
  config.vm.define "host" do |node|
    node.vm.box = "trusty64"
    node.vm.hostname = "host"
    node.vm.network :private_network, ip: "192.168.33.10"
  end

  config.vm.define "client" do |node|
    node.vm.box = "trusty64"
    node.vm.hostname = "client"
    node.vm.network :private_network, ip: "192.168.33.11"
  end
end

起動する。

vagrant up

状態を確認すると2台のVMが立ち上がっていることが分かる。

vagrant status
Current machine states:

host                      running (virtualbox)
client                    running (virtualbox)

sshはホスト名を指定すればそれぞれのサーバーに接続できる。

Ansibleのインストール

続いて、ホストマシン側にAnsibleのインストールを行う。

sudo apt-get install ansible

但し、これだと古いバージョンのansibleが入ってしまうので注意。
続いて、Host <-> Client間をssh出来るように鍵設定を行う。

鍵の作成。

ssh-keygen -t rsa

公開鍵をclientへのコピー

ssh-copy-id client

使い方

まずはInventryファイルを作成する。 Host側で以下のhostsファイルを作成する。

hosts

[client]
192.168.33.11

試しにpingモジュールを試してみる。

ansible all -i hosts -m ping

結果

192.168.33.11 | success >> {
    "changed": false, 
    "ping": "pong"
}

以下のansible.cfgを作成しておくとInventryファイルの記述を省略できる。
ansible.cfg

[defaults]
hostfile = ./hosts
ansible all -m ping

playbook

まず、playbookを作成する。yml形式で記述を行う。
今回はapache2をインストールしてみた。

playbook.yml

---
- hosts: client
  sudo: yes
  tasks:
    - name: install apache2
      apt: name=apache2 state=latest
    - name: start apache and enabled
      service: name=apache2 state=started enabled=yes

playbookで使用できるモジュールの詳細は公式ドキュメントをCheck

playbookを実行する。

ansible-palybook playbook.yml

クライアント側にapache2がインストールされ&起動しているはずなのでhttp://192.168.33.11/にアクセスするとapache2のデフォルト画面が表示される。

f:id:orange_lily27:20150519163122p:plain

playbookの例

  • apache2のインストール
- name: install apche2
      apt: name=apache2 state=latest
  • apache2の起動
- name: start apache and enabled
      service: name=apache2 state=started enabled=yes
  • オーナーの変更
- name: change owner
      file: dest=/var/www/html owner=vagrant recurse=yes

recurseは再帰的な実行

  • ディレクトリの作成
  - name: create derectory
      file: path=/var/www/html/audio state=directory
  • ファイルのコピー
- name: copy index.html
      copy: src=./index.html dest=/var/www/html/index.html

deviseでTwitterアカウントを使ってログイン機能を実装してみた

ruby rails

外部アカウント(今回はTwitter)を使ってのログイン機能の実装をしてみた時のメモ。

Twitter APPを作成する

まずTwitter DeveloperでAPPの作成を行う。
APP作成には電話番号登録が必須になったみたい(´;ω;`)

railsプロジェクトを用意する

rails new devise_twitter_test
cd devise_twitter_test

gemfileに以下を追記して、bundle installを行う。

# Use devise as login system
gem 'devise'
# Use omniauth as Twitter etc... login
gem 'omniauth-twitter'
bundle install

続いて、Userモデルを作成する。

rails g model User provider uid name

さらにコントローラーを作成し、ルーティングルートを設定しておく。

rails g controller Home index

OmniAuthを使う

デバイスの設定を行う。

rails g devise:install

config/initializers/devise.rbに以下を設定する。

config.omniauth :twitter, 'APP_ID', 'APP_SECRET', display: 'popup'

次にUserモデルを作成する。

rails g model User provider uid name

app/models/user.rbを以下のように変更する。

class User < ActiveRecord::Base
  devise :omniauthable
end

さらにconfig/routes.rbを以下のようにする。

Rails.application.routes.draw do

  root "home#index"
  get "home/index"

  devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
  devise_scope :user do
    get 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
  end
end

上記の設定を行うと以下のようなルーティングが自動的に生成される。

user_omniauth_authorize GET|POST /users/auth/:provider(.:format)        devise/omniauth_callbacks#passthru {:provider=>/twitter/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) devise/omniauth_callbacks#(?-mix:twitter)

Controllerを作成する

app/controller直下にuserディレクトリを作成しその中にomniauth_callbacks_controller.rbを作成する。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def twitter
    @user = User.find_or_initialize_by(user_params) # 見つからない場合は新規作成

    if @user.new_record? # 新規作成の場合実行される
      @user.name = request.env["omniauth.auth"].info.nickname
      @user.save
    end

    if @user.persisted? #DBに保存済みかどうか
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
    else
      session["devise.twitter_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  private
  def user_params
    request.env["omniauth.auth"].slice(:provider, :uid).to_h
  end
end

Viewを作成する

app/views/layouts/application.html.erb中にTwitterログイン/ログアウトへのリンクを張る。

<% if user_signed_in? %>
      <%= link_to "Sign out", destroy_user_session_path %>
<% else %>
      <%= link_to "Sign in with Twitter", user_omniauth_authorize_path(:twitter) %>
<% end %>

<% if !current_user.nil? %>
    <p>ようこそ<%= current_user.name %></p>
<% end %>

f:id:orange_lily27:20150720195947p:plain

コントローラーでは@user.name = request.env["omniauth.auth"].info.nicknametwitterのIDを取得した。その他の値については以下を参照。

参考

deviseのメッセージを日本語化する

rails ruby

前回、deviseを使ってサクッとユーザー認証機能を作ってみた。
しかし、デフォルトではエラーメッセージなどすべて英語で表示されてしまう(´;ω;`)エイゴワカラナイ
今回はこれらのメッセージを日本語化してみた。

やり方

config/locales中に日本語用の辞書ファイルを作成する。辞書ファイルはyml形式で記述する。
ありがたいことに辞書を公開してくれている方々がいるのでそれを使わせていただく。

それぞれをconfig/locales/ja.yml, config/locales/devise.ja.ymlとして保存する。

さらに、config/application.rb中に以下の設定を追加する。

# i18nを日本語に設定する
config.i18n.default_locale = :ja

結果はこんな感じ。

f:id:orange_lily27:20150716202800p:plain

viewの部分は置き換えるしか方法はないかな(・・?)

参考