-
Notifications
You must be signed in to change notification settings - Fork 22
/
PackageSlideShow.rb
340 lines (286 loc) · 11 KB
/
PackageSlideShow.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
require "yast"
require "yast2/system_time"
# Yast namespace
module Yast
# Module to access slides from installation repository
class PackageSlideShowClass < Module
include Yast::Logger
def main
Yast.import "UI"
Yast.import "Pkg"
textdomain "packager"
Yast.import "SlideShow"
Yast.import "String"
Yast.import "Mode"
Yast.import "Packages"
@inst_src_names = [] # a list of strings identifying each repository
@total_size_installed = 0
@total_size_to_install = 0
@init_pkg_data_complete = false
# package summary
# package counters
@installed_packages = 0
@updated_packages = 0
@removed_packages = 0
@total_downloaded = 0
@total_installed = 0
@total_pkgs_to_install = 0
@expected_total_download_size = 0
@finished_total_download_size = 0
@current_pkg_download_percent = 0
# package list (only used in installed system)
@installed_packages_list = []
@updated_packages_list = []
@removed_packages_list = []
@updating = false
end
def ResetPackageSummary
@installed_packages = 0
@updated_packages = 0
@removed_packages = 0
@total_downloaded = 0
@total_installed = 0
@expected_total_download_size = 0
@finished_total_download_size = 0
@current_pkg_download_size = 0
@current_pkg_download_percent = 0
@current_pkg_name = ""
@installed_packages_list = []
@updated_packages_list = []
@removed_packages_list = []
# temporary values
@updating = false
nil
end
def GetPackageSummary
{
"installed" => @installed_packages,
"updated" => @updated_packages,
"removed" => @removed_packages,
"installed_list" => @installed_packages_list,
"updated_list" => @updated_packages_list,
"removed_list" => @removed_packages_list,
"downloaded_bytes" => @total_downloaded,
"installed_bytes" => @total_installed
}
end
# ***************************************************************************
# ************** Formatting functions and helpers **************************
# ***************************************************************************
# Sum up all list items. It flattens the list and also skips all negative values.
#
# @param sizes [Array<Fixnum|Array>] Sizes to sum
# @return [Fixnum] Sizes sum
def ListSum(sizes)
sizes.flatten.select(&:positive?).reduce(0, :+)
end
# The total size in bytes to install.
def TotalSizeToInstall
@total_size_to_install
end
# The current size in bytes that is already installed.
def TotalInstalledSize
@total_size_installed
end
# Format number of remaining bytes to be installed as string.
# @param [Fixnum] remaining bytes remaining, -1 for 'done'
# @return [String] human readable remaining time or byte / kB/ MB size
#
def FormatRemainingSize(remaining)
if remaining < 0
# Nothing more to install from this CD (very concise - little space!!)
return _("Done.")
end
return "" if remaining.zero?
String.FormatSize(remaining)
end
# Format number of remaining packages to be installed as string.
# @param [Fixnum] remaining bytes remaining, -1 for 'done'
# @return [String] human readable remaining time or byte / kB/ MB size
#
def FormatRemainingCount(remaining)
if remaining < 0
# Nothing more to install from this CD (very concise - little space!!)
return _("Done.")
end
return "" if remaining.zero?
Builtins.sformat("%1", remaining)
end
# Initialize internal pacakge data, such as remaining package sizes and
# times. This may not be called before the pkginfo server is up and
# running, so this cannot be reliably done from the constructor in all
# cases.
# @param [Boolean] force true to force reinitialization
#
def InitPkgData(force)
return if @init_pkg_data_complete && !force
ResetPackageSummary()
# Reinititalize some globals (in case this is a second run)
@total_size_installed = 0
@updated_packages = 0
@installed_packages = 0
total_sizes_per_cd_per_src = Pkg.PkgMediaSizes
total_pkg_count_per_cd_per_src = Pkg.PkgMediaCount
@total_size_to_install = ListSum(total_sizes_per_cd_per_src)
log.info "total_size_to_install: #{@total_size_to_install}"
@total_pkgs_to_install = ListSum(total_pkg_count_per_cd_per_src)
@init_pkg_data_complete = true
@expected_total_download_size = Packages.CountSizeToBeDownloaded
end
# ***************************************************************************
# ***************** Callbacks and progress bars ****************************
# ***************************************************************************
# Update the overall progress value (download + installation)
def UpdateTotalProgressValue
total_size = @total_size_to_install + @expected_total_download_size
if total_size.zero?
total_progress = 100.0 # Nothing to install. Should not happen.
else
current = TotalInstalledSize() + CurrentDownloadSize()
total_progress = 100.0 * current / total_size
end
log.info "### Total package installation progress: #{total_progress}%"
SlideShow.StageProgress(total_progress.round, nil)
end
# Calculate the size of the current downloads
def CurrentDownloadSize
current_pkg = @current_pkg_download_size * @current_pkg_download_percent / 100
@finished_total_download_size + current_pkg
end
# Update progress widgets
#
def UpdateTotalProgress(_silent_check)
# update the overall progress value (download + installation)
log.info "### UpdateTotalProgressValue"
UpdateTotalProgressValue()
end
# Progress display update
# This is called via the packager's progress callbacks.
#
# @param [Fixnum] pkg_percent package percentage
#
def UpdateCurrentPackageProgress(pkg_percent)
# FIXME: Obsolete?
log.info "### UpdateCurrentPackageProgress #{pkg_percent}"
end
def DisplayGlobalProgress
remaining_string = FormatRemainingSize(@total_size_to_install - @total_size_installed)
remaining_string += ", " unless remaining_string.empty?
SlideShow.SetGlobalProgressLabel(
Ops.add(
SlideShow.CurrentStageDescription,
Builtins.sformat(
_(" (Remaining: %1%2 packages)"),
remaining_string,
@total_pkgs_to_install - @installed_packages - @updated_packages
)
)
)
nil
end
# Notification when package download starts
def DownloadStart(pkg_name, download_size)
log.info "### DownloadStart #{pkg_name} size: #{download_size}"
sleep(1)
@current_pkg_name = pkg_name
@current_pkg_download_size = download_size
@current_pkg_download_percent = 0
UpdateTotalProgressValue()
nil
end
# Update the download progress for the current package
def DownloadProgress(pkg_percent)
log.info "### DownloadProgress #{pkg_percent}"
@current_pkg_download_percent = pkg_percent
UpdateTotalProgressValue()
nil
end
# Notification when package download is finished (but not yet installed)
def DownloadEnd(pkg_name)
log.info("### DownloadEnd #{pkg_name}")
CurrentDownloadFinished()
UpdateTotalProgressValue()
sleep(3)
nil
end
# Notification about a download error.
# @param [Integer] error Numeric error code
# @param [String] reason
# @param [String] pkg_name
def DownloadError(error, reason, pkg_name)
log.error("Download error #{error} for #{pkg_name}: #{reason}")
CurrentDownloadFinished()
UpdateTotalProgressValue()
nil
end
# Finalize the sums for the current download
def CurrentDownloadFinished
@finished_total_download_size += @current_pkg_download_size
@current_pkg_download_size = 0
@current_pkg_download_percent = 0
@current_pkg_name = ""
end
# Notification that a package starts being installed, updated or removed.
# Not to be confused with DownloadStart.
#
# @param [String] pkg_name package name
# @param [String] _pkg_location full path to a package
# @param [String] _pkg_summary package summary (short description)
# @param [Integer] _pkg_size installed package size in bytes
# @param [Boolean] deleting Flag: deleting (true) or installing (false) package?
#
def PkgInstallStart(pkg_name, _pkg_location, _pkg_summary, _pkg_size, deleting)
@updating = Pkg.PkgInstalled(pkg_name) if !deleting
# Update global progress bar
DisplayGlobalProgress()
nil
end
# Progress notification while a package is finished being installed, updated or removed.
#
# @param [Integer] percent of progress of this package
def PkgInstallProgress(_pkg_percent)
nil
end
# Notification that a package is finished being installed, updated or removed.
#
# @param [String] pkg_name package name
# @param [String] pkg_size package size in bytes
# @param [Boolean] deleting Flag: deleting (true) or installing (false) package
#
def PkgInstallDone(pkg_name, pkg_size, deleting)
if deleting
@removed_packages += 1
@removed_packages_list << pkg_name if Mode.normal
else
@total_size_installed += pkg_size
UpdateTotalProgress(false)
# Update global progress bar
DisplayGlobalProgress()
if @updating
@updated_packages += 1
@updated_packages_list << pkg_name if Mode.normal
else
@installed_packages += 1
@installed_packages_list << pkg_name if Mode.normal
end
@total_installed += pkg_size
end
nil
end
publish variable: :total_size_to_install, type: "integer" # Used in installation client
publish function: :TotalSizeToInstall, type: "integer ()" # Better substitute for the above
publish function: :GetPackageSummary, type: "map <string, any> ()"
publish function: :InitPkgData, type: "void (boolean)"
publish function: :UpdateCurrentPackageProgress, type: "void (integer)"
publish function: :DisplayGlobalProgress, type: "void ()"
publish function: :DownloadStart, type: "void (string, integer)"
publish function: :DownloadProgress, type: "void (integer)"
publish function: :DownloadEnd, type: "void (string)"
publish function: :DownloadError, type: "void (integer, string, string)"
publish function: :PkgInstallStart, type: "void (string, integer, string, boolean)"
publish function: :PkgInstallProgress, type: "void (integer)"
publish function: :PkgInstallDone, type: "void (string, integer, boolean)"
end
PackageSlideShow = PackageSlideShowClass.new
PackageSlideShow.main
end