Skip to content

Commit 4c490d1

Browse files
committed
3.0.0 - make compatible with abstract-blob-store api
1 parent ae439df commit 4c490d1

File tree

5 files changed

+69
-35
lines changed

5 files changed

+69
-35
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
node_modules
1+
node_modules
2+
.DS_Store

index.js

+24-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var request = require('request')
33
var concat = require('concat-stream')
44
var mime = require('mime-types')
55
var through = require('through2')
6+
var duplexify = require('duplexify')
67
var formEncoder = require('form-urlencoded')
78
var debug = require('debug')('google-drive-blobs')
89

@@ -83,8 +84,10 @@ Blobs.prototype.createWriteStream = function(options, cb) {
8384
var response = JSON.parse(body)
8485
self.addProperty(response.id, 'hash', response.md5Checksum, function(err, resp, props) {
8586
if (err) return cb(err)
87+
if (resp.statusCode > 299) return cb(new Error(JSON.stringify(props)))
8688
response.hash = response.md5Checksum
87-
response.size = response.fileSize
89+
response.size = +response.fileSize
90+
if (process.env['DEBUG']) debug('createWriteStream done', JSON.stringify(response))
8891
cb(null, response)
8992
})
9093
})
@@ -101,25 +104,28 @@ Blobs.prototype.addProperty = function(id, key, val, cb) {
101104

102105
var reqOpts = {
103106
url: baseURL + 'files/' + id + '/properties',
104-
json: hashProp
107+
json: hashProp,
108+
contentType: 'application/json'
105109
}
106110

107111
return this.request(reqOpts, cb)
108112
}
109113

