ACC SHELL
Path : /usr/share/YaST2/modules/ |
|
Current File : //usr/share/YaST2/modules/OneClickInstallWorkerFunctions.ycp |
/**
* Holds functions both the CLI and GUI installers require.
*/
{
module "OneClickInstallWorkerFunctions";
textdomain "oneclickinstall";
import "HTTP";
import "FTP";
import "OneClickInstall";
import "OneClickInstallWorkerResponse";
import "Popup";
include "packager/inst_source_dialogs.ycp";
import "PackageCallbacks";
import "SourceManager";
import "Progress";
import "PackageSlideShow";
import "SlideShow";
import "CommandLine";
string SEPARATOR = "/";
boolean GUI = true;
global void setGUI(boolean value)
{
GUI = value;
}
void print(string value)
{
if (!GUI)
CommandLine::Print(value);
}
global boolean FuzzyMatch(string one, string two)
{
string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
return (tolower(filterchars(one,chars)) == tolower(filterchars(two,chars)));
}
list<integer> deduped_repos = [];
/**
** Check whether this repository is already subscribed
**/
global list<string> DeDupe(list<string> url_list)
{
list<integer> sources = Pkg::SourceStartCache(true);
list<string> deduped = [];
foreach (string new, url_list,
{
boolean dupeFound = false;
foreach (integer srcid, sources,
{
map<string,any> repoData = Pkg::SourceGeneralData(srcid);
if (repoData["url"]:"" == new)
{
//keep a note of this repo, we still want to prefer packages from it
//to those in other repositories
deduped_repos = add(deduped_repos,srcid);
dupeFound = true;
break;
}
if (FuzzyMatch(repoData["name"]:"",OneClickInstall::GetRepositoryName(new)))
{
deduped_repos = add(deduped_repos,srcid);
dupeFound = true;
break;
}
if (FuzzyMatch(repoData["alias"]:"",OneClickInstall::GetRepositoryName(new)))
{
deduped_repos = add(deduped_repos,srcid);
dupeFound = true;
break;
}
});
if (!dupeFound)
deduped = add(deduped,new);
});
return deduped;
}
list<integer> sourceids = [];
/**
** Subscribe to all the specified repositories
** return true if all catalogues were added successfully, false otherwise.
**/
global boolean AddRepositories(list<string> repositories)
{
boolean addRepoSuccess = true;
print(_("Loading Package Management"));
list<string> dedupedRepos = DeDupe(repositories);
foreach (string new_url, dedupedRepos,
{
print(sformat(_("Adding repository %1"),new_url));
boolean again = true;
while(again)
{
map<string,any> repoData =
$[
"enabled":true,
"autorefresh":true,
"name":OneClickInstall::GetRepositoryName(new_url),
"alias":OneClickInstall::GetRepositoryName(new_url),
"base_urls":[new_url]
];
integer srcid = Pkg::RepositoryAdd(repoData);
boolean success = Pkg::SourceRefreshNow(srcid);
if (!success)
{
if (Popup::YesNo (_("An error occurred while initializing the software repository.") + "\n" + _("Details:") + "\n" + Pkg::LastError() + "\n" + _("Try again?")))
{
new_url = editUrl (new_url);
}
else
{
OneClickInstallWorkerResponse::AddFailedRepository(new_url);
again = false;
addRepoSuccess = false;
return false;
}
}
else
{
sourceids = add(sourceids,srcid);
// save the repository
Pkg::SourceSaveAll();
again = false;
}
}
//Should be safe, definition ignores call when in command line mode or no progress is visible.
Progress::NextStage();
});
return addRepoSuccess;
}
void InitSlideShow(string description)
{
PackageSlideShow::InitPkgData(true); // force reinitialization
// TODO FIXME: doesn't work properly for removed packages
list< map<string,any> > stages = [
$[
"name" : "packages",
"description": description,
"value" : PackageSlideShow::total_size_to_install / 1024 , // kilobytes
"units" : `kb,
],
];
SlideShow::Setup(stages);
SlideShow::MoveToStage("packages");
}
/**
** Install all the specified packages
** return true if all installations were successful, false otherwise
**/
global boolean InstallPackages(list<string> packages)
{
Pkg::SourceLoad();
foreach (string name, packages,
{
print(sformat(_("Marking package %1 for installation"),name));
//Prefer packages from repositories specified in the YMP
boolean inYmpRepos = false;
foreach (integer id, (list<integer>)merge(sourceids,deduped_repos),
{
y2debug("Looking for %1 in %2",name,id);
inYmpRepos = Pkg::ResolvableInstallRepo(name,`package,id);
if (inYmpRepos)
{
y2debug("Found %1 in %2",name,id);
break;
} else
{
y2debug("Didn't find %1 in %2", name, id);
}
});
if (!inYmpRepos)
y2debug("Didn't find %1 At ALL in any YMP repos",name);
//If we didn't find it in the repos specified in the YMP try any repo.
if (!inYmpRepos && !Pkg::PkgInstall(name))
{
print(sformat(_("Warning: package %1 could not be installed."),name));
if(GUI)
OneClickInstallWorkerResponse::AddFailedPackage(name);
}
});
boolean state = true;
Pkg::TargetInit( "/", false );
if(Pkg::PkgSolve(true))
{
// initialize slideshow data (package counters)
InitSlideShow(_("Installing Packages..."));
print(_("Performing Installation..."));
state = !(Pkg::PkgCommit(0)[0]:-1 < 0);
} else //xxx no callback for resolve failures
{
symbol result = (symbol)WFM::CallFunction( "inst_packages", [`summaryMode]);
if (result == `accept)
{
state = !(Pkg::PkgCommit(0)[0]:-1 < 0);
} else
{
state = false;
}
}
return state;
}
/**
** Install all the specified patterns
** return true if all installations were successful, false otherwise
**/
global boolean InstallPatterns(list<string> patterns)
{
Pkg::TargetInit( "/", false );
foreach (string name, patterns,
{
if (!Pkg::ResolvableInstall(name,`pattern))
{
print(sformat(_("Warning: pattern %1 could not be installed."),name));
if (GUI)
OneClickInstallWorkerResponse::AddFailedPattern(name);
}
});
boolean state = true;
if(Pkg::PkgSolve(true))
{
// initialize slideshow data (package counters)
InitSlideShow(_("Installing Patterns..."));
state = !(Pkg::PkgCommit(0)[0]:-1 < 0);
} else //xxx no callback for resolve failures
{
symbol result = (symbol)WFM::CallFunction( "inst_packages", [`summaryMode]);
if (result == `accept)
{
state = !(Pkg::PkgCommit(0)[0]:-1 < 0);
} else
{
state = false;
}
}
return state;
}
/**
** Remove all the specified packages
** return true if all installations were successful, false otherwise
**/
global boolean RemovePackages(list<string> packages)
{
Pkg::TargetInit( "/", false );
boolean result = true;
foreach (string name, packages,
{
result = Pkg::PkgDelete(name);
});
boolean state = true;
if(Pkg::PkgSolve(true))
{
// initialize slideshow data (package counters)
InitSlideShow(_("Removing Packages..."));
state = !(Pkg::PkgCommit(0)[0]:-1 < 0);
} else //xxx no callback for resolve failures
{
symbol result = (symbol)WFM::CallFunction( "inst_packages", [`summaryMode]);
if (result == `accept)
{
state = !(Pkg::PkgCommit(0)[0]:-1 < 0);
} else
{
state = false;
}
}
return state;
}
global boolean RemoveAddedRepositories()
{
boolean success = true;
foreach(integer srcid, sourceids,
{
success = success && Pkg::SourceDelete(srcid);
}
);
Pkg::SourceSaveAll();
return success;
}
global string GrabFile(string url)
{
string newUrl = (string)SCR::Read (.target.tmpdir) + SEPARATOR + "metapackage.xml";
if (substring(url,0,4) == "http" || substring(url,0,4) == "file")
{
map response = HTTP::Get(url,newUrl);
if (response["code"]:400 >= 400)
return nil;
return newUrl;
} else if (substring(url,0,3) == "ftp")
{
FTP::Get(url,newUrl);
return newUrl;
} else
{
y2error ("Argument is neither local absolute path nor an HTTP or FTP URL. Bye.");
return nil;
}
return nil;
}
}
ACC SHELL 2018