Module: Yast::PrinterPoliciesInclude

Defined in:
../../src/include/printer/policies.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) ApplyPoliciesSettings



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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File '../../src/include/printer/policies.rb', line 262

def ApplyPoliciesSettings
  applied_policies = true
  # Get the actual settings and values from the dialog:
  current_operation_policy = Convert.to_string(
    UI.QueryWidget(Id("operation_policy"), :Value)
  )
  apply_operation_policy = Convert.to_boolean(
    UI.QueryWidget(Id("apply_operation_policy"), :Value)
  )
  Builtins.y2milestone(
    "current_operation_policy: '%1' apply it to all local queues: '%2'",
    current_operation_policy,
    apply_operation_policy
  )
  current_error_policy = Convert.to_string(
    UI.QueryWidget(Id("error_policy"), :Value)
  )
  apply_error_policy = Convert.to_boolean(
    UI.QueryWidget(Id("apply_error_policy"), :Value)
  )
  Builtins.y2milestone(
    "current_error_policy: '%1' apply it to all local queues: '%2'",
    current_error_policy,
    apply_error_policy
  )
  if current_operation_policy == @initial_operation_policy &&
      current_error_policy == @initial_error_policy &&
      !apply_operation_policy &&
      !apply_error_policy
    Builtins.y2milestone("Nothing changed in 'Policies' dialog.")
    Builtins.y2milestone("leaving storePolicies")
    return true
  end
  if apply_operation_policy || apply_error_policy
    # The Overview dialog is also shown in any case after a queue was added.
    # Finally the Overview dialog is re-run (with a re-created list of queues) via the sequencer
    # after a queue was deleted.
    # The Overview dialog calls Printer::QueueItems which calls AutodetectQueues so that
    # the queues have been already autodetected and the Printer::queues list is up to date.
    # so that there is no need to call Printer::AutodetectQueues here again.
    Builtins.foreach(Printer.queues) do |queue|
      name = Ops.get(queue, "name", "")
      next if "" == Builtins.filterchars(name, Printer.alnum_chars)
      commandline = Ops.add(
        Ops.add("/usr/sbin/lpadmin -h localhost -p '", name),
        "'"
      )
      if apply_operation_policy
        commandline = Ops.add(
          Ops.add(
            Ops.add(commandline, " -o 'printer-op-policy="),
            current_operation_policy
          ),
          "'"
        )
      end
      if apply_error_policy
        commandline = Ops.add(
          Ops.add(
            Ops.add(commandline, " -o 'printer-error-policy="),
            current_error_policy
          ),
          "'"
        )
      end
      if !Printerlib.ExecuteBashCommand(commandline)
        Popup.ErrorDetails(
          Builtins.sformat(
            # where %1 will be replaced by the print queue name.
            _("Failed to apply the policy to '%1'"),
            name
          ), # Popup::ErrorDetails message
          Ops.get_string(Printerlib.result, "stderr", "")
        )
        applied_policies = false
      end
    end
  end
  if current_operation_policy != @initial_operation_policy
    if !Printerlib.ExecuteBashCommand(
        Ops.add(
          Ops.add(
            Printerlib.yast_bin_dir,
            "modify_cupsd_conf DefaultPolicy "
          ),
          current_operation_policy
        )
      )
      Popup.ErrorDetails(
        Builtins.sformat(
          # where %1 will be replaced by the default operation policy value.
          # Do not change or translate "DefaultPolicy", it is a system settings name.
          _("Failed to set 'DefaultPolicy %1' in /etc/cups/cupsd.conf"),
          current_operation_policy
        ), # Popup::ErrorDetails message
        Ops.get_string(Printerlib.result, "stderr", "")
      )
      applied_policies = false
    end
  end
  if current_error_policy != @initial_error_policy
    if !Printerlib.ExecuteBashCommand(
        Ops.add(
          Ops.add(Printerlib.yast_bin_dir, "modify_cupsd_conf ErrorPolicy "),
          current_error_policy
        )
      )
      Popup.ErrorDetails(
        Builtins.sformat(
          # where %1 will be replaced by the default error policy value.
          # Do not change or translate "ErrorPolicy", it is a system settings name.
          _("Failed to set 'ErrorPolicy %1' in /etc/cups/cupsd.conf"),
          current_error_policy
        ), # Popup::ErrorDetails message
        Ops.get_string(Printerlib.result, "stderr", "")
      )
      applied_policies = false
    end
  end
  # Restart a local cupsd only if a policy in /etc/cups/cupsd.conf was changed:
  if current_operation_policy != @initial_operation_policy ||
      current_error_policy != @initial_error_policy
    # otherwise do nothing (i.e. do not start it now):
    if Printerlib.GetAndSetCupsdStatus("")
      if !Printerlib.GetAndSetCupsdStatus("restart")
        applied_policies = false
      end
    end
  end
  Builtins.y2milestone("leaving storePolicies")
  applied_policies
end

- (Object) handlePolicies(key, event)



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File '../../src/include/printer/policies.rb', line 395

