Blob Blame History Raw
-- Repository/mirror selector for apt
-- Usable both as a first-time "druid" or as a "mirror-select" command
-- (c) pmatilai@welho.com / 2003
-- Licensed under the GPLv2

if script_slot == "Scripts::AptGet::Help::Command" then
	print(_("   mirror-select - Select repositories and mirrors for use with apt"))
elseif script_slot == "Scripts::Init" and not confexists("Apt::State::FirstRun") then
	confset("Apt::State::ReallyFirstRun", "true")
elseif script_slot == "Scripts::AptGet::Command" then
	if command_args[1] == "mirror-select" then
		command_consume = 1
	else
		return
	end
	-- on the very first run the mirror-selector has already been executed
	if confexists("Apt::State::ReallyFirstRun") then
		return
	else
		confset("Apt::State::FirstRun", "true")
	end
end

if confget("Apt::State::FirstRun/b", "true") == "false" then
	return
end
-- don't run if set to non-interactive or not running on a tty
if tonumber(confget("quiet", "0")) > 0 then
	return
end
-- check that we're not running synaptic
-- synaptic >= 0.47
if confget("Program") == "synaptic" then
	return
	-- synaptic < 0.47
else
	cmdline = io.open("/proc/self/cmdline")
	if cmdline then
		res = cmdline:read()
		if string.find(res, "synaptic") then
			return 
		end
	end
end

function fetch_mirrors()
	lmirror = confget("Dir::State::mirrors/f")
	rmirrors = confgetlist("Apt::State::mirrors-URL")
	urls = ""
	for i, mirror in ipairs(rmirrors) do
		urls = urls.." "..mirror
	end
			
	print(_("Fetching list of repositories/mirrors..."))
	res = os.execute("wget -q -O "..lmirror..".new "..urls)
	if res == 0 then
		os.rename(lmirror, lmirror..".old")
		os.rename(lmirror..".new", lmirror)
		return true
	else
		return false
	end
end
	

function parse_mirrors()
	local file = io.open(confget("Dir::State::mirrors/f"))
	local line = file:read()
	local list = {}
	while line do
		local entry = {}
		entry.selected = false
		entry.name = line
		entry.mirrors = {}
		line = file:read()
		while line do
			mirror = {}
			mirror.name = line
			mirror.server = file:read()
			line = file:read()
			if line == "--" or line == "----" then
				mirror.selected = false
				table.insert(entry.mirrors, mirror)
				if line == "----" then
					line = file:read()
					break
				end
			else
				apterror(_("Corrupted mirror list"))
				return
			end
			line = file:read()
		end
		table.insert(list, entry)
	end
	file:close()
	return list
end

function disable_druid()
	confset("Apt::State::FirstRun", "true")
	if not confexists("Apt::State::ReallyFirstRun") then
		return
	end
	aptconf = io.open(confget("Dir::Etc::main/f"), "a+")
	aptconf:write(_('// Automatically written by your friendly first-time druid...\n'))
	aptconf:write('Apt::State::FirstRun "false";\n')
	aptconf:close()
end

function write_sourcelist(list)
	-- move sources.list out of the way when migrating to mirror-select config
	if confexists("Apt::State::ReallyFirstRun") then
		slmain = confget("Dir::Etc::sourcelist/f")
		os.rename(slmain, slmain..".backup")
		print(_("NOTE: "..slmain.." moved to "..slmain..".backup !!"))
		sl = io.open(slmain, "w+")
		sl:write(_('# Add any local repositories here.\n\n'))
		sl:write(_('# Be sure to read /etc/apt/sources.list.d/mirror-select.list which has\n'))
		sl:write(_('# been automatically configured by the Fedora apt mirror selector\n'))
		sl:write('# Run "apt-get mirror-select" to reselect mirrors for that file.\n')
		sl:close()
	end	

	srclist = io.open(sourcelist, "w+")
	srclist:write(_('# DO NOT EDIT ME!  Use "apt-get mirror-select" instead.\n'))
	for i, entry in ipairs(list) do
		if entry.selected == true then
			for i, mirror in ipairs(entry.mirrors) do
				if mirror.selected then
					srclist:write("# "..entry.name.." ("..mirror.name..")\n")
					srclist:write("rpm "..mirror.server.."\n")
					-- fedora.us doesn't have src indexes for all components :(
					srclist:write("#rpm-src "..mirror.server.."\n")
					srclist:write("\n")
				end
			end
		end
	end
	srclist:close()
end

function print_list(list)
	for i, entry in ipairs(list) do
		if entry.selected then
			chosen = "(x)"
		else
			chosen = ""
		end
		print(i.." "..chosen, entry.name)
	end
end

function cls()
	os.execute("clear")
end

function select_list(list, res)
	res = string.gsub(res..",", "(%p)", ",")
	for w in string.gfind(res, "(.-),", "%1") do
		num = tonumber(w)
		if num == nul then
			print(_("Invalid selection "..res.."\n"))
		elseif num <= 0 or num > table.getn(list) then
			print(_("Ignoring invalid selection "..num.."\n"))
		else
			if list[num].selected then
				list[num].selected = false
			else
				list[num].selected = true
			end
		end
	end
end

function ask_list(list, message)
	ok = false
	while not ok do
		print(message)
		print_list(list)
	
		print(_("\nWhen finished choose 'c' to continue or choose 'q'"))
		print(_("to quit repository selector without changing anything."))
		print(_("Enter your selection(s) in a comma-separated list:"))
		res = io.stdin:read()
		if res == "q" then
			return false
		elseif res == "c" then
			return true
		end
		select_list(list, res)
		cls()
	end
end

sourcelist = confget("Dir::Etc::sourceparts::mirrorsource/f");

if fetch_mirrors() == false then
	apterror(_("Failed to fetch mirror list file:\n"..confget("Apt::State::mirrors-URL")))
	return
end

local repos = parse_mirrors()

if not repos then
	apterror(_("Mirror list not found or corrupted."))
	return 
end

cls()

if confexists("Apt::State::ReallyFirstRun") then
	print(_("\nThis appears to be the first time you are running APT."))
	print(_("Before you can use apt for software installation you need to"))
	print(_("select some software repositories first.\n"))
end

if not ask_list(repos, _("Choose the repositories you want to use from the list below:")) then
	disable_druid()
	return
end

cls()
for i, repo in ipairs(repos) do
	if repo.selected then
		if not ask_list(repo.mirrors, _("Choose the geographically nearest mirror(s)for use with:\n\n  "..repo.name)) then
			disable_druid()
			return
		end
		cls()
	end
end
print(_("Writing source list entries..."))
write_sourcelist(repos)
print(_("Done."))
disable_druid()

-- vim:ts=4