1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-01-10 12:24:20 +01:00
ipfs-boards/lib/boards-api.js

270 lines
6.3 KiB
JavaScript
Raw Normal View History

2015-11-11 15:51:07 +01:00
/*
This file contains the IPFS Boards API. It's a simple abstraction over the
js-ipfs-api that also provides an additional level of caching for this
particular application. Let's hope it turns out decent
2015-11-14 15:03:38 +01:00
Needs to be browserified to work in the browser
2015-11-11 15:51:07 +01:00
*/
2015-11-14 15:03:38 +01:00
var EventEmitter = require('wolfy87-eventemitter')
2015-11-11 09:18:36 +01:00
function asObj(str,done){
var obj
try {
obj = JSON.parse(str)
} catch (e) {
2015-11-11 12:38:10 +01:00
return done(e,null)
2015-11-11 09:18:36 +01:00
}
2015-11-11 12:38:10 +01:00
done(null,obj)
2015-11-11 09:18:36 +01:00
}
function replyAsObj(res,isJson,done){
if(res.readable){
// Is a stream
2015-11-14 12:06:37 +01:00
console.log('got stream')
2015-11-11 09:18:36 +01:00
res.setEncoding('utf8')
var data = ''
res.on('data',d => {
2015-11-14 12:06:37 +01:00
console.log('got stream data:',d)
2015-11-11 09:18:36 +01:00
data += d
})
res.on('end',() => {
if(isJson) {
asObj(data,done)
} else {
done(null,data)
}
})
} else {
2015-11-14 12:06:37 +01:00
console.log('got string:',res)
2015-11-11 09:18:36 +01:00
// Is a string
if(isJson){
asObj(res,done)
} else {
done(null,res)
}
}
}
function BoardsAPI(ipfs){
this.ipfs = ipfs
this.version = 'dev'
2015-11-11 15:22:58 +01:00
this.users = {} // userID : profileHash
this.posts = {} // boardName : postsList
this.comments = {} // objectID : comments
}
2015-11-11 12:38:10 +01:00
// This function works but needs a little rethinking.
BoardsAPI.prototype.resolveIPNS = function(n,done){
var cached = this.users[n]
if(cached){
2015-11-14 12:06:37 +01:00
console.log('Returning cached',n,'is',this.users[n])
2015-11-11 12:38:10 +01:00
done(null,cached)
}
this.ipfs.name.resolve(n,(err,r) => {
2015-11-14 13:12:48 +01:00
if(!err) console.log('Resolved',n,'to',r.Path)
2015-11-11 12:38:10 +01:00
if(err){
done(err)
} else if(!cached){
2015-11-14 15:03:38 +01:00
this.users[n] = r.Path
2015-11-11 12:38:10 +01:00
done(err,r.Path)
} else if(cached !== r.Path){
// Update cache
this.users[n] = r.Path
}
})
}
BoardsAPI.prototype.isUserProfile = function(addr,done){
this.ipfs.cat(addr+'/ipfs-boards-version.txt',(err,r) => {
if(err) return done(false)
replyAsObj(r,false,(_,res) => {
var v = res.trim()
console.log('Version for',addr,'is',v)
done(v)
})
})
}
2015-11-14 15:03:38 +01:00
BoardsAPI.prototype.isUser = function(s,done){
2015-11-11 12:38:10 +01:00
var ss = s.split('/')
var addr = ss[ss.length-1]
// Try to see if they run IPFS Boards
this.resolveIPNS(addr,(err,url) => {
2015-11-14 15:03:38 +01:00
if(err){
if(done) done(false)
return console.log('Cannot resolve',addr,':',err)
}
2015-11-11 12:38:10 +01:00
this.isUserProfile(url,isit => {
if(isit == this.version){
console.log(addr,'is a user')
this.users[addr] = url
2015-11-14 15:03:38 +01:00
if(done) done(true,addr,url)
} else if(done) done(false)
2015-11-11 12:38:10 +01:00
})
})
}
BoardsAPI.prototype.searchUsers = function(){
2015-11-14 15:03:38 +01:00
var ee = new EventEmitter()
2015-11-11 09:18:36 +01:00
// Look at our peers
2015-11-11 12:38:10 +01:00
this.ipfs.swarm.peers((err,r) => {
if(err) return console.log(err)
replyAsObj(r,true,(e,reply) => {
2015-11-11 15:22:58 +01:00
console.log('Checking',reply.Strings.length,'peers')
2015-11-14 15:03:38 +01:00
reply.Strings.forEach(item => {
this.isUser(item,(isit,addr,url) => {
if(isit){
ee.emit('found user',addr,url)
}
})
})
2015-11-11 09:18:36 +01:00
})
})
2015-11-14 15:03:38 +01:00
return ee
2015-11-11 09:18:36 +01:00
}
BoardsAPI.prototype.getProfile = function(userID,done){
2015-11-14 15:03:38 +01:00
var ee = new EventEmitter()
2015-11-14 12:06:37 +01:00
console.log('profile requested for',userID)
this.resolveIPNS(userID,(err,url) => {
2015-11-11 09:18:36 +01:00
if(err){
done(err,null)
2015-11-14 15:03:38 +01:00
} else {
// Download actual profile
this.ipfs.cat(url+'/profile.json',(err2,res) => {
console.log('got something')
if(err2){
done(err2,null)
} else {
// It already returns a JSON?
done(null,res)
}
})
// Get other info
this.ipfs.ls(url+'/boards/',(err2,res) => {
if(!err2){
console.log('RES',res)
var l = res.Objects[0].Links.map(i => {
return { name: i.Name, hash: i.Hash }
})
ee.emit('boards',l)
} else console.log(err2)
})
}
2015-11-11 09:18:36 +01:00
})
2015-11-14 15:03:38 +01:00
return ee
2015-11-11 09:18:36 +01:00
}
BoardsAPI.prototype.getName = function(userID,done){
this.ipfs.cat(userID+'/name',(err,res) => {
if(err){
done(err,null)
} else {
replyAsObj(res,false,done)
}
})
}
BoardsAPI.prototype.getBoardSettings = function(userID,board,done){
var url = userID+'/boards/'+board+'/settings.json'
console.log('Getting Board Settings:',url)
2015-11-11 09:18:36 +01:00
this.ipfs.cat(url,function(err,res){
2015-11-11 12:38:10 +01:00
console.log('Done')
2015-11-11 09:18:36 +01:00
if(err){
done(err,{})
} else {
replyAsObj(res,true,done)
}
})
}
2015-11-14 15:03:38 +01:00
BoardsAPI.prototype.getPostsInBoard = function(adminID,board){
var ee = new EventEmitter()
/*
2015-11-11 15:22:58 +01:00
this.getBoardSettings(administratorID,board,(err,res) => {
// NEEDS: board settings structure definition
2015-11-14 15:03:38 +01:00
// For now we only list admin's posts
2015-11-11 15:22:58 +01:00
})
2015-11-14 15:03:38 +01:00
*/
this.getUserPostListInBoard(adminID,board,(err,res) =>{
if(err){
console.log(err)
} else res.forEach(item => {
this.ipfs.cat(item.hash,(err2,r) => {
console.log('got something')
if(err2){
console.log('Could not download post',item,'of',board+'@'+adminID)
} else {
// It already returns a JSON?
ee.emit('post',r)
}
})
})
})
return ee
2015-11-11 09:18:36 +01:00
}
2015-11-14 15:03:38 +01:00
BoardsAPI.prototype.getUserPostListInBoard = function(user,board,done){
2015-11-11 15:22:58 +01:00
this.resolveIPNS(user,(err,url) => {
if(err){
done(err)
2015-11-14 15:03:38 +01:00
} else this.ipfs.ls(url+'/posts/'+board,(e,r) => {
2015-11-11 15:22:58 +01:00
if(e){
done(e)
2015-11-14 15:03:38 +01:00
} else if(r && !r.split){
console.log('Found',r.Objects[0].Links.length,'posts in',board,'at',user)
var l = r.Objects[0].Links.map(i => {
2015-11-11 15:22:58 +01:00
return { date: i.Name, hash: i.Hash }
})
2015-11-14 15:03:38 +01:00
done(null,l)
2015-11-11 15:22:58 +01:00
}
})
})
2015-11-11 09:18:36 +01:00
}
2015-11-11 15:22:58 +01:00
BoardsAPI.prototype.getCommentsFor = function(parent,done){
2015-11-11 09:18:36 +01:00
}
2015-11-11 15:22:58 +01:00
// Work only in writable mode:
2015-11-11 12:38:10 +01:00
BoardsAPI.prototype.createPost = function(post,board,done){
2015-11-11 09:18:36 +01:00
}
2015-11-11 12:38:10 +01:00
BoardsAPI.prototype.createComment = function(parent,comment,done){
2015-11-11 09:18:36 +01:00
}
2015-11-11 12:38:10 +01:00
BoardsAPI.prototype.createUpvote = function(parent,done){
2015-11-11 09:18:36 +01:00
}
// API for managing the administrations to be done later
// Initialize API
BoardsAPI.prototype.init = function(done){
this.ipfs.id( (err, res) => {
if(err){
console.log(err)
done(err)
} else {
console.log('I am',res.ID)
this.id = res.ID
2015-11-11 12:38:10 +01:00
this.isUser(res.ID)
2015-11-11 09:18:36 +01:00
console.log('Version is',this.version)
this.ipfs.add(new Buffer('ipfs:boards:version:'+this.version),(err,r) => {
2015-11-14 15:03:38 +01:00
if(err){
console.log('Error while calculating version hash:',err)
}
2015-11-11 09:18:36 +01:00
this.version_hash = r[0].Hash
console.log('Version hash is',this.version_hash)
done(null)
})
}
})
}
module.exports = BoardsAPI