Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 39536
1
"""
2
Server directory listing through the HTTP server
3
4
{files:[..., {size:?,name:?,mtime:?,isdir:?}]}
5
6
where mtime is integer SECONDS since epoch, size is in bytes, and isdir
7
is only there if true.
8
9
Obviously we should probably use POST instead of GET, due to the
10
result being a function of time... but POST is so complicated.
11
Use ?random= or ?time= if you're worried about cacheing.
12
"""
13
14
fs = require('fs')
15
async = require('async')
16
17
exports.directory_listing_router = (express) ->
18
base = '/.smc/directory_listing/'
19
router = express.Router()
20
return directory_listing_http_server(base, router)
21
22
directory_listing_http_server = (base, router) ->
23
24
router.get base + '*', (req, res) ->
25
path = decodeURI(req.path.slice(base.length).trim())
26
hidden = req.query.hidden
27
exports.get_listing1 path, hidden, (err, listing) ->
28
if err
29
res.json({error:err})
30
else
31
res.json(listing)
32
###
33
exports.get_listing path, hidden, (err, info) ->
34
if err
35
res.json({error:err})
36
else
37
res.json({files:info})
38
###
39
40
return router
41
42
# SMC_LOCAL_HUB_HOME is used for developing cocalc inside cocalc...
43
HOME = process.env.SMC_LOCAL_HUB_HOME ? process.env.HOME
44
45
misc_node = require('smc-util-node/misc_node')
46
47
# We temporarily use the old cc-ls python script until the pure node get_listing0 below,
48
# which is 100x faster, works in all cases: symlinks, bad timestamps, etc.
49
exports.get_listing1 = (path, hidden, cb) ->
50
dir = HOME + '/' + path
51
if hidden
52
args = ['--hidden', dir]
53
else
54
args = [dir]
55
misc_node.execute_code
56
command : "cc-ls"
57
args : args
58
bash : false
59
cb : (err, out) ->
60
if err
61
cb(err)
62
else
63
cb(undefined, JSON.parse(out?.stdout))
64
65
exports.get_listing0 = (path, hidden, cb) ->
66
dir = HOME + '/' + path
67
fs.readdir dir, (err, files) ->
68
if err
69
cb(err)
70
return
71
if not hidden
72
files = (file for file in files when file[0] != '.')
73
74
get_metadata = (file, cb) ->
75
obj = {name:file}
76
# use lstat instead of stat so it works on symlinks too
77
fs.lstat dir + '/' + file, (err, stats) ->
78
if err
79
obj.error = err
80
else
81
if stats.isDirectory()
82
obj.isdir = true
83
else
84
obj.size = stats.size
85
obj.mtime = Math.floor((stats.mtime - 0)/1000)
86
cb(undefined, obj)
87
88
async.map(files, get_metadata, cb)
89
90
91
92
93
94
95
96
97
98