Version 2.0005

1) Added changelog support
2) Added remote file access support
master
Durel 7 years ago
parent d6504a1f97
commit e9e6299eae

@ -72,6 +72,8 @@ dbot.wish : Module to track which wishes a character has purchased
dbot.pagesize : Module to determine a character's current page size (# lines before page prompt)
dbot.execute : Execute one or more commands without contention from user-entered commands
dbot.callback : Module to help manage callback functions and parameters
dbot.remote : Module to retrieve remote files
dbot.version : Module to track version and changelog information and update the plugin
-->
@ -85,7 +87,7 @@ dbot.callback : Module to help manage callback functions and parameters
save_state="y"
date_written="2017-08-12 08:45:15"
requires="4.98"
version="2.0004"
version="2.0005"
>
<description trim="y">
<![CDATA[
@ -157,7 +159,7 @@ Usage
dinv pass <pass ID> <# of seconds>
Plugin info
dinv version [check | update] <confirm>
dinv version [check | changelog | update confirm]
dinv help <command>
@ -347,7 +349,7 @@ Feature Wishlist
<alias
script="inv.cli.version.fn"
match="^[ ]*dinv[ ]+version[ ]*(check|update[ ]+confirm)?[ ]*$"
match="^[ ]*dinv[ ]+version[ ]*(check|changelog|update[ ]+confirm)?[ ]*$"
enabled="y"
regexp="y"
send_to="12"
@ -615,6 +617,7 @@ require "check"
require "serialize"
require "tprint"
require "gmcphelper"
require "async"
-- Use the absolute path to the file in case a user's current directory isn't what we'd expect
dofile(GetInfo(56) .. GetInfo(60) .. "aardwolf_colors.lua")
@ -4405,6 +4408,10 @@ function inv.cli.version.fn(name, line, wildcards)
retval = inv.version.display()
return inv.tags.stop(invTagsVersion, line, retval)
elseif (command == "changelog") then
dbot.info("Full changelog:")
retval = dbot.version.changelog(0, line) -- show changelog from version 0 to the latest
elseif (command == "check") then
retval = dbot.update.version(drlDbotUpdateCheck, line)
@ -4418,7 +4425,7 @@ end -- inv.cli.version.fn
function inv.cli.version.usage()
dbot.print("@W " .. pluginNameCmd .. " version @G[check | update] @Y<confirm>@w")
dbot.print("@W " .. pluginNameCmd .. " version @Y[check | changelog | update confirm]@w")
end -- inv.cli.version.usage
@ -4429,17 +4436,22 @@ function inv.cli.version.examples()
[[@W
The version mode without arguments will tell you the version information for the
plugin and format versions for components of the plugin. You can also check if
you have the latest official plugin release and update to that release if you are
not yet running the latest and greatest version of the plugin.
you have the latest official plugin release and optionally view the changelog
between your current version and the latest version. If you wish to upgrade to
the latest release, you can do that too :)
Examples:
1) Display your current version information
"@Gdinv version@W"
2) Compare your plugin version to the version of the latest published release
and display the changelog between your version and the latest release
"@Gdinv version check@W"
3) Check if you have the latest plugin version. If your version is not the
3) Display the entire plugin changelog
"@Gdinv version changelog@W"
4) Check if you have the latest plugin version. If your version is not the
latest and greatest, download the latest release and install it. You do
not need to log out or restart mush.
"@Gdinv version update confirm@W"
@ -15912,6 +15924,8 @@ dbot.wish : Module to track which wishes a character has purchased
dbot.pagesize : Module to determine a character's current page size (# lines before page prompt)
dbot.execute : Execute one or more commands without contention from user-entered commands
dbot.callback : Module to help manage callback functions and parameters
dbot.remote : Module to retrieve remote files
dbot.version : Module to track version and changelog information and update the plugin
--]]
@ -16081,146 +16095,6 @@ function dbot.reload()
end -- dbot.reload
----------------------------------------------------------------------------------------------------
-- dbot.update: If the current plugin isn't the latest published version, update it, and reload it
--
-- Note: This code is derived from a plugin written by Arcidayne. Thanks Arcidayne!
----------------------------------------------------------------------------------------------------
dbot.update = {}
dbot.update.url = "https://raw.githubusercontent.com/Aardurel/aard-plugins/master/aard_inventory.xml"
dbot.update.protocol = "HTTPS"
dbot.update.pkg = nil
drlDbotUpdateCheck = "check"
drlDbotUpdateInstall = "install"
function dbot.update.version(mode, endTag)
local retval = DRL_RET_SUCCESS
if (mode == nil) or ((mode ~= drlDbotUpdateCheck) and (mode ~= drlDbotUpdateInstall)) then
dbot.warn("dbot.update.version: Missing or invalid mode parameter")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_INVALID_PARAM)
end -- if
if (dbot.update.pkg ~= nil) then
dbot.info("Skipping update request: another update request is in progress")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_BUSY)
end -- if
-- Pull in the async package if it exists
local asyncOk, async = pcall (require, "async")
if (not asyncOk) or (async == nil) then
dbot.warn("dbot.update.version: Failed to find \"async\" package, skipping update request")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_UNSUPPORTED)
end -- if
dbot.update.pkg = {}
dbot.update.pkg.mode = mode
dbot.update.pkg.endTag = endTag
-- Make a request to grab the latest plugin file. Newer versions of mush have nice async
-- capabilities and we use that if possible. Otherwise, we fall back to an old-style request.
-- Both methods of making the request will call dbot.update.callback upon completion.
if (async.doAsyncRemoveRequest ~= nil) then
async.doAsyncRemoteRequest(dbot.update.url, dbot.update.callback, dbot.update.protocol)
else
wait.make(dbot.updateCR) -- Fall back to a co-routine running the old-style async code
end
return retval
end -- dbot.update
-- Scan the file we just (hopefully) downloaded and check the file's version. If the user
-- requested a version check, we report the current and latest available versions. If the
-- user requested an installation of the latest plugin, do the upgrade if everything looks
-- sane.
function dbot.update.callback(retval, page, status, headers, fullStatus, requestUrl)
local retval = DRL_RET_SUCCESS
if (dbot.update.pkg == nil) or (dbot.update.pkg.mode == nil) then
dbot.error("dbot.update.callback: Missing or invalid update package detected")
return inv.tags.stop(invTagsVersion, "end tag is nil", DRL_RET_INVALID_PARAM)
end -- if
local endTag = dbot.update.pkg.endTag
if (status ~= 200) then
dbot.warn("dbot.update.callback: Failed to retrieve remote plugin information")
retval = DRL_RET_INTERNAL_ERROR
else
local currentVersion = GetPluginInfo(GetPluginID(), 19) or 0
local currentVerStr = string.format("%1.4f", currentVersion)
local remoteVerStr = string.match(page, '%s%s+version="([0-9%.]+)"')
local remoteVersion = tonumber(remoteVerStr or "") or 0
if (remoteVersion == currentVersion) then
dbot.info("You are running the most recent plugin (v" .. currentVerStr .. ")")
elseif (remoteVersion < currentVersion) then
dbot.warn("Your current plugin (v" .. currentVerStr .. ") " ..
"is newer than the latest official release (v" .. remoteVerStr .. ")")
retval = DRL_RET_VER_MISMATCH
elseif (dbot.update.pkg.mode == drlDbotUpdateCheck) then
dbot.info("You are running v" .. currentVerStr .. ", latest version is v" .. remoteVerStr)
elseif (dbot.update.pkg.mode == drlDbotUpdateInstall) then
dbot.info("Updating plugin from version " .. currentVerStr .. " to version " .. remoteVerStr)
dbot.info("Please do not enter anything until the update completes")
local pluginFile = GetPluginInfo(GetPluginID(), 6)
local file = io.open(pluginFile, "w")
file:write(page)
file:close()
dbot.reload()
else
dbot.error("dbot.update.callback: Detected invalid mode \"@R" .. (dbot.update.pkg.mode or "nil") ..
"@W\"")
end -- if
end -- if
dbot.update.pkg = nil
return inv.tags.stop(invTagsVersion, endTag, retval)
end -- dbot.update.callback
function dbot.updateCR()
local urlThread = async.request(dbot.update.url, dbot.update.protocol)
local updateRet, page, status, headers, fullStatus = -1, nil, -1, nil, nil, dbot.update.url
if (urlThread == nil) then
dbot.warn("dbot.updateCR: Failed to create thread requesting update")
else
local timeout = 10
local totTime = 0
while (urlThread:alive()) do
if (totTime > timeout) then
retval = DRL_RET_TIMEOUT
break
end -- if
wait.time(drlSpinnerPeriodDefault)
totTime = totTime + drlSpinnerPeriodDefault
end -- while
if (retval ~= DRL_RET_SUCCESS) then
updateRet, page, status, headers, fullStatus = urlThread:join()
end -- if
end -- if
dbot.update.callback(updateRet, page, status, headers, fullStatus)
end -- dbot.updateCR
----------------------------------------------------------------------------------------------------
-- dbot.shell: Run a shell command in the background without pulling up a command prompt window
----------------------------------------------------------------------------------------------------
@ -19576,6 +19450,376 @@ function dbot.callback.wait(resultData, timeout, period)
end -- dbot.callback.wait
----------------------------------------------------------------------------------------------------
-- Module to retrieve remote files
--
-- dbot.remote.get(url, protocol)
-- dbot.remote.getCR()
--
----------------------------------------------------------------------------------------------------
dbot.remote = {}
dbot.remote.getPkg = nil
-- Blocks and then returns file, retval
-- Must be called from within a co-routine
function dbot.remote.get(url, protocol)
local retval = DRL_RET_SUCCESS
local fileData = nil
if (url == nil) or (url == "") then
dbot.warn("dbot.remote.get: missing url parameter")
return fileData, DRL_RET_INVALID_PARAMETER
end -- if
if (protocol == nil) or (protocol == "") then
dbot.warn("dbot.remote.get: missing protocol parameter")
return fileData, DRL_RET_INVALID_PARAMETER
end -- if
if (dbot.remote.getPkg ~= nil) then
dbot.info("Skipping remote request: another request is in progress")
return fileData, DRL_RET_BUSY
end -- if
dbot.remote.getPkg = {}
dbot.remote.getPkg.url = url
dbot.remote.getPkg.protocol = protocol
dbot.remote.getPkg.isDone = false
wait.make(dbot.remote.getCR)
local timeout = 10
local totTime = 0
while (dbot.remote.getPkg.isDone == false) do
if (totTime > timeout) then
retval = DRL_RET_TIMEOUT
break
end -- if
wait.time(drlSpinnerPeriodDefault)
totTime = totTime + drlSpinnerPeriodDefault
end -- while
if (dbot.remote.getPkg ~= nil) and (dbot.remote.getPkg.fileData ~= nil) then
fileData = dbot.remote.getPkg.fileData
else
dbot.warn("dbot.remote.get: Failed to find data for file \"@G" .. url .. "@W\"")
retval = DRL_RET_MISSING_ENTRY
end -- if
dbot.remote.getPkg = nil
return fileData, retval
end -- dbot.remote.get
function dbot.remote.getCR()
local retval = DRL_RET_SUCCESS
if (dbot.remote.getPkg == nil) or (dbot.remote.getPkg.url == nil) then
dbot.error("dbot.remote.getCR: remote package is nil or corrupted!")
dbot.remote.getPkg = nil
return DRL_RET_INTERNAL_ERROR
end -- if
local urlThread = async.request(dbot.remote.getPkg.url, dbot.remote.getPkg.protocol)
if (urlThread == nil) then
dbot.warn("dbot.remote.getCR: Failed to create thread requesting remote data")
retval = DRL_RET_INTERNAL_ERROR
else
local timeout = 10
local totTime = 0
while (urlThread:alive()) do
if (totTime > timeout) then
retval = DRL_RET_TIMEOUT
break
end -- if
wait.time(drlSpinnerPeriodDefault)
totTime = totTime + drlSpinnerPeriodDefault
end -- while
local remoteRet, page, status, headers, fullStatus = urlThread:join()
if (status ~= 200) then
dbot.warn("dbot.remote.getCR: Failed to retrieve remote file")
retval = DRL_RET_INTERNAL_ERROR
else
dbot.remote.getPkg.fileData = page
end -- if
dbot.remote.getPkg.isDone = true
end -- if
return retval
end -- dbot.remote.getCR
----------------------------------------------------------------------------------------------------
-- dbot.version: Track the plugin's version and changelog and update the plugin
--
-- dbot.version.changelog(minVersion, endTag)
-- dbot.version.changelogCR()
-- dbot.version.displayChanges(minVersion, changeLog)
-- dbot.version.displayChange(changeLogEntries)
--
--
-- Note: This code is derived from a plugin written by Arcidayne. Thanks Arcidayne!
----------------------------------------------------------------------------------------------------
dbot.version = {}
dbot.version.changeLogPkg = nil
drlDbotChangeLogTypeFix = "@RFix@W"
drlDbotChangeLogTypeNew = "@GNew@W"
drlDbotChangeLogTypeMisc = "@yMsc@W"
function dbot.version.changelog(minVersion, endTag)
local url = "https://raw.githubusercontent.com/Aardurel/aard-plugins/master/aard_inventory.changelog"
local protocol = "HTTPS"
if (dbot.version.changeLogPkg ~= nil) then
dbot.info("Skipping changelog request: another request is in progress")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_BUSY)
end -- if
dbot.version.changeLogPkg = {}
dbot.version.changeLogPkg.url = url
dbot.version.changeLogPkg.protocol = protocol
dbot.version.changeLogPkg.minVersion = minVersion or 0
dbot.version.changeLogPkg.endTag = endTag
wait.make(dbot.version.changelogCR)
return DRL_RET_SUCCESS
end -- dbot.version.changelog
function dbot.version.changelogCR()
if (dbot.version.changeLogPkg == nil) then
dbot.error("dbot.version.changelogCR: Change log package is missing!")
return inv.tags.stop(invTagsVersion, "missing end tag", DRL_RET_INTERNAL_ERROR)
end -- if
local fileData, retval = dbot.remote.get(dbot.version.changeLogPkg.url, dbot.version.changeLogPkg.protocol)
if (retval ~= DRL_RET_SUCCESS) then
dbot.warn("dbot.version.changelogCR: Failed to retrieve remote changelog file: " ..
dbot.retval.getString(retval))
elseif (fileData == nil) then
dbot.info("No changelog information was found.")
else
loadstring(fileData)()
if (dbot.changelog == nil) then
dbot.warn("dbot.version.changelogCR: Invalid changelog format detected")
retval = DRL_RET_INTERNAL_ERROR
else
retval = dbot.version.displayChanges(dbot.version.changeLogPkg.minVersion, dbot.changelog)
end -- if
end -- if
dbot.version.changeLogPkg = nil
return inv.tags.stop(invTagsVersion, endTag, retval)
end -- dbot.version.changelogCR
function dbot.version.displayChanges(minVersion, changeLog)
local sortedLog = {}
for k, v in pairs(changeLog) do
table.insert(sortedLog, { version = tonumber(k) or 0, changes = v})
end -- for
table.sort(sortedLog, function (v1, v2) return v1.version > v2.version end)
for _, clog in ipairs(sortedLog) do
if (clog.version > minVersion) then
dbot.version.displayChange(clog)
end -- if
end -- for
return DRL_RET_SUCCESS
end -- dbot.version.displayChanges
-- Format of entry is: { version = 2.0004,
-- changes = { { change = drlDbotChangeLogTypeXYZ, desc = "what changed" }
-- }
-- }
function dbot.version.displayChange(changeLogEntries)
local retval = DRL_RET_SUCCESS
if (changeLogEntries == nil) then
dbot.warn("dbot.version.displayChange: Change entries are missing!")
return DRL_RET_INVALID_PARAM
end -- if
dbot.print(string.format("@Cv%1.4f@W", changeLogEntries.version))
for _, logEntry in ipairs(changeLogEntries.changes) do
dbot.print(string.format("@W (%s): %s", logEntry.change, logEntry.desc))
end -- for
return retval
end -- dbot.version.displayChange
--FIXME: rename this version.update???
dbot.update = {}
dbot.update.url = "https://raw.githubusercontent.com/Aardurel/aard-plugins/master/aard_inventory.xml"
dbot.update.protocol = "HTTPS"
dbot.update.pkg = nil
drlDbotUpdateCheck = "check"
drlDbotUpdateInstall = "install"
function dbot.update.version(mode, endTag)
local retval = DRL_RET_SUCCESS
if (mode == nil) or ((mode ~= drlDbotUpdateCheck) and (mode ~= drlDbotUpdateInstall)) then
dbot.warn("dbot.update.version: Missing or invalid mode parameter")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_INVALID_PARAM)
end -- if
if (dbot.update.pkg ~= nil) then
dbot.info("Skipping update request: another update request is in progress")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_BUSY)
end -- if
-- Pull in the async package if it exists
local asyncOk, async = pcall (require, "async")
if (not asyncOk) or (async == nil) then
dbot.warn("dbot.update.version: Failed to find \"async\" package, skipping update request")
return inv.tags.stop(invTagsVersion, endTag, DRL_RET_UNSUPPORTED)
end -- if
dbot.update.pkg = {}
dbot.update.pkg.mode = mode
dbot.update.pkg.endTag = endTag
-- Make a request to grab the latest plugin file. Newer versions of mush have nice async
-- capabilities and we use that if possible. Otherwise, we fall back to an old-style request.
-- Both methods of making the request will call dbot.update.callback upon completion.
if (async.doAsyncRemoveRequest ~= nil) then
async.doAsyncRemoteRequest(dbot.update.url, dbot.update.callback, dbot.update.protocol)
else
wait.make(dbot.updateCR) -- Fall back to a co-routine running the old-style async code
end
return retval
end -- dbot.update
-- Scan the file we just (hopefully) downloaded and check the file's version. If the user
-- requested a version check, we report the current and latest available versions. If the
-- user requested an installation of the latest plugin, do the upgrade if everything looks
-- sane.
function dbot.update.callback(retval, page, status, headers, fullStatus, requestUrl)
local retval = DRL_RET_SUCCESS
if (dbot.update.pkg == nil) or (dbot.update.pkg.mode == nil) then
dbot.error("dbot.update.callback: Missing or invalid update package detected")
return inv.tags.stop(invTagsVersion, "end tag is nil", DRL_RET_INVALID_PARAM)
end -- if
local endTag = dbot.update.pkg.endTag
if (status ~= 200) then
dbot.warn("dbot.update.callback: Failed to retrieve remote plugin information")
retval = DRL_RET_INTERNAL_ERROR
else
local currentVersion = GetPluginInfo(GetPluginID(), 19) or 0
local currentVerStr = string.format("%1.4f", currentVersion)
local remoteVerStr = string.match(page, '%s%s+version="([0-9%.]+)"')
local remoteVersion = tonumber(remoteVerStr or "") or 0
if (remoteVersion == currentVersion) then
dbot.info("You are running the most recent plugin (v" .. currentVerStr .. ")")
elseif (remoteVersion < currentVersion) then
dbot.warn("Your current plugin (v" .. currentVerStr .. ") " ..
"is newer than the latest official release (v" .. remoteVerStr .. ")")
retval = DRL_RET_VER_MISMATCH
elseif (dbot.update.pkg.mode == drlDbotUpdateCheck) then
dbot.info("You are running v" .. currentVerStr .. ", latest version is v" .. remoteVerStr)
dbot.info("Changes since your last update:")
dbot.update.pkg = nil
return dbot.version.changelog(currentVersion, endTag)
elseif (dbot.update.pkg.mode == drlDbotUpdateInstall) then
dbot.info("Updating plugin from version " .. currentVerStr .. " to version " .. remoteVerStr)
dbot.info("Please do not enter anything until the update completes")
local pluginFile = GetPluginInfo(GetPluginID(), 6)
local file = io.open(pluginFile, "w")
file:write(page)
file:close()
dbot.reload()
else
dbot.error("dbot.update.callback: Detected invalid mode \"@R" .. (dbot.update.pkg.mode or "nil") ..
"@W\"")
end -- if
end -- if
dbot.update.pkg = nil
return inv.tags.stop(invTagsVersion, endTag, retval)
end -- dbot.update.callback
function dbot.updateCR()
local urlThread = async.request(dbot.update.url, dbot.update.protocol)
local updateRet, page, status, headers, fullStatus = -1, nil, -1, nil, nil, dbot.update.url
if (urlThread == nil) then
dbot.warn("dbot.updateCR: Failed to create thread requesting update")
else
local timeout = 10
local totTime = 0
while (urlThread:alive()) do
if (totTime > timeout) then
retval = DRL_RET_TIMEOUT
break
end -- if
wait.time(drlSpinnerPeriodDefault)
totTime = totTime + drlSpinnerPeriodDefault
end -- while
--FIXME: this is broken!!! retval is never defined!!!
if (retval ~= DRL_RET_SUCCESS) then
updateRet, page, status, headers, fullStatus = urlThread:join()
end -- if
end -- if
dbot.update.callback(updateRet, page, status, headers, fullStatus)
end -- dbot.updateCR
]]>
</script>

Loading…
Cancel
Save