[haiku-commits] haiku: hrev50766 - src/apps/softwareupdater

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 14 Dec 2016 22:32:57 +0100 (CET)

hrev50766 adds 1 changeset to branch 'master'
old head: b2251661bc31a3ece6ca3368e91ba2743cd02a75
new head: 015754479e17acbd369f5e201042222fdfd4c0da
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=015754479e17+%5Eb2251661bc31

----------------------------------------------------------------------------

015754479e17: softwareupdater: Start filling in package kit code

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev50766
Commit:      015754479e17acbd369f5e201042222fdfd4c0da
URL:         http://cgit.haiku-os.org/haiku/commit/?id=015754479e17
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Mon Dec 12 20:51:34 2016 UTC

----------------------------------------------------------------------------

5 files changed, 505 insertions(+), 38 deletions(-)
src/apps/softwareupdater/Jamfile                 |   5 +-
.../softwareupdater/SoftwareUpdaterWindow.cpp    | 109 ++++--
src/apps/softwareupdater/SoftwareUpdaterWindow.h |  13 +-
src/apps/softwareupdater/UpdateManager.cpp       | 345 +++++++++++++++++++
src/apps/softwareupdater/UpdateManager.h         |  71 ++++

----------------------------------------------------------------------------

diff --git a/src/apps/softwareupdater/Jamfile b/src/apps/softwareupdater/Jamfile
index bdea8f0..4fd6d40 100644
--- a/src/apps/softwareupdater/Jamfile
+++ b/src/apps/softwareupdater/Jamfile
@@ -1,11 +1,10 @@
 SubDir HAIKU_TOP src apps softwareupdater ;
 
-UsePrivateHeaders interface shared ;
-
 Application SoftwareUpdater :
        SoftwareUpdaterApp.cpp
        SoftwareUpdaterWindow.cpp
        StripeView.cpp
-       : be localestub tracker translation [ TargetLibsupc++ ]
+       UpdateManager.cpp
+       : be localestub package translation [ TargetLibsupc++ ]
        : SoftwareUpdater.rdef
 ;
diff --git a/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp 
b/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
index 43c38f2..a1856cd 100644
--- a/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
+++ b/src/apps/softwareupdater/SoftwareUpdaterWindow.cpp
@@ -12,16 +12,17 @@
 #include <stdio.h>
 #include <AppDefs.h>
 #include <Application.h>
-#include <Button.h>
 #include <GroupLayout.h>
 #include <GroupLayoutBuilder.h>
 #include <NodeInfo.h>
 #include <LayoutBuilder.h>
 #include <Message.h>
+#include <package/Context.h>
+#include <package/RefreshRepositoryRequest.h>
+#include <package/PackageRoster.h>
 #include <Resources.h>
 #include <SeparatorView.h>
 #include <String.h>
-#include <StringView.h>
 
 
 #undef B_TRANSLATION_CONTEXT
@@ -32,13 +33,25 @@ const uint32 kMsgUpdate = 'iUPD';
 const uint32 kMsgExit = 'iEXT';
 
 
+using namespace BPackageKit;
+
+
 SoftwareUpdaterWindow::SoftwareUpdaterWindow()
        :
        BWindow(BRect(0, 0, 0, 300), "Software Update",
                B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE),
-       fStripeView(NULL)
+//     fUpdateManager(NULL),
+       fStripeView(NULL),
+       fHeaderView(NULL),
+       fDetailView(NULL),
+       fUpdateButton(NULL),
+       fCancelButton(NULL)
 {
-       uint32 updatesAvailable = 45;
+       fUpdateManager = new UpdateManager(
+               BPackageKit::B_PACKAGE_INSTALLATION_LOCATION_HOME);
+       fUpdateManager->SetDebugLevel(10);
+       fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES
+               | BPackageManager::B_ADD_REMOTE_REPOSITORIES);
 
        BBitmap* icon = new BBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32);
        team_info teamInfo;
@@ -49,40 +62,23 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
 
        fStripeView = new StripeView(icon);
 
