git ssb

0+

cel / dillo-dat



Commit 2cddb59e95f37cc571b8cec12afbbe9d601104f5

Render Rotonde sites

cel committed on 10/14/2017, 3:08:57 AM
Parent: 8ae5cfd3842505847e8c879d7fba2bef2f655068

Files changed

dat.dpichanged
package.jsonchanged
dat.dpiView
@@ -11,27 +11,49 @@
1111 var hyperdrive = require('hyperdrive')
1212 var crypto = require('crypto')
1313 var h = require('hyperscript')
1414 var hyperdiscovery = require('hyperdiscovery')
15 +var multicb = require('multicb')
1516
1617 var dilloDir = path.join(process.env.HOME, '.dillo')
1718 var dpidKeysPath = path.join(dilloDir, 'dpid_comm_keys')
1819 var archivesPath = path.join(dilloDir, 'dat', 'archives')
1920
2021 var dpidKeys = fs.readFileSync(dpidKeysPath, {encoding: 'ascii'}).split(/\s+/)
2122
23 +var log = console.log.bind(console, '[dat dpi]')
24 +var error = console.error.bind(console, '[dat dpi]')
25 +
26 +function readJSON(archive, pathname, cb) {
27 + archive.readFile(pathname, function (err, data) {
28 + var obj
29 + if (!err) try { obj = JSON.parse(data) }
30 + catch(e) { return cb(e) }
31 + cb(null, obj)
32 + })
33 +}
34 +
2235 function readManifest(archive, cb) {
23- archive.readFile('dat.json', function (err, data) {
24- var manifest
25- if (!err) try { manifest = JSON.parse(data) } catch(e) {}
26- if (manifest) return cb(null, manifest)
36 + readJSON(archive, 'dat.json', function (err, manifest) {
37 + if (manifest) return cb(null, manifest || {})
2738 archive.readFile('CNAME', 'ascii', function (err, data) {
28- if (err) return cb('Not found')
39 + if (err) return cb(null, {})
2940 cb(null, {title: data})
3041 })
3142 })
3243 }
3344
45 +function readPortal(archive, cb) {
46 + readJSON(archive, 'portal.json', cb)
47 +}
48 +
49 +function readRotondeInfo(archive, cb) {
50 + var done = multicb({pluck: 1, spread: true})
51 + readPortal(archive, done())
52 + readManifest(archive, done())
53 + done(cb)
54 +}
55 +
3456 var archives = {}
3557 var getArchive = memo({cache: {
3658 has: function (key) { return key in archives },
3759 get: function (key) { return archives[key] },
@@ -345,20 +367,57 @@
345367 try { if (self.urlp.version) archive = archive.checkout(+self.urlp.version) }
346368 catch(e) { return self.serveError(err) }
347369 self.archive = archive
348370 self.sendStatus('serving file')
349- self.serve()
371 + self.serveDat2()
350372 })
351373 })
352374 }
353375
376 +var hostsToKeys = {}
377 +var datsToNames = {}
378 +
379 +function getName(url) {
380 + var host = parseDatUrl(url, true).host
381 + var key = hostsToKeys[host] || host
382 + var name = datsToNames[key]
383 + return name ? '@' + name : (String(key).substr(0, 8) + '…')
384 +}
385 +
386 +DpiReq.prototype.serveRotonde = function () {
387 + var self = this
388 + self.urlp = parseDatUrl(self.url, true)
389 + if (!self.urlp.host) return self.serveError('Archive not found')
390 + self.sendStatus('resolving name')
391 + datDns.resolveName(self.urlp.host, {ignoreCachedMiss: true}, function (err, key) {
392 + hostsToKeys[self.urlp.host] = key
393 + if (err) return self.serveError(err)
394 + if (!key) return cb(new TypeError('resolve failed'))
395 + self.sendStatus('getting archive')
396 + withTimeout(getArchive, 10000)(key, function (err, archive) {
397 + if (err) return self.serveError(err)
398 + if (!archive) return self.serveError('Unable to get archive')
399 + readPortal(archive, function (err, portal) {
400 + if (err) return
401 + datsToNames[key] = portal.name
402 + })
403 + if (!archive) return self.serveTimedout(self.urlp)
404 + try { if (self.urlp.version) archive = archive.checkout(+self.urlp.version) }
405 + catch(e) { return self.serveError(err) }
406 + self.archive = archive
407 + self.sendStatus('serving')
408 + self.serveRotonde2()
409 + })
410 + })
411 +}
412 +
354413 DpiReq.prototype.serveInternal = function () {
355414 this.urlp = parseUrl(this.url, true)
356415 if (this.urlp.pathname === '/dat/') return this.serveDashboard()
357416 this.serveNotFound()
358417 }
359418
360-DpiReq.prototype.serve = function () {
419 +DpiReq.prototype.serveDat2 = function () {
361420 var self = this
362421 if (self.closed) return
363422 self.stat(self.urlp.pathname || '/', function (err, st) {
364423 if (err) return self.serveNotFound(err)
@@ -368,8 +427,64 @@
368427 self.serveFile()
369428 })
370429 }
371430
431 +DpiReq.prototype.serveRotonde2 = function () {
432 + var self = this
433 + if (self.closed) return
434 + if (!self.urlp.pathname || self.urlp.pathname === '/') {
435 + return self.serveRotondeFeed()
436 + }
437 + return this.serveNotFound()
438 +}
439 +
440 +DpiReq.prototype.serveRotondeFeed = function () {
441 + var self = this
442 + if (self.closed) return
443 + readRotondeInfo(self.archive, function (err, portal, manifest) {
444 + if (err) return self.serveError(err)
445 + // return self.serveRotondeFeed()
446 + self.writeHeader('text/html')
447 + self.socket.end('<!doctype html>' + h('html', [
448 + h('head', [
449 + h('title', manifest.title || ('Rotonde (' + portal.name + ')'))
450 + ]),
451 + h('body', [
452 + h('h2', portal.name),
453 + h('blockquote', portal.desc),
454 + h('div', h('a', {href: portal.dat})),
455 + h('div', h('a', {href: portal.site})),
456 + Array.isArray(portal.port) ? portal.port.map(function (port) {
457 + var href = port.replace(/^dat:/, 'rotonde:')
458 + return [h('a', {href: href}, getName(port)), ' ']
459 + }) : '',
460 + Array.isArray(portal.feed)
461 + ? portal.feed.reverse().map(renderFeedItem) : ''
462 + ])
463 + ]).outerHTML)
464 + })
465 +}
466 +
467 +var urlRegex = /(\b(?:https?|dat):[^ ]*|<br>)/
468 +function linkify(text) {
469 + var arr = text.split(urlRegex)
470 + for (var i = 1; i < arr.length; i += 2) {
471 + if (arr[i] === '<br>') arr[i] = h('br')
472 + else arr[i] = h('a', {href: arr[i]}, arr[i])
473 + }
474 + return arr
475 +}
476 +
477 +function renderFeedItem(item) {
478 + var date = new Date(item.timestamp)
479 + // item.media
480 +
481 + return [
482 + h('p', date.toLocaleString()),
483 + h('blockquote', linkify(item.message))
484 + ]
485 +}
486 +
372487 function DpiReq_onAuth(m) {
373488 this.authed = (m[1] == dpidKeys[1])
374489 if (!this.authed) {
375490 console.error('[dat dpi] bad auth from', this.getAddress())
@@ -384,8 +499,9 @@
384499 return this.socket.end()
385500 }
386501 this.url = m[1]
387502 if (this.url.startsWith('dat:')) return this.serveDat()
503 + if (this.url.startsWith('rotonde:')) return this.serveRotonde()
388504 if (this.url.startsWith('dpi:/dat/')) return this.serveInternal()
389505 this.serveError('Not found')
390506 }
391507
package.jsonView
@@ -1,11 +1,12 @@
11 {
22 "dependencies": {
33 "asyncmemo": "^1.0.0",
44 "dat-dns": "^1.3.2",
5 + "hyperdiscovery": "^6.0.4",
6 + "hyperdrive": "^9.4.7",
57 "hyperscript": "^2.0.7",
6- "hyperdrive": "^9.4.7",
7- "hyperdiscovery": "^6.0.4",
8 + "multicb": "^1.2.2",
89 "parse-dat-url": "^2.0.1"
910 },
1011 "name": "dillo-dat",
1112 "license": "AGPL-3.0+",

Built with git-ssb-web