Skip to content

Commit bf99ba9

Browse files
committed
move build scripts from holidays-jp/generator
1 parent 88bd12d commit bf99ba9

10 files changed

+3528
-0
lines changed

.editorconfig

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.{php,json}]
13+
indent_style = space
14+
indent_size = 4
15+
16+
[*.md]
17+
trim_trailing_whitespace = false

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/vendor/
2+
.idea/
3+
.*.cache

app/holidaysJP.php

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
3+
namespace HolidaysJP;
4+
5+
use Cake\Chronos\Chronos;
6+
use Illuminate\Support\Collection;
7+
8+
/**
9+
* Class holidaysJP
10+
* @package HolidaysJP
11+
*/
12+
class holidaysJP
13+
{
14+
protected $ical_url;
15+
const DIST = __DIR__ . '/../docs/v1';
16+
17+
/**
18+
* holidaysJP constructor.
19+
* @param $url
20+
*/
21+
public function __construct($url = null)
22+
{
23+
date_default_timezone_set('Asia/Tokyo');
24+
25+
$this->ical_url = $url ?: 'https://calendar.google.com/calendar/ical/ja.japanese%23holiday%40group.v.calendar.google.com/public/basic.ics';
26+
}
27+
28+
/**
29+
* APIファイル生成 メイン処理
30+
*/
31+
public function generate()
32+
{
33+
// icalデータを取得して配列化
34+
$data = $this->get_ical_data();
35+
$holidays = $this->convert_ical_to_array($data);
36+
37+
// 一覧データを出力
38+
$this->generate_api_file($holidays);
39+
40+
// データを年別に分解
41+
$yearly = Collection::make($holidays)
42+
->groupBy(function ($item, $key) {
43+
return Chronos::createFromTimestamp($key)->year;
44+
}, true)
45+
->toArray();
46+
47+
// 年別データを出力
48+
foreach ($yearly as $year => $ary) {
49+
$this->generate_api_file($ary, $year);
50+
}
51+
}
52+
53+
/**
54+
* iCalデータの取得 (+ 不要文字などの削除)
55+
* @return array|false|string|string[]
56+
*/
57+
function get_ical_data()
58+
{
59+
$ics = file_get_contents($this->ical_url);
60+
return str_replace("\r", '', $ics);
61+
}
62+
63+
/**
64+
* iCal形式のデータを配列に変換
65+
* @param $data
66+
* @return array
67+
*/
68+
function convert_ical_to_array($data): array
69+
{
70+
$results = [];
71+
72+
// イベントごとに区切って配列化
73+
$events = explode('END:VEVENT', $data);
74+
75+
foreach ($events as $event) {
76+
// 日付を求める
77+
if (preg_match('/DTSTART;\D*(\d+)/m', $event, $m) != 1) {
78+
continue;
79+
}
80+
$date = Chronos::createFromTimestamp(strtotime($m[1]));
81+
82+
// サマリ(祝日名)を求める
83+
if (preg_match('/SUMMARY:(.+?)\n/m', $event, $summary) != 1) {
84+
continue;
85+
}
86+
87+
$results[$date->timestamp] = $this->convert_holiday_name($date, $summary[1]);
88+
}
89+
90+
// 日付順にソートして返却
91+
ksort($results);
92+
return $results;
93+
}
94+
95+
96+
/**
97+
* @param Chronos $date
98+
* @param $name
99+
* @return string
100+
*/
101+
public function convert_holiday_name(Chronos $date, $name): string
102+
{
103+
if ($name == '体育の日' && $date->year >= 2020) {
104+
return 'スポーツの日';
105+
}
106+
107+
return $name;
108+
}
109+
110+
/**
111+
* APIデータをファイルに出力
112+
* @param $data
113+
* @param string $year
114+
*/
115+
function generate_api_file($data, string $year = '')
116+
{
117+
// 出力先フォルダがなければ作成
118+
$dist_dir = (!empty($year)) ? self::DIST . '/' . $year : self::DIST;
119+
if (!is_dir($dist_dir)) {
120+
mkdir($dist_dir);
121+
}
122+
123+
// ファイル出力 (datetime型)
124+
$this->output_json_file($dist_dir . "/datetime.json", $data);
125+
$this->output_csv_file($dist_dir . "/datetime.csv", $data);
126+
127+
// キーをYMD形式に変換して出力
128+
$date_data = Collection::make($data)
129+
->keyBy(function ($item, $key) {
130+
return Chronos::createFromTimestamp($key)->toDateString();
131+
})
132+
->toArray();
133+
134+
// ファイル出力 (date)
135+
$this->output_json_file($dist_dir . "/date.json", $date_data);
136+
$this->output_csv_file($dist_dir . "/date.csv", $date_data);
137+
}
138+
139+
140+
/**
141+
* JSONファイルを出力
142+
* @param $filename
143+
* @param $data
144+
*/
145+
protected function output_json_file($filename, $data)
146+
{
147+
file_put_contents($filename, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
148+
}
149+
150+
/**
151+
* CSVファイルを出力
152+
* @param $filename
153+
* @param $data
154+
*/
155+
protected function output_csv_file($filename, $data)
156+
{
157+
$recordArr = array();
158+
159+
foreach ($data as $date => $text) {
160+
$recordArr[] = [$date, $text];
161+
}
162+
$fp = fopen($filename, 'w');
163+
foreach ($recordArr as $record) {
164+
fputcsv($fp, $record);
165+
}
166+
fclose($fp);
167+
}
168+
}

composer.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"autoload": {
3+
"psr-4": {
4+
"HolidaysJP\\": "app/"
5+
}
6+
},
7+
"require": {
8+
"cakephp/chronos": "^2.2",
9+
"illuminate/support": "^8.58",
10+
"phpunit/phpunit": "^9.5"
11+
},
12+
"scripts": {
13+
"build": "php main.php",
14+
"test": "phpunit"
15+
}
16+
}

0 commit comments

Comments
 (0)