xref: /haiku/src/apps/haikudepot/server/PopulatePkgSizesProcess.cpp (revision 4c07199d8201fcf267e90be0d24b76799d03cea6)
1 /*
2  * Copyright 2018-2023, Andrew Lindesay <apl@lindesay.co.nz>.
3 
4  * All rights reserved. Distributed under the terms of the MIT License.
5  *
6  * Note that this file included code earlier from `MainWindow.cpp` and
7  * copyrights have been latterly been carried across in 2021.
8  */
9 
10 
11 #include "PopulatePkgSizesProcess.h"
12 
13 #include <Catalog.h>
14 
15 #include "Logger.h"
16 #include "PackageUtils.h"
17 
18 
19 #undef B_TRANSLATION_CONTEXT
20 #define B_TRANSLATION_CONTEXT "PopulatePkgSizesProcess"
21 
22 
23 PopulatePkgSizesProcess::PopulatePkgSizesProcess(Model* model)
24 	:
25 	fModel(model)
26 {
27 }
28 
29 
30 PopulatePkgSizesProcess::~PopulatePkgSizesProcess()
31 {
32 }
33 
34 
35 const char*
36 PopulatePkgSizesProcess::Name() const
37 {
38 	return "PopulatePkgSizesProcess";
39 }
40 
41 
42 const char*
43 PopulatePkgSizesProcess::Description() const
44 {
45 	return B_TRANSLATE("Populating package sizes");
46 }
47 
48 
49 status_t
50 PopulatePkgSizesProcess::RunInternal()
51 {
52 	int countPkgs = 0;
53 	int countPkgSized = 0;
54 	int countPkgUnsized = 0;
55 
56 	HDINFO("[%s] will populate size for pkgs without a size", Name());
57 
58 	for (int32 d = 0; d < fModel->CountDepots() && !WasStopped(); d++) {
59 		DepotInfoRef depotInfo = fModel->DepotAtIndex(d);
60 		countPkgs += depotInfo->CountPackages();
61 
62 		for (int32 p = 0; p < depotInfo->CountPackages(); p++) {
63 			PackageInfoRef packageInfo = depotInfo->PackageAtIndex(p);
64 			PackageState state = packageInfo->State();
65 
66 			if (packageInfo->Size() <= 0
67 					&& (state == ACTIVATED || state == INSTALLED)) {
68 				off_t derivedSize = _DeriveSize(packageInfo);
69 
70 				if (derivedSize > 0) {
71 					packageInfo->SetSize(derivedSize);
72 					countPkgSized++;
73 					HDDEBUG("[%s] did derive a size for package [%s]",
74 						Name(), packageInfo->Name().String());
75 				} else {
76 					countPkgUnsized++;
77 					HDDEBUG("[%s] unable to derive a size for package [%s]",
78 						Name(), packageInfo->Name().String());
79 				}
80 			}
81 		}
82 	}
83 
84 	HDINFO("[%s] did populate size for %" B_PRId32 " packages with %" B_PRId32
85 		" already having a size and %" B_PRId32 " unable to derive a size",
86 		Name(), countPkgSized, countPkgs - countPkgSized, countPkgUnsized);
87 
88 	return B_OK;
89 }
90 
91 
92 off_t
93 PopulatePkgSizesProcess::_DeriveSize(const PackageInfoRef package) const
94 {
95 	BPath path;
96 	if (PackageUtils::DeriveLocalFilePath(package.Get(), path) == B_OK) {
97 		BEntry entry(path.Path());
98 		struct stat s = {};
99 		if (entry.GetStat(&s) == B_OK)
100 			return s.st_size;
101 		else
102 			HDDEBUG("unable to get the size of local file [%s]", path.Path());
103 	} else
104 		HDDEBUG("unable to get the local file of package [%s]", package->Name().String());
105 	return 0;
106 }