Remove ThreadColor
Replaced with raw color values. In the future, we should probably investigate using "themes"
This commit is contained in:
@@ -54,8 +54,6 @@ Miscellaneous
|
||||
|
||||
.. autoclass:: ThreadLocation(Enum)
|
||||
:undoc-members:
|
||||
.. autoclass:: ThreadColor(Enum)
|
||||
:undoc-members:
|
||||
.. autoclass:: ActiveStatus()
|
||||
.. autoclass:: TypingStatus(Enum)
|
||||
:undoc-members:
|
||||
|
@@ -70,8 +70,8 @@ corresponds to the ID of a single user, and the ID of a group respectively::
|
||||
Some functions don't require a thread type, so in these cases you just provide the thread ID::
|
||||
|
||||
thread = fbchat.Thread(session=session, id="<user-or-group-id>")
|
||||
thread.set_color(ThreadColor.BILOBA_FLOWER)
|
||||
thread.set_color(ThreadColor.MESSENGER_BLUE)
|
||||
thread.set_color("#a695c7")
|
||||
thread.set_color("#67b868")
|
||||
|
||||
|
||||
.. _intro_message_ids:
|
||||
|
@@ -54,8 +54,8 @@ thread.set_nickname(fbchat.User(session=session, id="<user id>"), "<new nickname
|
||||
# Will set the typing status of the thread
|
||||
thread.start_typing()
|
||||
|
||||
# Will change the thread color to `MESSENGER_BLUE`
|
||||
thread.set_color(fbchat.ThreadColor.MESSENGER_BLUE)
|
||||
# Will change the thread color to #0084ff
|
||||
thread.set_color("#0084ff")
|
||||
|
||||
# Will change the thread emoji to `👍`
|
||||
thread.set_emoji("👍")
|
||||
|
@@ -4,7 +4,7 @@ import fbchat
|
||||
old_thread_id = "1234567890"
|
||||
|
||||
# Change these to match your liking
|
||||
old_color = fbchat.ThreadColor.MESSENGER_BLUE
|
||||
old_color = "#0084ff"
|
||||
old_emoji = "👍"
|
||||
old_title = "Old group chat name"
|
||||
old_nicknames = {
|
||||
|
@@ -14,7 +14,7 @@ from . import _core, _util
|
||||
from ._core import Image
|
||||
from ._exception import FBchatException, FBchatFacebookError
|
||||
from ._session import Session
|
||||
from ._thread import ThreadLocation, ThreadColor, ThreadABC, Thread
|
||||
from ._thread import ThreadLocation, ThreadABC, Thread
|
||||
from ._user import TypingStatus, User, UserData, ActiveStatus
|
||||
from ._group import Group, GroupData
|
||||
from ._page import Page, PageData
|
||||
|
@@ -6,7 +6,7 @@ from ._core import log
|
||||
from . import _util, _graphql, _session
|
||||
|
||||
from ._exception import FBchatException, FBchatFacebookError
|
||||
from ._thread import ThreadLocation, ThreadColor
|
||||
from ._thread import ThreadLocation
|
||||
from ._user import TypingStatus, User, UserData, ActiveStatus
|
||||
from ._group import Group, GroupData
|
||||
from ._page import Page, PageData
|
||||
@@ -947,12 +947,11 @@ class Client:
|
||||
|
||||
# Color change
|
||||
elif delta_type == "change_thread_theme":
|
||||
new_color = ThreadColor._from_graphql(delta["untypedData"]["theme_color"])
|
||||
thread = get_thread(metadata)
|
||||
self.on_color_change(
|
||||
mid=mid,
|
||||
author_id=author_id,
|
||||
new_color=new_color,
|
||||
new_color=ThreadABC._parse_color(delta["untypedData"]["theme_color"]),
|
||||
thread=get_thread(metadata),
|
||||
at=at,
|
||||
metadata=metadata,
|
||||
@@ -1566,7 +1565,7 @@ class Client:
|
||||
Args:
|
||||
mid: The action ID
|
||||
author_id: The ID of the person who changed the color
|
||||
new_color (ThreadColor): The new color
|
||||
new_color: The new color. Not limited to the ones in `ThreadABC.set_color`
|
||||
thread: Thread that the action was sent to. See :ref:`intro_threads`
|
||||
at (datetime.datetime): When the action was executed
|
||||
metadata: Extra metadata about the action
|
||||
|
@@ -150,7 +150,7 @@ class GroupData(Group):
|
||||
participants = attr.ib(factory=set)
|
||||
#: A dictionary, containing user nicknames mapped to their IDs
|
||||
nicknames = attr.ib(factory=dict)
|
||||
#: A `ThreadColor`. The groups's message color
|
||||
#: The groups's message color
|
||||
color = attr.ib(None)
|
||||
#: The groups's default emoji
|
||||
emoji = attr.ib(None)
|
||||
@@ -189,8 +189,8 @@ class GroupData(Group):
|
||||
]
|
||||
),
|
||||
nicknames=c_info.get("nicknames"),
|
||||
color=c_info.get("color"),
|
||||
emoji=c_info.get("emoji"),
|
||||
color=c_info["color"],
|
||||
emoji=c_info["emoji"],
|
||||
admins=set([node.get("id") for node in data.get("thread_admins")]),
|
||||
approval_mode=bool(data.get("approval_mode"))
|
||||
if data.get("approval_mode") is not None
|
||||
|
@@ -4,7 +4,7 @@ import collections
|
||||
import datetime
|
||||
from ._core import attrs_default, Enum, Image
|
||||
from . import _util, _exception, _session, _graphql, _attachment, _file, _plan
|
||||
from typing import MutableMapping, Any, Iterable, Tuple
|
||||
from typing import MutableMapping, Any, Iterable, Tuple, Optional
|
||||
|
||||
|
||||
class ThreadLocation(Enum):
|
||||
@@ -16,39 +16,29 @@ class ThreadLocation(Enum):
|
||||
OTHER = "OTHER"
|
||||
|
||||
|
||||
class ThreadColor(Enum):
|
||||
"""Used to specify a thread colors."""
|
||||
|
||||
MESSENGER_BLUE = "#0084ff"
|
||||
VIKING = "#44bec7"
|
||||
GOLDEN_POPPY = "#ffc300"
|
||||
RADICAL_RED = "#fa3c4c"
|
||||
SHOCKING = "#d696bb"
|
||||
PICTON_BLUE = "#6699cc"
|
||||
FREE_SPEECH_GREEN = "#13cf13"
|
||||
PUMPKIN = "#ff7e29"
|
||||
LIGHT_CORAL = "#e68585"
|
||||
MEDIUM_SLATE_BLUE = "#7646ff"
|
||||
DEEP_SKY_BLUE = "#20cef5"
|
||||
FERN = "#67b868"
|
||||
CAMEO = "#d4a88c"
|
||||
BRILLIANT_ROSE = "#ff5ca1"
|
||||
BILOBA_FLOWER = "#a695c7"
|
||||
TICKLE_ME_PINK = "#ff7ca8"
|
||||
MALACHITE = "#1adb5b"
|
||||
RUBY = "#f01d6a"
|
||||
DARK_TANGERINE = "#ff9c19"
|
||||
BRIGHT_TURQUOISE = "#0edcde"
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, color):
|
||||
if color is None:
|
||||
return None
|
||||
if not color:
|
||||
return cls.MESSENGER_BLUE
|
||||
color = color[2:] # Strip the alpha value
|
||||
value = "#{}".format(color.lower())
|
||||
return cls._extend_if_invalid(value)
|
||||
DEFAULT_COLOR = "#0084ff"
|
||||
SETABLE_COLORS = (
|
||||
DEFAULT_COLOR,
|
||||
"#44bec7",
|
||||
"#ffc300",
|
||||
"#fa3c4c",
|
||||
"#d696bb",
|
||||
"#6699cc",
|
||||
"#13cf13",
|
||||
"#ff7e29",
|
||||
"#e68585",
|
||||
"#7646ff",
|
||||
"#20cef5",
|
||||
"#67b868",
|
||||
"#d4a88c",
|
||||
"#ff5ca1",
|
||||
"#a695c7",
|
||||
"#ff7ca8",
|
||||
"#1adb5b",
|
||||
"#f01d6a",
|
||||
"#ff9c19",
|
||||
"#0edcde",
|
||||
)
|
||||
|
||||
|
||||
class ThreadABC(metaclass=abc.ABCMeta):
|
||||
@@ -375,22 +365,50 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
"/messaging/save_thread_nickname/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def set_color(self, color: ThreadColor):
|
||||
def set_color(self, color: str):
|
||||
"""Change thread color.
|
||||
|
||||
The new color must be one of the following:
|
||||
|
||||
"#0084ff", "#44bec7", "#ffc300", "#fa3c4c", "#d696bb", "#6699cc", "#13cf13",
|
||||
"#ff7e29", "#e68585", "#7646ff", "#20cef5", "#67b868", "#d4a88c", "#ff5ca1",
|
||||
"#a695c7", "#ff7ca8", "#1adb5b", "#f01d6a", "#ff9c19" or "#0edcde".
|
||||
|
||||
The default is "#0084ff".
|
||||
|
||||
This list is subject to change in the future!
|
||||
|
||||
Args:
|
||||
color: New thread color
|
||||
"""
|
||||
data = {
|
||||
"color_choice": color.value if color != ThreadColor.MESSENGER_BLUE else "",
|
||||
"thread_or_other_fbid": self.id,
|
||||
}
|
||||
if color not in SETABLE_COLORS:
|
||||
raise ValueError(
|
||||
"Invalid color! Please use one of: {}".format(SETABLE_COLORS)
|
||||
)
|
||||
|
||||
# Set color to "" if DEFAULT_COLOR. Just how the endpoint works...
|
||||
if color == DEFAULT_COLOR:
|
||||
color = ""
|
||||
|
||||
data = {"color_choice": color, "thread_or_other_fbid": self.id}
|
||||
j = self.session._payload_post(
|
||||
"/messaging/save_thread_color/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
# def set_theme(self, theme_id: str):
|
||||
# data = {
|
||||
# "client_mutation_id": "0",
|
||||
# "actor_id": self.session.user_id,
|
||||
# "thread_id": self.id,
|
||||
# "theme_id": theme_id,
|
||||
# "source": "SETTINGS",
|
||||
# }
|
||||
# j = self.session._graphql_requests(
|
||||
# _graphql.from_doc_id("1768656253222505", {"data": data})
|
||||
# )
|
||||
|
||||
def set_emoji(self, emoji: str):
|
||||
"""Change thread color.
|
||||
"""Change thread emoji.
|
||||
|
||||
Args:
|
||||
emoji: New thread emoji
|
||||
@@ -541,15 +559,22 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
)
|
||||
return j
|
||||
|
||||
@staticmethod
|
||||
def _parse_color(inp: Optional[str]) -> str:
|
||||
if not inp:
|
||||
return DEFAULT_COLOR
|
||||
# Strip the alpha value, and lower the string
|
||||
return "#{}".format(inp[2:].lower())
|
||||
|
||||
@staticmethod
|
||||
def _parse_customization_info(data: Any) -> MutableMapping[str, Any]:
|
||||
if data is None or data.get("customization_info") is None:
|
||||
return {}
|
||||
if not data or not data.get("customization_info"):
|
||||
return {"emoji": None, "color": DEFAULT_COLOR}
|
||||
info = data["customization_info"]
|
||||
|
||||
rtn = {
|
||||
"emoji": info.get("emoji"),
|
||||
"color": ThreadColor._from_graphql(info.get("outgoing_bubble_color")),
|
||||
"color": ThreadABC._parse_color(info.get("outgoing_bubble_color")),
|
||||
}
|
||||
if (
|
||||
data.get("thread_type") == "GROUP"
|
||||
|
@@ -110,7 +110,7 @@ class UserData(User):
|
||||
nickname = attr.ib(None)
|
||||
#: The clients nickname, as seen by the user
|
||||
own_nickname = attr.ib(None)
|
||||
#: A `ThreadColor`. The message color
|
||||
#: The message color
|
||||
color = attr.ib(None)
|
||||
#: The default emoji
|
||||
emoji = attr.ib(None)
|
||||
@@ -136,8 +136,8 @@ class UserData(User):
|
||||
gender=GENDERS.get(data["gender"]),
|
||||
affinity=data.get("viewer_affinity"),
|
||||
nickname=c_info.get("nickname"),
|
||||
color=c_info.get("color"),
|
||||
emoji=c_info.get("emoji"),
|
||||
color=c_info["color"],
|
||||
emoji=c_info["emoji"],
|
||||
own_nickname=c_info.get("own_nickname"),
|
||||
photo=Image._from_uri(data["profile_picture"]),
|
||||
name=data["name"],
|
||||
@@ -186,8 +186,8 @@ class UserData(User):
|
||||
is_friend=user["is_viewer_friend"],
|
||||
gender=GENDERS.get(user["gender"]),
|
||||
nickname=c_info.get("nickname"),
|
||||
color=c_info.get("color"),
|
||||
emoji=c_info.get("emoji"),
|
||||
color=c_info["color"],
|
||||
emoji=c_info["emoji"],
|
||||
own_nickname=c_info.get("own_nickname"),
|
||||
photo=Image._from_uri(user["big_image_src"]),
|
||||
message_count=data["messages_count"],
|
||||
|
@@ -35,7 +35,7 @@ def test_group_from_graphql(session):
|
||||
plan=None,
|
||||
participants={"1234", "2345", "3456"},
|
||||
nicknames={},
|
||||
color=None,
|
||||
color="#0084ff",
|
||||
emoji="😀",
|
||||
admins={"1234"},
|
||||
approval_mode=False,
|
||||
|
@@ -1,20 +1,19 @@
|
||||
import pytest
|
||||
import fbchat
|
||||
from fbchat import ThreadColor, ThreadABC, Thread
|
||||
from fbchat import ThreadABC, Thread
|
||||
|
||||
|
||||
def test_thread_color_from_graphql():
|
||||
assert None is ThreadColor._from_graphql(None)
|
||||
assert ThreadColor.MESSENGER_BLUE is ThreadColor._from_graphql("")
|
||||
assert ThreadColor.VIKING is ThreadColor._from_graphql("FF44BEC7")
|
||||
assert ThreadColor._from_graphql("DEADBEEF") is getattr(
|
||||
ThreadColor, "UNKNOWN_#ADBEEF"
|
||||
)
|
||||
def test_parse_color():
|
||||
assert "#0084ff" == ThreadABC._parse_color(None)
|
||||
assert "#0084ff" == ThreadABC._parse_color("")
|
||||
assert "#44bec7" == ThreadABC._parse_color("FF44BEC7")
|
||||
assert "#adbeef" == ThreadABC._parse_color("DEADBEEF")
|
||||
|
||||
|
||||
def test_thread_parse_customization_info_empty():
|
||||
assert {} == ThreadABC._parse_customization_info(None)
|
||||
assert {} == ThreadABC._parse_customization_info({"customization_info": None})
|
||||
default = {"color": "#0084ff", "emoji": None}
|
||||
assert default == ThreadABC._parse_customization_info(None)
|
||||
assert default == ThreadABC._parse_customization_info({"customization_info": None})
|
||||
|
||||
|
||||
def test_thread_parse_customization_info_group():
|
||||
@@ -34,7 +33,7 @@ def test_thread_parse_customization_info_group():
|
||||
}
|
||||
expected = {
|
||||
"emoji": "🎉",
|
||||
"color": ThreadColor.BRILLIANT_ROSE,
|
||||
"color": "#ff5ca1",
|
||||
"nicknames": {"123456789": "A", "987654321": "B"},
|
||||
}
|
||||
assert expected == ThreadABC._parse_customization_info(data)
|
||||
@@ -55,7 +54,7 @@ def test_thread_parse_customization_info_user():
|
||||
"thread_type": "ONE_TO_ONE",
|
||||
# ... Other irrelevant fields
|
||||
}
|
||||
expected = {"emoji": None, "color": None, "own_nickname": "A", "nickname": "B"}
|
||||
expected = {"emoji": None, "color": "#0084ff", "own_nickname": "A", "nickname": "B"}
|
||||
assert expected == ThreadABC._parse_customization_info(data)
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from fbchat import Message, FBchatFacebookError, TypingStatus, ThreadColor
|
||||
from fbchat import Message, FBchatFacebookError, TypingStatus
|
||||
from utils import random_hex, subset
|
||||
from os import path
|
||||
|
||||
@@ -91,14 +91,10 @@ def test_change_image_remote(client1, group, catch_event):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"color",
|
||||
[x for x in ThreadColor if x in [ThreadColor.MESSENGER_BLUE, ThreadColor.PUMPKIN]],
|
||||
)
|
||||
def test_change_color(client, catch_event, compare, color):
|
||||
def test_change_color(client, catch_event, compare):
|
||||
with catch_event("on_color_change") as x:
|
||||
client.change_thread_color(color)
|
||||
assert compare(x, new_color=color)
|
||||
client.change_thread_color("#44bec7")
|
||||
assert compare(x, new_color="#44bec7")
|
||||
|
||||
|
||||
@pytest.mark.xfail(raises=FBchatFacebookError, reason="Should fail, but doesn't")
|
||||
|
@@ -27,6 +27,7 @@ def test_user_from_graphql(session):
|
||||
is_friend=True,
|
||||
gender="female_singular",
|
||||
affinity=0.4560002,
|
||||
color="#0084ff",
|
||||
) == UserData._from_graphql(session, data)
|
||||
|
||||
|
||||
@@ -152,7 +153,7 @@ def test_user_from_thread_fetch(session):
|
||||
gender="female_singular",
|
||||
nickname="A",
|
||||
own_nickname="B",
|
||||
color=None,
|
||||
color="#0084ff",
|
||||
emoji=None,
|
||||
) == UserData._from_thread_fetch(session, data)
|
||||
|
||||
|
Reference in New Issue
Block a user