-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rb
102 lines (84 loc) · 2.42 KB
/
main.rb
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
require 'dotenv/load'
require 'rss'
require 'textmood'
require 'open-uri'
require 'x'
require 'date'
require 'active_support/all'
X_CREDENTIALS = {
api_key: ENV['X_API_KEY'],
api_key_secret: ENV['X_API_KEY_SECRET'],
access_token: ENV['X_ACCESS_TOKEN'],
access_token_secret: ENV['X_ACCESS_TOKEN_SECRET']
}.freeze
def post_tweet(tweet)
tweet.gsub!("\n", "\\n")
@x_client ||= X::Client.new(**X_CREDENTIALS)
@x_client.post('tweets', "{\"text\":\"#{tweet}\"}")
end
def tm
@tm ||= TextMood.new(language: 'es')
end
def prepare
@filtered_news = []
@discarded_news = []
if ENV['NEWS_RSS_SOURCES'].nil? || ENV['MOOD_THRESHOLD'].nil? || ENV['PERIODICITY'].nil?
puts 'Please set the NEWS_RSS_SOURCES, MOOD_THRESHOLD and PERIODICITY environment variables.'
exit
end
@news_rss_sources = ENV['NEWS_RSS_SOURCES'].split(',')
@mood_threshold = ENV['MOOD_THRESHOLD'].to_f
@excluded_categories = ENV['EXCLUDED_CATEGORIES'].split(',') || []
@periodicity = ENV['PERIODICITY'].to_i
end
class NewsItem
attr_accessor :title, :category, :link, :pub_date, :guid, :mood
def initialize(title, category, link, pub_date, guid, mood)
@title = title
@mood = mood
@category = category
@link = link
@pub_date = pub_date
@guid = guid
end
end
def include_news?(news_item)
news_item.mood > @mood_threshold &&
!@excluded_categories.include?(news_item.category) &&
news_item.pub_date > @periodicity.minutes.ago
end
def news_exists?(news_item)
@filtered_news.any? { |i| i.guid.to_s == news_item.guid.to_s }
end
def process_news
@news_rss_sources.each do |url|
URI.open(url) do |rss|
feed = RSS::Parser.parse(rss, validate: false)
feed.items.filter { |i| i.pubDate.present? }.each do |item|
unless news_exists?(item)
mood = tm.analyze(item.title)
item = NewsItem.new(item.title, item.category, item.link, item.pubDate, item.guid, mood)
include_news?(item) ? @filtered_news << item : @discarded_news << item
end
end
end
end
end
def publish_news
return unless ENV['PUBLISH_TO_X'] == 'true'
@filtered_news.sort { |a, b| a.pub_date <=> b.pub_date }.each do |item|
puts "Publishing: #{item.title}" if ENV['DEBUG'] == 'true'
text = <<~TEXT
#{item.title}
#{item.link}
TEXT
post_tweet(text)
end
end
def run
prepare
process_news
puts "Items to publish: #{@filtered_news.length}"
publish_news
end
run