Permalinks changed from id to title slug...

This commit is contained in:
hbrain 2026-06-20 17:28:27 +02:00
parent 07aa53689e
commit db4a48d08d
7 changed files with 267 additions and 35 deletions

View file

@ -28,10 +28,21 @@ function video_metadata($path){
}
return $meta;
}
function article_id_is_valid($id){ return is_string($id) && preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $id); }
function read_article_id($dir){ $file=rtrim((string)$dir,'/').'/.mvlog-id'; if(!is_file($file)) return ''; $id=strtolower(trim((string)file_get_contents($file))); return article_id_is_valid($id)?$id:''; }
function slug_from_title($title,$fallback='post'){
$slug=strtr((string)$title,['æ'=>'ae','Æ'=>'ae','ø'=>'o','Ø'=>'o','å'=>'aa','Å'=>'aa','ä'=>'ae','Ä'=>'ae','ö'=>'oe','Ö'=>'oe','ü'=>'ue','Ü'=>'ue','ß'=>'ss','ẞ'=>'ss','č'=>'c','Č'=>'c','ć'=>'c','Ć'=>'c','ž'=>'z','Ž'=>'z','š'=>'s','Š'=>'s','đ'=>'d','Đ'=>'d']);
if(function_exists('iconv')){ $ascii=@iconv('UTF-8','ASCII//TRANSLIT//IGNORE',$slug); if($ascii!==false)$slug=$ascii; }
$slug=strtolower($slug); $slug=preg_replace('/[^a-z0-9]+/','-',$slug)??''; $slug=trim($slug,'-'); return $slug!==''?$slug:$fallback;
}
function title_from_data($dir){ $file=rtrim((string)$dir,'/').'/data.txt'; if(is_file($file)){ foreach(file($file, FILE_IGNORE_NEW_LINES)?:[] as $line){ if(!str_contains($line,':')) continue; [$k,$v]=array_map('trim',explode(':',$line,2)); if(in_array(strtolower($k),['title','name'],true)&&$v!=='') return $v; }} return nice_title(basename((string)$dir)); }
function article_permalink_map($config){ $map=[]; $used=[]; $dirs=glob($config['uploads_dir'].'/*', GLOB_ONLYDIR)?:[]; sort($dirs,SORT_STRING); foreach($dirs as $dir){ if(!is_file($dir.'/.mvlog-permalink')) continue; $id=read_article_id($dir); if($id==='') continue; $base=slug_from_title(title_from_data($dir),$id); $slug=$base; if(isset($used[$slug])) $slug=$base.'-'.substr($id,-6); $n=2; while(isset($used[$slug])){ $slug=$base.'-'.substr($id,-6).'-'.$n; $n++; } $used[$slug]=true; $map[$id]='/post/'.rawurlencode($slug); } return $map; }
function article_permalink_for_video($config,$videoName,$map){ $videoName=basename((string)$videoName); foreach(glob($config['uploads_dir'].'/*', GLOB_ONLYDIR)?:[] as $dir){ if(!is_file($dir.'/.mvlog-permalink')) continue; $stateFile=$dir.'/.movmaker-state.json'; if(!is_file($stateFile)) continue; $state=json_decode((string)file_get_contents($stateFile),true); if(!is_array($state)) continue; if($videoName===basename((string)($state['output']??''))){ $id=read_article_id($dir); return $map[$id]??''; }} return ''; }
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'https';
$host = $_SERVER['HTTP_HOST'] ?? 'bubulescu.org';
$baseUrl = $scheme . '://' . $host . rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
$hiddenOutputs = hidden_video_outputs($config);
$permalinkMap = article_permalink_map($config);
$videos = array_values(array_filter(glob($config['videos_dir'].'/*.{mp4,webm,mov,m4v}', GLOB_BRACE) ?: [], fn($v)=>empty($hiddenOutputs[basename($v)]) && !preg_match('/_preview\.(mp4|webm|mov|m4v)$/i', basename($v)) && !preg_match('/_preview\.(mp4|webm|mov|m4v)$/i', basename($v))));
usort($videos, fn($a,$b)=>filemtime($b)<=>filemtime($a));
$videos = array_slice($videos,0,20);
@ -45,14 +56,14 @@ echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
<description>Latest videos from MVLog Bubulescu.Org</description>
<language>en</language>
<lastBuildDate><?=date(DATE_RSS)?></lastBuildDate>
<?php foreach($videos as $v): $name=basename($v); $m=video_metadata($v); $url=$baseUrl.'/out-dir/'.rawurlencode($name); $desc=trim(($m['location'] ? $m['location'].'. ' : '').$m['description']); ?>
<?php foreach($videos as $v): $name=basename($v); $m=video_metadata($v); $videoUrl=$baseUrl.'/out-dir/'.rawurlencode($name); $articlePath=article_permalink_for_video($config,$name,$permalinkMap); $url=$articlePath!=='' ? ('https://bubulescu.org'.$articlePath) : $videoUrl; $desc=trim(($m['location'] ? $m['location'].'. ' : '').$m['description']); ?>
<item>
<title><?=x($m['title'])?></title>
<link><?=x($url)?></link>
<guid isPermaLink="true"><?=x($url)?></guid>
<pubDate><?=date(DATE_RSS, filemtime($v))?></pubDate>
<description><?=x($desc)?></description>
<enclosure url="<?=x($url)?>" length="<?=filesize($v)?>" type="video/mp4" />
<enclosure url="<?=x($videoUrl)?>" length="<?=filesize($v)?>" type="video/mp4" />
</item>
<?php endforeach; ?>
</channel>