1
0
mirror of https://github.com/fazo96/ipfs-boards synced 2025-03-11 21:38:38 +01:00

developing...

This commit is contained in:
Enrico Fasoli 2015-11-11 09:18:36 +01:00
parent 110000beef
commit 00593e9e44
10 changed files with 209 additions and 46 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules/
example_user/
server/node_modules/
test/

View File

@ -68,8 +68,7 @@ __Administrations can be a lot more than filters:__
An administration can personalize almost everything in how content is viewed, what content is allowed (acting a filter), whitelists, blacklists, eventually even the CSS or Layout of the front page, post tags and a lot more.
`admin` is the administrator of the repo. He decides the rules. He can name moderators and their modifications
will be merged with his boards' profile by his Admin Node.
`admin` is the administrator of the repo. He decides the rules.
You (the user) will be able to choose a main _administration_ for a board and then also include content from other administrations.
@ -93,7 +92,7 @@ If this gets implemented it should go in the Admin Node.
__About private boards__
They probably will be possible but are not included for now, because hidden content is far away in the IPFS roadmap.
Administration can forbit people to write, but not to read.
Administrations can forbit people to write, but not to read.
__Important Note:__ due to how the system works, an _administration_'s rules and decisions are just _guidelines_ for your computer.
Your computer will always be able to choose what to see and what to hide, it just uses your administration's guidelines _by default_.
@ -104,12 +103,14 @@ That's why there are __Cache Servers__.
They monitor _administrations_ and cache all the content (or some of it) as soon as it becomes available on the network, making sure it never gets lost.
They are completely optional but they help out in serving the users.
Cache servers also act as gateways and provide an HTTP API to access the boards.
Also note that due to how IPFS works, the more popular some content gets, the _faster it downloads_ and the _easier it is for your computer to find it_. Censorship is impractical in such a system and data is almost impossible to take down. That's why IPFS is also called _the
permanent web_.
## Faq
#### Can I be anonymous?
#### Can I be anonymous?
What if someone monitors my IPFS node? Will they know what content I'm seeing and everything I post and link it to my IP?
@ -117,7 +118,7 @@ __Yes, but there is a solution.__
You can access a Cache Server's HTTP(s) gateway via Tor for read only access to content.
To post while mantaining anonimity, you would need to run IPFS via Tor. This is probably not easily done at the moment but [it is planned](
To post while mantaining anonimity, you would need to run IPFS via Tor. This is probably not easily done at the moment but it is planned.
## Components
@ -141,25 +142,30 @@ Each user exposes via IPNS a folder containing:
- boards
- _board name(s)_
- settings.json - the board's settings
- whitelist - contains links to all whitelisted users
- blacklist - contains links to all blacklisted users
- approved - contains links to all approved content
- posts
- _board name(s)_
- _admin name(s)_
- _post(s)_
- _post(s)_
- comments
- _board name(s)_
- _admin name(s)_
- _comment(s)_
- _comment(s)_
- votes
- _board name(s)_
- _admin name(s)_
- _vote(s)_
- compatibility: could be used to store compatibility information
- _vote(s)_
- name - stores the user's screen name (also stored in profile?)
- profile.json - user's additional profile data
- ipfs-boards-version.txt - used to store compatibility information
#### Post
{
"title": "Title of the post",
"date": "date of the post",
"op": "id_of_the_original_poster",
"preference": "id_of_the_preferred_administration",
"text": "Content of the post"
}
@ -168,16 +174,21 @@ possible for lange texts without duplicating data.
#### Comment
Comment text
{
"parent": "id_of_the_parent_object",
"date": "date of the comment"
"preference": "id_of_the_preferred_administration",
"op": "id_of_the_original_poster",
"text": "Content of the post"
}
#### Vote
ipfs-board:vote-for:object_url
ipfs:boards:vote-for:object_url
### Versioning
#### Versioning
a `version` file or something should be included in the user's files to ensure compatibility between different
versions or forks.
just the version ID written in the version file
### License

138
lib/boards-api.js Normal file
View File

@ -0,0 +1,138 @@
// Write an API to aggregate data without duplication and making accessing content easy. Use the IPFS http api
function asObj(str,done){
var obj
try {
obj = JSON.parse(str)
} catch (e) {
done(e,null)
}
if(obj != undefined) done(null,obj)
}
function replyAsObj(res,isJson,done){
if(res.readable){
// Is a stream
res.setEncoding('utf8')
var data = ''
res.on('data',d => {
data += d
})
res.on('end',() => {
if(isJson) {
asObj(data,done)
} else {
done(null,data)
}
})
} else {
// Is a string
if(isJson){
asObj(res,done)
} else {
done(null,res)
}
}
}
function BoardsAPI(ipfs){
this.ipfs = ipfs
this.version = 'dev'
}
BoardsAPI.prototype.searchUsers = function(done){
// Look at our peers
this.ipfs.swarm.peers(function(err,r){
var peers = r.Strings.forEach(function(s){
var ss = s.split('/')
var addr = ss[ss.length-1]
// Try to see if they run IPFS Boards
this.ipfs.cat(addr+'/ipfs-boards-version.txt',function(err,r){
if(err) return console.log('Search Err:',err)
replyAsObj(r,false,(_,res) => {
// He does!
// TODO: store found users in a list?
console.log('Found user:',addr,'using version',res)
})
})
})
})
}
BoardsAPI.prototype.getProfile = function(userID,done){
this.ipfs.cat(userID+'/profile.json',(err,res) => {
if(err){
done(err,null)
} else {
replyAsObj(res,true,done)
}
})
}
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'
this.ipfs.cat(url,function(err,res){
if(err){
done(err,{})
} else {
replyAsObj(res,true,done)
}
})
}
BoardsAPI.prototype.getBoardPosts(board,administratorID,done){
// Returns a stream
}
BoardsAPI.prototype.getUserPosts(user,board,done){
// Returns a stream
}
BoardsAPI.prototype.getComments(parent,board,done){
// Returns a stream
}
BoardsAPI.prototype.createPost(post,board,done){
}
BoardsAPI.prototype.createComment(parent,comment,done){
}
BoardsAPI.prototype.createUpvote(parent,done){
}
// 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
console.log('Version is',this.version)
this.ipfs.add(new Buffer('ipfs:boards:version:'+this.version),(err,r) => {
this.version_hash = r[0].Hash
console.log('Version hash is',this.version_hash)
done(null)
})
}
})
}
module.exports = BoardsAPI

