def get_settings(self, rule): """Get the settings.""" obj = { "bold": False, "italic": False, "underline": False, "foreground": None, "background": None, "border": None } if re.search(r"(?<!-)\bfont-weight\s*:\s*bold", rule) is not None: obj["bold"] = True if re.search(r"(?<!-)\bfont-style\s*:\s*italic", rule) is not None: obj["italic"] = True if re.search(r"(?<!-)\btext-decoration\s*:\s*underline", rule) is not None: obj["underline"] = True m = re.search(r"(?<!-)\bborder\s*:\s*[\d]+px\s*\w+\s*(?P<color>#[a-zA-z\d]{6}|#[a-zA-z\d]{3}|\w+)", rule) if m: color = m.group('color') obj["border"] = normalize_hex(color) if color.startswith('#') else name_to_hex(color) m = re.search(r"(?<!-)\bcolor\s*:\s*(?P<color>#[a-zA-z\d]{6}|#[a-zA-z\d]{3}|\w+)", rule) if m: color = m.group('color') obj["foreground"] = normalize_hex(color) if color.startswith('#') else name_to_hex(color) m = re.search(r"(?<!-)\bbackground-color\s*:\s*(?P<color>#[a-zA-z\d]{6}|#[a-zA-z\d]{3}|\w+)", rule) if m: color = m.group('color') obj["background"] = normalize_hex(color) if color.startswith('#') else name_to_hex(color) return obj
def __init__(self, definition, opacity=None): if not isinstance(definition, str): raise Exception("Unable to parse color %s" % definition) color_definition = definition.lower() self.opacity = float(1) if color_definition == "transparent": self.opacity = 0.0 self.value = '#000000' elif color_definition.startswith("rgb("): m = RGB_PARSER.match(color_definition) color_rgb = (int(m.group(1)), int(m.group(2)), int(m.group(3))) self.value = webcolors.rgb_to_hex(color_rgb) elif color_definition.startswith("rgba("): m = RGBA_PARSER.match(color_definition) color_rgb = (int(m.group(1)), int(m.group(2)), int(m.group(3))) self.value = webcolors.rgb_to_hex(color_rgb) self.opacity = float(m.group(4)) elif color_definition.startswith("#"): self.value = webcolors.normalize_hex(color_definition) else: self.value = webcolors.rgb_to_hex( webcolors.html5_parse_legacy_color(color_definition)) if opacity is not None: self.opacity = opacity
def color_object_to_tuple( color: Union[Tuple[int, ...], str]) -> Optional[Tuple[int, ...]]: # see if it's already a color tuple if isinstance(color, tuple) and len(color) in [3, 4, 5]: return color # can't convert non-string if not isinstance(color, str): return None color = color.strip() # try to convert from an english name with contextlib.suppress(Exception): return cast(Tuple[int, int, int], webcolors.name_to_rgb(color)) # try to convert an web hex code with contextlib.suppress(Exception): return cast( Tuple[int, int, int], webcolors.hex_to_rgb(webcolors.normalize_hex(color)), ) # try to convert a string RGB tuple with contextlib.suppress(Exception): val = ast.literal_eval(color) if type(val) is not tuple or len(val) not in [3, 4, 5]: raise Exception return val return None
def _get_color(color: str): try: return webcolors.normalize_hex(color) except ValueError: pass try: return webcolors.name_to_hex(color) except ValueError: pass
def normalize_color_to_hex(self, color_string): try: return webcolors.normalize_hex("#" + color_string) except ValueError: pass try: return webcolors.name_to_hex(color_string) except ValueError: pass try: return webcolors.normalize_hex(color_string) except ValueError: pass if color_string: logger.error('background_color value could not be parsed')
def test_html_definition_conformance(self): """ Compare the results of name-to-hex conversion to the canonical hex values provided in the HTML 4 specification. """ for color, hex_value in HTML4_COLOR_DEFINITIONS.items(): normalized = webcolors.normalize_hex(hex_value) assert normalized == webcolors.name_to_hex(color)
def normalize_hex(value): """ Normalize a hexadecimal color value to a string followed by six lowercase hexadecimal digits (what HTML5 terms a “valid lowercase simple color”) :param hex_value: The hexadecimal color value to normalize. :returns: A normalized 6-digit hexadecimal color prepended with a # """ return webcolors.normalize_hex(value)
def test_normalize_hex(self): """ Hexadecimal normalization normalizes valid hex color codes to 6 digits, lowercase. """ test_pairs = ((u'#0099cc', u'#0099cc'), (u'#0099CC', u'#0099cc'), (u'#09c', u'#0099cc'), (u'#09C', u'#0099cc')) for pair in test_pairs: self.assertEqual(pair[1], webcolors.normalize_hex(pair[0]))
def convert_color_to_rrggbb(color): """The color in "#RRGGBB" format. :return: the :attr:`color` in "#RRGGBB" format """ if not color.startswith("#"): rgb = webcolors.html5_parse_legacy_color(color) hex_color = webcolors.html5_serialize_simple_color(rgb) else: hex_color = color return webcolors.normalize_hex(hex_color)
def test_normalize_hex(self): """ Hexadecimal normalization normalizes valid hex color codes to 6 digits, lowercase. """ test_pairs = ((u'#0099cc', u'#0099cc'), (u'#0099CC', u'#0099cc'), (u'#09c', u'#0099cc'), (u'#09C', u'#0099cc')) for raw, normalized in test_pairs: assert normalized == webcolors.normalize_hex(raw)
def convert_color_to_rrggbb(color): """The color in "#RRGGBB" format. :return: the :attr:`color` in "#RRGGBB" format """ if not color.startswith("#"): rgb = webcolors.html5_parse_legacy_color(color) hex_color = webcolors.html5_serialize_simple_color(rgb) else: hex_color = color return webcolors.normalize_hex(hex_color)
def get_settings(self, rule): """Get the settings.""" obj = { "bold": False, "italic": False, "underline": False, "foreground": None, "background": None, "border": None } if re.search(r"(?<!-)\bfont-weight\s*:\s*bold", rule) is not None: obj["bold"] = True if re.search(r"(?<!-)\bfont-style\s*:\s*italic", rule) is not None: obj["italic"] = True if re.search(r"(?<!-)\btext-decoration\s*:\s*underline", rule) is not None: obj["underline"] = True m = re.search( r"(?<!-)\bborder\s*:\s*[\d]+px\s*\w+\s*(?P<color>#[a-zA-z\d]{6}|#[a-zA-z\d]{3}|\w+)", rule) if m: color = m.group('color') obj["border"] = normalize_hex(color) if color.startswith( '#') else name_to_hex(color) m = re.search( r"(?<!-)\bcolor\s*:\s*(?P<color>#[a-zA-z\d]{6}|#[a-zA-z\d]{3}|\w+)", rule) if m: color = m.group('color') obj["foreground"] = normalize_hex(color) if color.startswith( '#') else name_to_hex(color) m = re.search( r"(?<!-)\bbackground-color\s*:\s*(?P<color>#[a-zA-z\d]{6}|#[a-zA-z\d]{3}|\w+)", rule) if m: color = m.group('color') obj["background"] = normalize_hex(color) if color.startswith( '#') else name_to_hex(color) return obj
def get_rgb_color(color) -> Tuple[float, float, float]: if isinstance(color, str): if color and color[0] == "#": color = webcolors.normalize_hex(color) return normalize_color(webcolors.hex_to_rgb(color)) else: return normalize_color(webcolors.name_to_rgb(color)) assert len(color) == 3 for v in color: assert isinstance(v, float) return tuple(color)
def configureProperties(self, properties): """Configure the menue from tmx properties.""" for item in properties: if item == 'Margin': self._margin= int(properties[item]) elif item == 'ResourcePath': self._resourcePath = properties[item] elif item == 'SoundButton': self._soundButton = properties[item] elif item == 'SoundMove': self._soundMove = properties[item] elif item == 'Font': self._fontProperties.FontName = properties[item] elif item == 'FontSize': self._fontProperties.Size = int(properties[item]) elif item == 'FontColor': self._fontProperties.Color = webcolors.hex_to_rgb(webcolors.normalize_hex(properties[item])) elif item == 'FontBackground': self._fontProperties.Background = webcolors.hex_to_rgb(webcolors.normalize_hex(properties[item])) if self._resourcePath: for item in properties: if item.startswith('MenuItem'): newEntry = self.__parseMenueItemEntry(self._resourcePath, item, properties[item]) newEntry.configure() self._menuItems.append(newEntry) if 'Pointer' in properties: self.pointerImage = MenuAnimationInfo.loadAnimationResourceFile(self._resourcePath, self.parseImagePath(properties['Pointer'])).convert() # Make it transparent self.pointerImage.set_colorkey(self.pointerImage.get_at((0,0))) else: raise SystemError("No pointer image defined!") self._menuItems.sort(key = lambda item: item.id) pass
def test_normalize_hex(self): """ Hexadecimal normalization normalizes valid hex color codes to 6 digits, lowercase. """ test_pairs = ((u'#0099cc', u'#0099cc'), (u'#0099CC', u'#0099cc'), (u'#09c', u'#0099cc'), (u'#09C', u'#0099cc')) for pair in test_pairs: self.assertEqual(pair[1], webcolors.normalize_hex(pair[0]))
def get_colours_from_message(message, reg=re.compile(r'#[0-9A-F]{6}|#[0-9A-F]{3}\b', re.I)): """ Harvest hex colour values of 3 or 6 characters in length from the message string and return a normalized list. """ # Replace all '0x' with '#' message = message.replace('0x', '#') lines = message.split('\n') normalized_colours = [] for line in lines: colours = reg.findall(line) if colours: normalized_colours.append([normalize_hex(colour) for colour in colours]) return normalized_colours
def test_normalize_hex(self): """ Hexadecimal normalization normalizes valid hex color codes to 6 digits, lowercase. """ test_pairs = ( (u'#0099cc', u'#0099cc'), (u'#0099CC', u'#0099cc'), (u'#09c', u'#0099cc'), (u'#09C', u'#0099cc') ) for raw, normalized in test_pairs: assert normalized == webcolors.normalize_hex(raw)
def color_page(query): color = None # Hex (000, 000000) if re.search(COLOR_HEX_PATTERN, query): color = normalize_hex(f"#{query}") # Name (black) if re.search(COLOR_NAME_PATTERN, query): try: color = name_to_hex(query) except ValueError: pass if not color: return render_template("pages/color_not_found.html") return render_template("pages/color.html", color=color)
def convert_to_hex(colors): try: hex_list = [] for color in colors: if not color.startswith('inherit') and not color.startswith( 'transparent'): if color.startswith('rgba'): color = color.replace('rgba', '').replace('(', '').replace( ')', '').replace(' ', '') c = color.split(',') r = int(c[0]) g = int(c[1]) b = int(c[2]) a = float(c[3]) color = webcolors.rgb_to_hex((r, g, b, a)) print color elif color.startswith('rgb'): color = color.replace('rgb', '').replace('(', '').replace( ')', '').replace(' ', '') c = color.split(',') r = int(c[0]) g = int(c[1]) b = int(c[2]) color = webcolors.rgb_to_hex((r, g, b)) print color elif color.startswith('#'): color = webcolors.normalize_hex(color) print color else: try: color = webcolors.name_to_hex(color) except: pass hex_list.append(color) hex_list = list(set(hex_list)) return hex_list except exceptions.Exception as e: logfile.write("!ERROR! FUNCTION: convert_to_hex " + "\n") finally: pass
def convert_colour(input_colour): input_colour = input_colour.strip('#') try: colour = input_colour int(colour, 16) if len(colour) == 3: colour = webcolors.normalize_hex("#" + colour).strip('#') if len(colour) == 6: return discord.Colour.from_rgb(int(colour[:2], 16), int(colour[2:4], 16), int(colour[4:6], 16)) else: raise commands.BadArgument() except ValueError: try: return discord.Colour.from_rgb( *(webcolors.name_to_rgb(input_colour.replace(" ", "")))) except ValueError: raise commands.BadArgument()
def convert(paths, attributes, viewbox): for path, path_attributes in zip(paths, attributes): for subpath in path.continuous_subpaths(): yield ("START", *normalize_coord(subpath[0].start, viewbox)) for segment in subpath: if isinstance(segment, Line): yield ("MOVE", *normalize_coord(segment.end, viewbox)) else: for i in range(0, CURVE_RESOLUTION): sample = segment.point(i / (CURVE_RESOLUTION - 1)) yield ("MOVE", *normalize_coord(sample, viewbox)) if "fill" in path_attributes: fill = path_attributes["fill"] if fill.startswith("#"): yield ("FILL", *bytes.fromhex(normalize_hex(fill)[1:])) else: yield ("FILL", *name_to_rgb(fill)) else: yield ("FILL", *DEFAULT_COLOR)
def get_color(color: str) -> Optional[int]: color = color.strip().lower() # Attempt to convert from any color specification to hex. try: color = webcolors.name_to_hex(color) except ValueError: pass try: color = webcolors.normalize_hex(color) except ValueError: pass if len(color) != 7 or color[0] != '#': return None intval = int(color[1:], 16) if intval < 0 or intval > 0xFFFFFF: return None return intval
def _parseColor(self, val): """ Parse a color definition. Returns a color in hex format, 'inherit', or 'none'. 'none' means that the geometry is not to be rendered. See: http://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint """ # http://www.w3.org/TR/SVG11/color.html # http://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#color-units if val[0] == " ": val = val.strip() if val[0] == '#': return normalize_hex(val) elif val.startswith('rgba'): floats = parseFloats(val[5:-1]) if len(floats) == 4: log.warn("opacity in rgba is ignored, \ use stroke-opacity/fill-opacity instead") return rgb_to_hex(tuple(floats[:3])) elif val.startswith('rgb'): floats = parseFloats(val[4:-1]) if len(floats) == 3: return rgb_to_hex(tuple(floats)) elif val == 'none': # 'none' means the geometry is not to be filled or stroked # http://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint return 'none' elif val.startswith('hsl'): log.warn("hsl/hsla color spaces are not supported") elif val.startswith('url'): log.warn("defs are not supported"); elif val in css3_names_to_hex: # named colors return css3_names_to_hex[val] elif val in ['currentColor', 'inherit']: return 'inherit' else: log.warn("invalid color, skipped: " + str(val)) return 'inherit'
def _parseColor(self, val): """ Parse a color definition. Returns a color in hex format, 'inherit', or 'none'. 'none' means that the geometry is not to be rendered. See: http://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint """ # http://www.w3.org/TR/SVG11/color.html # http://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#color-units if val[0] == " ": val = val.strip() if val[0] == '#': return normalize_hex(val) elif val.startswith('rgba'): floats = parseFloats(val[5:-1]) if len(floats) == 4: log.warn("opacity in rgba is ignored, \ use stroke-opacity/fill-opacity instead") return rgb_to_hex(tuple(floats[:3])) elif val.startswith('rgb'): floats = parseFloats(val[4:-1]) if len(floats) == 3: return rgb_to_hex(tuple(floats)) elif val == 'none': # 'none' means the geometry is not to be filled or stroked # http://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint return 'none' elif val.startswith('hsl'): log.warn("hsl/hsla color spaces are not supported") elif val.startswith('url'): log.warn("defs are not supported") elif val in css3_names_to_hex: # named colors return css3_names_to_hex[val] elif val in ['currentColor', 'inherit']: return 'inherit' else: log.warn("invalid color, skipped: " + str(val)) return 'inherit'
def color_object_to_tuple(color): global webcolors_available # see if it's already a color tuple if type(color) is tuple and len(color) == 3: return color # can't convert non-string if type(color) is not str: return None color = color.strip() if webcolors_available: # try to convert from an english name try: return webcolors.name_to_rgb(color) except ValueError: pass except: pass # try to convert an web hex code try: return webcolors.hex_to_rgb(webcolors.normalize_hex(color)) except ValueError: pass except: pass # try to convert a string RGB tuple try: val = ast.literal_eval(color) if type(val) is not tuple or len(val) != 3: raise Exception return val except: pass return None
def color_object_to_tuple(color): global webcolors_available # see if it's already a color tuple if type(color) is tuple and len(color) == 3: return color # can't convert non-string if type(color) is not str: return None color = color.strip() if webcolors_available: # try to convert from an english name try: return webcolors.name_to_rgb(color) except ValueError: pass except: pass # try to convert an web hex code try: return webcolors.hex_to_rgb(webcolors.normalize_hex(color)) except ValueError: pass except: pass # try to convert a string RGB tuple try: val = ast.literal_eval(color) if type(val) is not tuple or len(val) != 3: raise Exception return val except: pass return None
def get(self, request, *args, **kwargs): job = get_object_or_404(Job, pk=self.kwargs.get('pk')) feature_types = FeatureType.objects.all() aoi_count = job.total_count() aoi_complete = job.complete_count() aoi_work = job.in_work_count() cookie_url_trailer = get_cookie_trailer(request) description = 'Job #'+str(job.id)+': '+str(job.name)+'\n'+str(job.project.name)+'\n' if aoi_count == 0: output = '<?xml version="1.0" encoding="UTF-8"?>\n' output += '<kml xmlns="http://www.opengis.net/kml/2.2">\n' output += ' <Document>\n' output += ' <name>Empty Job</name>\n' output += ' <description>'+description+'</description>\n' output += ' </Document>\n' output += '</kml>\n' return HttpResponse(output, mimetype="application/vnd.google-earth.kml+xml", status=200) aoi_comp_pct = (100 * float(aoi_complete)/float(aoi_count)) aoi_work_pct = int(100 * float(aoi_work)/float(aoi_count)) aoi_tot_pct = int(100 * float(aoi_work+aoi_complete)/float(aoi_count)) doc_name = 'GeoQ C:'+str(aoi_complete)+', W:'+str(aoi_work)+', Tot:'+str(aoi_count)+' ['+str(aoi_tot_pct)+'%]' description = description + 'Complete Cells: ' + str(aoi_complete) + ' ['+str(aoi_comp_pct)+'%], In Work: ' + str(aoi_work) + ' ['+str(aoi_work_pct)+'%], Total: ' + str(aoi_count) output = '<?xml version="1.0" encoding="UTF-8"?>\n' output += '<kml xmlns="http://www.opengis.net/kml/2.2">\n' output += ' <Document>\n' output += ' <name>'+doc_name+'</name>\n' output += ' <description>'+description+'</description>\n' output += ' <Style id="geoq_inwork">\n' output += ' <LineStyle>\n' output += ' <width>4</width>\n' output += ' <color>7f0186cf</color>\n' output += ' </LineStyle>\n' output += ' <PolyStyle>\n' output += ' <fill>0</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' output += ' </Style>\n' output += ' <Style id="geoq_complete">\n' output += ' <LineStyle>\n' output += ' <width>3</width>\n' output += ' <color>7f0101cf</color>\n' output += ' </LineStyle>\n' output += ' <PolyStyle>\n' output += ' <fill>0</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' output += ' </Style>\n' output += ' <Style id="geoq_unassigned">\n' output += ' <LineStyle>\n' output += ' <width>2</width>\n' output += ' <color>7f00ff00</color>\n' output += ' </LineStyle>\n' output += ' <PolyStyle>\n' output += ' <fill>0</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' output += ' </Style>\n' for feature in feature_types: output += ' <Style id="geoq_'+str(feature.id)+'">\n' out_color = '7f0066ff' if feature.style == None: output += ' </Style>\n' continue if feature.style.has_key('color'): color = feature.style['color'] #convert to a kml-recognized color if color[0:1] == '#' and len(color) == 4: color = normalize_hex(color) try: c = name_to_hex(color) out_color = '7f' + c[5:7] + c[3:5] + c[1:3] except Exception: out_color = '7f0066ff' output += ' <PolyStyle>\n' output += ' <color>'+out_color+'</color>\n' output += ' <colorMode>normal</colorMode>\n' output += ' <fill>1</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' if feature.style.has_key('weight'): output += ' <LineStyle>\n' output += ' <width>'+str(feature.style['weight'])+'</width>\n' if feature.style.has_key('color'): output += ' <color>'+out_color+'</color>\n' output += ' </LineStyle>\n' if feature.style.has_key('iconUrl'): icon_url = str(feature.style['iconUrl']) if not icon_url.startswith("http"): icon_url = request.build_absolute_uri(icon_url) else: icon_url += cookie_url_trailer output += ' <IconStyle>\n' output += ' <Icon>\n' output += ' <href>' + xml_escape(icon_url) + '</href>\n' output += ' </Icon>\n' output += ' </IconStyle>\n' output += ' </Style>\n' # locations = job.feature_set.all().order_by('template') locations = job.feature_set.all()\ .extra(tables=['maps_featuretype'])\ .extra(where=['maps_featuretype.id=maps_feature.template_id'])\ .order_by('maps_featuretype.name') last_template = "" skip_the_first = True template_has_started = False for loc in locations: template_name = str(loc.template.name) if template_name != last_template: if skip_the_first: skip_the_first = False else: output += ' </Folder>\n' output += ' <Folder><name>'+template_name+'</name>\n' last_template = template_name template_has_started = True analyst_name = str(loc.analyst.username) dtg = str(loc.created_at) job_id = str(loc.job.id) #TODO: Add links to Jobs and Projects datetime_obj = datetime.strptime(dtg, "%Y-%m-%d %H:%M:%S.%f+00:00") datetime_obj_utc = datetime_obj.replace(tzinfo=timezone('UTC')) date_time = datetime_obj_utc.strftime('%Y-%m-%dT%H:%M:%SZ') date_time_desc = datetime_obj_utc.strftime('%Y-%m-%d %H:%M:%S') desc = 'Posted by '+analyst_name+' at '+date_time_desc+' Zulu (UTC) in Job #'+job_id #TODO: Add more details #TODO: Add links to linked objects #Simplify polygons to reduce points in complex shapes if loc.the_geom.num_coords > 0: #skip empty locations simplegeom = loc.the_geom.simplify(0.0002) if simplegeom.num_coords > 0: kml = str(loc.the_geom.simplify(0.0002).kml) else: kml = str(loc.the_geom.kml) if '<Polygon><outerBoundaryIs><LinearRing><coordinates>' in kml: add_text = '<altitudeMode>clampToGround</altitudeMode>' kml = kml.replace('<coordinates>', add_text+'<coordinates>') kml = kml.replace('</outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing>', '') output += ' <Placemark><name>'+template_name+'</name>\n' output += ' <TimeStamp><when>'+date_time+'</when></TimeStamp>\n' output += ' <description>'+desc+'</description>\n' output += ' <styleUrl>#geoq_'+str(loc.template.id)+'</styleUrl>\n' output += ' '+str(kml)+'\n' output += ' </Placemark>\n' if template_has_started: output += ' </Folder>\n' output += ' <Folder><name>Work Cells</name>\n' aois = job.aois.order_by('status') for aoi in aois: style = 'complete' if aoi.status == 'In work': style = 'inwork' if aoi.status == 'Unassigned': style = 'unassigned' aoi_name = "#"+str(aoi.id)+", "+str(aoi.status)+" - Priority:"+str(aoi.priority) kml = str(aoi.polygon.simplify(0.0002).kml) if '<Polygon><outerBoundaryIs><LinearRing><coordinates>' in kml: add_text = '<tessellate>1</tessellate><altitudeMode>clampToGround</altitudeMode>' kml = kml.replace('<coordinates>', add_text+'<coordinates>') output += ' <Placemark>\n' output += ' <name>'+aoi_name+'</name>\n' output += ' <styleUrl>#geoq_'+style+'</styleUrl>\n' output += ' '+kml+'\n' output += ' </Placemark>\n' output += ' </Folder>\n' output += ' </Document>\n' output += '</kml>' return HttpResponse(output, mimetype="application/vnd.google-earth.kml+xml", status=200)
def getColor(color): ''' Convert any specification of a color to a hexadecimal color used by matplotlib. >>> graph.utilities.getColor('red') '#ff0000' >>> graph.utilities.getColor('r') '#ff0000' >>> graph.utilities.getColor('Steel Blue') '#4682b4' >>> graph.utilities.getColor('#f50') '#ff5500' >>> graph.utilities.getColor([0.5, 0.5, 0.5]) '#808080' >>> graph.utilities.getColor(0.8) '#cccccc' >>> graph.utilities.getColor([0.8]) '#cccccc' >>> graph.utilities.getColor([255, 255, 255]) '#ffffff' Invalid colors raise GraphExceptions: >>> graph.utilities.getColor('l') Traceback (most recent call last): music21.graph.utilities.GraphException: invalid color abbreviation: l >>> graph.utilities.getColor('chalkywhitebutsortofgreenish') Traceback (most recent call last): music21.graph.utilities.GraphException: invalid color name: chalkywhitebutsortofgreenish >>> graph.utilities.getColor(True) Traceback (most recent call last): music21.graph.utilities.GraphException: invalid color specification: True ''' # expand a single value to three if common.isNum(color): color = [color, color, color] if isinstance(color, str): if color[0] == '#': # assume is hex # this will expand three-value codes, and check for badly # formed codes return webcolors.normalize_hex(color) color = color.lower().replace(' ', '') # check for one character matplotlib colors if len(color) == 1: colorMap = {'b': 'blue', 'g': 'green', 'r': 'red', 'c': 'cyan', 'm': 'magenta', 'y': 'yellow', 'k': 'black', 'w': 'white'} try: color = colorMap[color] except KeyError: raise GraphException(f'invalid color abbreviation: {color}') try: return webcolors.name_to_hex(color) except ValueError: # no color match raise GraphException(f'invalid color name: {color}') elif common.isListLike(color): percent = False for sub in color: if sub < 1: percent = True break if percent: if len(color) == 1: color = [color[0], color[0], color[0]] # convert to 0 100% values as strings with % symbol colorStrList = [str(x * 100) + '%' for x in color] return webcolors.rgb_percent_to_hex(colorStrList) else: # assume integers return webcolors.rgb_to_hex(tuple(color)) raise GraphException(f'invalid color specification: {color}')
def _build_line(self, route_master, itineraries): """Helper function to build a Line object Returns a initiated Line object from raw data """ osm_type = "relation" if len(itineraries) == 0: logging.warning( "Relation without valid members. Please fix in OpenStreetMap") logging.warning(" https://osm.org/relation/%s", route_master.id) logging.warning(" Skipping whole route without valid members.") return None if 'ref' in route_master.tags: ref = route_master.tags['ref'] else: logging.warning( "Relation without 'ref'. Please fix in OpenStreetMap") logging.warning(" https://osm.org/relation/%s", route_master.id) # Check if a ref can be taken from one of the itineraries ref = False for itinerary in list(itineraries.values()): if not ref and itinerary.route_id: ref = itinerary.route_id logging.warning("Using 'ref' from member variant instead") logging.warning("%s", itinerary.osm_url) if not ref: ref = "" # Move to Elements class, once attributes with defaults play well # with inheritance https://github.com/python-attrs/attrs/issues/38 osm_url = "https://osm.org/" + str(osm_type) + "/" + str( route_master.id) if 'name' in route_master.tags: name = route_master.tags['name'] elif 'ref' in route_master.tags: name = route_master.tags['ref'] else: name = None # Normalize route color information if 'colour' in route_master.tags: try: # Check if colour is a valid hex format route_master.tags['colour'] = webcolors.normalize_hex( route_master.tags['colour']) except ValueError: try: # Convert web color names into rgb hex values route_master.tags['colour'] = webcolors.name_to_hex( route_master.tags['colour']) except ValueError: logging.warning("Invalid colour: %s found in OSM data", route_master.tags['colour']) # Create Line (route master) object line = Line(osm_id=route_master.id, osm_type=osm_type, osm_url=osm_url, tags=route_master.tags, name=name, route_id=ref) # Add Itinerary objects (route variants) to Line (route master) for itinerary in list(itineraries.values()): try: line.add_itinerary(itinerary) except ValueError: logging.warning( "Itinerary ID doesn't match line ID. Please fix in OSM.") logging.warning("%s", line.osm_url) itinerary.route_id = line.route_id line.add_itinerary(itinerary) return line
def getcolor(color): if color != "#": return webcolors.name_to_hex(color) else: return webcolors.normalize_hex(color)
def is_css_color_code(instance: object) -> bool: return webcolors.normalize_hex(instance)
def is_css_color_code(instance): try: webcolors.normalize_hex(instance) except (ValueError, TypeError): return False return True
def _scrape_team_colors(self, team_soup): def find_nearest_color(hex_color): # make hex rgb rgb_triplet = webcolors.hex_to_rgb(hex_color) min_colours = defaultdict() # {score: color name,..} for key, name in webcolors.CSS3_HEX_TO_NAMES.items(): r_c, g_c, b_c = webcolors.hex_to_rgb(key) rd = (r_c - rgb_triplet[0])**2 gd = (g_c - rgb_triplet[1])**2 bd = (b_c - rgb_triplet[2])**2 min_colours[rd + gd + bd] = name return (min_colours[min(min_colours.keys())]) team_colors = defaultdict(lambda: defaultdict(list)) # background colors first (kit) imgs = team_soup.find('td', attrs={'class': 'toccolours'}) if imgs: hexs = [] for ss in imgs.find_all('div', style=re.compile('background-color')): colcode = ss["style"].split('background-color:')[-1].replace( ';', '').strip() if len(colcode) == 7: hexs.append(colcode) for t in Counter(hexs).most_common(5): try: c = webcolors.hex_to_name(webcolors.normalize_hex(t[0])) except: c = find_nearest_color(t[0]) team_colors['kit']['hex'].append(t[0]) team_colors['kit']['name'].append(c) team_colors['kit']['name'] = list(set(team_colors['kit']['name'])) # team logos if not os.path.isdir('data_temp'): os.mkdir('data_temp') im_logo = team_soup.find('a', class_='image') with open('data_temp/logofile.png', 'wb') as f: f.write( requests.get('https:' + im_logo.find('img')['src']).content) i1 = cv2.imread('data_temp/logofile.png') rgbs = [] for x in range(i1.shape[0]): for y in range(i1.shape[1]): bgr = list(i1[x, y, :]) rgbs.append(tuple(bgr[::-1])) for t in Counter(rgbs).most_common(5): try: c = webcolors.rgb_to_name(t[0]) except: c = find_nearest_color(webcolors.rgb_to_hex(t[0])) team_colors['logo']['hex'].append(webcolors.rgb_to_hex(t[0])) team_colors['logo']['name'].append(c) shutil.rmtree('data_temp') team_colors['logo']['name'] = list(set(team_colors['logo']['name'])) return {"team_colors": team_colors}
def is_css_color_code(instance): return webcolors.normalize_hex(instance)
def get(self, request, *args, **kwargs): job = get_object_or_404(Job, pk=self.kwargs.get('pk')) feature_types = FeatureType.objects.all() aoi_count = job.total_count() aoi_complete = job.complete_count() aoi_work = job.in_work_count() cookie_url_trailer = get_cookie_trailer(request) description = 'Job #' + str(job.id) + ': ' + str( job.name) + '\n' + str(job.project.name) + '\n' if aoi_count == 0: output = '<?xml version="1.0" encoding="UTF-8"?>\n' output += '<kml xmlns="http://www.opengis.net/kml/2.2">\n' output += ' <Document>\n' output += ' <name>Empty Job</name>\n' output += ' <description>' + description + '</description>\n' output += ' </Document>\n' output += '</kml>\n' return HttpResponse( output, mimetype="application/vnd.google-earth.kml+xml", status=200) aoi_comp_pct = (100 * float(aoi_complete) / float(aoi_count)) aoi_work_pct = int(100 * float(aoi_work) / float(aoi_count)) aoi_tot_pct = int(100 * float(aoi_work + aoi_complete) / float(aoi_count)) doc_name = 'GeoQ C:' + str(aoi_complete) + ', W:' + str( aoi_work) + ', Tot:' + str(aoi_count) + ' [' + str( aoi_tot_pct) + '%]' description = description + 'Complete Cells: ' + str( aoi_complete) + ' [' + str(aoi_comp_pct) + '%], In Work: ' + str( aoi_work) + ' [' + str(aoi_work_pct) + '%], Total: ' + str( aoi_count) output = '<?xml version="1.0" encoding="UTF-8"?>\n' output += '<kml xmlns="http://www.opengis.net/kml/2.2">\n' output += ' <Document>\n' output += ' <name>' + doc_name + '</name>\n' output += ' <description>' + description + '</description>\n' output += ' <Style id="geoq_inwork">\n' output += ' <LineStyle>\n' output += ' <width>4</width>\n' output += ' <color>7f0186cf</color>\n' output += ' </LineStyle>\n' output += ' <PolyStyle>\n' output += ' <fill>0</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' output += ' </Style>\n' output += ' <Style id="geoq_complete">\n' output += ' <LineStyle>\n' output += ' <width>3</width>\n' output += ' <color>7f0101cf</color>\n' output += ' </LineStyle>\n' output += ' <PolyStyle>\n' output += ' <fill>0</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' output += ' </Style>\n' output += ' <Style id="geoq_unassigned">\n' output += ' <LineStyle>\n' output += ' <width>2</width>\n' output += ' <color>7f00ff00</color>\n' output += ' </LineStyle>\n' output += ' <PolyStyle>\n' output += ' <fill>0</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' output += ' </Style>\n' for feature in feature_types: output += ' <Style id="geoq_' + str(feature.id) + '">\n' out_color = '7f0066ff' if feature.style == None: output += ' </Style>\n' continue if feature.style.has_key('color'): color = feature.style['color'] #convert to a kml-recognized color if color[0:1] == '#' and len(color) == 4: color = normalize_hex(color) try: c = name_to_hex(color) out_color = '7f' + c[5:7] + c[3:5] + c[1:3] except Exception: out_color = '7f0066ff' output += ' <PolyStyle>\n' output += ' <color>' + out_color + '</color>\n' output += ' <colorMode>normal</colorMode>\n' output += ' <fill>1</fill>\n' output += ' <outline>1</outline>\n' output += ' </PolyStyle>\n' if feature.style.has_key('weight'): output += ' <LineStyle>\n' output += ' <width>' + str( feature.style['weight']) + '</width>\n' if feature.style.has_key('color'): output += ' <color>' + out_color + '</color>\n' output += ' </LineStyle>\n' if feature.style.has_key('iconUrl'): icon_url = str(feature.style['iconUrl']) if not icon_url.startswith("http"): icon_url = request.build_absolute_uri(icon_url) else: icon_url += cookie_url_trailer output += ' <IconStyle>\n' output += ' <Icon>\n' output += ' <href>' + xml_escape( icon_url) + '</href>\n' output += ' </Icon>\n' output += ' </IconStyle>\n' output += ' </Style>\n' # locations = job.feature_set.all().order_by('template') locations = job.feature_set.all()\ .extra(tables=['maps_featuretype'])\ .extra(where=['maps_featuretype.id=maps_feature.template_id'])\ .order_by('maps_featuretype.name') last_template = "" skip_the_first = True template_has_started = False for loc in locations: template_name = str(loc.template.name) if template_name != last_template: if skip_the_first: skip_the_first = False else: output += ' </Folder>\n' output += ' <Folder><name>' + template_name + '</name>\n' last_template = template_name template_has_started = True analyst_name = str(loc.analyst.username) dtg = str(loc.created_at) job_id = str(loc.job.id) #TODO: Add links to Jobs and Projects datetime_obj = datetime.strptime(dtg, "%Y-%m-%d %H:%M:%S.%f+00:00") datetime_obj_utc = datetime_obj.replace(tzinfo=timezone('UTC')) date_time = datetime_obj_utc.strftime('%Y-%m-%dT%H:%M:%SZ') date_time_desc = datetime_obj_utc.strftime('%Y-%m-%d %H:%M:%S') desc = 'Posted by ' + analyst_name + ' at ' + date_time_desc + ' Zulu (UTC) in Job #' + job_id #TODO: Add more details #TODO: Add links to linked objects #Simplify polygons to reduce points in complex shapes if loc.the_geom.num_coords > 0: #skip empty locations simplegeom = loc.the_geom.simplify(0.0002) if simplegeom.num_coords > 0: kml = str(loc.the_geom.simplify(0.0002).kml) else: kml = str(loc.the_geom.kml) if '<Polygon><outerBoundaryIs><LinearRing><coordinates>' in kml: add_text = '<altitudeMode>clampToGround</altitudeMode>' kml = kml.replace('<coordinates>', add_text + '<coordinates>') kml = kml.replace( '</outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing>', '') output += ' <Placemark><name>' + template_name + '</name>\n' output += ' <TimeStamp><when>' + date_time + '</when></TimeStamp>\n' output += ' <description>' + desc + '</description>\n' output += ' <styleUrl>#geoq_' + str( loc.template.id) + '</styleUrl>\n' output += ' ' + str(kml) + '\n' output += ' </Placemark>\n' if template_has_started: output += ' </Folder>\n' output += ' <Folder><name>Work Cells</name>\n' aois = job.aois.order_by('status') for aoi in aois: style = 'complete' if aoi.status == 'In work': style = 'inwork' if aoi.status == 'Unassigned': style = 'unassigned' aoi_name = "#" + str(aoi.id) + ", " + str( aoi.status) + " - Priority:" + str(aoi.priority) kml = str(aoi.polygon.simplify(0.0002).kml) if '<Polygon><outerBoundaryIs><LinearRing><coordinates>' in kml: add_text = '<tessellate>1</tessellate><altitudeMode>clampToGround</altitudeMode>' kml = kml.replace('<coordinates>', add_text + '<coordinates>') output += ' <Placemark>\n' output += ' <name>' + aoi_name + '</name>\n' output += ' <styleUrl>#geoq_' + style + '</styleUrl>\n' output += ' ' + kml + '\n' output += ' </Placemark>\n' output += ' </Folder>\n' output += ' </Document>\n' output += '</kml>' return HttpResponse(output, mimetype="application/vnd.google-earth.kml+xml", status=200)
def is_css_color_code(instance): return webcolors.normalize_hex(instance)
import sys import Alfred from webcolors import normalize_hex, hex_to_rgb from printer import push_colors handler = Alfred.Handler(args=sys.argv) try: hex_query = normalize_hex("#%s" % sys.argv[1]) rgb = hex_to_rgb(hex_query) push_colors(handler, hex_query.upper(), rgb) except: handler.add_new_item(title="...") handler.push()