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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
from nodebox_web.web.url import URLAccumulator
from urllib import quote
from nodebox_web.web.cache import Cache
import simplejson
def clear_cache():
Cache("colr").clear()
### COLOR MODELS #####################################################################################
def hex_to_rgb(hex):
hex = hex.lstrip("#")
if len(hex) < 6:
hex += hex[-1] * (6-len(hex))
r, g, b = hex[0:2], hex[2:4], hex[4:]
r, g, b = [int(n, 16) for n in (r, g, b)]
return (r/255.0, g/255.0, b/255.0)
### COLR THEME #######################################################################################
class ColrTheme(list):
def __init__(self):
self.id = 0
self.author = u""
self.label = u""
self.tags = []
def _darkest(self):
""" Returns the darkest swatch.
Knowing the contract between a light and a dark swatch
can help us decide how to display readable typography.
"""
rgb, n = (1.0, 1.0, 1.0), 3.0
for r,g,b in self:
if r+g+b < n:
rgb, n = (r,g,b), r+g+b
return rgb
darkest = property(_darkest)
def _lightest(self):
""" Returns the lightest swatch.
"""
rgb, n = (0.0, 0.0, 0.0), 0.0
for r,g,b in self:
if r+g+b > n:
rgb, n = (r,g,b), r+g+b
return rgb
lightest = property(_lightest)
def draw(self, x, y, w=40, h=40):
try: from nodebox_web.web.web import _ctx
except: pass
from nodebox.graphics import RGB
for r,g,b in self:
_ctx.colormode(RGB)
_ctx.fill(r,g,b)
_ctx.rect(x, y, w, h)
x += w
### KULER ############################################################################################
class Colr(list, URLAccumulator):
def __init__(self, q, page=0, wait=10, asynchronous=False, cached=True):
""" Parses color themes from Adobe Kuler.
Valid queries are "popular", "rating",
a theme id as an integer, or a search string.
"""
if cached:
cache = "colr"
else:
cache = None
url = "http://www.colr.org/json/"
if isinstance(q, int):
url += "scheme/" + str(q)
elif q in ["latest", "random"]:
url += "scheme/" + q
else:
url += "tag/" + quote(q)
# Refresh cached results every day
# for latest requests.
if q == "latest":
if cached and Cache(cache).age(url) > 0:
Cache(cache).remove(url)
if q == "random":
Cache(cache).remove(url)
URLAccumulator.__init__(self, url, wait, asynchronous, cache, type=".xml", throttle=3)
def load(self, data):
data = simplejson.loads(data)
for theme in data["schemes"]:
ct = ColrTheme()
ct.id = theme["id"]
ct.label = theme["id"]
ct.tags = [x["name"] for x in theme["tags"]]
for clr in theme["colors"]:
if len(clr) == 3: clr += clr
ct.append(hex_to_rgb(clr))
self.append(ct)
######################################################################################################
def latest(page=0, wait=10, asynchronous=False, cached=True):
return Colr("latest", page, wait, asynchronous, cached)[0]
def random(page=0, wait=10, asynchronous=False, cached=True):
return Colr("random", page, wait, asynchronous, cached)[0]
def search(q, page=0, wait=10, asynchronous=False, cached=True):
return Colr(str(q), page, wait, asynchronous, cached)
def search_by_id(id, page=0, wait=10, asynchronous=False, cached=True):
return Colr(int(id), page, wait, asynchronous, cached)
######################################################################################################
def preview(theme):
try: from web import _ctx
except: pass
# Use the darkest swatch as background.
r,g,b = theme.darkest
c = _ctx.color(r, g, b)
c.brightness *= 0.5
c.brightness = max(0.1, c.brightness)
c.brightness = 0.15
_ctx.background(c)
#_ctx.background(0.1)
from random import random, choice
for i in range(100):
r,g,b = choice(theme)
_ctx.fill(r,g,b)
r,g,b = choice(theme)
_ctx.stroke(r,g,b)
_ctx.strokewidth(random()*30)
r = random()*100
_ctx.oval(random()*400, random()*400, r, r)
# Draw swatches.
_ctx.nostroke()
theme.draw(20, 480)
# Theme info colored in the lightest swatch.
r,g,b = theme.lightest
_ctx.fontsize(18)
_ctx.fill(r,g,b)
_ctx.text(theme.label + u" | " + str(theme.id), 20, 540)
_ctx.fontsize(_ctx.fontsize()/2)
_ctx.text(", ".join(theme.tags), 20, 555, width=400)
#web = ximport("web")
#size(500, 650)
#themes = search("office")
#theme = themes[0]
#preview(theme)
|