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); |