aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock31
-rw-r--r--app/controllers/application_controller.rb12
-rw-r--r--app/controllers/i_controller.rb22
-rw-r--r--app/controllers/sessions_controller.rb11
-rw-r--r--app/controllers/users_controller.rb123
-rw-r--r--app/models/account.rb3
-rw-r--r--app/models/favorite.rb8
-rw-r--r--app/models/retweet.rb8
-rw-r--r--app/models/tweet.rb38
-rw-r--r--app/models/user.rb12
-rw-r--r--app/views/errors/error_404.json.jbuilder4
-rw-r--r--app/views/errors/error_500.json.jbuilder4
-rw-r--r--app/views/i/_list.html.haml2
-rw-r--r--app/views/i/best.html.haml1
-rw-r--r--app/views/i/recent.html.haml1
-rw-r--r--app/views/i/show.haml1
-rw-r--r--app/views/layouts/application.html.haml (renamed from app/views/layouts/application.haml)2
-rw-r--r--app/views/main/index.haml29
-rw-r--r--app/views/main/index.html.haml42
-rw-r--r--app/views/shared/_tweet.html.haml (renamed from app/views/shared/_tweet.haml)4
-rw-r--r--app/views/shared/_tweet.json.jbuilder19
-rw-r--r--app/views/shared/_tweets.haml4
-rw-r--r--app/views/shared/_user.json.jbuilder2
-rw-r--r--app/views/shared/_user_info.html.haml17
-rw-r--r--app/views/shared/_user_nav.html.haml11
-rw-r--r--app/views/users/_list.html.haml6
-rw-r--r--app/views/users/best.haml1
-rw-r--r--app/views/users/best.html.haml1
-rw-r--r--app/views/users/best.json.jbuilder4
-rw-r--r--app/views/users/info.haml10
-rw-r--r--app/views/users/my.haml1
-rw-r--r--app/views/users/my.html.haml1
-rw-r--r--app/views/users/my.json.jbuilder4
-rw-r--r--app/views/users/recent.haml1
-rw-r--r--app/views/users/recent.html.haml1
-rw-r--r--app/views/users/recent.json.jbuilder4
-rw-r--r--app/views/users/show.html.haml4
-rw-r--r--app/views/users/show.json.jbuilder2
-rw-r--r--app/views/users/timeline.haml1
-rw-r--r--app/views/users/timeline.html.haml1
-rw-r--r--app/views/users/timeline.json.jbuilder4
-rw-r--r--client/settings.yml.default6
-rw-r--r--client/worker.rb45
-rw-r--r--config/application.rb2
-rw-r--r--config/environments/development.rb4
-rw-r--r--config/environments/production.rb2
-rw-r--r--config/initializers/omniauth.rb15
-rw-r--r--config/routes.rb37
-rw-r--r--config/settings.yml6
-rw-r--r--db/migrate/20130322152541_add_user_id_index_to_events.rb6
-rw-r--r--db/migrate/20130322171251_add_column_consumer_version_to_accounts.rb5
-rw-r--r--db/migrate/20130323045606_add_protected_to_users.rb5
-rw-r--r--db/schema.rb6
-rw-r--r--lib/receiver/worker.rb81
-rw-r--r--public/404.xhtml26
-rw-r--r--public/500.xhtml25
-rw-r--r--public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js.gzbin410 -> 0 bytes
-rw-r--r--public/assets/application-c0feb24db0871514682a56320c7b2b2b.js (renamed from public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js)5
-rw-r--r--public/assets/application-c0feb24db0871514682a56320c7b2b2b.js.gzbin0 -> 410 bytes
-rw-r--r--public/assets/manifest-53d4de075a772d1eda47ac6355907a22.json (renamed from public/assets/manifest-8b2cd06c78837f5f27435d8942b3f60f.json)2
61 files changed, 453 insertions, 285 deletions
diff --git a/Gemfile b/Gemfile
index 04b048c..808371e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
gem 'rails', '4.0.0.beta1'
gem 'mysql2'
+gem 'dalli'
gem 'unicorn'
gem 'daemon-spawn', :require => 'daemon_spawn'
@@ -18,9 +19,9 @@ group :assets do
end
gem 'haml-rails'
+gem 'jbuilder'
gem 'msgpack'
gem 'omniauth-twitter', :github => "re4k/omniauth-twitter"
gem 'em-twitter'
-gem 'twitter'
diff --git a/Gemfile.lock b/Gemfile.lock
index d6c2a46..5638adf 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -33,7 +33,7 @@ GEM
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.33)
- arel (4.0.0.beta1)
+ arel (4.0.0.beta2)
atomic (1.0.1)
builder (3.1.4)
coffee-rails (4.0.0.beta1)
@@ -42,8 +42,9 @@ GEM
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.6.1)
+ coffee-script-source (1.6.2)
daemon-spawn (0.4.2)
+ dalli (2.6.2)
em-twitter (0.2.1)
eventmachine (~> 1.0)
http_parser.rb (~> 0.5)
@@ -51,12 +52,10 @@ GEM
em-work_queue (0.0.1)
eventmachine
erubis (2.7.0)
- eventmachine (1.0.1)
+ eventmachine (1.0.3)
execjs (1.4.0)
multi_json (~> 1.0)
- faraday (0.8.6)
- multipart-post (~> 1.1)
- haml (4.0.0)
+ haml (4.0.1)
tilt
haml-rails (0.4)
actionpack (>= 3.1, < 4.1)
@@ -67,6 +66,8 @@ GEM
hike (1.2.1)
http_parser.rb (0.5.3)
i18n (0.6.4)
+ jbuilder (1.0.2)
+ activesupport (>= 3.0.0)
json (1.7.7)
kaminari (0.14.1)
actionpack (>= 3.0.0)
@@ -77,10 +78,9 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.21)
- minitest (4.6.2)
+ minitest (4.7.0)
msgpack (0.5.4)
- multi_json (1.6.1)
- multipart-post (1.2.0)
+ multi_json (1.7.2)
mysql2 (0.3.11)
oauth (0.4.7)
omniauth (1.1.3)
@@ -113,7 +113,7 @@ GEM
rake (10.0.3)
rdoc (3.12.2)
json (~> 1.4)
- sass (3.2.6)
+ sass (3.2.7)
sass-rails (4.0.0.beta1)
railties (>= 4.0.0.beta, < 5.0)
sass (>= 3.1.10)
@@ -132,15 +132,11 @@ GEM
thor (0.17.0)
thread_safe (0.1.0)
atomic
- tilt (1.3.4)
+ tilt (1.3.6)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
- twitter (4.5.0)
- faraday (~> 0.8, < 0.10)
- multi_json (~> 1.0)
- simple_oauth (~> 0.2)
- tzinfo (0.3.36)
+ tzinfo (0.3.37)
uglifier (1.3.0)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
@@ -155,9 +151,11 @@ PLATFORMS
DEPENDENCIES
coffee-rails (~> 4.0.0.beta1)
daemon-spawn
+ dalli
em-twitter
em-work_queue
haml-rails
+ jbuilder
kaminari
msgpack
mysql2
@@ -165,6 +163,5 @@ DEPENDENCIES
rails (= 4.0.0.beta1)
rails_config
sass-rails (~> 4.0.0.beta1)
- twitter
uglifier (>= 1.0.3)
unicorn
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9157caa..93eb126 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -16,16 +16,4 @@ class ApplicationController < ActionController::Base
end
return 1
end
-
- def prepare_cache
- # check
- #return unless @items
-
- #@favorite_cache = Favorite.where(@items.map{|m| "tweet_id = #{m.id}"}.join(" OR ")).sort_by{|m| m.id}.group_by{|m| m.tweet_id}
- #@retweet_cache = Retweet.where(@items.map{|m| "tweet_id = #{m.id}"}.join(" OR ")).sort_by{|m| m.id}.group_by{|m| m.tweet_id}
- #@user_cache = Hash[User.where(
- # (@items.to_a + @favorite_cache.values + @retweet_cache.values).flatten.map{|m| m.user_id}.uniq
- # .map{|m| "id = #{m}"}.join(" OR "))
- # .map{|m| [m.id, m]}]
- end
end
diff --git a/app/controllers/i_controller.rb b/app/controllers/i_controller.rb
index 74a1701..7ee38da 100644
--- a/app/controllers/i_controller.rb
+++ b/app/controllers/i_controller.rb
@@ -1,12 +1,16 @@
class IController < ApplicationController
- def show
- id = params[:id].to_i
- items = Tweet.where(:id => id)
- if items.count > 0
- @items = items.page(1)
- @title = "\"#{ApplicationController.helpers.strip_tags(ApplicationController.helpers.format_tweet_text(items.first.text))[0...30]}\" from @#{items.first.user.screen_name}"
- else
- @items = []
- end
+ def best
+ @items = Tweet
+ .reacted
+ .order_by_reactions
+ .limit(Settings.page_per)
+ end
+
+ def recent
+ @items = Tweet
+ .recent
+ .reacted
+ .order_by_reactions
+ .limit(Settings.page_per)
end
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 3a75894..20afa15 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -6,12 +6,19 @@ class SessionsController < ApplicationController
user = Account.find_or_initialize_by(:user_id => auth["uid"])
user.oauth_token = auth["credentials"]["token"]
user.oauth_token_secret = auth["credentials"]["secret"]
+ user.consumer_version = Settings.consumer_version
user.save!
session[:user_id] = user.user_id
session[:screen_name] = auth["info"]["nickname"]
- UNIXSocket.open(Settings.register_server_path) do |socket|
- socket.write({:type => "register", :id => user.id, :user_id => user.user_id}.to_msgpack)
+ begin
+ UNIXSocket.open(Settings.register_server_path) do |socket|
+ socket.write({:type => "register", :id => user.id, :user_id => user.user_id}.to_msgpack)
+ end
+ rescue Errno::ECONNREFUSED
+ # receiver not started?
+ warn $!
+ warn $@
end
redirect_to root_url
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 670c1c6..1ebb5a6 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,84 +1,83 @@
class UsersController < ApplicationController
+ def show
+ tweet_id = Integer(params[:id])
+
+ @item = Tweet.find(tweet_id)
+ @user = @item.user
+ helpers = ApplicationController.helpers
+ @title = "\"#{helpers.strip_tags(helpers.format_tweet_text(@item.text))[0...30]}\" from @#{@item.user.screen_name}"
+
+ respond_to do |format|
+ format.html do
+ prepare_info
+ end
+
+ format.json do
+ @trim_user = params[:trim_user] == "true"
+ end
+ end
+ end
+
def best
- page = get_page_number(params)
- screen_name = params[:screen_name]
- user = User.where(:screen_name => screen_name).first
- if user
- @items = user.tweets
- .where("favorites_count > 0 OR retweets_count > 0")
- .order("COALESCE(favorites_count, 0) + COALESCE(retweets_count, 0) DESC")
- .page(page)
- .per(Settings.page_per)
- else
- @items = []
+ user = render_timeline(params) do |tweets, user|
+ tweets.of(user).reacted.order_by_reactions
end
- @title = "@#{screen_name}'s Best Tweets"
+ @title = "@#{user.screen_name}'s Best Tweets"
end
def recent
- page = get_page_number(params)
- screen_name = params[:screen_name]
- user = User.where(:screen_name => screen_name).first
- if user
- @items = user.tweets
- .where("favorites_count > 0 OR retweets_count > 0")
- .order("id DESC")
- .page(page)
- .per(Settings.page_per)
- else
- @items = []
+ user = render_timeline(params) do |tweets, user|
+ tweets.of(user).recent.reacted.order_by_reactions
end
- @title = "@#{screen_name}'s Newest Favorited Tweets"
+ @title = "@#{user.screen_name}'s Recent Best Tweets"
end
def timeline
- page = get_page_number(params)
- screen_name = params[:screen_name]
- user = User.where(:screen_name => screen_name).first
- if user
- @items = user.tweets
- .order("id DESC")
- .page(page)
- .per(Settings.page_per)
- else
- @items = []
+ user = render_timeline(params) do |tweets, user|
+ if params[:tweets] == "all"
+ tweets.of(user).order_by_id
+ else
+ tweets.of(user).reacted.order_by_id
+ end
+ end
+ @title = "@#{user.screen_name}'s Newest Tweets"
+
+ if user.protected
+ raise Exception # FIXME
end
- @title = "@#{screen_name}'s Newest Tweets"
end
def my
+ user = render_timeline(params) do |tweets, user|
+ tweets.discovered(user).order_by_id
+ end
+ @title = "@#{user.screen_name}'s Recent Discoveries"
+ end
+
+ private
+ def render_timeline(params, &g)
page = get_page_number(params)
screen_name = params[:screen_name]
- user = User.where(:screen_name => screen_name).first
- if user
- @items = Tweet
- .where("id IN (SELECT tweet_id FROM (" +
- "SELECT tweet_id FROM favorites WHERE user_id = #{user.id} " +
- "UNION " +
- "SELECT tweet_id FROM retweets WHERE user_id = #{user.id}" +
- ") AS rf)")
- .order("id DESC")
- .page(page)
- .per(Settings.page_per)
- else
- @items = []
+ @user = User.where(:screen_name => screen_name).first
+ unless @user
+ raise ActiveRecord::RecordNotFound.new(screen_name)
end
- @title = "@#{screen_name}'s Recent Discoveries"
- prepare_cache
- end
- def info
- screen_name = params[:screen_name]
- user = User.where(:screen_name => screen_name).first
- if user
- @tweets_count = user.tweets.count
- @favorites_count = user.favorites.count
- @retweets_count = user.retweets.count
- @favorited_count = user.tweets.inject(0){|s, m| s + m.favorites_count}
- @retweeted_count = user.tweets.inject(0){|s, m| s + m.retweets_count}
- else
- @info = nil
+ @items = g.call(Tweet, @user)
+ .page(page)
+ .per(Settings.page_per)
+
+ respond_to do |format|
+ format.html do
+ prepare_info
+ end
+
+ format.json do
+ @trim_user = params[:trim_user] == "true"
+ end
end
+
+ return @user
end
end
diff --git a/app/models/account.rb b/app/models/account.rb
index 50229f9..31fe26d 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -1,2 +1,5 @@
class Account < ActiveRecord::Base
+ def user
+ User.cached(user_id)
+ end
end
diff --git a/app/models/favorite.rb b/app/models/favorite.rb
index c764d08..6e15dc4 100644
--- a/app/models/favorite.rb
+++ b/app/models/favorite.rb
@@ -1,4 +1,12 @@
class Favorite < ActiveRecord::Base
belongs_to :tweet, :counter_cache => true
belongs_to :user
+
+ def user
+ User.cached(user_id)
+ end
+
+ def tweet
+ Tweet.cached(tweet_id)
+ end
end
diff --git a/app/models/retweet.rb b/app/models/retweet.rb
index 34da286..296b877 100644
--- a/app/models/retweet.rb
+++ b/app/models/retweet.rb
@@ -1,4 +1,12 @@
class Retweet < ActiveRecord::Base
belongs_to :tweet, :counter_cache => true
belongs_to :user
+
+ def user
+ User.cached(user_id)
+ end
+
+ def tweet
+ Tweet.cached(tweet_id)
+ end
end
diff --git a/app/models/tweet.rb b/app/models/tweet.rb
index a1124f9..6b6311d 100644
--- a/app/models/tweet.rb
+++ b/app/models/tweet.rb
@@ -2,4 +2,42 @@ class Tweet < ActiveRecord::Base
belongs_to :user
has_many :favorites, :dependent => :delete_all
has_many :retweets, :dependent => :delete_all
+
+ scope :recent, -> do
+ where("tweeted_at > ?", Time.zone.now - 3.days)
+ end
+
+ scope :reacted, -> do
+ where("favorites_count > 0 OR retweets_count > 0")
+ end
+
+ scope :order_by_id, -> do
+ order("id DESC")
+ end
+
+ scope :order_by_reactions, -> do
+ order("COALESCE(favorites_count, 0) + COALESCE(retweets_count, 0) DESC")
+ end
+
+ scope :discovered, -> user do
+ where("id IN (" +
+ "SELECT tweet_id FROM favorites WHERE user_id = ?" +
+ " UNION ALL " +
+ "SELECT tweet_id FROM retweets WHERE user_id = ?" +
+ ")", user.id, user.id)
+ end
+
+ scope :of, -> user do
+ where("user_id = ?", user.id)
+ end
+
+ def self.cached(id)
+ Rails.cache.fetch("tweet/#{id}", :expires_in => 3.hour) do
+ where(:id => id).first
+ end
+ end
+
+ def user
+ User.cached(user_id)
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index d268fcb..b93eac9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -5,11 +5,21 @@ class User < ActiveRecord::Base
attrs = {:id => u}
end
attrs[:profile_image_url] ||= ActionController::Base.helpers.asset_path("missing_profile_image.png")
- attrs[:name] ||= "Missing: id=#{u}"
+ attrs[:name] ||= "Missing name: #{u}"
super(attrs)
end
has_many :tweets, :dependent => :delete_all
has_many :favorites, :dependent => :delete_all
has_many :retweets, :dependent => :delete_all
+
+ def self.cached(uid)
+ Rails.cache.fetch("user/#{uid}", :expires_in => 1.hour) do
+ where(:id => uid).first
+ end
+ end
+
+ def registered?
+ Account.exists?(:user_id => id)
+ end
end
diff --git a/app/views/errors/error_404.json.jbuilder b/app/views/errors/error_404.json.jbuilder
new file mode 100644
index 0000000..a58331f
--- /dev/null
+++ b/app/views/errors/error_404.json.jbuilder
@@ -0,0 +1,4 @@
+json.error do |json|
+ json.status 404
+ json.message "Not found"
+end
diff --git a/app/views/errors/error_500.json.jbuilder b/app/views/errors/error_500.json.jbuilder
new file mode 100644
index 0000000..1cb2a1b
--- /dev/null
+++ b/app/views/errors/error_500.json.jbuilder
@@ -0,0 +1,4 @@
+json.error do |json|
+ json.status 500
+ json.message "Internal error"
+end
diff --git a/app/views/i/_list.html.haml b/app/views/i/_list.html.haml
new file mode 100644
index 0000000..91a14b4
--- /dev/null
+++ b/app/views/i/_list.html.haml
@@ -0,0 +1,2 @@
+.items
+ = render :partial => "shared/tweet", :collection => @items, :as => :item
diff --git a/app/views/i/best.html.haml b/app/views/i/best.html.haml
new file mode 100644
index 0000000..1410df9
--- /dev/null
+++ b/app/views/i/best.html.haml
@@ -0,0 +1 @@
+= render :partial => "list"
diff --git a/app/views/i/recent.html.haml b/app/views/i/recent.html.haml
new file mode 100644
index 0000000..1410df9
--- /dev/null
+++ b/app/views/i/recent.html.haml
@@ -0,0 +1 @@
+= render :partial => "list"
diff --git a/app/views/i/show.haml b/app/views/i/show.haml
deleted file mode 100644
index 2672287..0000000
--- a/app/views/i/show.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render :partial => "shared/tweets", :locals => {:items => @items}
diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.html.haml
index b36d91a..5627ac7 100644
--- a/app/views/layouts/application.haml
+++ b/app/views/layouts/application.html.haml
@@ -7,7 +7,7 @@
.container
.left
%h1><
- Aclog
+ = link_to "Aclog", :controller => "main", :action => "index"
%div
- if session[:screen_name]
%span= link_to "@#{session[:screen_name]}", :controller => "users", :action => "best", :screen_name => session[:screen_name]
diff --git a/app/views/main/index.haml b/app/views/main/index.haml
deleted file mode 100644
index bf7e2eb..0000000
--- a/app/views/main/index.haml
+++ /dev/null
@@ -1,29 +0,0 @@
-%p
- %strong (´へεへ`*) < トップページだよ〜〜
-%p
- Favstar クローンです。UserStreams つかってます。
- = link_to "@KOBA789", "https://twitter.com/KOBA789"
- さんにサーバーを貸していただけることになりました…!!ありがとうございます!ありがとうございます!!!
-%strong まだ開発途中段階のものです。うごかなかったらごめんね
-%strong 動作のテスト中ですので、途中で登録をうちきったりあまりにふぁぼられ・ふぁぼりが多いユーザーの登録を削除する可能性もあります。
-%div
- URLとかについて
- %div
- best:
- = link_to "/cat", "/cat"
- %div
- recent:
- = link_to "/cat/recent", "/cat/recent"
- %div
- timeline(exclude RTs):
- = link_to "/cat/timeline", "/cat/timeline"
- %div
- discovery:
- = link_to "/cat/my", "/cat/my"
- %div
- こんどほかのところもFavstar互換にする
- %div
- API つくりたいですねハイ
-%div
- = link_to "@cat", "https://twitter.com/cat"
-
diff --git a/app/views/main/index.html.haml b/app/views/main/index.html.haml
new file mode 100644
index 0000000..dfebde1
--- /dev/null
+++ b/app/views/main/index.html.haml
@@ -0,0 +1,42 @@
+%p
+ %strong (´へεへ`*) < トップページだよ〜〜
+%p
+ Favstar クローンです。UserStreams つかってます。
+ = link_to "@KOBA789", "https://twitter.com/KOBA789"
+ さんにサーバーを貸していただけることになりました…!!ありがとうございます!ありがとうございます!!!
+%p
+ %strong まだ開発途中段階のものです。うごかなかったらごめんね
+%p
+ Read/Write 要求するけど今のところ UserStreams しか使ってないです。こんど Favstar みたいにページ内から Fav/RT できるようにしたいなあと…
+%p
+ %strong 動作のテスト中ですので、途中で登録をうちきったりあまりにふぁぼられ・ふぁぼりが多いユーザーの登録を削除する可能性もあります。
+%p
+ 登録ユーザーだったら一番下に統計(?)が表示されてるんじゃないですかね
+%div
+ URLとかについて
+ %div
+ best:
+ = link_to "/cat", "/cat"
+ %div
+ recent(最新3日のbest):
+ = link_to "/cat/recent", "/cat/recent"
+ %div
+ timeline(Favstar の Recent、ただ0Fav0RTも含む):
+ = link_to "/cat/timeline", "/cat/timeline"
+ %div
+ discovery:
+ = link_to "/cat/my", "/cat/my"
+ %div
+ %div
+ 全体のbest:
+ = link_to "/i/best", "/i/best"
+ %div
+ 全体の最新3日のbest
+ = link_to "/i/recent", "/i/recent"
+ %div
+ URL 変えちゃうかもしれないです
+ %div
+ API つくりたいですねハイ
+%div
+ = link_to "@cat", "https://twitter.com/cat"
+
diff --git a/app/views/shared/_tweet.haml b/app/views/shared/_tweet.html.haml
index 2f7adb2..e706079 100644
--- a/app/views/shared/_tweet.haml
+++ b/app/views/shared/_tweet.html.haml
@@ -15,7 +15,7 @@
%span.twitter_bird
= link_to image_tag("bird_gray_16.png", :alt => "Twitter"), twitter_status_url(item), :target => "_blank"
%span.created_at
- = link_to format_tweet_created_at(item.tweeted_at), :controller => "i", :action => "show", :id => item.id
+ = link_to format_tweet_created_at(item.tweeted_at), :controller => "users", :action => "show", :id => item.id
%span.source
= raw format_source_text(item.source)
.stats
@@ -26,7 +26,7 @@
%span.type= type
.height_fix
%ul.favoriters.clearfix
- - actions.take(params[:controller] == "i" && params[:action] == "show" ? actions.size : 20).each do |a| |
+ - actions.take(params[:controller] == "users" && params[:action] == "show" ? actions.size : 20).each do |a| |
- m = a.user || User.new
%li
- if m.screen_name
diff --git a/app/views/shared/_tweet.json.jbuilder b/app/views/shared/_tweet.json.jbuilder
new file mode 100644
index 0000000..a6c22ae
--- /dev/null
+++ b/app/views/shared/_tweet.json.jbuilder
@@ -0,0 +1,19 @@
+json.(item, :id, :text, :source, :tweeted_at, :favorites_count, :retweets_count)
+
+json.user do |json|
+ json.partial! "shared/user", :user => item.user
+end
+
+unless @trim_user
+ json.favorites item.favorites.order("id") do |json, favorite|
+ json.user do |json|
+ json.partial! "shared/user", :user => favorite.user || User.new
+ end
+ end
+ json.retweets item.retweets.order("id") do |json, retweet|
+ json.id retweet.id
+ json.user do |json|
+ json.partial! "shared/user", :user => retweet.user || User.new
+ end
+ end
+end
diff --git a/app/views/shared/_tweets.haml b/app/views/shared/_tweets.haml
deleted file mode 100644
index 681b9cc..0000000
--- a/app/views/shared/_tweets.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-.items
- = render :partial => "shared/tweet", :collection => items, :as => :item, :local => {:showallusers => @showallusers}
-- if items.size > 0
- = paginate items
diff --git a/app/views/shared/_user.json.jbuilder b/app/views/shared/_user.json.jbuilder
new file mode 100644
index 0000000..a0447c0
--- /dev/null
+++ b/app/views/shared/_user.json.jbuilder
@@ -0,0 +1,2 @@
+json.(user, :id, :screen_name, :name, :profile_image_url)
+
diff --git a/app/views/shared/_user_info.html.haml b/app/views/shared/_user_info.html.haml
new file mode 100644
index 0000000..6188bdc
--- /dev/null
+++ b/app/views/shared/_user_info.html.haml
@@ -0,0 +1,17 @@
+- if user.registered?
+ %ul
+ %li
+ Tweets:
+ = user.tweets.length
+ %li
+ Favorites:
+ = user.favorites.length
+ %li
+ Retweets:
+ = user.retweets.length
+ %li
+ Favorited:
+ = user.tweets.inject(0){|s, m| s + m.favorites_count}
+ %li
+ Retweeted:
+ = user.tweets.inject(0){|s, m| s + m.retweets_count}
diff --git a/app/views/shared/_user_nav.html.haml b/app/views/shared/_user_nav.html.haml
new file mode 100644
index 0000000..93c7d35
--- /dev/null
+++ b/app/views/shared/_user_nav.html.haml
@@ -0,0 +1,11 @@
+- if user
+ .links
+ %ul
+ %li
+ = link_to "Best", :controller => "users", :action => "best", :screen_name => user.screen_name
+ %li
+ = link_to "Recent", :controller => "users", :action => "recent", :screen_name => user.screen_name
+ %li
+ = link_to "Timeline", :controller => "users", :action => "timeline", :screen_name => user.screen_name
+ %li
+ = link_to "Discovered", :controller => "users", :action => "my", :screen_name => user.screen_name
diff --git a/app/views/users/_list.html.haml b/app/views/users/_list.html.haml
new file mode 100644
index 0000000..3147f1b
--- /dev/null
+++ b/app/views/users/_list.html.haml
@@ -0,0 +1,6 @@
+= render :partial => "shared/user_nav", :locals => {:user => @user}
+.items
+ = render :partial => "shared/tweet", :collection => @items, :as => :item
+- if @items
+ = paginate @items
+= render :partial => "shared/user_info", :locals => {:user => @user}
diff --git a/app/views/users/best.haml b/app/views/users/best.haml
deleted file mode 100644
index 2672287..0000000
--- a/app/views/users/best.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render :partial => "shared/tweets", :locals => {:items => @items}
diff --git a/app/views/users/best.html.haml b/app/views/users/best.html.haml
new file mode 100644
index 0000000..1410df9
--- /dev/null
+++ b/app/views/users/best.html.haml
@@ -0,0 +1 @@
+= render :partial => "list"
diff --git a/app/views/users/best.json.jbuilder b/app/views/users/best.json.jbuilder
new file mode 100644
index 0000000..d2637d3
--- /dev/null
+++ b/app/views/users/best.json.jbuilder
@@ -0,0 +1,4 @@
+json.array! @items do |json, item|
+ json.partial! "shared/tweet", :item => item
+end
+
diff --git a/app/views/users/info.haml b/app/views/users/info.haml
deleted file mode 100644
index e326422..0000000
--- a/app/views/users/info.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-Tweets:
- = @tweets_count
-Favorite:
- = @favorites_count
-Retweets:
- = @retweets_count
-Favorited:
- = @favorited_count
-Retweetted:
- = @retweeted_count
diff --git a/app/views/users/my.haml b/app/views/users/my.haml
deleted file mode 100644
index 2672287..0000000
--- a/app/views/users/my.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render :partial => "shared/tweets", :locals => {:items => @items}
diff --git a/app/views/users/my.html.haml b/app/views/users/my.html.haml
new file mode 100644
index 0000000..1410df9
--- /dev/null
+++ b/app/views/users/my.html.haml
@@ -0,0 +1 @@
+= render :partial => "list"
diff --git a/app/views/users/my.json.jbuilder b/app/views/users/my.json.jbuilder
new file mode 100644
index 0000000..d2637d3
--- /dev/null
+++ b/app/views/users/my.json.jbuilder
@@ -0,0 +1,4 @@
+json.array! @items do |json, item|
+ json.partial! "shared/tweet", :item => item
+end
+
diff --git a/app/views/users/recent.haml b/app/views/users/recent.haml
deleted file mode 100644
index 2672287..0000000
--- a/app/views/users/recent.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render :partial => "shared/tweets", :locals => {:items => @items}
diff --git a/app/views/users/recent.html.haml b/app/views/users/recent.html.haml
new file mode 100644
index 0000000..1410df9
--- /dev/null
+++ b/app/views/users/recent.html.haml
@@ -0,0 +1 @@
+= render :partial => "list"
diff --git a/app/views/users/recent.json.jbuilder b/app/views/users/recent.json.jbuilder
new file mode 100644
index 0000000..d2637d3
--- /dev/null
+++ b/app/views/users/recent.json.jbuilder
@@ -0,0 +1,4 @@
+json.array! @items do |json, item|
+ json.partial! "shared/tweet", :item => item
+end
+
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
new file mode 100644
index 0000000..f56e0c0
--- /dev/null
+++ b/app/views/users/show.html.haml
@@ -0,0 +1,4 @@
+= render :partial => "shared/user_nav", :locals => {:user => @user}
+.items
+ = render :partial => "shared/tweet", :locals => {:item => @item}
+= render :partial => "shared/user_info", :locals => {:user => @user}
diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder
new file mode 100644
index 0000000..049306e
--- /dev/null
+++ b/app/views/users/show.json.jbuilder
@@ -0,0 +1,2 @@
+json.partial! "shared/tweet", :item => @items.first
+
diff --git a/app/views/users/timeline.haml b/app/views/users/timeline.haml
deleted file mode 100644
index 2672287..0000000
--- a/app/views/users/timeline.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render :partial => "shared/tweets", :locals => {:items => @items}
diff --git a/app/views/users/timeline.html.haml b/app/views/users/timeline.html.haml
new file mode 100644
index 0000000..1410df9
--- /dev/null
+++ b/app/views/users/timeline.html.haml
@@ -0,0 +1 @@
+= render :partial => "list"
diff --git a/app/views/users/timeline.json.jbuilder b/app/views/users/timeline.json.jbuilder
new file mode 100644
index 0000000..d2637d3
--- /dev/null
+++ b/app/views/users/timeline.json.jbuilder
@@ -0,0 +1,4 @@
+json.array! @items do |json, item|
+ json.partial! "shared/tweet", :item => item
+end
+
diff --git a/client/settings.yml.default b/client/settings.yml.default
index 2f8e787..874e239 100644
--- a/client/settings.yml.default
+++ b/client/settings.yml.default
@@ -1,5 +1,7 @@
-consumer_key:
-consumer_secret:
+consumer:
+ -
+ - **key**
+ - **secret**
secret_key:
worker_count:
worker_number:
diff --git a/client/worker.rb b/client/worker.rb
index d4cc1cd..1ed3414 100644
--- a/client/worker.rb
+++ b/client/worker.rb
@@ -1,15 +1,9 @@
-require "time"
require "em-twitter"
require "yajl"
require "msgpack"
require "./settings"
require "./logger"
-module EM
- class Connection
- end
-end
-
class Worker
class DBProxyClient < EM::Connection
def send_object(data)
@@ -66,8 +60,8 @@ class Worker
:host => "userstream.twitter.com",
:path => "/1.1/user.json",
:oauth => {
- :consumer_key => Settings.consumer_key,
- :consumer_secret => Settings.consumer_secret,
+ :consumer_key => Settings.consumer[msg["consumer_version"].to_i].key,
+ :consumer_secret => Settings.consumer[msg["consumer_version"].to_i].secret,
:token => msg["oauth_token"],
:token_secret => msg["oauth_token_secret"]},
:method => "GET"})
@@ -77,7 +71,8 @@ class Worker
:id => user[:id],
:screen_name => user[:screen_name],
:name => user[:name],
- :profile_image_url => user[:profile_image_url_https]}
+ :profile_image_url => user[:profile_image_url_https],
+ :protected => user[:protected]}
send_object(out)
$logger.debug("User(##{account_id}/#{user_id}): #{user[:id]} = #{user[:screen_name]}")
end
@@ -123,6 +118,14 @@ class Worker
$logger.debug("Retweet(##{account_id}/#{user_id}): #{status[:user][:id]} => #{status[:retweeted_status][:id]}")
end
+ send_delete = -> deleted_status_id, deleted_user_id do
+ out = {:type => "delete",
+ :id => deleted_status_id,
+ :user_id => deleted_user_id}
+ send_object(out)
+ $logger.debug("Delete(##{account_id}/#{user_id}): #{deleted_user_id} => #{deleted_status_id}")
+ end
+
client.on_error do |message|
$logger.warn("Unknown Error(##{account_id}/#{user_id}): #{message}")
end
@@ -160,11 +163,7 @@ class Worker
elsif hash[:delete] && hash[:delete][:status]
deleted_status_id = hash[:delete][:status][:id]
deleted_user_id = hash[:delete][:status][:user_id]
- out = {:type => "delete",
- :id => deleted_status_id,
- :user_id => deleted_user_id}
- send_object(out)
- $logger.debug("Delete(##{account_id}/#{user_id}): #{deleted_user_id} => #{deleted_status_id}")
+ send_delete.call(deleted_status_id, deleted_user_id)
elsif hash[:limit]
$logger.warn("UserStreams Limit Event(##{account_id}/#{user_id}): #{hash[:limit][:track]}")
elsif hash[:event]
@@ -213,8 +212,7 @@ class Worker
def post_init
out = {:type => "init",
:secret_key => Settings.secret_key,
- :worker_number => Settings.worker_number,
- :worker_count => Settings.worker_count}
+ :worker_number => Settings.worker_number}
send_object(out)
end
@@ -228,7 +226,7 @@ class Worker
def receive_data(data)
@pac.feed_each(data) do |msg|
- unless msg["type"]
+ unless msg.is_a?(Hash) && msg["type"]
$logger.warn("Unknown data: #{msg}")
return
end
@@ -240,8 +238,17 @@ class Worker
$logger.info("error: #{msg["message"]}")
when "fatal"
$logger.info("fatal: #{msg["message"]}")
+ when "bye"
+ $logger.info("bye: #{msg["message"]}")
when "account"
- receive_account(msg)
+ begin
+ receive_account(msg)
+ rescue
+ $logger.error($!)
+ $logger.error($@)
+ end
+ else
+ $logger.info("Unknown message type: #{msg}")
end
end
end
@@ -253,7 +260,7 @@ class Worker
end
def initialize
- $logger = Aclog::Logger.new(:debug)
+ $logger = Aclog::Logger.new(:info)
end
def start
diff --git a/config/application.rb b/config/application.rb
index 7df2cca..ab8b888 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -21,5 +21,7 @@ module Aclog
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
+
+ config.exceptions_app = self.routes
end
end
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 5f95ca6..5089ff4 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -10,7 +10,7 @@ Aclog::Application.configure do
config.eager_load = false
# Show full error reports and disable caching.
- config.consider_all_requests_local = true
+ config.consider_all_requests_local = false#true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send.
@@ -24,4 +24,6 @@ Aclog::Application.configure do
# Expands the lines which load the assets.
config.assets.debug = true
+
+ # config.cache_store = :dalli_store
end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index c219686..fc529ba 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -52,7 +52,7 @@ Aclog::Application.configure do
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production.
- # config.cache_store = :mem_cache_store
+ config.cache_store = :dalli_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = "http://assets.example.com"
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index 540652c..eaee9f6 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -1,7 +1,18 @@
+OmniAuth.config.full_host = -> env do
+ scheme = env["rack.url_scheme"]
+ forwarded_host = env["HTTP_X_FORWARDED_HOST"]
+
+ host = forwarded_host.blank? ?
+ env["HTTP_HOST"] :
+ forwarded_host
+
+ "#{scheme}://#{host}"
+end
+
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter,
- Settings.consumer_key,
- Settings.consumer_secret,
+ Settings.consumer[Settings.consumer_version].key,
+ Settings.consumer[Settings.consumer_version].secret,
:request_path => "/i/login",
:callback_path => "/i/callback"
end
diff --git a/config/routes.rb b/config/routes.rb
index a7b879f..66a28c7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,18 +4,31 @@ Aclog::Application.routes.draw do
:screen_name => /[a-zA-Z0-9_]{1,20}/,
:page => /[0-9]+/,
}
+ get "/404" => "errors#error_404"
+ get "/500" => "errors#error_500"
root :to => "main#index"
- get "i/callback" => "sessions#callback"
- get "i/logout" => "sessions#destroy"
-
- get "i/:id" => "i#show", :constraints => constraints
- get ":screen_name/status(es)/:id" => "i#show", :constraints => constraints
-
- get ":screen_name(/:page)" => "users#best", :constraints => constraints
- get ":screen_name/my(/:page)" => "users#my", :constraints => constraints
- get ":screen_name/discovered(/:page)" => "users#my", :constraints => constraints
- get ":screen_name/timeline(/:page)" => "users#timeline", :constraints => constraints
- get ":screen_name/recent(/:page)" => "users#recent", :constraints => constraints
- get ":screen_name/info(/:page)" => "users#info", :constraints => constraints
+
+ get "/i/callback" => "sessions#callback"
+ get "/i/logout" => "sessions#destroy"
+
+ get "/i/best" => "i#best"
+ get "/i/recent" => "i#recent"
+
+ get "/i/:id" => "users#show", :constraints => constraints
+ get "/(users)/:screen_name/status(es)/:id" => redirect("/i/%{id}")
+
+ get "/:screen_name(/:page)" => "users#best", :constraints => constraints
+ get "/:screen_name/best" => redirect("/%{screen_name}")
+ get "/users/:screen_name" => redirect("/%{screen_name}")
+
+ get "/:screen_name/discovered(/:page)" => "users#my", :constraints => constraints
+ get "/:screen_name/my(/:page)" => "users#my", :constraints => constraints
+ get "/users/:screen_name/discovered" => redirect("/%{screen_name}/discovered")
+
+ get "/:screen_name/timeline(/:page)" => "users#timeline", :constraints => constraints
+ get "/:screen_name/timeline/all(/:page)" => "users#timeline", :constraints => constraints, :defaults => {:tweets => "all"}
+ get "/users/:screen_name/recent" => redirect("/%{screen_name}/timeline")
+
+ get "/:screen_name/recent(/:page)" => "users#recent", :constraints => constraints
end
diff --git a/config/settings.yml b/config/settings.yml
index c165051..8c3650f 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -1,5 +1,7 @@
-consumer_key: <%= ENV["CONSUMER_KEY"] %>
-consumer_secret: <%= ENV["CONSUMER_SECRET"] %>
+#consumer:
+# - key: <%= ENV["CONSUMER_KEY"] %>
+# secret: <%= ENV["CONSUMER_SECRET"] %>
+consumer_version: 1
page_per: <%= ENV["ACLOG_PAGE_PER"] %>
worker_count: <%= ENV["ACLOG_WORKER_COUNT"] %>
secret_key: <%= ENV["ACLOG_SECRET_KEY"] %>
diff --git a/db/migrate/20130322152541_add_user_id_index_to_events.rb b/db/migrate/20130322152541_add_user_id_index_to_events.rb
new file mode 100644
index 0000000..8543185
--- /dev/null
+++ b/db/migrate/20130322152541_add_user_id_index_to_events.rb
@@ -0,0 +1,6 @@
+class AddUserIdIndexToEvents < ActiveRecord::Migration
+ def change
+ add_index :favorites, :user_id
+ add_index :retweets, :user_id
+ end
+end
diff --git a/db/migrate/20130322171251_add_column_consumer_version_to_accounts.rb b/db/migrate/20130322171251_add_column_consumer_version_to_accounts.rb
new file mode 100644
index 0000000..747287b
--- /dev/null
+++ b/db/migrate/20130322171251_add_column_consumer_version_to_accounts.rb
@@ -0,0 +1,5 @@
+class AddColumnConsumerVersionToAccounts < ActiveRecord::Migration
+ def change
+ add_column :accounts, :consumer_version, :integer
+ end
+end
diff --git a/db/migrate/20130323045606_add_protected_to_users.rb b/db/migrate/20130323045606_add_protected_to_users.rb
new file mode 100644
index 0000000..dcc85f6
--- /dev/null
+++ b/db/migrate/20130323045606_add_protected_to_users.rb
@@ -0,0 +1,5 @@
+class AddProtectedToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :protected, :boolean
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4ec571b..d8b9299 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20130226151042) do
+ActiveRecord::Schema.define(version: 20130323045606) do
create_table "accounts", force: true do |t|
t.integer "user_id", limit: 8, null: false
@@ -19,6 +19,7 @@ ActiveRecord::Schema.define(version: 20130226151042) do
t.string "oauth_token_secret", null: false
t.datetime "created_at"
t.datetime "updated_at"
+ t.integer "consumer_version"
end
add_index "accounts", ["user_id"], name: "index_accounts_on_user_id", unique: true
@@ -30,6 +31,7 @@ ActiveRecord::Schema.define(version: 20130226151042) do
add_index "favorites", ["tweet_id", "user_id"], name: "index_favorites_on_tweet_id_and_user_id", unique: true
add_index "favorites", ["tweet_id"], name: "index_favorites_on_tweet_id"
+ add_index "favorites", ["user_id"], name: "index_favorites_on_user_id"
create_table "retweets", force: true do |t|
t.integer "tweet_id", limit: 8, null: false
@@ -37,6 +39,7 @@ ActiveRecord::Schema.define(version: 20130226151042) do
end
add_index "retweets", ["tweet_id"], name: "index_retweets_on_tweet_id"
+ add_index "retweets", ["user_id"], name: "index_retweets_on_user_id"
create_table "tweets", force: true do |t|
t.text "text", null: false
@@ -53,6 +56,7 @@ ActiveRecord::Schema.define(version: 20130226151042) do
t.text "profile_image_url"
t.datetime "created_at"
t.datetime "updated_at"
+ t.boolean "protected"
end
add_index "users", ["screen_name"], name: "index_users_on_screen_name"
diff --git a/lib/receiver/worker.rb b/lib/receiver/worker.rb
index b22d410..87b55da 100644
--- a/lib/receiver/worker.rb
+++ b/lib/receiver/worker.rb
@@ -27,7 +27,8 @@ class Receiver::Worker < DaemonSpawn::Base
:id => account.id,
:oauth_token => account.oauth_token,
:oauth_token_secret => account.oauth_token_secret,
- :user_id => account.user_id}
+ :user_id => account.user_id,
+ :consumer_version => account.consumer_version.to_i}
send_object(out)
end
@@ -43,13 +44,13 @@ class Receiver::Worker < DaemonSpawn::Base
def unbind
$connections.delete_if{|k, v| v == self}
- $logger.info("Connection closed: #{@worker_number}")
+ $logger.info("Connection closed(#{@worker_number})")
end
def receive_data(data)
@pac.feed_each(data) do |msg|
- unless msg["type"]
- $logger.error("???: #{msg}")
+ unless msg.is_a?(Hash) && msg["type"]
+ $logger.error("???(#{@worker_number}): #{msg}")
send_object({:type => "fatal", :message => "Unknown data"})
close_connection_after_writing
return
@@ -80,7 +81,7 @@ class Receiver::Worker < DaemonSpawn::Base
when "quit"
receive_quit(msg)
else
- $logger.warn("Unknown message type: #{msg["type"]}")
+ $logger.warn("Unknown message type(#{@worker_number}): #{msg["type"]}")
send_object({:type => "error", :message => "Unknown message type: #{msg["type"]}"})
end
end
@@ -90,7 +91,7 @@ class Receiver::Worker < DaemonSpawn::Base
secret_key = msg["secret_key"]
worker_number = msg["worker_number"]
unless secret_key == Settings.secret_key
- $logger.error("Invalid secret_key: #{secret_key}")
+ $logger.error("Invalid secret_key(?:#{worker_number}): #{secret_key}")
send_object({:type => "fatal", :message => "Invalid secret_key"})
close_connection_after_writing
return
@@ -98,52 +99,59 @@ class Receiver::Worker < DaemonSpawn::Base
$connections[worker_number] = self
@worker_number = worker_number
@authorized = true
- $logger.info("Connected: #{worker_number}")
+ $logger.info("Connected(#{@worker_number})")
send_object({:type => "ok", :message => "Connected"})
send_account_all
end
def receive_unauthorized(msg)
- $logger.warn("Unauthorized: #{msg["user_id"]}")
+ $logger.warn("Unauthorized(#{@worker_number}): #{msg["user_id"]}")
# unregister
end
def receive_user(msg)
@@wq.push -> do
- $logger.debug("Received User")
- rec = User.find_or_initialize_by(:id => msg["id"])
- rec.screen_name = msg["screen_name"]
- rec.name = msg["name"]
- rec.profile_image_url = msg["profile_image_url"]
- rec.save! if rec.changed?
+ $logger.debug("Received User(#{@worker_number}): #{msg["id"]}")
+ begin
+ rec = User.find_or_initialize_by(:id => msg["id"])
+ rec.screen_name = msg["screen_name"]
+ rec.name = msg["name"]
+ rec.profile_image_url = msg["profile_image_url"]
+ rec.protected = msg["protected"]
+ rec.save! if rec.changed?
+ rescue
+ $logger.error("Unknown error while inserting user: #{$!}/#{$@}")
+ end
end
end
def receive_tweet(msg)
@@wq.push -> do
- $logger.debug("Received Tweet")
+ $logger.debug("Received Tweet(#{@worker_number}): #{msg["id"]}")
begin
Tweet.create!(:id => msg["id"],
:text => msg["text"],
:source => msg["source"],
:tweeted_at => Time.parse(msg["tweeted_at"]),
:user_id => msg["user_id"])
- $logger.debug("Saved Tweet")
rescue ActiveRecord::RecordNotUnique
- $logger.info("Can't Save Tweet: Duplicate")
+ $logger.debug("Duplicate Tweet(#{@worker_number}): #{msg["id"]}")
+ rescue
+ $logger.error("Unknown error while inserting tweet: #{$!}/#{$@}")
end
end
end
def receive_favorite(msg)
@@wq.push -> do
- $logger.debug("Received Favorite")
+ $logger.debug("Receive Favorite(#{@worker_number}): #{msg["user_id"]} => #{msg["tweet_id"]}")
begin
Favorite.create!(:tweet_id => msg["tweet_id"],
:user_id => msg["user_id"])
- $logger.debug("Saved Favorite")
rescue ActiveRecord::RecordNotUnique
- $logger.info("Can't Save Tweet: Duplicate")
+ $logger.debug("Duplicate Favorite(#{@worker_number}): #{msg["id"]}")
+ rescue
+ $logger.error("Unknown error while inserting favorite: #{$!}/#{$@}")
end
end
end
@@ -155,29 +163,36 @@ class Receiver::Worker < DaemonSpawn::Base
Retweet.create!(:id => msg["id"],
:tweet_id => msg["tweet_id"],
:user_id => msg["user_id"])
- $logger.debug("Saved Retweet")
rescue ActiveRecord::RecordNotUnique
- $logger.info("Can't Save Retweet: Duplicate")
+ $logger.debug("Duplicate Retweet(#{@worker_number}): #{msg["id"]}")
+ rescue
+ $logger.error("Unknown error while inserting retweet: #{$!}/#{$@}")
end
end
end
def receive_delete(msg)
@@wq.push -> do
- if msg["id"]
- Tweet.where(:id => msg["id"]).destroy_all
- Retweet.where(:id => msg["id"]).destroy_all
- elsif msg["tweet_id"]
- Favorite
- .where("tweet_id = #{msg["tweet_id"]} AND user_id = #{msg["user_id"]}")
- .destroy_all
+ begin
+ if msg["id"]
+ $logger.debug("Receive Delete(#{@worker_number}): #{msg["id"]}")
+ Tweet.where(:id => msg["id"]).destroy_all
+ Retweet.where(:id => msg["id"]).destroy_all
+ elsif msg["tweet_id"]
+ $logger.debug("Receive Unfavorite(#{@worker_number}): #{msg["user_id"]} => #{msg["tweet_id"]}")
+ Favorite
+ .where("tweet_id = #{msg["tweet_id"]} AND user_id = #{msg["user_id"]}")
+ .destroy_all
+ end
+ rescue
+ $logger.error("Unknown error while deleting: #{$!}/#{$@}")
end
end
end
def receive_quit(msg)
- $logger.warn("Quit: #{@worker_number}")
- send_data({:type => "ok", :message => "Bye"})
+ $logger.warn("Quit(#{@worker_number}): #{msg["reason"]}")
+ send_data({:type => "bye", :message => "Bye"})
close_connection_after_writing
end
end
@@ -225,8 +240,8 @@ class Receiver::Worker < DaemonSpawn::Base
end
def initialize(opts = {})
- #super(opts)
- $logger = Receiver::Logger.new(:debug)
+ super(opts)
+ $logger = Receiver::Logger.new(:info)
$connections = {}
end
diff --git a/public/404.xhtml b/public/404.xhtml
deleted file mode 100644
index 9a48320..0000000
--- a/public/404.xhtml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>The page you were looking for doesn't exist (404)</title>
- <style type="text/css">
- body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 25em;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
- </style>
-</head>
-
-<body>
- <!-- This file lives in public/404.html -->
- <div class="dialog">
- <h1>The page you were looking for doesn't exist.</h1>
- <p>You may have mistyped the address or the page may have moved.</p>
- </div>
-</body>
-</html>
diff --git a/public/500.xhtml b/public/500.xhtml
deleted file mode 100644
index f3648a0..0000000
--- a/public/500.xhtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>We're sorry, but something went wrong (500)</title>
- <style type="text/css">
- body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 25em;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
- </style>
-</head>
-
-<body>
- <!-- This file lives in public/500.html -->
- <div class="dialog">
- <h1>We're sorry, but something went wrong.</h1>
- </div>
-</body>
-</html>
diff --git a/public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js.gz b/public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js.gz
deleted file mode 100644
index a70851a..0000000
--- a/public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js.gz
+++ /dev/null
Binary files differ
diff --git a/public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js b/public/assets/application-c0feb24db0871514682a56320c7b2b2b.js
index a6f3663..d287f32 100644
--- a/public/assets/application-47a9a60feaec5625a9c66b1c985a1179.js
+++ b/public/assets/application-c0feb24db0871514682a56320c7b2b2b.js
@@ -1,27 +1,22 @@
(function() {
-
}).call(this);
(function() {
-
}).call(this);
(function() {
-
}).call(this);
(function() {
-
}).call(this);
(function() {
-
}).call(this);
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
diff --git a/public/assets/application-c0feb24db0871514682a56320c7b2b2b.js.gz b/public/assets/application-c0feb24db0871514682a56320c7b2b2b.js.gz
new file mode 100644
index 0000000..b820f5f
--- /dev/null
+++ b/public/assets/application-c0feb24db0871514682a56320c7b2b2b.js.gz
Binary files differ
diff --git a/public/assets/manifest-8b2cd06c78837f5f27435d8942b3f60f.json b/public/assets/manifest-53d4de075a772d1eda47ac6355907a22.json
index 7803527..db1f481 100644
--- a/public/assets/manifest-8b2cd06c78837f5f27435d8942b3f60f.json
+++ b/public/assets/manifest-53d4de075a772d1eda47ac6355907a22.json
@@ -1 +1 @@
-{"files":{"bird_gray_16-93f51980875017e26744056b62aaac22.png":{"logical_path":"bird_gray_16.png","mtime":"2013-03-09T14:41:39+09:00","size":1106,"digest":"93f51980875017e26744056b62aaac22"},"missing_profile_image-d5d708680693a18615dfb8f5b1a5a96c.png":{"logical_path":"missing_profile_image.png","mtime":"2013-03-16T16:45:26+09:00","size":9350,"digest":"d5d708680693a18615dfb8f5b1a5a96c"},"rails-bc7d436ef8afbf0f88829742a43ba3a4.png":{"logical_path":"rails.png","mtime":"2013-02-25T21:20:52+09:00","size":6646,"digest":"bc7d436ef8afbf0f88829742a43ba3a4"},"application-47a9a60feaec5625a9c66b1c985a1179.js":{"logical_path":"application.js","mtime":"2013-03-09T01:51:23+09:00","size":743,"digest":"47a9a60feaec5625a9c66b1c985a1179"},"application-8ad8039145e9fbab6b0de0f554e4487b.css":{"logical_path":"application.css","mtime":"2013-03-16T18:11:28+09:00","size":3584,"digest":"8ad8039145e9fbab6b0de0f554e4487b"}},"assets":{"bird_gray_16.png":"bird_gray_16-93f51980875017e26744056b62aaac22.png","missing_profile_image.png":"missing_profile_image-d5d708680693a18615dfb8f5b1a5a96c.png","rails.png":"rails-bc7d436ef8afbf0f88829742a43ba3a4.png","application.js":"application-47a9a60feaec5625a9c66b1c985a1179.js","application.css":"application-8ad8039145e9fbab6b0de0f554e4487b.css"}} \ No newline at end of file
+{"files":{"bird_gray_16-93f51980875017e26744056b62aaac22.png":{"logical_path":"bird_gray_16.png","mtime":"2013-03-09T14:41:39+09:00","size":1106,"digest":"93f51980875017e26744056b62aaac22"},"missing_profile_image-d5d708680693a18615dfb8f5b1a5a96c.png":{"logical_path":"missing_profile_image.png","mtime":"2013-03-16T16:45:26+09:00","size":9350,"digest":"d5d708680693a18615dfb8f5b1a5a96c"},"rails-bc7d436ef8afbf0f88829742a43ba3a4.png":{"logical_path":"rails.png","mtime":"2013-02-25T21:20:52+09:00","size":6646,"digest":"bc7d436ef8afbf0f88829742a43ba3a4"},"application-c0feb24db0871514682a56320c7b2b2b.js":{"logical_path":"application.js","mtime":"2013-03-09T01:51:23+09:00","size":738,"digest":"c0feb24db0871514682a56320c7b2b2b"},"application-8ad8039145e9fbab6b0de0f554e4487b.css":{"logical_path":"application.css","mtime":"2013-03-16T18:11:28+09:00","size":3584,"digest":"8ad8039145e9fbab6b0de0f554e4487b"}},"assets":{"bird_gray_16.png":"bird_gray_16-93f51980875017e26744056b62aaac22.png","missing_profile_image.png":"missing_profile_image-d5d708680693a18615dfb8f5b1a5a96c.png","rails.png":"rails-bc7d436ef8afbf0f88829742a43ba3a4.png","application.js":"application-c0feb24db0871514682a56320c7b2b2b.js","application.css":"application-8ad8039145e9fbab6b0de0f554e4487b.css"}} \ No newline at end of file