|
38 |
import univention.config_registry |
38 |
import univention.config_registry |
39 |
|
39 |
|
40 |
from fnmatch import * |
40 |
from fnmatch import * |
|
|
41 |
from time import sleep |
41 |
import re |
42 |
import re |
42 |
import string |
43 |
import string |
43 |
import subprocess |
44 |
import subprocess |
|
107 |
|
108 |
|
108 |
self.finished(request.id,result) |
109 |
self.finished(request.id,result) |
109 |
|
110 |
|
110 |
def get(self,request): |
111 |
def get_printer(self,request): |
111 |
""" gets detail data for one printer. """ |
112 |
""" gets detail data for one printer. """ |
112 |
|
113 |
|
113 |
# ----------- DEBUG ----------------- |
114 |
# ----------- DEBUG ----------------- |
|
145 |
MODULE.info(" << %s" % s) |
146 |
MODULE.info(" << %s" % s) |
146 |
# ----------------------------------- |
147 |
# ----------------------------------- |
147 |
|
148 |
|
148 |
result = self._job_list(request.options.get('printer','')) |
149 |
printer = request.options.get('printer','') |
|
|
150 |
result = self._job_list(printer) |
149 |
|
151 |
|
150 |
# ---------- DEBUG -------------- |
152 |
# ---------- DEBUG -------------- |
151 |
MODULE.info("printers/jobs/query returns:") |
153 |
MODULE.info("printers/jobs/query returns:") |
|
166 |
def list_quota(self,request): |
168 |
def list_quota(self,request): |
167 |
""" lists all quota entries related to this printer. """ |
169 |
""" lists all quota entries related to this printer. """ |
168 |
|
170 |
|
169 |
# fill a dummy result table. |
171 |
# ----------- DEBUG ----------------- |
|
|
172 |
MODULE.info("printers/quota/query invoked with:") |
173 |
pp = pprint.PrettyPrinter(indent=4) |
174 |
st = pp.pformat(request.options).split("\n") |
175 |
for s in st: |
176 |
MODULE.info(" << %s" % s) |
177 |
# ----------------------------------- |
178 |
|
170 |
printer = request.options.get('printer','') |
179 |
printer = request.options.get('printer','') |
|
|
180 |
|
171 |
result = [] |
181 |
result = [] |
|
|
182 |
|
183 |
(stdout,stderr,status) = self._shell_command(['/usr/bin/pkusers','--list'],{'LANG':'C'}) |
184 |
users = [] |
185 |
expr = re.compile('^\s*(.*?)\s+\-\s\<') |
186 |
if status == 0: |
187 |
for line in stdout.split("\n"): |
188 |
match = expr.match(line) |
189 |
if match: |
190 |
users.append(match.group(1)) |
191 |
|
192 |
result = [] |
193 |
for user in users: |
194 |
(stdout,stderr,status) = self._shell_command(['/usr/bin/repykota','-P',printer,user],{'LANG':'C'}) |
195 |
if status == 0: |
196 |
for line in stdout.split("\n"): |
197 |
data = line[16:].split() # ignore possibly truncated user name |
198 |
if len(data) >= 7: |
199 |
ok = True |
200 |
for n in (2,3,4,len(data)-3): |
201 |
if not data[n].isdigit(): |
202 |
ok = False |
203 |
if ok: |
204 |
MODULE.info(" -> user='%s' used=%s soft=%s hard=%s total=%s" % (user,data[2],data[3],data[4],data[len(data)-3])) |
205 |
entry = { |
206 |
'user': user, |
207 |
'used': data[2], |
208 |
'soft': data[3], |
209 |
'hard': data[4], |
210 |
'total': data[len(data)-3] |
211 |
} |
212 |
result.append(entry) |
172 |
|
213 |
|
|
|
214 |
# ---------- DEBUG -------------- |
215 |
MODULE.info("printers/quota/query returns:") |
216 |
pp = pprint.PrettyPrinter(indent=4) |
217 |
st = '' |
218 |
if len(result) > 5: |
219 |
tmp = result[0:5] |
220 |
MODULE.info(" >> %d entries, first 5 are:" % len(result)) |
221 |
st = pp.pformat(tmp).split("\n") |
222 |
else: |
223 |
st = pp.pformat(result).split("\n") |
224 |
for s in st: |
225 |
MODULE.info(" >> %s" % s) |
226 |
# -------------------------------- |
227 |
|
173 |
self.finished(request.id,result) |
228 |
self.finished(request.id,result) |
174 |
|
229 |
|
175 |
def enable(self,request): |
230 |
def list_users(self,request): |
|
|
231 |
""" convenience function for the username entry. Lists |
232 |
all user names. We don't return this as an array of {id,label} |
233 |
tuples because: |
234 |
|
235 |
(1) id and label are always the same here |
236 |
(2) at the frontend, we must do some postprocessing, and an array |
237 |
is easier to handle. |
238 |
(3) the ComboBox is able to handle a plain array. |
239 |
""" |
240 |
|
241 |
# ----------- DEBUG ----------------- |
242 |
MODULE.info("printers/users/query invoked with:") |
243 |
pp = pprint.PrettyPrinter(indent=4) |
244 |
st = pp.pformat(request.options).split("\n") |
245 |
for s in st: |
246 |
MODULE.info(" << %s" % s) |
247 |
# ----------------------------------- |
248 |
|
249 |
result = [] |
250 |
expr = re.compile('^\s*username:\s*(.*?)\s*$') |
251 |
(stdout,stderr,status) = self._shell_command(['/usr/sbin/univention-directory-manager','users/user','list'],{'LANG':'C'}) |
252 |
if status == 0: |
253 |
for line in stdout.split("\n"): |
254 |
match = expr.match(line) |
255 |
if match: |
256 |
MODULE.warn(" -> %s" % match.group(1)) |
257 |
result.append(match.group(1)) |
258 |
|
259 |
# simulate 10000 more users |
260 |
for g in range(0,100): |
261 |
gn = 'group %d' % g |
262 |
for u in range(0,100): |
263 |
un = 'user %d' % u |
264 |
result.append('%s in %s' % (un,gn)) |
265 |
|
266 |
# ---------- DEBUG -------------- |
267 |
MODULE.info("printers/users/query returns:") |
268 |
pp = pprint.PrettyPrinter(indent=4) |
269 |
st = '' |
270 |
if len(result) > 5: |
271 |
tmp = result[0:5] |
272 |
MODULE.info(" >> %d entries, first 5 are:" % len(result)) |
273 |
st = pp.pformat(tmp).split("\n") |
274 |
else: |
275 |
st = pp.pformat(result).split("\n") |
276 |
for s in st: |
277 |
MODULE.info(" >> %s" % s) |
278 |
# -------------------------------- |
279 |
|
280 |
self.finished(request.id,result) |
281 |
|
282 |
def enable_printer(self,request): |
176 |
""" can enable or disable a printer, depending on args. |
283 |
""" can enable or disable a printer, depending on args. |
177 |
returns empty string on success, else error message. |
284 |
returns empty string on success, else error message. |
178 |
""" |
285 |
""" |
|
200 |
|
307 |
|
201 |
self.finished(request.id, result) |
308 |
self.finished(request.id, result) |
202 |
|
309 |
|
203 |
def cancel(self,request): |
310 |
def cancel_jobs(self,request): |
204 |
""" cancels one or more print jobs. Job IDs are passed |
311 |
""" cancels one or more print jobs. Job IDs are passed |
205 |
as an array that can be directly passed on to the |
312 |
as an array that can be directly passed on to the |
206 |
_shell_command() method |
313 |
_shell_command() method |
|
228 |
|
335 |
|
229 |
self.finished(request.id, result) |
336 |
self.finished(request.id, result) |
230 |
|
337 |
|
|
|
338 |
|
339 |
def set_quota(self,request): |
340 |
""" sets quota limits for a (printer,user) combination. |
341 |
optionally tries to create the corresponding user entry. |
342 |
""" |
343 |
|
344 |
# ----------- DEBUG ----------------- |
345 |
MODULE.info("printers/quota/set invoked with:") |
346 |
pp = pprint.PrettyPrinter(indent=4) |
347 |
st = pp.pformat(request.options).split("\n") |
348 |
for s in st: |
349 |
MODULE.info(" << %s" % s) |
350 |
# ----------------------------------- |
351 |
|
352 |
printer = request.options.get('printer','') |
353 |
user = request.options.get('user','') |
354 |
soft = request.options.get('soft',0) |
355 |
hard = request.options.get('hard',0) |
231 |
|
356 |
|
|
|
357 |
if printer=='' or user=='': |
358 |
result = "Required parameter missing" |
359 |
else: |
360 |
result = self._set_quota(printer,user,soft,hard) |
232 |
|
361 |
|
|
|
362 |
# ---------- DEBUG -------------- |
363 |
MODULE.info("printers/quota/set returns:") |
364 |
pp = pprint.PrettyPrinter(indent=4) |
365 |
st = pp.pformat(result).split("\n") |
366 |
for s in st: |
367 |
MODULE.info(" >> %s" % s) |
368 |
# -------------------------------- |
369 |
|
370 |
self.finished(request.id, result) |
371 |
|
372 |
|
373 |
def reset_quota(self,request): |
374 |
""" resets quota for a (printer,user) combination. |
375 |
""" |
376 |
|
377 |
# ----------- DEBUG ----------------- |
378 |
MODULE.info("printers/quota/reset invoked with:") |
379 |
pp = pprint.PrettyPrinter(indent=4) |
380 |
st = pp.pformat(request.options).split("\n") |
381 |
for s in st: |
382 |
MODULE.info(" << %s" % s) |
383 |
# ----------------------------------- |
384 |
|
385 |
printer = request.options.get('printer','') |
386 |
users = request.options.get('users',[]) |
387 |
|
388 |
result = self._reset_quota(printer,users) |
389 |
|
390 |
# ---------- DEBUG -------------- |
391 |
MODULE.info("printers/quota/reset returns:") |
392 |
pp = pprint.PrettyPrinter(indent=4) |
393 |
st = pp.pformat(result).split("\n") |
394 |
for s in st: |
395 |
MODULE.info(" >> %s" % s) |
396 |
# -------------------------------- |
397 |
|
398 |
self.finished(request.id, result) |
399 |
|
400 |
|
233 |
# ----------------------- Internal functions ------------------------- |
401 |
# ----------------------- Internal functions ------------------------- |
234 |
|
402 |
|
235 |
def _job_list(self,printer): |
403 |
def _job_list(self,printer): |
|
317 |
|
485 |
|
318 |
return '' |
486 |
return '' |
319 |
|
487 |
|
|
|
488 |
def _set_quota(self,printer,user,soft,hard): |
489 |
""" sets a quota entry. Can also add a user """ |
490 |
|
491 |
# Before we can set quota we have to ensure that the user is |
492 |
# already known to PyKota. Fortunately these tools don't complain |
493 |
# if we try to create a user that doesn't already exist. |
494 |
|
495 |
self._shell_command(['/usr/bin/pkusers','--skipexisting','--add',user],{'LANG':'C'}) |
496 |
|
497 |
# Caution! order of args is important! |
498 |
|
499 |
(stdout,stderr,status) = self._shell_command([ |
500 |
'/usr/bin/edpykota', |
501 |
'--printer',printer, |
502 |
'--softlimit',str(soft), |
503 |
'--hardlimit',str(hard), |
504 |
'--add',user |
505 |
],{'LANG':'C'}) |
506 |
|
507 |
# not all errors are propagated in exit codes... |
508 |
# but at least they adhere to the general rule that |
509 |
# progress is printed to STDOUT and errors/warnings to STDERR |
510 |
if status or len(stderr): |
511 |
return stderr |
512 |
|
513 |
return '' |
514 |
|
515 |
def _reset_quota(self,printer,users): |
516 |
""" resets the 'used' counter on a quota entry. """ |
517 |
|
518 |
cmd = [ '/usr/bin/edpykota','--printer',printer,'--reset' ] |
519 |
# appending user names to the args array -> spaces in user names |
520 |
# don't confuse edpykota (In 2.4, this was a problem) |
521 |
for user in users: |
522 |
cmd.append(user) |
523 |
(stdout,stderr,status) = self._shell_command(cmd,{'LANG':'C'}) |
524 |
|
525 |
if status or len(stderr): |
526 |
return stderr |
527 |
|
528 |
return '' |
529 |
|
320 |
def _quota_enabled(self,printer=None): |
530 |
def _quota_enabled(self,printer=None): |
321 |
""" returns a dictionary with printer names and their 'quota active' status. |
531 |
""" returns a dictionary with printer names and their 'quota active' status. |
322 |
if printer is specified, returns only quota status for this printer. |
532 |
if printer is specified, returns only quota status for this printer. |
|
363 |
outputs = proc.communicate() |
573 |
outputs = proc.communicate() |
364 |
|
574 |
|
365 |
return (outputs[0],outputs[1],proc.returncode) |
575 |
return (outputs[0],outputs[1],proc.returncode) |
366 |
|
576 |
|