Files
Twitch-Drops-Miner/TwitchChannelPointsMiner/classes/entities/Streamer.py
2021-02-26 12:21:15 +01:00

185 lines
5.8 KiB
Python

import json
import logging
import os
import time
from threading import Lock
from TwitchChannelPointsMiner.classes.entities.Bet import BetSettings
from TwitchChannelPointsMiner.classes.entities.Stream import Stream
from TwitchChannelPointsMiner.classes.Settings import Settings
from TwitchChannelPointsMiner.constants import URL
from TwitchChannelPointsMiner.utils import _millify
logger = logging.getLogger(__name__)
class StreamerSettings(object):
__slots__ = [
"make_predictions",
"follow_raid",
"claim_drops",
"watch_streak",
"bet",
]
def __init__(
self,
make_predictions: bool = None,
follow_raid: bool = None,
claim_drops: bool = None,
watch_streak: bool = None,
bet: BetSettings = None,
):
self.make_predictions = make_predictions
self.follow_raid = follow_raid
self.claim_drops = claim_drops
self.watch_streak = watch_streak
self.bet = bet
def default(self):
for name in ["make_predictions", "follow_raid", "claim_drops", "watch_streak"]:
if getattr(self, name) is None:
setattr(self, name, True)
if self.bet is None:
self.bet = BetSettings()
def __repr__(self):
return f"BetSettings(make_predictions={self.make_predictions}, follow_raid={self.follow_raid}, claim_drops={self.claim_drops}, watch_streak={self.watch_streak}, bet={self.bet})"
class Streamer(object):
__slots__ = [
"username",
"channel_id",
"settings",
"is_online",
"stream_up",
"online_at",
"offline_at",
"channel_points",
"minute_watched_requests",
"viewer_is_mod",
"stream",
"raid",
"history",
"streamer_url",
]
def __init__(self, username, settings=None):
self.username: str = username.lower().strip()
self.channel_id: str = ""
self.settings = settings
self.is_online = False
self.stream_up = 0
self.online_at = 0
self.offline_at = 0
self.channel_points = 0
self.minute_watched_requests = None
self.viewer_is_mod = False
self.stream = Stream()
self.raid = None
self.history = {}
self.streamer_url = f"{URL}/{self.username}"
self.mutex = Lock()
def __repr__(self):
return f"Streamer(username={self.username}, channel_id={self.channel_id}, channel_points={_millify(self.channel_points)})"
def __str__(self):
return (
f"{self.username} ({_millify(self.channel_points)} points)"
if Settings.logger.less
else self.__repr__()
)
def set_offline(self):
if self.is_online is True:
self.offline_at = time.time()
self.is_online = False
logger.info(f"{self} is Offline!", extra={"emoji": ":sleeping:"})
def set_online(self):
if self.is_online is False:
self.online_at = time.time()
self.is_online = True
self.stream.init_watch_streak()
logger.info(f"{self} is Online!", extra={"emoji": ":partying_face:"})
def print_history(self):
return ", ".join(
[
f"{key}({self.history[key]['counter']} times, {_millify(self.history[key]['amount'])} gained)"
for key in sorted(self.history)
if self.history[key]["counter"] != 0
]
)
def update_history(self, reason_code, earned, counter=1):
if reason_code not in self.history:
self.history[reason_code] = {"counter": 0, "amount": 0}
self.history[reason_code]["counter"] += counter
self.history[reason_code]["amount"] += earned
if reason_code == "WATCH_STREAK":
self.stream.watch_streak_missing = False
def stream_up_elapsed(self):
return self.stream_up == 0 or ((time.time() - self.stream_up) > 120)
def drops_condition(self):
return (
self.settings.claim_drops is True
and self.is_online is True
and self.stream.drops_tags is True
and self.stream.campaigns_ids != []
)
# === ANALYTICS === #
def persistent_points(self, event_type, event_text):
event_type = event_type.upper()
if event_type in ["WATCH_STREAK", "WIN", "LOSE"]:
primary_color = (
"#45c1ff"
if event_type == "WATCH_STREAK"
else ("#ff4560" if event_type == "LOSE" else "#54ff45")
)
data = {
"marker": {
"size": 5,
"fillColor": "#fff",
"strokeColor": primary_color,
"radius": 2,
},
"label": {
"borderColor": primary_color,
"offsetY": 0,
"style": {
"color": "#fff",
"background": primary_color,
},
"text": event_text,
},
}
self.__save_json("points", data)
def persistent_series(self):
self.__save_json("series")
def __save_json(self, key, data={}):
# https://stackoverflow.com/questions/4676195/why-do-i-need-to-multiply-unix-timestamps-by-1000-in-javascript
data.update({"x": round(time.time() * 1000), "y": self.channel_points})
fname = os.path.join(Settings.analytics_path, f"{self.username}.json")
with self.mutex:
json_data = json.load(open(fname, "r")) if os.path.isfile(fname) else {}
if key not in json_data:
json_data[key] = []
json_data[key].append(data)
json.dump(json_data, open(fname, "w"), indent=4)