Added item-reports endpoint, schematic-exporter2.lua
This commit is contained in:
parent
78a8aec3e8
commit
4762e216d9
|
@ -0,0 +1,299 @@
|
|||
local g = require("simple-graphics")
|
||||
local mon = peripheral.wrap("monitor_24")
|
||||
local W, H = mon.getSize()
|
||||
local RUNNING = true -- Flag to indicate global program state.
|
||||
|
||||
-- Export flags
|
||||
local EXPORTING = false -- Flag to indicate if we're exporting.
|
||||
local EXPORT_SKIP = false -- Flag to indicate we should skip the current item.
|
||||
local EXPORT_REPORT = false -- Flag to indicate we should report the current item as invalid.
|
||||
|
||||
local function startsWith(str, start)
|
||||
return str:sub(1, #start) == start
|
||||
end
|
||||
|
||||
local function getTotalItemCount(itemList)
|
||||
local total = 0
|
||||
for name, value in pairs(itemList) do
|
||||
if not startsWith(name, "__") then
|
||||
total = total + value
|
||||
end
|
||||
end
|
||||
local count = 1
|
||||
if itemList.__COUNT__ then count = itemList.__COUNT__ end
|
||||
return count * total
|
||||
end
|
||||
|
||||
local function findItem(items, name)
|
||||
for _, item in pairs(items) do
|
||||
if item.name == name then return item end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function attemptItemExport(name, count)
|
||||
local P_NAME = "meBridge_4"
|
||||
local p = peripheral.wrap(P_NAME)
|
||||
if p == nil then
|
||||
return nil, "Missing peripheral "..P_NAME
|
||||
end
|
||||
local func = function()
|
||||
return p.exportItem({name=name, count=count}, "south")
|
||||
end
|
||||
local success, result = pcall(func)
|
||||
if success then
|
||||
return result
|
||||
else
|
||||
return nil, result
|
||||
end
|
||||
end
|
||||
|
||||
local function drawProgress(p)
|
||||
local discreteWidth = W - 2
|
||||
local filled = p * discreteWidth
|
||||
g.drawXLine(mon, 2, W-1, 5, colors.lightGray)
|
||||
g.drawXLine(mon, 2, 2+filled-1, 5, colors.green)
|
||||
local s = string.format("%.0f%%", p*100)
|
||||
for i = 1, #s do
|
||||
local x = 2+i
|
||||
local c = s:sub(i,i)
|
||||
local bg = colors.lightGray
|
||||
if x < filled then bg = colors.green end
|
||||
g.drawText(mon, x, 5, c, colors.white, bg)
|
||||
end
|
||||
end
|
||||
|
||||
local function setProgressText(text)
|
||||
g.drawXLine(mon, 2, W-1, 6, colors.gray)
|
||||
if text ~= nil and #text > 0 then
|
||||
g.drawText(mon, 2, 6, text, colors.white, colors.gray)
|
||||
end
|
||||
end
|
||||
|
||||
local function clearMainPanel()
|
||||
g.fillRect(mon, 1, 7, W, H-6, colors.black)
|
||||
end
|
||||
|
||||
local function clearExportPanel()
|
||||
g.fillRect(mon, 1, 7, W, H-9, colors.black)
|
||||
end
|
||||
|
||||
local function promptForUrlInput()
|
||||
clearMainPanel()
|
||||
drawProgress(0)
|
||||
setProgressText(nil)
|
||||
g.drawText(mon, 1, 8, "Please enter a schematic URL that", colors.white, colors.black)
|
||||
g.drawText(mon, 1, 9, "you've obtained from", colors.white, colors.black)
|
||||
g.drawText(mon, 1, 10, "schematics.andrewlalis.com in the", colors.white, colors.black)
|
||||
g.drawText(mon, 1, 11, "computer to your right to continue.", colors.white, colors.black)
|
||||
|
||||
g.clear(term, colors.black)
|
||||
g.drawText(term, 1, 1, "Paste your schematic URL here (CTRL+V): ", colors.white)
|
||||
g.drawText(term, 2, 2, "*Press enter without pasting to quit*", colors.gray)
|
||||
term.setCursorPos(1, 3)
|
||||
term.setTextColor(colors.lightGray)
|
||||
local link = io.read()
|
||||
if link == nil or #link == 0 then
|
||||
g.drawText(term, 1, 8, "No URL entered. Quitting.", colors.white)
|
||||
return nil
|
||||
else
|
||||
g.drawText(term, 1, 8, "URL was pasted. Please continue on the monitor.", colors.white)
|
||||
return link
|
||||
end
|
||||
end
|
||||
|
||||
local function fetchItemLists(url)
|
||||
local response = http.get(url)
|
||||
if response == nil then
|
||||
return nil, "HTTP request failed."
|
||||
end
|
||||
if response.getResponseCode() ~= 200 then
|
||||
return nil, "HTTP code " .. response.getResponseCode()
|
||||
end
|
||||
local rawText = response.readAll()
|
||||
response.close()
|
||||
local itemLists, jsonErr = textutils.unserializeJSON(rawText)
|
||||
if not itemLists then
|
||||
return nil, "Failed to parse JSON: "..jsonErr
|
||||
end
|
||||
return itemLists
|
||||
end
|
||||
|
||||
local function exportItem(name, count)
|
||||
clearExportPanel()
|
||||
g.drawText(mon, 1, 7, "Exporting "..count.." of", colors.white, colors.black)
|
||||
g.drawText(mon, 1, 8, name, colors.lime, colors.black)
|
||||
-- Check for flags and do different stuff if so.
|
||||
if EXPORT_REPORT then
|
||||
-- Report the item issue to the schematic site.
|
||||
g.drawText(mon, 1, 10, "Reporting item. Skipping to next one.", colors.orange, colors.black)
|
||||
os.sleep(2)
|
||||
return count
|
||||
elseif EXPORT_SKIP then
|
||||
-- Skip this item.
|
||||
g.drawText(mon, 1, 10, "Skipping this item.", colors.orange, colors.black)
|
||||
os.sleep(2)
|
||||
return count
|
||||
end
|
||||
|
||||
local me = peripheral.find("meBridge")
|
||||
if me == nil then
|
||||
g.drawText(mon, 1, 10, "Error: No \"meBridge\" peripheral.", colors.red, colors.black)
|
||||
g.drawText(mon, 1, 11, "Attach one please.", colors.red, colors.black)
|
||||
os.sleep(1)
|
||||
return 0
|
||||
end
|
||||
|
||||
local allItems, err = me.listItems()
|
||||
if allItems == nil or #allItems < 5 then
|
||||
g.drawText(mon, 1, 10, "Error: Couldn't list AE items.", colors.red, colors.black)
|
||||
g.drawText(mon, 1, 11, "Msg: " .. err, colors.red, colors.black)
|
||||
os.sleep(1)
|
||||
return 0
|
||||
end
|
||||
|
||||
local item = findItem(allItems, name)
|
||||
if item ~= nil and item.amount > 0 then
|
||||
local exported, err = attemptItemExport(name, count)
|
||||
if exported ~= nil then
|
||||
if exported == 0 then
|
||||
g.drawText(mon, 1, 10, "Exported 0 items. Make sure there is", colors.yellow, colors.black)
|
||||
g.drawText(mon, 1, 11, "space in the output container.", colors.yellow, colors.black)
|
||||
os.sleep(0.5)
|
||||
end
|
||||
return exported
|
||||
end
|
||||
g.drawText(mon, 1, 10, "Transfer failed: " .. err, colors.red, colors.black)
|
||||
os.sleep(1)
|
||||
return 0
|
||||
else
|
||||
g.drawText(mon, 1, 10, "Item isn't present in the AE system.", colors.yellow, colors.black)
|
||||
g.drawText(mon, 1, 11, "Please add some, craft, or skip.", colors.yellow, colors.black)
|
||||
os.sleep(1)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local function exportSchematics(itemLists)
|
||||
-- First build a list of instances of schematics, each with a task list.
|
||||
local totalItemCount = 0
|
||||
local listInstances = {}
|
||||
for _, list in pairs(itemLists) do
|
||||
totalItemCount = totalItemCount + getTotalItemCount(list)
|
||||
for i = 1, list.__COUNT__ do
|
||||
local instance = {
|
||||
name = list.__NAME__,
|
||||
instanceNumber = i,
|
||||
countOfThisType = list.__COUNT__,
|
||||
tasks = {}
|
||||
}
|
||||
for name, amount in pairs(list) do
|
||||
if not startsWith(name, "__") then
|
||||
table.insert(instance.tasks, {name=name, amount=amount})
|
||||
end
|
||||
end
|
||||
table.insert(listInstances, instance)
|
||||
end
|
||||
end
|
||||
-- Now execute on that task list, quitting if the EXPORTING flag goes false.
|
||||
local totalItemsExported = 0
|
||||
local instanceIndex = 1
|
||||
while instanceIndex <= #listInstances and EXPORTING do
|
||||
local listInstance = listInstances[instanceIndex]
|
||||
setProgressText(listInstance.instanceNumber.."/"..listInstance.countOfThisType.." "..listInstance.name)
|
||||
local taskIndex = 1
|
||||
while taskIndex <= #listInstance.tasks and EXPORTING do
|
||||
local task = listInstance.tasks[taskIndex]
|
||||
local itemsExported = 0
|
||||
-- Reset item-specific control flags.
|
||||
EXPORT_REPORT = false
|
||||
EXPORT_SKIP = false
|
||||
while itemsExported < task.amount and EXPORTING do
|
||||
local exportedCount = exportItem(task.name, task.amount - itemsExported)
|
||||
itemsExported = itemsExported + exportedCount
|
||||
totalItemsExported = totalItemsExported + exportedCount
|
||||
drawProgress(totalItemsExported / totalItemCount)
|
||||
end
|
||||
taskIndex = taskIndex + 1
|
||||
end
|
||||
instanceIndex = instanceIndex + 1
|
||||
end
|
||||
-- Done! Show a small message, then set the EXPORTING flag to false.
|
||||
EXPORTING = false
|
||||
for i = 1, 3 do -- Queue up some no-op touch events make sure the event handler quits.
|
||||
os.queueEvent("monitor_touch", "monitor_24", 1, 1)
|
||||
end
|
||||
g.drawText(mon, 1, H-4, "Export complete!", colors.lime, colors.black)
|
||||
end
|
||||
|
||||
local function handleExportEvents()
|
||||
while EXPORTING do
|
||||
local event, monName, x, y = os.pullEvent("monitor_touch")
|
||||
if monName == "monitor_24" and y >= H-2 then
|
||||
if x >= 27 then
|
||||
EXPORTING = false
|
||||
elseif x >= 14 then
|
||||
EXPORT_REPORT = true
|
||||
else
|
||||
EXPORT_SKIP = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handleSchematicUrl(url)
|
||||
clearMainPanel()
|
||||
if url == nil then
|
||||
g.drawText(mon, 1, 8, "No URL was entered. Quitting.", colors.white, colors.black)
|
||||
RUNNING = false
|
||||
os.sleep(2)
|
||||
return
|
||||
end
|
||||
g.drawText(mon, 1, 8, "Fetching item lists from URL...", colors.lightGray, colors.black)
|
||||
local itemLists, err = fetchItemLists(url)
|
||||
if not itemLists then
|
||||
g.drawText(mon, 1, 9, "Failed to fetch item lists.", colors.red, colors.black)
|
||||
g.drawText(mon, 1, 10, err, colors.red, colors.black)
|
||||
os.sleep(3)
|
||||
return
|
||||
end
|
||||
g.drawText(mon, 1, 9, "Got lists for "..(#itemLists).." schematics.", colors.white, colors.black)
|
||||
local y = 10
|
||||
for i, itemList in pairs(itemLists) do
|
||||
local count = itemList.__COUNT__
|
||||
local name = itemList.__NAME__
|
||||
g.drawText(mon, 2, y, count.."x "..name, colors.white, colors.black)
|
||||
y = y+1
|
||||
if y == H and i < #itemLists then
|
||||
local numRemaining = #itemLists - i
|
||||
g.drawText(mon, 2, y, "... and "..numRemaining.." more.")
|
||||
end
|
||||
end
|
||||
os.sleep(3)
|
||||
-- Draw control buttons.
|
||||
g.fillRect(mon, 1, H-2, 13, 3, colors.blue)
|
||||
g.drawText(mon, 5, H-1, "Skip", colors.white)
|
||||
g.fillRect(mon, 14, H-2, 13, 3, colors.yellow)
|
||||
g.drawText(mon, 14, H-1, "Report Error", colors.lightBlue)
|
||||
g.fillRect(mon, 27, H-2, 13, 3, colors.red)
|
||||
g.drawText(mon, 31, H-1, "Quit", colors.white)
|
||||
EXPORTING = true
|
||||
local fExport = function() exportSchematics(itemLists) end
|
||||
local fHandleEvents = function() handleExportEvents() end
|
||||
parallel.waitForAll(fExport, fHandleEvents)
|
||||
end
|
||||
|
||||
-- MAIN SCRIPT
|
||||
|
||||
g.clear(mon, colors.black)
|
||||
g.fillRect(mon, 1, 1, W, 3, colors.yellow)
|
||||
g.drawTextCenter(mon, W/2, 2, "Schematic Exporter", colors.black)
|
||||
|
||||
g.fillRect(mon, 1, 4, W, 3, colors.gray)
|
||||
g.drawText(mon, 2, 4, "Progress", colors.white)
|
||||
g.drawXLine(mon, 2, W-1, 5, colors.lightGray)
|
||||
|
||||
while RUNNING do
|
||||
local url = promptForUrlInput()
|
||||
handleSchematicUrl(url)
|
||||
end
|
|
@ -17,6 +17,7 @@ void startServer() {
|
|||
PathDelegatingHandler handler = new PathDelegatingHandler();
|
||||
handler.addMapping("POST", "/extracts", &handleExtract);
|
||||
handler.addMapping("GET", "/extracts/{extractId}", &getExtract);
|
||||
handler.addMapping("POST", "/item-reports", &handleItemReport);
|
||||
handler.addMapping("GET", "/status", (ref HttpRequestContext ctx) {
|
||||
ctx.response.setStatus(HttpStatus.OK);
|
||||
ctx.response.writeBodyString("online");
|
||||
|
@ -42,4 +43,14 @@ private void getExtract(ref HttpRequestContext ctx) {
|
|||
string extractId = ctx.request.getPathParamAs!string("extractId");
|
||||
const extractFile = buildPath(EXTRACTS_DIR, extractId ~ ".json");
|
||||
fileResponse(ctx.response, extractFile, "application/json");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleItemReport(ref HttpRequestContext ctx) {
|
||||
import std.string : strip;
|
||||
import std.stdio;
|
||||
|
||||
string itemName = ctx.request.readBodyAsString().strip();
|
||||
File f = File("item-reports.txt", "a");
|
||||
f.writeln(itemName);
|
||||
f.close();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue