Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement hex color conversion #1270

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion gspread/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import re
from collections import defaultdict
from collections.abc import Sequence
from collections.abc import Mapping, Sequence
alifeee marked this conversation as resolved.
Show resolved Hide resolved
from functools import wraps
from itertools import chain
from typing import (
Expand Down Expand Up @@ -718,6 +718,89 @@ def combined_merge_values(worksheet_metadata, values):
return new_values


def convert_hex_to_colors_dict(hex_color: str) -> Mapping[str, float]:
"""Convert a hex color code to RGB color values.

:param str hex_color: Hex color code in the format "#RRGGBB".

:returns: Dict containing the color's red, green and blue values between 0 and 1.
:rtype: dict

:raises:
ValueError: If the input hex string is not in the correct format or length.

Examples:
>>> convert_hex_to_colors_dict("#3300CC")
{'red': 0.2, 'green': 0.0, 'blue': 0.8}

>>> convert_hex_to_colors_dict("#30C")
{'red': 0.2, 'green': 0.0, 'blue': 0.8}

"""
hex_color = hex_color.lstrip("#")

# Google API ColorStyle Reference:
# "The alpha value in the Color object isn't generally supported."
# https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#colorstyle
if len(hex_color) == 8:
hex_color = hex_color[:-2]

alifeee marked this conversation as resolved.
Show resolved Hide resolved
# Expand 3 character hex.
if len(hex_color) == 3:
hex_color = "".join([char * 2 for char in hex_color])

if len(hex_color) != 6:
raise ValueError("Hex color code must be in the format '#RRGGBB'.")

try:
rgb_color = {
"red": int(hex_color[0:2], 16) / 255,
"green": int(hex_color[2:4], 16) / 255,
"blue": int(hex_color[4:6], 16) / 255,
}

return rgb_color
except ValueError:
raise ValueError(f"Invalid character in hex color string: #{hex_color}")


def convert_colors_to_hex_value(
red: float = 0.0, green: float = 0.0, blue: float = 0.0
) -> str:
"""Convert RGB color values to a hex color code.

:param float red: Red color value (0-1).
:param float green: Green color value (0-1).
:param float blue: Blue color value (0-1).

:returns: Hex color code in the format "#RRGGBB".
:rtype: str

:raises:
ValueError: If any color value is out of the accepted range (0-1).

Example:

>>> convert_colors_to_hex_value(0.2, 0, 0.8)
'#3300CC'

>>> convert_colors_to_hex_value(green=0.5)
'#008000'
"""

def to_hex(value: float) -> str:
"""
Convert an integer to a 2-digit uppercase hex string.
"""
hex_value = hex(round(value * 255))[2:]
return hex_value.upper().zfill(2)

if any(value < 0 or value > 1 for value in (red, green, blue)):
raise ValueError("Color value out of accepted range 0-1.")

return f"#{to_hex(red)}{to_hex(green)}{to_hex(blue)}"


if __name__ == "__main__":
import doctest

Expand Down
10 changes: 10 additions & 0 deletions gspread/worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
cast_to_a1_notation,
cell_list_to_rect,
combined_merge_values,
convert_hex_to_colors_dict,
fill_gaps,
finditem,
numericise_all,
Expand Down Expand Up @@ -1577,6 +1578,15 @@ def clear_tab_color(self) -> JSONResponse:
self._properties.pop("tabColorStyle")
return response

def set_tab_color(self, hex_color: str):
idonec marked this conversation as resolved.
Show resolved Hide resolved
"""Changes the worksheet's tab color.
Use clear_tab_color() to remove the color.

:param str hex_color: Hex color code in the format "#RRGGBB".
"""
rgb_color = convert_hex_to_colors_dict(hex_color)
return self.update_tab_color(rgb_color)

def update_index(self, index: int) -> JSONResponse:
"""Updates the ``index`` property for the worksheet.

Expand Down
Loading