ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
Current File : //usr/share/YaST2/modules/OnlineUpdateCallbacks.ycp

/**
 * 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