static void pk_backend_transaction_progress_cb (alpm_progress_t type, const gchar *target, gint percent, gsize targets, gsize current) { static gint recent = 101; gsize overall = percent + (current - 1) * 100; /* TODO: remove block if/when this is made consistent upstream */ if (type == ALPM_PROGRESS_CONFLICTS_START || type == ALPM_PROGRESS_DISKSPACE_START || type == ALPM_PROGRESS_INTEGRITY_START || type == ALPM_PROGRESS_LOAD_START || type == ALPM_PROGRESS_KEYRING_START) { if (current < targets) { ++current; overall += 100; } } if (current < 1 || targets < current) { g_warning ("TODO: CURRENT/TARGETS FAILED for %d", type); } g_return_if_fail (target != NULL); g_return_if_fail (0 <= percent && percent <= 100); g_return_if_fail (1 <= current && current <= targets); g_return_if_fail (backend != NULL); /* update transaction progress */ switch (type) { case ALPM_PROGRESS_ADD_START: case ALPM_PROGRESS_UPGRADE_START: case ALPM_PROGRESS_DOWNGRADE_START: case ALPM_PROGRESS_REINSTALL_START: case ALPM_PROGRESS_REMOVE_START: case ALPM_PROGRESS_CONFLICTS_START: case ALPM_PROGRESS_DISKSPACE_START: case ALPM_PROGRESS_INTEGRITY_START: case ALPM_PROGRESS_LOAD_START: case ALPM_PROGRESS_KEYRING_START: if (percent == recent) { break; } pk_backend_set_sub_percentage (backend, percent); pk_backend_job_set_percentage (job, overall / targets); recent = percent; g_debug ("%d%% of %s complete (%zu of %zu)", percent, target, current, targets); break; default: g_warning ("unknown progress type %d", type); break; } }
static void pk_backend_transaction_dlcb (const gchar *basename, off_t complete, off_t total) { guint percentage = 100, sub_percentage = 100; g_return_if_fail (basename != NULL); g_return_if_fail (complete <= total); g_return_if_fail (backend != NULL); if (total > 0) { sub_percentage = complete * 100 / total; } if (dtotal > 0) { percentage = (dcomplete + complete) * 100 / dtotal; } else if (dtotal < 0) { /* database files */ percentage = (dcomplete * 100 + sub_percentage) / -dtotal; if (complete == total) { complete = total = 1; } else { complete = total + 1; } } if (complete == 0) { g_debug ("downloading file %s", basename); pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD); pk_backend_transaction_download_start (backend, basename); } else if (complete == total) { dcomplete += complete; } pk_backend_set_sub_percentage (backend, sub_percentage); pk_backend_job_set_percentage (job, percentage); }
/* This draws the current progress. Each line has an overall percent meter and a per active item status meter along with an overall bandwidth and ETA indicator. */ bool AcqPackageKitStatus::Pulse(pkgAcquire *Owner) { pkgAcquireStatus::Pulse(Owner); unsigned long percent_done; percent_done = long(double((CurrentBytes + CurrentItems)*100.0)/double(TotalBytes+TotalItems)); // Emit the percent done if (last_percent != percent_done) { if (last_percent < percent_done) { pk_backend_set_percentage(m_backend, percent_done); } else { pk_backend_set_percentage(m_backend, PK_BACKEND_PERCENTAGE_INVALID); pk_backend_set_percentage(m_backend, percent_done); } last_percent = percent_done; } set<string> localCurrentPackages = currentPackages;; for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0; I = Owner->WorkerStep(I)) { // Check if there is no item running or if we don't have // any packages set we are probably refreshing the cache if (I->CurrentItem == 0 || packages.size() == 0) { continue; } emit_package(I->CurrentItem->ShortDesc, false); localCurrentPackages.erase(I->CurrentItem->ShortDesc); // Add the total size and percent if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false) { unsigned long sub_percent; // TODO PackageKit needs to emit package with progress. sub_percent = long(double(I->CurrentSize*100.0)/double(I->TotalSize)); if (last_sub_percent != sub_percent) { if (last_sub_percent < sub_percent) { pk_backend_set_sub_percentage(m_backend, sub_percent); } else { pk_backend_set_sub_percentage(m_backend, PK_BACKEND_PERCENTAGE_INVALID); pk_backend_set_sub_percentage(m_backend, sub_percent); } last_sub_percent = sub_percent; } } } // the items that still on the set are finished for (set<string>::iterator it = localCurrentPackages.begin(); it != localCurrentPackages.end(); it++ ) { emit_package(*it, true); } double localCPS = (CurrentCPS >= 0) ? CurrentCPS : -1 * CurrentCPS; if (localCPS != last_CPS) { last_CPS = localCPS; pk_backend_set_speed(m_backend, (int) last_CPS); } Update = false; return !_cancelled;; }
/** * pk_backend_spawn_parse_stdout: **/ static gboolean pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line, GError **error) { gchar **sections; guint size; gchar *command; gchar *text; gboolean ret = TRUE; guint64 speed; PkInfoEnum info; PkRestartEnum restart; PkGroupEnum group; gulong package_size; gint percentage; PkErrorEnum error_enum; PkStatusEnum status_enum; PkMessageEnum message_enum; PkRestartEnum restart_enum; PkSigTypeEnum sig_type; PkUpdateStateEnum update_state_enum; PkMediaTypeEnum media_type_enum; PkDistroUpgradeEnum distro_upgrade_enum; PkBackendSpawnPrivate *priv = backend_spawn->priv; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* check if output line */ if (line == NULL) return FALSE; /* split by tab */ sections = g_strsplit (line, "\t", 0); command = sections[0]; /* get size */ size = g_strv_length (sections); if (g_strcmp0 (command, "package") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (pk_package_id_check (sections[2]) == FALSE) { g_set_error_literal (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } info = pk_info_enum_from_string (sections[1]); if (info == PK_INFO_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } pk_backend_package (priv->backend, info, sections[2], sections[3]); } else if (g_strcmp0 (command, "details") == 0) { if (size != 7) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } group = pk_group_enum_from_string (sections[3]); /* ITS4: ignore, checked for overflow */ package_size = atol (sections[6]); if (package_size > 1073741824) { g_set_error_literal (error, 1, 0, "package size cannot be larger than one Gb"); ret = FALSE; goto out; } text = g_strdup (sections[4]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_details (priv->backend, sections[1], sections[2], group, text, sections[5], package_size); g_free (text); } else if (g_strcmp0 (command, "finished") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_finished (priv->backend); /* from this point on, we can start the kill timer */ pk_backend_spawn_start_kill_timer (backend_spawn); } else if (g_strcmp0 (command, "files") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_files (priv->backend, sections[1], sections[2]); } else if (g_strcmp0 (command, "repo-detail") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (g_strcmp0 (sections[3], "true") == 0) { pk_backend_repo_detail (priv->backend, sections[1], sections[2], TRUE); } else if (g_strcmp0 (sections[3], "false") == 0) { pk_backend_repo_detail (priv->backend, sections[1], sections[2], FALSE); } else { g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]); ret = FALSE; goto out; } } else if (g_strcmp0 (command, "updatedetail") == 0) { if (size != 13) { g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size); ret = FALSE; goto out; } restart = pk_restart_enum_from_string (sections[7]); if (restart == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]); ret = FALSE; goto out; } update_state_enum = pk_update_state_enum_from_string (sections[10]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (sections[8], ";", '\n'); g_strdelimit (sections[9], ";", '\n'); pk_backend_update_detail (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5], sections[6], restart, sections[8], sections[9], update_state_enum, sections[11], sections[12]); } else if (g_strcmp0 (command, "percentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtoint (sections[1], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid percentage value %i", percentage); ret = FALSE; } else { pk_backend_set_percentage (priv->backend, percentage); } } else if (g_strcmp0 (command, "subpercentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtoint (sections[1], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid subpercentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid subpercentage value %i", percentage); ret = FALSE; } else { pk_backend_set_sub_percentage (priv->backend, percentage); } } else if (g_strcmp0 (command, "item-percentage") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (!pk_package_id_check (sections[1])) { g_set_error (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } ret = pk_strtoint (sections[2], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid item-percentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid item-percentage value %i", percentage); ret = FALSE; } else { pk_backend_set_item_progress (priv->backend, sections[1], percentage); } } else if (g_strcmp0 (command, "error") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } error_enum = pk_error_enum_from_string (sections[1]); if (error_enum == PK_ERROR_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } /* convert back all the ;'s to newlines */ text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); /* convert % else we try to format them */ g_strdelimit (text, "%", '$'); pk_backend_error_code (priv->backend, error_enum, text); g_free (text); } else if (g_strcmp0 (command, "requirerestart") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } restart_enum = pk_restart_enum_from_string (sections[1]); if (restart_enum == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (!pk_package_id_check (sections[2])) { g_set_error (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } pk_backend_require_restart (priv->backend, restart_enum, sections[2]); } else if (g_strcmp0 (command, "message") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } message_enum = pk_message_enum_from_string (sections[1]); if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Message enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_message (priv->backend, message_enum, text); g_free (text); } else if (g_strcmp0 (command, "change-transaction-data") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_set_transaction_data (priv->backend, sections[1]); } else if (g_strcmp0 (command, "status") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } status_enum = pk_status_enum_from_string (sections[1]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } pk_backend_set_status (priv->backend, status_enum); } else if (g_strcmp0 (command, "speed") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtouint64 (sections[1], &speed); if (!ret) { g_set_error (error, 1, 0, "failed to parse speed: '%s'", sections[1]); ret = FALSE; goto out; } pk_backend_set_speed (priv->backend, speed); } else if (g_strcmp0 (command, "allow-cancel") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (g_strcmp0 (sections[1], "true") == 0) { pk_backend_set_allow_cancel (priv->backend, TRUE); } else if (g_strcmp0 (sections[1], "false") == 0) { pk_backend_set_allow_cancel (priv->backend, FALSE); } else { g_set_error (error, 1, 0, "invalid section '%s'", sections[1]); ret = FALSE; goto out; } } else if (g_strcmp0 (command, "no-percentage-updates") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_set_percentage (priv->backend, PK_BACKEND_PERCENTAGE_INVALID); } else if (g_strcmp0 (command, "repo-signature-required") == 0) { if (size != 9) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } sig_type = pk_sig_type_enum_from_string (sections[8]); if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Sig enum not recognised, and hence ignored: '%s'", sections[8]); ret = FALSE; goto out; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "repository name blank, and hence ignored: '%s'", sections[2]); ret = FALSE; goto out; } /* pass _all_ of the data */ ret = pk_backend_repo_signature_required (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5], sections[6], sections[7], sig_type); goto out; } else if (g_strcmp0 (command, "eula-required") == 0) { if (size != 5) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "eula_id blank, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[2]); ret = FALSE; goto out; } if (pk_strzero (sections[4])) { g_set_error (error, 1, 0, "agreement name blank, and hence ignored: '%s'", sections[4]); ret = FALSE; goto out; } ret = pk_backend_eula_required (priv->backend, sections[1], sections[2], sections[3], sections[4]); goto out; } else if (g_strcmp0 (command, "media-change-required") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } media_type_enum = pk_media_type_enum_from_string (sections[1]); if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "media type enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } ret = pk_backend_media_change_required (priv->backend, media_type_enum, sections[2], sections[3]); goto out; } else if (g_strcmp0 (command, "distro-upgrade") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]); if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } ret = pk_backend_distro_upgrade (priv->backend, distro_upgrade_enum, sections[2], sections[3]); goto out; } else if (g_strcmp0 (command, "category") == 0) { if (size != 6) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (g_strcmp0 (sections[1], sections[2]) == 0) { g_set_error_literal (error, 1, 0, "cat_id cannot be the same as parent_id"); ret = FALSE; goto out; } if (pk_strzero (sections[2])) { g_set_error_literal (error, 1, 0, "cat_id cannot not blank"); ret = FALSE; goto out; } if (pk_strzero (sections[3])) { g_set_error_literal (error, 1, 0, "name cannot not blank"); ret = FALSE; goto out; } if (pk_strzero (sections[5])) { g_set_error_literal (error, 1, 0, "icon cannot not blank"); ret = FALSE; goto out; } if (g_str_has_prefix (sections[5], "/")) { g_set_error (error, 1, 0, "icon '%s' should be a named icon, not a path", sections[5]); ret = FALSE; goto out; } ret = pk_backend_category (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]); goto out; } else { ret = FALSE; g_set_error (error, 1, 0, "invalid command '%s'", command); } out: g_strfreev (sections); return ret; }