Skip to content

Commit

Permalink
better 'Watch Streak' strategy in priority system #11
Browse files Browse the repository at this point in the history
  • Loading branch information
Tkd-Alex committed Jan 23, 2021
1 parent c4e9466 commit 467fb8e
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 23 deletions.
10 changes: 9 additions & 1 deletion TwitchChannelPointsMiner/TwitchChannelPointsMiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(
username: str,
make_predictions: bool = True,
follow_raid: bool = True,
watch_streak: bool = False,
logger_settings: LoggerSettings = LoggerSettings(),
browser_settings: BrowserSettings = BrowserSettings(),
bet_settings: BetSettings = BetSettings(),
Expand All @@ -46,6 +47,7 @@ def __init__(
self.twitch = Twitch(self.username)
self.twitch_browser = None
self.follow_raid = follow_raid
self.watch_streak = watch_streak
self.streamers = []
self.events_predictions = {}
self.minute_watcher_thread = None
Expand Down Expand Up @@ -135,7 +137,11 @@ def run(self, streamers: list = [], followers=False):
self.twitch_browser.init()

self.minute_watcher_thread = threading.Thread(
target=self.twitch.send_minute_watched_events, args=(self.streamers,)
target=self.twitch.send_minute_watched_events,
args=(
self.streamers,
self.watch_streak,
),
)
# self.minute_watcher_thread.daemon = True
self.minute_watcher_thread.start()
Expand Down Expand Up @@ -186,6 +192,8 @@ def run(self, streamers: list = [], followers=False):
WebSocketsPool.handle_websocket_reconnection(self.ws_pool.ws)

def end(self, signum, frame):
logger.info("CTRL+C Detected! Please wait, just a moment\n")

if self.twitch_browser is not None:
self.twitch_browser.browser.quit()

Expand Down
29 changes: 25 additions & 4 deletions TwitchChannelPointsMiner/classes/Streamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ def __init__(self, username, channel_id, less_printing: bool = False):
self.online_at = 0
self.offline_at = 0
self.channel_points = 0

self.minute_watched_requests = None
self.minute_watched = 0
self.last_minute_watched = 0

self.raid = None
self.watch_streak_missing = True
self.history = {}

self.streamer_url = f"https://www.twitch.tv/{self.username}"
Expand All @@ -36,15 +41,28 @@ def __str__(self):
)

def set_offline(self):
self.offline_at = time.time()
self.is_online = False
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):
self.online_at = time.time()
self.is_online = True
if self.is_online is False:
self.online_at = time.time()
self.is_online = True
# Watch streak variables
self.watch_streak_missing = True
self.minute_watched = 0
self.last_minute_watched = 0

logger.info(f"{self} is Online!", extra={"emoji": ":partying_face:"})

def update_minute_watched(self):
if self.last_minute_watched != 0:
self.minute_watched += round((time.time() - self.last_minute_watched) / 60, 5)
self.last_minute_watched = time.time()

def print_history(self):
return ", ".join(
[
Expand All @@ -59,5 +77,8 @@ def update_history(self, reason_code, earned):
self.history[reason_code]["counter"] += 1
self.history[reason_code]["amount"] += earned

if reason_code == "WATCH_STREAK":
self.watch_streak_missing = False

def set_less_printing(self, value):
self.less_printing = value
51 changes: 43 additions & 8 deletions TwitchChannelPointsMiner/classes/Twitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,25 +180,60 @@ def make_predictions(self, event):
}
)

def send_minute_watched_events(self, streamers):
def send_minute_watched_events(self, streamers, watch_streak=False):
headers = {"user-agent": USER_AGENT}
while self.running:
# Twitch has a limit - you can't watch more than 2 channels at one time.
# We take the first two streamers from the list as they have the highest priority.
streamers_watching = [
streamer for streamer in streamers if streamer.is_online
][:2]
for streamer in streamers_watching:
streamers_index = [
i for i in range(0, len(streamers)) if streamers[i].is_online
]

