Skip to content

Commit 15a2c35

Browse files
committed
v2.0.6
1 parent 77565bf commit 15a2c35

File tree

6 files changed

+85
-27
lines changed

6 files changed

+85
-27
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ Thanks to everyone for using this bot, contributing, leaving feedback and
124124
helping other people in [our Discord](https://discord.gg/kkq2XY4cJM)!
125125

126126
## Update History
127+
### v2.0.6
128+
_Thanks [1Gzy](https://github.com/1Gzy) for implementation idea!_
129+
* Fixes [this](https://github.com/ucarno/ow-league-tokens/issues/85) issue by not relying on live embed url.
130+
* Added experimental schedule mode based on [this](https://overwatchleague.com/en-us/schedule) schedule from OWL website.
131+
This option will fall back to checking stream status using new method if something goes wrong.
132+
127133
### v2.0.5
128134
* Added option to shut down PC after stream (requires root on Linux)
129135
* Fixed macOS certificate setup

src/app.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
OWL_CHANNEL_ID, PATH_PROFILES, OWC_CHANNEL_ID, YOUTUBE_AUTH_PASS_RE, STREAM_CHECK_FREQUENCY, NEW_TAB_URL, \
1515
DISCORD_URL, ISSUES_URL
1616
from utils import log_error, log_info, log_debug, get_active_stream, is_debug, check_for_new_version, set_debug, \
17-
make_debug_file, get_console_message, set_nowait, wait_before_finish, kill_headless_chromes, shut_down_pc, get_relative_time
17+
make_debug_file, get_console_message, set_nowait, wait_before_finish, kill_headless_chromes, shut_down_pc, get_seconds_till_next_match
1818

1919
error = lambda msg: log_error(f'Bot', msg)
2020
info = lambda msg: log_info(f'Bot', msg)
@@ -200,10 +200,10 @@ def start_chrome(config: dict):
200200
else:
201201
driver_info(driver, '&rAuthentication check failed. '
202202
'&mPlease log in to your Google account. If you don\'t see Google\'s login screen, '
203-
'then go to https://gmail.com/ and log in there and then go to '
204-
'https://youtube.com/. You have 5000 seconds for this.\n'
205-
'&rIf you still can\'t log in, then sync your Google Chrome profile '
206-
'using profile button located in upper right corner of a browser.')
203+
'then sync your Google Chrome profile using profile button located in upper right '
204+
'corner of a browser and go manually to https://www.youtube.com/ '
205+
'Please leave your browser open for a couple of minutes after logging in to make '
206+
'sure your session persists. You have 5000 seconds for that.\n')
207207

208208
WebDriverWait(driver, 5000).until(EC.url_matches(YOUTUBE_AUTH_PASS_RE))
209209
driver.get(NEW_TAB_URL)
@@ -224,6 +224,7 @@ def start_chrome(config: dict):
224224
live_url = None
225225
live_src = None
226226
checks_until_reload = 3
227+
sleep_schedule = 0
227228

228229
while True:
229230
skip_owc_check = False
@@ -239,9 +240,10 @@ def start_chrome(config: dict):
239240
debug('&gOWL stream is online!')
240241
current_url, current_src = url, 'OWL'
241242
skip_owc_check = True
242-
elif config['time_delta']:
243-
delta = get_relative_time()
244-
info('time until next live stream' + delta)
243+
elif config['schedule']:
244+
seconds = get_seconds_till_next_match()
245+
if seconds and seconds > 30 * 60:
246+
sleep_schedule = seconds - 30 * 60
245247

246248
if config['enable_owc'] and not skip_owc_check:
247249
url = get_active_stream(OWC_CHANNEL_ID)
@@ -297,6 +299,11 @@ def start_chrome(config: dict):
297299
info('Nothing changed, stream still &rOffline&y!')
298300

299301
live_url, live_src = current_url, current_src
302+
if sleep_schedule:
303+
info(f'Bot is going to sleep for {sleep_schedule} due to schedule.')
304+
sleep(sleep_schedule)
305+
sleep_schedule = 0
306+
300307
sleep(STREAM_CHECK_FREQUENCY)
301308

302309

src/constants.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
from colorama import Fore
44

55

6-
CURRENT_VERSION = '2.0.5'
6+
CURRENT_VERSION = '2.0.6'
77
UPDATE_DOWNLOAD_URL = 'https://github.com/ucarno/ow-league-tokens/releases/latest'
88
DISCORD_URL = 'https://discord.gg/kkq2XY4cJM'
99
ISSUES_URL = 'https://github.com/ucarno/ow-league-tokens/issues'
10+
FAKE_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
1011

1112
DEBUG_ENVIRON = 'OW_LEAGUE_TOKENS_DEBUG'
1213
NOWAIT_ENVIRON = 'OW_LEAGUE_TOKENS_NOWAIT'

src/menu.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ def menu():
119119
view_profiles
120120
),
121121
(
122-
f'Switch headless mode {"&g[enabled]" if config["headless"] else "&r[disabled]"} &m(experimental!)',
122+
f'Switch headless mode {"&g[enabled]" if config["headless"] else "&r[disabled]"}',
123123
lambda c: switch_setting(c, 'headless')
124124
),
125125
(
126-
f'Switch time delta mode {"&g[enabled]" if config["time_delta"] else "&r[disabled]"}',
127-
lambda c: switch_setting(c, 'time_delta')
126+
f'Switch schedule mode {"&g[enabled]" if config["schedule"] else "&r[disabled]"} &m(experimental!)',
127+
lambda c: switch_setting(c, 'schedule')
128128
),
129129
(
130130
f'Switch debug mode {"&g[enabled]" if config["debug"] else "&r[disabled]"}',

src/utils.py

+58-14
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from constants import TMPL_LIVE_STREAM_EMBED_URL, COLORS, TMPL_LIVE_STREAM_URL, VERSION_CHECK_URL, PATH_DEBUG, \
1515
CURRENT_VERSION, VERSION_ENVIRON, DEBUG_ENVIRON, PATH_CONFIG, UPDATE_DOWNLOAD_URL, NOWAIT_ENVIRON, \
16-
DEFAULT_CHROMIUM_FLAGS, PATH_STATS, SCHEDULE_URL
16+
DEFAULT_CHROMIUM_FLAGS, PATH_STATS, SCHEDULE_URL, FAKE_USER_AGENT
1717

1818

1919
def get_version(version: str) -> tuple:
@@ -36,6 +36,7 @@ def get_default_config() -> dict:
3636
'shut_down': False,
3737
'debug': False,
3838
'time_delta': False,
39+
'schedule': False,
3940
'chromium_binary': None,
4041
'chromium_flags': DEFAULT_CHROMIUM_FLAGS,
4142
}
@@ -57,6 +58,9 @@ def load_config() -> dict:
5758

5859
# v2.0.5
5960
'shut_down',
61+
62+
# v2.0.6
63+
'schedule',
6064
):
6165
if new_flag not in content:
6266
update_config = True
@@ -144,29 +148,69 @@ def kill_headless_chromes(binary_path: str | None = None):
144148
log_debug(src, f'Failed killing Chrome process(es): {str(e)}')
145149

146150

151+
def make_get_request(url: str):
152+
return requests.get(url, headers={'User-Agent': FAKE_USER_AGENT}, timeout=10)
153+
154+
147155
def get_active_stream(channel_id: str) -> str | None:
148156
"""Returns stream url if a channel with specified channel_id has active stream"""
149157
src = 'LiveCheck'
150158

151159
try:
152-
response = requests.get('https://www.youtube.com/channel/%s' % channel_id, timeout=10).text
153-
if "hqdefault_live.jpg" in response:
160+
response = make_get_request('https://www.youtube.com/channel/%s' % channel_id).text
161+
with open('response_sample.html', 'w+', encoding='utf-8') as f:
162+
f.write(response)
163+
f.close()
164+
if 'hqdefault_live.jpg' in response:
154165
video_id = re.search(r'vi/(.*?)/hqdefault_live.jpg', response).group(1)
155166
return TMPL_LIVE_STREAM_URL % video_id
156-
except requests.RequestException as e:
167+
except Exception as e:
157168
log_error(src, f'&rLive stream check failed: {str(e)}')
158-
tb = traceback.format_exc()
159-
make_debug_file('failed-getting-active-stream', tb)
169+
make_debug_file('failed-getting-active-stream', traceback.format_exc())
160170
return
161171

162-
def get_relative_time():
163-
resSCH = requests.get(SCHEDULE_URL, timeout=10).text
164-
JSONSCH = json.loads(re.search(r'statusText":"Watch Online","date":(.*?),"competitors":', resSCH).group(1))
165-
unix_time =(JSONSCH['startDate'])
166-
dt = datetime.fromtimestamp(unix_time/1000, timezone.utc)
167-
now = datetime.now(timezone.utc)
168-
delta_time = dt - now
169-
return str(delta_time - timedelta(microseconds=delta_time.microseconds))
172+
173+
def get_seconds_till_next_match() -> float | None:
174+
src = 'Schedule'
175+
176+
try:
177+
# getting page json
178+
schedule_html = requests.get(SCHEDULE_URL, timeout=10).text
179+
next_data = (
180+
schedule_html
181+
.split('<script id="__NEXT_DATA__" type="application/json">')[1]
182+
.split('</script>')[0].strip()
183+
)
184+
schedule_json = json.loads(next_data)
185+
186+
# getting matches
187+
blocks = schedule_json['props']['pageProps']['blocks']
188+
matches: list = []
189+
for block in blocks:
190+
if 'owlHeader' in block.keys():
191+
matches = block['owlHeader']['scoreStripList']['scoreStrip']['matches']
192+
break
193+
194+
if not matches:
195+
raise Exception('Could not get matches.')
196+
197+
pending_matches = list(filter(lambda match: match.get('status') == 'PENDING', matches))
198+
pending_matches.sort(key=lambda match: match['date']['startDate'])
199+
200+
if not pending_matches:
201+
raise Exception(f"No matches with status 'PENDING'.")
202+
203+
timestamp_ms = pending_matches[0]['date']['startDate']
204+
delta = datetime.fromtimestamp(timestamp_ms / 1000, timezone.utc) - datetime.now(timezone.utc)
205+
total_seconds = delta.total_seconds()
206+
207+
log_info(src, f'Closest match will be played in {delta}.')
208+
209+
return total_seconds
210+
except Exception as e:
211+
log_error(src, f'&rSchedule check failed: {str(e)}. Falling back to regular checks.')
212+
make_debug_file('failed-getting-schedule', traceback.format_exc())
213+
170214

171215
def check_for_new_version():
172216
log_src = 'Version'

version.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.5
1+
2.0.6

0 commit comments

Comments
 (0)