mostly implemented an import system

This commit is contained in:
2026-07-31 20:51:08 -06:00
parent f4efb0f48a
commit ae9d04ffa7
2 changed files with 153 additions and 10 deletions
Regular → Executable
+143 -1
View File
@@ -66,6 +66,13 @@ local filters = {
end
return false
end,
exclude_series = function(book)
if book.hidden then return false end
if book.series and not (book.title or book.author) then
return false
end
return true
end,
}
local sort_orders
@@ -84,7 +91,7 @@ sort_orders = {
end,
most_pages_remaining = function(A, B)
if not (A.pages and B.pages) then -- if pages is unknown for both, fallback to percentage
return A.progress > B.progress
return A.progress < B.progress
end
local average_page_count = data.total_pages / #data.books
local a = (A.pages or average_page_count) - (A.pages or average_page_count) * A.progress
@@ -96,6 +103,47 @@ sort_orders = {
end,
}
local get_display_name = function(book)
local result = ""
if book.title then
result = book.title
if book.author then
result = result .. " by " .. book.author
end
elseif book.author then
result = book.author .. " (author)"
end
if book.series then
if #result > 0 then
result = result .. " (" .. book.series .. ")"
else
result = book.series .. " (series)"
end
end
if book.genre then
if #result > 0 then
result = result .. " (" .. book.genre .. ")"
else
result = book.genre .. " (genre)"
end
end
if book.pages then
result = result .. " ~" .. math.floor(book.progress * book.pages) .. "/" .. book.pages .. " pages read"
elseif book.progress > 0 and book.progress < 1 then
result = result .. " ~" .. math.floor(book.progress * 100) .. "% read"
end
return result
end
-- TODO this procedural code should be split into functions where feasible
local data
if path_exists(default_file) then
data = load_json(default_file)
@@ -115,4 +163,98 @@ else
},
},
}
save_json(default_file, data)
end
-- main menu
-- TODO should be a loop/function to return to
local selected_books = {}
for i = 1, #data.books do
local book = data.books[i]
if filters[data.defaults.launch.filter](book) then
selected_books[#selected_books + 1] = book
end
end
table.sort(selected_books, sort_orders[data.defaults.launch.sort])
for i = 1, math.min(10, #selected_books) do
local book = selected_books[i]
print(" " .. (i == 10 and "0" or i) .. ". " .. get_display_name(book))
end
print("Commands: " .. (#selected_books > 0 and "[0-9] to modify a book's progress. " or "") .. "[a <book>] to add a book. [i <file>] to import from a JSON file.")
-- TODO define what can go in <book> and how it will be interpreted
-- TODO actually implement modifying progress and adding books
-- TODO implement elo ranking
-- TODO type title to add or edit an extant book (this is better than the "a" command I wrote above)
local input = io.read("*line")
if input:sub(1, 1) == "i" then
-- TODO this should all be broken out into a function
import = load_json(input:sub(3))
if import.books then
for i = 1, #import.books do
data.books[#data.books + 1] = import.books[i]
-- TODO detect and ignore duplicates (would be better to provide user an option for what to do with duplicates)
-- default should accept highest progress of duplicates?
end
else -- assume we are importing from decider.lua's format
for title, value in pairs(import) do
local run = function()
local book = { -- minimum required book data strucutre
priority = 0,
progress = 0,
}
local i = title:find(" %(.-series.-%)")
if i then
book.series = title:sub(1, i - 1)
end
local i = title:find(" %(trilogy%)")
if i then
book.series = title:sub(1, i - 1)
end
local i = title:find(" %(.-author%)")
if i then
book.author = title:sub(1, i - 1)
end
local i = title:find(" %(genre%)")
if i then
print("Skipping import of \"" .. title .. "\"")
return false
end
if not (book.series or book.author) then
-- TODO detect " by " and split if needed
book.title = title
end
if type(value) == "number" then
book.priority = value
else
book.priority = value.score
if value.done == true then
book.progress = 1
elseif value.done == false then
book.hidden = true
end
end
-- TODO detect duplicates before adding them
data.books[#data.books + 1] = book
end
run()
end
end
save_json(default_file, data)
-- TODO there should be a sort of main menu I am returned to
end