-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmetadata
130 lines (120 loc) · 2.98 KB
/
metadata
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
local unpack = unpack or table.unpack
function parse(path)
if fs.exists(path) then
local handle = fs.open(path, "r")
if handle then
local data = {}
local fn, err = loadstring(handle.readAll())
handle.close()
if fn then
setfenv(fn, data)
local success, err = pcall(fn)
if success then
return data
else
return nil, err
end
else
return nil, err
end
else
return nil, "could not read metadata"
end
else
return nil, "no metadata found"
end
end
function getMetaFolderForPath(path)
local drive = fs.getDrive(path)
if drive == "hdd" or drive == "rom" then
return "/.meta", path
elseif drive then
local mountPath = disk.getMountPath(drive)
local metaPath = fs.combine(mountPath, ".meta")
if string.sub(mountPath, 1, 1) ~= "/" then mountPath = "/"..mountPath end
if string.sub(path, 1, 1) ~= "/" then path = "/"..path end
local pathRemainder = string.match(path, fs.combine(mountPath, "(.*)"))
return metaPath, pathRemainder
else
return "/.meta", path
end
end
function getForFile(path)
return metadata.parse(fs.combine(metadata.getMetaFolderForPath(path)))
end
function getForFolder(path)
if fs.exists(path) and fs.isDir(path) then
local data = {}
for _, file in ipairs(fs.list(fs.combine(metadata.getMetaFolderForPath(path), path))) do
data[fs.combine(path, file)] = metadata.parse(fs.combine(fs.combine(metadata.getMetaFolderForPath(path), path), file))
end
return data
end
end
local function walkFolder(path, meta)
local path = path or "/"
local data = meta or {}
if fs.exists(path) and fs.isDir(path) then
for _, file in ipairs(fs.list(path)) do
local current = fs.combine(path, file)
if fs.isDir(current) then
walkFolder(current, data)
else
data[current] = metadata.getForFile(current)
end
end
return data
end
end
function load()
if fs.exists(".meta") and fs.isDir(".meta") then
return walkFolder()
else
return nil, "no metadata available"
end
end
function prepare(meta)
local str = ""
for k, v in pairs(meta) do
if type(k) == "string" then
if type(v) == "number" or type(v) == "string" or type(v) == "boolean" then
str = str..k.." = "..tostring(v).."\n"
elseif type(v) == "table" then
str = str..k.." = "..textutils.serialize(v).."\n"
end
end
end
return str
end
local function makeFolders(path)
local folders = ""
repeat
local newFolder = string.match(path, folders.."([^/]+/)")
if not newFolder then break end
folders = folders..newFolder
if not fs.exists(folders) then fs.makeDir(folders) end
until false
end
function save(path, meta)
if meta then
local data = prepare(meta)
local path = fs.combine(metadata.getMetaFolderForPath(path))
makeFolders(path)
local handle = fs.open(path, "w")
if handle then
handle.write(data)
handle.close()
else
return nil, "could not open metadata file"
end
else
return nil, "no metadata to write"
end
end
function saveAll(meta)
if meta then
for k, v in pairs(meta) do
metadata.save(k, v)
end
end
end