ACC SHELL
/**
* Module: OnlineUpdateCallbacks.ycp
*
* Authors: Cornelius Schumacher <cschum@suse.de>
*
* Purpose: provides the Callbacks for the online update
*/
{
module "OnlineUpdateCallbacks";
textdomain "online-update";
import "OnlineUpdateDialogs";
import "PackageCallbacks";
import "Popup";
import "Report";
integer total_progress = 0;
// if user aborted the installation
boolean aborted = false;
// last callback called
string last_callback = "";
// indentation of subtasks progress reports
string indent = " ";
/**
* Callback for patch (resp. delta rpm) progress widget.
* @param num position of progress widget (0 to 100)
*/
global define boolean PatchProgressCallback (integer num) {
// do not save this one - we need to store Start/Done pairs
// last_callback = "PatchProgressCallback";
y2debug("PatchProgressCallback %1", num);
if ( UI::WidgetExists( `id( `you_patch_progress ) ) ) {
UI::ChangeWidget( `id( `you_patch_progress ), `Value, num );
}
if (aborted) return false;
symbol ret =(symbol) UI::PollInput();
if ((ret == `abort || ret == `cancel) &&
OnlineUpdateDialogs::ConfirmAbortUpdate (`incomplete)) {
aborted = true;
return false;
}
return true;
}
global boolean ProgressDownloadCallback (integer percent, integer bps_avg, integer bps_current)
{
y2debug ("ProgressDownloadCallback %1%%", percent);
return PatchProgressCallback (percent);
}
global void MessageCallback( string patchname, string patchsummary, string message )
{
last_callback = "MessageCallback";
// handle all messages as post (OK only)
list<map> patches = [
$[
"name" : patchname,
"summary" : patchsummary,
"postinformation": message,
]
];
OnlineUpdateDialogs::MessagePopup( patches, false );
}
/**
* add a text to the installation progress log
*/
global define void ProgressLog (string text) {
y2debug ("ProgressLog %1", text);
if ( UI::WidgetExists( `id( `log ) ) ) {
UI::ChangeWidget( `id( `log ), `LastLine, text );
}
}
/**
Callback for starting download of a package.
*/
global void StartProvide(string name, integer archivesize,boolean remote)
{
// progress log item (%1 is name of package)
ProgressLog (sformat (_("Retrieving %1..."), name));
if (UI::WidgetExists (`id (`you_patch_progress)))
{
UI::ChangeWidget (`id (`you_patch_progress), `Label,
// progress bar label
_("Package Download Progress"));
UI::ChangeWidget (`id (`you_patch_progress), `Value, 0);
}
last_callback = "StartProvide";
}
global void StartDownload (string url, string localfile)
{
/*
// reformat the URL
string url_report = URL::FormatURL(URL::Parse(url), max_size);
FIXME new text to ProgressLog?
// progress log item (%1 is name of file)
string message = sformat (_("Downloading: %1"), url_report);
ProgressLog (message);
// + progress to 0?
*/
last_callback = "StartDownload";
}
/**
Callback for starting installation of a package.
*/
global void StartPackage(string name, string summary, integer
installsize, boolean is_delete)
{
// progress log action (what is being done with the package)
string action = is_delete ? _("Removing") : _("Installing");
// progress log item: %1 is action ("Removing" ot "Installing"),
// %2 is name of package, %3 is summary
string text = sformat ("%1 %2: \"%3\"", action, name, summary);
if (summary == "")
// alternative progress log item: only action and package name
text = sformat ("%1 %2", action, name);
ProgressLog (text);
if (UI::WidgetExists (`id (`you_patch_progress)))
{
UI::ChangeWidget (`id (`you_patch_progress), `Label,
// progress bar label
_("Package Installation Progress"));
UI::ChangeWidget (`id (`you_patch_progress), `Value, 0);
}
last_callback = "StartPackage";
}
/**
* Callback for finishing an action in the log
* @param line true if we are adding to the end of line
*/
global boolean FinishLine (boolean line)
{
// progress log item (=previous action finished correctly)
ProgressLog ((line ? indent : "") + _("OK") + "\n" );
return true;
}
/**
* callback for 'package installed' action
*
* return "" for ignore
* return "R" for retry
* return "C" for abort (not implemented !)
*/
global string DonePackage (integer error, string reason) {
string ret = PackageCallbacks::DonePackage (error, reason);
if (ret == "I")
{
FinishLine (true);
total_progress = total_progress + 1;
if ( UI::WidgetExists( `id( `you_total_progress ) ) ) {
UI::ChangeWidget( `id( `you_total_progress ), `Value, total_progress);
}
}
last_callback = "DonePackage";
return ret;
}
/**
* callback for 'package provided' action
*
* return "" for ignore
* return "R" for retry
* return "C" for abort (not implemented !)
*/
global string DoneProvide (integer error, string reason, string name) {
string ret = PackageCallbacks::DoneProvide (error, reason, name);
if (ret == "I")
{
if (last_callback != "FinishPatchDeltaProvide")
FinishLine (false);
total_progress = total_progress + 1;
if ( UI::WidgetExists( `id( `you_total_progress ) ) ) {
UI::ChangeWidget( `id( `you_total_progress ), `Value, total_progress);
}
}
last_callback = "DoneProvide";
return ret;
}
global void DoneDownload (integer error_value, string error_text) {
y2debug ("DoneDownload %1, %2", error_value, error_text);
PackageCallbacks::DoneDownload (error_value, error_text);
/*
if (last_callback != "FinishPatchDeltaProvide")
FinishLine (false);
last_callback = "DoneDownload";
*/
}
/**
* callback for start of delta download
*/
global void StartDeltaDownload (string name, integer download_size) {
// progress log item (%1 is name of delta RPM
if (last_callback == "StartProvide" || last_callback == "StartDownload")
ProgressLog ("\n" + indent);
// Progress log. Leave the space at the end, some other text may follow
ProgressLog (sformat(_("Downloading delta RPM %1 "), name));
if (UI::WidgetExists (`id (`you_patch_progress)))
{
UI::ChangeWidget (`id (`you_patch_progress), `Label,
// progress bar label
_("Delta RPM Download Progress"));
UI::ChangeWidget (`id (`you_patch_progress), `Value, 0);
}
last_callback = "StartDeltaDownload";
}
/**
* callback for delta download progress
* @return boolean abort the download?
*/
global boolean ProgressDeltaDownload (integer num) {
y2debug ("ProgressDeltaDownload %1", num);
boolean ret = PatchProgressCallback (num);
last_callback = "ProgressDeltaDownload";
return ret;
}
/**
* callback for problem during downloading delta
*/
global void ProblemDeltaDownload (string description) {
y2debug ("ProblemDeltaDownload: %1", description);
ProgressLog (
"\n" + indent +
// progress log item (previous action failed(%1 is reason)
sformat(_("Failed to download delta RPM: %1"), description) +
"\n"
);
last_callback = "ProblemDeltaDownload";
}
/*
* callback for start of applying delta rpm
*/
global void StartDeltaApply (string name) {
// Progress log item (%1 is name of delta RPM).
// Leave the space at the end, some other text may follow.
ProgressLog (indent + sformat(_("Applying delta RPM: %1 "), name));
if (UI::WidgetExists (`id (`you_patch_progress)))
{
UI::ChangeWidget (`id (`you_patch_progress), `Label,
// progress bar label
_("Delta RPM Application Progress"));
UI::ChangeWidget (`id (`you_patch_progress), `Value, 0);
}
last_callback = "StartDeltaApply";
}
/**
* progress of applying delta
* (cannot be aborted)
*/
global void ProgressDeltaApply (integer num) {
y2debug ("ProgressDeltaApply: %1", num);
if (UI::WidgetExists (`id (`you_patch_progress))) {
UI::ChangeWidget (`id (`you_patch_progress), `Value, num);
}
last_callback = "ProgressDeltaApply";
}
/**
* callback for problem during aplying delta
*/
global void ProblemDeltaApply (string description) {
y2debug ("ProblemDeltaAply: %1", description);
ProgressLog (
"\n" + indent +
// progress log item (previous action failed(%1 is reason)
sformat(_("Failed to apply delta RPM: %1"), description) +
"\n"
);
last_callback = "ProblemDeltaApply";
}
/**
* callback for start of downloading patch
*/
global void StartPatchDownload (string name, integer download_size) {
// progress log item (%1 is name of delta RPM)
if (last_callback == "StartProvide")
ProgressLog ("\n" + indent);
// Progress log; lave the space at the end, some other text may follow.
ProgressLog (sformat(_("Downloading patch RPM %1 "), name));
if (UI::WidgetExists (`id (`you_patch_progress)))
{
UI::ChangeWidget (`id (`you_patch_progress), `Label,
// progress bar label
_("Patch RPM Download Progress"));
UI::ChangeWidget (`id (`you_patch_progress), `Value, 0);
}
last_callback = "StartPatchDownload";
}
/**
* callback for path download progress
* @return boolean abort the download?
*/
global boolean ProgressPatchDownload (integer num) {
y2debug ("ProgressPatchDownload %1", num);
boolean ret = PatchProgressCallback (num);
last_callback = "ProgressPatchDownload";
return ret;
}
/**
* callback for problem during aplying delta
*/
global void ProblemPatchDownload (string description) {
y2debug ("ProblemPatchDownload: %1", description);
ProgressLog (
"\n" + indent +
// progress log item (previous action failed(%1 is reason)
sformat(_("Failed to download patch RPM: %1"), description) +
"\n"
);
last_callback = "ProblemPatchDownload";
}
// finish of download/application of delta or patch download
global void FinishPatchDeltaProvide () {
if (last_callback != "DoneDownload")
FinishLine (false);
last_callback = "FinishPatchDeltaProvide";
}
// Script callbacks
// a script has been started
global void ScriptStart(string patch_name, string patch_version, string patch_arch, string script_path)
{
y2milestone("ScriptStart: patch_name:%1, patch_version:%2, patch_arch:%3, script:%4", patch_name, patch_version, patch_arch, script_path);
string patch_full_name = PackageCallbacks::FormatPatchName(patch_name, patch_version, patch_arch);
if (UI::WidgetExists(`id(`you_patch_progress)))
{
UI::ChangeWidget(`id(`you_patch_progress), `Label,
// progress bar label
_("Script Execution Progress"));
UI::ChangeWidget(`id(`you_patch_progress), `Value, 0);
}
// log entry, %1 is name of the patch which contains the script
string log_line = sformat(_("Starting script %1"), patch_full_name);
ProgressLog("\n" + log_line);
last_callback = "ScriptStart";
}
// print output of the script
global boolean ScriptProgress(boolean ping, string output)
{
y2milestone("ScriptProgress: ping:%1, output: %2", ping, output);
if (output != nil && output != "")
{
// add the output to the log widget
ProgressLog(output);
}
last_callback = "ScriptProgress";
any input = UI::PollInput();
if (input == `abort || input == `close)
{
y2milestone("Aborting the script (input: %1)", input);
return false;
}
else
{
return true;
}
}
// an error has occurred
global string ScriptProblem(string description)
{
y2milestone("ScriptProblem: %1", description);
// FIXME: use rather LongError here?
Popup::Error(description);
last_callback = "ScriptProblem";
return "A"; // = Abort, TODO: support also Ignore and Retry
}
// the script has finished
global void ScriptFinish()
{
y2milestone("ScriptFinish");
if (UI::WidgetExists(`id(`you_patch_progress)))
{
UI::ChangeWidget(`id(`you_patch_progress), `Value, 100);
}
FinishLine(true);
total_progress = total_progress + 1;
if (UI::WidgetExists(`id( `you_total_progress )))
{
UI::ChangeWidget(`id(`you_total_progress), `Value, total_progress);
}
last_callback = "ScriptFinish";
}
// display a message
global boolean Message(string patch_name, string patch_version, string patch_arch, string message)
{
string patch_full_name = PackageCallbacks::FormatPatchName(patch_name, patch_version, patch_arch);
y2milestone("Message (%1): %2", patch_full_name, message);
if (patch_full_name != "")
{
// label, %1 is patch name with version and architecture
patch_full_name = sformat(_("Patch %1\n\n"), patch_full_name);
}
// use richtext, the message might be too long for standard popup
Popup::LongMessage(patch_full_name + message);
last_callback = "Message";
return true; // = continue, TODO: use Continue/Cancel dialog
}
/**
Constructor
*/
global define void RegisterOnlineUpdateCallbacks()
``{
y2milestone ( "OnlineUpdateCallbacks constructor" );
Pkg::CallbackStartProvide( OnlineUpdateCallbacks::StartProvide );
Pkg::CallbackProgressProvide( OnlineUpdateCallbacks::PatchProgressCallback );
Pkg::CallbackDoneProvide( OnlineUpdateCallbacks::DoneProvide );
Pkg::CallbackStartPackage( OnlineUpdateCallbacks::StartPackage );
Pkg::CallbackProgressPackage (OnlineUpdateCallbacks::PatchProgressCallback);
Pkg::CallbackDonePackage( OnlineUpdateCallbacks::DonePackage );
Pkg::CallbackResolvableReport(OnlineUpdateCallbacks::MessageCallback);
Pkg::CallbackStartDownload( OnlineUpdateCallbacks::StartDownload );
Pkg::CallbackProgressDownload( OnlineUpdateCallbacks::ProgressDownloadCallback );
Pkg::CallbackDoneDownload (OnlineUpdateCallbacks::DoneDownload);
Pkg::CallbackMediaChange (PackageCallbacks::MediaChange);
// delta download
Pkg::CallbackStartDeltaDownload (OnlineUpdateCallbacks::StartDeltaDownload);
Pkg::CallbackProgressDeltaDownload (OnlineUpdateCallbacks::ProgressDeltaDownload);
Pkg::CallbackProblemDeltaDownload (OnlineUpdateCallbacks::ProblemDeltaDownload);
Pkg::CallbackFinishDeltaDownload (OnlineUpdateCallbacks::FinishPatchDeltaProvide);
// delta application
Pkg::CallbackStartDeltaApply (OnlineUpdateCallbacks::StartDeltaApply);
Pkg::CallbackProgressDeltaApply (OnlineUpdateCallbacks::ProgressDeltaApply);
Pkg::CallbackProblemDeltaApply (OnlineUpdateCallbacks::ProblemDeltaApply);
Pkg::CallbackFinishDeltaApply (OnlineUpdateCallbacks::FinishPatchDeltaProvide);
// patch download
Pkg::CallbackStartPatchDownload (OnlineUpdateCallbacks::StartPatchDownload);
Pkg::CallbackProgressPatchDownload (OnlineUpdateCallbacks::ProgressPatchDownload);
Pkg::CallbackProblemPatchDownload (OnlineUpdateCallbacks::ProblemPatchDownload);
Pkg::CallbackFinishPatchDownload (OnlineUpdateCallbacks::FinishPatchDeltaProvide);
// script callbacks
Pkg::CallbackScriptStart(OnlineUpdateCallbacks::ScriptStart);
Pkg::CallbackScriptProgress(OnlineUpdateCallbacks::ScriptProgress);
Pkg::CallbackScriptProblem(OnlineUpdateCallbacks::ScriptProblem);
Pkg::CallbackScriptFinish(OnlineUpdateCallbacks::ScriptFinish);
Pkg::CallbackMessage(OnlineUpdateCallbacks::Message);
}
/*
* Refresh all sources with autorefresh enabled.
* This function is a temporary solution for bug #154990
*/
global define void RefreshAllSources () {
y2milestone("Refreshing all sources...");
boolean mgr_ok = Pkg::SourceStartManager(true);
if (!mgr_ok)
{
// error popoup (detailed info follows)
Report::LongWarning(_("There was an error in the repository initialization.") + "\n" + Pkg::LastError ());
}
list <map<string,any> > all_sources = Pkg::SourceEditGet();
// There are no sources, nothing to refresh
if (all_sources == nil || size(all_sources)<1) {
y2warning("No sources defined, nothing to refresh...");
return;
}
foreach (map<string,any> one_source, all_sources, {
integer source_id = (integer) one_source["SrcId"]:nil;
boolean source_autorefresh = (boolean) one_source["autorefresh"]:true;
boolean source_enabled = (boolean) one_source["enabled"]:true;
if (source_id != nil && source_autorefresh == true && source_enabled == true) {
y2milestone("Refreshing source: %1", source_id);
Pkg::SourceRefreshNow(source_id);
}
});
y2milestone ("... refreshing done");
}
/**
* Refresh sources given by argument
*/
global define void RefreshSources (list<map> sources) {
y2milestone("Refreshing sources...");
foreach (map one_source, sources, {
integer source_id = (integer) one_source["SrcId"]:nil;
boolean source_autorefresh = (boolean) one_source["autorefresh"]:true;
boolean source_enabled = (boolean) one_source["enabled"]:true;
if (source_id != nil && source_autorefresh == true && source_enabled == true) {
y2milestone("Refreshing source: %1", source_id);
Pkg::SourceRefreshNow(source_id);
}
});
y2milestone ("... refreshing done");
}
}
ACC SHELL 2018