1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# -*- coding: utf-8 -*-
require 'json'
Plugin.create :core do
# Serviceと、Messageの配列を受け取り、一度以上受け取ったことのあるものを除外して返すフィルタを作成して返す。
# ただし、除外したかどうかはService毎に記録する。
# また、アカウント登録前等、serviceがnilの時はシステムメッセージ以外を全て削除し、記録しない。
# ==== Return
# フィルタのプロシージャ(Proc)
def gen_message_filter_with_service
service_filters = Hash.new{|h,k|h[k] = gen_message_filter}
->(service, messages, &cancel) {
if service
[service] + service_filters[service.user_obj.id].(messages)
else
system = messages.select(&:system?)
if system.empty?
cancel.call
else
[nil, system] end end } end
# Messageの配列を受け取り、一度以上受け取ったことのあるものを除外して返すフィルタを作成して返す
# ==== Return
# フィルタのプロシージャ(Proc)
def gen_message_filter
appeared = Set.new
->(messages){
[messages.select{ |message|
appeared.add(message.id) unless appeared.include?(message.id) }] } end
# URL _url_ がTwitterに投稿された時に何文字としてカウントされるかを返す
# ==== Args
# [url] String URL
# ==== Return
# Fixnum URLの長さ
def posted_url_length(url)
if url.start_with?('https://'.freeze)
@twitter_configuration[:short_url_length_https] || 23
else
@twitter_configuration[:short_url_length] || 22 end end
filter_update(&gen_message_filter_with_service)
filter_mention(&gen_message_filter_with_service)
filter_direct_messages(&gen_message_filter_with_service)
filter_appear(&gen_message_filter)
# リツイートを削除した時、ちゃんとリツイートリストからそれを削除する
on_destroyed do |messages|
messages.each{ |message|
if message.retweet?
source = message.retweet_source(false)
if source
Plugin.call(:retweet_destroyed, source, message.user, message[:id])
source.retweeted_sources.delete(message) end end } end
end
Module.new do
Plugin.create(:core) do
defevent :favorite,
priority: :ui_favorited,
prototype: [Diva::Model, User, Message]
defevent :unfavorite,
priority: :ui_favorited,
prototype: [Diva::Model, User, Message]
favorites = Hash.new{ |h, k| h[k] = Set.new } # {user_id: set(message_id)}
unfavorites = Hash.new{ |h, k| h[k] = Set.new } # {user_id: set(message_id)}
@twitter_configuration = JSON.parse(file_get_contents(File.join(__dir__, 'configuration.json'.freeze)), symbolize_names: true)
onappear do |messages|
retweets = messages.select(&:retweet?).map do |message|
result = message.retweet_ancestors.to_a[-2]
fail "invalid retweet #{message.inspect}. ancestors: #{message.retweet_ancestors.to_a.inspect}" unless result.is_a?(Message)
result
end
if not(retweets.empty?)
Plugin.call(:retweet, retweets) end end
# イベントフィルタを他のスレッドで並列実行する
Delayer.new do
Event.filter_another_thread = true end
# Twitter API help/configuration.json を叩いて最新情報を取得する
Delayer.new do
service = Service.primary
if service
(service/:help/:configuration).json(cache: true).next do |configuration|
@twitter_configuration = configuration.symbolize end end end
# 同じツイートに対するfavoriteイベントは一度しか発生させない
filter_favorite do |service, user, message|
Plugin.filter_cancel! if favorites[user[:id]].include? message[:id]
favorites[user[:id]] << message[:id]
[service, user, message]
end
# 同じツイートに対するunfavoriteイベントは一度しか発生させない
filter_unfavorite do |service, user, message|
Plugin.filter_cancel! if unfavorites[user[:id]].include? message[:id]
unfavorites[user[:id]] << message[:id]
[service, user, message]
end
# followers_createdイベントが発生したら、followイベントも発生させる
on_followers_created do |service, users|
users.each{ |user|
Plugin.call(:follow, user, service.user_obj) } end
# followings_createdイベントが発生したら、followイベントも発生させる
on_followings_created do |service, users|
users.each{ |user|
Plugin.call(:follow, service.user_obj, user) } end
# t.coによって短縮されたURLの長さを求める
filter_tco_url_length do |url, length|
[url, posted_url_length(url)] end
end
end
|