Permalink
Browse files

Add importing favs feature(partial: only status_activity).

Refactor models
  • Loading branch information...
1 parent 27bf534 commit 90d8845257404bb445d7611f9e9c7828ec25dc34 @rhenium rhenium committed Mar 31, 2013
View
@@ -4,6 +4,7 @@ source 'https://rubygems.org'
gem 'rails', '4.0.0.beta1'
gem 'mysql2'
gem 'dalli'
+gem 'counter_culture'
gem 'unicorn'
gem 'thin'
View
@@ -33,6 +33,8 @@ GEM
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.33)
+ after_commit_action (0.1.3)
+ activerecord (>= 3.0.0)
arel (4.0.0.beta2)
atomic (1.0.1)
bootstrap-sass (2.3.1.0)
@@ -45,6 +47,8 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.6.2)
+ counter_culture (0.1.10)
+ after_commit_action (~> 0.1.3)
daemon-spawn (0.4.2)
daemons (1.1.9)
dalli (2.6.2)
@@ -165,6 +169,7 @@ PLATFORMS
DEPENDENCIES
bootstrap-sass
coffee-rails (~> 4.0.0.beta1)
+ counter_culture
daemon-spawn
dalli
em-twitter
@@ -16,7 +16,7 @@ def best
end
end
- def recent
+ def recent
@title = "@#{@user.screen_name}'s Recent Best Tweets"
render_tweets do
case order
@@ -116,22 +116,24 @@ def given_retweets_to
def show
tweet_id = params[:id].to_i
- @items = Tweet.where(:id => tweet_id).page
+ @item = Tweet.where(:id => tweet_id).first
- item = @items.first
- raise Aclog::Exceptions::TweetNotFound unless item
- @user = item.user
+ raise Aclog::Exceptions::TweetNotFound unless @item
+ @user = @item.user
+
+ # import 100
+ if params[:import] == "force" && session[:account]
+ session[:account].import_favorites(@item.id)
+ end
helpers = ApplicationController.helpers
- @title = "\"#{helpers.strip_tags(helpers.format_tweet_text(item.text))[0...30]}\" from @#{@user.screen_name}"
+ @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
- render "shared/tweets"
- end
+ format.html
format.json do
- render "shared/_tweet", :locals => {:item => item}
+ render "shared/_tweet", :locals => {:item => @item}
end
end
end
View
@@ -9,6 +9,23 @@ def twitter_user
end
end
+ def import_favorites(id)
+ result = client.status_activity(id)
+
+ # favs ユーザー一覧回収
+ Favorite.from_tweet_object(result)
+
+ # favs ユーザー回収
+ client.users(result.favoriters).each do |u|
+ User.from_user_object(u)
+ end
+
+ # rts 回収・RTのステータスIDを取得する必要がある
+ client.retweets(id).each do |status|
+ Retweet.from_tweet_object(status)
+ end
+ end
+
def client
Twitter::Client.new(
:consumer_key => Settings.consumer[consumer_version.to_i].key,
View
@@ -1,5 +1,6 @@
class Favorite < ActiveRecord::Base
- belongs_to :tweet, :counter_cache => true
+ belongs_to :tweet
+ counter_culture :tweet
belongs_to :user
scope :order_by_id, -> do
@@ -13,4 +14,30 @@ def user
def tweet
Tweet.cached(tweet_id)
end
+
+ def self.from_hash(hash)
+ begin
+ create!(:tweet_id => hash[:tweet_id],
+ :user_id => hash[:user_id])
+ logger.debug("Created Favorite: #{hash[:user_id]} => #{hash[:tweet_id]}")
+ rescue ActiveRecord::RecordNotUnique
+ logger.debug("Duplicate Favorite: #{hash[:user_id]} => #{hash[:tweet_id]}")
+ rescue
+ logger.error("Unknown error while inserting favorite: #{$!}/#{$@}")
+ end
+ end
+
+ def self.from_tweet_object(tweet_object)
+ if tweet_object.favoriters.is_a? Array
+ tweet_object.favoriters.each do |uid|
+ from_hash(:user_id => uid, :tweet_id => tweet_object.id)
+ end
+ end
+ end
+
+ def self.delete_from_hash(hash)
+ where(:tweet_id => hash[:tweet_id])
+ .where(:user_id => hash[:user_id])
+ .destroy_all
+ end
end
View
@@ -1,5 +1,6 @@
class Retweet < ActiveRecord::Base
- belongs_to :tweet, :counter_cache => true
+ belongs_to :tweet
+ counter_culture :tweet
belongs_to :user
scope :order_by_id, -> do
@@ -13,4 +14,28 @@ def user
def tweet
Tweet.cached(tweet_id)
end
+
+ def self.from_hash(hash)
+ begin
+ create!(:id => hash[:id],
+ :tweet_id => hash[:tweet_id],
+ :user_id => hash[:user_id])
+ logger.debug("Created Retweet: #{hash[:id]}: #{hash[:user_id]} => #{hash[:tweet_id]}")
+ rescue ActiveRecord::RecordNotUnique
+ logger.debug("Duplicate Retweet: #{hash[:id]}: #{hash[:user_id]} => #{hash[:tweet_id]}")
+ rescue
+ logger.error("Unknown error while inserting retweet: #{$!}/#{$@}")
+ end
+ end
+
+ def self.from_tweet_object(status)
+ User.from_user_object(status.user)
+ from_hash(:id => status.id,
+ :user_id => status.user.id,
+ :tweet_id => status.retweeted_status.id)
+ end
+
+ def self.delete_from_id(id)
+ where(:id => id).destroy_all
+ end
end
View
@@ -28,18 +28,19 @@ class Tweet < ActiveRecord::Base
end
scope :favorited_by, -> user do
- where("id IN (SELECT tweet_id FROM favorites WHERE user_id = ?)", user.id)
+ joins(:favorites).where(:favorites => {:user_id => user.id})
end
scope :retweeted_by, -> user do
- where("id IN (SELECT tweet_id FROM retweets WHERE user_id = ?)", user.id)
+ joins(:retweets).where(:retweets => {:user_id => user.id})
end
scope :discovered_by, -> user do
- where("id IN (SELECT tweet_id FROM favorites WHERE user_id = ?)" +
- " OR " +
- "id IN (SELECT tweet_id FROM retweets WHERE user_id = ?)",
- user.id, user.id)
+ joins("INNER JOIN (" +
+ "(SELECT favorites.tweet_id FROM favorites WHERE favorites.user_id = #{user.id})" +
+ " UNION " +
+ "(SELECT retweets.tweet_id FROM retweets WHERE retweets.user_id = #{user.id})" +
+ ") AS m ON m.tweet_id = tweets.id")
end
def self.cached(id)
@@ -51,4 +52,31 @@ def self.cached(id)
def user
User.cached(user_id)
end
+
+ def self.delete_from_id(id)
+ begin
+ # where(:id => id).destroy_all
+ # counter_cache の無駄を省くために delete_all で
+ Favorite.delete_all(:tweet_id => id)
+ Retweet.delete_all(:tweet_id => id)
+ Tweet.delete_all(:id => id)
+ rescue
+ logger.error("Unknown error while deleting tweet: #{$!}/#{$@}")
+ end
+ end
+
+ def self.from_hash(hash)
+ begin
+ create!(:id => hash[:id],
+ :text => hash[:text],
+ :source => hash[:source],
+ :tweeted_at => hash[:tweeted_at],
+ :user_id => hash[:user_id])
+ rescue ActiveRecord::RecordNotUnique
+ $logger.debug("Duplicate Tweet: #{hash[:id]}")
+ rescue
+ $logger.error("Unknown error while inserting tweet: #{$!}/#{$@}")
+ end
+ end
end
+
View
@@ -67,4 +67,25 @@ def stats
end
}.call
end
+
+ def self.from_hash(hash)
+ begin
+ rec = find_or_initialize_by(:id => hash[:id])
+ rec.screen_name = hash[:screen_name]
+ rec.name = hash[:name]
+ rec.profile_image_url = hash[:profile_image_url]
+ rec.protected = hash[:protected]
+ rec.save! if rec.changed?
+ rescue
+ $logger.error("Unknown error while inserting user: #{$!}/#{$@}")
+ end
+ end
+
+ def self.from_user_object(user_object)
+ from_hash(:id => user_object.id,
+ :screen_name => user_object.screen_name,
+ :name => user_object.name,
+ :profile_image_url => user_object.profile_image_url_https,
+ :protected => user_object.protected)
+ end
end
@@ -6,10 +6,13 @@
- if user
= link_to_user_page user.screen_name do
.avatar= image_tag user.profile_image_url, :alt => user.screen_name, :title => user.name
+ .data
+ = link_to url_for(params.merge(:screen_name_b => user.screen_name)) do
+ .count= count
+ .type= @event_type
- else
.avatar= image_tag asset_path("missing_profile_image.png"), :alt => "Missing User: #{user_id}", :title => "Missing User: #{user_id}"
- .data
- = link_to url_for(params.merge(:screen_name_b => user.screen_name)) do
+ .data
.count= count
.type= @event_type
@@ -0,0 +1,3 @@
+.items
+ = render :partial => "shared/tweet", :locals => {:item => @item}
+
View
@@ -15,6 +15,8 @@ def initialize
@pac = MessagePack::Unpacker.new
end
+ def escape_colon(str); str.gsub(":", "%3A").gsub("<", "%3C").gsub(">", "%3E"); end
+
def format_text(status)
chars = status[:text].to_s.split(//)
@@ -39,13 +41,11 @@ def format_text(status)
result.flatten.join
end
- def escape_colon(str); str.gsub(":", "%3A").gsub("<", "%3C").gsub(">", "%3E"); end
-
def format_source(status)
if status[:source].index("<a")
url = status[:source].scan(/href="(.+?)"/).flatten.first
name = status[:source].scan(/>(.+?)</).flatten.first
- "<url:#{CGI.escape(url)}:#{CGI.escape(name)}>"
+ "<url:#{escapecolon(url)}:#{escapecolon(name)}>"
else
status[:source]
end
@@ -1,3 +1,2 @@
-# Be sure to restart your server when you modify this file.
-
+require 'action_dispatch/middleware/session/dalli_store'
Aclog::Application.config.session_store ActionDispatch::Session::CacheStore, :expire_after => 3.days
View
@@ -28,6 +28,11 @@
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
+
+ if defined?(ActiveSupport::Cache::DalliStore) && Rails.cache.is_a?(ActiveSupport::Cache::DalliStore)
+ Rails.cache.reset
+ ObjectSpace.each_object(ActionDispatch::Session::DalliStore) { |obj| obj.reset }
+ end
end
Oops, something went wrong.

0 comments on commit 90d8845

Please sign in to comment.