mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 04:53:36 +00:00
ruff: Fix UP007 Use X | Y for type annotations.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
committed by
Tim Abbott
parent
e08a24e47f
commit
531b34cb4c
@@ -1,4 +1,4 @@
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -139,7 +139,7 @@ def get_topic_based_on_event(payload: WildValue, event: str) -> str:
|
||||
return get_code_repository_name(payload) # nocoverage
|
||||
|
||||
|
||||
def get_event_name(payload: WildValue, branches: Optional[str]) -> Optional[str]:
|
||||
def get_event_name(payload: WildValue, branches: str | None) -> str | None:
|
||||
event_name = payload["eventType"].tame(check_string)
|
||||
if event_name == "git.push" and branches is not None:
|
||||
branch = get_code_push_branch_name(payload)
|
||||
@@ -175,7 +175,7 @@ def api_azuredevops_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
) -> HttpResponse:
|
||||
event = get_event_name(payload, branches)
|
||||
if event is None:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Webhooks for external integrations.
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from pydantic import Json
|
||||
@@ -23,8 +22,8 @@ def build_message_from_gitlog(
|
||||
after: str,
|
||||
url: str,
|
||||
pusher: str,
|
||||
forced: Optional[str] = None,
|
||||
created: Optional[str] = None,
|
||||
forced: str | None = None,
|
||||
created: str | None = None,
|
||||
deleted: bool = False,
|
||||
) -> tuple[str, str]:
|
||||
short_ref = re.sub(r"^refs/heads/", "", ref)
|
||||
@@ -60,7 +59,7 @@ def api_beanstalk_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: Json[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
) -> HttpResponse:
|
||||
# Beanstalk supports both SVN and Git repositories
|
||||
# We distinguish between the two by checking for a
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
from zerver.decorator import authenticated_rest_api_view
|
||||
@@ -18,7 +16,7 @@ def api_bitbucket_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
) -> HttpResponse:
|
||||
repository = payload["repository"]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Webhooks for external integrations.
|
||||
import re
|
||||
import string
|
||||
from typing import Optional, Protocol
|
||||
from typing import Protocol
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -83,7 +83,7 @@ def api_bitbucket2_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
user_specified_topic: OptionalUserSpecifiedTopicStr = None,
|
||||
) -> HttpResponse:
|
||||
type = get_type(request, payload)
|
||||
@@ -119,7 +119,7 @@ def api_bitbucket2_webhook(
|
||||
|
||||
|
||||
def get_topic_for_branch_specified_events(
|
||||
payload: WildValue, branch_name: Optional[str] = None
|
||||
payload: WildValue, branch_name: str | None = None
|
||||
) -> str:
|
||||
return TOPIC_WITH_BRANCH_TEMPLATE.format(
|
||||
repo=get_repository_name(payload["repository"]),
|
||||
@@ -525,7 +525,7 @@ def get_actor_info(request: HttpRequest, payload: WildValue) -> str:
|
||||
return get_user_info(request, actor)
|
||||
|
||||
|
||||
def get_branch_name_for_push_event(payload: WildValue) -> Optional[str]:
|
||||
def get_branch_name_for_push_event(payload: WildValue) -> str | None:
|
||||
change = payload["push"]["changes"][-1]
|
||||
potential_tag = (change["new"] or change["old"])["type"].tame(check_string)
|
||||
if potential_tag == "tag":
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import string
|
||||
from typing import Optional, Protocol
|
||||
from typing import Protocol
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -72,8 +72,8 @@ def get_user_name(payload: WildValue) -> str:
|
||||
|
||||
def ping_handler(
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
if include_title:
|
||||
topic_name = include_title
|
||||
@@ -86,8 +86,8 @@ def ping_handler(
|
||||
def repo_comment_handler(
|
||||
action: str,
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
repo_name = payload["repository"]["name"].tame(check_string)
|
||||
topic_name = BITBUCKET_TOPIC_TEMPLATE.format(repository_name=repo_name)
|
||||
@@ -111,8 +111,8 @@ def repo_comment_handler(
|
||||
|
||||
def repo_forked_handler(
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
repo_name = payload["repository"]["origin"]["name"].tame(check_string)
|
||||
topic_name = BITBUCKET_TOPIC_TEMPLATE.format(repository_name=repo_name)
|
||||
@@ -127,8 +127,8 @@ def repo_forked_handler(
|
||||
|
||||
def repo_modified_handler(
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
topic_name_new = BITBUCKET_TOPIC_TEMPLATE.format(
|
||||
repository_name=payload["new"]["name"].tame(check_string)
|
||||
@@ -195,8 +195,8 @@ def repo_push_tag_data(payload: WildValue, change: WildValue) -> dict[str, str]:
|
||||
|
||||
def repo_push_handler(
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
data = []
|
||||
for change in payload["changes"]:
|
||||
@@ -216,7 +216,7 @@ def repo_push_handler(
|
||||
return data
|
||||
|
||||
|
||||
def get_assignees_string(pr: WildValue) -> Optional[str]:
|
||||
def get_assignees_string(pr: WildValue) -> str | None:
|
||||
reviewers = []
|
||||
for reviewer in pr["reviewers"]:
|
||||
name = reviewer["user"]["name"].tame(check_string)
|
||||
@@ -235,7 +235,7 @@ def get_pr_topic(repo: str, type: str, id: int, title: str) -> str:
|
||||
return TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format(repo=repo, type=type, id=id, title=title)
|
||||
|
||||
|
||||
def get_simple_pr_body(payload: WildValue, action: str, include_title: Optional[str]) -> str:
|
||||
def get_simple_pr_body(payload: WildValue, action: str, include_title: str | None) -> str:
|
||||
pr = payload["pullRequest"]
|
||||
return get_pull_request_event_message(
|
||||
user_name=get_user_name(payload),
|
||||
@@ -247,7 +247,7 @@ def get_simple_pr_body(payload: WildValue, action: str, include_title: Optional[
|
||||
|
||||
|
||||
def get_pr_opened_or_modified_body(
|
||||
payload: WildValue, action: str, include_title: Optional[str]
|
||||
payload: WildValue, action: str, include_title: str | None
|
||||
) -> str:
|
||||
pr = payload["pullRequest"]
|
||||
description = pr.get("description").tame(check_none_or(check_string))
|
||||
@@ -271,7 +271,7 @@ def get_pr_opened_or_modified_body(
|
||||
)
|
||||
|
||||
|
||||
def get_pr_merged_body(payload: WildValue, action: str, include_title: Optional[str]) -> str:
|
||||
def get_pr_merged_body(payload: WildValue, action: str, include_title: str | None) -> str:
|
||||
pr = payload["pullRequest"]
|
||||
return get_pull_request_event_message(
|
||||
user_name=get_user_name(payload),
|
||||
@@ -284,7 +284,7 @@ def get_pr_merged_body(payload: WildValue, action: str, include_title: Optional[
|
||||
)
|
||||
|
||||
|
||||
def get_pr_needs_work_body(payload: WildValue, include_title: Optional[str]) -> str:
|
||||
def get_pr_needs_work_body(payload: WildValue, include_title: str | None) -> str:
|
||||
pr = payload["pullRequest"]
|
||||
if not include_title:
|
||||
return PULL_REQUEST_MARKED_AS_NEEDS_WORK_TEMPLATE.format(
|
||||
@@ -300,7 +300,7 @@ def get_pr_needs_work_body(payload: WildValue, include_title: Optional[str]) ->
|
||||
)
|
||||
|
||||
|
||||
def get_pr_reassigned_body(payload: WildValue, include_title: Optional[str]) -> str:
|
||||
def get_pr_reassigned_body(payload: WildValue, include_title: str | None) -> str:
|
||||
pr = payload["pullRequest"]
|
||||
assignees_string = get_assignees_string(pr)
|
||||
if not assignees_string:
|
||||
@@ -338,8 +338,8 @@ def get_pr_reassigned_body(payload: WildValue, include_title: Optional[str]) ->
|
||||
def pr_handler(
|
||||
action: str,
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
pr = payload["pullRequest"]
|
||||
topic_name = get_pr_topic(
|
||||
@@ -365,8 +365,8 @@ def pr_handler(
|
||||
def pr_comment_handler(
|
||||
action: str,
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
include_title: Optional[str],
|
||||
branches: str | None,
|
||||
include_title: str | None,
|
||||
) -> list[dict[str, str]]:
|
||||
pr = payload["pullRequest"]
|
||||
topic_name = get_pr_topic(
|
||||
@@ -392,7 +392,7 @@ def pr_comment_handler(
|
||||
|
||||
class EventHandler(Protocol):
|
||||
def __call__(
|
||||
self, payload: WildValue, branches: Optional[str], include_title: Optional[str]
|
||||
self, payload: WildValue, branches: str | None, include_title: str | None
|
||||
) -> list[dict[str, str]]: ...
|
||||
|
||||
|
||||
@@ -428,10 +428,10 @@ def api_bitbucket3_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
user_specified_topic: OptionalUserSpecifiedTopicStr = None,
|
||||
) -> HttpResponse:
|
||||
eventkey: Optional[str]
|
||||
eventkey: str | None
|
||||
if "eventKey" in payload:
|
||||
eventkey = payload["eventKey"].tame(check_string)
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Callable, Iterable, Iterator, Optional
|
||||
from typing import Callable, Iterable, Iterator
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -83,7 +83,7 @@ def get_action_with_primary_id(payload: WildValue) -> WildValue:
|
||||
return action_with_primary_id
|
||||
|
||||
|
||||
def get_event(payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
def get_event(payload: WildValue, action: WildValue) -> str | None:
|
||||
event = "{}_{}".format(
|
||||
action["entity_type"].tame(check_string), action["action"].tame(check_string)
|
||||
)
|
||||
@@ -129,7 +129,7 @@ def get_event(payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
|
||||
def get_topic_function_based_on_type(
|
||||
payload: WildValue, action: WildValue
|
||||
) -> Optional[Callable[[WildValue, WildValue], Optional[str]]]:
|
||||
) -> Callable[[WildValue, WildValue], str | None] | None:
|
||||
entity_type = action["entity_type"].tame(check_string)
|
||||
return EVENT_TOPIC_FUNCTION_MAPPER.get(entity_type)
|
||||
|
||||
@@ -299,7 +299,7 @@ def get_story_task_body(operation: str, payload: WildValue, action: WildValue) -
|
||||
return STORY_TASK_TEMPLATE.format(**kwargs)
|
||||
|
||||
|
||||
def get_story_task_completed_body(payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
def get_story_task_completed_body(payload: WildValue, action: WildValue) -> str | None:
|
||||
kwargs = {
|
||||
"task_description": action["description"].tame(check_string),
|
||||
}
|
||||
@@ -371,7 +371,7 @@ def get_story_update_estimate_body(payload: WildValue, action: WildValue) -> str
|
||||
return STORY_ESTIMATE_TEMPLATE.format(**kwargs)
|
||||
|
||||
|
||||
def get_reference_by_id(payload: WildValue, ref_id: Optional[int]) -> Optional[WildValue]:
|
||||
def get_reference_by_id(payload: WildValue, ref_id: int | None) -> WildValue | None:
|
||||
ref = None
|
||||
for reference in payload["references"]:
|
||||
if reference["id"].tame(check_string_or_int) == ref_id:
|
||||
@@ -431,7 +431,7 @@ def get_story_create_github_entity_body(entity: str, payload: WildValue, action:
|
||||
return template.format(**kwargs)
|
||||
|
||||
|
||||
def get_story_update_attachment_body(payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
def get_story_update_attachment_body(payload: WildValue, action: WildValue) -> str | None:
|
||||
kwargs = {
|
||||
"name_template": STORY_NAME_TEMPLATE.format(
|
||||
name=action["name"].tame(check_string),
|
||||
@@ -475,7 +475,7 @@ def get_story_joined_label_list(payload: WildValue, label_ids_added: list[int])
|
||||
return ", ".join(labels)
|
||||
|
||||
|
||||
def get_story_label_body(payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
def get_story_label_body(payload: WildValue, action: WildValue) -> str | None:
|
||||
kwargs = {
|
||||
"name_template": STORY_NAME_TEMPLATE.format(
|
||||
name=action["name"].tame(check_string),
|
||||
@@ -543,7 +543,7 @@ def get_story_update_owner_body(payload: WildValue, action: WildValue) -> str:
|
||||
return STORY_UPDATE_OWNER_TEMPLATE.format(**kwargs)
|
||||
|
||||
|
||||
def get_story_update_batch_body(payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
def get_story_update_batch_body(payload: WildValue, action: WildValue) -> str | None:
|
||||
# When the user selects one or more stories with the checkbox, they can perform
|
||||
# a batch update on multiple stories while changing multiple attributes at the
|
||||
# same time.
|
||||
@@ -660,7 +660,7 @@ def get_story_update_batch_body(payload: WildValue, action: WildValue) -> Option
|
||||
return STORY_UPDATE_BATCH_TEMPLATE.format(**kwargs)
|
||||
|
||||
|
||||
def get_entity_name(entity: str, payload: WildValue, action: WildValue) -> Optional[str]:
|
||||
def get_entity_name(entity: str, payload: WildValue, action: WildValue) -> str | None:
|
||||
name = action["name"].tame(check_string) if "name" in action else None
|
||||
|
||||
if name is None or action["entity_type"] == "branch":
|
||||
@@ -701,7 +701,7 @@ def send_channel_messages_for_actions(
|
||||
check_send_webhook_message(request, user_profile, topic_name, body, event)
|
||||
|
||||
|
||||
EVENT_BODY_FUNCTION_MAPPER: dict[str, Callable[[WildValue, WildValue], Optional[str]]] = {
|
||||
EVENT_BODY_FUNCTION_MAPPER: dict[str, Callable[[WildValue, WildValue], str | None]] = {
|
||||
"story_update_archived": partial(get_update_archived_body, "story"),
|
||||
"epic_update_archived": partial(get_update_archived_body, "epic"),
|
||||
"story_create": get_story_create_body,
|
||||
@@ -734,7 +734,7 @@ EVENT_BODY_FUNCTION_MAPPER: dict[str, Callable[[WildValue, WildValue], Optional[
|
||||
|
||||
ALL_EVENT_TYPES = list(EVENT_BODY_FUNCTION_MAPPER.keys())
|
||||
|
||||
EVENT_TOPIC_FUNCTION_MAPPER: dict[str, Callable[[WildValue, WildValue], Optional[str]]] = {
|
||||
EVENT_TOPIC_FUNCTION_MAPPER: dict[str, Callable[[WildValue, WildValue], str | None]] = {
|
||||
"story": partial(get_entity_name, "story"),
|
||||
"pull-request": partial(get_entity_name, "story"),
|
||||
"branch": partial(get_entity_name, "story"),
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
from zerver.decorator import webhook_view
|
||||
@@ -16,7 +14,7 @@ def api_dropbox_webhook(
|
||||
request: HttpRequest,
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
challenge: Optional[str] = None,
|
||||
challenge: str | None = None,
|
||||
) -> HttpResponse:
|
||||
if request.method == "POST":
|
||||
topic_name = "Dropbox"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# vim:fenc=utf-8
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -57,7 +56,7 @@ def api_gitea_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
user_specified_topic: OptionalUserSpecifiedTopicStr = None,
|
||||
) -> HttpResponse:
|
||||
return gogs_webhook_main(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -908,7 +908,7 @@ def api_github_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
user_specified_topic: OptionalUserSpecifiedTopicStr = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
@@ -943,8 +943,8 @@ def api_github_webhook(
|
||||
def get_zulip_event_name(
|
||||
header_event: str,
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
) -> Optional[str]:
|
||||
branches: str | None,
|
||||
) -> str | None:
|
||||
"""
|
||||
Usually, we return an event name that is a key in EVENT_FUNCTION_MAPPER.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import re
|
||||
from typing import Optional, Protocol, Union
|
||||
from typing import Protocol
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from pydantic import Json
|
||||
@@ -176,7 +176,7 @@ def get_merge_request_open_or_updated_body(
|
||||
)
|
||||
|
||||
|
||||
def get_assignees(payload: WildValue) -> Union[list[WildValue], WildValue]:
|
||||
def get_assignees(payload: WildValue) -> list[WildValue] | WildValue:
|
||||
assignee_details = payload.get("assignees")
|
||||
if not assignee_details:
|
||||
single_assignee_details = payload.get("assignee")
|
||||
@@ -189,7 +189,7 @@ def get_assignees(payload: WildValue) -> Union[list[WildValue], WildValue]:
|
||||
|
||||
|
||||
def replace_assignees_username_with_name(
|
||||
assignees: Union[list[WildValue], WildValue],
|
||||
assignees: list[WildValue] | WildValue,
|
||||
) -> list[dict[str, str]]:
|
||||
"""Replace the username of each assignee with their (full) name.
|
||||
|
||||
@@ -423,7 +423,7 @@ def api_gitlab_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
use_merge_request_title: Json[bool] = True,
|
||||
user_specified_topic: OptionalUserSpecifiedTopicStr = None,
|
||||
) -> HttpResponse:
|
||||
@@ -508,7 +508,7 @@ def get_topic_based_on_event(event: str, payload: WildValue, use_merge_request_t
|
||||
return get_repo_name(payload)
|
||||
|
||||
|
||||
def get_event(request: HttpRequest, payload: WildValue, branches: Optional[str]) -> Optional[str]:
|
||||
def get_event(request: HttpRequest, payload: WildValue, branches: str | None) -> str | None:
|
||||
event = validate_extract_webhook_http_header(request, "X-GitLab-Event", "GitLab")
|
||||
if event == "System Hook":
|
||||
# Convert the event name to a GitLab event title
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vim:fenc=utf-8
|
||||
from typing import Optional, Protocol
|
||||
from typing import Protocol
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -157,7 +157,7 @@ def api_gogs_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
user_specified_topic: OptionalUserSpecifiedTopicStr = None,
|
||||
) -> HttpResponse:
|
||||
return gogs_webhook_main(
|
||||
@@ -183,8 +183,8 @@ def gogs_webhook_main(
|
||||
request: HttpRequest,
|
||||
user_profile: UserProfile,
|
||||
payload: WildValue,
|
||||
branches: Optional[str],
|
||||
user_specified_topic: Optional[str],
|
||||
branches: str | None,
|
||||
user_specified_topic: str | None,
|
||||
) -> HttpResponse:
|
||||
repo = payload["repository"]["name"].tame(check_string)
|
||||
event = validate_extract_webhook_http_header(request, http_header_name, integration_name)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -45,7 +45,7 @@ def ticket_started_body(payload: WildValue) -> str:
|
||||
)
|
||||
|
||||
|
||||
def ticket_assigned_body(payload: WildValue) -> Optional[str]:
|
||||
def ticket_assigned_body(payload: WildValue) -> str | None:
|
||||
state = payload["state"].tame(check_string)
|
||||
kwargs = {
|
||||
"state": "open" if state == "opened" else state,
|
||||
@@ -90,7 +90,7 @@ def replied_body(actor: str, action: str, payload: WildValue) -> str:
|
||||
return body
|
||||
|
||||
|
||||
EVENTS_FUNCTION_MAPPER: dict[str, Callable[[WildValue], Optional[str]]] = {
|
||||
EVENTS_FUNCTION_MAPPER: dict[str, Callable[[WildValue], str | None]] = {
|
||||
"ticket_started": ticket_started_body,
|
||||
"ticket_assigned": ticket_assigned_body,
|
||||
"agent_replied": partial(replied_body, "agent", "replied to"),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Optional
|
||||
|
||||
from django.db.models import Q
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
@@ -22,7 +21,7 @@ IGNORED_EVENTS = [
|
||||
]
|
||||
|
||||
|
||||
def guess_zulip_user_from_harbor(harbor_username: str, realm: Realm) -> Optional[UserProfile]:
|
||||
def guess_zulip_user_from_harbor(harbor_username: str, realm: Realm) -> UserProfile | None:
|
||||
try:
|
||||
# Try to find a matching user in Zulip
|
||||
# We search a user's full name, short name,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Webhooks for external integrations.
|
||||
import re
|
||||
import string
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.models import Q
|
||||
@@ -29,7 +29,7 @@ IGNORED_EVENTS = [
|
||||
]
|
||||
|
||||
|
||||
def guess_zulip_user_from_jira(jira_username: str, realm: Realm) -> Optional[UserProfile]:
|
||||
def guess_zulip_user_from_jira(jira_username: str, realm: Realm) -> UserProfile | None:
|
||||
try:
|
||||
# Try to find a matching user in Zulip
|
||||
# We search a user's full name, short name,
|
||||
@@ -105,7 +105,7 @@ def get_in(payload: WildValue, keys: list[str], default: str = "") -> WildValue:
|
||||
|
||||
|
||||
def get_issue_string(
|
||||
payload: WildValue, issue_id: Optional[str] = None, with_title: bool = False
|
||||
payload: WildValue, issue_id: str | None = None, with_title: bool = False
|
||||
) -> str:
|
||||
# Guess the URL as it is not specified in the payload
|
||||
# We assume that there is a /browse/BUG-### page
|
||||
@@ -181,7 +181,7 @@ def get_sub_event_for_update_issue(payload: WildValue) -> str:
|
||||
return sub_event
|
||||
|
||||
|
||||
def get_event_type(payload: WildValue) -> Optional[str]:
|
||||
def get_event_type(payload: WildValue) -> str | None:
|
||||
event = payload.get("webhookEvent").tame(check_none_or(check_string))
|
||||
if event is None and payload.get("transition"):
|
||||
event = "jira:issue_updated"
|
||||
@@ -189,7 +189,7 @@ def get_event_type(payload: WildValue) -> Optional[str]:
|
||||
|
||||
|
||||
def add_change_info(
|
||||
content: str, field: Optional[str], from_field: Optional[str], to_field: Optional[str]
|
||||
content: str, field: str | None, from_field: str | None, to_field: str | None
|
||||
) -> str:
|
||||
content += f"* Changed {field}"
|
||||
if from_field:
|
||||
@@ -339,7 +339,7 @@ def handle_comment_deleted_event(payload: WildValue, user_profile: UserProfile)
|
||||
)
|
||||
|
||||
|
||||
JIRA_CONTENT_FUNCTION_MAPPER: dict[str, Optional[Callable[[WildValue, UserProfile], str]]] = {
|
||||
JIRA_CONTENT_FUNCTION_MAPPER: dict[str, Callable[[WildValue, UserProfile], str] | None] = {
|
||||
"jira:issue_created": handle_created_issue_event,
|
||||
"jira:issue_deleted": handle_deleted_issue_event,
|
||||
"jira:issue_updated": handle_updated_issue_event,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -133,7 +133,7 @@ def api_linear_webhook(
|
||||
return json_success(request)
|
||||
|
||||
|
||||
def get_topic(user_specified_topic: Optional[str], event: str, payload: WildValue) -> str:
|
||||
def get_topic(user_specified_topic: str | None, event: str, payload: WildValue) -> str:
|
||||
if user_specified_topic is not None:
|
||||
return user_specified_topic
|
||||
elif event == "comment":
|
||||
@@ -149,7 +149,7 @@ def get_topic(user_specified_topic: Optional[str], event: str, payload: WildValu
|
||||
raise UnsupportedWebhookEventTypeError(event)
|
||||
|
||||
|
||||
def get_event_type(payload: WildValue) -> Optional[str]:
|
||||
def get_event_type(payload: WildValue) -> str | None:
|
||||
event_type = payload["type"].tame(check_string)
|
||||
|
||||
if event_type == "Issue":
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from email.headerregistry import Address
|
||||
from typing import Union
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from typing_extensions import TypeAlias
|
||||
@@ -12,7 +11,7 @@ from zerver.lib.validator import WildValue, check_int, check_none_or, check_stri
|
||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||
from zerver.models import UserProfile
|
||||
|
||||
FormatDictType: TypeAlias = dict[str, Union[str, int]]
|
||||
FormatDictType: TypeAlias = dict[str, str | int]
|
||||
|
||||
PAGER_DUTY_EVENT_NAMES = {
|
||||
"incident.trigger": "triggered",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -28,7 +28,7 @@ def get_custom_http_headers_from_filename(http_header_key: str) -> Callable[[str
|
||||
fixture_to_headers = get_custom_http_headers_from_filename("HTTP_X_PATREON_EVENT")
|
||||
|
||||
|
||||
def get_members_create_body(payload: WildValue) -> Optional[str]:
|
||||
def get_members_create_body(payload: WildValue) -> str | None:
|
||||
last_charge_status = get_last_charge_status(payload)
|
||||
patron_status = get_patron_status(payload)
|
||||
# null values indicate the member has never pledged
|
||||
@@ -40,7 +40,7 @@ def get_members_create_body(payload: WildValue) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def get_members_update_body(payload: WildValue) -> Optional[str]:
|
||||
def get_members_update_body(payload: WildValue) -> str | None:
|
||||
last_charge_status = get_last_charge_status(payload)
|
||||
patron_status = get_patron_status(payload)
|
||||
if last_charge_status in ("Paid", None) and patron_status in ("active_patron", "former_patron"):
|
||||
@@ -52,7 +52,7 @@ def get_members_update_body(payload: WildValue) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def get_members_delete_body(payload: WildValue) -> Optional[str]:
|
||||
def get_members_delete_body(payload: WildValue) -> str | None:
|
||||
last_charge_status = get_last_charge_status(payload)
|
||||
patron_status = get_patron_status(payload)
|
||||
# null value indicates the member has never pledged
|
||||
@@ -64,7 +64,7 @@ def get_members_delete_body(payload: WildValue) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def get_members_pledge_create_body(payload: WildValue) -> Optional[str]:
|
||||
def get_members_pledge_create_body(payload: WildValue) -> str | None:
|
||||
last_charge_status = get_last_charge_status(payload)
|
||||
pledge_amount = get_pledge_amount(payload)
|
||||
# The only successful charge status is "Paid". null if not yet charged.
|
||||
@@ -79,7 +79,7 @@ def get_members_pledge_create_body(payload: WildValue) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def get_members_pledge_update_body(payload: WildValue) -> Optional[str]:
|
||||
def get_members_pledge_update_body(payload: WildValue) -> str | None:
|
||||
last_charge_status = get_last_charge_status(payload)
|
||||
pledge_amount = get_pledge_amount(payload)
|
||||
# The only successful charge status is "Paid". null if not yet charged.
|
||||
@@ -93,7 +93,7 @@ def get_members_pledge_update_body(payload: WildValue) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def get_members_pledge_delete_body(payload: WildValue) -> Optional[str]:
|
||||
def get_members_pledge_delete_body(payload: WildValue) -> str | None:
|
||||
last_charge_status = get_last_charge_status(payload)
|
||||
if last_charge_status in ("Paid", "Deleted", None):
|
||||
template = "{user_name}'s pledge has been cancelled. :cross_mark:\nTotal number of patrons: {patron_count}"
|
||||
@@ -104,11 +104,11 @@ def get_members_pledge_delete_body(payload: WildValue) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def get_last_charge_status(payload: WildValue) -> Optional[str]:
|
||||
def get_last_charge_status(payload: WildValue) -> str | None:
|
||||
return payload["data"]["attributes"]["last_charge_status"].tame(check_none_or(check_string))
|
||||
|
||||
|
||||
def get_patron_status(payload: WildValue) -> Optional[str]:
|
||||
def get_patron_status(payload: WildValue) -> str | None:
|
||||
return payload["data"]["attributes"]["patron_status"].tame(check_none_or(check_string))
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ def get_pay_per_name(payload: WildValue) -> str:
|
||||
return payload["included"][0]["attributes"]["pay_per_name"].tame(check_string)
|
||||
|
||||
|
||||
EVENT_FUNCTION_MAPPER: dict[str, Callable[[WildValue], Optional[str]]] = {
|
||||
EVENT_FUNCTION_MAPPER: dict[str, Callable[[WildValue], str | None]] = {
|
||||
"members:create": get_members_create_body,
|
||||
"members:update": get_members_update_body,
|
||||
"members:delete": get_members_delete_body,
|
||||
@@ -178,7 +178,7 @@ def api_patreon_webhook(
|
||||
def get_zulip_event_name(
|
||||
header_event: str,
|
||||
payload: WildValue,
|
||||
) -> Optional[str]:
|
||||
) -> str | None:
|
||||
"""
|
||||
Usually, we return an event name that is a key in EVENT_FUNCTION_MAPPER.
|
||||
We return None for an event that we know we don't want to handle.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Webhooks for external integrations."""
|
||||
|
||||
import re
|
||||
from typing import Any, Optional
|
||||
from typing import Any
|
||||
|
||||
import orjson
|
||||
from defusedxml.ElementTree import fromstring as xml_fromstring
|
||||
@@ -110,7 +110,7 @@ def api_pivotal_webhook_v5(request: HttpRequest, user_profile: UserProfile) -> t
|
||||
content = ""
|
||||
topic_name = f"#{story_id}: {story_name}"
|
||||
|
||||
def extract_comment(change: dict[str, Any]) -> Optional[str]:
|
||||
def extract_comment(change: dict[str, Any]) -> str | None:
|
||||
if change.get("kind") == "comment":
|
||||
return change.get("new_values", {}).get("text", None)
|
||||
return None
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
@@ -45,7 +45,7 @@ def get_push_branch_name(payload: WildValue) -> str:
|
||||
return payload["event"]["push"]["commits"][0]["raw_id"].tame(check_string).split("=>")[1]
|
||||
|
||||
|
||||
def get_event_name(payload: WildValue, branches: Optional[str]) -> Optional[str]:
|
||||
def get_event_name(payload: WildValue, branches: str | None) -> str | None:
|
||||
event_name = payload["event"]["name"].tame(check_string)
|
||||
if event_name == "repo-push" and branches is not None:
|
||||
branch = get_push_branch_name(payload)
|
||||
@@ -82,7 +82,7 @@ def api_rhodecode_webhook(
|
||||
user_profile: UserProfile,
|
||||
*,
|
||||
payload: JsonBodyPayload[WildValue],
|
||||
branches: Optional[str] = None,
|
||||
branches: str | None = None,
|
||||
) -> HttpResponse:
|
||||
event = get_event_name(payload, branches)
|
||||
if event is None:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Optional
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
@@ -161,7 +160,7 @@ def semaphore_classic(payload: WildValue) -> tuple[str, str, str, str]:
|
||||
return content, project_name, branch_name, event
|
||||
|
||||
|
||||
def semaphore_2(payload: WildValue) -> tuple[str, str, Optional[str], str]:
|
||||
def semaphore_2(payload: WildValue) -> tuple[str, str, str | None, str]:
|
||||
repo_url = payload["repository"]["url"].tame(check_string)
|
||||
project_name = payload["project"]["name"].tame(check_string)
|
||||
organization_name = payload["organization"]["name"].tame(check_string)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Optional
|
||||
from typing import Any
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
@@ -90,7 +90,7 @@ def is_sample_event(event: dict[str, Any]) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def convert_lines_to_traceback_string(lines: Optional[list[str]]) -> str:
|
||||
def convert_lines_to_traceback_string(lines: list[str] | None) -> str:
|
||||
traceback = ""
|
||||
if lines is not None:
|
||||
for line in lines:
|
||||
@@ -243,7 +243,7 @@ def handle_deprecated_payload(payload: dict[str, Any]) -> tuple[str, str]:
|
||||
return (topic_name, body)
|
||||
|
||||
|
||||
def transform_webhook_payload(payload: dict[str, Any]) -> Optional[dict[str, Any]]:
|
||||
def transform_webhook_payload(payload: dict[str, Any]) -> dict[str, Any] | None:
|
||||
"""Attempt to use webhook payload for the notification.
|
||||
|
||||
When the integration is configured as a webhook, instead of being added as
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest
|
||||
from django.http.response import HttpResponse
|
||||
from django.utils.translation import gettext as _
|
||||
@@ -24,7 +22,7 @@ def api_slack_webhook(
|
||||
user_name: str,
|
||||
text: str,
|
||||
channel_name: str,
|
||||
channels_map_to_topics: Optional[str] = None,
|
||||
channels_map_to_topics: str | None = None,
|
||||
) -> HttpResponse:
|
||||
content = ZULIP_MESSAGE_TEMPLATE.format(message_sender=user_name, text=text)
|
||||
topic_name = "Message from Slack"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Webhooks for external integrations.
|
||||
import time
|
||||
from typing import Optional, Sequence
|
||||
from typing import Sequence
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -318,7 +318,7 @@ def amount_string(amount: int, currency: str) -> str:
|
||||
|
||||
|
||||
def linkified_id(object_id: str, lower: bool = False) -> str:
|
||||
names_and_urls: dict[str, tuple[str, Optional[str]]] = {
|
||||
names_and_urls: dict[str, tuple[str, str | None]] = {
|
||||
# Core resources
|
||||
"ch": ("Charge", "charges"),
|
||||
"cus": ("Customer", "customers"),
|
||||
|
||||
@@ -7,8 +7,6 @@ value should always be in bold; otherwise the subject of US/task
|
||||
should be in bold.
|
||||
"""
|
||||
|
||||
from typing import Optional, Union
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
@@ -19,7 +17,7 @@ from zerver.lib.validator import WildValue, check_bool, check_none_or, check_str
|
||||
from zerver.lib.webhooks.common import check_send_webhook_message
|
||||
from zerver.models import UserProfile
|
||||
|
||||
EventType: TypeAlias = dict[str, Union[str, dict[str, Optional[Union[str, bool]]]]]
|
||||
EventType: TypeAlias = dict[str, str | dict[str, str | bool | None]]
|
||||
ReturnType: TypeAlias = tuple[WildValue, WildValue]
|
||||
|
||||
|
||||
@@ -204,10 +202,10 @@ def parse_create_or_delete(
|
||||
}
|
||||
|
||||
|
||||
def parse_change_event(change_type: str, message: WildValue) -> Optional[EventType]:
|
||||
def parse_change_event(change_type: str, message: WildValue) -> EventType | None:
|
||||
"""Parses change event."""
|
||||
evt: EventType = {}
|
||||
values: dict[str, Optional[Union[str, bool]]] = {
|
||||
values: dict[str, str | bool | None] = {
|
||||
"user": get_owner_name(message),
|
||||
"user_link": get_owner_link(message),
|
||||
"subject": get_subject(message),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Webhooks for teamcity integration
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from django.db.models import Q
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
@@ -28,7 +27,7 @@ need further help!
|
||||
"""
|
||||
|
||||
|
||||
def guess_zulip_user_from_teamcity(teamcity_username: str, realm: Realm) -> Optional[UserProfile]:
|
||||
def guess_zulip_user_from_teamcity(teamcity_username: str, realm: Realm) -> UserProfile | None:
|
||||
try:
|
||||
# Try to find a matching user in Zulip
|
||||
# We search a user's full name, short name,
|
||||
@@ -43,7 +42,7 @@ def guess_zulip_user_from_teamcity(teamcity_username: str, realm: Realm) -> Opti
|
||||
return None
|
||||
|
||||
|
||||
def get_teamcity_property_value(property_list: WildValue, name: str) -> Optional[str]:
|
||||
def get_teamcity_property_value(property_list: WildValue, name: str) -> str | None:
|
||||
for property in property_list:
|
||||
if property["name"].tame(check_string) == name:
|
||||
return property["value"].tame(check_string)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
@@ -40,7 +39,7 @@ def canary_kind(message: WildValue) -> str:
|
||||
return "canary"
|
||||
|
||||
|
||||
def source_ip_and_reverse_dns(message: WildValue) -> tuple[Optional[str], Optional[str]]:
|
||||
def source_ip_and_reverse_dns(message: WildValue) -> tuple[str | None, str | None]:
|
||||
"""
|
||||
Extract the source IP and reverse DNS information from a canary request.
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from pydantic import Json
|
||||
@@ -24,8 +23,8 @@ def api_transifex_webhook(
|
||||
resource: str,
|
||||
language: str,
|
||||
event: str,
|
||||
translated: Optional[Json[int]] = None,
|
||||
reviewed: Optional[Json[int]] = None,
|
||||
translated: Json[int] | None = None,
|
||||
reviewed: Json[int] | None = None,
|
||||
) -> HttpResponse:
|
||||
topic_name = f"{project} in {language}"
|
||||
if event == "translation_completed":
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Webhooks for external integrations.
|
||||
from typing import Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
||||
from zerver.decorator import return_success_on_head_request, webhook_view
|
||||
@@ -35,7 +33,7 @@ def api_trello_webhook(
|
||||
return json_success(request)
|
||||
|
||||
|
||||
def get_topic_and_body(payload: WildValue, action_type: str) -> Optional[tuple[str, str]]:
|
||||
def get_topic_and_body(payload: WildValue, action_type: str) -> tuple[str, str] | None:
|
||||
if action_type in SUPPORTED_CARD_ACTIONS:
|
||||
return process_card_action(payload, action_type)
|
||||
if action_type in IGNORED_CARD_ACTIONS:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Mapping, Optional
|
||||
from typing import Mapping
|
||||
|
||||
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
|
||||
from zerver.lib.validator import WildValue, check_string
|
||||
@@ -25,16 +25,14 @@ ACTIONS_TO_MESSAGE_MAPPER = {
|
||||
}
|
||||
|
||||
|
||||
def process_board_action(
|
||||
payload: WildValue, action_type: Optional[str]
|
||||
) -> Optional[tuple[str, str]]:
|
||||
def process_board_action(payload: WildValue, action_type: str | None) -> tuple[str, str] | None:
|
||||
action_type = get_proper_action(payload, action_type)
|
||||
if action_type is not None:
|
||||
return get_topic(payload), get_body(payload, action_type)
|
||||
return None
|
||||
|
||||
|
||||
def get_proper_action(payload: WildValue, action_type: Optional[str]) -> Optional[str]:
|
||||
def get_proper_action(payload: WildValue, action_type: str | None) -> str | None:
|
||||
if action_type == "updateBoard":
|
||||
data = get_action_data(payload)
|
||||
# we don't support events for when a board's background
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Mapping, Optional
|
||||
from typing import Mapping
|
||||
|
||||
from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
|
||||
from zerver.lib.validator import WildValue, check_bool, check_none_or, check_string
|
||||
@@ -75,14 +75,14 @@ def prettify_date(date_string: str) -> str:
|
||||
return date_string.replace("T", " ").replace(".000", "").replace("Z", " UTC")
|
||||
|
||||
|
||||
def process_card_action(payload: WildValue, action_type: str) -> Optional[tuple[str, str]]:
|
||||
def process_card_action(payload: WildValue, action_type: str) -> tuple[str, str] | None:
|
||||
proper_action = get_proper_action(payload, action_type)
|
||||
if proper_action is not None:
|
||||
return get_topic(payload), get_body(payload, proper_action)
|
||||
return None
|
||||
|
||||
|
||||
def get_proper_action(payload: WildValue, action_type: str) -> Optional[str]:
|
||||
def get_proper_action(payload: WildValue, action_type: str) -> str | None:
|
||||
if action_type == "updateCard":
|
||||
data = get_action_data(payload)
|
||||
old_data = data["old"]
|
||||
|
||||
Reference in New Issue
Block a user