172 lines
4.4 KiB
PHP
172 lines
4.4 KiB
PHP
|
<?php declare(strict_types=1);
|
||
|
|
||
|
class Content
|
||
|
{
|
||
|
public string $data;
|
||
|
public string $mimeType;
|
||
|
public string $fileName;
|
||
|
public string $hash;
|
||
|
private array $metadata = [];
|
||
|
|
||
|
const TTL = 60;
|
||
|
|
||
|
public function __construct(string $file)
|
||
|
{
|
||
|
$this->fileName = basename(dirname($file)).'/'.basename($file);
|
||
|
$this->data = file_get_contents($file);
|
||
|
$this->hash = md5($this->data);
|
||
|
|
||
|
$this->parseMetadata();
|
||
|
}
|
||
|
|
||
|
public function toRecords(): string
|
||
|
{
|
||
|
$chunks = str_split(base64_encode($this->data), 250);
|
||
|
|
||
|
$records = [];
|
||
|
$records[] = "; {$this->getDnsName()}";
|
||
|
$records[] = $this->getDnsName().$this->buildMiddle().'"'.$this->buildIndexString(count($chunks)).'"';
|
||
|
|
||
|
foreach($chunks as $id => $chunk)
|
||
|
{
|
||
|
$records[] = $this->buildRecord($id, $chunk);
|
||
|
}
|
||
|
|
||
|
$result = "";
|
||
|
foreach ($records as $record)
|
||
|
{
|
||
|
$result .= $record . PHP_EOL;
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
private function getDnsName(): string
|
||
|
{
|
||
|
return str_replace(['/', '\\', '.'], '-', $this->fileName);
|
||
|
}
|
||
|
|
||
|
private function buildIndexString(int $chunkCount): string
|
||
|
{
|
||
|
$metadata = base64_encode(json_encode($this->metadata));
|
||
|
return "t={$this->mimeType()};c={$chunkCount};h={$this->hash};m={$metadata}";
|
||
|
}
|
||
|
|
||
|
private function buildMiddle(): string
|
||
|
{
|
||
|
return "\t".self::TTL."\tIN\tTXT\t";
|
||
|
}
|
||
|
|
||
|
private function buildRecord(int $id, string $data): string
|
||
|
{
|
||
|
$name = "$id.{$this->hash}";
|
||
|
|
||
|
return "$name".$this->buildMiddle().'"'.$data.'"';
|
||
|
}
|
||
|
|
||
|
private function mimeType()
|
||
|
{
|
||
|
$extension = pathinfo($this->fileName, PATHINFO_EXTENSION);
|
||
|
|
||
|
switch($extension)
|
||
|
{
|
||
|
case "js":
|
||
|
return "text/javascript";
|
||
|
case "md":
|
||
|
return "text/markdown";
|
||
|
|
||
|
default:
|
||
|
return mime_content_type($this->file);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function parseMetadata()
|
||
|
{
|
||
|
if ($this->mimeType() != "text/markdown") return [];
|
||
|
|
||
|
$frontmatter_chars = "+++";
|
||
|
|
||
|
$end_of_frontmatter = strpos($this->data, $frontmatter_chars, 2);
|
||
|
if (false === $end_of_frontmatter) {
|
||
|
var_dump($end_of_frontmatter);
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
$frontmatter = substr(
|
||
|
$this->data,
|
||
|
strlen($frontmatter_chars) + 1,
|
||
|
$end_of_frontmatter - strlen($frontmatter_chars) - 2
|
||
|
);
|
||
|
|
||
|
$this->data = trim(substr($this->data, $end_of_frontmatter + strlen($frontmatter_chars))).PHP_EOL;
|
||
|
|
||
|
$lines = explode(PHP_EOL, $frontmatter);
|
||
|
foreach($lines as $line) {
|
||
|
$eq_pos = strpos($line, "=");
|
||
|
$key = trim(substr($line, 0, $eq_pos - 1));
|
||
|
$value = trim(substr($line, $eq_pos + 1));
|
||
|
$this->metadata[$key] = $value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function update_serial_line(string $line)
|
||
|
{
|
||
|
$matches = [];
|
||
|
preg_match("#(\s+)(\d{10})(.*)#", $line, $matches);
|
||
|
list($_, $start, $serial, $last) = $matches;
|
||
|
|
||
|
$today = date("Ymd");
|
||
|
$day = substr($serial, 0, 8);
|
||
|
$nr = (int) substr($serial, -2);
|
||
|
|
||
|
if ($day === $today) {
|
||
|
$nr++;
|
||
|
} else {
|
||
|
$day = $today;
|
||
|
$nr = 1;
|
||
|
}
|
||
|
|
||
|
$new_serial = sprintf('%1$s%2$02d', $day, $nr);
|
||
|
|
||
|
return $start.$new_serial.$last;
|
||
|
}
|
||
|
|
||
|
$zone_file = "zones/db.hod.experiments.jacobkiers.net";
|
||
|
if (!file_exists($zone_file)) {
|
||
|
fwrite(STDERR, "The zone file {$zone_file} does not exist!");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
$lines = file($zone_file);
|
||
|
|
||
|
foreach($lines as $index => &$line)
|
||
|
{
|
||
|
if (str_contains($line, "; serial")) {
|
||
|
$matches = [];
|
||
|
preg_match("#(\s+)(\d{10})(.*)#", $line, $matches);
|
||
|
list($_, $start, $serial, $last) = $matches;
|
||
|
$line = update_serial_line($line).PHP_EOL;
|
||
|
}
|
||
|
if (str_starts_with($line, ";; START BLOG RECORDS")) break;
|
||
|
}
|
||
|
|
||
|
$zone_file_contents = implode("", array_slice($lines, 0, $index+1));
|
||
|
|
||
|
echo $zone_file_contents;
|
||
|
|
||
|
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__."/content"));
|
||
|
foreach ($it as $file)
|
||
|
{
|
||
|
if ($file->isDir()) continue;
|
||
|
if (str_contains($file->getPathname(), "ignore")) continue;
|
||
|
|
||
|
$bootstrap = new Content($file->getPathname());
|
||
|
$zone_file_contents .= PHP_EOL.$bootstrap->toRecords().PHP_EOL;
|
||
|
}
|
||
|
|
||
|
$zone_file_contents .= PHP_EOL;
|
||
|
|
||
|
#echo $zone_file_contents;
|
||
|
|
||
|
file_put_contents($zone_file, $zone_file_contents);
|