diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-01-23 17:16:09 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-01-23 17:16:09 +0900 |
commit | c3d4489f007ecd22328c90e4dbcf873776014735 (patch) | |
tree | d6e2c5c08c46b870931489366c75d3589d34ed92 | |
parent | eae815cca9e9a0edab3ab35c18fc0fad5ebf5915 (diff) | |
download | aclog-c3d4489f007ecd22328c90e4dbcf873776014735.tar.gz |
refactor Tweet.update_from_twitter
-rw-r--r-- | app/controllers/tweets_controller.rb | 6 | ||||
-rw-r--r-- | app/models/tweet.rb | 67 | ||||
-rw-r--r-- | frontend/src/lib/aclog.js | 5 |
3 files changed, 42 insertions, 36 deletions
diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index 5faefdc..29eb603 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -12,14 +12,16 @@ class TweetsController < ApplicationController TweetUpdateJob.perform_later(t.id) unless bot_request? t rescue ActiveRecord::RecordNotFound - Tweet.update_from_twitter(params[:id], current_user).first || (raise Aclog::Exceptions::TweetNotFound, params[:id]) + Tweet.update_from_twitter(params[:id], current_user) + Tweet.find(params[:id]) end @user = authorize! @tweet.user render_show end def update - @tweet = authorize! Tweet.update_from_twitter(params[:id], current_user).first + Tweet.update_from_twitter(params[:id], current_user) + @tweet = authorize! Tweet.find(params[:id]) @user = @tweet.user render_show end diff --git a/app/models/tweet.rb b/app/models/tweet.rb index 89f5f15..9dbb289 100644 --- a/app/models/tweet.rb +++ b/app/models/tweet.rb @@ -87,54 +87,57 @@ class Tweet < ActiveRecord::Base def update_from_twitter(ids, current_user = nil) client = (current_user ? current_user.account : Account.random).client - if ids.is_a?(Array) - ids.map!(&:to_i) - else - ids = [ids.to_i] - end - ids.reject! {|id| id <= 0 } - - unless ids.size > 0 - raise Aclog::Exceptions::TweetNotFound, "specify at least one valid status ID" - end + ids = [ids] unless Array === ids + ids = ids.map { |id| id.to_i }.select { |id| id > 0 } + raise Aclog::Exceptions::TweetNotFound, "specify at least one valid status ID" if ids.empty? currents = Tweet.where(id: ids).eager_load(:user).to_a # query immediately + currenth = currents.map { |t| [t.id, t] }.to_h begin - if ids.size == 1 - sts = [client.status(ids.first)] - else - sts = client.statuses(ids) - end - rescue Twitter::Error::NotFound + sts = client.statuses(ids).map { |st| st.retweet? ? st.retweeted_status : st } + rescue Twitter::Error::NotFound, Twitter::Error::Forbidden sts = [] end - sts.map! {|st| st.retweet? ? st.retweeted_status : st } + User.create_or_update_bulk_from_json(sts.map { |st| st.attrs[:user] }) - User.create_or_update_bulk_from_json(sts.map {|st| st.attrs[:user] }) - Tweet.create_bulk_from_json(sts.map {|st| st.attrs }) + newjsons = sts.reject { |st| currenth[st.id] }.map { |st| st.attrs } + Tweet.create_bulk_from_json(newjsons) - tweets = Tweet.where(id: sts.map(&:id)).each do |tweet| - st = sts.find {|s| s.id == tweet.id } + exsts = sts.select { |st| currenth[st.id] } + Tweet.where(id: exsts.map(&:id)).zip(exsts) do |tweet, st| tweet.update(text: extract_entities(st.attrs), source: st.attrs[:source], - in_reply_to_id: (tweet.in_reply_to_id || st.attrs[:in_reply_to_status_id])) + in_reply_to_id: (tweet.in_reply_to_id || st.attrs[:in_reply_to_status_id]), + favorites_count: st.attrs[:favorite_count].to_i, + retweets_count: st.attrs[:retweet_count].to_i, + reactions_count: st.attrs[:favorite_count].to_i + st.attrs[:retweet_count].to_i) end - tobedelete = currents.reject {|tw| tw.user.protected? || sts.any? {|st| st.id == tw.id } } - tbdusers = client.users(tobedelete.map {|tw| tw.user_id }) rescue [] + stsids = Set.new(sts.map(&:id)) + check_deleted(currents.reject { |t| stsids.include?(t.id) }, current_user) + end - tobedelete.each do |tweet| - if tbdusers.any? {|u| u.id == tweet.user_id } - tweet.destroy - else - # TORIAEZU protected + def check_deleted(tweets, current_user = nil) + client = (current_user ? current_user.account : Account.random).client + + user_cache = {} + + tweets.each { |tweet| + begin + client.status(tweet.id) + rescue Twitter::Error::Forbidden tweet.user.update(protected: true) + rescue Twitter::Error::NotFound + u = user_cache[tweet.user.id] ||= (client.user(tweet.user.id) rescue :not_found) + if u == :not_found + tweet.user.update(protected: true) + else + tweet.destroy + end end - end - - tweets + } end # Parses /\d+[dwmy]/ style query and returns recent tweets (Relation) in specified period. diff --git a/frontend/src/lib/aclog.js b/frontend/src/lib/aclog.js index 4dd6b5a..1e7ec6d 100644 --- a/frontend/src/lib/aclog.js +++ b/frontend/src/lib/aclog.js @@ -1,5 +1,6 @@ import Settings from "../../settings"; import Storage from "storage"; +import utils from "utils"; var encodeQuery = (params) => { if (!params) return ""; @@ -25,7 +26,7 @@ var continueRequest = promise => { var get = (endpoint, params) => { if (Settings.debug) console.log("[API Request] " + endpoint + " query: " + encodeQuery(params)); - var url = Settings.backendPrefix + "/i/api/" + endpoint + ".json?" + encodeQuery(params); + var url = utils.getCurrentBaseUrl() + "/i/api/" + endpoint + ".json?" + encodeQuery(params); return continueRequest(fetch(url, { method: "get", credentials: "include", @@ -34,7 +35,7 @@ var get = (endpoint, params) => { var post = (endpoint, body) => { if (Settings.debug) console.log("[API Request] " + endpoint + " body: " + encodeQuery(body)); - var url = Settings.backendPrefix + "/i/api/" + endpoint + ".json"; + var url = utils.getCurrentBaseUrl() + "/i/api/" + endpoint + ".json"; return continueRequest(fetch(url, { method: "post", credentials: "include", |