-       BButton* updateButton = new BButton("Update now",
+       BButton* fUpdateButton = new BButton("Update now",
                new BMessage(kMsgUpdate));
+       fUpdateButton->Hide();
 
-       BButton* exitButton = new BButton("Cancel",
+       BButton* fCancelButton = new BButton("Cancel",
                new BMessage(kMsgExit));
 
-       // Form text based on updates available
-       BStringView* headerView;
-       BStringView* detailView;
-
-       if (updatesAvailable > 0) {
-               headerView = new BStringView("header",
-                       "Software updates are available.", B_WILL_DRAW);
-               char detailString[1024];
-               snprintf(detailString, 1024, "There are %" B_PRIu32 " updates 
available"
-                       " for your system.", updatesAvailable);
-               detailView = new BStringView("detail", detailString, 
B_WILL_DRAW);
-               updateButton->MakeDefault(true);
-       } else {
-               headerView = new BStringView("header",
-                       "Your system is up to date.", B_WILL_DRAW);
-               detailView = new BStringView("detail",
-                       "No updates are available at this time.",
-                       B_WILL_DRAW);
-               updateButton->Hide();
-               exitButton->SetLabel("Quit");
-               exitButton->MakeDefault(true);
-       }
+       fHeaderView = new BStringView("header",
+               "Checking for updates...", B_WILL_DRAW);
+       fDetailView = new BStringView("detail", "Contacting software 
repositories"
+               " to check for package updates.", B_WILL_DRAW);
 
        BFont font;
-       headerView->GetFont(&font);
+       fHeaderView->GetFont(&font);
        font.SetFace(B_BOLD_FACE);
        font.SetSize(font.Size() * 1.5);
-       headerView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
+       fHeaderView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
                | B_FONT_FLAGS);
 
        BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0)
@@ -90,13 +86,13 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
                .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
                        .SetInsets(0, B_USE_DEFAULT_SPACING,
                                B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
-                       .Add(headerView)
-                       .Add(detailView)
+                       .Add(fHeaderView)
+                       .Add(fDetailView)
                        .AddStrut(B_USE_DEFAULT_SPACING)
                        .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
                                .AddGlue()
-                               .Add(exitButton)
-                               .Add(updateButton)
+                               .Add(fCancelButton)
+                               .Add(fUpdateButton)
                        .End()
                .End()
                .AddGlue()
@@ -104,6 +100,9 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
        ;
        CenterOnScreen();
        Show();
+
+       // Refresh our repos and update UI
+       _Refresh();
 }
 
 
@@ -133,3 +132,45 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
                        BWindow::MessageReceived(message);
        }
 }
+
+
+void
+SoftwareUpdaterWindow::_Error(const char* error)
+{
+       fHeaderView->SetText("Error encountered!");
+       fDetailView->SetText(error);
+       fUpdateButton->Hide();
+       fCancelButton->Show();
+}
+
+void
+SoftwareUpdaterWindow::_Refresh()
+{
+       BPackageRoster roster;
+       BStringList repoNames(20);
+
+       status_t result = roster.GetRepositoryNames(repoNames);
+       if (result != B_OK) {
+               _Error("Unable to obtain repository names.");
+               return;
+       }
+
+       for (int i = 0; i < repoNames.CountStrings(); i++) {
+               const BString& repoName = repoNames.StringAt(i);
+               BRepositoryConfig repoConfig;
+               result = roster.GetRepositoryConfig(repoName, &repoConfig);
+               if (result != B_OK) {
+                       printf("Skipping '%s' repo due to unknown config\n",
+                               repoName.String());
+                       continue;
+               }
+               /*
+               BRefreshRepositoryRequest request(context, repoConfig);
+               result = request.Process();
+               if (result != B_OK) {
+                       printf("Skipping %s repo due to unreachable repo");
+                       continue;
+               }
+               */
+       }
+}
diff --git a/src/apps/softwareupdater/SoftwareUpdaterWindow.h 
b/src/apps/softwareupdater/SoftwareUpdaterWindow.h
index fb3d979..a0776b1 100644
--- a/src/apps/softwareupdater/SoftwareUpdaterWindow.h
+++ b/src/apps/softwareupdater/SoftwareUpdaterWindow.h
@@ -9,11 +9,13 @@
 #define _SOFTWARE_UPDATER_WINDOW_H
 
 
+#include <Button.h>
 #include <Roster.h>
-#include <StatusBar.h>
+#include <StringView.h>
 #include <Window.h>
 
 #include "StripeView.h"
+#include "UpdateManager.h"
 
 
 class SoftwareUpdaterWindow : public BWindow {
@@ -25,8 +27,17 @@ public:
                        void                    MessageReceived(BMessage* 
message);
 
 private:
+                       void                    _Error(const char* error);
+                       void                    _Refresh();
+
+                       UpdateManager*  fUpdateManager;
                        StripeView*             fStripeView;
                        app_info*               fAppInfo;
+
+                       BStringView*    fHeaderView;
+                       BStringView*    fDetailView;
+                       BButton*                fUpdateButton;
+                       BButton*                fCancelButton;
 };
 
 
