2013-12-20 16:29:46 +01:00
|
|
|
--
|
|
|
|
-- This file is part of the Doodle3D project (http://doodle3d.com).
|
|
|
|
--
|
|
|
|
-- @copyright 2013, Doodle3D
|
|
|
|
-- @license This software is licensed under the terms of the GNU GPL v2 or later.
|
|
|
|
-- See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
|
|
|
|
|
|
|
|
|
2013-10-30 21:20:42 +01:00
|
|
|
local wifi = require('network.wlanconfig')
|
|
|
|
local netconf = require('network.netconfig')
|
|
|
|
local settings = require('util.settings')
|
|
|
|
|
2013-12-04 17:40:43 +01:00
|
|
|
-- NOTE: the updater module 'detects' command-line invocation by existence of 'arg', so we have to make sure it is not defined.
|
2013-10-18 21:46:41 +02:00
|
|
|
argStash = arg
|
|
|
|
arg = nil
|
|
|
|
local updater = require('script.d3d-updater')
|
|
|
|
arg = argStash
|
|
|
|
|
|
|
|
local log = require('util.logger')
|
|
|
|
local utils = require('util.utils')
|
2013-10-23 16:12:19 +02:00
|
|
|
local accessManager = require('util.access')
|
|
|
|
local printerAPI = require('rest.api.api_printer')
|
2013-10-18 21:46:41 +02:00
|
|
|
|
|
|
|
local M = {
|
|
|
|
isApi = true
|
|
|
|
}
|
|
|
|
|
2013-10-23 16:12:19 +02:00
|
|
|
|
|
|
|
-- TODO: this function is also defined in 2 other places, combine them (and avoid require loops)
|
|
|
|
local function operationsAccessOrFail(request, response)
|
|
|
|
if not accessManager.hasControl(request.remoteAddress) then
|
|
|
|
response:setFail("No control access")
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local rv, printerState = printerAPI.state(request, response, true)
|
2013-12-20 17:11:58 +01:00
|
|
|
-- NOTE: rv being false means a printer device exists but no server is running for it, so it cannot be 'busy'
|
|
|
|
if rv == false then return true end
|
2013-10-23 16:12:19 +02:00
|
|
|
|
|
|
|
if printerState == 'buffering' or printerState == 'printing' or printerState == 'stopping' then
|
|
|
|
response:setFail("Printer is busy, please wait")
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2013-10-18 21:46:41 +02:00
|
|
|
function M.status(request, response)
|
2014-02-25 14:26:31 +01:00
|
|
|
local includeBetas = settings.get('doodle3d.update.includeBetas')
|
|
|
|
local baseUrl = settings.get('doodle3d.update.baseUrl')
|
2013-10-18 21:46:41 +02:00
|
|
|
updater.setLogger(log)
|
2014-02-25 14:26:31 +01:00
|
|
|
updater.setBaseUrl(baseUrl)
|
2013-10-21 12:36:54 +02:00
|
|
|
updater.setUseCache(false)
|
2014-02-21 09:54:03 +01:00
|
|
|
local success,status,msg = updater.getStatus(includeBetas)
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
response:addData('current_version', updater.formatVersion(status.currentVersion))
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
response:addData('state_code', status.stateCode)
|
|
|
|
response:addData('state_text', status.stateText)
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
if not success then
|
2013-10-18 21:46:41 +02:00
|
|
|
response:setFail(msg)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-02-21 09:54:03 +01:00
|
|
|
local canUpdate = updater.compareVersions(status.newestVersion, status.currentVersion, status.newestReleaseTimestamp, status.currentReleaseTimestamp) > 0
|
2014-02-24 20:15:00 +01:00
|
|
|
if (status.currentVersion.suffix ~= nil) and not includeBetas then canUpdate = true end -- always allow downgrade from beta to stable if !includeBetas
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
response:addData('newest_version', updater.formatVersion(status.newestVersion))
|
2014-02-21 09:54:03 +01:00
|
|
|
if status.currentReleaseTimestamp then response:addData('current_release_date', updater.formatDate(status.currentReleaseTimestamp)) end
|
|
|
|
if status.newestReleaseTimestamp then response:addData('newest_release_date', updater.formatDate(status.newestReleaseTimestamp)) end
|
2013-10-18 21:46:41 +02:00
|
|
|
response:addData('can_update', canUpdate)
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-18 21:46:41 +02:00
|
|
|
if status.progress then response:addData('progress', status.progress) end
|
|
|
|
if status.imageSize then response:addData('image_size', status.imageSize) end
|
|
|
|
response:setSuccess()
|
|
|
|
end
|
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
-- accepts: version(string) (major.minor.patch)
|
2013-10-18 21:46:41 +02:00
|
|
|
-- accepts: clear_gcode(bool, defaults to true) (this is to lower the chance on out-of-memory crashes, but still allows overriding this behaviour)
|
|
|
|
-- accepts: clear_images(bool, defaults to true) (same rationale as with clear_gcode)
|
|
|
|
-- note: call this with a long timeout - downloading may take a while (e.g. ~3.3MB with slow internet...)
|
|
|
|
function M.download_POST(request, response)
|
|
|
|
local argVersion = request:get("version")
|
|
|
|
local argClearGcode = utils.toboolean(request:get("clear_gcode"))
|
|
|
|
local argClearImages = utils.toboolean(request:get("clear_images"))
|
|
|
|
if argClearGcode == nil then argClearGcode = true end
|
|
|
|
if argClearImages == nil then argClearImages = true end
|
|
|
|
|
2013-10-23 16:12:19 +02:00
|
|
|
-- block access to prevent potential issues with printing (e.g. out of memory)
|
|
|
|
if not operationsAccessOrFail(request, response) then return end
|
|
|
|
|
2014-02-25 14:26:31 +01:00
|
|
|
local includeBetas = settings.get('doodle3d.update.includeBetas')
|
|
|
|
local baseUrl = settings.get('doodle3d.update.baseUrl')
|
2013-10-18 21:46:41 +02:00
|
|
|
updater.setLogger(log)
|
2014-02-25 14:26:31 +01:00
|
|
|
updater.setBaseUrl(baseUrl)
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.DOWNLOADING,"")
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-21 12:36:54 +02:00
|
|
|
local vEnt, rv, msg
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
if not argVersion then
|
2014-02-21 09:54:03 +01:00
|
|
|
local success,status,msg = updater.getStatus(includeBetas)
|
2013-10-22 03:30:23 +02:00
|
|
|
if not success then
|
|
|
|
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
|
|
|
|
response:setFail(msg)
|
|
|
|
return
|
2013-10-23 16:12:19 +02:00
|
|
|
else
|
2013-10-22 03:30:23 +02:00
|
|
|
argVersion = updater.formatVersion(status.newestVersion)
|
|
|
|
end
|
|
|
|
end
|
2013-10-23 16:12:19 +02:00
|
|
|
|
2013-10-18 21:46:41 +02:00
|
|
|
if argClearImages then
|
|
|
|
rv,msg = updater.clear()
|
|
|
|
if not rv then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
|
2013-10-18 21:46:41 +02:00
|
|
|
response:setFail(msg)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if argClearGcode then
|
2013-10-21 13:42:58 +02:00
|
|
|
response:addData('gcode_clear',true)
|
|
|
|
local rv,msg = printer:clearGcode()
|
2013-10-18 21:46:41 +02:00
|
|
|
|
2013-10-21 13:42:58 +02:00
|
|
|
if not rv then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
|
2013-10-21 13:42:58 +02:00
|
|
|
response:setError(msg)
|
|
|
|
return
|
|
|
|
end
|
2013-10-18 21:46:41 +02:00
|
|
|
end
|
|
|
|
|
2014-02-24 15:22:08 +01:00
|
|
|
vEnt,msg = updater.findVersion(argVersion, includeBetas)
|
2013-10-21 12:36:54 +02:00
|
|
|
if vEnt == nil then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.DOWNLOAD_FAILED, "error searching version index (" .. msg .. ")")
|
2013-10-21 12:36:54 +02:00
|
|
|
response:setFail("error searching version index (" .. msg .. ")")
|
|
|
|
return
|
2013-10-21 13:42:58 +02:00
|
|
|
elseif vEnt == false then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.DOWNLOAD_FAILED, "no such version")
|
2013-10-21 12:36:54 +02:00
|
|
|
response:setFail("no such version")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
rv,msg = updater.downloadImageFile(vEnt)
|
2013-10-18 21:46:41 +02:00
|
|
|
if not rv then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.DOWNLOAD_FAILED, msg)
|
2013-10-18 21:46:41 +02:00
|
|
|
response:setFail(msg)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
response:setSuccess()
|
|
|
|
end
|
|
|
|
|
|
|
|
-- if successful, this call won't return since the device will flash its memory and reboot
|
2013-12-04 17:40:43 +01:00
|
|
|
-- accepts: version (string, will try to use most recent if not specified)
|
|
|
|
-- accepts: no_retain (bool, device will be completely cleaned if true (aka '-n' flag to sysupgrade))
|
2013-10-18 21:46:41 +02:00
|
|
|
function M.install_POST(request, response)
|
2013-10-21 12:36:54 +02:00
|
|
|
local argVersion = request:get("version")
|
2013-12-04 17:40:43 +01:00
|
|
|
local argNoRetain = request:get("no_retain")
|
2013-12-23 17:36:57 +01:00
|
|
|
log:info("API:update/install (noRetain: "..utils.dump(argNoRetain)..")")
|
2013-12-23 23:24:31 +01:00
|
|
|
local noRetain = argNoRetain == 'true'
|
2014-02-21 09:54:03 +01:00
|
|
|
|
2013-10-23 16:12:19 +02:00
|
|
|
if not operationsAccessOrFail(request, response) then return end
|
2014-02-21 09:54:03 +01:00
|
|
|
|
2014-02-25 14:26:31 +01:00
|
|
|
local includeBetas = settings.get('doodle3d.update.includeBetas')
|
|
|
|
local baseUrl = settings.get('doodle3d.update.baseUrl')
|
|
|
|
updater.setBaseUrl(baseUrl)
|
2013-10-23 16:12:19 +02:00
|
|
|
updater.setLogger(log)
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.INSTALLING,"")
|
2013-12-04 17:40:43 +01:00
|
|
|
|
2014-01-10 12:23:32 +01:00
|
|
|
--local ssid = wifi.getSubstitutedSsid(settings.get('network.ap.ssid'))
|
|
|
|
--local rv,msg = netconf.enableAccessPoint(ssid)
|
2013-12-04 17:40:43 +01:00
|
|
|
|
2013-10-21 12:36:54 +02:00
|
|
|
if not argVersion then
|
2014-02-21 09:54:03 +01:00
|
|
|
local success,status,msg = updater.getStatus(includeBetas)
|
2013-10-22 03:30:23 +02:00
|
|
|
if not success then
|
|
|
|
updater.setState(updater.STATE.INSTALL_FAILED, msg)
|
|
|
|
response:setFail(msg)
|
|
|
|
return
|
2013-10-23 16:12:19 +02:00
|
|
|
else
|
2013-10-22 03:30:23 +02:00
|
|
|
argVersion = updater.formatVersion(status.newestVersion)
|
|
|
|
end
|
2013-10-21 12:36:54 +02:00
|
|
|
end
|
|
|
|
|
2014-02-24 15:22:08 +01:00
|
|
|
vEnt,msg = updater.findVersion(argVersion, includeBetas)
|
2013-10-21 13:42:58 +02:00
|
|
|
if vEnt == nil then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.INSTALL_FAILED, "error searching version index (" .. msg .. ")")
|
2013-10-21 13:42:58 +02:00
|
|
|
response:setFail("error searching version index (" .. msg .. ")")
|
|
|
|
return
|
|
|
|
elseif vEnt == false then
|
2013-10-22 03:30:23 +02:00
|
|
|
updater.setState(updater.STATE.INSTALL_FAILED, "no such version")
|
2013-10-21 13:42:58 +02:00
|
|
|
response:setFail("no such version")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2013-12-23 23:24:31 +01:00
|
|
|
local rv,msg = updater.flashImageVersion(vEnt, noRetain)
|
2013-10-21 12:36:54 +02:00
|
|
|
|
2013-10-22 03:30:23 +02:00
|
|
|
if not rv then
|
|
|
|
updater.setState(updater.STATE.INSTALL_FAILED, "installation failed (" .. msg .. ")")
|
|
|
|
response:setFail("installation failed (" .. msg .. ")")
|
2013-10-23 16:12:19 +02:00
|
|
|
else
|
2013-10-22 03:30:23 +02:00
|
|
|
response:setSuccess()
|
2013-10-21 12:36:54 +02:00
|
|
|
end
|
2013-10-18 21:46:41 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function M.clear_POST(request, response)
|
|
|
|
updater.setLogger(log)
|
|
|
|
local rv,msg = updater.clear()
|
|
|
|
|
|
|
|
if rv then response:setSuccess()
|
|
|
|
else response:setFail(msg)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return M
|