ls.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. """List packages according to various criteria
  2. @copyright: 2014, Ansgar Burchardt <ansgar@debian.org>
  3. @license: GPL-2+
  4. """
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. import sqlalchemy.sql as sql
  19. import sqlalchemy.dialects.postgresql as pgsql
  20. from daklib.dbconn import DBConn
  21. from collections import defaultdict
  22. def list_packages(packages, suites=None, components=None, architectures=None, binary_types=None,
  23. source_and_binary=False, regex=False,
  24. format=None, highest=None):
  25. session = DBConn().session()
  26. try:
  27. t = DBConn().view_package_list
  28. comparison_operator = "~" if regex else "="
  29. where = sql.false()
  30. for package in packages:
  31. where = where | t.c.package.op(comparison_operator)(package)
  32. if source_and_binary:
  33. where = where | t.c.source.op(comparison_operator)(package)
  34. if suites is not None:
  35. where = where & (t.c.suite.in_(suites) | t.c.codename.in_(suites))
  36. if components is not None:
  37. where = where & t.c.component.in_(components)
  38. if architectures is not None:
  39. where = where & t.c.architecture.in_(architectures)
  40. if binary_types is not None:
  41. where = where & t.c.type.in_(binary_types)
  42. if format is None:
  43. c_architectures = sql.func.string_agg(t.c.architecture, pgsql.aggregate_order_by(', ', t.c.architecture_is_source.desc(), t.c.architecture))
  44. query = sql.select([t.c.package, t.c.version, t.c.display_suite, c_architectures]) \
  45. .where(where) \
  46. .group_by(t.c.package, t.c.version, t.c.display_suite) \
  47. .order_by(t.c.package, t.c.version, t.c.display_suite)
  48. result = session.execute(query).fetchall()
  49. if len(result) == 0:
  50. return
  51. lengths = {
  52. 'package': max(10, max(len(row[t.c.package]) for row in result)),
  53. 'version': max(13, max(len(row[t.c.version]) for row in result)),
  54. 'suite': max(10, max(len(row[t.c.display_suite]) for row in result))
  55. }
  56. format = "{0:{lengths[package]}} | {1:{lengths[version]}} | {2:{lengths[suite]}} | {3}"
  57. for row in result:
  58. yield format.format(row[t.c.package], row[t.c.version], row[t.c.display_suite], row[c_architectures], lengths=lengths)
  59. elif format in ('control-suite', 'heidi'):
  60. query = sql.select([t.c.package, t.c.version, t.c.architecture]).where(where)
  61. result = session.execute(query)
  62. for row in result:
  63. yield "{0} {1} {2}".format(row[t.c.package], row[t.c.version], row[t.c.architecture])
  64. elif format == "python":
  65. c_architectures = sql.func.string_agg(t.c.architecture, pgsql.aggregate_order_by(',', t.c.architecture_is_source.desc(), t.c.architecture))
  66. query = sql.select([t.c.package,
  67. t.c.version,
  68. t.c.display_suite,
  69. c_architectures,
  70. t.c.source,
  71. t.c.source_version,
  72. t.c.component]) \
  73. .where(where) \
  74. .group_by(t.c.package,
  75. t.c.version,
  76. t.c.display_suite,
  77. t.c.source,
  78. t.c.component,
  79. t.c.source_version)
  80. result = session.execute(query).fetchall()
  81. if len(result) == 0:
  82. return
  83. def val():
  84. return defaultdict(val)
  85. ret = val()
  86. for row in result:
  87. ret[row[t.c.package]][row[t.c.display_suite]][row[t.c.version]] = {'component': row[t.c.component],
  88. 'architectures': row[c_architectures].split(','),
  89. 'source': row[t.c.source],
  90. 'source_version': row[t.c.source_version]
  91. }
  92. yield ret
  93. return
  94. else:
  95. raise ValueError("Unknown output format requested.")
  96. if highest is not None:
  97. query = sql.select([t.c.package, sql.func.max(t.c.version)]).where(where) \
  98. .group_by(t.c.package).order_by(t.c.package)
  99. result = session.execute(query)
  100. yield ""
  101. for row in result:
  102. yield "{0} ({1} {2})".format(row[0], highest, row[1])
  103. finally:
  104. session.close()