This file is indexed.

/usr/lib/python3/dist-packages/sassutils/wsgi.py is in python3-libsass 0.11.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
""":mod:`sassutils.wsgi` --- WSGI middleware for development purpose
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"""
from __future__ import absolute_import, with_statement

import collections
import logging
import os
import os.path

from pkg_resources import resource_filename

from sass import CompileError
from .builder import Manifest

__all__ = 'SassMiddleware',


class SassMiddleware(object):
    """WSGI middleware for development purpose.  Everytime a CSS file has
    requested it finds a matched SASS/SCSS source file and then compiled
    it into CSS.

    It shows syntax errors in three ways:

    Heading comment
        The result CSS includes detailed error message in the heading
        CSS comment e.g.:

        .. code-block:: css

           /*
           Error: invalid property name
           */

    Red text in ``body:before``
        The result CSS draws detailed error message in ``:before``
        pseudo-class of ``body`` element e.g.::

        .. code-block:: css

           /*
           body:before {
             content: 'Error: invalid property name';
             color: maroon;
             background-color: white;
           }
           */

        In most cases you could be aware of syntax error by refreshing your
        working document because it will removes all other styles and leaves
        only a red text.

    :mod:`logging`
        It logs syntax errors if exist during compilation to
        ``sassutils.wsgi.SassMiddleware`` logger with level ``ERROR``.

        To enable this::

            from logging import Formatter, StreamHandler, getLogger
            logger = getLogger('sassutils.wsgi.SassMiddleware')
            handler = StreamHandler(level=logging.ERROR)
            formatter = Formatter(fmt='*' * 80 + '\n%(message)s\n' + '*' * 80)
            handler.setFormatter(formatter)
            logger.addHandler(handler)

        Or simply::

            import logging
            logging.basicConfig()

    :param app: the WSGI application to wrap
    :type app: :class:`collections.Callable`
    :param manifests: build settings.  the same format to
                      :file:`setup.py` script's ``sass_manifests``
                      option
    :type manifests: :class:`collections.Mapping`
    :param package_dir: optional mapping of package names to directories.
                        the same format to :file:`setup.py` script's
                        ``package_dir`` option
    :type package_dir: :class:`collections.Mapping`

    .. versionchanged:: 0.4.0
       It creates also source map files with filenames followed by
       :file:`.map` suffix.

    .. versionadded:: 0.8.0
       It logs syntax errors if exist during compilation to
       ``sassutils.wsgi.SassMiddleware`` logger with level ``ERROR``.

    """

    def __init__(self, app, manifests, package_dir={},
                 error_status='200 OK'):
        if not callable(app):
            raise TypeError('app must be a WSGI-compliant callable object, '
                            'not ' + repr(app))
        self.app = app
        self.manifests = Manifest.normalize_manifests(manifests)
        if not isinstance(package_dir, collections.Mapping):
            raise TypeError('package_dir must be a mapping object, not ' +
                            repr(package_dir))
        self.error_status = error_status
        self.package_dir = dict(package_dir)
        for package_name in self.manifests:
            if package_name in self.package_dir:
                continue
            path = resource_filename(package_name, '')
            self.package_dir[package_name] = path
        self.paths = []
        for package_name, manifest in self.manifests.items():
            wsgi_path = manifest.wsgi_path
            if not wsgi_path.startswith('/'):
                wsgi_path = '/' + wsgi_path
            if not wsgi_path.endswith('/'):
                wsgi_path += '/'
            package_dir = self.package_dir[package_name]
            self.paths.append((wsgi_path, package_dir, manifest))

    def __call__(self, environ, start_response):
        path = environ.get('PATH_INFO', '/')
        if path.endswith('.css'):
            for prefix, package_dir, manifest in self.paths:
                if not path.startswith(prefix):
                    continue
                css_filename = path[len(prefix):]
                sass_filename = css_filename[:-4]
                try:
                    result = manifest.build_one(package_dir,
                                                sass_filename,
                                                source_map=True)
                except (IOError, OSError):
                    break
                except CompileError as e:
                    logger = logging.getLogger(__name__ + '.SassMiddleware')
                    logger.error(str(e))
                    start_response(
                        self.error_status,
                        [('Content-Type', 'text/css; charset=utf-8')]
                    )
                    return [
                        b'/*\n', str(e).encode('utf-8'), b'\n*/\n\n',
                        b'body:before { content: ',
                        self.quote_css_string(str(e)).encode('utf-8'),
                        b'; color: maroon; background-color: white',
                        b'; white-space: pre-wrap; display: block',
                        b'; font-family: "Courier New", monospace'
                        b'; user-select: text; }'
                    ]

                def read_file(path):
                    with open(path, 'rb') as in_:
                        while 1:
                            chunk = in_.read(4096)
                            if chunk:
                                yield chunk
                            else:
                                break
                start_response('200 OK', [('Content-Type', 'text/css')])
                return read_file(os.path.join(package_dir, result))
        return self.app(environ, start_response)

    @staticmethod
    def quote_css_string(s):
        """Quotes a string as CSS string literal."""
        return "'" + ''.join('\\%06x' % ord(c) for c in s) + "'"