mirror of
https://github.com/fazo96/ipfs-boards
synced 2025-03-11 21:38:38 +01:00
developing...
This commit is contained in:
parent
110000beef
commit
00593e9e44
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
node_modules/
|
||||
example_user/
|
||||
server/node_modules/
|
||||
test/
|
||||
|
45
README.md
45
README.md
@ -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
138
lib/boards-api.js
Normal 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
|
15
package.json
15
package.json
@ -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"
|
||||
}
|
||||
|
24
server.js
24
server.js
@ -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
28
server/server.js
Executable 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()
|
||||
}
|
||||
})
|
@ -1,5 +1,3 @@
|
||||
console.log(require('ipfs-api'))
|
||||
|
||||
var boards = angular.module('boards',['ui.router'])
|
||||
|
||||
boards.config(function($stateProvider,$urlRouterProvider,$locationProvider){
|
Loading…
Reference in New Issue
Block a user