 edit this file to name it for gitweb.</title>
<meta name='generator' content='cgit v1.2.3'/>
<meta name='robots' content='index, nofollow'/>
<link rel='stylesheet' type='text/css' href='/cgit-css/cgit.css'/>
<link rel='stylesheet' type='text/css' href='/cgit-local/local.css'/>
<script type='text/javascript' src='/cgit.js'></script>
<link rel='shortcut icon' href='/favicon.ico'/>
<link rel='alternate' title='Atom feed' href='https://source.jones.dk/ikiwiki-upstream/atom/IkiWiki/Plugin/amazon_s3.pm?h=master' type='application/atom+xml'/>
<link rel='vcs-git' href='https://source.jones.dk/ikiwiki-upstream' title='ikiwiki-upstream Git repository'/>
<link rel='vcs-git' href='user@source.jones.dk:ikiwiki-upstream' title='ikiwiki-upstream Git repository'/>
</head>
<body>
<div id='cgit'><table id='header'>
<tr>
<td class='logo' rowspan='2'><a href='/'><img src='/cgit-css/cgit.png' alt='cgit logo'/></a></td>
<td class='main'><a href='/'>index</a> : <a href='/ikiwiki-upstream/'>ikiwiki-upstream</a></td><td class='form'><form method='get'>
<input type='hidden' name='id' value='e6d130877bb374abe9721e497f0d4868b6c952d8'/><select name='h' onchange='this.form.submit();'>
<option value='layoutgala'>layoutgala</option>
<option value='master' selected='selected'>master</option>
</select> <input type='submit' value='switch'/></form></td></tr>
<tr><td class='sub'>Unnamed repository; edit this file to name it for gitweb.</td><td class='sub right'>Jonas Smedegaard</td></tr></table>
<table class='tabs'><tr><td>
<a href='/ikiwiki-upstream/'>summary</a><a href='/ikiwiki-upstream/refs/?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>refs</a><a href='/ikiwiki-upstream/log/IkiWiki/Plugin/amazon_s3.pm'>log</a><a class='active' href='/ikiwiki-upstream/tree/IkiWiki/Plugin/amazon_s3.pm?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>tree</a><a href='/ikiwiki-upstream/commit/IkiWiki/Plugin/amazon_s3.pm?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>commit</a><a href='/ikiwiki-upstream/diff/IkiWiki/Plugin/amazon_s3.pm?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>diff</a></td><td class='form'><form class='right' method='get' action='/ikiwiki-upstream/log/IkiWiki/Plugin/amazon_s3.pm'>
<input type='hidden' name='id' value='e6d130877bb374abe9721e497f0d4868b6c952d8'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/ikiwiki-upstream/tree/?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>root</a>/<a href='/ikiwiki-upstream/tree/IkiWiki?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>IkiWiki</a>/<a href='/ikiwiki-upstream/tree/IkiWiki/Plugin?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>Plugin</a>/<a href='/ikiwiki-upstream/tree/IkiWiki/Plugin/amazon_s3.pm?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>amazon_s3.pm</a></div><div class='content'>blob: cfd8cd3477f81dd0758564994f35979419e330a0 (<a href='/ikiwiki-upstream/plain/IkiWiki/Plugin/amazon_s3.pm?id=e6d130877bb374abe9721e497f0d4868b6c952d8'>plain</a>)
<table summary='blob content' class='blob'>
<tr>
<td class='lines'><pre><code><ol class="hl">
<li id="n_1" class="hl"><span class="hl slc">#!/usr/bin/perl</span></li>
<li id="n_2" class="hl"><span class="hl kwa">package&nbsp;</span>IkiWiki<span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">;</span></li>
<li id="n_3" class="hl"></li>
<li id="n_4" class="hl"><span class="hl kwa">use </span>warnings<span class="hl opt">;</span></li>
<li id="n_5" class="hl"><span class="hl kwa">no </span>warnings <span class="hl sng">&#39;redefine&#39;</span><span class="hl opt">;</span></li>
<li id="n_6" class="hl"><span class="hl kwa">use </span>strict<span class="hl opt">;</span></li>
<li id="n_7" class="hl"><span class="hl kwa">use </span>IkiWiki <span class="hl num">3.00</span><span class="hl opt">;</span></li>
<li id="n_8" class="hl"><span class="hl kwa">use </span>IkiWiki<span class="hl opt">::</span>Render<span class="hl opt">;</span></li>
<li id="n_9" class="hl"><span class="hl kwa">use </span>Net<span class="hl opt">::</span>Amazon<span class="hl opt">::</span>S3<span class="hl opt">;</span></li>
<li id="n_10" class="hl"></li>
<li id="n_11" class="hl"><span class="hl slc"># Store references to real subs before overriding them.</span></li>
<li id="n_12" class="hl"><span class="hl kwc">our </span><span class="hl kwb">%subs</span><span class="hl opt">;</span></li>
<li id="n_13" class="hl"><span class="hl kwa">BEGIN </span><span class="hl opt">{</span></li>
<li id="n_14" class="hl">    <span class="hl kwa">foreach </span><span class="hl kwc">my </span><span class="hl kwb">$sub </span><span class="hl opt">(</span><span class="hl sng">qw{IkiWiki::writefile IkiWiki::prune}</span><span class="hl opt">) {</span></li>
<li id="n_15" class="hl">        <span class="hl kwb">$subs</span><span class="hl opt">{</span><span class="hl kwb">$sub</span><span class="hl opt">}=</span>\<span class="hl opt">&amp;</span><span class="hl kwb">$sub</span><span class="hl opt">;</span></li>
<li id="n_16" class="hl">    <span class="hl opt">}</span></li>
<li id="n_17" class="hl"><span class="hl opt">};</span></li>
<li id="n_18" class="hl"></li>
<li id="n_19" class="hl"><span class="hl kwa">sub </span>import <span class="hl opt">{</span></li>
<li id="n_20" class="hl">    hook<span class="hl opt">(</span>type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;getopt&quot;</span><span class="hl opt">, </span>id <span class="hl opt">=&gt; </span><span class="hl sng">&quot;amazon_s3&quot;</span><span class="hl opt">, </span>call <span class="hl opt">=&gt; </span>\<span class="hl opt">&amp;</span>getopt<span class="hl opt">);</span></li>
<li id="n_21" class="hl">    hook<span class="hl opt">(</span>type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;getsetup&quot;</span><span class="hl opt">, </span>id <span class="hl opt">=&gt; </span><span class="hl sng">&quot;amazon_s3&quot;</span><span class="hl opt">, </span>call <span class="hl opt">=&gt; </span>\<span class="hl opt">&amp;</span>getsetup<span class="hl opt">);</span></li>
<li id="n_22" class="hl">    hook<span class="hl opt">(</span>type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;checkconfig&quot;</span><span class="hl opt">, </span>id <span class="hl opt">=&gt; </span><span class="hl sng">&quot;amazon_s3&quot;</span><span class="hl opt">, </span>call <span class="hl opt">=&gt; </span>\<span class="hl opt">&amp;</span>checkconfig<span class="hl opt">);</span></li>
<li id="n_23" class="hl"><span class="hl opt">}</span></li>
<li id="n_24" class="hl"></li>
<li id="n_25" class="hl"><span class="hl kwa">sub </span>getopt <span class="hl opt">() {</span></li>
<li id="n_26" class="hl">        <span class="hl kwc">eval </span><span class="hl sng">q{use Getopt::Long}</span><span class="hl opt">;</span></li>
<li id="n_27" class="hl">        error<span class="hl opt">(</span><span class="hl kwb">$&#64;</span><span class="hl opt">) </span><span class="hl kwa">if </span><span class="hl kwb">$&#64;</span><span class="hl opt">;</span></li>
<li id="n_28" class="hl">        Getopt<span class="hl opt">::</span>Long<span class="hl opt">::</span>Configure<span class="hl opt">(</span><span class="hl sng">&#39;pass_through&#39;</span><span class="hl opt">);</span></li>
<li id="n_29" class="hl">        GetOptions<span class="hl opt">(</span><span class="hl sng">&quot;delete-bucket&quot;</span> <span class="hl opt">=&gt; </span><span class="hl kwa">sub </span><span class="hl opt">{</span></li>
<li id="n_30" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$bucket</span><span class="hl opt">=</span>getbucket<span class="hl opt">();</span></li>
<li id="n_31" class="hl">        debug<span class="hl opt">(</span>gettext<span class="hl opt">(</span><span class="hl sng">&quot;deleting bucket..&quot;</span><span class="hl opt">));</span></li>
<li id="n_32" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$resp </span><span class="hl opt">= </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">list_all </span><span class="hl kwc">or die </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">err </span><span class="hl opt">. </span><span class="hl sng">&quot;: &quot;</span> <span class="hl opt">. </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">errstr</span><span class="hl opt">;</span></li>
<li id="n_33" class="hl">        <span class="hl kwa">foreach </span><span class="hl kwc">my </span><span class="hl kwb">$key </span><span class="hl opt">(&#64;{</span><span class="hl kwb">$resp</span><span class="hl opt">-&gt;{</span><span class="hl kwc">keys</span><span class="hl opt">}}) {</span></li>
<li id="n_34" class="hl">            debug<span class="hl opt">(</span><span class="hl sng">&quot;</span><span class="hl esc">\t</span><span class="hl sng">&quot;</span><span class="hl opt">.</span><span class="hl kwb">$key</span><span class="hl opt">-&gt;{</span>key<span class="hl opt">});</span></li>
<li id="n_35" class="hl">            <span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">delete_key</span><span class="hl opt">(</span><span class="hl kwb">$key</span><span class="hl opt">-&gt;{</span>key<span class="hl opt">}) </span><span class="hl kwc">or die </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">err </span><span class="hl opt">. </span><span class="hl sng">&quot;: &quot;</span> <span class="hl opt">. </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">errstr</span><span class="hl opt">;</span></li>
<li id="n_36" class="hl">        <span class="hl opt">}</span></li>
<li id="n_37" class="hl">        <span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">delete_bucket </span><span class="hl kwc">or die </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">err </span><span class="hl opt">. </span><span class="hl sng">&quot;: &quot;</span> <span class="hl opt">. </span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">errstr</span><span class="hl opt">;</span></li>
<li id="n_38" class="hl">        debug<span class="hl opt">(</span>gettext<span class="hl opt">(</span><span class="hl sng">&quot;done&quot;</span><span class="hl opt">));</span></li>
<li id="n_39" class="hl">        <span class="hl kwa">exit</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">);</span></li>
<li id="n_40" class="hl">    <span class="hl opt">});</span></li>
<li id="n_41" class="hl"><span class="hl opt">}</span></li>
<li id="n_42" class="hl"></li>
<li id="n_43" class="hl"><span class="hl kwa">sub </span>getsetup <span class="hl opt">() {</span></li>
<li id="n_44" class="hl">    <span class="hl kwa">return</span></li>
<li id="n_45" class="hl">        plugin <span class="hl opt">=&gt; {</span></li>
<li id="n_46" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">0</span><span class="hl opt">,</span></li>
<li id="n_47" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">0</span><span class="hl opt">,</span></li>
<li id="n_48" class="hl">        <span class="hl opt">},</span></li>
<li id="n_49" class="hl">        amazon_s3_key_id <span class="hl opt">=&gt; {</span></li>
<li id="n_50" class="hl">            type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;string&quot;</span><span class="hl opt">,</span></li>
<li id="n_51" class="hl">            example <span class="hl opt">=&gt; </span><span class="hl sng">&quot;XXXXXXXXXXXXXXXXXXXX&quot;</span><span class="hl opt">,</span></li>
<li id="n_52" class="hl">            description <span class="hl opt">=&gt; </span><span class="hl sng">&quot;public access key id&quot;</span><span class="hl opt">,</span></li>
<li id="n_53" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_54" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">0</span><span class="hl opt">,</span></li>
<li id="n_55" class="hl">        <span class="hl opt">},</span></li>
<li id="n_56" class="hl">        amazon_s3_key_id <span class="hl opt">=&gt; {</span></li>
<li id="n_57" class="hl">            type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;string&quot;</span><span class="hl opt">,</span></li>
<li id="n_58" class="hl">            example <span class="hl opt">=&gt; </span><span class="hl sng">&quot;</span><span class="hl ipl">$ENV</span><span class="hl sng">{HOME}/.s3_key&quot;</span><span class="hl opt">,</span></li>
<li id="n_59" class="hl">            description <span class="hl opt">=&gt; </span><span class="hl sng">&quot;file holding secret key (must not be readable by others!)&quot;</span><span class="hl opt">,</span></li>
<li id="n_60" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">0</span><span class="hl opt">, </span><span class="hl slc"># ikiwiki reads this file</span></li>
<li id="n_61" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">0</span><span class="hl opt">,</span></li>
<li id="n_62" class="hl">        <span class="hl opt">},</span></li>
<li id="n_63" class="hl">        amazon_s3_bucket <span class="hl opt">=&gt; {</span></li>
<li id="n_64" class="hl">            type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;string&quot;</span><span class="hl opt">,</span></li>
<li id="n_65" class="hl">            example <span class="hl opt">=&gt; </span><span class="hl sng">&quot;mywiki&quot;</span><span class="hl opt">,</span></li>
<li id="n_66" class="hl">            description <span class="hl opt">=&gt; </span><span class="hl sng">&quot;globally unique name of bucket to store wiki in&quot;</span><span class="hl opt">,</span></li>
<li id="n_67" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_68" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_69" class="hl">        <span class="hl opt">},</span></li>
<li id="n_70" class="hl">        amazon_s3_prefix <span class="hl opt">=&gt; {</span></li>
<li id="n_71" class="hl">            type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;string&quot;</span><span class="hl opt">,</span></li>
<li id="n_72" class="hl">            example <span class="hl opt">=&gt; </span><span class="hl sng">&quot;wiki/&quot;</span><span class="hl opt">,</span></li>
<li id="n_73" class="hl">            description <span class="hl opt">=&gt; </span><span class="hl sng">&quot;a prefix to prepend to each page name&quot;</span><span class="hl opt">,</span></li>
<li id="n_74" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_75" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_76" class="hl">        <span class="hl opt">},</span></li>
<li id="n_77" class="hl">        amazon_s3_location <span class="hl opt">=&gt; {</span></li>
<li id="n_78" class="hl">            type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;string&quot;</span><span class="hl opt">,</span></li>
<li id="n_79" class="hl">            example <span class="hl opt">=&gt; </span><span class="hl sng">&quot;EU&quot;</span><span class="hl opt">,</span></li>
<li id="n_80" class="hl">            description <span class="hl opt">=&gt; </span><span class="hl sng">&quot;which S3 datacenter to use (leave blank for default)&quot;</span><span class="hl opt">,</span></li>
<li id="n_81" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_82" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_83" class="hl">        <span class="hl opt">},</span></li>
<li id="n_84" class="hl">        amazon_s3_dupindex <span class="hl opt">=&gt; {</span></li>
<li id="n_85" class="hl">            type <span class="hl opt">=&gt; </span><span class="hl sng">&quot;boolean&quot;</span><span class="hl opt">,</span></li>
<li id="n_86" class="hl">            example <span class="hl opt">=&gt; </span><span class="hl num">0</span><span class="hl opt">,</span></li>
<li id="n_87" class="hl">            description <span class="hl opt">=&gt; </span><span class="hl sng">&quot;store each index file twice? (allows urls ending in </span><span class="hl esc">\&quot;</span><span class="hl sng">/index.html</span><span class="hl esc">\&quot; </span><span class="hl sng">and </span><span class="hl esc">\&quot;</span><span class="hl sng">/</span><span class="hl esc">\&quot;</span><span class="hl sng">)&quot;</span><span class="hl opt">,</span></li>
<li id="n_88" class="hl">            safe <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_89" class="hl">            rebuild <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_90" class="hl">        <span class="hl opt">},</span></li>
<li id="n_91" class="hl"><span class="hl opt">}</span></li>
<li id="n_92" class="hl"></li>
<li id="n_93" class="hl"><span class="hl kwa">sub </span>checkconfig <span class="hl opt">{</span></li>
<li id="n_94" class="hl">    <span class="hl kwa">foreach </span><span class="hl kwc">my </span><span class="hl kwb">$field </span><span class="hl opt">(</span><span class="hl sng">qw{amazon_s3_key_id amazon_s3_key_file</span></li>
<li id="n_95" class="hl"><span class="hl sng">                          amazon_s3_bucket}</span><span class="hl opt">) {</span></li>
<li id="n_96" class="hl">        <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwc">exists </span><span class="hl kwb">$config</span><span class="hl opt">{</span><span class="hl kwb">$field</span><span class="hl opt">} || ! </span><span class="hl kwc">defined </span><span class="hl kwb">$config</span><span class="hl opt">{</span><span class="hl kwb">$field</span><span class="hl opt">}) {</span></li>
<li id="n_97" class="hl">            error<span class="hl opt">(</span><span class="hl kwc">sprintf</span><span class="hl opt">(</span>gettext<span class="hl opt">(</span><span class="hl sng">&quot;Must specify </span><span class="hl ipl">%s</span><span class="hl sng">&quot;</span><span class="hl opt">), </span><span class="hl kwb">$field</span><span class="hl opt">));</span></li>
<li id="n_98" class="hl">        <span class="hl opt">}</span></li>
<li id="n_99" class="hl">    <span class="hl opt">}</span></li>
<li id="n_100" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwc">exists </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_prefix<span class="hl opt">} ||</span></li>
<li id="n_101" class="hl">        <span class="hl opt">! </span><span class="hl kwc">defined </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_prefix<span class="hl opt">}) {</span></li>
<li id="n_102" class="hl">        <span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_prefix<span class="hl opt">}=</span><span class="hl sng">&quot;wiki/&quot;</span><span class="hl opt">;</span></li>
<li id="n_103" class="hl">    <span class="hl opt">}</span></li>
<li id="n_104" class="hl"><span class="hl opt">}</span></li>
<li id="n_105" class="hl"></li>
<li id="n_106" class="hl"><span class="hl opt">{</span></li>
<li id="n_107" class="hl"><span class="hl kwc">my </span><span class="hl kwb">$bucket</span><span class="hl opt">;</span></li>
<li id="n_108" class="hl"><span class="hl kwa">sub </span>getbucket <span class="hl opt">{</span></li>
<li id="n_109" class="hl">    <span class="hl kwa">return </span><span class="hl kwb">$bucket </span><span class="hl kwa">if </span><span class="hl kwc">defined </span><span class="hl kwb">$bucket</span><span class="hl opt">;</span></li>
<li id="n_110" class="hl">    </li>
<li id="n_111" class="hl">    <span class="hl kwc">open</span><span class="hl opt">(</span>IN<span class="hl opt">, </span><span class="hl sng">&quot;&lt;&quot;</span><span class="hl opt">, </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_key_file<span class="hl opt">}) || </span>error<span class="hl opt">(</span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_key_file<span class="hl opt">}.</span><span class="hl sng">&quot;: &quot;</span><span class="hl opt">.</span><span class="hl kwb">$!</span><span class="hl opt">);</span></li>
<li id="n_112" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">$key</span><span class="hl opt">=&lt;</span>IN<span class="hl opt">&gt;;</span></li>
<li id="n_113" class="hl">    <span class="hl kwc">chomp </span><span class="hl kwb">$key</span><span class="hl opt">;</span></li>
<li id="n_114" class="hl">    <span class="hl kwc">close </span>IN<span class="hl opt">;</span></li>
<li id="n_115" class="hl"></li>
<li id="n_116" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">$s3</span><span class="hl opt">=</span>Net<span class="hl opt">::</span>Amazon<span class="hl opt">::</span>S3-<span class="hl opt">&gt;</span><span class="hl kwd">new</span><span class="hl opt">({</span></li>
<li id="n_117" class="hl">        aws_access_key_id <span class="hl opt">=&gt; </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_key_id<span class="hl opt">},</span></li>
<li id="n_118" class="hl">        aws_secret_access_key <span class="hl opt">=&gt; </span><span class="hl kwb">$key</span><span class="hl opt">,</span></li>
<li id="n_119" class="hl">        retry <span class="hl opt">=&gt; </span><span class="hl num">1</span><span class="hl opt">,</span></li>
<li id="n_120" class="hl">    <span class="hl opt">});</span></li>
<li id="n_121" class="hl"></li>
<li id="n_122" class="hl">    <span class="hl slc"># make sure the bucket exists</span></li>
<li id="n_123" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(</span><span class="hl kwc">exists </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_location<span class="hl opt">}) {</span></li>
<li id="n_124" class="hl">        <span class="hl kwb">$bucket</span><span class="hl opt">=</span><span class="hl kwb">$s3</span><span class="hl opt">-&gt;</span><span class="hl kwd">add_bucket</span><span class="hl opt">({</span></li>
<li id="n_125" class="hl">            bucket <span class="hl opt">=&gt; </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_bucket<span class="hl opt">},</span></li>
<li id="n_126" class="hl">            location_constraint <span class="hl opt">=&gt; </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_location<span class="hl opt">},</span></li>
<li id="n_127" class="hl">        <span class="hl opt">});</span></li>
<li id="n_128" class="hl">    <span class="hl opt">}</span></li>
<li id="n_129" class="hl">    <span class="hl kwa">else </span><span class="hl opt">{</span></li>
<li id="n_130" class="hl">        <span class="hl kwb">$bucket</span><span class="hl opt">=</span><span class="hl kwb">$s3</span><span class="hl opt">-&gt;</span><span class="hl kwd">add_bucket</span><span class="hl opt">({</span></li>
<li id="n_131" class="hl">            bucket <span class="hl opt">=&gt; </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_bucket<span class="hl opt">},</span></li>
<li id="n_132" class="hl">        <span class="hl opt">});</span></li>
<li id="n_133" class="hl">    <span class="hl opt">}</span></li>
<li id="n_134" class="hl"></li>
<li id="n_135" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwb">$bucket</span><span class="hl opt">) {</span></li>
<li id="n_136" class="hl">        <span class="hl slc"># Try to use existing bucket.</span></li>
<li id="n_137" class="hl">        <span class="hl kwb">$bucket</span><span class="hl opt">=</span><span class="hl kwb">$s3</span><span class="hl opt">-&gt;</span><span class="hl kwd">bucket</span><span class="hl opt">(</span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_bucket<span class="hl opt">});</span></li>
<li id="n_138" class="hl">    <span class="hl opt">}</span></li>
<li id="n_139" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwb">$bucket</span><span class="hl opt">) {</span></li>
<li id="n_140" class="hl">        error<span class="hl opt">(</span>gettext<span class="hl opt">(</span><span class="hl sng">&quot;Failed to create S3 bucket: &quot;</span><span class="hl opt">).</span></li>
<li id="n_141" class="hl">            <span class="hl kwb">$s3</span><span class="hl opt">-&gt;</span><span class="hl kwd">err</span><span class="hl opt">.</span><span class="hl sng">&quot;: &quot;</span><span class="hl opt">.</span><span class="hl kwb">$s3</span><span class="hl opt">-&gt;</span><span class="hl kwd">errstr</span><span class="hl opt">.</span><span class="hl sng">&quot;</span><span class="hl esc">\n</span><span class="hl sng">&quot;</span><span class="hl opt">);</span></li>
<li id="n_142" class="hl">    <span class="hl opt">}</span></li>
<li id="n_143" class="hl"></li>
<li id="n_144" class="hl">    <span class="hl kwa">return </span><span class="hl kwb">$bucket</span><span class="hl opt">;</span></li>
<li id="n_145" class="hl"><span class="hl opt">}</span></li>
<li id="n_146" class="hl"><span class="hl opt">}</span></li>
<li id="n_147" class="hl"></li>
<li id="n_148" class="hl"><span class="hl slc"># Given a file, return any S3 keys associated with it.</span></li>
<li id="n_149" class="hl"><span class="hl kwa">sub </span>file2keys <span class="hl opt">($) {</span></li>
<li id="n_150" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">$file</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_151" class="hl"></li>
<li id="n_152" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">&#64;keys</span><span class="hl opt">;</span></li>
<li id="n_153" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(</span><span class="hl kwb">$file </span><span class="hl opt">=~ </span><span class="hl kwd">/^\Q$config{destdir}\/</span>\E<span class="hl opt">(.*)/) {</span></li>
<li id="n_154" class="hl">        <span class="hl kwc">push </span><span class="hl kwb">&#64;keys</span><span class="hl opt">, </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_prefix<span class="hl opt">}.</span><span class="hl kwb">$1</span><span class="hl opt">;</span></li>
<li id="n_155" class="hl"></li>
<li id="n_156" class="hl">        <span class="hl slc"># Munge foo/index.html to foo/</span></li>
<li id="n_157" class="hl">        <span class="hl kwa">if </span><span class="hl opt">(</span><span class="hl kwb">$keys</span><span class="hl opt">[</span><span class="hl num">0</span><span class="hl opt">]=~</span><span class="hl kwd">/(^|.*\/</span><span class="hl opt">)</span><span class="hl kwc">index</span><span class="hl opt">.</span><span class="hl kwb">$config</span><span class="hl opt">{</span>htmlext<span class="hl opt">}</span><span class="hl kwb">$/</span><span class="hl opt">) {</span></li>
<li id="n_158" class="hl">            <span class="hl slc"># A duplicate might need to be stored under the</span></li>
<li id="n_159" class="hl">            <span class="hl slc"># unmunged name too.</span></li>
<li id="n_160" class="hl">            <span class="hl kwa">if </span><span class="hl opt">(!</span><span class="hl kwb">$config</span><span class="hl opt">{</span>usedirs<span class="hl opt">} || </span><span class="hl kwb">$config</span><span class="hl opt">{</span>amazon_s3_dupindex<span class="hl opt">}) {</span></li>
<li id="n_161" class="hl">                <span class="hl kwc">push </span><span class="hl kwb">&#64;keys</span><span class="hl opt">, </span><span class="hl kwb">$1</span><span class="hl opt">;</span></li>
<li id="n_162" class="hl">            <span class="hl opt">}</span></li>
<li id="n_163" class="hl">            <span class="hl kwa">else </span><span class="hl opt">{</span></li>
<li id="n_164" class="hl">                <span class="hl kwb">&#64;keys</span><span class="hl opt">=(</span><span class="hl kwb">$1</span><span class="hl opt">);</span></li>
<li id="n_165" class="hl">            <span class="hl opt">}</span></li>
<li id="n_166" class="hl">        <span class="hl opt">}</span></li>
<li id="n_167" class="hl">    <span class="hl opt">}</span></li>
<li id="n_168" class="hl">    <span class="hl kwa">return </span><span class="hl kwb">&#64;keys</span><span class="hl opt">;</span></li>
<li id="n_169" class="hl"><span class="hl opt">}</span></li>
<li id="n_170" class="hl"></li>
<li id="n_171" class="hl"><span class="hl kwa">package </span>IkiWiki<span class="hl opt">;</span></li>
<li id="n_172" class="hl"><span class="hl kwa">use </span>File<span class="hl opt">::</span>MimeInfo<span class="hl opt">;</span></li>
<li id="n_173" class="hl"><span class="hl kwa">use </span>Encode<span class="hl opt">;</span></li>
<li id="n_174" class="hl"></li>
<li id="n_175" class="hl"><span class="hl slc"># This is a wrapper around the real writefile.</span></li>
<li id="n_176" class="hl"><span class="hl kwa">sub </span>writefile <span class="hl opt">(</span><span class="hl kwb">$$$</span><span class="hl opt">;</span><span class="hl kwb">$$</span><span class="hl opt">) {</span></li>
<li id="n_177" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$file</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_178" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$destdir</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_179" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$content</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_180" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$binary</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_181" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$writer</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_182" class="hl"></li>
<li id="n_183" class="hl">    <span class="hl slc"># First, write the file to disk.</span></li>
<li id="n_184" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">$ret</span><span class="hl opt">=</span><span class="hl kwb">$IkiWiki</span><span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">::</span>subs<span class="hl opt">{</span><span class="hl sng">&#39;IkiWiki::writefile&#39;</span><span class="hl opt">}-&gt;(</span><span class="hl kwb">$file</span><span class="hl opt">, </span><span class="hl kwb">$destdir</span><span class="hl opt">, </span><span class="hl kwb">$content</span><span class="hl opt">, </span><span class="hl kwb">$binary</span><span class="hl opt">, </span><span class="hl kwb">$writer</span><span class="hl opt">);</span></li>
<li id="n_185" class="hl"></li>
<li id="n_186" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">&#64;keys</span><span class="hl opt">=</span>IkiWiki<span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">::</span>file2keys<span class="hl opt">(</span><span class="hl sng">&quot;</span><span class="hl ipl">$destdir/$file</span><span class="hl sng">&quot;</span><span class="hl opt">);</span></li>
<li id="n_187" class="hl"></li>
<li id="n_188" class="hl">    <span class="hl slc"># Store the data in S3.</span></li>
<li id="n_189" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(</span><span class="hl kwb">&#64;keys</span><span class="hl opt">) {</span></li>
<li id="n_190" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$bucket</span><span class="hl opt">=</span>IkiWiki<span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">::</span>getbucket<span class="hl opt">();</span></li>
<li id="n_191" class="hl"></li>
<li id="n_192" class="hl">        <span class="hl slc"># The http layer tries to downgrade utf-8</span></li>
<li id="n_193" class="hl">        <span class="hl slc"># content, but that can fail (see</span></li>
<li id="n_194" class="hl">        <span class="hl slc"># http://rt.cpan.org/Ticket/Display.html?id=35710),</span></li>
<li id="n_195" class="hl">        <span class="hl slc"># so force convert it to bytes.</span></li>
<li id="n_196" class="hl">        <span class="hl kwb">$content</span><span class="hl opt">=</span>encode_utf8<span class="hl opt">(</span><span class="hl kwb">$content</span><span class="hl opt">) </span><span class="hl kwa">if </span><span class="hl kwc">defined </span><span class="hl kwb">$content</span><span class="hl opt">;</span></li>
<li id="n_197" class="hl"></li>
<li id="n_198" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">%opts</span><span class="hl opt">=(</span></li>
<li id="n_199" class="hl">            acl_short <span class="hl opt">=&gt; </span><span class="hl sng">&#39;public-read&#39;</span><span class="hl opt">,</span></li>
<li id="n_200" class="hl">            content_type <span class="hl opt">=&gt; </span>mimetype<span class="hl opt">(</span><span class="hl sng">&quot;</span><span class="hl ipl">$destdir/$file</span><span class="hl sng">&quot;</span><span class="hl opt">),</span></li>
<li id="n_201" class="hl">        <span class="hl opt">);</span></li>
<li id="n_202" class="hl"></li>
<li id="n_203" class="hl">        <span class="hl slc"># If there are multiple keys to write, data is sent</span></li>
<li id="n_204" class="hl">        <span class="hl slc"># multiple times.</span></li>
<li id="n_205" class="hl">        <span class="hl slc"># TODO: investigate using the new copy operation.</span></li>
<li id="n_206" class="hl">        <span class="hl slc">#       (It may not be robust enough.)</span></li>
<li id="n_207" class="hl">        <span class="hl kwa">foreach </span><span class="hl kwc">my </span><span class="hl kwb">$key </span><span class="hl opt">(</span><span class="hl kwb">&#64;keys</span><span class="hl opt">) {</span></li>
<li id="n_208" class="hl">            <span class="hl kwc">my </span><span class="hl kwb">$res</span><span class="hl opt">;</span></li>
<li id="n_209" class="hl">            <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwb">$writer</span><span class="hl opt">) {</span></li>
<li id="n_210" class="hl">                <span class="hl kwb">$res</span><span class="hl opt">=</span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">add_key</span><span class="hl opt">(</span><span class="hl kwb">$key</span><span class="hl opt">, </span><span class="hl kwb">$content</span><span class="hl opt">, </span>\<span class="hl kwb">%opts</span><span class="hl opt">);</span></li>
<li id="n_211" class="hl">            <span class="hl opt">}</span></li>
<li id="n_212" class="hl">            <span class="hl kwa">else </span><span class="hl opt">{</span></li>
<li id="n_213" class="hl">                <span class="hl slc"># This test for empty files is a workaround</span></li>
<li id="n_214" class="hl">                <span class="hl slc"># for this bug:</span></li>
<li id="n_215" class="hl">                <span class="hl slc"># http://rt.cpan.org//Ticket/Display.html?id=35731</span></li>
<li id="n_216" class="hl">                <span class="hl kwa">if </span><span class="hl opt">(-</span>z <span class="hl sng">&quot;</span><span class="hl ipl">$destdir/$file</span><span class="hl sng">&quot;</span><span class="hl opt">) {</span></li>
<li id="n_217" class="hl">                    <span class="hl kwb">$res</span><span class="hl opt">=</span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">add_key</span><span class="hl opt">(</span><span class="hl kwb">$key</span><span class="hl opt">, </span><span class="hl sng">&quot;&quot;</span><span class="hl opt">, </span>\<span class="hl kwb">%opts</span><span class="hl opt">);</span></li>
<li id="n_218" class="hl">                <span class="hl opt">}</span></li>
<li id="n_219" class="hl">                <span class="hl kwa">else </span><span class="hl opt">{</span></li>
<li id="n_220" class="hl">                    <span class="hl slc"># read back in the file that the writer emitted</span></li>
<li id="n_221" class="hl">                    <span class="hl kwb">$res</span><span class="hl opt">=</span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">add_key_filename</span><span class="hl opt">(</span><span class="hl kwb">$key</span><span class="hl opt">, </span><span class="hl sng">&quot;</span><span class="hl ipl">$destdir/$file</span><span class="hl sng">&quot;</span><span class="hl opt">, </span>\<span class="hl kwb">%opts</span><span class="hl opt">);</span></li>
<li id="n_222" class="hl">                <span class="hl opt">}</span></li>
<li id="n_223" class="hl">            <span class="hl opt">}</span></li>
<li id="n_224" class="hl">            <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwb">$res</span><span class="hl opt">) {</span></li>
<li id="n_225" class="hl">                error<span class="hl opt">(</span>gettext<span class="hl opt">(</span><span class="hl sng">&quot;Failed to save file to S3: &quot;</span><span class="hl opt">).</span></li>
<li id="n_226" class="hl">                    <span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">err</span><span class="hl opt">.</span><span class="hl sng">&quot;: &quot;</span><span class="hl opt">.</span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">errstr</span><span class="hl opt">.</span><span class="hl sng">&quot;</span><span class="hl esc">\n</span><span class="hl sng">&quot;</span><span class="hl opt">);</span></li>
<li id="n_227" class="hl">            <span class="hl opt">}</span></li>
<li id="n_228" class="hl">        <span class="hl opt">}</span></li>
<li id="n_229" class="hl">    <span class="hl opt">}</span></li>
<li id="n_230" class="hl"></li>
<li id="n_231" class="hl">    <span class="hl kwa">return </span><span class="hl kwb">$ret</span><span class="hl opt">;</span></li>
<li id="n_232" class="hl"><span class="hl opt">}</span></li>
<li id="n_233" class="hl"></li>
<li id="n_234" class="hl"><span class="hl slc"># This is a wrapper around the real prune.</span></li>
<li id="n_235" class="hl"><span class="hl kwa">sub </span>prune <span class="hl opt">($) {</span></li>
<li id="n_236" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">$file</span><span class="hl opt">=</span><span class="hl kwc">shift</span><span class="hl opt">;</span></li>
<li id="n_237" class="hl"></li>
<li id="n_238" class="hl">    <span class="hl kwc">my </span><span class="hl kwb">&#64;keys</span><span class="hl opt">=</span>IkiWiki<span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">::</span>file2keys<span class="hl opt">(</span><span class="hl kwb">$file</span><span class="hl opt">);</span></li>
<li id="n_239" class="hl"></li>
<li id="n_240" class="hl">    <span class="hl slc"># Prune files out of S3 too.</span></li>
<li id="n_241" class="hl">    <span class="hl kwa">if </span><span class="hl opt">(</span><span class="hl kwb">&#64;keys</span><span class="hl opt">) {</span></li>
<li id="n_242" class="hl">        <span class="hl kwc">my </span><span class="hl kwb">$bucket</span><span class="hl opt">=</span>IkiWiki<span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">::</span>getbucket<span class="hl opt">();</span></li>
<li id="n_243" class="hl"></li>
<li id="n_244" class="hl">        <span class="hl kwa">foreach </span><span class="hl kwc">my </span><span class="hl kwb">$key </span><span class="hl opt">(</span><span class="hl kwb">&#64;keys</span><span class="hl opt">) {</span></li>
<li id="n_245" class="hl">            <span class="hl kwc">my </span><span class="hl kwb">$res</span><span class="hl opt">=</span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">delete_key</span><span class="hl opt">(</span><span class="hl kwb">$key</span><span class="hl opt">);</span></li>
<li id="n_246" class="hl">            <span class="hl kwa">if </span><span class="hl opt">(! </span><span class="hl kwb">$res</span><span class="hl opt">) {</span></li>
<li id="n_247" class="hl">                error<span class="hl opt">(</span>gettext<span class="hl opt">(</span><span class="hl sng">&quot;Failed to delete file from S3: &quot;</span><span class="hl opt">).</span></li>
<li id="n_248" class="hl">                    <span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">err</span><span class="hl opt">.</span><span class="hl sng">&quot;: &quot;</span><span class="hl opt">.</span><span class="hl kwb">$bucket</span><span class="hl opt">-&gt;</span><span class="hl kwd">errstr</span><span class="hl opt">.</span><span class="hl sng">&quot;</span><span class="hl esc">\n</span><span class="hl sng">&quot;</span><span class="hl opt">);</span></li>
<li id="n_249" class="hl">            <span class="hl opt">}</span></li>
<li id="n_250" class="hl">        <span class="hl opt">}</span></li>
<li id="n_251" class="hl">    <span class="hl opt">}</span></li>
<li id="n_252" class="hl"></li>
<li id="n_253" class="hl">    <span class="hl kwa">return </span><span class="hl kwb">$IkiWiki</span><span class="hl opt">::</span>Plugin<span class="hl opt">::</span>amazon_s3<span class="hl opt">::</span>subs<span class="hl opt">{</span><span class="hl sng">&#39;IkiWiki::prune&#39;</span><span class="hl opt">}-&gt;(</span><span class="hl kwb">$file</span><span class="hl opt">);</span></li>
<li id="n_254" class="hl"><span class="hl opt">}</span></li>
<li id="n_255" class="hl"></li>
<li id="n_256" class="hl"><span class="hl num">1</span></li>
</ol></code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.46.0</a>) at 2025-06-22 19:57:45 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
