Skip to content

Commit

Permalink
implement json source
Browse files Browse the repository at this point in the history
  • Loading branch information
recca0120 committed Nov 11, 2024
1 parent fef33f3 commit 7021d9f
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 26 deletions.
Binary file added resources/Zip32_11208.zip
Binary file not shown.
Binary file removed resources/Zip32_utf8_10501_1.zip
Binary file not shown.
43 changes: 32 additions & 11 deletions resources/converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

include __DIR__.'/../vendor/autoload.php';

use Recca0120\Twzipcode\Sources\CSV;
use Recca0120\Twzipcode\Sources\Csv;
use Recca0120\Twzipcode\Sources\Json;
use Recca0120\Twzipcode\Storages\File;

// https://data.gov.tw/dataset/5948
$downloadUrl = 'https://quality.data.gov.tw/dq_download_json.php?nid=5948&md5_url=e1f6004ad33eb3ff3a824fb992a4b01a';
$extension = 'json';
$file = __DIR__.'/Zip32_11208.zip';

set_error_handler(static function ($severity, $message, $file, $line) {
throw new ErrorException($message, $severity, $severity, $file, $line);
});

$start = microtime(true);
$file = __DIR__.'/Zip32_utf8_10501_1.zip';

// https://data.gov.tw/dataset/5948
$url = 'https://quality.data.gov.tw/dq_download_csv.php?nid=5948&md5_url=e1f6004ad33eb3ff3a824fb992a4b01a';

if (file_exists($file) === false) {
touch($file);
function csv($url)
{
$contents = file_get_contents($url);

$encoding = mb_detect_encoding($contents, ['UCS-2LE', 'BIG5', 'UTF-8']);
Expand All @@ -30,11 +30,32 @@
throw new RuntimeException($contents);
}

return $contents;
}

function json($url)
{
return file_get_contents($url);
}

$start = microtime(true);
if (file_exists($file) === false) {
$contents = $extension($downloadUrl);

touch($file);
$zip = new ZipArchive;
$zip->open($file, ZipArchive::OVERWRITE);
$zip->addFromString(pathinfo($file, PATHINFO_FILENAME).'.csv', $contents);
$zip->addFromString(pathinfo($file, PATHINFO_FILENAME).'.'.$extension, $contents);
$zip->close();
}

(new File)->load(new CSV($file));
$lookup = [
'csv' => Csv::class,
'json' => Json::class,
];
$class = $lookup[$extension];

$source = new $class($file);

(new File)->load($source);
echo 'benchmark: '.(microtime(true) - $start)."\n";
Binary file modified resources/data/zip5.rules
Binary file not shown.
3 changes: 0 additions & 3 deletions src/Rules.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ class Rules
*/
private $storage;

/**
* @param Storage|null $storage
*/
public function __construct(Storage $storage = null)
{
$this->storage = $storage ?: new File;
Expand Down
2 changes: 1 addition & 1 deletion src/Sources/CSV.php → src/Sources/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Recca0120\Twzipcode\Sources;

class CSV extends Source
class Csv extends Source
{
/** @var string */
protected $file;
Expand Down
21 changes: 21 additions & 0 deletions src/Sources/Json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Recca0120\Twzipcode\Sources;

class Json extends Csv
{
/**
* @return array{array{zipcode: string, county: string, district: string, text: string}} $rows
*/
protected function rows()
{
return array_map(static function ($data) {
return [
'zipcode' => $data['郵遞區號'],
'county' => $data['縣市名稱'],
'district' => $data['鄉鎮市區'],
'rule' => implode(',', $data),
];
}, json_decode($this->contents(), true));
}
}
13 changes: 9 additions & 4 deletions src/Sources/Source.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,15 @@ protected function rows()
return ! empty(trim($line));
});

