Exemplo n.º 1
0
def nth(lst, n):
    """
    Return the Nth item in the string
    """
    n = NumberValue(n).value
    lst = List(lst).value
    try:
        n = int(float(n)) - 1
        n = n % len(lst)
    except:
        if n.lower() == 'first':
            n = 0
        elif n.lower() == 'last':
            n = -1
    try:
        ret = lst[n]
    except KeyError:
        lst = [v for k, v in sorted(lst.items()) if isinstance(k, int)]
        try:
            ret = lst[n]
        except:
            ret = ''
    return ret.__class__(ret)
Exemplo n.º 2
0
Arquivo: core.py Projeto: croby/pyScss
def percentage(value):
    value = NumberValue(value)
    value.units = {'%': _units_weights.get('%', 1), '_': '%'}
    return value
Exemplo n.º 3
0
Arquivo: core.py Projeto: croby/pyScss
def lightness(color):
    c = ColorValue(color).value
    h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0)
    ret = NumberValue(l)
    ret.units = {'%': _units_weights.get('%', 1), '_': '%'}
    return ret
Exemplo n.º 4
0
Arquivo: core.py Projeto: croby/pyScss
def hue(color):
    c = ColorValue(color).value
    h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0)
    ret = NumberValue(h * 360.0)
    ret.units = {'deg': _units_weights.get('deg', 1), '_': 'deg'}
    return ret
Exemplo n.º 5
0
def hue(color):
    c = ColorValue(color).value
    h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0)
    return NumberValue(h * 360, unit='deg')
Exemplo n.º 6
0
def alpha(color):
    c = ColorValue(color).value
    return NumberValue(c[3])
Exemplo n.º 7
0
def blue(color):
    c = ColorValue(color).value
    return NumberValue(c[2])
Exemplo n.º 8
0
    return _position(False, p)


@register('opposite-position')
def opposite_position(p):
    return _position(True, p)


# ------------------------------------------------------------------------------
# Math

@register('pi', 0)
def pi():
    return NumberValue(math.pi)

COMPASS_HELPERS_LIBRARY.add(NumberValue.wrap_python_function(math.sin), 'sin', 1)
COMPASS_HELPERS_LIBRARY.add(NumberValue.wrap_python_function(math.cos), 'cos', 1)
COMPASS_HELPERS_LIBRARY.add(NumberValue.wrap_python_function(math.tan), 'tan', 1)


# ------------------------------------------------------------------------------
# Fonts

def _font_url(path, only_path=False, cache_buster=True, inline=False):
    filepath = StringValue(path).value
    path = None
    if callable(config.STATIC_ROOT):
        try:
            _file, _storage = list(config.STATIC_ROOT(filepath))[0]
            d_obj = _storage.modified_time(_file)
            filetime = int(time.mktime(d_obj.timetuple()))
Exemplo n.º 9
0
def red(color):
    c = ColorValue(color).value
    return NumberValue(c[0])
Exemplo n.º 10
0
def hsl(h, s, l, type='hsl'):
    return hsla(h, s, l, NumberValue(1), type)
Exemplo n.º 11
0
# ------------------------------------------------------------------------------
# Number functions


@register('percentage', 1)
def percentage(value):
    if not isinstance(value, NumberValue):
        raise TypeError("Expected number, got %r" % (value, ))

    if not value.is_unitless:
        raise TypeError("Expected unitless number, got %r" % (value, ))

    return value * NumberValue(100, unit='%')


CORE_LIBRARY.add(NumberValue.wrap_python_function(abs), 'abs', 1)
CORE_LIBRARY.add(NumberValue.wrap_python_function(round), 'round', 1)
CORE_LIBRARY.add(NumberValue.wrap_python_function(math.ceil), 'ceil', 1)
CORE_LIBRARY.add(NumberValue.wrap_python_function(math.floor), 'floor', 1)


# ------------------------------------------------------------------------------
# List functions
def __parse_separator(separator, default_from=None):
    if separator is None:
        return None
    separator = StringValue(separator).value
    if separator == 'comma':
        return True
    elif separator == 'space':
        return False
Exemplo n.º 12
0
def __radial_svg(color_stops, cx, cy, r):
    gradient = '<radialGradient id="grad" gradientUnits="userSpaceOnUse" cx="%s" cy="%s" r="%s">%s</radialGradient>' % (
        to_str(NumberValue(cx)), to_str(NumberValue(cy)), to_str(
            NumberValue(r)), __color_stops_svg(color_stops))
    return __svg_template(gradient)