def handlePolicies(key, event)
  event = deep_copy(event)
  Builtins.y2milestone(
    "entering handlePolicies with key '%1'\nand event '%2'",
    key,
    event
  )
  if "Activated" == Ops.get_string(event, "EventReason", "")
    if :abort == Ops.get(event, "ID") || :cancel == Ops.get(event, "ID") ||
        :back == Ops.get(event, "ID")
      # There is only a "Cancel" functionality (via the "back" button) which goes back one step
      # and the button with the "abort" functionality is not shown at all (see dialogs.ycp).
      # Unfortunately when the YaST package installer is run via Printerlib::TestAndInstallPackage
      # it leaves a misused "abort" button labeled "Skip Autorefresh" with WidgetID "`abort"
      # so that this case is mapped to the "Cancel" functionality:
      return :policies_back
    end
    if :next == Ops.get(event, "ID")
      if !ApplyPoliciesSettings()
        Popup.Error(_("Failed to apply the settings to the system."))
      end
      return :policies_next
    end
  end
  nil
end

- (Object) initialize_printer_policies(include_target)



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
# File '../../src/include/printer/policies.rb', line 30

def initialize_printer_policies(include_target)
  Yast.import "UI"

  textdomain "printer"

  Yast.import "Printerlib"
  Yast.import "Printer"
  Yast.import "Popup"

  Yast.include include_target, "printer/helps.rb"

  @initial_operation_policy = "default"
  # An entry for a ComboBox from which the user can select that the CUPS error policy
  # which is used when it fails to send a job to the printer is to
  # stop the printer and keep the job for future printing:
  @error_policy_stop_printer_string = _(
    "stop the printer and keep the job for future printing"
  )
  # An entry for a ComboBox from which the user can select that the CUPS error policy
  # which is used when it fails to send a job to the printer is to
  # re-send the job from the beginning after waiting some time
  # (the default JobRetryInterval is 30 seconds but this can be changed):
  @error_policy_retry_job_string = _(
    "re-send the job after waiting some time"
  )
  # An entry for a ComboBox from which the user can select that the CUPS error policy
  # which is used when it fails to send a job to the printer is to
  # abort and delete the job and proceed with the next job:
  @error_policy_abort_job_string = _(
    "abort and delete the job and proceed with the next job"
  )
  @initial_error_policy = "stop-printer"

  # Have the error policy stuff first because this is of more importance for a normal user.
  # Normal users may like to change the CUPS upstream default "stop-printer" error policy
  # to "abort-job" because is often more convenient for a workstation with local printers
  # when a failing print job is simply removed instead of having the whole queue disabled
  # and get the failed job re-printed when the queue becomes re-enabled at any time later.
  # In contrast normal users should usually not change the CUPS upstream default
  # operation policy "default" to something else because other operation policies
  # are either less secure or too secure for usual printing operation.
  @widgetPolicies = VBox(
    VStretch(),
    Left(
      ComboBox(
        Id("error_policy"),
        # Header for a ComboBox to specify the CUPS error policy:
        _("Specify the &error policy"),
        [
          Item(Id("stop-printer"), @error_policy_stop_printer_string),
          Item(Id("retry-job"), @error_policy_retry_job_string),
          Item(Id("abort-job"), @error_policy_abort_job_string)
        ]
      )
    ),
    Left(
      CheckBox(
        Id("apply_error_policy"),
        # CheckBox to apply the CUPS error policy which is selected in the ComboBox above
        # to all local printer configurations (i.e. to all local print queues).
        # When possible we perefer to use the wording "printer configuration"
        # instead of "print queue" because the latter may sound too technical
        # but sometimes (e.g. in the Connection Wizard) we must use the exact technical term:
        _("&Apply this error policy to all local printer configurations")
      )
    ),
    VStretch(),
    Left(
      ComboBox(
        Id("operation_policy"),
        # Header for a ComboBox to specify the CUPS operation policy:
        _("Specify the &operation policy"),
        [""]
      )
    ),
    Left(
      CheckBox(
        Id("apply_operation_policy"),
        # CheckBox to apply the CUPS operation policy which is selected in the ComboBox above
        # to all local printer configurations (i.e. to all local print queues).
        # When possible we perefer to use the wording "printer configuration"
        # instead of "print queue" because the latter may sound too technical
        # but sometimes (e.g. in the Connection Wizard) we must use the exact technical term:
        _(
          "Apply this operation &policy to all local printer configurations"
        )
      )
    ),
    VStretch()
  )
end

- (Object) initPolicies(key)



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
# File '../../src/include/printer/policies.rb', line 122

