mirror of
https://github.com/koreader/koreader
synced 2024-11-10 01:10:34 +00:00
98 lines
1.8 KiB
Lua
98 lines
1.8 KiB
Lua
-- parse "metadata.calibre" files
|
|
local lj = require("lunajson")
|
|
local rapidjson = require("rapidjson")
|
|
|
|
local array_fields = {
|
|
authors = true,
|
|
tags = true,
|
|
series = true,
|
|
}
|
|
|
|
local required_fields = {
|
|
authors = true,
|
|
last_modified = true,
|
|
lpath = true,
|
|
series = true,
|
|
series_index = true,
|
|
size = true,
|
|
tags = true,
|
|
title = true,
|
|
uuid = true,
|
|
}
|
|
|
|
local field
|
|
local t = {}
|
|
local function append(v)
|
|
-- Some fields *may* be arrays, so check whether we ran through startarray first or not
|
|
if t[field] then
|
|
table.insert(t[field], v)
|
|
else
|
|
t[field] = v
|
|
field = nil
|
|
end
|
|
end
|
|
|
|
local depth = 0
|
|
local result = rapidjson.array({})
|
|
local sax = {
|
|
startobject = function()
|
|
depth = depth + 1
|
|
end,
|
|
endobject = function()
|
|
if depth == 1 then
|
|
table.insert(result, rapidjson.object(t))
|
|
t = {}
|
|
end
|
|
depth = depth - 1
|
|
end,
|
|
startarray = function()
|
|
if array_fields[field] then
|
|
t[field] = rapidjson.array({})
|
|
end
|
|
end,
|
|
endarray = function()
|
|
if field then
|
|
field = nil
|
|
end
|
|
end,
|
|
key = function(s)
|
|
if required_fields[s] then
|
|
field = s
|
|
end
|
|
end,
|
|
string = function(s)
|
|
if field then
|
|
append(s)
|
|
end
|
|
end,
|
|
number = function(n)
|
|
if field then
|
|
append(n)
|
|
end
|
|
end,
|
|
boolean = function(b)
|
|
if field then
|
|
append(b)
|
|
end
|
|
end,
|
|
}
|
|
|
|
local function parse_unsafe(path)
|
|
local p = lj.newfileparser(path, sax)
|
|
p.run()
|
|
end
|
|
|
|
local parser = {}
|
|
|
|
function parser.parseFile(file)
|
|
result = rapidjson.array({})
|
|
local ok, err = pcall(parse_unsafe, file)
|
|
field = nil
|
|
if not ok then
|
|
return nil, err
|
|
end
|
|
return result
|
|
end
|
|
|
|
return parser
|