aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-01-23 17:16:09 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-01-23 17:16:09 +0900
commitc3d4489f007ecd22328c90e4dbcf873776014735 (patch)
treed6e2c5c08c46b870931489366c75d3589d34ed92
parenteae815cca9e9a0edab3ab35c18fc0fad5ebf5915 (diff)
downloadaclog-c3d4489f007ecd22328c90e4dbcf873776014735.tar.gz
refactor Tweet.update_from_twitter
-rw-r--r--app/controllers/tweets_controller.rb6
-rw-r--r--app/models/tweet.rb67
-rw-r--r--frontend/src/lib/aclog.js5
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",