iOSアプリ、Androidアプリのダウンロード数などの情報を集約してくれてメール通知などもしてくれるDISTIMOがAPIを提供してたのでmixpanelの時と同じようにTeam Dashboardに出してみました。
アプリ版ももっと頑張ろうというモチベーションが湧いて来ました。
iOSアプリ、Androidアプリのダウンロード数などの情報を集約してくれてメール通知などもしてくれるDISTIMOがAPIを提供してたのでmixpanelの時と同じようにTeam Dashboardに出してみました。
アプリ版ももっと頑張ろうというモチベーションが湧いて来ました。
Team DashboardはHTTP Proxyという機能があって、ブラウザ上からJSONのデータを引っ張ってきてパスを指定すればそれだけでウィジェットに表示できるので、合計数は怖話本体にJSON APIを作り、PVのGoogle Analyticsと収益のnendはそれぞれ引っ張ってきて(nendはmechanizeでスクレイプ)、heroku上のsinatraで自作のJSONを返しています。
グラフだけはganglia互換みたいなDatapointsを自分で用意する必要があります。でもdemoコードがついてるので実装はパクれば簡単。レンジ指定などは端折ってとりあえずMixpanelから日別の怖い話投稿数・サインアップ数・シェア数を取ってきて出すようにしてみました。
# app/models/sources/datapoints/mixpanel.rb:
module Sources
module Datapoints
class Mixpanel < Sources::Datapoints::Base
def get(targets, from, to, options = {})
client = ::Mixpanel::Client.new(
api_key: 'xxxxxxxxxxxxxxxxxxxxxxx',
api_secret: 'xxxxxxxxxxxxxxxxxxxxxxxx'
)
data = client.request('events', {
event: '["Share","Signed up","Posted story"]',
type: 'general',
unit: 'day',
interval: 30,
})
results = []
targets.each do |target|
datapoints = []
data["data"]["series"].each do |date|
datapoints << [data["data"]["values"][target][date], Time.parse(date).to_i]
end
results << {'target' => target, 'datapoints' => datapoints}
end
results
end
def available_targets(options = {})
["Share", "Posted story", "Signed up"]
end
def supports_target_browsing?
true
end
end
end
end
SNSログイン(Twitterでログインとか)をリリースしてから明らかにサインアップ数が増えてることが分かって嬉しい。
あとはWebとiPhone版とAndroid版の比率とか出したいので円グラフを出したいところです。
昨日Team Dashboardを設定して今日見てみたら…
もう、オマエら勝手に弄るなよなぁw
そもそもイントラ向けっぽいのでデータ変更系メソッドだけにBASIC認証かけときました。
# app/controllers/api/base_controller.rb:
module Api
class BaseController < ApplicationController
http_basic_authenticate_with name: 'admin', password: 'foo', only: [:create, :update, :destroy]
# some codes
end
end
これでよし。
追記:
弊社オフィスのダッシュボードは現Engine Yardの@yandoさんから貰ったEeePCで動かしています。@yandoさんとても助かっています。ありがとうございます。みんなEngine Yard使おう!(東京リージョンもあるよ!)
オフィスでGoogle AnalyticsとかMixpanelとかlogentriesとかディスプレイに表示させてたんですが、適当じゃなくてそろそろちゃんとした指標(ユーザー増加率とか)を出して共有したいなと思いました。自分で作るのは面倒なので探していたらTeam Dashboardがrails + backborne.jsで出来てて手頃そう。(qnypさんのブログで知りました)
$ git clone git://github.com/fdietz/team_dashboard.git
$ bundle
$ cp config/database.example.yml config/database.yml
$ rake db:create && rake db:migrate
$ rake populate
$ rails s
デフォルトはmysqlなのでherokuで動かしたい場合はpostgresql-adapterを追加。
# Gemfile:
group :production do
gem "activerecord-postgresql-adapter"
end
$ brew install qt
# Gemfile:
group :development, :test do
gem 'capybara-webkit'
gem 'konacha'
end
# config/initializers/konacha.rb:
Konacha.configure do |config|
config.spec_dir = 'spec/javascripts'
config.driver = :webkit
config.stylesheets = %w(application)
end if defined?(Konacha)
# app/assets/javascripts/foo.js.coffee:
class Foo
bar: ->
'bar'
# spec/javascripts/foo_spec.js.coffee:
#= require foo
describe 'Foo', ->
it '#bar', ->
(new Foo).bar().should.equal('bar')
% rake konacha:run
F
Failed: Foo #bar
ReferenceError: Can't find variable: Foo
Finished in 0.00 seconds
1 examples, 1 failed, 0 pending
そりゃそうだ。だってcoffeeだと
(function() {
var Foo;
Foo = (function() {
function Foo() {}
Foo.prototype.bar = function() {
return 'bar';
};
return Foo;
})();
}).call(this);
こうやってグローバグ汚さないように囲われてるんだから。だからといって元々デフォルトOFFだった--bareオプションは今はデフォルトONになってるのでわざわざ外すもの気持ち悪い。
だったら
class @Foo
って書けばいいじゃん。って言ってるんだけどマジで?みんなどうやってるの?
sprockets-commonjsが標準で入ってファイル名にmoduleが必要じゃなきゃいいんだけどなあ。
長かった。
seleniumはguard時とかにウィンドウ出てきてウザい。capybara-webkitはcapybara2系に対応してない。(reposのheadでは対応してるので次bump upされたら対応されるっぽい)
現時点ではpoltergeist一択っぽい。
ただ、Macでwebfontを読むとphantomjsがcrushするのでpatch当てる。
$ brew install phantomjs
# Gemfile:
group :test do
gem 'poltergeist'
gem 'rack-contrib'
end
# spec/spec_helper.rb:
require 'capybara/poltergeist'
RSpec.configure do |config|
Capybara.javascript_driver = :poltergeist
end
# config/initializers/poltergeist.rb:
if Rails.env.test?
require 'rack/contrib/simple_endpoint'
Rails.application.config.middleware.insert_after Rack::Runtime, Rack::SimpleEndpoint, /\.ttf$/ do |req, res|
ua = req.env['HTTP_USER_AGENT']
if ua =~ /Intel Mac OS X.*PhantomJS/
res.status = 403
"Denying #{req.fullpath} to #{ua}"
else
:pass
end
end
end
これは酷い。
この作業、@mreinschとペアプロでやってたんですがpoltergeistってドイツ語だそうです。ちなみに@hrysdがhidden fieldを「ハイデンフィールド」とドイツ語っぽく呼んでたのでドイツ語で何て言うのか聞いたら、「verstecktes felder」だそうです。全く違いました。どんな言語でも「ハイデンフィールド」は間違いだそうです。
ActiveRecordでserializeを使った場合、デフォルトではyamlでserializeされる。独自のserializerを実装すればそれを渡せる。
Post < ActiveRecord::Base
serialize :meta, Foo.new
end
しかしデフォルトではjson用のserializerが無いのでserializer-railsを使うと便利。
Post < ActiveRecord::Base
serialize :meta, format: :json
end
xmlも使えたり、gzip圧縮できたりもする。
Thomas on Rails。楽しげなメロディーと共に大惨事連発してます。Railsエンジニアのお父さんはお子さんとうっかり見たら心を深くえぐられそうです。
「じこはおこるさ」
スリルなんてちょっとなら楽しみさ
でもイライラすると事故が起きる
へっちゃらさ なんて知らん顔して
走っているとそんな時
事故がほら起きるよ いきなり来る
調子乗ってやってるとバチがあたる
事故がほら 起きるよ
いい気になってると
そうさ、よそ見してるその時に
事故は 起きるものさ
思いつきでやると きっと 失敗するよ
幸運の女神は気まぐれだから
ウキウキしてるとまっさかさま
忘れないで気をつけてね いつだって
事故がほら起きるよ 突然さ
運が無い時はしょうがない
なんとかしよう
事故がもし起きたら
落ち込まないで
うまくやれるようにがんばろうよ
事故は起きるものさ
”標識はいくつもあるのにさ
大事なモノばかり見落とすね”
そんな時必ずやってくる
二度とやらなければいいけど
事故がほら起きるよ いきなり来る
調子乗ってやってると
バチがあたる
事故がほら起きるよ
いい気になってると
そうさ、よそ見してるその時に
事故は起きるものさ
事故がほら起きるよ突然さ
運が無い時はしょうがない
なんとかしよう
事故がもし起きたら
落ち込まないで
「まぁ、自信過剰だと集中力なんて
たいがい散漫になっちゃうからね」
事故だ 事故だ
忘れてると事故は起こるさ
ほーら!
"Accidents Will Happen"
Thrills and spills on the railway, it's a life of happiness
But sometimes impatience can lead to carelessness
Some think they are smart cats, and some just know it all
But sooner or later we all find out that
Accidents happen now and again, just when you least expect
Just when you think that life is okay, fate comes to collect
Accidents happen now and again, when people or trains get smart
If you don't concentrate on the thing that you're doing
Accidents will happen, just like that
Your best-laid plans can turn upside down if you get too confident
Sometimes you will slip and slide if that's Lady Luck's intent
One minute you're riding high, the next you're on the ground
But please remember, whatever the weather
You must take care 'cause
Accidents happen now and again, sometimes just by chance
You gotta pick yourself up and dust yourself down
Put it down to experience
Accidents happen now and again
Just don't take it all to heart
If you don't concentrate on the thing that you're doing
Accidents will happen, just like that
The warning signs are there for us to see most of the time
But sometimes we take chances and ignore the danger signs
Fate can surprise you, with no reason or rhyme
Make sure you learn your lesson you'll know better next time
Accidents happen now and again, just when you least expect
Just when you think that life is okay, fate comes to collect
Accidents happen now and again, when people or trains get smart
If you don't concentrate on the thing that you're doing
Accidents will happen, just like that
Accidents happen now and again
Sometimes just by chance
You gotta pick yourself up and dust yourself down
Put it down to experience
Accidents happen now and again
Just don't take it all to heart
If you don't concentrate on the thing that you're doing
And whatever you're doin' is not what you're thinking
Accidents, incidents
Accidents, incidents, accidents happen, just like that!
怖話でcomment付ける対象なんて"怖い話"だけに決まってるじゃん!
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.references :story
t.timestamps
end
end
end
余裕過ぎワロタwww
1年後・・・
"怖い漫画"・・・だと・・・!?
\( ^o^)/ オワタ
じゃ、じゃあ、comic_commentsというテーブルを・・・(レガシー直行)
でも大丈夫、後からでもcommentableに移行できます。今回はacts_as_commentableを使いました。
# Gemfile:
gem 'acts_as_commentable', '2.0.1'
% rails g comment
modelとmigrationでファイルを上書きしそうになるけど上書きしない。
# app/models/comment.rb:
class Comment < ActiveRecord::Base
include ActsAsCommentable::Comment
belongs_to :commentable, polymorphic: true, counter_cache: true
end
# app/models/story.rb:
class Story < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
acts_as_commentable
attr_readonly :comments_count
end
# app/models/comic.rb:
class Comic < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
acts_as_commentable
attr_readonly :comments_count
end
polymorphicかつcounter_cache使う時は、相手先をreadonlyにしとく必要があるみたいです。
class AddCommentableToComment < ActiveRecord::Migration
def up
rename_column :comments, :story_id, :commentable_id
add_column :comments, :commentable_type, :string, default: 'Story'
add_index :comments, :commentable_id
add_index :comments, :commentable_type
end
def down
rename_column :comments, :commentable_id, :story_id
remove_column :comments, :commentable_type
end
end
これで既にコメントが沢山あってもcommentableへの移行がバッチリ。この調子でtag, category, voteもどんどんやっていこう!