Home | History | Annotate | Download | only in web
      1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
      2 <html> 
      3   <head> 
      4     <meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type"> 
      5     <script language="javascript">
      6       // Split a string in 2 parts. The first is the leading number, if any,
      7       // the second is the string following the numbers.
      8       function splitNum(s) {
      9         var results = new Array();
     10         results[0] = 'None';
     11         for (var i = 0; i < s.length; i++) {
     12           var substr = s.substr(0, i+1)
     13           if (isNaN(substr)) {
     14             // Not a number anymore.
     15             results[1] = s.substr(i)
     16             break;
     17           } else {
     18             // This is a number. update the results.
     19             results[0] = parseFloat(substr);
     20           }
     21         }
     22         return results;
     23       }
     24 
     25       // Compare 2 strings using a custom alphanumerical algorithm.
     26       // This is similar to a normal string sort, except that we sort
     27       // first by leading digits, if any.
     28       // For example:
     29       //  100hello > 2goodbye
     30       // Numbers anywhere else in the string are compared using the normal
     31       // sort algorithm.
     32       function alphanumCompare(a, b) {
     33         var parsedA = splitNum(a);
     34         var parsedB = splitNum(b);
     35         var numA = parsedA[0];
     36         var numB = parsedB[0];
     37         var strA = parsedA[1];
     38         var strB = parsedB[1];
     39 
     40         if (isNaN(numA) == false && isNaN(numB) == false) {
     41           // They both start with numbers.
     42           if (numA < numB) return -1;
     43           if (numA > numB) return 1;
     44           // Identical. Fallback to string.
     45           return (strA < strB) ? -1 : (strA > strB ? 1 : 0)
     46         }
     47 
     48         // If only one starts with a number, we start with that one as
     49         // the lowest.
     50         if (isNaN(numA) == false) return -1
     51         if (isNaN(numB) == false) return 1
     52        
     53         // They are both strings. 
     54         return (a < b) ? -1 : (a > b ? 1 : 0)
     55       }
     56     </script>
     57   </head> 
     58   <body> 
     59     <script type="application/javascript"> 
     60       String.prototype.startsWith = function(str) {
     61         return (this.match('^' + str) == str)
     62       }
     63  
     64       // Helper function to retrieve the value of a GET query parameter.
     65       // Greatly inspired from http://alturl.com/8rj7a
     66       function getParameter(parameterName) {
     67         // Add '=' to the parameter name (i.e. parameterName=value)
     68         var parameterName = parameterName + '=';
     69         var queryString = window.location.search.substring(1);
     70         if (queryString.length <= 0) {
     71           return '';
     72         }
     73         
     74         // Find the beginning of the string
     75         begin = queryString.indexOf(parameterName);
     76  
     77         // If the parameter name is not found, skip it, otherwise return the
     78         // value.
     79         if (begin == -1) {
     80           return '';
     81         }
     82          
     83         // Add the length (integer) to the beginning.
     84         begin += parameterName.length;
     85  
     86         // Multiple parameters are separated by the '&' sign.
     87         end = queryString.indexOf ('&', begin);
     88         
     89         if (end == -1) {
     90           end = queryString.length;
     91         }
     92         
     93         // Return the string.
     94         return unescape(queryString.substring(begin, end));
     95       }
     96  
     97       // Given a tag and a node, returns the value for this tag on this node.
     98       function getNodeValue(node, tag) {
     99         return node.getElementsByTagName(tag)[0].firstChild.nodeValue;
    100       }
    101 
    102       // Displays the directory listing given the XML and path.
    103       function displayList(xmlstring, root, path, pathRoot) {
    104         // Display the header
    105         document.write('

Index of /' + path + '

'
); 106 107 // Start the table for the results. 108 document.write(''); 109 110 varsortOrder =getParameter('sort'); 111 varsortLink =location.pathname + '?path=' + path; 112 if (sortOrder != 'desc') { 113 sortLink += '&sort=desc'; 114 } 115 116 // Displaythetableheader. 117 document.write(''); 119 document.write(''); 120 document.write(''); 121 document.write(''); 122 document.write(''); 123 document.write(''); 124 document.write(''); 125 126 // Displaythe'go back'button. 127 if (path != '') { 128 varbackpath =location.pathname; 129 130 // Ifthereismorethanonesectiondelimitedby'/'inthecurrent 131 // pathwetruncatethelastsectionandappendtheresttobackpath. 132 vardelimiter =path.lastIndexOf('/'); 133 if (delimiter >= 0) { 134 delimiter = path.substr(0, delimiter).lastIndexOf('/'); 135 if (delimiter >= 0) { 136 backpath += '?path='; 137 backpath += path.substr(0, delimiter+1); 138 } 139 } 140 141 document.write('<tr><tdvalign="top"><imgsrc="' + root + pathRoot + 142 'icons/back.gif"alt="[DIR]"></td>'); 143 document.write('<td><ahref="'); 144 document.write(backpath); 145 document.write('">Parent Directory</a></td>'); 146 document.write('<td>&nbsp;</td>'); 147 document.write('<tdalign="right"> - </td></tr>'); 148 } 149 150 // Set up the variables. 151 var directories = new Array(); 152 var files = new Array(); 153 154 for (var iter = 0; iter < xmlstrings.length; iter++) { 155 varxmlstring =xmlstrings[iter]; 156 // ParsetheXMLoutput. 157 varparser =newDOMParser(); 158 varxmlDoc =parser.parseFromString(xmlstring, 'text/xml'); 159 160 // Getthemainelement. 161 varresults =xmlDoc.getElementsByTagName('ListBucketResult'); 162 163 // Getallthedirectories. 164 varprefixes =results[0].getElementsByTagName('CommonPrefixes'); 165 for (vari =0; i < prefixes.length; i++) { 166 var prefix = getNodeValue(prefixes[i], 'Prefix'); 167 directories.push(prefix.substr(path.length)); 168 } 169 170 // Get all the files. 171 var contents = results[0].getElementsByTagName('Contents'); 172 for (var i = 0; i < contents.length; i++) { 173 varobj =newObject(); 174 obj.keyName = getNodeValue(contents[i], 'Key'); 175 obj.lastModified = getNodeValue(contents[i], 'LastModified'); 176 obj.eTag = getNodeValue(contents[i], 'ETag'); 177 obj.size = getNodeValue(contents[i], 'Size'); 178 files.push(obj); 179 } 180 } 181 182 files.sort(alphanumCompare); 183 directories.sort(alphanumCompare); 184 185 // Reversethelistforadescendingsort. 186 if (sortOrder == 'desc') { 187 files.reverse(); 188 directories.reverse(); 189 } 190 191 // Displaythedirectories. 192 for (vari =0; i < directories.length; i++) { 193 var lnk = location.pathname.substr(0, location.pathname.indexOf('?')); 194 lnk += '?path=' + path + directories[i]; 195 196 document.write('<tr>'); 197 document.write('<tdvalign="top"><imgsrc="' + root + pathRoot + 198 'icons/folder.gif"alt="[DIR]"></td>'); 199 document.write('<td><ahref="' + lnk + '">' + 200 directories[i].split('/')[0] + '</a></td>'); 201 document.write('<tdalign="right">-</td>'); 202 document.write('<tdalign="right">-</td>'); 203 document.write('<tdalign="right">-</td>'); 204 document.write('<tdalign="right">-</td>'); 205 document.write('</tr>'); 206 } 207 208 // Display the files. 209 for (var i = 0; i < files.length; i++) { 210 varlink =root + files[i].keyName; 211 varfilename =files[i].keyName.substr(path.length); 212 varsize =files[i].size / 1024 / 1024; 213 varlastModified =files[i].lastModified.replace('T', ' '); 214 lastModified =lastModified.substr(0, lastModified.indexOf('.')); 215 216 // Removetheentrieswedon't want to show. 217 if (filename == '') { 218 continue; 219 } 220 221 if (filename.indexOf('$folder$') >= 0) { 222 continue; 223 } 224 225 // Display the row. 226 document.write('<tr>'); 227 document.write('<tdvalign="top"><imgsrc="' + root + pathRoot + 228 'icons/binary.gif"alt="[DIR]"></td>'); 229 document.write('<td><ahref="' + link + '">' + filename + 230 '</a></td>'); 231 document.write('<tdalign="right">' + lastModified + '</td>'); 232 document.write('<tdalign="right">' + size.toFixed(2) + 'MB</td>'); 233 document.write('<tdalign="right"><pre>' + 234 files[i].eTag.split('"')[1] + '</pre></td>'); 235 document.write('</tr>'); 236 } 237 238 // Close the table. 239 document.write('<tr><thcolspan="6"><hr></th></tr>'); 240 document.write('</table>'); 241 } 242 243 var xmlstrings = new Array(); 244 245 function fetchAndDisplay(marker) { 246 var path = getParameter('path'); 247 var lastSlash = location.pathname.lastIndexOf("/"); 248 var filename = location.pathname.substring(lastSlash + 1); 249 var firstSlash = location.pathname.indexOf("/", 1); 250 var root = location.pathname.substring(0, firstSlash + 1); 251 var pathRoot = location.pathname.substring(firstSlash + 1, 252 lastSlash + 1); 253 if (!path) { 254 path = location.pathname.substring(firstSlash + 1, lastSlash + 1); 255 } 256 257 var markerParam = ''; 258 if (marker != '') { 259 markerParam = '&marker=' + marker; 260 } 261 262 var http = new XMLHttpRequest(); 263 http.open('GET', 264 root + '?delimiter=/&prefix=' + path + markerParam, 265 true); 266 http.onreadystatechange = useHttpResponse; 267 http.send(null); 268 function useHttpResponse() { 269 if (http.readyState == 4) { 270 var xmlstring = http.responseText; 271 xmlstrings.push(xmlstring); 272 273 // Check if the data is truncated. if so, we need to request the 274 // rest. 275 var parser = new DOMParser(); 276 var xmlDoc = parser.parseFromString(xmlstring, 'text/xml'); 277 278 // Get the main element. 279 var results = xmlDoc.getElementsByTagName('ListBucketResult'); 280 281 // Get IsTruncated. 282 var truncated = getNodeValue(results[0], 'IsTruncated'); 283 var nextMarker = ''; 284 if (truncated == 'true') { 285 nextMarker = getNodeValue(results[0], 'NextMarker'); 286 fetchAndDisplay(nextMarker); 287 } else { 288 displayList(xmlstrings, root, path, pathRoot); 289 } 290 } 291 } 292 } 293 294 fetchAndDisplay(''); 295 </script> 296 </body> 297 </html> 298
root + pathRoot + 118 'icons/blank.gif" alt="[ICO]"> sortLink + '">Name Last modified Size Storage Class ETag