def initPolicies(key)
  Builtins.y2milestone("entering initPolicies with key '%1'", key)
  # Note that the "Policies" dialog is not useless when there is no local queue.
  # For example the user may like to configure the "Policies" before he set up the first local queue.
  policies_dialog_is_useless = false
  # Determine whether or not it is currently a real client-only config
  # (i.e. a ServerName != "localhost/127.0.0.1" in /etc/cups/client.conf)
  # and ignore when it fails (i.e. use the fallback value silently):
  Printerlib.DetermineClientOnly
  if Printerlib.client_only
    if !Popup.YesNoHeadline(
        Builtins.sformat(
          # where %1 will be replaced by the server name:
          _("Disable Remote CUPS Server '%1'"),
          Printerlib.client_conf_server_name
        ), # PopupYesNoHeadline headline
        # PopupYesNoHeadline body:
        _(
          "A remote CUPS server setting conflicts with setting policies for the local system."
        )
      )
      policies_dialog_is_useless = true
      Builtins.y2milestone(
        "policies_dialog_is_useless because user decided not to disable client-only CUPS server '%1'",
        Printerlib.client_conf_server_name
      )
    else
      if !Printerlib.ExecuteBashCommand(
          Ops.add(Printerlib.yast_bin_dir, "cups_client_only none")
        )
        Popup.ErrorDetails(
          _(
            "Failed to remove the 'ServerName' entry in /etc/cups/client.conf"
          ),
          Ops.add(
            Ops.add(Ops.get_string(Printerlib.result, "stderr", ""), "\n"),
            Ops.get_string(Printerlib.result, "stdout", "")
          )
        )
        policies_dialog_is_useless = true
        Builtins.y2milestone(
          "policies_dialog_is_useless because it failed to disable client-only CUPS server '%1'",
          Printerlib.client_conf_server_name
        )
      end
    end
  end
  # When it is no "client-only" config,
  # determine whether or not a local cupsd is accessible:
  if !policies_dialog_is_useless
    if !Printerlib.GetAndSetCupsdStatus("")
      if !Printerlib.GetAndSetCupsdStatus("start")
        policies_dialog_is_useless = true
        Builtins.y2milestone(
          "policies_dialog_is_useless because 'rccups start' failed."
        )
      end
    end
  end
  # Determine the existing policy names in '<Policy policy-name>' sections in /etc/cups/cupsd.conf:
  policy_names = [""]
  if Printerlib.ExecuteBashCommand(
      Ops.add(Printerlib.yast_bin_dir, "modify_cupsd_conf Policies")
    )
    # but possible duplicate policy names are not removed in the command output:
    policy_names = Builtins.toset(
      Builtins.splitstring(
        Ops.get_string(Printerlib.result, "stdout", ""),
        " "
      )
    )
  else
    policy_names = ["default"]
  end
  # Determine the DefaultPolicy in /etc/cups/cupsd.conf:
  if Printerlib.ExecuteBashCommand(
      Ops.add(Printerlib.yast_bin_dir, "modify_cupsd_conf DefaultPolicy")
    )
    # but possible duplicate policy names are not removed in the command output.
    # Multiple DefaultPolicy entries are a broken config but it can happen
    # and in this case the first DefaultPolicy entry is used:
    @initial_operation_policy = Ops.get(
      Builtins.splitstring(
        Ops.get_string(Printerlib.result, "stdout", ""),
        " "
      ),
      0,
      "default"
    )
  else
    @initial_operation_policy = "default"
  end
  # Use only the plain strings in the policy_names list without an id
  # for the operation_policy ComboBox:
  UI.ChangeWidget(Id("operation_policy"), :Items, policy_names)
  # Have the initial_operation_policy preselected:
  UI.ChangeWidget(Id("operation_policy"), :Value, @initial_operation_policy)
  # Have the CheckBox to apply the operation policy to all local print queues
  # un-checked in any case:
  UI.ChangeWidget(Id("apply_operation_policy"), :Value, false)
  # Determine the ErrorPolicy in /etc/cups/cupsd.conf:
  if Printerlib.ExecuteBashCommand(
      Ops.add(Printerlib.yast_bin_dir, "modify_cupsd_conf ErrorPolicy")
    )
    # but possible duplicate policy names are not removed in the command output.
    # Multiple ErrorPolicy entries are a broken config but it can happen
    # and in this case the first ErrorPolicy entry is used:
    @initial_error_policy = Ops.get(
      Builtins.splitstring(
        Ops.get_string(Printerlib.result, "stdout", ""),
        " "
      ),
      0,
      "stop-printer"
    )
  else
    @initial_error_policy = "stop-printer"
  end
  # Have the initial_error_policy preselected:
  UI.ChangeWidget(Id("error_policy"), :Value, Id(@initial_error_policy))
  # Have the CheckBox to apply the error policy to all local print queues
  # un-checked in any case:
  UI.ChangeWidget(Id("apply_error_policy"), :Value, false)
  if policies_dialog_is_useless
    UI.ChangeWidget(Id("operation_policy"), :Enabled, false)
    UI.ChangeWidget(Id("apply_operation_policy"), :Enabled, false)
    UI.ChangeWidget(Id("error_policy"), :Enabled, false)
    UI.ChangeWidget(Id("apply_error_policy"), :Enabled, false)
  end
  Builtins.y2milestone(
    "leaving initPolicies with\n" +
      "initial_operation_policy = '%1'\n" +
      "initial_error_policy = '%2'",
    @initial_operation_policy,
    @initial_error_policy
  )

  nil
end