Exemplo n.º 13
0
def _linear_svg(color_stops, x1, y1, x2, y2):
    gradient = '<linearGradient id="grad" x1="%s" y1="%s" x2="%s" y2="%s">%s</linearGradient>' % (
        to_str(NumberValue(x1)), to_str(
            NumberValue(y1)), to_str(NumberValue(x2)), to_str(
                NumberValue(y2)), __color_stops_svg(color_stops))
    return __svg_template(gradient)
Exemplo n.º 14
0
def __color_stops(percentages, *args):
    if len(args) == 1:
        if isinstance(args[0], (list, tuple, List)):
            list(args[0])
        elif isinstance(args[0], (StringValue, six.string_types)):
            color_stops = []
            colors = split_params(getattr(args[0], 'value', args[0]))
            for color in colors:
                color = color.strip()
                if color.startswith('color-stop('):
                    s, c = split_params(color[11:].rstrip(')'))
                    s = s.strip()
                    c = c.strip()
                else:
                    c, s = color.split()
                color_stops.append((to_float(s), c))
            return color_stops

    colors = []
    stops = []
    prev_color = False
    for c in args:
        for c in List.from_maybe(c):
            if isinstance(c, ColorValue):
                if prev_color:
                    stops.append(None)
                colors.append(c)
                prev_color = True
            elif isinstance(c, NumberValue):
                stops.append(c)
                prev_color = False

    if prev_color:
        stops.append(None)
    stops = stops[:len(colors)]
    if stops[0] is None:
        stops[0] = NumberValue(0, '%')
    if stops[-1] is None:
        stops[-1] = NumberValue(100, '%')

    if percentages:
        max_stops = max(s and (s.value if s.unit != '%' else None) or None
                        for s in stops)
    else:
        max_stops = max(s if s and s.unit != '%' else None for s in stops)

    stops = [s / max_stops if s and s.unit != '%' else s for s in stops]

    init = 0
    start = None
    for i, s in enumerate(stops + [1.0]):
        if s is None:
            if start is None:
                start = i
            end = i
        else:
            final = s
            if start is not None:
                stride = (final -
                          init) / NumberValue(end - start + 1 +
                                              (1 if i < len(stops) else 0))
                for j in range(start, end + 1):
                    stops[j] = init + stride * NumberValue(j - start + 1)
            init = final
            start = None

    if not max_stops or percentages:
        pass
    else:
        stops = [s * max_stops for s in stops]
    return zip(stops, colors)
Exemplo n.º 15
0
def grad_end_position(*color_stops):
    color_stops = __color_stops(False, *color_stops)
    return NumberValue(__grad_end_position(False, color_stops))
Exemplo n.º 16
0

# ------------------------------------------------------------------------------
# Number functions

@register('percentage', 1)
def percentage(value):
    if not isinstance(value, NumberValue):
        raise TypeError("Expected number, got %r" % (value,))

    if not value.is_unitless:
        raise TypeError("Expected unitless number, got %r" % (value,))

    return value * NumberValue(100, unit='%')

CORE_LIBRARY.add(NumberValue.wrap_python_function(abs), 'abs', 1)
CORE_LIBRARY.add(NumberValue.wrap_python_function(round), 'round', 1)
CORE_LIBRARY.add(NumberValue.wrap_python_function(math.ceil), 'ceil', 1)
CORE_LIBRARY.add(NumberValue.wrap_python_function(math.floor), 'floor', 1)


# ------------------------------------------------------------------------------
# List functions
def __parse_separator(separator, default_from=None):
    if separator is None:
        return None
    separator = StringValue(separator).value
    if separator == 'comma':
        return True
    elif separator == 'space':
        return False
Exemplo n.º 17
0
def green(color):
    c = ColorValue(color).value
    return NumberValue(c[1])
