forked from nodeSolidServer/node-solid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathldp-container.js
More file actions
161 lines (141 loc) · 4.31 KB
/
ldp-container.js
File metadata and controls
161 lines (141 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
module.exports.addContainerStats = addContainerStats
module.exports.addFile = addFile
module.exports.addStats = addStats
module.exports.readdir = readdir
const $rdf = require('rdflib')
const debug = require('./debug')
const error = require('./http-error')
const fs = require('fs')
const ns = require('solid-namespace')($rdf)
const mime = require('mime-types')
const path = require('path')
async function addContainerStats (ldp, reqUri, filename, resourceGraph) {
const containerStats = await ldp.stat(filename)
addStats(resourceGraph, reqUri, containerStats, filename)
resourceGraph.add(
resourceGraph.sym(reqUri),
ns.rdf('type'),
ns.ldp('BasicContainer'))
resourceGraph.add(
resourceGraph.sym(reqUri),
ns.rdf('type'),
ns.ldp('Container'))
}
async function addFile (ldp, resourceGraph, containerUri, reqUri, container, file) {
// Skip .meta and .acl
if (file.endsWith(ldp.suffixMeta) || file.endsWith(ldp.suffixAcl)) {
return null
}
const filePath = path.join(container, file)
// Get file stats
let stats
try {
stats = await ldp.stat(filePath)
} catch (e) {
return null
}
let memberUri = reqUri + (stats.isDirectory() ? '/' : '')
// Add fileStats to resource Graph
addStats(resourceGraph, memberUri, stats, file)
// Add to `contains` list
resourceGraph.add(
resourceGraph.sym(containerUri),
ns.ldp('contains'),
resourceGraph.sym(memberUri))
// Set up a metaFile path
// Earlier code used a .ttl file as its own meta file, which
// caused massive data files to parsed as part of deirectory listings just looking for type triples
const metaFile = containerUri + file + ldp.suffixMeta
let metadataGraph
try {
metadataGraph = await getMetadataGraph(ldp, metaFile, memberUri)
} catch (err) {
metadataGraph = $rdf.graph()
}
// Add Container or BasicContainer types
if (stats.isDirectory()) {
resourceGraph.add(
metadataGraph.sym(memberUri),
ns.rdf('type'),
ns.ldp('BasicContainer'))
resourceGraph.add(
metadataGraph.sym(memberUri),
ns.rdf('type'),
ns.ldp('Container'))
}
// Add generic LDP type
resourceGraph.add(
metadataGraph.sym(memberUri),
ns.rdf('type'),
ns.ldp('Resource'))
// Add type from metadataGraph
metadataGraph
.statementsMatching(
metadataGraph.sym(memberUri),
ns.rdf('type'),
undefined)
.forEach(function (typeStatement) {
// If the current is a file and its type is BasicContainer,
// This is not possible, so do not infer its type!
if (
(
typeStatement.object.uri !== ns.ldp('BasicContainer').uri &&
typeStatement.object.uri !== ns.ldp('Container').uri
) ||
!stats.isFile()
) {
resourceGraph.add(
resourceGraph.sym(reqUri),
typeStatement.predicate,
typeStatement.object)
}
})
return null
}
function addStats (resourceGraph, reqUri, stats, filename) {
resourceGraph.add(
resourceGraph.sym(reqUri),
ns.stat('mtime'), // Deprecate?
stats.mtime.getTime() / 1000)
resourceGraph.add(
resourceGraph.sym(reqUri),
ns.dct('modified'),
stats.mtime) // An actual datetime value from a Date object
resourceGraph.add(
resourceGraph.sym(reqUri),
ns.stat('size'),
stats.size)
if (mime.lookup(filename)) { // Is the file has a well-known type,
let type = 'http://www.w3.org/ns/iana/media-types/' + mime.lookup(filename) + '#Resource'
resourceGraph.add(
resourceGraph.sym(reqUri),
ns.rdf('type'), // convert MIME type to RDF
resourceGraph.sym(type)
)
}
}
function readdir (filename) {
debug.handlers('GET -- Reading directory')
return new Promise((resolve, reject) => {
fs.readdir(filename, function (err, files) {
if (err) {
debug.handlers('GET -- Error reading files: ' + err)
return reject(error(err, 'Can\'t read container'))
}
debug.handlers('Files in directory: ' + files.toString().slice(0, 100))
return resolve(files)
})
})
}
async function getMetadataGraph (ldp, metaFile) {
const metaStats = await ldp.stat(metaFile)
if (metaStats && metaStats.isFile()) {
try {
return await ldp.getGraph(metaFile)
} catch (err) {
throw error(err, 'Can\'t parse container metadata')
}
} else {
return $rdf.graph()
}
}