# Check if we need need to change priority based on watch streak
"""
Viewers receive points for returning for x consecutive streams.
Each stream must be at least 10 minutes long and it must have been at least 30 minutes since the last stream ended.
"""
streamers_watching = []
if watch_streak is True:
for index in streamers_index:
if (
streamers[index].watch_streak_missing
and (
streamers[index].offline_at == 0
or ((time.time() - streamers[index].offline_at) // 60) > 30
)
and streamers[index].minute_watched <= 6
):
logger.info(
f"Switch priority: {streamers[index]}, WatchStreak missing is {streamers[index].watch_streak_missing} and minute_watched: {streamers[index].minute_watched}"
)
streamers_watching.append(index)
if len(streamers_watching) == 2:
break

if streamers_watching == []:
streamers_watching = streamers_index
else:
while len(streamers_watching) < 2 and len(streamers_index) > 1:
another_streamer_index = streamers_index.pop(0)
if another_streamer_index not in streamers_watching:
streamers_watching.append(another_streamer_index)

streamers_watching = streamers_watching[:2]
for index in streamers_watching:
next_iteration = time.time() + 60 / len(streamers_watching)
try:
response = requests.post(
streamer.minute_watched_requests.url,
data=streamer.minute_watched_requests.payload,
streamers[index].minute_watched_requests.url,
data=streamers[index].minute_watched_requests.payload,
headers=headers,
)
logger.debug(
f"Send minute watched request for {streamer} - Status code: {response.status_code}"
f"Send minute watched request for {streamers[index]} - Status code: {response.status_code}"
)
if response.status_code == 204:
streamers[index].update_minute_watched()
except requests.exceptions.ConnectionError as e:
logger.error(f"Error while trying to watch a minute: {e}")

Expand Down
7 changes: 3 additions & 4 deletions TwitchChannelPointsMiner/classes/TwitchLogin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ def __init__(self, client_id, username, user_agent):
self.token = None
self.login_check_result = False
self.session = requests.session()
self.session.headers.update({
"Client-ID": self.client_id,
"User-Agent": user_agent
})
self.session.headers.update(
{"Client-ID": self.client_id, "User-Agent": user_agent}
)
self.username = username
self.user_id = None
self.email = None
Expand Down
5 changes: 2 additions & 3 deletions TwitchChannelPointsMiner/classes/TwitchWebSocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import time

from datetime import timedelta
from random import randrange
from websocket import WebSocketApp

Expand Down Expand Up @@ -66,7 +65,7 @@ def reset(self, parent_pool):
self.last_ping = time.time()

def elapsed_last_pong(self):
return (time.time - self.last_pong) // 60
return (time.time() - self.last_pong) // 60

def elapsed_last_ping(self):
return (time.time - self.last_ping) // 60
return (time.time() - self.last_ping) // 60
7 changes: 4 additions & 3 deletions TwitchChannelPointsMiner/classes/WebSocketsPool.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,16 @@ def on_message(ws, message):
)

elif topic == "video-playback-by-id":
# There is stream-up message type, but it's sent earlier than the API updates
streamer_index = get_streamer_index(ws.streamers, topic_user)
if streamer_index != -1:
if message_type == "stream-down":
ws.streamers[streamer_index].set_offline()
if ws.streamers[streamer_index].is_online is True:
ws.streamers[streamer_index].set_offline()
elif message_type == "viewcount":
ws.twitch.check_streamer_online(
ws.streamers[streamer_index]
)
# There is stream-up message type, but it's sent earlier than the API updates

elif topic == "raid":
streamer_index = get_streamer_index(ws.streamers, topic_user)
Expand Down Expand Up @@ -234,14 +235,14 @@ def on_message(ws, message):
)
if start_bet_status is True:
# place_bet_thread = threading.Timer(event.closing_bet_after(current_timestamp), ws.twitch.make_predictions, (ws.events_predictions[event_id],))
execution_time = round(execution_time, 2)
start_after = (
event.closing_bet_after(
current_timestamp
)
- execution_time
)
start_after = max(1, start_after)
start_after = round(start_after, 2)
place_bet_thread = threading.Timer(
start_after,
ws.twitch_browser.place_bet,
Expand Down

0 comments on commit 467fb8e

Please sign in to comment.