Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/twitchio/rewards.py
7813 views
# -*- coding: utf-8 -*-12"""3The MIT License (MIT)45Copyright (c) 2017-2021 TwitchIO67Permission is hereby granted, free of charge, to any person obtaining a8copy of this software and associated documentation files (the "Software"),9to deal in the Software without restriction, including without limitation10the rights to use, copy, modify, merge, publish, distribute, sublicense,11and/or sell copies of the Software, and to permit persons to whom the12Software is furnished to do so, subject to the following conditions:1314The above copyright notice and this permission notice shall be included in15all copies or substantial portions of the Software.1617THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER23DEALINGS IN THE SOFTWARE.24"""2526import datetime27from typing import Optional, TYPE_CHECKING2829from .errors import HTTPException, Unauthorized3031if TYPE_CHECKING:32from .http import TwitchHTTP33from .user import PartialUser343536__all__ = "CustomReward", "CustomRewardRedemption"373839class CustomReward:40"""41Represents a Custom Reward object, as given by the api. Use :func:`User.get_custom_rewards` to fetch these42"""4344__slots__ = (45"_http",46"_channel",47"id",48"image",49"background_color",50"enabled",51"cost",52"title",53"prompt",54"input_required",55"max_per_stream",56"max_per_user_stream",57"cooldown",58"paused",59"in_stock",60"redemptions_skip_queue",61"redemptions_current_stream",62"cooldown_until",63"_broadcaster_id",64)6566def __init__(self, http: "TwitchHTTP", obj: dict, channel: "PartialUser"):67self._http = http68self._channel = channel6970try:71self._broadcaster_id = obj["broadcaster_id"]72except KeyError:73self._broadcaster_id = obj["channel_id"]7475self.id = obj["id"]76self.image = obj["image"]["url_1x"] if obj["image"] else obj["default_image"]["url_1x"]77self.background_color = obj["background_color"]78self.enabled = obj["is_enabled"]79self.cost = obj["cost"]80self.title = obj["title"]81self.prompt = obj["prompt"]82self.input_required = obj["is_user_input_required"]8384try:85self.max_per_stream = (86obj["max_per_stream_setting"]["is_enabled"],87obj["max_per_stream_setting"]["max_per_stream"],88)89self.max_per_user_stream = (90obj["max_per_user_per_stream_setting"]["is_enabled"],91obj["max_per_user_per_stream_setting"]["max_per_user_per_stream"],92)93self.cooldown = (94obj["global_cooldown_setting"]["is_enabled"],95obj["global_cooldown_setting"]["global_cooldown_seconds"],96)97except KeyError:98self.max_per_stream = (obj["max_per_stream"]["is_enabled"], obj["max_per_stream"]["max_per_stream"])99self.max_per_user_stream = (100obj["max_per_user_per_stream"]["is_enabled"],101obj["max_per_user_per_stream"]["max_per_user_per_stream"],102)103self.cooldown = (104obj["global_cooldown"]["is_enabled"],105obj["global_cooldown"]["global_cooldown_seconds"],106)107108self.paused = obj["is_paused"]109self.in_stock = obj["is_in_stock"]110self.redemptions_skip_queue = obj["should_redemptions_skip_request_queue"]111self.redemptions_current_stream = obj["redemptions_redeemed_current_stream"]112self.cooldown_until = obj["cooldown_expires_at"]113114async def edit(115self,116token: str,117title: str = None,118prompt: str = None,119cost: int = None,120background_color: str = None,121enabled: bool = None,122input_required: bool = None,123max_per_stream_enabled: bool = None,124max_per_stream: int = None,125max_per_user_per_stream_enabled: bool = None,126max_per_user_per_stream: int = None,127global_cooldown_enabled: bool = None,128global_cooldown: int = None,129paused: bool = None,130redemptions_skip_queue: bool = None,131):132"""133Edits the reward. Note that apps can only modify rewards they have made.134135Parameters136-----------137token: the bearer token for the channel of the reward138title: the new title of the reward139prompt: the new prompt for the reward140cost: the new cost for the reward141background_color: the new background color for the reward142enabled: whether the reward is enabled or not143input_required: whether user input is required or not144max_per_stream_enabled: whether the stream limit should be enabled145max_per_stream: how many times this can be redeemed per stream146max_per_user_per_stream_enabled: whether the user stream limit should be enabled147max_per_user_per_stream: how many times a user can redeem this reward per stream148global_cooldown_enabled: whether the global cooldown should be enabled149global_cooldown: how many seconds the global cooldown should be150paused: whether redemptions on this reward should be paused or not151redemptions_skip_queue: whether redemptions skip the request queue or not152153Returns154--------155:class:`CustomReward` itself.156"""157158try:159data = await self._http.update_reward(160token,161self._broadcaster_id,162self.id,163title,164prompt,165cost,166background_color,167enabled,168input_required,169max_per_stream_enabled,170max_per_stream,171max_per_user_per_stream_enabled,172max_per_user_per_stream,173global_cooldown_enabled,174global_cooldown,175paused,176redemptions_skip_queue,177)178except Unauthorized as error:179raise Unauthorized("The given token is invalid", "", 401) from error180except HTTPException as error:181status = error.args[2]182if status == 403:183raise HTTPException(184"The custom reward was created by a different application, or channel points are "185"not available for the broadcaster (403)",186error.args[1],187403,188) from error189raise190else:191for reward in data["data"]:192if reward["id"] == self.id:193self.__init__(self._http, reward, self._channel)194break195196return self197198async def delete(self, token: str):199"""200Deletes the custom reward201202Parameters203----------204token:205:class:`str` the oauth token of the target channel206207Returns208--------209None210"""211try:212await self._http.delete_custom_reward(token, self._broadcaster_id, self.id)213except Unauthorized as error:214raise Unauthorized("The given token is invalid", "", 401) from error215except HTTPException as error:216status = error.args[2]217if status == 403:218raise HTTPException(219"The custom reward was created by a different application, or channel points are "220"not available for the broadcaster (403)",221error.args[1],222403,223) from error224raise225226async def get_redemptions(self, token: str, status: str, sort: str = None):227"""228Gets redemptions for this reward229230Parameters231-----------232token:233:class:`str` the oauth token of the target channel234status:235:class:`str` one of UNFULFILLED, FULFILLED or CANCELED236sort:237:class:`str` the order redemptions are returned in. One of OLDEST, NEWEST. Default: OLDEST.238"""239try:240data = await self._http.get_reward_redemptions(241token, self._broadcaster_id, self.id, status=status, sort=sort242)243except Unauthorized as error:244raise Unauthorized("The given token is invalid", "", 401) from error245except HTTPException as error:246status = error.args[2]247if status == 403:248raise HTTPException(249"The custom reward was created by a different application, or channel points are "250"not available for the broadcaster (403)",251error.args[1],252403,253) from error254raise255else:256return [CustomRewardRedemption(x, self._http, self) for x in data["data"]]257258259class CustomRewardRedemption:260261__slots__ = "_http", "_broadcaster_id", "id", "user_id", "user_name", "input", "status", "redeemed_at", "reward"262263def __init__(self, obj: dict, http: "TwitchHTTP", parent: Optional[CustomReward]):264self._http = http265self._broadcaster_id = obj["broadcaster_id"]266self.id = obj["id"]267self.user_id = int(obj["user_id"])268self.user_name = obj["user_name"]269self.input = obj["user_input"]270self.status = obj["status"]271self.redeemed_at = datetime.datetime.fromisoformat(obj["redeemed_at"])272self.reward = parent or obj["reward"]273274async def fulfill(self, token: str):275"""276marks the redemption as fulfilled277278Parameters279----------280token:281:class:`str` the token of the target channel282283Returns284--------285itself.286"""287reward_id = self.reward.id if isinstance(self.reward, CustomReward) else self.reward["id"]288try:289data = await self._http.update_reward_redemption_status(290token, self._broadcaster_id, self.id, reward_id, True291)292except Unauthorized as error:293raise Unauthorized("The given token is invalid", "", 401) from error294except HTTPException as error:295status = error.args[2]296if status == 403:297raise HTTPException(298"The custom reward was created by a different application, or channel points are "299"not available for the broadcaster (403)",300error.args[1],301403,302) from error303raise304else:305self.__init__(data["data"], self._http, self.reward if isinstance(self.reward, CustomReward) else None)306return self307308async def refund(self, token: str):309"""310marks the redemption as cancelled311312Parameters313----------314token:315:class:`str` the token of the target channel316317Returns318--------319itself.320"""321reward_id = self.reward.id if isinstance(self.reward, CustomReward) else self.reward["id"]322try:323data = await self._http.update_reward_redemption_status(324token, self._broadcaster_id, self.id, reward_id, False325)326except Unauthorized as error:327raise Unauthorized("The given token is invalid", "", 401) from error328except HTTPException as error:329status = error.args[2]330if status == 403:331raise HTTPException(332"The custom reward was created by a different application, or channel points are "333"not available for the broadcaster (403)",334error.args[1],335403,336) from error337raise338else:339self.__init__(data["data"], self._http, self.reward if isinstance(self.reward, CustomReward) else None)340return self341342343