diff --git a/src/apps/softwareupdater/UpdateManager.cpp 
b/src/apps/softwareupdater/UpdateManager.cpp
new file mode 100644
index 0000000..8242a9d
--- /dev/null
+++ b/src/apps/softwareupdater/UpdateManager.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
+ *             Rene Gollent <rene@xxxxxxxxxxx>
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include "UpdateManager.h"
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <package/CommitTransactionResult.h>
+#include <package/DownloadFileRequest.h>
+#include <package/RefreshRepositoryRequest.h>
+#include <package/solver/SolverPackage.h>
+#include <package/solver/SolverProblem.h>
+#include <package/solver/SolverProblemSolution.h>
+
+
+using namespace BPackageKit;
+
+
+UpdateManager::UpdateManager(BPackageInstallationLocation location)
+       :
+       BPackageManager(location, &fClientInstallationInterface, this),
+       BPackageManager::UserInteractionHandler(),
+       fClientInstallationInterface()
+{
+}
+
+
+UpdateManager::~UpdateManager()
+{
+}
+
+
+void
+UpdateManager::JobFailed(BSupportKit::BJob* job)
+{
+       BString error = job->ErrorString();
+       if (error.Length() > 0) {
+               error.ReplaceAll("\n", "\n*** ");
+               fprintf(stderr, "%s", error.String());
+       }
+}
+
+
+void
+UpdateManager::JobAborted(BSupportKit::BJob* job)
+{
+       //DIE(job->Result(), "aborted");
+}
+
+
+void
+UpdateManager::HandleProblems()
+{
+       int32 problemCount = fSolver->CountProblems();
+       for (int32 i = 0; i < problemCount; i++) {
+               // print problem and possible solutions
+               BSolverProblem* problem = fSolver->ProblemAt(i);
+               printf("problem %" B_PRId32 ": %s\n", i + 1,
+                       problem->ToString().String());
+
+               int32 solutionCount = problem->CountSolutions();
+               for (int32 k = 0; k < solutionCount; k++) {
+                       const BSolverProblemSolution* solution = 
problem->SolutionAt(k);
+                       printf("  solution %" B_PRId32 ":\n", k + 1);
+                       int32 elementCount = solution->CountElements();
+                       for (int32 l = 0; l < elementCount; l++) {
+                               const BSolverProblemSolutionElement* element
+                                       = solution->ElementAt(l);
+                               printf("    - %s\n", 
element->ToString().String());
+                       }
+               }
+
+               // let the user choose a solution
+               printf("Please select a solution, skip the problem for now or 
quit.\n");
+               for (;;) {
+                       if (solutionCount > 1)
+                               printf("select [1...%" B_PRId32 "/s/q]: ", 
solutionCount);
+                       else
+                               printf("select [1/s/q]: ");
+
+                       char buffer[32];
+                       if (fgets(buffer, sizeof(buffer), stdin) == NULL
+                               || strcmp(buffer, "q\n") == 0) {
+                               //exit(1);
+                       }
+
+                       if (strcmp(buffer, "s\n") == 0)
+                               break;
+
+                       /*
+                       char* end;
+                       long selected = strtol(buffer, &end, 0);
+                       if (end == buffer || *end != '\n' || selected < 1
+                               || selected > solutionCount) {
+                               printf("*** invalid input\n");
+                               continue;
+                       }
+
+                       status_t error = fSolver->SelectProblemSolution(problem,
+                               problem->SolutionAt(selected - 1));
+                       if (error != B_OK)
+                               DIE(error, "failed to set solution");
+                       */
+                       break;
+               }
+       }
+}
+
+
+void
+UpdateManager::ConfirmChanges(bool fromMostSpecific)
+{
+       printf("The following changes will be made:\n");
+
+       int32 count = fInstalledRepositories.CountItems();
+       if (fromMostSpecific) {
+               for (int32 i = count - 1; i >= 0; i--)
+                       _PrintResult(*fInstalledRepositories.ItemAt(i));
+       } else {
+               for (int32 i = 0; i < count; i++)
+                       _PrintResult(*fInstalledRepositories.ItemAt(i));
+       }
+
+       /*
+       if (!fDecisionProvider.YesNoDecisionNeeded(BString(), "Continue?", 
"yes",
+                       "no", "yes")) {
+               //exit(1);
+       }
+       */
+}
+
+
+void
+UpdateManager::Warn(status_t error, const char* format, ...)
+{
+       va_list args;
+       va_start(args, format);
+       vfprintf(stderr, format, args);
+       va_end(args);
+
+       if (error == B_OK)
+               printf("\n");
+       else
+               printf(": %s\n", strerror(error));
+}
+
+
+void
+UpdateManager::ProgressPackageDownloadStarted(const char* packageName)
+{
+       printf("Downloading %s...\n", packageName);
+}
+
+
+void
+UpdateManager::ProgressPackageDownloadActive(const char* packageName,
+       float completionPercentage, off_t bytes, off_t totalBytes)
+{
+       return;
+       /*
+       if (!fInteractive)
+               return;
+
+       static const char* progressChars[] = {
+               "\xE2\x96\x8F",
+               "\xE2\x96\x8E",
+               "\xE2\x96\x8D",
+               "\xE2\x96\x8C",
+               "\xE2\x96\x8B",
+               "\xE2\x96\x8A",
+               "\xE2\x96\x89",
+               "\xE2\x96\x88",
+       };
+
+       int width = 70;
+
+       struct winsize winSize;
+       if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winSize) == 0
+               && winSize.ws_col < 77) {
+               // We need 7 characters for the percent display
+               width = winSize.ws_col - 7;
+       }
+
+       int position;
+       int ipart = (int)(completionPercentage * width);
+       int fpart = (int)(((completionPercentage * width) - ipart) * 8);
+
+       printf("\r"); // return to the beginning of the line
+
+       for (position = 0; position < width; position++) {
+               if (position < ipart) {
+                       // This part is fully downloaded, show a full block
+                       printf(progressChars[7]);
+               } else if (position > ipart) {
+                       // This part is not downloaded, show a space
+                       printf(" ");
+               } else {
+                       // This part is partially downloaded
+                       printf(progressChars[fpart]);
+               }
+       }
+
+       // Also print the progress percentage
+       printf(" %3d%%", (int)(completionPercentage * 100));
+
+       fflush(stdout);
+       */
+}
+
+
+void
+UpdateManager::ProgressPackageDownloadComplete(const char* packageName)
+{
+       // Overwrite the progress bar with whitespace
+       printf("\r");
+       struct winsize w;
+       ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+       for (int i = 0; i < (w.ws_col); i++)
+               printf(" ");
+       printf("\r\x1b[1A"); // Go to previous line.
+
+       printf("Downloading %s...done.\n", packageName);
+}
+
+
+void
+UpdateManager::ProgressPackageChecksumStarted(const char* title)
+{
+       printf("%s...", title);
+}
+
+
+void
+UpdateManager::ProgressPackageChecksumComplete(const char* title)
+{
+       printf("done.\n");
+}
+
+
+void
+UpdateManager::ProgressStartApplyingChanges(InstalledRepository& repository)
+{
+       printf("[%s] Applying changes ...\n", repository.Name().String());
+}
+
+
+void
+UpdateManager::ProgressTransactionCommitted(InstalledRepository& repository,
+       const BCommitTransactionResult& result)
+{
+       const char* repositoryName = repository.Name().String();
+
+       int32 issueCount = result.CountIssues();
+       for (int32 i = 0; i < issueCount; i++) {
+               const BTransactionIssue* issue = result.IssueAt(i);
+               if (issue->PackageName().IsEmpty()) {
+                       printf("[%s] warning: %s\n", repositoryName,
+                               issue->ToString().String());
+               } else {
+                       printf("[%s] warning: package %s: %s\n", repositoryName,
+                               issue->PackageName().String(), 
issue->ToString().String());
+               }
+       }
+
+       printf("[%s] Changes applied. Old activation state backed up in 
\"%s\"\n",
+               repositoryName, result.OldStateDirectory().String());
+       printf("[%s] Cleaning up ...\n", repositoryName);
+}
+
+
+void
+UpdateManager::ProgressApplyingChangesDone(InstalledRepository& repository)
+{
+       printf("[%s] Done.\n", repository.Name().String());
+}
+
+
+void
+UpdateManager::_PrintResult(InstalledRepository& installationRepository)
+{
+       if (!installationRepository.HasChanges())
+               return;
+
+       printf("  in %s:\n", installationRepository.Name().String());
+
+       PackageList& packagesToActivate
+               = installationRepository.PackagesToActivate();
+       PackageList& packagesToDeactivate
+               = installationRepository.PackagesToDeactivate();
+
+       BStringList upgradedPackages;
+       BStringList upgradedPackageVersions;
+       for (int32 i = 0;
+               BSolverPackage* installPackage = packagesToActivate.ItemAt(i);
+               i++) {
+               for (int32 j = 0;
+                       BSolverPackage* uninstallPackage = 
packagesToDeactivate.ItemAt(j);
+                       j++) {
+                       if (installPackage->Info().Name() == 
uninstallPackage->Info().Name()) {
+                               
upgradedPackages.Add(installPackage->Info().Name());
+                               
upgradedPackageVersions.Add(uninstallPackage->Info().Version().ToString());
+                               break;
+                       }
+               }
+       }
+
+       for (int32 i = 0; BSolverPackage* package = 
packagesToActivate.ItemAt(i);
+               i++) {
+               BString repository;
+               if (dynamic_cast<MiscLocalRepository*>(package->Repository()) 
!= NULL)
+                       repository = "local file";
+               else
+                       repository.SetToFormat("repository %s", 
package->Repository()->Name().String());
+
+               int position = upgradedPackages.IndexOf(package->Info().Name());
+               if (position >= 0) {
+                       printf("    upgrade package %s-%s to %s from %s\n",
+                               package->Info().Name().String(),
+                               
upgradedPackageVersions.StringAt(position).String(),
+                               package->Info().Version().ToString().String(),
+                               repository.String());
+               } else {
+                       printf("    install package %s-%s from %s\n",
+                               package->Info().Name().String(),
+                               package->Info().Version().ToString().String(),
+                               repository.String());
+               }
+       }
+
+       for (int32 i = 0; BSolverPackage* package = 
packagesToDeactivate.ItemAt(i);
+               i++) {
+               if (upgradedPackages.HasString(package->Info().Name()))
+                       continue;
+               printf("    uninstall package %s\n", 
package->VersionedName().String());
+       }
+}
diff --git a/src/apps/softwareupdater/UpdateManager.h 
b/src/apps/softwareupdater/UpdateManager.h
new file mode 100644
index 0000000..efef0bb
--- /dev/null
+++ b/src/apps/softwareupdater/UpdateManager.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ *             Rene Gollent <rene@xxxxxxxxxxx>
+ */
+#ifndef UPDATE_MANAGER_H
+#define UPDATE_MANAGER_H
+
+
+#include <package/DaemonClient.h>
+#include <package/manager/PackageManager.h>
+
+
+//using namespace BPackageKit;
+using BPackageKit::BPrivate::BDaemonClient;
+using BPackageKit::BManager::BPrivate::BPackageManager;
+
+
+class UpdateManager : public BPackageManager,
+       private BPackageManager::UserInteractionHandler {
+public:
+                                                               UpdateManager(
+                                                                       
BPackageKit::BPackageInstallationLocation location);
+                                                               
~UpdateManager();
+
+       virtual void                            JobFailed(BSupportKit::BJob* 
job);
+       virtual void                            JobAborted(BSupportKit::BJob* 
job);
+
+private:
+       // UserInteractionHandler
+       virtual void                            HandleProblems();
+       virtual void                            ConfirmChanges(bool 
fromMostSpecific);
+
+       virtual void                            Warn(status_t error, const 
char* format, ...);
+
+
+       virtual void                            ProgressPackageDownloadStarted(
+                                                                       const 
char* packageName);
+       virtual void                            ProgressPackageDownloadActive(
+                                                                       const 
char* packageName,
+                                                                       float 
completionPercentage,
+                                                                       off_t 
bytes, off_t totalBytes);
+       virtual void                            ProgressPackageDownloadComplete(
+                                                                       const 
char* packageName);
+       virtual void                            ProgressPackageChecksumStarted(
+                                                                       const 
char* packageName);
+       virtual void                            ProgressPackageChecksumComplete(
+                                                                       const 
char* packageName);
+
+       virtual void                            ProgressStartApplyingChanges(
+                                                                       
InstalledRepository& repository);
+       virtual void                            ProgressTransactionCommitted(
+                                                                       
InstalledRepository& repository,
+                                                                       const 
BPackageKit::BCommitTransactionResult& result);
+       virtual void                            ProgressApplyingChangesDone(
+                                                                       
InstalledRepository& repository);
+
+private:
+                       void                            
_PrintResult(InstalledRepository&
+                                                                       
installationRepository);
+
+private:
+                       BPackageManager::ClientInstallationInterface
+                                                                       
fClientInstallationInterface;
+};
+
+
+#endif // UPDATE_MANAGER_H 


Other related posts: