Last active
January 1, 2016 21:09
-
-
Save lifthrasiir/8201847 to your computer and use it in GitHub Desktop.
Simple hgwebdir-to-bitbucket translation script for hg.mearie.org
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// hgwebdir.php | |
// Written by Kang Seonghoon, 2014-01-01 (!) | |
// Public domain. No warranty guaranteed. | |
define('YEAR_SCALE', 3600 * 24 * 365); | |
define('MONTH_SCALE', 3600 * 24 * 30); | |
define('WEEK_SCALE', 3600 * 24 * 7); | |
define('DAY_SCALE', 3600 * 24); | |
define('HOUR_SCALE', 3600); | |
define('MINUTE_SCALE', 60); | |
function diff_to_age($date, $now) { | |
// http://selenic.com/hg/file/tip/mercurial/templatefilters.py | |
$diff = $date - $now; | |
$future = ($diff > 0); | |
$absdiff = max(1, intval(abs($diff))); | |
if ($absdiff < 2 * MINUTE_SCALE) { | |
$div = 1; | |
$unit = 'second'; | |
} else if ($absdiff < 2 * HOUR_SCALE) { | |
$div = MINUTE_SCALE; | |
$unit = 'minute'; | |
} else if ($absdiff < 2 * DAY_SCALE) { | |
$div = HOUR_SCALE; | |
$unit = 'hour'; | |
} else if ($absdiff < 2 * WEEK_SCALE) { | |
$div = DAY_SCALE; | |
$unit = 'day'; | |
} else if ($absdiff < 2 * MONTH_SCALE) { | |
$div = WEEK_SCALE; | |
$unit = 'week'; | |
} else if ($absdiff < 2 * YEAR_SCALE) { | |
$div = MONTH_SCALE; | |
$unit = 'month'; | |
} else if (!$future) { | |
return date('Y-m-d', $date); | |
} else if ($absdiff < 30 * YEAR_SCALE) { | |
$div = YEAR_SCALE; | |
$unit = 'year'; | |
} else { | |
return 'in the distant future'; | |
} | |
$n = intval($absdiff / $div); | |
return $n.' '.$unit.($n == 1 ? '' : 's').($future ? ' from now' : ' ago'); | |
} | |
function notfound() { | |
header('HTTP/1.1 404 Not Found'); | |
echo '<!doctype html><html><head><meta charset=utf-8><title>hg.mearie.org</title></head>'; | |
echo '<body><p>Not found.</p><address><a href="http://hg.mearie.org/">hg.mearie.org</a></address></body></html>'; | |
exit; | |
} | |
function gone() { | |
header('HTTP/1.1 410 Gone'); | |
echo '<!doctype html><html><head><meta charset=utf-8><title>hg.mearie.org</title></head>'; | |
echo '<body><p>This repository is gone since it was unused or highly experimental at the moment.</p>'; | |
echo '<address><a href="http://hg.mearie.org/">hg.mearie.org</a></address></body></html>'; | |
exit; | |
} | |
function redirect($url) { | |
header('HTTP/1.1 301 Moved Permanently'); | |
header('Location: '.$url); | |
echo '<!doctype html><html><head><meta charset=utf-8><title>hg.mearie.org</title></head>'; | |
echo '<body><p>Redirecting to <a href="'.htmlspecialchars($url).'">'.htmlspecialchars($url).'</a>...</p>'; | |
echo '<address><a href="http://hg.mearie.org/">hg.mearie.org</a></address></body></html>'; | |
exit; | |
} | |
// change this array to customize (null for 410 Gone) | |
$repomapping = array( | |
'angolmois' => 'angolmois', | |
'delight/core' => 'delight-core', | |
'hangeul.vim' => 'hangeulvim', | |
'sandbox' => null, | |
); | |
$cmdmapping = array( // <cmd> = [<style>-]<maincmd> | |
'log' => '', // either changelog or filelog | |
'atom-log' => 'atom', | |
'rss-log' => 'rss', | |
'rawfile' => 'raw/REV/PATH', | |
'raw-file' => 'raw/REV/PATH', | |
'file' => 'src/REV/PATH', | |
'changelog' => 'commits/all', | |
'shortlog' => 'commits/all', | |
'changeset' => 'commits/REV', | |
'rev' => 'commits/REV', | |
'manifest' => 'src/REV', | |
'tags' => '#tags', | |
'branches' => '#branches', | |
'summary' => '', | |
'filediff' => 'diff/PATH?diff2=REV', | |
'diff' => 'diff/PATH?diff2=REV', | |
'annotate' => 'annotate/REV/PATH', | |
'filelog' => 'history-node/REV/PATH', | |
'archive' => 'get/REV', | |
'graph' => 'commits/all', | |
); | |
$path = preg_replace('#/+#', '/', trim($_SERVER['PATH_INFO'], '/')); | |
if ($path !== '') { | |
foreach ($repomapping as $localpath => $bbpath) { | |
if (substr($path, 0, strlen($localpath)) === $localpath) { | |
$repopath = substr($path, strlen($localpath)); | |
if ($repopath !== '' && $repopath !== false && $repopath[0] !== '/') continue; | |
if (is_null($bbpath)) gone(); | |
$parts = explode('/', substr($repopath, 1), 3); | |
$cmd = (count($parts) > 0 ? $parts[0] : ''); | |
$maincmd = preg_replace('/^(?:.*-)?([^-]*)$/', '\1', $cmd); | |
$rev = (count($parts) > 1 ? $parts[1] : ''); | |
$filepath = (count($parts) > 2 ? $parts[2] : ''); | |
if ($cmd === 'log') $cmd = ($filepath !== '' ? 'filelog' : 'changelog'); | |
if ($rev === '') $rev = 'tip'; | |
$template = (isset($cmdmapping[$cmd]) ? $cmdmapping[$cmd] : | |
(isset($cmdmapping[$maincmd]) ? $cmdmapping[$maincmd] : '')); | |
$template = strtr($template, array('REV' => $rev, 'PATH' => $filepath)); | |
redirect('https://bitbucket.org/lifthrasiir/'.$bbpath.'/'.$template); | |
} | |
} | |
notfound(); | |
} | |
?> | |
<!DOCTYPE html> | |
<html lang="en-US"> | |
<head> | |
<meta charset="utf-8"/> | |
<meta name="generator" content="Mercurial" /> | |
<meta name="robots" content="index, nofollow"/> | |
<link rel="stylesheet" media="screen" href="http://mearie.org/res/hgweb.css" type="text/css" /> | |
<!--[if IE]><link rel="stylesheet" media="screen" href="http://mearie.org/res/hgweb.ie.css" type="text/css" /><![endif]--> | |
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> | |
<script type="text/javascript" src="http://mearie.org/res/global.js"></script> | |
<!--<link rel="shortcut icon" href="/static/hgicon.png" type="image/png" />--> | |
<link rel="shortcut icon" href="http://mearie.org/res/icon-hg.ico" type="image/vnd.microsoft.icon" /> | |
<title>hg.mearie.org</title> | |
</head> | |
<body lang="en" class="lang-en"> | |
<div id="sitebody"> | |
<h1>hg.mearie.org</h1> | |
<p><strong>This is used to be an index to <a href="http://mercurial.selenic.com/">Mercurial</a> repositories hosted by <a href="http://mearie.org/">mearie.org</a></strong>. Unfortunately, due to the frequent server issues, this subdomain is now reduced to an index to <a href="http://bitbucket.org/lifthrasiir/">Bitbucket</a>-powered repositories which are synchronized daily. Sorry for inconvenience.</p> | |
<p>Some of old materials can be found in <a href="http://svn.mearie.org/">Subversion repository</a>, which is neither maintained nor current.</p> | |
<table class="repos"> | |
<?php | |
$parity = 1; | |
$now = time(); | |
define(HGROOT, '/path/to/hg/'); | |
foreach ($repomapping as $localrepo => $bbrepo): | |
if (is_null($bbrepo)) continue; | |
$parity ^= 1; | |
$mtime = filemtime(HGROOT.$localrepo.'/.hg/store/00changelog.i'); | |
$conf = parse_ini_file(HGROOT.$localrepo.'/.hg/hgrc', true, INI_SCANNER_RAW); | |
$age = diff_to_age($mtime, $now); | |
?> | |
<tr class="parity<?=$parity?>"><th><a href="https://bitbucket.org/lifthrasiir/<?=$bbrepo?>"><?=$localrepo?></a></th><td><span class="contact"><?=$conf['web']['contact']?></span><br/><?=$conf['web']['description']?></td><td class="moreinfo"><time class="age" datetime="<?=date('c', $mtime)?>"><?=$age?></time> <span class="shortcuts"><span>|</span> <a rel="nofollow" class="archive" href="https://bitbucket.org/lifthrasiir/<?=$bbrepo?>/get/tip.zip">zip</a> <a rel="nofollow" class="archive" href="https://bitbucket.org/lifthrasiir/<?=$bbrepo?>/get/tip.tar.gz">gz</a> <a class="feed" href="https://bitbucket.org/lifthrasiir/<?=$bbrepo?>/rss">RSS</a> <a class="feed" href="https://bitbucket.org/lifthrasiir/<?=$bbrepo?>/atom">Atom</a></span></td></tr> | |
<? | |
endforeach; | |
?> | |
</table> | |
</div> | |
<hr/> | |
<div id="siteside"> | |
<div class="slogan"> | |
<a href="http://mearie.org/"><img class="logo" src="http://mearie.org/res/logo.png" width="117" height="117" alt="Go to mearie.org front page." /></a> | |
</div> | |
<div class="menu"> | |
<ul> | |
<li><strong><a href="/">hg.mearie.org</a></strong><ul> | |
</ul></li> | |
</ul> | |
</div> | |
</div> | |
<div id="sitemeta"> | |
<div class="tray"> | |
Powered by <a href="http://mercurial.selenic.com/">Mercurial</a> | |
</div> | |
<form action="http://www.google.com/cse" class="search"><div> | |
<input type="hidden" name="cx" value="017879559261112115196:ygyuirvfnku"/> | |
<input type="text" name="q" size="30"/> | |
<input type="submit" name="sa" value="Google Search" class="button"/> | |
</div></form> | |
<div class="copyright">Copyright © 1999–2014 Kang Seonghoon. <a href="http://mearie.org/about/copyright">Some Rights Reserved.</a></div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment