月末だったのでツイッターのトレンドをアーカイブするサイトに月毎の集計処理を追加しました。今回新規で追加した月毎のページは以下のようなURLでアクセスできます。年/05月https://wiki.imo-tikuwa.com/trends/2018
プログラムは以下のような感じで単体でバッチとして呼び出せる形で作成しました。今回はこのプログラムを既存のbatch.phpの末尾からexec関数で連動して呼び出すことで1時間毎、日毎の処理の後に続けて実行されるようにしました。
その他、プログラムを分けたためGrowiAPIのURLについては定数化しました。
month_summary_batch.php
<?php /** * TwitterのAPIで取得したトレンド情報を月毎に集計した情報をGrowiにAPIで登録するバッチ */ require 'functions.php'; require 'lib/GrowiAPI/GrowiAPI.php'; use Tikuwa\GrowiAPI\GrowiAPI; try { // 月のサマリーデータの入れ物作成 $month_summary_data = []; foreach (_getCities() as $city) { $month_summary_data[$city['name_ja']] = []; } // 日毎のサマリーデータの読み込み&月毎の集計 // ------------------------------ $first_date = new DateTime('first day of this month'); $first_date->setTime(0, 0, 0); $end_date = new DateTime('now'); $end_date->setTime(23, 59, 59); $date_interval = DateInterval::createFromDateString('1 day'); $date_period = new DatePeriod($first_date, $date_interval, $end_date); foreach ($date_period as $date) { // 日毎のサマリーデータを取得 $day_summary_data = @file_get_contents(SUMMARY_DATA_DIR . $date->format("Ymd")); if (!$day_summary_data) { continue; } $day_summary_data = unserialize($day_summary_data); // 日毎のサマリーデータを月毎集計 foreach ($day_summary_data as $city_name => $city_data) { foreach ($city_data as $name => $each_data) { if (!isset($month_summary_data[$city_name][$name])) { $month_summary_data[$city_name][$name] = $each_data; $month_summary_data[$city_name][$name]['count'] = 0; } $month_summary_data[$city_name][$name]['count'] += $each_data['count']; } } } // Growiに投稿 // ------------------------------ $datetime = _getJSTDate(); $growi_api = new GrowiAPI(GROWI_API_URL, GROWI_ACCESS_TOKEN); // 月毎のページを取得 $month_page = $growi_api->get("pages.get", [ 'path' => "/trends/" . $datetime->format('Y年/m月'), ]); // 月毎のページが存在しない場合は新規投稿、存在する場合は更新 $month_post_data = [ 'path' => "/trends/" . $datetime->format('Y年/m月'), 'body' => _createMonthSummaryMarkdown($datetime, $month_summary_data), ]; if (isset($month_page) && $month_page['ok'] === true) { $month_method = "pages.update"; $month_post_data['page_id'] = $month_page['page']['id']; } else { $month_method = "pages.create"; } $growi_api->post($month_method, $month_post_data); } catch (Exception $e) { var_dump(_getExceptionTraceAsString($e)); }
batch.php(末尾に追加)
try { // 月の集計処理を実行 exec("/usr/bin/php " . __DIR__ . "/month_summary_batch.php", $output, $return_value); } catch (Exception $e) { var_dump(_getExceptionTraceAsString($e)); }
月毎の集計データはファイルとしては保存せずにプログラム実行時に都度日毎の集計データから取得して月毎用のデータを作成することにしました。
日毎のデータを読み取るのに日付分foreachでループする際はDatePeriodというオブジェクトを使用してみました。DateInterval、DatePeriodを使用したことによりコードはすっきりしましたがループの際にデフォルトではend側の日付は含まれないためsetTime()で明示的な時間指定をする必要があるようでした。今回は以下の参考のように23時59分59秒をsetTime()によって指定しました。
参考:PHPで日付をループする方法と罠
プログラムの動作時間は5月の日毎の集計データが1日からあるわけではないので正確ではないですが1秒掛からないくらいなので大丈夫っぽい。