PageRenderTime 38ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/components/tools/OmeroPy/src/omero/plugins/hql.py

https://github.com/aherbert/openmicroscopy
Python | 233 lines | 220 code | 2 blank | 11 comment | 0 complexity | 7dcf3c1e62862eb0cfe51da6130a6090 MD5 | raw file
  1. #!/usr/bin/env python
  2. """
  3. HQL plugin
  4. Plugin read by omero.cli.Cli during initialization. The method(s)
  5. defined here will be added to the Cli class for later use.
  6. Copyright 2008 Glencoe Software, Inc. All rights reserved.
  7. Use is subject to license terms supplied in LICENSE.txt
  8. """
  9. from omero.cli import BaseControl, CLI
  10. import exceptions
  11. import cmd
  12. import time
  13. import cmd
  14. import sys
  15. HELP = """Executes an HQL statement with the given parameters.
  16. If no query is given, then a shell is opened which
  17. will run any entered query with the current parameters."""
  18. class HqlControl(BaseControl):
  19. def _configure(self, parser):
  20. parser.set_defaults(func=self.__call__)
  21. parser.add_argument("query", nargs="?", help="Single query to run")
  22. parser.add_argument("-q", "--quiet", action="store_true", help="No user input")
  23. parser.add_argument("--limit", help="Maximum number of return values", type=int, default=25)
  24. parser.add_argument("--offset", help="Number of entries to skip", type=int, default=0)
  25. parser.add_argument("--admin", help="Run an admin query", default=False, action="store_true")
  26. def __call__(self, args):
  27. if args.query:
  28. self.hql(args)
  29. else:
  30. if args.quiet:
  31. self.ctx.die(67, "Can't ask for query with --quiet option")
  32. while True:
  33. args.query = self.ctx.input("Enter query:")
  34. if not args.query:
  35. break
  36. if not self.hql(args, loop = True):
  37. break
  38. def hql(self, args, loop = False):
  39. from omero_sys_ParametersI import ParametersI
  40. ice_map = dict()
  41. if args.admin:
  42. ice_map["omero.group"]="-1"
  43. c = self.ctx.conn(args)
  44. q = c.sf.getQueryService()
  45. p = ParametersI()
  46. p.page(args.offset, args.limit)
  47. rv = self.project(q, args.query, p, ice_map)
  48. has_details = self.display(rv)
  49. if args.quiet:
  50. return
  51. input = """
  52. To see details for object, enter line number.
  53. To move ahead one page, enter 'p'
  54. To re-display list, enter 'r'.
  55. To quit, enter 'q' or just enter.
  56. """
  57. if loop:
  58. input = input + """To run another query, press enter\n"""
  59. while True:
  60. id = self.ctx.input(input)
  61. id = id.lower()
  62. # Exit loop
  63. if not id:
  64. return True
  65. if id.startswith("q"):
  66. return False
  67. # Stay in loop
  68. if id.startswith("p"):
  69. p.page(p.getOffset().val + p.getLimit().val, p.getLimit())
  70. self.ctx.dbg("\nCurrent page: offset=%s, limit=%s\n" % (p.theFilter.offset.val, p.theFilter.limit.val))
  71. rv = self.project(q, args.query, p, ice_map)
  72. self.display(rv)
  73. elif id.startswith("r"):
  74. self.display(rv)
  75. else:
  76. try:
  77. id = long(id)
  78. obj = rv[id]
  79. if id not in has_details:
  80. self.ctx.out("No details available: %s" % id)
  81. continue
  82. else:
  83. obj = obj[0].val # Unwrap the object_list from IQuery.projection
  84. except:
  85. self.ctx.out("Invalid choice: %s" % id)
  86. continue
  87. keys = sorted(obj.__dict__)
  88. keys.remove("_id")
  89. keys.remove("_details")
  90. self.ctx.out("id = %s" % obj.id.val)
  91. for key in keys:
  92. value = self.unwrap(obj.__dict__[key])
  93. if isinstance(value, (str, unicode)):
  94. value = "'%s'" % value
  95. if key.startswith("_"):
  96. key = key[1:]
  97. self.ctx.out("%s = %s" % (key, value))
  98. continue
  99. def display(self, rv, cols = None):
  100. import omero_model_Details_ice
  101. import omero_model_IObject_ice
  102. import omero.rtypes
  103. from omero.model import IObject
  104. from omero.model import Details
  105. from omero.util.text import TableBuilder
  106. has_details = []
  107. tb = TableBuilder("#")
  108. for idx, object_list in enumerate(rv):
  109. klass = "Null"
  110. id = ""
  111. values = {}
  112. # Handling for simple lookup
  113. if len(object_list) == 1 and isinstance(object_list[0], omero.rtypes.RObjectI):
  114. has_details.append(idx)
  115. o = object_list[0].val
  116. if o:
  117. tb.cols(["Class", "Id"])
  118. klass = o.__class__.__name__
  119. id = o.id.val
  120. for k, v in o.__dict__.items():
  121. values[k] = self.unwrap(v)
  122. values = self.filter(values)
  123. tb.cols(values.keys())
  124. tb.row(idx, klass, id, **values)
  125. # Handling for true projections
  126. else:
  127. indices = range(1, len(object_list) + 1)
  128. if cols is not None:
  129. tb.cols(cols)
  130. else:
  131. tb.cols(["Col%s" % x for x in indices])
  132. values = tuple([self.unwrap(x) for x in object_list])
  133. tb.row(idx, *values)
  134. self.ctx.out(str(tb.build()))
  135. return has_details
  136. def unwrap(self, object, cache = None):
  137. if cache == None:
  138. cache = {}
  139. elif object in cache:
  140. return cache[id(object)]
  141. from omero.rtypes import unwrap
  142. import omero_model_Details_ice
  143. import omero_model_IObject_ice
  144. from omero.model import IObject
  145. from omero.model import Details
  146. from omero.rtypes import RObjectI
  147. from omero.rtypes import RTimeI
  148. #if isinstance(object, list):
  149. # return [self.unwrap(x, cache) for x in object]
  150. #elif isinstance(object, RObject):
  151. # return self.unwrap(object.val, cache)
  152. unwrapped = unwrap(object, cache)
  153. if isinstance(unwrapped, IObject):
  154. rv = "%s:%s" % (unwrapped.__class__.__name__, unwrapped.id.val)
  155. elif isinstance(object, RTimeI):
  156. rv = time.ctime(unwrapped/1000.0)
  157. elif isinstance(object, Details):
  158. owner = None
  159. group = None
  160. if unwrapped.owner is not None:
  161. owner = unwrapped.owner.id.val
  162. if unwrapped.group is not None:
  163. group = unwrapped.group.id.val
  164. rv = "owner=%s;group=%s" % (owner, group)
  165. else:
  166. rv = unwrapped
  167. cache[id(object)] = rv
  168. return rv;
  169. def filter(self, values):
  170. values = dict(values)
  171. for x in ("_id", "_loaded"):
  172. if x in values:
  173. values.pop(x)
  174. if "owner=None;group=None" == values.get("_details"):
  175. values.pop("_details")
  176. multi_valued = sorted([k for k in values if isinstance(values[k], list)])
  177. false_valued = sorted([k for k in values if not values[k]])
  178. for x in multi_valued + false_valued:
  179. if x in values:
  180. values.pop(x)
  181. rv = dict()
  182. for k, v in values.items():
  183. if k.startswith("_"):
  184. rv[k[1:]] = v
  185. else:
  186. rv[k] = v
  187. return rv
  188. def project(self, querySvc, queryStr, params, ice_map):
  189. import omero
  190. try:
  191. rv = querySvc.projection(queryStr, params, ice_map)
  192. self.ctx.set("last.hql.rv", rv)
  193. return rv
  194. except omero.SecurityViolation, sv:
  195. if "omero.group" in ice_map:
  196. self.ctx.die(53, "SecurityViolation: Current user is not an admin and cannot use '--admin'")
  197. else:
  198. self.ctx.die(54, "SecurityViolation: %s" % sv)
  199. except omero.QueryException, qe:
  200. self.ctx.set("last.hql.rv", [])
  201. self.ctx.die(52, "Bad query: %s" % qe.message)
  202. try:
  203. register("hql", HqlControl, HELP)
  204. except NameError:
  205. if __name__ == "__main__":
  206. cli = CLI()
  207. cli.register("hql", HqlControl, HELP)
  208. cli.invoke(sys.argv[1:])