Changeset 516 for yum/trunk/output.py
Legend:
- Unmodified
- Added
- Removed
-
yum/trunk
-
Property svn:mergeinfo
set to
/yum/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
yum/trunk/output.py
r2 r516 39 39 from yum.constants import * 40 40 41 from yum import logginglevels, _ 41 from yum import logginglevels, _, P_ 42 42 from yum.rpmtrans import RPMBaseCallback 43 43 from yum.packageSack import packagesNewestByNameArch 44 44 import yum.packages 45 46 import yum.history 45 47 46 48 from yum.i18n import utf8_width, utf8_width_fill, utf8_text_fill … … 380 382 data[d] = sorted(pdata[d].items()) 381 383 384 # We start allocating 1 char to everything but the last column, and a 385 # space between each (again, except for the last column). Because 386 # at worst we are better with: 387 # |one two three| 388 # | four | 389 # ...than: 390 # |one two three| 391 # | f| 392 # |our | 393 # ...the later being what we get if we pre-allocate the last column, and 394 # thus. the space, due to "three" overflowing it's column by 2 chars. 382 395 if columns is None: 383 columns = [1] * cols 396 columns = [1] * (cols - 1) 397 columns.append(0) 384 398 385 399 total_width -= (sum(columns) + (cols - 1) + utf8_width(indent)) 400 if not columns[-1]: 401 total_width += 1 386 402 while total_width > 0: 387 403 # Find which field all the spaces left will help best … … 407 423 if helps: 408 424 diff = data[val].pop(0)[0] - columns[val] 425 if not columns[val] and (val == (cols - 1)): 426 # If we are going from 0 => N on the last column, take 1 427 # for the space before the column. 428 total_width -= 1 409 429 columns[val] += diff 410 430 total_width -= diff … … 453 473 return (val, width, hibeg, hiend) 454 474 455 def fmtColumns(self, columns, msg=u'', end=u''): 456 """ Return a string for columns of data, which can overflow.""" 475 def fmtColumns(self, columns, msg=u'', end=u'', text_width=utf8_width): 476 """ Return a string for columns of data, which can overflow. 477 text_width parameter finds the width of columns, this defaults to 478 utf8 but can be changed to len() if you know it'll be fine. """ 457 479 458 480 total_width = len(msg) … … 467 489 468 490 (align, width) = self._fmt_column_align_width(width) 469 if utf8_width(val) <= width: 470 msg += u"%s " 471 val = utf8_width_fill(val, width, left=(align == u'-'), 472 prefix=hibeg, suffix=hiend) 473 data.append(val) 491 val_width = text_width(val) 492 if val_width <= width: 493 # Don't use utf8_width_fill() because it sucks performance 494 # wise for 1,000s of rows. Also allows us to use len(), when 495 # we can. 496 msg += u"%s%s%s%s " 497 if (align == u'-'): 498 data.extend([hibeg, val, " " * (width - val_width), hiend]) 499 else: 500 data.extend([hibeg, " " * (width - val_width), val, hiend]) 474 501 else: 475 502 msg += u"%s%s%s\n" + " " * (total_width + width + 1) … … 496 523 rid = pkg.ui_from_repo 497 524 columns = zip((na, ver, rid), columns, hi_cols) 498 print self.fmtColumns(columns )525 print self.fmtColumns(columns, text_width=len) 499 526 500 527 def simpleEnvraList(self, pkg, ui_overflow=False, … … 509 536 rid = pkg.ui_from_repo 510 537 columns = zip((envra, rid), columns, hi_cols) 511 print self.fmtColumns(columns )538 print self.fmtColumns(columns, text_width=len) 512 539 513 540 def fmtKeyValFill(self, key, val): … … 552 579 def infoOutput(self, pkg, highlight=False): 553 580 (hibeg, hiend) = self._highlight(highlight) 554 print _("Name : %s%s%s") % (hibeg, to_unicode(pkg.name), hiend)555 print _("Arch : %s") % to_unicode(pkg.arch)581 print _("Name : %s%s%s") % (hibeg, to_unicode(pkg.name), hiend) 582 print _("Arch : %s") % to_unicode(pkg.arch) 556 583 if pkg.epoch != "0": 557 print _("Epoch : %s") % to_unicode(pkg.epoch)558 print _("Version : %s") % to_unicode(pkg.version)559 print _("Release : %s") % to_unicode(pkg.release)560 print _("Size : %s") % self.format_number(float(pkg.size))561 print _("Repo : %s") % to_unicode(pkg.repoid)584 print _("Epoch : %s") % to_unicode(pkg.epoch) 585 print _("Version : %s") % to_unicode(pkg.version) 586 print _("Release : %s") % to_unicode(pkg.release) 587 print _("Size : %s") % self.format_number(float(pkg.size)) 588 print _("Repo : %s") % to_unicode(pkg.repoid) 562 589 if pkg.repoid == 'installed' and 'from_repo' in pkg.yumdb_info: 563 print _("From repo : %s") % to_unicode(pkg.yumdb_info.from_repo)590 print _("From repo : %s") % to_unicode(pkg.yumdb_info.from_repo) 564 591 if self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3): 565 print _("Committer : %s") % to_unicode(pkg.committer)566 print _("Committime : %s") % time.ctime(pkg.committime)567 print _("Buildtime : %s") % time.ctime(pkg.buildtime)592 print _("Committer : %s") % to_unicode(pkg.committer) 593 print _("Committime : %s") % time.ctime(pkg.committime) 594 print _("Buildtime : %s") % time.ctime(pkg.buildtime) 568 595 if hasattr(pkg, 'installtime'): 569 print _("Installtime: %s") % time.ctime(pkg.installtime) 570 print self.fmtKeyValFill(_("Summary : "), self._enc(pkg.summary)) 596 print _("Install time: %s") % time.ctime(pkg.installtime) 597 if pkg.repoid == 'installed': 598 uid = None 599 if 'installed_by' in pkg.yumdb_info: 600 try: 601 uid = int(pkg.yumdb_info.installed_by) 602 except ValueError: # In case int() fails 603 uid = None 604 print _("Installed by: %s") % self._pwd_ui_username(uid) 605 uid = None 606 if 'changed_by' in pkg.yumdb_info: 607 try: 608 uid = int(pkg.yumdb_info.changed_by) 609 except ValueError: # In case int() fails 610 uid = None 611 print _("Changed by : %s") % self._pwd_ui_username(uid) 612 print self.fmtKeyValFill(_("Summary : "), self._enc(pkg.summary)) 571 613 if pkg.url: 572 print _("URL : %s") % to_unicode(pkg.url)573 print self.fmtKeyValFill(_("License : "), to_unicode(pkg.license))574 print self.fmtKeyValFill(_("Description : "),self._enc(pkg.description))614 print _("URL : %s") % to_unicode(pkg.url) 615 print self.fmtKeyValFill(_("License : "), to_unicode(pkg.license)) 616 print self.fmtKeyValFill(_("Description : "),self._enc(pkg.description)) 575 617 print "" 576 618 … … 743 785 if group.ui_description: 744 786 print _(' Description: %s') % to_unicode(group.ui_description) 787 if group.langonly: 788 print _(' Language: %s') % group.langonly 745 789 746 790 sections = ((_(' Mandatory Packages:'), group.mandatory_packages), … … 766 810 """take a list of findDeps results and 'pretty print' the output""" 767 811 768 for pkg in results: 812 verb = self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3) 813 for pkg in sorted(results): 769 814 print _("package: %s") % pkg.compactPrint() 770 815 if len(results[pkg]) == 0: … … 772 817 continue 773 818 774 for req in results[pkg]:819 for req in sorted(results[pkg]): 775 820 reqlist = results[pkg][req] 776 821 print _(" dependency: %s") % prco_tuple_to_string(req) … … 779 824 continue 780 825 781 for po in reqlist: 826 seen = {} 827 for po in reversed(sorted(reqlist)): 828 key = (po.name, po.arch) 829 if not verb and key in seen: 830 continue 831 seen[key] = po 782 832 print " provider: %s" % po.compactPrint() 783 833 … … 848 898 return 849 899 850 print _("Repo : %s") % po. repoid851 print _('Matched from:')900 print _("Repo : %s") % po.ui_from_repo 901 done = False 852 902 for item in yum.misc.unique(values): 853 903 item = to_utf8(item) … … 855 905 continue # Skip double name/summary printing 856 906 907 if not done: 908 print _('Matched from:') 909 done = True 857 910 can_overflow = True 858 911 if False: pass … … 928 981 _("Installed size: %s"), 929 982 self.format_number(insize)) 983 984 def reportRemoveSize(self, packages): 985 """Report the total size of packages being removed. """ 986 totsize = 0 987 error = False 988 for pkg in packages: 989 # Just to be on the safe side, if for some reason getting 990 # the package size fails, log the error and don't report download 991 # size 992 try: 993 size = int(pkg.size) 994 totsize += size 995 except: 996 error = True 997 self.logger.error(_('There was an error calculating installed size')) 998 break 999 if (not error): 1000 self.verbose_logger.log(logginglevels.INFO_1, 1001 _("Installed size: %s"), 1002 self.format_number(totsize)) 930 1003 931 1004 def listTransaction(self): … … 979 1052 980 1053 for (action, pkglist) in [(_('Skipped (dependency problems)'), 981 self.skipped_packages),]: 1054 self.skipped_packages), 1055 (_('Not installed'), self._not_found_i.values()), 1056 (_('Not available'), self._not_found_a.values())]: 982 1057 lines = [] 983 1058 for po in pkglist: … … 1024 1099 out.append(totalmsg) 1025 1100 1026 summary =_("""1101 out.append(_(""" 1027 1102 Transaction Summary 1028 1103 %s 1029 """) % ('=' * self.term.columns,) 1030 out.append(summary) 1031 num_in = len(self.tsInfo.installed + self.tsInfo.depinstalled) 1032 num_up = len(self.tsInfo.updated + self.tsInfo.depupdated) 1033 summary = _("""\ 1034 Install %5.5s Package(s) 1035 Upgrade %5.5s Package(s) 1036 """) % (num_in, num_up,) 1037 if num_in or num_up: # Always do this? 1038 out.append(summary) 1039 num_rm = len(self.tsInfo.removed + self.tsInfo.depremoved) 1040 num_re = len(self.tsInfo.reinstalled) 1041 num_dg = len(self.tsInfo.downgraded) 1042 summary = _("""\ 1043 Remove %5.5s Package(s) 1044 Reinstall %5.5s Package(s) 1045 Downgrade %5.5s Package(s) 1046 """) % (num_rm, num_re, num_dg) 1047 if num_rm or num_re or num_dg: 1048 out.append(summary) 1049 1104 """) % ('=' * self.term.columns)) 1105 for action, count in ( 1106 (_('Install'), len(self.tsInfo.installed) + len(self.tsInfo.depinstalled)), 1107 (_('Upgrade'), len(self.tsInfo.updated) + len(self.tsInfo.depupdated)), 1108 (_('Remove'), len(self.tsInfo.removed) + len(self.tsInfo.depremoved)), 1109 (_('Reinstall'), len(self.tsInfo.reinstalled)), 1110 (_('Downgrade'), len(self.tsInfo.downgraded)), 1111 ): 1112 if count: out.append('%-9s %5d %s\n' % ( 1113 action, count, P_('Package', 'Packages', count), 1114 )) 1050 1115 return ''.join(out) 1051 1116 … … 1122 1187 # One of these is a download 1123 1188 if self.conf.debuglevel < 2 or not sys.stdout.isatty(): 1124 self.repos.setProgressBar(None)1125 self.repos.callback = None1189 progressbar = None 1190 callback = None 1126 1191 else: 1127 self.repos.setProgressBar(YumTextMeter(fo=sys.stdout))1128 self.repos.callback = CacheProgressCallback()1192 progressbar = YumTextMeter(fo=sys.stdout) 1193 callback = CacheProgressCallback() 1129 1194 1130 1195 # setup our failure report for failover 1131 1196 freport = (self.failureReport,(),{}) 1132 self.repos.setFailureCallback(freport)1197 failure_callback = freport 1133 1198 1134 1199 # setup callback for CTRL-C's 1135 self.repos.setInterruptCallback(self.interrupt_callback) 1136 1200 interrupt_callback = self.interrupt_callback 1201 if hasattr(self, 'prerepoconf'): 1202 self.prerepoconf.progressbar = progressbar 1203 self.prerepoconf.callback = callback 1204 self.prerepoconf.failure_callback = failure_callback 1205 self.prerepoconf.interrupt_callback = interrupt_callback 1206 else: 1207 # Just in case some API user decides to do self.repos before 1208 # calling us. 1209 self.repos.setProgressBar(progressbar) 1210 self.repos.callback = callback 1211 self.repos.setFailureCallback(failure_callback) 1212 self.repos.setInterruptCallback(interrupt_callback) 1213 1137 1214 # setup our depsolve progress callback 1138 1215 dscb = DepSolveProgressCallBack(weakref(self)) … … 1144 1221 1145 1222 def setupKeyImportCallbacks(self): 1146 self.repos.confirm_func = self._cli_confirm_gpg_key_import 1147 self.repos.gpg_import_func = self.getKeyForRepo 1223 confirm_func = self._cli_confirm_gpg_key_import 1224 gpg_import_func = self.getKeyForRepo 1225 gpgca_import_func = self.getCAKeyForRepo 1226 if hasattr(self, 'prerepoconf'): 1227 self.prerepoconf.confirm_func = confirm_func 1228 self.prerepoconf.gpg_import_func = gpg_import_func 1229 self.prerepoconf.gpgca_import_func = gpgca_import_func 1230 else: 1231 self.repos.confirm_func = confirm_func 1232 self.repos.gpg_import_func = gpg_import_func 1233 self.repos.gpgca_import_func = gpgca_import_func 1148 1234 1149 1235 def interrupt_callback(self, cbobj): … … 1233 1319 1234 1320 def _pwd_ui_username(self, uid, limit=None): 1235 # loginuid is set to -1 on init. 1236 if uid is None or uid == 0xFFFFFFFF: 1321 if type(uid) == type([]): 1322 return [self._pwd_ui_username(u, limit) for u in uid] 1323 1324 # loginuid is set to -1 (0xFFFF_FFFF) on init, in newer kernels. 1325 # loginuid is set to INT_MAX (0x7FFF_FFFF) on init, in older kernels. 1326 if uid is None or uid in (0xFFFFFFFF, 0x7FFFFFFF): 1237 1327 loginid = _("<unset>") 1238 1328 name = _("System") + " " + loginid … … 1241 1331 return to_unicode(name) 1242 1332 1333 def _safe_split_0(text, *args): 1334 """ Split gives us a [0] for everything _but_ '', this function 1335 returns '' in that case. """ 1336 ret = text.split(*args) 1337 if not ret: 1338 return '' 1339 return ret[0] 1340 1243 1341 try: 1244 1342 user = pwd.getpwuid(uid) 1245 fullname = user.pw_gecos.split(';', 2)[0]1343 fullname = _safe_split_0(user.pw_gecos, ';', 2) 1246 1344 name = "%s <%s>" % (fullname, user.pw_name) 1247 1345 if limit is not None and len(name) > limit: 1248 name = "%s ... <%s>" % ( fullname.split()[0], user.pw_name)1346 name = "%s ... <%s>" % (_safe_split_0(fullname), user.pw_name) 1249 1347 if len(name) > limit: 1250 1348 name = "<%s>" % user.pw_name … … 1253 1351 return to_unicode(str(uid)) 1254 1352 1353 @staticmethod 1354 def _historyRangeRTIDs(old, tid): 1355 ''' Convert a user "TID" string of 2..4 into: (2, 4). ''' 1356 def str2int(x): 1357 try: 1358 if x == 'last' or x.startswith('last-'): 1359 tid = old.tid 1360 if x.startswith('last-'): 1361 off = int(x[len('last-'):]) 1362 if off <= 0: 1363 int("z") 1364 tid -= off 1365 return tid 1366 return int(x) 1367 except ValueError: 1368 return None 1369 1370 if '..' not in tid: 1371 return None 1372 btid, etid = tid.split('..', 2) 1373 btid = str2int(btid) 1374 if btid > old.tid: 1375 return None 1376 elif btid <= 0: 1377 return None 1378 etid = str2int(etid) 1379 if etid > old.tid: 1380 return None 1381 1382 if btid is None or etid is None: 1383 return None 1384 1385 # Have a range ... do a "merged" transaction. 1386 if btid > etid: 1387 btid, etid = etid, btid 1388 return (btid, etid) 1389 1390 def _historyRangeTIDs(self, rtids): 1391 ''' Convert a list of ranged tid typles into all the tids needed, Eg. 1392 [(2,4), (6,8)] == [2, 3, 4, 6, 7, 8]. ''' 1393 tids = set() 1394 last_end = -1 # This just makes displaying it easier... 1395 for mtid in sorted(rtids): 1396 if mtid[0] < last_end: 1397 self.logger.warn(_('Skipping merged transaction %d to %d, as it overlaps' % (mtid[0], mtid[1]))) 1398 continue # Don't do overlapping 1399 last_end = mtid[1] 1400 for num in range(mtid[0], mtid[1] + 1): 1401 tids.add(num) 1402 return tids 1403 1255 1404 def _history_list_transactions(self, extcmds): 1405 old = self.history.last() 1406 if old is None: 1407 self.logger.critical(_('No transactions')) 1408 return None, None 1409 1256 1410 tids = set() 1257 1411 pats = [] … … 1267 1421 tids.add(tid) 1268 1422 except ValueError: 1423 rtid = self._historyRangeRTIDs(old, tid) 1424 if rtid: 1425 tids.update(self._historyRangeTIDs([rtid])) 1426 continue 1269 1427 pats.append(tid) 1270 1428 if pats: … … 1281 1439 tids, printall = self._history_list_transactions(extcmds) 1282 1440 if tids is None: 1283 return 1, ['Failed history info'] 1441 return 1, ['Failed history list'] 1442 1443 limit = 20 1444 if printall: 1445 limit = None 1446 1447 old_tids = self.history.old(tids, limit=limit) 1448 done = 0 1449 if self.conf.history_list_view == 'users': 1450 uids = [1,2] 1451 elif self.conf.history_list_view == 'commands': 1452 uids = [1] 1453 else: 1454 assert self.conf.history_list_view == 'single-user-commands' 1455 uids = set() 1456 blanks = 0 1457 for old in old_tids: 1458 if not printall and done >= limit: 1459 break 1460 1461 done += 1 1462 if old.cmdline is None: 1463 blanks += 1 1464 uids.add(old.loginuid) 1465 if len(uids) == 1 and blanks > (done / 2): 1466 uids.add('blah') 1284 1467 1285 1468 fmt = "%s | %s | %s | %s | %s" 1469 if len(uids) == 1: 1470 name = _("Command line") 1471 else: 1472 name = _("Login user") 1286 1473 print fmt % (utf8_width_fill(_("ID"), 6, 6), 1287 utf8_width_fill( _("Login user"), 22, 22),1474 utf8_width_fill(name, 24, 24), 1288 1475 utf8_width_fill(_("Date and time"), 16, 16), 1289 1476 utf8_width_fill(_("Action(s)"), 14, 14), … … 1292 1479 fmt = "%6u | %s | %-16.16s | %s | %4u" 1293 1480 done = 0 1294 limit = 20 1295 if printall: 1296 limit = None 1297 for old in self.history.old(tids, limit=limit): 1481 for old in old_tids: 1298 1482 if not printall and done >= limit: 1299 1483 break 1300 1484 1301 1485 done += 1 1302 name = self._pwd_ui_username(old.loginuid, 22) 1486 if len(uids) == 1: 1487 name = old.cmdline or '' 1488 else: 1489 name = self._pwd_ui_username(old.loginuid, 24) 1303 1490 tm = time.strftime("%Y-%m-%d %H:%M", 1304 1491 time.localtime(old.beg_timestamp)) 1305 1492 num, uiacts = self._history_uiactions(old.trans_data) 1306 name = utf8_width_fill(name, 2 2, 22)1493 name = utf8_width_fill(name, 24, 24) 1307 1494 uiacts = utf8_width_fill(uiacts, 14, 14) 1308 1495 rmark = lmark = ' ' … … 1311 1498 elif old.return_code: 1312 1499 rmark = lmark = '#' 1500 # We don't check .errors, because return_code will be non-0 1501 elif old.output: 1502 rmark = lmark = 'E' 1503 elif old.rpmdb_problems: 1504 rmark = lmark = 'P' 1505 elif old.trans_skip: 1506 rmark = lmark = 's' 1313 1507 if old.altered_lt_rpmdb: 1314 1508 rmark = '<' … … 1371 1565 1372 1566 def historyInfoCmd(self, extcmds): 1567 def str2int(x): 1568 try: 1569 return int(x) 1570 except ValueError: 1571 return None 1572 1373 1573 tids = set() 1574 mtids = set() 1374 1575 pats = [] 1576 old = self.history.last() 1577 if old is None: 1578 self.logger.critical(_('No transactions')) 1579 return 1, ['Failed history info'] 1580 1375 1581 for tid in extcmds[1:]: 1376 try: 1377 int(tid) 1378 tids.add(tid) 1379 except ValueError: 1380 pats.append(tid) 1582 if self._historyRangeRTIDs(old, tid): 1583 # Have a range ... do a "merged" transaction. 1584 mtids.add(self._historyRangeRTIDs(old, tid)) 1585 continue 1586 elif str2int(tid) is not None: 1587 tids.add(str2int(tid)) 1588 continue 1589 pats.append(tid) 1381 1590 if pats: 1382 1591 tids.update(self.history.search(pats)) 1592 utids = tids.copy() 1593 if mtids: 1594 mtids = sorted(mtids) 1595 tids.update(self._historyRangeTIDs(mtids)) 1383 1596 1384 1597 if not tids and len(extcmds) < 2: … … 1386 1599 if old is not None: 1387 1600 tids.add(old.tid) 1601 utids.add(old.tid) 1388 1602 1389 1603 if not tids: … … 1397 1611 1398 1612 done = False 1613 bmtid, emtid = -1, -1 1614 mobj = None 1615 if mtids: 1616 bmtid, emtid = mtids.pop(0) 1399 1617 for tid in self.history.old(tids): 1400 1618 if lastdbv is not None and tid.tid == lasttid: … … 1406 1624 lastdbv = None 1407 1625 1626 if tid.tid >= bmtid and tid.tid <= emtid: 1627 if mobj is None: 1628 mobj = yum.history.YumMergedHistoryTransaction(tid) 1629 else: 1630 mobj.merge(tid) 1631 elif mobj is not None: 1632 if done: 1633 print "-" * 79 1634 done = True 1635 1636 self._historyInfoCmd(mobj) 1637 mobj = None 1638 if mtids: 1639 bmtid, emtid = mtids.pop(0) 1640 if tid.tid >= bmtid and tid.tid <= emtid: 1641 mobj = yum.history.YumMergedHistoryTransaction(tid) 1642 1643 if tid.tid in utids: 1644 if done: 1645 print "-" * 79 1646 done = True 1647 1648 self._historyInfoCmd(tid, pats) 1649 1650 if mobj is not None: 1408 1651 if done: 1409 1652 print "-" * 79 1410 done = True 1411 self._historyInfoCmd(tid, pats) 1653 1654 self._historyInfoCmd(mobj) 1655 1656 def _hpkg2from_repo(self, hpkg): 1657 """ Given a pkg, find the ipkg.ui_from_repo ... if none, then 1658 get an apkg. ... and put a ? in there. """ 1659 ipkgs = self.rpmdb.searchPkgTuple(hpkg.pkgtup) 1660 if not ipkgs: 1661 apkgs = self.pkgSack.searchPkgTuple(hpkg.pkgtup) 1662 if not apkgs: 1663 return '?' 1664 return '@?' + str(apkgs[0].repoid) 1665 1666 return ipkgs[0].ui_from_repo 1412 1667 1413 1668 def _historyInfoCmd(self, old, pats=[]): 1414 1669 name = self._pwd_ui_username(old.loginuid) 1415 1670 1416 print _("Transaction ID :"), old.tid 1671 _pkg_states_installed = {'i' : _('Installed'), 'e' : _('Erased'), 1672 'o' : _('Updated'), 'n' : _('Downgraded')} 1673 _pkg_states_available = {'i' : _('Installed'), 'e' : _('Not installed'), 1674 'o' : _('Older'), 'n' : _('Newer')} 1675 # max() only in 2.5.z 1676 maxlen = sorted([len(x) for x in (_pkg_states_installed.values() + 1677 _pkg_states_available.values())])[-1] 1678 _pkg_states_installed['maxlen'] = maxlen 1679 _pkg_states_available['maxlen'] = maxlen 1680 def _simple_pkg(pkg, prefix_len, was_installed=False, highlight=False, 1681 pkg_max_len=0): 1682 prefix = " " * prefix_len 1683 if was_installed: 1684 _pkg_states = _pkg_states_installed 1685 else: 1686 _pkg_states = _pkg_states_available 1687 state = _pkg_states['i'] 1688 ipkgs = self.rpmdb.searchNames([hpkg.name]) 1689 ipkgs.sort() 1690 if not ipkgs: 1691 state = _pkg_states['e'] 1692 elif hpkg.pkgtup in (ipkg.pkgtup for ipkg in ipkgs): 1693 pass 1694 elif ipkgs[-1] > hpkg: 1695 state = _pkg_states['o'] 1696 elif ipkgs[0] < hpkg: 1697 state = _pkg_states['n'] 1698 else: 1699 assert False, "Impossible, installed not newer and not older" 1700 if highlight: 1701 (hibeg, hiend) = self._highlight('bold') 1702 else: 1703 (hibeg, hiend) = self._highlight('normal') 1704 state = utf8_width_fill(state, _pkg_states['maxlen']) 1705 print "%s%s%s%s %-*s %s" % (prefix, hibeg, state, hiend, 1706 pkg_max_len, hpkg, 1707 self._hpkg2from_repo(hpkg)) 1708 1709 if type(old.tid) == type([]): 1710 print _("Transaction ID :"), "%u..%u" % (old.tid[0], old.tid[-1]) 1711 else: 1712 print _("Transaction ID :"), old.tid 1417 1713 begtm = time.ctime(old.beg_timestamp) 1418 1714 print _("Begin time :"), begtm … … 1435 1731 sofar += len(begtms[i]) + 1 1436 1732 endtm = (' ' * sofar) + endtm[sofar:] 1437 diff = _("(%s seconds)") % (old.end_timestamp - old.beg_timestamp) 1733 diff = old.end_timestamp - old.beg_timestamp 1734 if diff < 5 * 60: 1735 diff = _("(%u seconds)") % diff 1736 elif diff < 5 * 60 * 60: 1737 diff = _("(%u minutes)") % (diff / 60) 1738 elif diff < 5 * 60 * 60 * 24: 1739 diff = _("(%u hours)") % (diff / (60 * 60)) 1740 else: 1741 diff = _("(%u days)") % (diff / (60 * 60 * 24)) 1438 1742 print _("End time :"), endtm, diff 1439 1743 if old.end_rpmdbversion is not None: … … 1442 1746 else: 1443 1747 print _("End rpmdb :"), old.end_rpmdbversion 1444 print _("User :"), name 1445 if old.return_code is None: 1748 if type(name) == type([]): 1749 for name in name: 1750 print _("User :"), name 1751 else: 1752 print _("User :"), name 1753 if type(old.return_code) == type([]): 1754 codes = old.return_code 1755 if codes[0] is None: 1756 print _("Return-Code :"), "**", _("Aborted"), "**" 1757 codes = codes[1:] 1758 if codes: 1759 print _("Return-Code :"), _("Failures:"), ", ".join(codes) 1760 elif old.return_code is None: 1446 1761 print _("Return-Code :"), "**", _("Aborted"), "**" 1447 1762 elif old.return_code: … … 1449 1764 else: 1450 1765 print _("Return-Code :"), _("Success") 1451 print _("Transaction performed with:") 1766 1767 if old.cmdline is not None: 1768 if type(old.cmdline) == type([]): 1769 for cmdline in old.cmdline: 1770 print _("Command Line :"), cmdline 1771 else: 1772 print _("Command Line :"), old.cmdline 1773 1774 if type(old.tid) != type([]): 1775 addon_info = self.history.return_addon_data(old.tid) 1776 1777 # for the ones we create by default - don't display them as there 1778 default_addons = set(['config-main', 'config-repos', 'saved_tx']) 1779 non_default = set(addon_info).difference(default_addons) 1780 if len(non_default) > 0: 1781 print _("Additional non-default information stored: %d" 1782 % len(non_default)) 1783 1784 if old.trans_with: 1785 # This is _possible_, but not common 1786 print _("Transaction performed with:") 1787 pkg_max_len = max((len(str(hpkg)) for hpkg in old.trans_with)) 1452 1788 for hpkg in old.trans_with: 1453 prefix = " " * 4 1454 state = _('Installed') 1455 ipkgs = self.rpmdb.searchNames([hpkg.name]) 1456 ipkgs.sort() 1457 if not ipkgs: 1458 state = _('Erased') 1459 elif hpkg.pkgtup in (ipkg.pkgtup for ipkg in ipkgs): 1460 pass 1461 elif ipkgs[-1] > hpkg: 1462 state = _('Updated') 1463 elif ipkgs[0] < hpkg: 1464 state = _('Downgraded') 1465 else: # multiple versions installed, both older and newer 1466 state = _('Weird') 1467 print "%s%s %s" % (prefix, utf8_width_fill(state, 12), hpkg) 1789 _simple_pkg(hpkg, 4, was_installed=True, pkg_max_len=pkg_max_len) 1468 1790 print _("Packages Altered:") 1469 1791 self.historyInfoCmdPkgsAltered(old, pats) 1792 1793 if old.trans_skip: 1794 print _("Packages Skipped:") 1795 pkg_max_len = max((len(str(hpkg)) for hpkg in old.trans_skip)) 1796 for hpkg in old.trans_skip: 1797 _simple_pkg(hpkg, 4, pkg_max_len=pkg_max_len) 1798 1799 if old.rpmdb_problems: 1800 print _("Rpmdb Problems:") 1801 for prob in old.rpmdb_problems: 1802 key = "%s%s: " % (" " * 4, prob.problem) 1803 print self.fmtKeyValFill(key, prob.text) 1804 if prob.packages: 1805 pkg_max_len = max((len(str(hpkg)) for hpkg in prob.packages)) 1806 for hpkg in prob.packages: 1807 _simple_pkg(hpkg, 8, was_installed=True, highlight=hpkg.main, 1808 pkg_max_len=pkg_max_len) 1809 1470 1810 if old.output: 1471 1811 print _("Scriptlet output:") … … 1481 1821 print "%4d" % num, line 1482 1822 1823 _history_state2uistate = {'True-Install' : _('Install'), 1824 'Install' : _('Install'), 1825 'Dep-Install' : _('Dep-Install'), 1826 'Obsoleted' : _('Obsoleted'), 1827 'Obsoleting' : _('Obsoleting'), 1828 'Erase' : _('Erase'), 1829 'Reinstall' : _('Reinstall'), 1830 'Downgrade' : _('Downgrade'), 1831 'Downgraded' : _('Downgraded'), 1832 'Update' : _('Update'), 1833 'Updated' : _('Updated'), 1834 } 1483 1835 def historyInfoCmdPkgsAltered(self, old, pats=[]): 1484 1836 last = None 1837 # Note that these don't use _simple_pkg() because we are showing what 1838 # happened to them in the transaction ... not the difference between the 1839 # version in the transaction and now. 1840 all_uistates = self._history_state2uistate 1841 maxlen = 0 1842 pkg_max_len = 0 1843 for hpkg in old.trans_data: 1844 uistate = all_uistates.get(hpkg.state, hpkg.state) 1845 if maxlen < len(uistate): 1846 maxlen = len(uistate) 1847 if pkg_max_len < len(str(hpkg)): 1848 pkg_max_len = len(str(hpkg)) 1849 1485 1850 for hpkg in old.trans_data: 1486 1851 prefix = " " * 4 … … 1499 1864 cn = hpkg.ui_nevra 1500 1865 1501 uistate = {'True-Install' : _('Install'), 1502 'Install' : _('Install'), 1503 'Dep-Install' : _('Dep-Install'), 1504 'Obsoleted' : _('Obsoleted'), 1505 'Obsoleting' : _('Obsoleting'), 1506 'Erase' : _('Erase'), 1507 'Reinstall' : _('Reinstall'), 1508 'Downgrade' : _('Downgrade'), 1509 'Downgraded' : _('Downgraded'), 1510 'Update' : _('Update'), 1511 'Updated' : _('Updated'), 1512 }.get(hpkg.state, hpkg.state) 1513 uistate = utf8_width_fill(uistate, 12, 12) 1866 uistate = all_uistates.get(hpkg.state, hpkg.state) 1867 uistate = utf8_width_fill(uistate, maxlen) 1514 1868 # Should probably use columns here... 1515 1869 if False: pass … … 1519 1873 ln = len(hpkg.name) + 1 1520 1874 cn = (" " * ln) + cn[ln:] 1521 print "%s%s%s%s %s" % (prefix, hibeg, uistate, hiend, cn)1522 1875 elif (last is not None and 1523 1876 last.state == 'Downgrade' and last.name == hpkg.name and … … 1525 1878 ln = len(hpkg.name) + 1 1526 1879 cn = (" " * ln) + cn[ln:] 1527 print "%s%s%s%s %s" % (prefix, hibeg, uistate, hiend, cn)1528 1880 else: 1529 1881 last = None 1530 1882 if hpkg.state in ('Updated', 'Downgrade'): 1531 1883 last = hpkg 1532 print "%s%s%s%s %s" % (prefix, hibeg, uistate, hiend, cn) 1884 print "%s%s%s%s %-*s %s" % (prefix, hibeg, uistate, hiend, 1885 pkg_max_len, cn, 1886 self._hpkg2from_repo(hpkg)) 1533 1887 1534 1888 def historySummaryCmd(self, extcmds): … … 1588 1942 uperiod = _period2user[period] 1589 1943 # Should probably use columns here, esp. for uiacts? 1590 print fmt % (utf8_width_fill(name, 2 2, 22),1944 print fmt % (utf8_width_fill(name, 26, 26), 1591 1945 utf8_width_fill(uperiod, 19, 19), 1592 1946 utf8_width_fill(uiacts, 16, 16), count) 1947 1948 def historyAddonInfoCmd(self, extcmds): 1949 tid = None 1950 if len(extcmds) > 1: 1951 tid = extcmds[1] 1952 if tid == 'last': 1953 tid = None 1954 if tid is not None: 1955 try: 1956 int(tid) 1957 except ValueError: 1958 self.logger.critical(_('Bad transaction ID given')) 1959 return 1, ['Failed history addon-info'] 1960 1961 if tid is not None: 1962 old = self.history.old(tids=[tid]) 1963 else: 1964 old = [self.history.last(complete_transactions_only=False)] 1965 if old[0] is None: 1966 self.logger.critical(_('No transaction ID, or package, given')) 1967 return 1, ['Failed history addon-info'] 1968 1969 if not old: 1970 self.logger.critical(_('No Transaction %s found') % tid) 1971 return 1, ['Failed history addon-info'] 1972 1973 hist_data = old[0] 1974 addon_info = self.history.return_addon_data(hist_data.tid) 1975 if len(extcmds) <= 2: 1976 print _("Transaction ID:"), hist_data.tid 1977 print _('Available additional history information:') 1978 for itemname in self.history.return_addon_data(hist_data.tid): 1979 print ' %s' % itemname 1980 print '' 1981 1982 return 0, ['history addon-info'] 1983 1984 for item in extcmds[2:]: 1985 if item in addon_info: 1986 print '%s:' % item 1987 print self.history.return_addon_data(hist_data.tid, item) 1988 else: 1989 print _('%s: No additional data found by this name') % item 1990 1991 print '' 1992 1993 def historyPackageListCmd(self, extcmds): 1994 """ Shows the user a list of data about the history, from the point 1995 of a package(s) instead of via. transactions. """ 1996 tids = self.history.search(extcmds) 1997 limit = None 1998 if extcmds and not tids: 1999 self.logger.critical(_('Bad transaction IDs, or package(s), given')) 2000 return 1, ['Failed history packages-list'] 2001 if not tids: 2002 limit = 20 2003 2004 all_uistates = self._history_state2uistate 2005 2006 fmt = "%s | %s | %s" 2007 # REALLY Needs to use columns! 2008 print fmt % (utf8_width_fill(_("ID"), 6, 6), 2009 utf8_width_fill(_("Action(s)"), 14, 14), 2010 utf8_width_fill(_("Package"), 53, 53)) 2011 print "-" * 79 2012 fmt = "%6u | %s | %-50s" 2013 num = 0 2014 for old in self.history.old(tids, limit=limit): 2015 if limit is not None and num and (num +len(old.trans_data)) > limit: 2016 break 2017 last = None 2018 2019 # Copy and paste from list ... uh. 2020 rmark = lmark = ' ' 2021 if old.return_code is None: 2022 rmark = lmark = '*' 2023 elif old.return_code: 2024 rmark = lmark = '#' 2025 # We don't check .errors, because return_code will be non-0 2026 elif old.output: 2027 rmark = lmark = 'E' 2028 elif old.rpmdb_problems: 2029 rmark = lmark = 'P' 2030 elif old.trans_skip: 2031 rmark = lmark = 's' 2032 if old.altered_lt_rpmdb: 2033 rmark = '<' 2034 if old.altered_gt_rpmdb: 2035 lmark = '>' 2036 2037 for hpkg in old.trans_data: # Find a pkg to go with each cmd... 2038 if limit is None: 2039 x,m,u = yum.packages.parsePackages([hpkg], extcmds) 2040 if not x and not m: 2041 continue 2042 2043 uistate = all_uistates.get(hpkg.state, hpkg.state) 2044 uistate = utf8_width_fill(uistate, 14) 2045 2046 # To chop the name off we need nevra strings, str(pkg) gives 2047 # envra so we have to do it by hand ... *sigh*. 2048 cn = hpkg.ui_nevra 2049 2050 # Should probably use columns here... 2051 if False: pass 2052 elif (last is not None and 2053 last.state == 'Updated' and last.name == hpkg.name and 2054 hpkg.state == 'Update'): 2055 ln = len(hpkg.name) + 1 2056 cn = (" " * ln) + cn[ln:] 2057 elif (last is not None and 2058 last.state == 'Downgrade' and last.name == hpkg.name and 2059 hpkg.state == 'Downgraded'): 2060 ln = len(hpkg.name) + 1 2061 cn = (" " * ln) + cn[ln:] 2062 else: 2063 last = None 2064 if hpkg.state in ('Updated', 'Downgrade'): 2065 last = hpkg 2066 2067 num += 1 2068 print fmt % (old.tid, uistate, cn), "%s%s" % (lmark,rmark) 2069 2070 # And, again, copy and paste... 2071 lastdbv = self.history.last() 2072 if lastdbv is None: 2073 self._rpmdb_warn_checks(warn=False) 2074 else: 2075 # If this is the last transaction, is good and it doesn't 2076 # match the current rpmdb ... then mark it as bad. 2077 rpmdbv = self.rpmdb.simpleVersion(main_only=True)[0] 2078 if lastdbv.end_rpmdbversion != rpmdbv: 2079 self._rpmdb_warn_checks() 1593 2080 1594 2081 … … 1604 2091 def pkgAdded(self, pkgtup, mode): 1605 2092 modedict = { 'i': _('installed'), 1606 'u': _('updated'), 1607 'o': _('obsoleted'), 1608 'e': _('erased')} 2093 'u': _('an update'), 2094 'e': _('erased'), 2095 'r': _('reinstalled'), 2096 'd': _('a downgrade'), 2097 'o': _('obsoleting'), 2098 'ud': _('updated'), 2099 'od': _('obsoleted'),} 1609 2100 (n, a, e, v, r) = pkgtup 1610 2101 modeterm = modedict[mode] 1611 2102 self.verbose_logger.log(logginglevels.INFO_2, 1612 _('---> Package %s.%s %s:%s-%s set tobe %s'), n, a, e, v, r,2103 _('---> Package %s.%s %s:%s-%s will be %s'), n, a, e, v, r, 1613 2104 modeterm) 1614 2105 … … 1640 2131 po) 1641 2132 2133 def groupRemoveReq(self, po, hits): 2134 self.verbose_logger.log(logginglevels.INFO_2, 2135 _('---> Keeping package: %s'), po) 2136 1642 2137 def unresolved(self, msg): 1643 2138 self.verbose_logger.log(logginglevels.INFO_2, _('--> Unresolved Dependency: %s'), … … 1661 2156 return msg 1662 2157 1663 ipkgs = set() 1664 for pkg in sorted(yb.rpmdb.getProvides(needname)): 1665 ipkgs.add(pkg.pkgtup) 2158 def _msg_pkg(action, pkg, needname): 2159 " Add a package to the message, including any provides matches. " 2160 msg = _('\n %s: %s (%s)') % (action, pkg, pkg.ui_from_repo) 2161 needtup = (needname, None, (None, None, None)) 2162 done = False 2163 for pkgtup in pkg.matchingPrcos('provides', needtup): 2164 done = True 2165 msg += _('\n %s') % yum.misc.prco_tuple_to_string(pkgtup) 2166 if not done: 2167 msg += _('\n Not found') 2168 return msg 2169 2170 def _run_inst_pkg(pkg, msg): 2171 nevr = (pkg.name, pkg.epoch, pkg.version, pkg.release) 2172 if nevr in seen_pkgs or (pkg.verEQ(last) and pkg.arch == last.arch): 2173 return msg 2174 2175 seen_pkgs.add(nevr) 1666 2176 action = _('Installed') 1667 if yb.tsInfo.getMembersWithState(pkg.pkgtup, TS_REMOVE_STATES): 2177 rmed = yb.tsInfo.getMembersWithState(pkg.pkgtup, TS_REMOVE_STATES) 2178 if rmed: 1668 2179 action = _('Removing') 1669 msg += _('\n %s: %s (%s)') % (action, pkg, pkg.ui_from_repo) 1670 last = None 1671 for pkg in sorted(yb.pkgSack.getProvides(needname)): 2180 msg += _msg_pkg(action, pkg, needname) 2181 # These should be the only three things we care about: 2182 relmap = {'updatedby' : _('Updated By'), 2183 'downgradedby' : _('Downgraded By'), 2184 'obsoletedby' : _('Obsoleted By'), 2185 } 2186 for txmbr in rmed: 2187 for (rpkg, rtype) in txmbr.relatedto: 2188 if rtype not in relmap: 2189 continue 2190 nevr = (rpkg.name, rpkg.epoch, rpkg.version, rpkg.release) 2191 seen_pkgs.add(nevr) 2192 msg += _msg_pkg(relmap[rtype], rpkg, needname) 2193 return msg 2194 2195 def _run_avail_pkg(pkg, msg): 1672 2196 # We don't want to see installed packages, or N packages of the 1673 2197 # same version, from different repos. 1674 if pkg.pkgtup in ipkgs or pkg.verEQ(last): 1675 continue 1676 last = pkg 2198 nevr = (pkg.name, pkg.epoch, pkg.version, pkg.release) 2199 if nevr in seen_pkgs or (pkg.verEQ(last) and pkg.arch == last.arch): 2200 return False, last, msg 2201 seen_pkgs.add(nevr) 1677 2202 action = _('Available') 1678 2203 if yb.tsInfo.getMembersWithState(pkg.pkgtup, TS_INSTALL_STATES): 1679 2204 action = _('Installing') 1680 msg += _('\n %s: %s (%s)') % (action, pkg, pkg.repoid) 2205 msg += _msg_pkg(action, pkg, needname) 2206 return True, pkg, msg 2207 2208 last = None 2209 seen_pkgs = set() 2210 for pkg in sorted(yb.rpmdb.getProvides(needname)): 2211 msg = _run_inst_pkg(pkg, msg) 2212 2213 available_names = set() 2214 for pkg in sorted(yb.pkgSack.getProvides(needname)): 2215 tst, last, msg = _run_avail_pkg(pkg, msg) 2216 if tst: 2217 available_names.add(pkg.name) 2218 2219 last = None 2220 for pkg in sorted(yb.rpmdb.searchNames(available_names)): 2221 msg = _run_inst_pkg(pkg, msg) 2222 last = None 2223 for pkg in sorted(yb.pkgSack.searchNames(available_names)): 2224 tst, last, msg = _run_avail_pkg(pkg, msg) 1681 2225 return msg 1682 2226 … … 1733 2277 # Note 'd' is a placeholder for downgrade, and 1734 2278 # 'r' is a placeholder for reinstall. Neither exist atm. 1735 ts_states = ('d', 'e', 'i', 'r', 'u' )2279 ts_states = ('d', 'e', 'i', 'r', 'u', 'od', 'ud') 1736 2280 1737 2281 matches = [] … … 1793 2337 # Installing things have pkg objects passed to the events, so only need to 1794 2338 # lookup for erased/obsoleted. 1795 def pkgname_ui(self, pkgname, ts_states=('e', None)):2339 def pkgname_ui(self, pkgname, ts_states=('e', 'od', 'ud', None)): 1796 2340 """ Get more information on a simple pkgname, if we can. """ 1797 2341 return _pkgname_ui(self.ayum, pkgname, ts_states) … … 1800 2344 # this is where a progress bar would be called 1801 2345 process = self.action[action] 2346 2347 if not hasattr(self, '_max_action_wid'): 2348 wid1 = 0 2349 for val in self.action.values(): 2350 wid_val = utf8_width(val) 2351 if wid1 < wid_val: 2352 wid1 = wid_val 2353 self._max_action_wid = wid1 2354 wid1 = self._max_action_wid 1802 2355 1803 2356 if type(package) not in types.StringTypes: … … 1814 2367 if self.output and (sys.stdout.isatty() or te_current == te_total): 1815 2368 (fmt, wid1, wid2) = self._makefmt(percent, ts_current, ts_total, 1816 pkgname=pkgname )2369 pkgname=pkgname, wid1=wid1) 1817 2370 msg = fmt % (utf8_width_fill(process, wid1, wid1), 1818 2371 utf8_width_fill(pkgname, wid2, wid2)) … … 1830 2383 1831 2384 def _makefmt(self, percent, ts_current, ts_total, progress = True, 1832 pkgname=None ):2385 pkgname=None, wid1=15): 1833 2386 l = len(str(ts_total)) 1834 2387 size = "%s.%s" % (l, l) … … 1844 2397 1845 2398 overhead = (2 * l) + 2 # Length of done, above 1846 overhead += 19 # Length of begining2399 overhead += 2+ wid1 +2 # Length of begining (" " action " :") 1847 2400 overhead += 1 # Space between pn and done 1848 2401 overhead += 2 # Ends for progress … … 1875 2428 fmt = " %s: %s " + bar + " " + done 1876 2429 wid2 = pnl 1877 return fmt, 15, wid22430 return fmt, wid1, wid2 1878 2431 1879 2432
Note:
See TracChangeset
for help on using the changeset viewer.
