Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: to async await #67

Merged
merged 3 commits into from
Oct 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ npm install --save ipfs-geoip

```js
const geoip = require('ipfs-geoip')
const ipfs = require('ipfs-api')()
const ipfs = require('ipfs-http-client')()

var exampleIp = '89.114.95.36'

Expand Down Expand Up @@ -113,7 +113,7 @@ This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/c

### Want to hack on IPFS?

[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md)
[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)

## License

Expand Down
5 changes: 1 addition & 4 deletions bin/generate
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@

const Gauge = require('gauge')
const gen = require('../src/generate')
const API = require('ipfs-api')
const ipfs = require('ipfs-http-client')()

function handleNoApi () {
console.error('No ipfs daemon running. Please start one')
process.exit(1)
}

// -- CLI interaction

const ipfs = new API()

ipfs.id()
.then((id) => {
if (!id) handleNoApi()
Expand Down
22 changes: 11 additions & 11 deletions example/lookup.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
'use strict'

const geoip = require('../')
const ipfs = require('ipfs-api')()
const ipfs = require('ipfs-http-client')()

if (process.argv.length !== 3) {
console.log('usage: node lookup.js <ip4-adr>')
process.exit(1)
}

geoip.lookup(ipfs, process.argv[2], (err, result) => {
if (err) {
console.log('Error: ' + err)
} else {
(async function() {
try {
const result = await geoip.lookup(ipfs, process.argv[2])
console.log('Result: ' + JSON.stringify(result, null, 2))
} catch (err) {
console.log('Error: ' + err)
}
})

geoip.lookupPretty(ipfs, '/ip4/' + process.argv[2], (err, result) => {
if (err) {
console.log('Error: ' + err)
} else {
try {
const result = await geoip.lookupPretty(ipfs, '/ip4/' + process.argv[2])
console.log('Pretty result: %s', result.formatted)
} catch (err) {
console.log('Error: ' + err)
}
})
})()
93 changes: 53 additions & 40 deletions src/lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,74 @@ const GEOIP_ROOT = mh.fromB58String('QmRn43NNNBEibc6m7zVNcS6UusB1u3qTTfyoLmkugbe

let memoizedLookup

function _lookup (ipfs, hash, lookfor, cb) {
ipfs.object.get(hash, (err, res) => {
if (err) return cb(err)

let obj
try {
obj = JSON.parse(res.data)
} catch (err) {
return cb(err)
}

let child = 0

if (obj.type === 'Node') {
while (obj.mins[child] && obj.mins[child] <= lookfor) {
child++
/**
* @param {Object} ipfs
* @param {string} hash
* @param {string} lookfor - ip
* @returns {Promise}
*/
function _lookup (ipfs, hash, lookfor) {
return new Promise((resolve, reject) => {
ipfs.object.get(hash, (err, res) => {
if (err) reject(err)

let obj
try {
obj = JSON.parse(res.data)
} catch (err) {
reject(err)
}

const next = res.links[child - 1]
let child = 0

if (!next) {
return cb(new Error('Failed to lookup node'))
}
if (obj.type === 'Node') {
while (obj.mins[child] && obj.mins[child] <= lookfor) {
child++
}

const nextCid = getCid(next)
const next = res.links[child - 1]

if (!nextCid) {
return cb(new Error('Failed to lookup node'))
}
if (!next) {
reject(new Error('Failed to lookup node'))
}

return memoizedLookup(ipfs, nextCid, lookfor, cb)
} else if (obj.type === 'Leaf') {
while (obj.data[child] && obj.data[child].min <= lookfor) {
child++
}
const nextCid = getCid(next)

const next = obj.data[child - 1]
if (!nextCid) {
reject(new Error('Failed to lookup node'))
}

if (!next) {
return cb(new Error('Failed to lookup leaf node'))
}
resolve(memoizedLookup(ipfs, nextCid, lookfor))
} else if (obj.type === 'Leaf') {
while (obj.data[child] && obj.data[child].min <= lookfor) {
child++
}

if (!next.data) {
return cb(new Error('Unmapped range'), null)
}
const next = obj.data[child - 1]

if (!next) {
reject(new Error('Failed to lookup leaf node'))
}

return cb(null, formatData(next.data))
}
if (!next.data) {
reject(new Error('Unmapped range'), null)
}

resolve(formatData(next.data))
}
})
})
}

memoizedLookup = memoize(_lookup, { async: true })

module.exports = function lookup (ipfs, ip, cb) {
memoizedLookup(ipfs, GEOIP_ROOT, inet.aton(ip), cb)
/**
* @param {Object} ipfs
* @param {string} ip
* @returns {Promise}
*/
module.exports = function lookup (ipfs, ip) {
return memoizedLookup(ipfs, GEOIP_ROOT, inet.aton(ip))
}

function getCid (node) {
Expand Down
64 changes: 34 additions & 30 deletions src/pretty.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,47 @@ function isLocal (address) {
return false
}

module.exports = function lookupPretty (ipfs, multiaddrs, cb) {
if (multiaddrs.length === 0) {
return cb(new Error('lookup requires a multiaddr array with length > 0'), null)
}

if (typeof multiaddrs === 'string') {
multiaddrs = [multiaddrs]
}

const current = multiaddrs[0].split('/')
const address = current[2]

// No ip6 support at the moment
if (isLocal(address) || current[1] === 'ip6') {
const next = multiaddrs.slice(1)
if (next.length > 0) {
return lookupPretty(ipfs, multiaddrs.slice(1), cb)
module.exports = function lookupPretty (ipfs, multiaddrs) {
return new Promise(async (resolve, reject) => {
if (multiaddrs.length === 0) {
reject(new Error('lookup requires a multiaddr array with length > 0'), null)
}
return cb(new Error('Unmapped range'), null)
}

lookup(ipfs, address, (err, res) => {
if (err) { return cb(err) }
if (typeof multiaddrs === 'string') {
multiaddrs = [multiaddrs]
}

const current = multiaddrs[0].split('/')
const address = current[2]

if (!res.country_name && multiaddrs.length > 1) {
return lookupPretty(ipfs, multiaddrs.slice(1), cb)
// No ip6 support at the moment
if (isLocal(address) || current[1] === 'ip6') {
const next = multiaddrs.slice(1)
if (next.length > 0) {
resolve(lookupPretty(ipfs, multiaddrs.slice(1)))
}
reject(new Error('Unmapped range'))
}

const location = []
try {
const res = await lookup(ipfs, address)

if (!res.country_name && multiaddrs.length > 1) {
resolve(lookupPretty(ipfs, multiaddrs.slice(1)))
}

if (res.planet) location.push(res.planet)
if (res.country_name) location.unshift(res.country_name)
if (res.region_code) location.unshift(res.region_code)
if (res.city) location.unshift(res.city)
const location = []

res.formatted = location.join(', ')
if (res.planet) location.push(res.planet)
if (res.country_name) location.unshift(res.country_name)
if (res.region_code) location.unshift(res.region_code)
if (res.city) location.unshift(res.city)

cb(null, res)
res.formatted = location.join(', ')

resolve(res)
} catch (err) {
reject(err)
}
})
}
65 changes: 30 additions & 35 deletions test/lookup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,51 +18,46 @@ describe('lookup', function () {
})
})

it('fails on 127.0.0.1', (done) => {
geoip.lookup(ipfs, '127.0.0.1', function (err, result) {
it('fails on 127.0.0.1', async () => {
try {
await geoip.lookup(ipfs, '127.0.0.1')
} catch (err) {
expect(err).to.have.property('message', 'Unmapped range')
done()
})
}
})

it('looks up 8.8.8.8', (done) => {
geoip.lookup(ipfs, '8.8.8.8', function (err, result) {
if (err) throw err
expect(
result
).to.be.eql({
country_name: 'United States',
country_code: 'US',
region_code: 'CA',
city: 'Mountain View',
postal_code: 94040,
latitude: 37.386,
longitude: -122.0838,
metro_code: 807,
area_code: 650,
planet: 'Earth'
})

done()
it('looks up 8.8.8.8', async () => {
const result = await geoip.lookup(ipfs, '8.8.8.8')
expect(
result
).to.be.eql({
country_name: 'United States',
country_code: 'US',
region_code: 'CA',
city: 'Mountain View',
postal_code: 94040,
latitude: 37.386,
longitude: -122.0838,
metro_code: 807,
area_code: 650,
planet: 'Earth'
})
})

describe('lookupPretty', () => {
it('fails on 127.0.0.1', (done) => {
geoip.lookupPretty(ipfs, '/ip4/127.0.0.1', function (err, result) {
it('fails on 127.0.0.1', async () => {
try {
await geoip.lookupPretty(ipfs, '/ip4/127.0.0.1')
} catch (err) {
expect(err).to.have.property('message', 'Unmapped range')
done()
})
}
})

it('looks up 8.8.8.8', (done) => {
geoip.lookupPretty(ipfs, '/ip4/8.8.8.8', function (err, result) {
if (err) throw err
expect(
result.formatted
).to.be.eql('Mountain View, CA, United States, Earth')
done()
})
it('looks up 8.8.8.8', async () => {
const result = await geoip.lookupPretty(ipfs, '/ip4/8.8.8.8')
expect(
result.formatted
).to.be.eql('Mountain View, CA, United States, Earth')
})
})
})