ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
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