Exemplo n.º 18
0
def sprite_map(g, **kwargs):
    """
    Generates a sprite map from the files matching the glob pattern.
    Uses the keyword-style arguments passed in to control the placement.
    """
    g = StringValue(g).value

    if not Image:
        raise Exception("Images manipulation require PIL")

    if g in sprite_maps:
        sprite_maps[glob]["*"] = datetime.datetime.now()
    elif ".." not in g:  # Protect against going to prohibited places...
        vertical = kwargs.get("direction", "vertical") == "vertical"
        repeat = StringValue(kwargs.get("repeat", "no-repeat"))
        position = NumberValue(kwargs.get("position", 0))
        collapse_x = NumberValue(kwargs.get("collapse_x", 0))
        collapse_y = NumberValue(kwargs.get("collapse_y", 0))
        if position and position > -1 and position < 1:
            position.units = {"%": _units_weights.get("%", 1), "_": "%"}

        dst_colors = kwargs.get("dst_color")
        if isinstance(dst_colors, ListValue):
            dst_colors = [list(ColorValue(v).value[:3]) for n, v in dst_colors.items() if v]
        else:
            dst_colors = [list(ColorValue(dst_colors).value[:3])] if dst_colors else []

        src_colors = kwargs.get("src_color")
        if isinstance(src_colors, ListValue):
            src_colors = [tuple(ColorValue(v).value[:3]) if v else (0, 0, 0) for n, v in src_colors.items()]
        else:
            src_colors = [tuple(ColorValue(src_colors).value[:3]) if src_colors else (0, 0, 0)]

        len_colors = max(len(dst_colors), len(src_colors))
        dst_colors = (dst_colors * len_colors)[:len_colors]
        src_colors = (src_colors * len_colors)[:len_colors]

        spacing = kwargs.get("spacing", 0)
        if isinstance(spacing, ListValue):
            spacing = [int(NumberValue(v).value) for n, v in spacing.items()]
        else:
            spacing = [int(NumberValue(spacing).value)]
        spacing = (spacing * 4)[:4]

        if callable(config.STATIC_ROOT):
            glob_path = g
            rfiles = files = sorted(config.STATIC_ROOT(g))
        else:
            glob_path = os.path.join(config.STATIC_ROOT, g)
            files = glob.glob(glob_path)
            files = sorted((f, None) for f in files)
            rfiles = [(f[len(config.STATIC_ROOT) :], s) for f, s in files]

        if not files:
            log.error("Nothing found at '%s'", glob_path)
            return StringValue(None)

        times = []
        for file, storage in files:
            try:
                d_obj = storage.modified_time(file)
                times.append(int(time.mktime(d_obj.timetuple())))
            except:
                times.append(int(os.path.getmtime(file)))

        map_name = os.path.normpath(os.path.dirname(g)).replace("\\", "_").replace("/", "_")
        key = list(zip(*files)[0]) + times + [repr(kwargs), config.ASSETS_URL]
        key = map_name + "-" + base64.urlsafe_b64encode(hashlib.md5(repr(key)).digest()).rstrip("=").replace("-", "_")
        asset_file = key + ".png"
        asset_path = os.path.join(config.ASSETS_ROOT, asset_file)

        try:
            asset, map, sizes = pickle.load(open(asset_path + ".cache"))
            sprite_maps[asset] = map
        except:

            def images():
                for file, storage in files:
                    yield Image.open(storage.open(file)) if storage is not None else Image.open(file)

            names = tuple(os.path.splitext(os.path.basename(file))[0] for file, storage in files)
            positions = []
            spacings = []
            tot_spacings = []
            for name in names:
                name = name.replace("-", "_")
                _position = kwargs.get(name + "_position")
                if _position is None:
                    _position = position
                else:
                    _position = NumberValue(_position)
                    if _position and _position > -1 and _position < 1:
                        _position.units = {"%": _units_weights.get("%", 1), "_": "%"}
                positions.append(_position)
                _spacing = kwargs.get(name + "_spacing")
                if _spacing is None:
                    _spacing = spacing
                else:
                    if isinstance(_spacing, ListValue):
                        _spacing = [int(NumberValue(v).value) for n, v in _spacing.items()]
                    else:
                        _spacing = [int(NumberValue(_spacing).value)]
                    _spacing = (_spacing * 4)[:4]
                spacings.append(_spacing)
                if _position and _position.unit != "%":
                    if vertical:
                        if _position > 0:
                            tot_spacings.append((_spacing[0], _spacing[1], _spacing[2], _spacing[3] + _position))
                    else:
                        if _position > 0:
                            tot_spacings.append((_spacing[0] + _position, _spacing[1], _spacing[2], _spacing[3]))
                else:
                    tot_spacings.append(_spacing)

            sizes = tuple((collapse_x or image.size[0], collapse_y or image.size[1]) for image in images())

            _spacings = zip(*tot_spacings)
            if vertical:
                width = max(zip(*sizes)[0]) + max(_spacings[1]) + max(_spacings[3])
                height = sum(zip(*sizes)[1]) + sum(_spacings[0]) + sum(_spacings[2])
            else:
                width = sum(zip(*sizes)[0]) + sum(_spacings[1]) + sum(_spacings[3])
                height = max(zip(*sizes)[1]) + max(_spacings[0]) + max(_spacings[2])

            new_image = Image.new(mode="RGBA", size=(width, height), color=(0, 0, 0, 0))

            offsets_x = []
            offsets_y = []
            offset = 0
            for i, image in enumerate(images()):
                spacing = spacings[i]
                position = positions[i]
                iwidth, iheight = image.size
                width, height = sizes[i]
                if vertical:
                    if position and position.unit == "%":
                        x = width * position.value - (spacing[3] + height + spacing[1])
                    elif position.value < 0:
                        x = width + position.value - (spacing[3] + height + spacing[1])
                    else:
                        x = position.value
                    offset += spacing[0]
                    for i, dst_color in enumerate(dst_colors):
                        src_color = src_colors[i]
                        pixdata = image.load()
                        for _y in xrange(image.size[1]):
                            for _x in xrange(image.size[0]):
                                pixel = pixdata[_x, _y]
                                if pixel[:3] == src_color:
                                    pixdata[_x, _y] = tuple(
                                        [int(c) for c in dst_color] + [pixel[3] if len(pixel) == 4 else 255]
                                    )
                    if iwidth != width or iheight != height:
                        cy = 0
                        while cy < iheight:
                            cx = 0
                            while cx < iwidth:
                                cropped_image = image.crop((cx, cy, cx + width, cy + height))
                                new_image.paste(cropped_image, (int(x + spacing[3]), offset), cropped_image)
                                cx += width
                            cy += height
                    else:
                        new_image.paste(image, (int(x + spacing[3]), offset))
                    offsets_x.append(x)
                    offsets_y.append(offset - spacing[0])
                    offset += height + spacing[2]
                else:
                    if position and position.unit == "%":
                        y = height * position.value - (spacing[0] + height + spacing[2])
                    elif position.value < 0:
                        y = height + position.value - (spacing[0] + height + spacing[2])
                    else:
                        y = position.value
                    offset += spacing[3]
                    for i, dst_color in enumerate(dst_colors):
                        src_color = src_colors[i]
                        pixdata = image.load()
                        for _y in xrange(image.size[1]):
                            for _x in xrange(image.size[0]):
                                pixel = pixdata[_x, _y]
                                if pixel[:3] == src_color:
                                    pixdata[_x, _y] = tuple(
                                        [int(c) for c in dst_color] + [pixel[3] if len(pixel) == 4 else 255]
                                    )
                    if iwidth != width or iheight != height:
                        cy = 0
                        while cy < iheight:
                            cx = 0
                            while cx < iwidth:
                                cropped_image = image.crop((cx, cy, cx + width, cy + height))
                                new_image.paste(cropped_image, (offset, int(y + spacing[0])), cropped_image)
                                cx += width
                            cy += height
                    else:
                        new_image.paste(image, (offset, int(y + spacing[0])))
                    offsets_x.append(offset - spacing[3])
                    offsets_y.append(y)
                    offset += width + spacing[1]

            try:
                new_image.save(asset_path)
            except IOError:
                log.exception("Error while saving image")
            filetime = int(time.mktime(datetime.datetime.now().timetuple()))

            url = "%s%s?_=%s" % (config.ASSETS_URL, asset_file, filetime)
            asset = 'url("%s") %s' % (escape(url), repeat)
            # Use the sorted list to remove older elements (keep only 500 objects):
            if len(sprite_maps) > 1000:
                for a in sorted(sprite_maps, key=lambda a: sprite_maps[a]["*"], reverse=True)[500:]:
                    del sprite_maps[a]
            # Add the new object:
            map = dict(zip(names, zip(sizes, rfiles, offsets_x, offsets_y)))
            map["*"] = datetime.datetime.now()
            map["*f*"] = asset_file
            map["*k*"] = key
            map["*n*"] = map_name
            map["*t*"] = filetime

            tmp_dir = config.ASSETS_ROOT
            cache_tmp = tempfile.NamedTemporaryFile(delete=False, dir=tmp_dir)
            pickle.dump((asset, map, zip(files, sizes)), cache_tmp)
            cache_tmp.close()
            os.rename(cache_tmp.name, asset_path + ".cache")

            sprite_maps[asset] = map
        for file, size in sizes:
            _image_size_cache[file] = size
    ret = StringValue(asset)
    return ret