Nightly WebKit auto-updater
Ever since I heard about the WebKit Nightly Builds I wanted a way to automatically update so that I would always be running the latest version of webkit. Well, here ya go.
Requires CURL and ( PHP_Compat or PHP 5 ).
It *should* "just work". But (indemnification coming) i'm not responsible if it erases your hard drive, makes you a peanut butter and jelly sandwich without jelly (or with some crappy skippy peanut butter) or sends insulting messages to random people on your IM buddy list.
$target="http://nightly.webkit.org/builds/Latest-WebKit+SVG-CVS.dmg"; $state_file="/tmp/webkit_cache"; $tmp="/tmp"; $hdiutil="/usr/bin/hdiutil"; $rsync="/usr/bin/rsync"; $name="WebKit+SVG.app"; $applications="/Applications"; $debug=false; $version="0.3.0"; $ref_url="http://blog.adamjacobmuller.com/" ."2005/10/17/nightly-webkit-auto-updater/"; require_once 'PEAR.php'; require_once 'PHP/Compat.php'; PHP_Compat::loadFunction('file_get_contents'); PHP_Compat::loadFunction('file_put_contents'); $url=parse_url($target); $sh=fsockopen($url['host'],80); fwrite($sh,"HEAD ".$url['path']." HTTP/1.1\r\n". "Connection: Close\r\n". "User-Agent: WebKit auto-updater $version ($ref_url)\r\n". "Host: ".$url['host']."\r\n\r\n"); while(!feof($sh)) { $headers.=fread($sh,1024); } preg_match_all("#(.*?): (.*?)\r\n#",$headers,$matches); $headers=array(); foreach($matches[1] as $idx=>$match) { $headers[$match]=$matches[2][$idx]; } $headers['ETag']=trim($headers['ETag'],'"'); $headers['Last-Modified']=strtotime($headers['Last-Modified']); $headers['Date']=strtotime($headers['Date']); if (file_exists($state_file)) { $data=file_get_contents($state_file); $data=unserialize($data); } else { $data['last']['ETag']=""; $data['last']['Last-Modified']=0; $data=array(); } if ( ($data['last']['headers']['ETag']<>$headers['ETag']) &&($data['last']['headers']['Last-Modified']<$headers['Last-Modified']) ) { $tmp=tempnam($tmp,"webkit_"); unlink($tmp); mkdir($tmp,0700); $dmg=$tmp.".dmg"; if ($debug) { $res=link("Latest-WebKit+SVG-CVS.dmg",$dmg); } else { $ch = curl_init($target); $fp = fopen($dmg, "w"); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, "WebKit auto-updater $version ($ref_url)"); $res=curl_exec($ch); $curl_info=curl_getinfo($ch); curl_close($ch); fclose($fp); } if ($res) { $cmd=$hdiutil." attach -mountpoint ".$tmp." ".$dmg; $cmd['attach']=$cmd."\n"; $output['attach']=`$cmd`; $src=$tmp."/".$name."/"; $dst=$applications."/".$name; $cmd=$rsync." -aHv --stats ".$src." ".$dst; $cmd['rsync']=$cmd."\n"; $output['rsync']=`$cmd 2>&1`; $cmd=$hdiutil." detach $tmp"; $cmd['detach']=$cmd."\n"; $output['detach']=`$cmd`; $this=array( "output"=>$output, "headers"=>$headers, "curl"=>$curl_info ); $data['historical'][$this['headers']['Last-Modified']]=$this; $data['last']=&$data['historical'][$this['headers']['Last-Modified']]; $data=serialize($data); file_put_contents($state_file,$data); } else { print "failed $tmp\n\n"; } unlink($dmg); rmdir($tmp); }
You can download it here.
It's pretty robust, it only downloads/upgrades if it has changed, based on the last-modified and ETag headers so you can probably do something like this in cron without pissing anyone off:
0 * * * * /path/to/webkit.php
Kudos to the WebKit people for making their Nightly Builds stable enough to use on a daily basis and for making such a great browser and inspiring technical innovation in a field that is generally satisfied with "good enough".
No Comments »
No comments yet.
RSS feed for comments on this post. TrackBack URI
Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>