xref: /haiku/src/apps/haikudepot/server/LocalRepositoryUpdateProcess.cpp (revision e705c841d784f0035a0ef3e9e96f6e017df16681)
1 /*
2  * Copyright 2018, Andrew Lindesay <apl@lindesay.co.nz>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "LocalRepositoryUpdateProcess.h"
8 
9 #include <Catalog.h>
10 #include <Roster.h>
11 #include <String.h>
12 #include <StringList.h>
13 
14 #include <package/Context.h>
15 #include <package/manager/Exceptions.h>
16 #include <package/PackageRoster.h>
17 #include <package/RefreshRepositoryRequest.h>
18 
19 #include "AppUtils.h"
20 #include "DecisionProvider.h"
21 #include "JobStateListener.h"
22 #include "Logger.h"
23 #include "HaikuDepotConstants.h"
24 
25 
26 #undef B_TRANSLATION_CONTEXT
27 #define B_TRANSLATION_CONTEXT "LocalRepositoryUpdateProcess"
28 
29 
30 using namespace BPackageKit;
31 using namespace BPackageKit::BManager::BPrivate;
32 
33 
34 LocalRepositoryUpdateProcess::LocalRepositoryUpdateProcess(
35 	Model *model, bool force)
36 	:
37 	AbstractProcess(),
38 	fModel(model),
39 	fForce(force)
40 {
41 }
42 
43 
44 LocalRepositoryUpdateProcess::~LocalRepositoryUpdateProcess()
45 {
46 }
47 
48 
49 const char*
50 LocalRepositoryUpdateProcess::Name() const
51 {
52 	return "LocalRepositoryUpdateProcess";
53 }
54 
55 
56 const char*
57 LocalRepositoryUpdateProcess::Description() const
58 {
59 	return B_TRANSLATE("Fetching remote repository data");
60 }
61 
62 
63 status_t
64 LocalRepositoryUpdateProcess::RunInternal()
65 {
66 	BPackageRoster roster;
67 	BStringList repoNames;
68 
69 	if (Logger::IsInfoEnabled()) {
70 		printf("[%s] will update local repositories\n", Name());
71 	}
72 
73 	status_t result = roster.GetRepositoryNames(repoNames);
74 
75 	if (result == B_OK) {
76 		DecisionProvider decisionProvider;
77 		JobStateListener listener;
78 		BContext context(decisionProvider, listener);
79 		BRepositoryCache cache;
80 
81 		for (
82 			int32 i = 0;
83 			result == B_OK && i < repoNames.CountStrings() && !WasStopped();
84 			++i) {
85 			result = _RunForRepositoryName(repoNames.StringAt(i), context,
86 				roster, &cache);
87 		}
88 	} else {
89 		_NotifyError(strerror(result));
90 		result = B_ERROR;
91 	}
92 
93 	if (result == B_OK && Logger::IsInfoEnabled()) {
94 		printf("[%s] did update %" B_PRIi32 " local repositories\n",
95 			Name(), repoNames.CountStrings());
96 	}
97 
98 	return result;
99 }
100 
101 status_t
102 LocalRepositoryUpdateProcess::_RunForRepositoryName(const BString& repoName,
103 	BPackageKit::BContext& context, BPackageKit::BPackageRoster& roster,
104 	BPackageKit::BRepositoryCache* cache)
105 {
106 	status_t result = B_ERROR;
107 	BRepositoryConfig repoConfig;
108 	result = roster.GetRepositoryConfig(repoName, &repoConfig);
109 	if (result == B_OK) {
110 		if (roster.GetRepositoryCache(repoName, cache) != B_OK || fForce) {
111 			try {
112 				BRefreshRepositoryRequest refreshRequest(context, repoConfig);
113 				result = refreshRequest.Process();
114 				result = B_OK;
115 			} catch (BFatalErrorException ex) {
116 				_NotifyError(ex.Message(), ex.Details());
117 			} catch (BException ex) {
118 				_NotifyError(ex.Message());
119 			}
120 		}
121 	} else {
122 		_NotifyError(strerror(result));
123 	}
124 
125 	return result;
126 }
127 
128 
129 void
130 LocalRepositoryUpdateProcess::_NotifyError(const BString& error) const
131 {
132 	_NotifyError(error, "");
133 }
134 
135 
136 void
137 LocalRepositoryUpdateProcess::_NotifyError(const BString& error,
138 	const BString& details) const
139 {
140 	printf("an error has arisen updating the local repositories : %s\n",
141 		error.String());
142 
143 	BString alertText(B_TRANSLATE("An error occurred while refreshing the "
144 		"repository: %error%"));
145 	alertText.ReplaceFirst("%error%", error);
146 
147 	if (!details.IsEmpty()) {
148 		alertText.Append(" (");
149 		alertText.Append(details);
150 		alertText.Append(")");
151 	}
152 
153 	AppUtils::NotifySimpleError(
154 		B_TRANSLATE("Repository Update Error"),
155 		alertText);
156 }