Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r13706 - main/branches/prefix/pym/_emerge
Date: Sat, 27 Jun 2009 13:12:27
Message-Id: E1MKXhg-0006e7-OY@stork.gentoo.org
1 Author: grobian
2 Date: 2009-06-27 13:12:24 +0000 (Sat, 27 Jun 2009)
3 New Revision: 13706
4
5 Added:
6 main/branches/prefix/pym/_emerge/JobStatusDisplay.py
7 main/branches/prefix/pym/_emerge/UninstallFailure.py
8 main/branches/prefix/pym/_emerge/getloadavg.py
9 main/branches/prefix/pym/_emerge/stdout_spinner.py
10 Modified:
11 main/branches/prefix/pym/_emerge/__init__.py
12 Log:
13 Merged from trunk -r13666:13667
14
15 | 13667 | Bug #275047 - Split _emerge/__init__.py into smaller pieces |
16 | zmedico | (part 2). Thanks to Sebastian Mingramm (few) |
17 | | <s.mingramm@×××.de> for this patch. |
18
19
20 Copied: main/branches/prefix/pym/_emerge/JobStatusDisplay.py (from rev 13667, main/trunk/pym/_emerge/JobStatusDisplay.py)
21 ===================================================================
22 --- main/branches/prefix/pym/_emerge/JobStatusDisplay.py (rev 0)
23 +++ main/branches/prefix/pym/_emerge/JobStatusDisplay.py 2009-06-27 13:12:24 UTC (rev 13706)
24 @@ -0,0 +1,269 @@
25 +import formatter
26 +import os
27 +import sys
28 +import time
29 +
30 +try:
31 + from cStringIO import StringIO
32 +except ImportError:
33 + from StringIO import StringIO
34 +
35 +# for an explanation on this logic, see pym/_emerge/__init__.py
36 +import os
37 +import sys
38 +if os.environ.__contains__("PORTAGE_PYTHONPATH"):
39 + sys.path.insert(0, os.environ["PORTAGE_PYTHONPATH"])
40 +else:
41 + sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym"))
42 +import portage
43 +
44 +from portage.output import xtermTitle
45 +
46 +from _emerge.getloadavg import getloadavg
47 +
48 +class JobStatusDisplay(object):
49 +
50 + _bound_properties = ("curval", "failed", "running")
51 + _jobs_column_width = 48
52 +
53 + # Don't update the display unless at least this much
54 + # time has passed, in units of seconds.
55 + _min_display_latency = 2
56 +
57 + _default_term_codes = {
58 + 'cr' : '\r',
59 + 'el' : '\x1b[K',
60 + 'nel' : '\n',
61 + }
62 +
63 + _termcap_name_map = {
64 + 'carriage_return' : 'cr',
65 + 'clr_eol' : 'el',
66 + 'newline' : 'nel',
67 + }
68 +
69 + def __init__(self, out=sys.stdout, quiet=False, xterm_titles=True):
70 + object.__setattr__(self, "out", out)
71 + object.__setattr__(self, "quiet", quiet)
72 + object.__setattr__(self, "xterm_titles", xterm_titles)
73 + object.__setattr__(self, "maxval", 0)
74 + object.__setattr__(self, "merges", 0)
75 + object.__setattr__(self, "_changed", False)
76 + object.__setattr__(self, "_displayed", False)
77 + object.__setattr__(self, "_last_display_time", 0)
78 + object.__setattr__(self, "width", 80)
79 + self.reset()
80 +
81 + isatty = hasattr(out, "isatty") and out.isatty()
82 + object.__setattr__(self, "_isatty", isatty)
83 + if not isatty or not self._init_term():
84 + term_codes = {}
85 + for k, capname in self._termcap_name_map.iteritems():
86 + term_codes[k] = self._default_term_codes[capname]
87 + object.__setattr__(self, "_term_codes", term_codes)
88 + encoding = sys.getdefaultencoding()
89 + for k, v in self._term_codes.items():
90 + if not isinstance(v, basestring):
91 + self._term_codes[k] = v.decode(encoding, 'replace')
92 +
93 + def _init_term(self):
94 + """
95 + Initialize term control codes.
96 + @rtype: bool
97 + @returns: True if term codes were successfully initialized,
98 + False otherwise.
99 + """
100 +
101 + term_type = os.environ.get("TERM", "vt100")
102 + tigetstr = None
103 +
104 + try:
105 + import curses
106 + try:
107 + curses.setupterm(term_type, self.out.fileno())
108 + tigetstr = curses.tigetstr
109 + except curses.error:
110 + pass
111 + except ImportError:
112 + pass
113 +
114 + if tigetstr is None:
115 + return False
116 +
117 + term_codes = {}
118 + for k, capname in self._termcap_name_map.iteritems():
119 + code = tigetstr(capname)
120 + if code is None:
121 + code = self._default_term_codes[capname]
122 + term_codes[k] = code
123 + object.__setattr__(self, "_term_codes", term_codes)
124 + return True
125 +
126 + def _format_msg(self, msg):
127 + return ">>> %s" % msg
128 +
129 + def _erase(self):
130 + self.out.write(
131 + self._term_codes['carriage_return'] + \
132 + self._term_codes['clr_eol'])
133 + self.out.flush()
134 + self._displayed = False
135 +
136 + def _display(self, line):
137 + self.out.write(line)
138 + self.out.flush()
139 + self._displayed = True
140 +
141 + def _update(self, msg):
142 +
143 + out = self.out
144 + if not self._isatty:
145 + out.write(self._format_msg(msg) + self._term_codes['newline'])
146 + self.out.flush()
147 + self._displayed = True
148 + return
149 +
150 + if self._displayed:
151 + self._erase()
152 +
153 + self._display(self._format_msg(msg))
154 +
155 + def displayMessage(self, msg):
156 +
157 + was_displayed = self._displayed
158 +
159 + if self._isatty and self._displayed:
160 + self._erase()
161 +
162 + self.out.write(self._format_msg(msg) + self._term_codes['newline'])
163 + self.out.flush()
164 + self._displayed = False
165 +
166 + if was_displayed:
167 + self._changed = True
168 + self.display()
169 +
170 + def reset(self):
171 + self.maxval = 0
172 + self.merges = 0
173 + for name in self._bound_properties:
174 + object.__setattr__(self, name, 0)
175 +
176 + if self._displayed:
177 + self.out.write(self._term_codes['newline'])
178 + self.out.flush()
179 + self._displayed = False
180 +
181 + def __setattr__(self, name, value):
182 + old_value = getattr(self, name)
183 + if value == old_value:
184 + return
185 + object.__setattr__(self, name, value)
186 + if name in self._bound_properties:
187 + self._property_change(name, old_value, value)
188 +
189 + def _property_change(self, name, old_value, new_value):
190 + self._changed = True
191 + self.display()
192 +
193 + def _load_avg_str(self):
194 + try:
195 + avg = getloadavg()
196 + except OSError:
197 + return 'unknown'
198 +
199 + max_avg = max(avg)
200 +
201 + if max_avg < 10:
202 + digits = 2
203 + elif max_avg < 100:
204 + digits = 1
205 + else:
206 + digits = 0
207 +
208 + return ", ".join(("%%.%df" % digits ) % x for x in avg)
209 +
210 + def display(self):
211 + """
212 + Display status on stdout, but only if something has
213 + changed since the last call.
214 + """
215 +
216 + if self.quiet:
217 + return
218 +
219 + current_time = time.time()
220 + time_delta = current_time - self._last_display_time
221 + if self._displayed and \
222 + not self._changed:
223 + if not self._isatty:
224 + return
225 + if time_delta < self._min_display_latency:
226 + return
227 +
228 + self._last_display_time = current_time
229 + self._changed = False
230 + self._display_status()
231 +
232 + def _display_status(self):
233 + # Don't use len(self._completed_tasks) here since that also
234 + # can include uninstall tasks.
235 + curval_str = str(self.curval)
236 + maxval_str = str(self.maxval)
237 + running_str = str(self.running)
238 + failed_str = str(self.failed)
239 + load_avg_str = self._load_avg_str()
240 +
241 + color_output = StringIO()
242 + plain_output = StringIO()
243 + style_file = portage.output.ConsoleStyleFile(color_output)
244 + style_file.write_listener = plain_output
245 + style_writer = portage.output.StyleWriter(file=style_file, maxcol=9999)
246 + style_writer.style_listener = style_file.new_styles
247 + f = formatter.AbstractFormatter(style_writer)
248 +
249 + number_style = "INFORM"
250 + f.add_literal_data("Jobs: ")
251 + f.push_style(number_style)
252 + f.add_literal_data(curval_str)
253 + f.pop_style()
254 + f.add_literal_data(" of ")
255 + f.push_style(number_style)
256 + f.add_literal_data(maxval_str)
257 + f.pop_style()
258 + f.add_literal_data(" complete")
259 +
260 + if self.running:
261 + f.add_literal_data(", ")
262 + f.push_style(number_style)
263 + f.add_literal_data(running_str)
264 + f.pop_style()
265 + f.add_literal_data(" running")
266 +
267 + if self.failed:
268 + f.add_literal_data(", ")
269 + f.push_style(number_style)
270 + f.add_literal_data(failed_str)
271 + f.pop_style()
272 + f.add_literal_data(" failed")
273 +
274 + padding = self._jobs_column_width - len(plain_output.getvalue())
275 + if padding > 0:
276 + f.add_literal_data(padding * " ")
277 +
278 + f.add_literal_data("Load avg: ")
279 + f.add_literal_data(load_avg_str)
280 +
281 + # Truncate to fit width, to avoid making the terminal scroll if the
282 + # line overflows (happens when the load average is large).
283 + plain_output = plain_output.getvalue()
284 + if self._isatty and len(plain_output) > self.width:
285 + # Use plain_output here since it's easier to truncate
286 + # properly than the color output which contains console
287 + # color codes.
288 + self._update(plain_output[:self.width])
289 + else:
290 + self._update(color_output.getvalue())
291 +
292 + if self.xterm_titles:
293 + xtermTitle(" ".join(plain_output.split()))
294
295 Copied: main/branches/prefix/pym/_emerge/UninstallFailure.py (from rev 13667, main/trunk/pym/_emerge/UninstallFailure.py)
296 ===================================================================
297 --- main/branches/prefix/pym/_emerge/UninstallFailure.py (rev 0)
298 +++ main/branches/prefix/pym/_emerge/UninstallFailure.py 2009-06-27 13:12:24 UTC (rev 13706)
299 @@ -0,0 +1,19 @@
300 +# for an explanation on this logic, see pym/_emerge/__init__.py
301 +import os
302 +import sys
303 +if os.environ.__contains__("PORTAGE_PYTHONPATH"):
304 + sys.path.insert(0, os.environ["PORTAGE_PYTHONPATH"])
305 +else:
306 + sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym"))
307 +import portage
308 +
309 +class UninstallFailure(portage.exception.PortageException):
310 + """
311 + An instance of this class is raised by unmerge() when
312 + an uninstallation fails.
313 + """
314 + status = 1
315 + def __init__(self, *pargs):
316 + portage.exception.PortageException.__init__(self, pargs)
317 + if pargs:
318 + self.status = pargs[0]
319
320 Modified: main/branches/prefix/pym/_emerge/__init__.py
321 ===================================================================
322 --- main/branches/prefix/pym/_emerge/__init__.py 2009-06-27 13:02:34 UTC (rev 13705)
323 +++ main/branches/prefix/pym/_emerge/__init__.py 2009-06-27 13:12:24 UTC (rev 13706)
324 @@ -96,87 +96,11 @@
325 from _emerge.PollSelectAdapter import PollSelectAdapter
326 from _emerge.SequentialTaskQueue import SequentialTaskQueue
327 from _emerge.ProgressHandler import ProgressHandler
328 +from _emerge.stdout_spinner import stdout_spinner
329 +from _emerge.UninstallFailure import UninstallFailure
330 +from _emerge.JobStatusDisplay import JobStatusDisplay
331 +from _emerge.getloadavg import getloadavg
332
333 -try:
334 - from cStringIO import StringIO
335 -except ImportError:
336 - from StringIO import StringIO
337 -
338 -class stdout_spinner(object):
339 - scroll_msgs = [
340 - "Gentoo Rocks ("+platform.system()+")",
341 - "Thank you for using Gentoo. :)",
342 - "Are you actually trying to read this?",
343 - "How many times have you stared at this?",
344 - "We are generating the cache right now",
345 - "You are paying too much attention.",
346 - "A theory is better than its explanation.",
347 - "Phasers locked on target, Captain.",
348 - "Thrashing is just virtual crashing.",
349 - "To be is to program.",
350 - "Real Users hate Real Programmers.",
351 - "When all else fails, read the instructions.",
352 - "Functionality breeds Contempt.",
353 - "The future lies ahead.",
354 - "3.1415926535897932384626433832795028841971694",
355 - "Sometimes insanity is the only alternative.",
356 - "Inaccuracy saves a world of explanation.",
357 - ]
358 -
359 - twirl_sequence = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
360 -
361 - def __init__(self):
362 - self.spinpos = 0
363 - self.update = self.update_twirl
364 - self.scroll_sequence = self.scroll_msgs[
365 - int(time.time() * 100) % len(self.scroll_msgs)]
366 - self.last_update = 0
367 - self.min_display_latency = 0.05
368 -
369 - def _return_early(self):
370 - """
371 - Flushing ouput to the tty too frequently wastes cpu time. Therefore,
372 - each update* method should return without doing any output when this
373 - method returns True.
374 - """
375 - cur_time = time.time()
376 - if cur_time - self.last_update < self.min_display_latency:
377 - return True
378 - self.last_update = cur_time
379 - return False
380 -
381 - def update_basic(self):
382 - self.spinpos = (self.spinpos + 1) % 500
383 - if self._return_early():
384 - return
385 - if (self.spinpos % 100) == 0:
386 - if self.spinpos == 0:
387 - sys.stdout.write(". ")
388 - else:
389 - sys.stdout.write(".")
390 - sys.stdout.flush()
391 -
392 - def update_scroll(self):
393 - if self._return_early():
394 - return
395 - if(self.spinpos >= len(self.scroll_sequence)):
396 - sys.stdout.write(darkgreen(" \b\b\b" + self.scroll_sequence[
397 - len(self.scroll_sequence) - 1 - (self.spinpos % len(self.scroll_sequence))]))
398 - else:
399 - sys.stdout.write(green("\b " + self.scroll_sequence[self.spinpos]))
400 - sys.stdout.flush()
401 - self.spinpos = (self.spinpos + 1) % (2 * len(self.scroll_sequence))
402 -
403 - def update_twirl(self):
404 - self.spinpos = (self.spinpos + 1) % len(self.twirl_sequence)
405 - if self._return_early():
406 - return
407 - sys.stdout.write("\b\b " + self.twirl_sequence[self.spinpos])
408 - sys.stdout.flush()
409 -
410 - def update_quiet(self):
411 - return
412 -
413 def userquery(prompt, responses=None, colours=None):
414 """Displays a prompt and a set of responses, then waits for a response
415 which is checked against the responses and the first to match is
416 @@ -6600,29 +6524,6 @@
417 return select.poll()
418 return PollSelectAdapter()
419
420 -getloadavg = getattr(os, "getloadavg", None)
421 -if getloadavg is None:
422 - def getloadavg():
423 - """
424 - Uses /proc/loadavg to emulate os.getloadavg().
425 - Raises OSError if the load average was unobtainable.
426 - """
427 - try:
428 - loadavg_str = open('/proc/loadavg').readline()
429 - except IOError:
430 - # getloadavg() is only supposed to raise OSError, so convert
431 - raise OSError('unknown')
432 - loadavg_split = loadavg_str.split()
433 - if len(loadavg_split) < 3:
434 - raise OSError('unknown')
435 - loadavg_floats = []
436 - for i in xrange(3):
437 - try:
438 - loadavg_floats.append(float(loadavg_split[i]))
439 - except ValueError:
440 - raise OSError('unknown')
441 - return tuple(loadavg_floats)
442 -
443 class PollScheduler(object):
444
445 class _sched_iface_class(SlotObject):
446 @@ -6910,253 +6811,6 @@
447 def add(self, task):
448 self._queue.add(task)
449
450 -class JobStatusDisplay(object):
451 -
452 - _bound_properties = ("curval", "failed", "running")
453 - _jobs_column_width = 48
454 -
455 - # Don't update the display unless at least this much
456 - # time has passed, in units of seconds.
457 - _min_display_latency = 2
458 -
459 - _default_term_codes = {
460 - 'cr' : '\r',
461 - 'el' : '\x1b[K',
462 - 'nel' : '\n',
463 - }
464 -
465 - _termcap_name_map = {
466 - 'carriage_return' : 'cr',
467 - 'clr_eol' : 'el',
468 - 'newline' : 'nel',
469 - }
470 -
471 - def __init__(self, out=sys.stdout, quiet=False, xterm_titles=True):
472 - object.__setattr__(self, "out", out)
473 - object.__setattr__(self, "quiet", quiet)
474 - object.__setattr__(self, "xterm_titles", xterm_titles)
475 - object.__setattr__(self, "maxval", 0)
476 - object.__setattr__(self, "merges", 0)
477 - object.__setattr__(self, "_changed", False)
478 - object.__setattr__(self, "_displayed", False)
479 - object.__setattr__(self, "_last_display_time", 0)
480 - object.__setattr__(self, "width", 80)
481 - self.reset()
482 -
483 - isatty = hasattr(out, "isatty") and out.isatty()
484 - object.__setattr__(self, "_isatty", isatty)
485 - if not isatty or not self._init_term():
486 - term_codes = {}
487 - for k, capname in self._termcap_name_map.iteritems():
488 - term_codes[k] = self._default_term_codes[capname]
489 - object.__setattr__(self, "_term_codes", term_codes)
490 - encoding = sys.getdefaultencoding()
491 - for k, v in self._term_codes.items():
492 - if not isinstance(v, basestring):
493 - self._term_codes[k] = v.decode(encoding, 'replace')
494 -
495 - def _init_term(self):
496 - """
497 - Initialize term control codes.
498 - @rtype: bool
499 - @returns: True if term codes were successfully initialized,
500 - False otherwise.
501 - """
502 -
503 - term_type = os.environ.get("TERM", "vt100")
504 - tigetstr = None
505 -
506 - try:
507 - import curses
508 - try:
509 - curses.setupterm(term_type, self.out.fileno())
510 - tigetstr = curses.tigetstr
511 - except curses.error:
512 - pass
513 - except ImportError:
514 - pass
515 -
516 - if tigetstr is None:
517 - return False
518 -
519 - term_codes = {}
520 - for k, capname in self._termcap_name_map.iteritems():
521 - code = tigetstr(capname)
522 - if code is None:
523 - code = self._default_term_codes[capname]
524 - term_codes[k] = code
525 - object.__setattr__(self, "_term_codes", term_codes)
526 - return True
527 -
528 - def _format_msg(self, msg):
529 - return ">>> %s" % msg
530 -
531 - def _erase(self):
532 - self.out.write(
533 - self._term_codes['carriage_return'] + \
534 - self._term_codes['clr_eol'])
535 - self.out.flush()
536 - self._displayed = False
537 -
538 - def _display(self, line):
539 - self.out.write(line)
540 - self.out.flush()
541 - self._displayed = True
542 -
543 - def _update(self, msg):
544 -
545 - out = self.out
546 - if not self._isatty:
547 - out.write(self._format_msg(msg) + self._term_codes['newline'])
548 - self.out.flush()
549 - self._displayed = True
550 - return
551 -
552 - if self._displayed:
553 - self._erase()
554 -
555 - self._display(self._format_msg(msg))
556 -
557 - def displayMessage(self, msg):
558 -
559 - was_displayed = self._displayed
560 -
561 - if self._isatty and self._displayed:
562 - self._erase()
563 -
564 - self.out.write(self._format_msg(msg) + self._term_codes['newline'])
565 - self.out.flush()
566 - self._displayed = False
567 -
568 - if was_displayed:
569 - self._changed = True
570 - self.display()
571 -
572 - def reset(self):
573 - self.maxval = 0
574 - self.merges = 0
575 - for name in self._bound_properties:
576 - object.__setattr__(self, name, 0)
577 -
578 - if self._displayed:
579 - self.out.write(self._term_codes['newline'])
580 - self.out.flush()
581 - self._displayed = False
582 -
583 - def __setattr__(self, name, value):
584 - old_value = getattr(self, name)
585 - if value == old_value:
586 - return
587 - object.__setattr__(self, name, value)
588 - if name in self._bound_properties:
589 - self._property_change(name, old_value, value)
590 -
591 - def _property_change(self, name, old_value, new_value):
592 - self._changed = True
593 - self.display()
594 -
595 - def _load_avg_str(self):
596 - try:
597 - avg = getloadavg()
598 - except OSError:
599 - return 'unknown'
600 -
601 - max_avg = max(avg)
602 -
603 - if max_avg < 10:
604 - digits = 2
605 - elif max_avg < 100:
606 - digits = 1
607 - else:
608 - digits = 0
609 -
610 - return ", ".join(("%%.%df" % digits ) % x for x in avg)
611 -
612 - def display(self):
613 - """
614 - Display status on stdout, but only if something has
615 - changed since the last call.
616 - """
617 -
618 - if self.quiet:
619 - return
620 -
621 - current_time = time.time()
622 - time_delta = current_time - self._last_display_time
623 - if self._displayed and \
624 - not self._changed:
625 - if not self._isatty:
626 - return
627 - if time_delta < self._min_display_latency:
628 - return
629 -
630 - self._last_display_time = current_time
631 - self._changed = False
632 - self._display_status()
633 -
634 - def _display_status(self):
635 - # Don't use len(self._completed_tasks) here since that also
636 - # can include uninstall tasks.
637 - curval_str = str(self.curval)
638 - maxval_str = str(self.maxval)
639 - running_str = str(self.running)
640 - failed_str = str(self.failed)
641 - load_avg_str = self._load_avg_str()
642 -
643 - color_output = StringIO()
644 - plain_output = StringIO()
645 - style_file = portage.output.ConsoleStyleFile(color_output)
646 - style_file.write_listener = plain_output
647 - style_writer = portage.output.StyleWriter(file=style_file, maxcol=9999)
648 - style_writer.style_listener = style_file.new_styles
649 - f = formatter.AbstractFormatter(style_writer)
650 -
651 - number_style = "INFORM"
652 - f.add_literal_data("Jobs: ")
653 - f.push_style(number_style)
654 - f.add_literal_data(curval_str)
655 - f.pop_style()
656 - f.add_literal_data(" of ")
657 - f.push_style(number_style)
658 - f.add_literal_data(maxval_str)
659 - f.pop_style()
660 - f.add_literal_data(" complete")
661 -
662 - if self.running:
663 - f.add_literal_data(", ")
664 - f.push_style(number_style)
665 - f.add_literal_data(running_str)
666 - f.pop_style()
667 - f.add_literal_data(" running")
668 -
669 - if self.failed:
670 - f.add_literal_data(", ")
671 - f.push_style(number_style)
672 - f.add_literal_data(failed_str)
673 - f.pop_style()
674 - f.add_literal_data(" failed")
675 -
676 - padding = self._jobs_column_width - len(plain_output.getvalue())
677 - if padding > 0:
678 - f.add_literal_data(padding * " ")
679 -
680 - f.add_literal_data("Load avg: ")
681 - f.add_literal_data(load_avg_str)
682 -
683 - # Truncate to fit width, to avoid making the terminal scroll if the
684 - # line overflows (happens when the load average is large).
685 - plain_output = plain_output.getvalue()
686 - if self._isatty and len(plain_output) > self.width:
687 - # Use plain_output here since it's easier to truncate
688 - # properly than the color output which contains console
689 - # color codes.
690 - self._update(plain_output[:self.width])
691 - else:
692 - self._update(color_output.getvalue())
693 -
694 - if self.xterm_titles:
695 - xtermTitle(" ".join(plain_output.split()))
696 -
697 class Scheduler(PollScheduler):
698
699 _opts_ignore_blockers = \
700 @@ -8907,17 +8561,6 @@
701
702 self._schedule()
703
704 -class UninstallFailure(portage.exception.PortageException):
705 - """
706 - An instance of this class is raised by unmerge() when
707 - an uninstallation fails.
708 - """
709 - status = 1
710 - def __init__(self, *pargs):
711 - portage.exception.PortageException.__init__(self, pargs)
712 - if pargs:
713 - self.status = pargs[0]
714 -
715 def unmerge(root_config, myopts, unmerge_action,
716 unmerge_files, ldpath_mtimes, autoclean=0,
717 clean_world=1, clean_delay=1, ordered=0, raise_on_error=0,
718
719 Copied: main/branches/prefix/pym/_emerge/getloadavg.py (from rev 13667, main/trunk/pym/_emerge/getloadavg.py)
720 ===================================================================
721 --- main/branches/prefix/pym/_emerge/getloadavg.py (rev 0)
722 +++ main/branches/prefix/pym/_emerge/getloadavg.py 2009-06-27 13:12:24 UTC (rev 13706)
723 @@ -0,0 +1,24 @@
724 +import os
725 +
726 +getloadavg = getattr(os, "getloadavg", None)
727 +if getloadavg is None:
728 + def getloadavg():
729 + """
730 + Uses /proc/loadavg to emulate os.getloadavg().
731 + Raises OSError if the load average was unobtainable.
732 + """
733 + try:
734 + loadavg_str = open('/proc/loadavg').readline()
735 + except IOError:
736 + # getloadavg() is only supposed to raise OSError, so convert
737 + raise OSError('unknown')
738 + loadavg_split = loadavg_str.split()
739 + if len(loadavg_split) < 3:
740 + raise OSError('unknown')
741 + loadavg_floats = []
742 + for i in xrange(3):
743 + try:
744 + loadavg_floats.append(float(loadavg_split[i]))
745 + except ValueError:
746 + raise OSError('unknown')
747 + return tuple(loadavg_floats)
748
749 Copied: main/branches/prefix/pym/_emerge/stdout_spinner.py (from rev 13667, main/trunk/pym/_emerge/stdout_spinner.py)
750 ===================================================================
751 --- main/branches/prefix/pym/_emerge/stdout_spinner.py (rev 0)
752 +++ main/branches/prefix/pym/_emerge/stdout_spinner.py 2009-06-27 13:12:24 UTC (rev 13706)
753 @@ -0,0 +1,80 @@
754 +import platform
755 +import sys
756 +import time
757 +
758 +from portage.output import darkgreen, green
759 +
760 +class stdout_spinner(object):
761 + scroll_msgs = [
762 + "Gentoo Rocks ("+platform.system()+")",
763 + "Thank you for using Gentoo. :)",
764 + "Are you actually trying to read this?",
765 + "How many times have you stared at this?",
766 + "We are generating the cache right now",
767 + "You are paying too much attention.",
768 + "A theory is better than its explanation.",
769 + "Phasers locked on target, Captain.",
770 + "Thrashing is just virtual crashing.",
771 + "To be is to program.",
772 + "Real Users hate Real Programmers.",
773 + "When all else fails, read the instructions.",
774 + "Functionality breeds Contempt.",
775 + "The future lies ahead.",
776 + "3.1415926535897932384626433832795028841971694",
777 + "Sometimes insanity is the only alternative.",
778 + "Inaccuracy saves a world of explanation.",
779 + ]
780 +
781 + twirl_sequence = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
782 +
783 + def __init__(self):
784 + self.spinpos = 0
785 + self.update = self.update_twirl
786 + self.scroll_sequence = self.scroll_msgs[
787 + int(time.time() * 100) % len(self.scroll_msgs)]
788 + self.last_update = 0
789 + self.min_display_latency = 0.05
790 +
791 + def _return_early(self):
792 + """
793 + Flushing ouput to the tty too frequently wastes cpu time. Therefore,
794 + each update* method should return without doing any output when this
795 + method returns True.
796 + """
797 + cur_time = time.time()
798 + if cur_time - self.last_update < self.min_display_latency:
799 + return True
800 + self.last_update = cur_time
801 + return False
802 +
803 + def update_basic(self):
804 + self.spinpos = (self.spinpos + 1) % 500
805 + if self._return_early():
806 + return
807 + if (self.spinpos % 100) == 0:
808 + if self.spinpos == 0:
809 + sys.stdout.write(". ")
810 + else:
811 + sys.stdout.write(".")
812 + sys.stdout.flush()
813 +
814 + def update_scroll(self):
815 + if self._return_early():
816 + return
817 + if(self.spinpos >= len(self.scroll_sequence)):
818 + sys.stdout.write(darkgreen(" \b\b\b" + self.scroll_sequence[
819 + len(self.scroll_sequence) - 1 - (self.spinpos % len(self.scroll_sequence))]))
820 + else:
821 + sys.stdout.write(green("\b " + self.scroll_sequence[self.spinpos]))
822 + sys.stdout.flush()
823 + self.spinpos = (self.spinpos + 1) % (2 * len(self.scroll_sequence))
824 +
825 + def update_twirl(self):
826 + self.spinpos = (self.spinpos + 1) % len(self.twirl_sequence)
827 + if self._return_early():
828 + return
829 + sys.stdout.write("\b\b " + self.twirl_sequence[self.spinpos])
830 + sys.stdout.flush()
831 +
832 + def update_quiet(self):
833 + return