You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.8 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2017 Therp BV <http://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. import inspect
  5. from openerp.sql_db import Cursor
  6. from openerp.modules import module
  7. from openerp.modules.graph import Graph
  8. original = module.load_information_from_description_file
  9. def load_information_from_description_file(module, mod_path=None):
  10. result = original(module, mod_path=mod_path)
  11. # add the keys you want to react on here
  12. if result.get('depends_if_installed'):
  13. cr = _get_cr()
  14. if cr:
  15. _handle_depends_if_installed(cr, result)
  16. return result
  17. def _handle_depends_if_installed(cr, manifest):
  18. if not manifest.get('depends_if_installed'):
  19. return
  20. cr.execute(
  21. 'select name from ir_module_module '
  22. 'where state in %s and name in %s',
  23. (
  24. tuple(['installed', 'to install', 'to upgrade']),
  25. tuple(manifest['depends_if_installed']),
  26. ),
  27. )
  28. manifest.pop('depends_if_installed')
  29. depends = manifest.setdefault('depends', [])
  30. depends.extend(module for module, in cr.fetchall())
  31. def _get_cr():
  32. cr = None
  33. for frame, filename, lineno, funcname, line, index in inspect.stack():
  34. # walk up the stack until we've found a cursor
  35. if 'cr' in frame.f_locals and isinstance(frame.f_locals['cr'], Cursor):
  36. cr = frame.f_locals['cr']
  37. break
  38. return cr
  39. def _get_graph():
  40. graph = None
  41. for frame, filename, lineno, funcname, line, index in inspect.stack():
  42. # walk up the stack until we've found a graph
  43. if 'graph' in frame.f_locals and isinstance(
  44. frame.f_locals['graph'], Graph
  45. ):
  46. graph = frame.f_locals['graph']
  47. break
  48. return graph
  49. def post_load_hook():
  50. cr = _get_cr()
  51. if not cr:
  52. return
  53. cr.execute(
  54. 'select id from ir_module_module where name=%s and state in %s',
  55. (
  56. 'base_manifest_extension',
  57. tuple(['installed', 'to install', 'to upgrade']),
  58. ),
  59. )
  60. # do nothing if we're not installed
  61. if not cr.rowcount:
  62. return
  63. module.load_information_from_description_file =\
  64. load_information_from_description_file
  65. # here stuff can become tricky: On the python level, modules
  66. # are not loaded in dependency order. This means that there might
  67. # be modules loaded depending on us before we could patch the function
  68. # above. So we reload the module graph for all modules coming after us
  69. graph = _get_graph()
  70. if not graph:
  71. return
  72. this = graph['base_manifest_extension']
  73. to_reload = []
  74. for node in graph.itervalues():
  75. if node.depth > this.depth:
  76. to_reload.append(node.name)
  77. for module_name in to_reload:
  78. del graph[module_name]
  79. graph.add_modules(cr, to_reload)