aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/application_controller.rb86
-rw-r--r--app/controllers/i_controller.rb13
-rw-r--r--app/controllers/users_controller.rb180
-rw-r--r--app/helpers/application_helper.rb18
-rw-r--r--app/models/tweet.rb18
-rw-r--r--app/views/main/index.html.haml8
-rw-r--r--app/views/shared/_tweet.html.haml4
-rw-r--r--app/views/shared/_tweet.json.jbuilder30
-rw-r--r--app/views/shared/tweets.html.haml13
-rw-r--r--app/views/users/show.json.jbuilder2
10 files changed, 188 insertions, 184 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 4973e08..c0af3c8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,64 +1,35 @@
# -*- coding: utf-8 -*-
class ApplicationController < ActionController::Base
protect_from_forgery
- before_filter :set_format, :get_include_user, :get_include_user_stats
+ before_filter :set_format
after_filter :xhtml
-
- def set_format
- unless request.format == :json || request.format == :html
- request.format = :html
- end
- end
-
- def xhtml
- if request.format == :html
- response.content_type = "application/xhtml+xml"
-
- # remove invalid charactors
- response.body = response.body.gsub(/[\x0-\x8\xb\xc\xe-\x1f]/, "")
- end
- end
-
- def get_include_user
- @include_user ||= get_bool(params[:include_user])
- end
-
- def get_include_user_stats
- if @include_user_stats ||= get_bool(params[:include_user_stats])
- @include_user = true
- end
- end
-
- def render_page(a = nil, &blk)
- @items = (a || blk.call).page(page || 1).per(count)
- @page_param = true
-
- render "shared/tweets"
- end
+ before_filter :get_include_user
def render_timeline(a = nil, &blk)
@items = a || blk.call
- if max_id
- @items = @items.where("tweets.id <= ?", max_id)
- end
+ @items = @items.where("tweets.id <= ?", max_id) if max_id
+ @items = @items.where("tweets.id > ?", since_id) if since_id
- if since_id
- @items = @items.where("tweets.id > ?", since_id)
+ if @force_page || page
+ @items = @items.page(page || 1).per(count)
+ else
+ @items = @items.limit(count)
end
- @items = @items.page(1).per(count)
-
render "shared/tweets"
end
+ # params
def page; get_int(params[:page], nil){|i| i > 0} end
-
def count; get_int(params[:count], 10){|i| (1..100) === i} end
-
def max_id; get_int(params[:max_id], nil){|i| i >= 0} end
-
def since_id; get_int(params[:since_id], nil){|i| i >= 0} end
+ def user_limit; get_int(params[:limit], 20){|i| i >= 0} end
+
+ def force_page
+ @force_page = true
+ end
def order
case params[:order]
@@ -71,21 +42,32 @@ class ApplicationController < ActionController::Base
end
end
- def all; get_bool(params[:all]) end
+ private
+ def set_format
+ unless [:json, :html].include?(request.format.to_sym)
+ request.format = :html
+ end
+ end
+
+ def xhtml
+ if request.format == :html
+ response.content_type = "application/xhtml+xml"
+
+ # remove invalid charactors
+ response.body = response.body.gsub(/[\x0-\x8\xb\xc\xe-\x1f]/, "")
+ end
+ end
- def full; get_bool(params[:full]) end
+ def get_include_user
+ @include_user ||= get_bool(params[:include_user])
+ end
- private
def get_bool(str)
- if /^(t.*|1)$/ =~ str
- true
- else
- false
- end
+ /^(t|true|1)$/ =~ str
end
def get_int(str, default = 0, &blk)
- if str =~ /^\d+$/
+ if str =~ /^[1-9]\d*$/
i = str.to_i
if !block_given? || blk.call(i)
return i
diff --git a/app/controllers/i_controller.rb b/app/controllers/i_controller.rb
index 89a887c..46c66b4 100644
--- a/app/controllers/i_controller.rb
+++ b/app/controllers/i_controller.rb
@@ -1,22 +1,26 @@
class IController < ApplicationController
+ before_filter :force_page, :only => [:best, :recent]
+
def best
@title = "Best Tweets"
- render_page do
+ render_timeline do
Tweet
.reacted
- .order_by_reactions
+ .not_protected
.original
+ .order_by_reactions
end
end
def recent
@title = "Recent Best Tweets"
- render_page do
+ render_timeline do
Tweet
.recent
.reacted
- .order_by_reactions
+ .not_protected
.original
+ .order_by_reactions
end
end
@@ -25,6 +29,7 @@ class IController < ApplicationController
render_timeline do
Tweet
.reacted
+ .not_protected
.order_by_id
end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index aeda688..dbd1206 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,10 +1,13 @@
class UsersController < ApplicationController
- before_filter :get_user, :except => [:show, :favoriters]
- before_filter :get_user_b
+ before_filter :force_page, :only => [:best, :recent]
+ before_filter :require_user, :except => [:show, :favoriters]
+ before_filter :include_user_b, :only => [:favorited_by, :retweeted_by, :given_favorites_to, :given_retweets_to]
+ after_filter :check_protected
def best
@title = "@#{@user.screen_name}'s Best Tweets"
- render_page do
+
+ render_timeline do
case order
when :favorite
@user.tweets.reacted.order_by_favorites
@@ -18,7 +21,8 @@ class UsersController < ApplicationController
def recent
@title = "@#{@user.screen_name}'s Recent Best Tweets"
- render_page do
+
+ render_timeline do
case order
when :favorite
@user.tweets.recent.reacted.order_by_favorites
@@ -31,11 +35,10 @@ class UsersController < ApplicationController
end
def timeline
- raise Aclog::Exceptions::UserProtected if @user.protected
-
@title = "@#{@user.screen_name}'s Newest Tweets"
+
render_timeline do
- if all
+ if get_bool(params[:all])
@user.tweets.order_by_id
else
@user.tweets.reacted.order_by_id
@@ -45,6 +48,7 @@ class UsersController < ApplicationController
def discovered
@title = "@#{@user.screen_name}'s Recent Discoveries"
+
render_timeline do
case params[:tweets]
when /^fav/
@@ -58,59 +62,42 @@ class UsersController < ApplicationController
end
def info
- raise Aclog::Exceptions::UserNotRegistered unless @user.account
+ raise Aclog::Exceptions::UserNotRegistered unless @user.registered?
@title = "@#{@user.screen_name} (#{@user.name})'s Profile"
- respond_to do |format|
- format.html
- format.json do
- @include_user_stats = true
- end
- end
+ @include_user_stats = true
end
def favorited_by
if @user_b
- @title = "@#{@user.screen_name}'s Tweets"
- render_timeline(@user.tweets.favorited_by(@user_b).order_by_id)
+ render_user_to_user
else
- @title = "Who Favorited @#{@user.screen_name}"
- @event_type = "favs"
- render_users_by(:favorite)
+ render_users_ranking
end
end
def retweeted_by
if @user_b
- @title = "@#{@user.screen_name}'s Tweets"
- render_timeline(@user.tweets.retweeted_by(@user_b).order_by_id)
+ render_user_to_user
else
- @title = "Who Retweeted @#{@user.screen_name}"
- @event_type = "retweets"
- render_users_by(:retweet)
+ render_users_ranking
end
end
def given_favorites_to
if @user_b
- @title = "@#{@user_b.screen_name}'s Tweets"
- render_timeline(@user_b.tweets.favorited_by(@user).order_by_id)
+ render_user_to_user
else
- @title = "@#{@user.screen_name}'s Favorites"
- @event_type = "favs"
- render_users_to(:favorite)
+ render_users_ranking
end
end
def given_retweets_to
if @user_b
- @title = "@#{@user_b.screen_name}'s Tweets"
- render_timeline(@user_b.tweets.retweeted_by(@user).order_by_id)
+ render_user_to_user
else
- @title = "@#{@user.screen_name}'s Retweets"
- @event_type = "retweets"
- render_users_to(:retweet)
+ render_users_ranking
end
end
@@ -130,15 +117,7 @@ class UsersController < ApplicationController
@title = "\"#{helpers.strip_tags(helpers.format_tweet_text(@item.text))[0...30]}\" from @#{@user.screen_name}"
@title_b = "@#{@user.screen_name}'s Tweet"
- respond_to do |format|
- format.html do
- @full = full
- end
-
- format.json do
- render "shared/_tweet", :locals => {:item => @item}
- end
- end
+ @full = get_bool(params[:full])
end
# only json
@@ -152,43 +131,63 @@ class UsersController < ApplicationController
end
private
- def render_users_by(event)
- case event
- when :favorite
- pr = -> tweet{tweet.favorites}
- when :retweet
- pr = -> tweet{tweet.retweets}
- end
-
- @usermap = @user.tweets
- .order_by_id
- .limit(100)
- .inject(Hash.new(0)){|hash, tweet| pr.call(tweet).each{|event| hash[event.user_id] += 1}; hash}
- .sort_by{|id, count| -count}
+ def render_users_ranking
+ by = -> model do
+ model.joins(
+ "INNER JOIN (" +
+ "SELECT id FROM tweets WHERE tweets.user_id = #{@user.id} ORDER BY id DESC LIMIT 100" +
+ ") target ON tweet_id = target.id")
+ end
- render "shared/users"
- end
+ to = -> model do
+ Tweet.joins(
+ "INNER JOIN (" +
+ "SELECT tweet_id FROM #{model.table_name} WHERE #{model.table_name}.user_id = #{@user.id} ORDER BY id DESC LIMIT 500" +
+ ") action ON tweets.id = action.tweet_id")
+ end
- def render_users_to(event)
- case event
- when :favorite
- es = @user.favorites
- when :retweet
- es = @user.retweets
+ case params[:action].to_sym
+ when :favorited_by
+ @title = "Who Favorited @#{@user.screen_name}"
+ users_object = by.call(Favorite)
+ when :retweeted_by
+ @title = "Who Retweeted @#{@user.screen_name}"
+ users_object = by.call(Retweet)
+ when :given_favorites_to
+ @title = "@#{@user.screen_name}'s Favorites"
+ users_object = to.call(Favorite)
+ when :given_retweets_to
+ @title = "@#{@user.screen_name}'s Retweets"
+ users_object = to.call(Retweet)
end
- @usermap = es
- .order_by_id
- .limit(500)
- .map{|e| Tweet.cached(e.tweet_id)}
- .compact
- .inject(Hash.new(0)){|hash, tweet| hash[tweet.user_id] += 1; hash}
- .sort_by{|user_id, count| -count}
+ @usermap = users_object
+ .inject(Hash.new(0)){|hash, obj| hash[obj.user_id] += 1; hash}
+ .sort_by{|id, count| -count}
render "shared/users"
end
- def get_user
+ def render_user_to_user
+ render_timeline do
+ case params[:action].to_sym
+ when :favorited_by
+ @title = "@#{@user.screen_name}'s Tweets"
+ @user.tweets.favorited_by(@user_b).order_by_id
+ when :retweeted_by
+ @title = "@#{@user.screen_name}'s Tweets"
+ @user.tweets.retweeted_by(@user_b).order_by_id
+ when :given_favorites_to
+ @title = "@#{@user_b.screen_name}'s Tweets"
+ @user_b.tweets.favorited_by(@user).order_by_id
+ when :given_retweets_to
+ @title = "@#{@user_b.screen_name}'s Tweets"
+ @user_b.tweets.retweeted_by(@user).order_by_id
+ end
+ end
+ end
+
+ def require_user
if params[:screen_name] == "me"
if session[:user_id]
params[:user_id] = session[:user_id]
@@ -198,34 +197,35 @@ class UsersController < ApplicationController
end
if params[:user_id]
- #@user = User.cached(params[:user_id].to_i)
- @user = User.cached(params[:user_id].to_i)
+ user = User.cached(params[:user_id].to_i)
end
- if !@user && params[:screen_name]
- #@user = User.where(:screen_name => params[:screen_name]).first
- @user = User.cached(params[:screen_name])
+ if !user && params[:screen_name]
+ user = User.cached(params[:screen_name])
end
- raise Aclog::Exceptions::UserNotFound unless @user
- raise Aclog::Exceptions::UserNotRegistered if @user.protected? && !@user.registered?
+ raise Aclog::Exceptions::UserNotFound unless user
+
+ @user = user
end
- def get_user_b
- if params[:screen_name_b] == "me"
- if session[:user_id]
- params[:user_id_b] = session[:user_id]
- else
- raise Aclog::Exceptions::LoginRequired
- end
+ def include_user_b
+ if params[:user_id_b]
+ user_b = User.cached(params[:user_id_b].to_i)
end
- if params[:user_id_b]
- @user_b = User.cached(params[:user_id_b].to_i)
+ if !user_b && params[:screen_name_b]
+ user_b = User.where(:screen_name => params[:screen_name_b]).first
end
- if !@user_b && params[:screen_name_b]
- @user_b = User.where(:screen_name => params[:screen_name_b]).first
+ @user_b = user_b
+ end
+
+ def check_protected
+ if @user && @user.protected? && !@user.registered?
+ unless session[:account] && session[:account].user_id == @user.id
+ raise Aclog::Exceptions::UserProtected if @user.protected
+ end
end
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 149b814..1ce3b7b 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -39,9 +39,21 @@ module ApplicationHelper
link_to(body, :controller => "users", :action => "best", :screen_name => screen_name)
end
- # _tweet
- def show_count(c)
- params[:action] == "show" ? (@full ? c : 100) : 20
+ def user_limit
+ i = params[:limit].to_i
+ if i == 0
+ if params[:action] == "show"
+ if params[:full] == "true"
+ return nil
+ else
+ return 100
+ end
+ else
+ return 20
+ end
+ else
+ return i
+ end
end
# utf8
diff --git a/app/models/tweet.rb b/app/models/tweet.rb
index cc30889..98b4f84 100644
--- a/app/models/tweet.rb
+++ b/app/models/tweet.rb
@@ -1,8 +1,8 @@
class Tweet < ActiveRecord::Base
belongs_to :user
- has_many :favorites, :dependent => :delete_all
- has_many :retweets, :dependent => :delete_all
+ has_many :favorites, ->{order("favorites.id")}, :dependent => :delete_all
+ has_many :retweets, ->{order("retweets.id")}, :dependent => :delete_all
has_many :favoriters, ->{order("favorites.id")}, :through => :favorites, :source => :user
has_many :retweeters, ->{order("retweets.id")}, :through => :retweets, :source => :user
@@ -10,23 +10,23 @@ class Tweet < ActiveRecord::Base
has_one :original, :through => :stolen_tweet, :source => :original
scope :recent, -> do
- where("tweeted_at > ?", Time.zone.now - 3.days)
+ where("tweets.tweeted_at > ?", Time.zone.now - 3.days)
end
scope :reacted, -> do
- where("favorites_count > 0 OR retweets_count > 0")
+ where("tweets.favorites_count > 0 OR tweets.retweets_count > 0")
end
scope :order_by_id, -> do
- order("id DESC")
+ order("tweets.id DESC")
end
scope :order_by_favorites, -> do
- order("favorites_count DESC")
+ order("tweets.favorites_count DESC")
end
scope :order_by_retweets, -> do
- order("retweets_count DESC")
+ order("tweets.retweets_count DESC")
end
scope :order_by_reactions, -> do
@@ -53,6 +53,10 @@ class Tweet < ActiveRecord::Base
joins("LEFT JOIN stolen_tweets ON tweets.id = stolen_tweets.tweet_id").where(:stolen_tweets => {:tweet_id => nil})
end
+ scope :not_protected, -> do
+ includes(:user).where(:users => {:protected => false})
+ end
+
def self.cached(id)
Rails.cache.fetch("tweet/#{id}", :expires_in => 3.hour) do
where(:id => id).first
diff --git a/app/views/main/index.html.haml b/app/views/main/index.html.haml
index 02d5b2b..7e1bbf2 100644
--- a/app/views/main/index.html.haml
+++ b/app/views/main/index.html.haml
@@ -4,8 +4,6 @@
%p
UserStreams で登録ユーザーのふぁぼり・ふぁぼられ・RTを集めて表示するサービスです。あんふぁぼも反映されます。
%p
- Favstar を参考に開発しています。現時点でトロフィー以外の機能はすべて使えるはずです。
-%p
API も提供する予定です。about → api を見てください(まだ開発中であり、変更がある可能性もあります)
.alert
(04/04) 諸事情でアプリケーションを作り直しました。再認証(logout → login)すると新しいトークンで上書きされます。
@@ -13,14 +11,16 @@
= link_to "アプリ連携", "https://twitter.com/settings/applications"
から不要な "AcLog" と "Aclog2" は解除しても大丈夫です。
%h4
- 今後の予定(2013/04/04)
+ 今後の予定(2013/04/16)
%ul
+ %li ふぁぼ爆撃対策: TLふぁぼり(エタフォ)・ユーザーTLふぁぼり(fav2you)対策
%li 通知を細かく設定できるように
%li パクリツイート対策
%li ふぁぼったー・Favstar からのデータの取り込み
- %li ふぁぼ爆撃対策
%li トロフィー機能をいらないよね…
%p
+ ふぁぼ爆撃(無差別なふぁぼなど)と判断された場合は数時間ふぁぼりの記録が停止されます。基準は相当高く設定しているので誤判定はまずないとは思いますがもしなにかあれば連絡ください。
+%p
= link_to "ツイート", "https://twitter.com/share", :class => "twitter-share-button", :"data-text" => "aclog", :"data-count" => "none", :"data-url" => "http://aclog.koba789.com/"
%hr
%h5
diff --git a/app/views/shared/_tweet.html.haml b/app/views/shared/_tweet.html.haml
index 3dd290b..c8c3a09 100644
--- a/app/views/shared/_tweet.html.haml
+++ b/app/views/shared/_tweet.html.haml
@@ -33,12 +33,12 @@
%dt
%span.count= actions.count
%span.type= type
- - if actions.count > show_count(actions.count)
+ - if user_limit && params[:action] == "show"
%span.full
= link_to "show full", params.merge(:full => true)
%dd
%ul.inline
- - actions.take(show_count(actions.count)).each do |m|
+ - actions.take(user_limit || actions.count).each do |m|
%li
= link_to_user_page m.screen_name do
= image_tag m.profile_image_url, :alt => m.screen_name, :title => m.name
diff --git a/app/views/shared/_tweet.json.jbuilder b/app/views/shared/_tweet.json.jbuilder
index c048dee..15dae1b 100644
--- a/app/views/shared/_tweet.json.jbuilder
+++ b/app/views/shared/_tweet.json.jbuilder
@@ -1,26 +1,26 @@
json.(item, :id, :text, :source, :tweeted_at, :favorites_count, :retweets_count)
-json.user do |json|
+json.user do
json.id item.user_id
if @include_user
json.partial! "shared/user", :user => item.user
end
end
-json.favorites item.favorites.order("id") do |json, favorite|
- json.user do |json|
- json.id favorite.user_id
- if @include_user
- json.partial! "shared/user", :user => favorite.user
- end
- end
-end
-json.retweets item.retweets.order("id") do |json, retweet|
- json.id retweet.id
- json.user do |json|
- json.id retweet.user_id
- if @include_user
- json.partial! "shared/user", :user => retweet.user
+render_actions = -> name, data, render_id do
+ n = 0
+ json.__send__(name, data) do |action|
+ json.id action.id if render_id
+ json.user do
+ json.id action.user_id
+ if @include_user && (!user_limit || n < user_limit)
+ json.partial! "shared/user", :user => action.user
+ end
end
+ n += 1
end
end
+
+render_actions.call(:favorites, item.favorites.includes(:user), false)
+render_actions.call(:retweets, item.retweets.includes(:user), true)
+
diff --git a/app/views/shared/tweets.html.haml b/app/views/shared/tweets.html.haml
index 0ab1a69..55e8e42 100644
--- a/app/views/shared/tweets.html.haml
+++ b/app/views/shared/tweets.html.haml
@@ -1,12 +1,11 @@
-- if @show_search
+- if params[:action] == "search"
= render :partial => "shared/search"
.items
= render :partial => "shared/tweet", :collection => @items, :as => :item
.loading
= image_tag "loading.gif", :alt => "loading...", :title => nil
-- if @items
- - if @page_param
- = paginate(@items)
- - elsif @items.last
- .pagination
- = link_to raw("Next &#8250;"), params.merge(:max_id => @items.last.id - 1), :rel => :next
+- if /offset/i =~ @items.to_sql
+ = paginate(@items)
+- elsif @items.last
+ .pagination
+ = link_to raw("Next &#8250;"), params.merge(:max_id => @items.last.id - 1), :rel => :next
diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder
new file mode 100644
index 0000000..bca1b00
--- /dev/null
+++ b/app/views/users/show.json.jbuilder
@@ -0,0 +1,2 @@
+json.partial! "shared/tweet", :item => @item
+