master
Sven Slootweg 9 years ago
parent 3e7ea8ca29
commit 70c81ba6ef

@ -0,0 +1,58 @@
# ia-headers
This module converts an object containing metadata into valid HTTP headers for the [Internet Archive](https://archive.org/) S3 API.
This is not a full-blown API client - it simply generates the metadata headers. You can use a module like [bhttp](https://www.npmjs.com/package/bhttp) to interact with the API. The documentation for the Internet Archive S3 API can be found [here](https://archive.org/help/abouts3.txt). API keys can be obtained [here](http://archive.org/account/s3.php).
`ia-header` supports multiple values for a metadata field - simply pass them in as an array (see also the Usage example below). Underscores are translated into double dashes, as per the IA S3 documentation.
## License
[WTFPL](http://www.wtfpl.net/txt/copying/) or [CC0](https://creativecommons.org/publicdomain/zero/1.0/), whichever you prefer. A donation and/or attribution are appreciated, but not required.
## Donate
My income consists entirely of donations for my projects. If this module is useful to you, consider [making a donation](http://cryto.net/~joepie91/donate.html)!
You can donate using Bitcoin, PayPal, Gratipay, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else.
## Contributing
Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the `.coffee` files, not the `.js` files.
Build tool of choice is `gulp`; simply run `gulp` while developing, and it will watch for changes.
Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.
## Caveats
* Metadata keys (not values!) may only be ASCII. The Internet Archive does not currently support non-ASCII metadata keys.
* All non-ASCII and non-printable characters in metadata values are URL-encoded - this could cause potentially significant header size increases. In most cases, this won't matter.
## Usage
```javascript
var iaHeaders = require("ia-headers");
var metadata = {
subject: ["mirror", "pdf.yt"],
mediatype: "texts",
collection: "pdfymirrors",
date: "2014-03-01",
title: "Some Document (PDFy mirror)",
description: "This is a document from PDFy.<br>It's a mirror."
}
var metadataHeaders = iaHeaders(metadata);
console.log(metadataHeaders);
/* Result:
{ 'x-archive-meta1-subject': 'mirror',
'x-archive-meta2-subject': 'pdf.yt',
'x-archive-meta-mediatype': 'texts',
'x-archive-meta-collection': 'pdfymirrors',
'x-archive-meta-date': '2014-03-01',
'x-archive-meta-title': 'Some Document (PDFy mirror)',
'x-archive-meta-description': 'This is a document from PDFy.<br>It\'s a mirror.' }
*/
```

@ -0,0 +1,28 @@
var gulp = require('gulp');
/* CoffeeScript compile deps */
var path = require('path');
var gutil = require('gulp-util');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var coffee = require('gulp-coffee');
var cache = require('gulp-cached');
var remember = require('gulp-remember');
var plumber = require('gulp-plumber');
var source = ["lib/**/*.coffee", "index.coffee"]
gulp.task('coffee', function() {
return gulp.src(source, {base: "."})
.pipe(plumber())
.pipe(cache("coffee"))
.pipe(coffee({bare: true}).on('error', gutil.log)).on('data', gutil.log)
.pipe(remember("coffee"))
.pipe(gulp.dest("."));
});
gulp.task('watch', function () {
gulp.watch(source, ['coffee']);
});
gulp.task('default', ['coffee', 'watch']);

@ -0,0 +1 @@
module.exports = require "./lib"

@ -0,0 +1 @@
module.exports = require("./lib");

@ -0,0 +1,34 @@
zeroFill = require "zero-fill"
maybeEncodeValue = (value) ->
if /[^ -~]/.exec(value) # Matches any Unicode and non-printable characters.
encoded = encodeURIComponent(value)
return "uri(#{encoded})"
else
return value
module.exports = (metadata) ->
headers = {}
for key, values of metadata
# It's easier to just always operate on an array, even if there's only a single value.
if not Array.isArray values
values = [values]
# Per RFC 822, we cannot have underscores in the header names. The IA S3 API will automatically convert double hyphens to an underscore, so we do the inverse.
key = key.replace("_", "--")
itemCount = values.length
if itemCount == 0
continue
else if itemCount == 1
headers["x-archive-meta-#{key}"] = maybeEncodeValue(values[0])
else
numberWidth = itemCount.toString().length
for value, i in values
headerName = "x-archive-meta#{zeroFill(numberWidth, i + 1)}-#{key}"
headers[headerName] = maybeEncodeValue(value)
return headers

@ -0,0 +1,39 @@
var maybeEncodeValue, zeroFill;
zeroFill = require("zero-fill");
maybeEncodeValue = function(value) {
var encoded;
if (/[^ -~]/.exec(value)) {
encoded = encodeURIComponent(value);
return "uri(" + encoded + ")";
} else {
return value;
}
};
module.exports = function(metadata) {
var headerName, headers, i, itemCount, key, numberWidth, value, values, _i, _len;
headers = {};
for (key in metadata) {
values = metadata[key];
if (!Array.isArray(values)) {
values = [values];
}
key = key.replace("_", "--");
itemCount = values.length;
if (itemCount === 0) {
continue;
} else if (itemCount === 1) {
headers["x-archive-meta-" + key] = maybeEncodeValue(values[0]);
} else {
numberWidth = itemCount.toString().length;
for (i = _i = 0, _len = values.length; _i < _len; i = ++_i) {
value = values[i];
headerName = "x-archive-meta" + (zeroFill(numberWidth, i + 1)) + "-" + key;
headers[headerName] = maybeEncodeValue(value);
}
}
}
return headers;
};

@ -0,0 +1,38 @@
{
"name": "ia-headers",
"version": "1.0.0",
"description": "Takes a metadata object, and turns it into valid HTTP headers for the Internet Archive S3 API.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.cryto.net:projects/joepie91/node-ia-headers"
},
"keywords": [
"internet",
"archive",
"s3",
"api",
"http",
"metadata"
],
"author": "Sven Slootweg",
"license": "WTFPL",
"dependencies": {
"zero-fill": "^2.2.0"
},
"devDependencies": {
"gulp": "~3.8.0",
"gulp-cached": "~0.0.3",
"gulp-coffee": "~2.0.1",
"gulp-concat": "~2.2.0",
"gulp-livereload": "~2.1.0",
"gulp-nodemon": "~1.0.4",
"gulp-plumber": "~0.6.3",
"gulp-remember": "~0.2.0",
"gulp-rename": "~1.2.0",
"gulp-util": "~2.2.17"
}
}
Loading…
Cancel
Save