@@ -10,14 +10,14 @@ namespace :news do
1010
1111 logger . info ( '==== START news:fetch ====' )
1212
13- # 本番環境では実サイトのフィード 、それ以外(テスト環境など)ではテスト用フェード
13+ # 本番/開発環境では実サイトのフィード 、それ以外(テスト環境など)ではテスト用フィード
1414 DOJO_NEWS_FEED = 'https://news.coderdojo.jp/feed/'
1515 TEST_NEWS_FEED = Rails . root . join ( 'spec' , 'fixtures' , 'sample_news.rss' )
16- RSS_FEED_LIST = Rails . env . production? ?
17- [ DOJO_NEWS_FEED ] :
18- [ TEST_NEWS_FEED ]
16+ RSS_FEED_LIST = ( Rails . env . test? || Rails . env . staging? ) ?
17+ [ TEST_NEWS_FEED ] :
18+ [ DOJO_NEWS_FEED ]
1919
20- news_items = RSS_FEED_LIST . flat_map do |feed |
20+ fetched_items = RSS_FEED_LIST . flat_map do |feed |
2121 feed = RSS ::Parser . parse ( feed , false )
2222 feed . items . map { |item |
2323 {
@@ -28,44 +28,41 @@ namespace :news do
2828 }
2929 end
3030
31- # 既存データ (YAML) を読み込み、ハッシュに変換
32- news_yaml_file = File . read Rails . root . join ( 'db' , 'news.yml' )
33- existing_news = YAML . safe_load ( news_yaml_file ) . index_by { |item | item [ 'url' ] }
31+ # 取得済みニュース (YAML) を読み込み、URL をキーとしたハッシュに変換
32+ news_yaml_file = File . read Rails . root . join ( 'db' , 'news.yml' )
33+ existing_items = YAML . safe_load ( news_yaml_file ) . index_by { it [ 'url' ] }
34+ existing_max_id = existing_items . flat_map { |url , item | item [ 'id' ] . to_i } . max || 0
3435
35- # 新しいアイテムと既存アイテムを分離
36- truly_new_items = [ ]
36+ # 新規記事と既存記事を分離
37+ created_items = [ ]
3738 updated_items = [ ]
3839
39- news_items . each do |new_item |
40- if existing_news . key? ( new_item [ 'url' ] )
41- existing_item = existing_news [ new_item [ 'url' ] ]
42- # タイトルまたは公開日が変わった場合のみ更新
43- if existing_item [ 'title' ] != new_item [ 'title' ] || existing_item [ 'published_at' ] != new_item [ 'published_at' ]
44- updated_items << existing_item . merge ( new_item )
40+ fetched_items . each do |fetched_item |
41+ existing_item = existing_items [ fetched_item [ 'url' ] ]
42+
43+ if existing_item
44+ # タイトルまたは公開日が変わっていたら更新
45+ if existing_item [ 'title' ] != fetched_item [ 'title' ] || existing_item [ 'published_at' ] != fetched_item [ 'published_at' ]
46+ updated_items << existing_item . merge ( fetched_item )
4547 end
4648 else
47- truly_new_items << new_item
49+ # 新規アイテムならそのまま追加
50+ created_items << fetched_item
4851 end
4952 end
5053
51- # 既存の最大IDを取得
52- max_existing_id = existing_news . map { |item | item [ 'id' ] . to_i } . max || 0
53-
5454 # 新しいアイテムのみに ID を割り当て(古い順)
55- truly_new_items_sorted = truly_new_items . sort_by { |item |
56- Time . parse ( item [ 'published_at' ] )
57- }
58-
59- truly_new_items_sorted . each_with_index do |item , index |
60- item [ 'id' ] = max_existing_id + index + 1
55+ created_items . sort_by! { Time . parse it [ 'published_at' ] }
56+ created_items . each_with_index do |item , index |
57+ item [ 'id' ] = existing_max_id + index + 1
6158 end
6259
6360 # 更新されなかった既存アイテムを取得
64- updated_urls = updated_items . map { | item | item [ 'url' ] }
65- unchanged_items = existing_news . reject { | item | updated_urls . include? ( item [ 'url' ] ) }
61+ updated_urls = updated_items . map { it [ 'url' ] }
62+ unchanged_items = existing_items . values . reject { updated_urls . include? ( it [ 'url' ] ) }
6663
6764 # 全アイテムをマージ
68- all_items = unchanged_items + updated_items + truly_new_items_sorted
65+ all_items = unchanged_items + updated_items + created_items
6966
7067 # 日付降順ソート
7168 sorted_items = all_items . sort_by { |item |
@@ -83,18 +80,18 @@ namespace :news do
8380 }
8481 end
8582
86- f . write ( { 'news' => formatted_items } . to_yaml )
83+ f . write ( formatted_items . to_yaml )
8784 end
8885
89- logger . info ( "✅ Wrote #{ sorted_items . size } items to db/news.yml (#{ truly_new_items_sorted . size } new, #{ updated_items . size } updated)" )
86+ logger . info ( "✅ Wrote #{ sorted_items . size } items to db/news.yml (#{ created_items . size } new, #{ updated_items . size } updated)" )
9087 logger . info ( '==== END news:fetch ====' )
9188 end
9289
9390 desc 'db/news.yml からデータベースに upsert'
9491 task upsert : :environment do
95- file_logger = ActiveSupport ::Logger . new ( 'log/news.log' )
9692 console = ActiveSupport ::Logger . new ( STDOUT )
97- logger = ActiveSupport ::BroadcastLogger . new ( file_logger , console )
93+ logger_file = ActiveSupport ::Logger . new ( 'log/news.log' )
94+ logger = ActiveSupport ::BroadcastLogger . new ( logger_file , console )
9895
9996 logger . info "==== START news:upsert ===="
10097
@@ -112,7 +109,7 @@ namespace :news do
112109 title : attrs [ 'title' ] ,
113110 published_at : attrs [ 'published_at' ]
114111 )
115-
112+
116113 if is_new || news . changed?
117114 news . save!
118115 status = is_new ? 'new' : 'updated'
0 commit comments