return array_map(static function ($line) {
$data = explode(',', $line);
return array_map(static function ($rule) {
$data = explode(',', $rule);

return ['zipcode' => $data[0], 'county' => $data[1], 'district' => $data[2], 'text' => $line];
return [
'zipcode' => $data[0],
'county' => $data[1],
'district' => $data[2],
'rule' => $rule,
];
}, $lines);
}

Expand All @@ -51,7 +56,7 @@ protected static function prepare($rows)
? self::$tricks[$row['county'].$row['district']]
: substr($row['zipcode'], 0, 3);

$results[$row['county']][$row['district']][$zip3][] = $row['text'];
$results[$row['county']][$row['district']][$zip3][] = $row['rule'];

return $results;
}, []);
Expand Down
3 changes: 2 additions & 1 deletion src/Tricky.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Tricky
{
/** @var Tricky */
private static $instance;

private static $cached = [];

/*
Expand Down Expand Up @@ -87,7 +88,7 @@ public function flip($token)
public static function instance()
{
if (! self::$instance) {
self::$instance = new self();
self::$instance = new self;
self::$instance->init();
}

Expand Down
6 changes: 2 additions & 4 deletions src/Zipcode.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ class Zipcode

/**
* @param string|Address $address
* @param ?Rules $rules
*/
public function __construct($address, Rules $rules = null)
public function __construct($address, ?Rules $rules = null)
{
$rules = $rules ?: new Rules;
$address = new Address($address);
Expand All @@ -44,10 +43,9 @@ public function __construct($address, Rules $rules = null)

/**
* @param string|Address $address
* @param ?Rules $rules
* @return static
*/
public static function parse($address, Rules $rules = null)
public static function parse($address, ?Rules $rules = null)
{
return new static($address, $rules);
}
Expand Down
42 changes: 42 additions & 0 deletions tests/Sources/CsvTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Recca0120\Twzipcode\Tests\Sources;

use PHPUnit\Framework\TestCase;
use Recca0120\Twzipcode\Sources\Csv;

class CsvTest extends TestCase
{
public function test_csv_contents()
{
$source = new StubCsv('test.csv');
$source->setContents('10058,臺北市,中正區,八德路1段,全
10079,臺北市,中正區,三元街,單全
');

$source->each(function ($zipcode, $county, $district, $rules) {
self::assertEquals(100, $zipcode);
self::assertEquals('臺北市', $county);
self::assertEquals('中正區', $district);
self::assertEquals([
'10058,臺北市,中正區,八德路1段,全',
'10079,臺北市,中正區,三元街,單全',
], $rules);
});
}
}

class StubCsv extends Csv
{
private $contents = '';

public function setContents($contents)
{
$this->contents = $contents;
}

public function contents()
{
return $this->contents;
}
}
40 changes: 40 additions & 0 deletions tests/Sources/JsonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Recca0120\Twzipcode\Tests\Sources;

use PHPUnit\Framework\TestCase;
use Recca0120\Twzipcode\Sources\Json;

class JsonTest extends TestCase
{
public function test_csv_contents()
{
$source = new StubJson('test.json');
$source->setContents('[{"郵遞區號":"10058","縣市名稱":"臺北市","鄉鎮市區":"中正區","原始路名":"八德路1段","投遞範圍":"全"},{"郵遞區號":"10079","縣市名稱":"臺北市","鄉鎮市區":"中正區","原始路名":"三元街","投遞範圍":"單全"}]');

$source->each(function ($zipcode, $county, $district, $rules) {
self::assertEquals(100, $zipcode);
self::assertEquals('臺北市', $county);
self::assertEquals('中正區', $district);
self::assertEquals([
'10058,臺北市,中正區,八德路1段,全',
'10079,臺北市,中正區,三元街,單全',
], $rules);
});
}
}

class StubJson extends Json
{
private $contents = '';

public function setContents($contents)
{
$this->contents = $contents;
}

public function contents()
{
return $this->contents;
}
}
4 changes: 2 additions & 2 deletions tests/Storages/FileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\TestCase;
use Recca0120\Twzipcode\Address;
use Recca0120\Twzipcode\Sources\CSV;
use Recca0120\Twzipcode\Sources\Json;
use Recca0120\Twzipcode\Sources\Text;
use Recca0120\Twzipcode\Storages\File as Storage;

Expand Down Expand Up @@ -125,7 +125,7 @@ public function testLoadResources()
Storage::$cached = ['zip3' => null, 'zip5' => null];
$root = vfsStream::setup();
$storage = new Storage($root->url());
$storage->flush()->load(new CSV(__DIR__.'/../../resources/Zip32_utf8_10501_1.zip'));
$storage->flush()->load(new Json(__DIR__.'/../../resources/Zip32_11208.zip'));

$address = m::mock(Address::class);

Expand Down

0 comments on commit 7021d9f

Please sign in to comment.