Files
ccphone/startup/01_repo.lua
2026-01-01 22:40:33 -08:00

155 lines
4.8 KiB
Lua

local lib = {}
local appregloc = ".appreg"
local expect = require "cc.expect".expect
local file = fs.open("/repos.dat","r")
local repos = {}
if file then
repos = textutils.unserialise(file.readAll() or "") or repos
end
local function saveRepos()
local file = fs.open("/repos.dat","w")
file.write(textutils.serialise(repos))
file.close()
end
function lib.addRepo(id)
expect(1,id,"number")
repos[id] = "computer"
saveRepos()
end
function lib.getRepos()
return repos
end
function lib.rmRepo(id)
expect(1,id,"number")
repos[id] = nil
saveRepos()
end
function lib.listPackages(type)
local queued_requests = {}
local recorded_packages = {}
for k,v in pairs(repos) do
if v == "computer" then
network.send({proto="query",package_type=type},k)
queued_requests[k] = "computer"
end
end
local next_timestamp = os.clock()+5
repeat
local event = {os.pullEvent()}
if event[1] == "network_packet" then
if queued_requests[event[3]] == "computer" and event[2].proto == "query_resp" and event[2].package_type == type then
for name,data in pairs(event[2].data) do
if recorded_packages[name] then
recorded_packages[name].repos[event[3]] = event[4]
else
data.repos = {[event[3]] = event[4]}
recorded_packages[name] = data
end
end
end
end
until next(queued_requests) == nil or os.clock() >= next_timestamp
return recorded_packages
end
function lib.getPackageData(type,id)
local queued_requests = {}
local package = nil
for k,v in pairs(repos) do
if v == "computer" then
network.send({proto="get_data",package_type=type,id=id},k)
queued_requests[k] = "computer"
end
end
local next_timestamp = os.clock()+5
repeat
local event = {os.pullEvent()}
if event[1] == "network_packet" then
if queued_requests[event[3]] == "computer" and event[2].proto == "data_resp" and event[2].package_type == type then
if package == nil then
package = event[2].data
package.repos = {[event[3]] = event[4]}
end
package.repos[event[3]] = event[4]
end
end
until next(queued_requests) == nil or os.clock() >= next_timestamp
return package
end
local function add_app_to_reg(appid)
local file = fs.open(appregloc,"r")
local data = {}
if file then data = textutils.unserialise(file.readAll() or "") or {} file.close() end
data[appid] = true
local file = fs.open(appregloc,"w")
if file then
file.write(textutils.serialise(data))
file.close()
end
end
local function app_in_reg(appid)
local file = fs.open(appregloc,"r")
local data = {}
if file then data = textutils.unserialise(file.readAll() or "") or {} file.close() end
return data[appid] or false
end
local function remove_app_from_reg(appid)
local file = fs.open(appregloc,"r")
local data = {}
if file then data = textutils.unserialise(file.readAll() or "") or {} file.close() end
data[appid] = nil
local file = fs.open(appregloc,"w")
if file then
file.write(textutils.serialise(data))
file.close()
end
end
local function install_app_from_data(data)
if not data.meta or not data.package or not data.meta.appid then return false, "incorrect package format" end
add_app_to_reg(data.meta.appid)
local app_meta = fs.open(fs.combine("/apps-meta",data.meta.appid..".meta"),"w")
local app = fs.open(fs.combine("/apps",data.meta.appid),"w")
if app_meta and app then
app_meta.write(textutils.serialise(data.meta))
app.write(data.package)
app_meta.close()
app.close()
return true
end
return false, "failed to open file"
end
function lib.uninstallApp(id)
if app_in_reg(id) then
remove_app_from_reg(id)
fs.delete(fs.combine("/apps-meta",id..".meta"))
fs.delete(fs.combine("/appears",id))
return true
end
return false, "Not installed"
end
function lib.installApp(package)
if type(package) == "table" then
return install_app_from_data(package)
elseif type(package) == "string" then
local handle = nil
if http.checkURL(package) then
handle = http.get(package)
else
handle = fs.open(package,"r")
end
if handle then
local data = textutils.unserialise(handle.readAll() or "")
if data then
return install_app_from_data(data)
end
handle.close()
end
end
return false
end
_G.repo = lib