Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

128 lignes
2.9 KiB

  1. # Copyright (c) 2015, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # License: MIT. See LICENSE
  3. import cProfile
  4. import pstats
  5. import subprocess # nosec
  6. import sys
  7. from functools import wraps
  8. from io import StringIO
  9. from os import environ
  10. import click
  11. import frappe
  12. import frappe.utils
  13. click.disable_unicode_literals_warning = True
  14. def pass_context(f):
  15. @wraps(f)
  16. def _func(ctx, *args, **kwargs):
  17. profile = ctx.obj["profile"]
  18. if profile:
  19. pr = cProfile.Profile()
  20. pr.enable()
  21. try:
  22. ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  23. except frappe.exceptions.SiteNotSpecifiedError as e:
  24. click.secho(str(e), fg="yellow")
  25. sys.exit(1)
  26. except frappe.exceptions.IncorrectSitePath:
  27. site = ctx.obj.get("sites", "")[0]
  28. click.secho(f"Site {site} does not exist!", fg="yellow")
  29. sys.exit(1)
  30. if profile:
  31. pr.disable()
  32. s = StringIO()
  33. ps = pstats.Stats(pr, stream=s).sort_stats("cumtime", "tottime", "ncalls")
  34. ps.print_stats()
  35. # print the top-100
  36. for line in s.getvalue().splitlines()[:100]:
  37. print(line)
  38. return ret
  39. return click.pass_context(_func)
  40. def get_site(context, raise_err=True):
  41. try:
  42. site = context.sites[0]
  43. return site
  44. except (IndexError, TypeError):
  45. if raise_err:
  46. raise frappe.SiteNotSpecifiedError
  47. return None
  48. def popen(command, *args, **kwargs):
  49. output = kwargs.get("output", True)
  50. cwd = kwargs.get("cwd")
  51. shell = kwargs.get("shell", True)
  52. raise_err = kwargs.get("raise_err")
  53. env = kwargs.get("env")
  54. if env:
  55. env = dict(environ, **env)
  56. def set_low_prio():
  57. import psutil
  58. if psutil.LINUX:
  59. psutil.Process().nice(19)
  60. psutil.Process().ionice(psutil.IOPRIO_CLASS_IDLE)
  61. elif psutil.WINDOWS:
  62. psutil.Process().nice(psutil.IDLE_PRIORITY_CLASS)
  63. psutil.Process().ionice(psutil.IOPRIO_VERYLOW)
  64. else:
  65. psutil.Process().nice(19)
  66. # ionice not supported
  67. proc = subprocess.Popen(
  68. command,
  69. stdout=None if output else subprocess.PIPE,
  70. stderr=None if output else subprocess.PIPE,
  71. shell=shell,
  72. cwd=cwd,
  73. preexec_fn=set_low_prio,
  74. env=env,
  75. )
  76. return_ = proc.wait()
  77. if return_ and raise_err:
  78. raise subprocess.CalledProcessError(return_, command)
  79. return return_
  80. def call_command(cmd, context):
  81. return click.Context(cmd, obj=context).forward(cmd)
  82. def get_commands():
  83. # prevent circular imports
  84. from .redis_utils import commands as redis_commands
  85. from .scheduler import commands as scheduler_commands
  86. from .site import commands as site_commands
  87. from .translate import commands as translate_commands
  88. from .utils import commands as utils_commands
  89. clickable_link = "\x1b]8;;https://frappeframework.com/docs\afrappeframework.com\x1b]8;;\a"
  90. all_commands = (
  91. scheduler_commands + site_commands + translate_commands + utils_commands + redis_commands
  92. )
  93. for command in all_commands:
  94. if not command.help:
  95. command.help = f"Refer to {clickable_link}"
  96. return all_commands
  97. commands = get_commands()