110-
Blobs.prototype.createReadStream = function(hash) {
114+
Blobs.prototype.createReadStream = function(opts) {
111115
var self = this
112-
var proxy = through()
113-
114-
self.get(hash, function(err, file) {
115-
if (err) return proxy.emit('error', err)
116-
self.request({
116+
var duplex = duplexify()
117+
debug('createReadStream', JSON.stringify(opts))
118+
self.get(opts.hash, function(err, file) {
119+
if (err) return duplex.destroy(err)
120+
if (!file) return duplex.destroy(new Error('Blob not found'))
121+
var req = self.request({
117122
url: file.downloadUrl,
118123
method: 'GET',
119-
}).pipe(proxy)
124+
})
125+
duplex.setReadable(req)
120126
})
121127

122-
return proxy
128+
return duplex
123129
}
124130

125131
Blobs.prototype.mkdir = function(filename, opts, cb) {
@@ -153,8 +159,12 @@ Blobs.prototype.request = function(opts, cb) {
153159
}
154160

155161
if (opts.url) reqOpts.url = opts.url
156-
157162
return request(reqOpts, function(err, resp, body) {
163+
if (process.env['DEBUG']) {
164+
var bodyStr = body
165+
if (bodyStr && typeof bodyStr.length === 'undefined') bodyStr = JSON.stringify(bodyStr)
166+
debug(resp.statusCode, JSON.stringify(reqOpts), bodyStr)
167+
}
158168
// token may have expired, refresh + retry
159169
if (resp.statusCode > 299) return self.refreshToken(function(err) {
160170
if (err) return cb(err)
@@ -181,18 +191,18 @@ Blobs.prototype.get = function(hash, cb) {
181191
})
182192
}
183193

184-
Blobs.prototype.remove = function(hash, cb) {
194+
Blobs.prototype.remove = function(opts, cb) {
185195
var self = this
186196

187-
self.get(hash, function(err, file) {
197+
self.get(opts.hash, function(err, file) {
188198
if (err) return cb(err)
189199
var reqOpts = {
190200
method: 'DELETE',
191201
url: baseURL + 'files/' + file.id
192202
}
193203

194204
self.request(reqOpts, function(err, resp, results) {
195-
if (err || resp.statusCode > 299) return cb(results)
205+
if (err || resp.statusCode > 299) return cb(results || new Error('could not delete'))
196206
cb(null)
197207
})
198208
})

package.json

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
{
22
"name": "google-drive-blobs",
3-
"version": "2.0.1",
4-
"description": "a simple content-addressable blob store API on top of google drive",
3+
"version": "3.0.0",
4+
"description": "a simple content-addressable streaming blob store API on top of google drive",
55
"main": "index.js",
66
"scripts": {
77
"test": "node test.js"
88
},
99
"author": "max ogden",
10-
"license": "bSD",
10+
"license": "BSD",
1111
"dependencies": {
1212
"debug": "^0.8.1",
13+
"duplexify": "^3.1.0",
1314
"form-urlencoded": "0.0.6",
1415
"mime-types": "^1.0.0"
1516
},
16-
"devDependencies": {},
17+
"devDependencies": {
18+
"abstract-blob-store": "^1.0.4"
19+
},
1720
"repository": {
1821
"type": "git",
1922
"url": "https://github.com/maxogden/google-drive-blobs.git"

readme.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
a simple content-addressable blob store API on top of google drive
44

5+
compatible with the [abstract-blob-store](https://github.com/maxogden/abstract-blob-store) API and passes its test suite
6+
57
[![NPM](https://nodei.co/npm/google-drive-blobs.png)](https://nodei.co/npm/google-drive-blobs/)
68

79
## API
@@ -22,16 +24,20 @@ returns a writable stream that you can pipe data to.
2224

2325
`cb` will be called with `(err, response)` where `response` is the response metadata
2426

25-
### blobs.createReadStream(md5)
27+
### blobs.createReadStream(opts)
28+
29+
opts should be `{hash: md5}`
2630

2731
returns a readable stream of data for the first file in your drive whose md5 checksum matches the `md5` argument
2832

2933
### blobs.get(md5, cb)
3034

3135
gets google drive metadata for the first file in your drive whose md5 checksum matches the `md5` argument
3236

33-
### blobs.remove(md5, cb)
37+
### blobs.remove(opts, cb)
3438

39+
opts should be `{hash: md5}`
40+
3541
deletes file by md5
3642

3743
### blobs.addProperty(fileId, key, val, cb)

test.js

+28-14
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,29 @@ var path = require('path')
33
var crypto = require('crypto')
44
var test = require('tape')
55
var concat = require('concat-stream')
6+
var abstractBlobTests = require('abstract-blob-store/tests')
67
var gdb = require('./')
78

89
// assumes you are using npm install googleauth -g
910
var tokens = JSON.parse(fs.readFileSync(path.join(process.env.HOME, '.config', 'googleauth.json')))
10-
tokens.client_id = process.env['GOOGLE_CLIENT'] || process.env[3]
11-
tokens.client_secret = process.env['GOOGLE_SECRET'] || process.env[4]
11+
tokens.client_id = process.env['GOOGLEAUTH_CLIENT'] || process.env[3]
12+
tokens.client_secret = process.env['GOOGLEAUTH_SECRET'] || process.env[4]
1213

1314
var testmd5 = crypto.createHash('md5').update(fs.readFileSync('./test.js')).digest('hex')
1415

16+
var common = {
17+
setup: function(t, cb) {
18+
var store = gdb(tokens)
19+
cb(null, store)
20+
},
21+
teardown: function(t, store, blob, cb) {
22+
if (blob) store.remove(blob, cb)
23+
else cb()
24+
}
25+
}
26+
27+
abstractBlobTests(test, common)
28+
1529
test('constructor does not throw', function(t) {
1630
var blobs = gdb()
1731
t.ok(blobs, 'constructed')
@@ -20,37 +34,37 @@ test('constructor does not throw', function(t) {
2034

2135
test('uploads a blob', function(t) {
2236
var blobs = gdb(tokens)
23-
37+
2438
var ws = blobs.createWriteStream({filename: 'test.js'}, function(err, resp) {
2539
t.false(err, 'should not error')
2640
if (err) console.error(err)
2741
t.equal(resp.hash, testmd5)
2842
t.end()
2943
})
30-
44+
3145
fs.createReadStream('./test.js').pipe(ws)
3246
})
3347

3448
test('gets blob metadata by md5', function(t) {
3549
var blobs = gdb(tokens)
36-
50+
3751
blobs.get(testmd5, function(err, file) {
3852
t.false(err, 'no err')
3953
t.equal(file.title, 'test.js')
4054
t.end()
4155
})
4256
})
43-
57+
4458
test('gets a blob', function(t) {
4559
var blobs = gdb(tokens)
46-
47-
var ws = blobs.createReadStream(testmd5)
48-
60+
61+
var ws = blobs.createReadStream({hash: testmd5})
62+
4963
ws.on('error', function(e) {
50-
t.false(e, 'should not error')
64+
t.error(e)
5165
t.end()
5266
})
53-
67+
5468
ws.pipe(concat(function(contents) {
5569
t.equal(contents.toString(), fs.readFileSync('./test.js').toString(), 'file contents match')
5670
t.end()
@@ -59,14 +73,14 @@ test('gets a blob', function(t) {
5973

6074
test('deletes a blob', function(t) {
6175
var blobs = gdb(tokens)
62-
63-
var ws = blobs.remove(testmd5, function(err) {
76+
77+
var ws = blobs.remove({hash: testmd5}, function(err) {
6478
t.false(err, 'snould not err')
6579
blobs.get(testmd5, function(err, file) {
6680
t.false(err, 'should not err')
6781
t.false(file, 'should have no results')
6882
t.end()
6983
})
7084
})
71-
85+
7286
})

0 commit comments

Comments
 (0)