View File

@ -2,13 +2,24 @@
"name": "ipfs-board",
"version": "0.1.0",
"description": "decentralized discussion board",
"main": "server.js",
"scripts": {
"start": "node server.js"
"start": "node cli/server.js"
},
"bin": {
"ipfs-board": "cli/server.js"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/fazo96/ipfs-board.git"
},
"bugs": {
"url": "https://github.com/fazo96/ipfs-board/issues"
},
"homepage": "https://github.com/fazo96/ipfs-board#readme",
"author": "Enrico Fasoli (fazo96)",
"license": "MIT",
"dependencies": {
"commander": "^2.9.0",
"express": "^4.13.3",
"ipfs-api": "^2.6.2"
}

View File

@ -1,24 +0,0 @@
#!/usr/bin/env node
var ipfs = require('ipfs-api')('localhost','5001')
var express = require('express')
var app = express()
// Serve files in ./static
app.use(express.static('static'))
app.get('/@:user/:board',function(req,res){
ipfs.cat(req.params.user+'/'+req.params.board,function(err,res){
})
})
// CatchAll route: serve the angular app
/*app.get('*',function(req,res){
res.sendFile(__dirname+'/static/index.html')
})*/
// Start http server
app.listen(3000,function(){
console.log('Started')
})

28
server/server.js Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env node
var ipfs = require('ipfs-api')('localhost','5001')
var BoardsAPI = require('../lib/boards-api.js')
var express = require('express')
var app = express()
var boards = new BoardsAPI(ipfs)
// Serve web app
app.use(express.static('../webapp'))
// Create gateways to access the BoardsAPI
function startWebServer(){
// Start http server
app.listen(3000,function(){
console.log('Started Web Server')
})
}
boards.init(function(err){
if(err){
console.log(err)
} else {
startWebServer()
}
})

View File

@ -1,5 +1,3 @@
console.log(require('ipfs-api'))
var boards = angular.module('boards',['ui.router'])
boards.config(function($stateProvider,$urlRouterProvider,$locationProvider){