Skip to content

Commit 088d081

Browse files
authored
Merge pull request #1724 from coderdojo-japan/refactor/rake_tasks_1716
Rakeタスクのリファクタリング
2 parents 6a4e448 + c41be03 commit 088d081

File tree

2 files changed

+46
-25
lines changed

2 files changed

+46
-25
lines changed

lib/tasks/fetch_news.rake

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,26 @@ def safe_open(url)
1616
end
1717
end
1818

19+
def fetch_rss_items(url, logger)
20+
logger.info("Fetching RSS → #{url}")
21+
begin
22+
rss = safe_open(url)
23+
feed = RSS::Parser.parse(rss, false)
24+
feed.items.map { |item| item_to_hash(item) }
25+
rescue => e
26+
logger.warn("⚠️ Failed to fetch #{url}: #{e.message}")
27+
[]
28+
end
29+
end
30+
31+
def item_to_hash(item)
32+
{
33+
'url' => item.link,
34+
'title' => item.title,
35+
'published_at' => item.pubDate.to_s
36+
}
37+
end
38+
1939
namespace :news do
2040
desc 'RSS フィードから最新ニュースを取得し、db/news.yml に書き出す'
2141
task fetch: :environment do
@@ -45,24 +65,7 @@ namespace :news do
4565
]
4666
end
4767

48-
# RSS 取得&パース
49-
new_items = feed_urls.flat_map do |url|
50-
logger.info("Fetching RSS → #{url}")
51-
begin
52-
rss = safe_open(url)
53-
feed = RSS::Parser.parse(rss, false)
54-
feed.items.map do |item|
55-
{
56-
'url' => item.link,
57-
'title' => item.title,
58-
'published_at' => item.pubDate.to_s
59-
}
60-
end
61-
rescue => e
62-
logger.warn("⚠️ Failed to fetch #{url}: #{e.message}")
63-
[]
64-
end
65-
end
68+
new_items = feed_urls.flat_map { |url| fetch_rss_items(url, logger) }
6669

6770
# 既存データをハッシュに変換(URL をキーに)
6871
existing_items_hash = existing_news.index_by { |item| item['url'] }
@@ -73,12 +76,12 @@ namespace :news do
7376

7477
new_items.each do |new_item|
7578
if existing_items_hash.key?(new_item['url'])
76-
# 既存アイテムの更新
7779
existing_item = existing_items_hash[new_item['url']]
78-
updated_item = existing_item.merge(new_item) # 新しい情報で更新
79-
updated_items << updated_item
80+
# タイトルまたは公開日が変わった場合のみ更新
81+
if existing_item['title'] != new_item['title'] || existing_item['published_at'] != new_item['published_at']
82+
updated_items << existing_item.merge(new_item)
83+
end
8084
else
81-
# 完全に新しいアイテム
8285
truly_new_items << new_item
8386
end
8487
end

lib/tasks/import_news.rake

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,40 @@ require 'yaml'
33
namespace :news do
44
desc 'db/news.yml を読み込んで News テーブルを upsert する'
55
task import_from_yaml: :environment do
6+
file_logger = ActiveSupport::Logger.new('log/news.log')
7+
console = ActiveSupport::Logger.new(STDOUT)
8+
logger = ActiveSupport::BroadcastLogger.new(file_logger, console)
9+
10+
logger.info "==== START news:import_from_yaml ===="
11+
612
yaml_path = Rails.root.join('db', 'news.yml')
713
raw = YAML.safe_load(File.read(yaml_path), permitted_classes: [Time], aliases: true)
814

915
# entries を計算
1016
entries = raw['news'] || []
17+
new_count = 0
18+
updated_count = 0
1119

1220
entries.each do |attrs|
1321
news = News.find_or_initialize_by(url: attrs['url'])
22+
is_new = news.new_record?
23+
1424
news.assign_attributes(
1525
title: attrs['title'],
1626
published_at: attrs['published_at']
1727
)
18-
news.save!
19-
puts "[news] #{news.published_at.to_date} #{news.title}"
28+
29+
if is_new || news.changed?
30+
news.save!
31+
status = is_new ? 'new' : 'updated'
32+
new_count += 1 if is_new
33+
updated_count += 1 unless is_new
34+
35+
logger.info "[News] #{news.published_at.to_date} #{news.title} (#{status})"
36+
end
2037
end
2138

22-
puts "Imported #{entries.size} items."
39+
logger.info "Imported #{new_count + updated_count} items (#{new_count} new, #{updated_count} updated)."
40+
logger.info "==== END news:import_from_yaml ===="
2341
end
2442
end

0 commit comments

Comments
 (0)