PageRenderTime 37ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/pyramid_debugtoolbar/utils.py

https://github.com/driax/pyramid_debugtoolbar
Python | 144 lines | 130 code | 9 blank | 5 comment | 13 complexity | 9542d223ab4b30cece0e85d942a9a0f7 MD5 | raw file
  1. import os.path
  2. import sys
  3. from logging import getLogger
  4. from pyramid.util import DottedNameResolver
  5. from pyramid.settings import asbool
  6. try:
  7. from pygments import highlight
  8. from pygments.formatters import HtmlFormatter
  9. from pygments.lexers import SqlLexer
  10. from pygments.styles import get_style_by_name
  11. PYGMENT_STYLE = get_style_by_name('colorful')
  12. HAVE_PYGMENTS = True
  13. except ImportError: # pragma: no cover
  14. HAVE_PYGMENTS = False
  15. SETTINGS_PREFIX = 'debugtoolbar.'
  16. STATIC_PATH = 'pyramid_debugtoolbar:static/'
  17. ROOT_ROUTE_NAME = 'debugtoolbar.root'
  18. EXC_ROUTE_NAME = 'debugtoolbar.exception'
  19. def format_fname(value, _sys_path=None):
  20. if _sys_path is None:
  21. _sys_path = sys.path # dependency injection
  22. # If the value is not an absolute path, the it is a builtin or
  23. # a relative file (thus a project file).
  24. if not os.path.isabs(value):
  25. if value.startswith(('{', '<')):
  26. return value
  27. if value.startswith('.' + os.path.sep):
  28. return value
  29. return '.' + os.path.sep + value
  30. # Loop through sys.path to find the longest match and return
  31. # the relative path from there.
  32. prefix_len = 0
  33. value_segs = value.split(os.path.sep)
  34. for path in _sys_path:
  35. count = common_segment_count(path.split(os.path.sep), value_segs)
  36. if count > prefix_len:
  37. prefix_len = count
  38. return '<%s>' % os.path.sep.join(value_segs[prefix_len:])
  39. def common_segment_count(path, value):
  40. """Return the number of path segments common to both"""
  41. i = 0
  42. if len(path) <= len(value):
  43. for x1, x2 in zip(path, value):
  44. if x1 == x2:
  45. i += 1
  46. else:
  47. return 0
  48. return i
  49. def format_sql(query):
  50. if not HAVE_PYGMENTS: # pragma: no cover
  51. return query
  52. return highlight(
  53. query,
  54. SqlLexer(encoding='utf-8'),
  55. HtmlFormatter(encoding='utf-8', noclasses=True, style=PYGMENT_STYLE))
  56. def escape(s, quote=False):
  57. """Replace special characters "&", "<" and ">" to HTML-safe sequences. If
  58. the optional flag `quote` is `True`, the quotation mark character is
  59. also translated.
  60. There is a special handling for `None` which escapes to an empty string.
  61. :param s: the string to escape.
  62. :param quote: set to true to also escape double quotes.
  63. """
  64. if s is None:
  65. return ''
  66. elif hasattr(s, '__html__'):
  67. return s.__html__()
  68. elif not isinstance(s, basestring):
  69. s = unicode(s)
  70. s = s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
  71. if quote:
  72. s = s.replace('"', "&quot;")
  73. return s
  74. def replace_insensitive(string, target, replacement):
  75. """Similar to string.replace() but is case insensitive
  76. Code borrowed from: http://forums.devshed.com/python-programming-11/case-insensitive-string-replace-490921.html
  77. """
  78. no_case = string.lower()
  79. index = no_case.rfind(target.lower())
  80. if index >= 0:
  81. return string[:index] + replacement + string[index + len(target):]
  82. else: # no results so return the original string
  83. return string
  84. resolver = DottedNameResolver(None)
  85. def as_cr_separated_list(value):
  86. if isinstance(value, basestring):
  87. value = filter(None, [x.strip() for x in value.splitlines()])
  88. return value
  89. def as_list(value):
  90. values = as_cr_separated_list(value)
  91. result = []
  92. for value in values:
  93. subvalues = value.split()
  94. result.extend(subvalues)
  95. return result
  96. def as_globals_list(value):
  97. L = []
  98. value = as_list(value)
  99. for dottedname in value:
  100. obj = resolver.resolve(dottedname)
  101. L.append(obj)
  102. return L
  103. def as_display_debug_or_false(value):
  104. if isinstance(value, basestring):
  105. val = value.lower().strip()
  106. if val in ('display', 'debug'):
  107. return val
  108. b = asbool(value)
  109. if b: # bw compat for dbt <=0.9
  110. return 'debug'
  111. return False
  112. def get_setting(settings, name, default=None):
  113. return settings.get('%s%s' % (SETTINGS_PREFIX, name), default)
  114. def dictrepr(d):
  115. out = {}
  116. for val in d:
  117. try:
  118. out[val] = repr(d[val])
  119. except:
  120. # defensive
  121. out[val] = '<unknown>'
  122. return sorted(out.items())
  123. logger = getLogger('pyramid_debugtoolbar')