-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhololive_schedule.py
executable file
·261 lines (225 loc) · 8.62 KB
/
hololive_schedule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# Required additional packages:
# 1. bs4 (html analyse)
# 2. requests (get webpage)
import re
import os
import time
import datetime
# Install BeautifulSoup, lxml and requests with pip3 (If they are not installed)
try:
from bs4 import BeautifulSoup
import lxml
import requests as req
except:
os.system('pip3 install bs4 lxml requests')
from bs4 import BeautifulSoup
import requests as req
start = time.time()
# Emoji of the members
emoji = {
'ときのそら': '',
'ロボ子さん': '🤖',
'さくらみこ': '💮',
'星街すいせい': '☄️',
'夜空メル': '🌟',
'夏色まつり': '🏮',
'赤井はあと': '❤️',
'アキロゼ': '🍎',
'白上フブキ': '🌽',
'湊あくあ': '⚓️',
'紫咲シオン': '🌙',
'百鬼あやめ': '😈',
'癒月ちょこ': '🍫💋',
'大空スバル': '🚑',
'大神ミオ': '🌲',
'猫又おかゆ': '🍙',
'戌神ころね': '🥐',
'兎田ぺこら': '👯',
'潤羽るしあ': '🦋',
'不知火フレア': '🔥',
'白銀ノエル': '⚔',
'宝鐘マリン': '🏴☠️',
'天音かなた': '💫',
'桐生ココ': '🐉',
'角巻わため': '🐏',
'常闇トワ': '👾',
'姫森ルーナ': '🍬',
'AZKi': '🎤',
'Risu': '🐿',
'Moona': '🔮',
'Iofi': '🎨',
'夕刻ロベル': '🍷',
'奏手イヅル': '🎸',
'月下カオル': '💅',
'花咲みやび': '🌺',
'鏡見キラ': '💙',
'アルランディス': '🍕',
'律可': '⚙',
'アステル・レダ': '🎭',
'岸堂天真': '🦔💨',
'影山シエン': '🟣',
'荒咬オウガ': '🐃',
'ホロスターズ': '',
'雪花ラミィ': '☃️',
'獅白ぼたん': '♌',
'尾丸ポルカ': '🎪',
'桃鈴ねね': '🥟',
'魔乃アロエ': '👅',
'Ina': '🐙',
'Gura': '🔱',
'Amelia': '🔎',
'Calli': '💀',
'Kiara': '🐔'
}
# Designed UA header for HTTP-GET request
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
}
# Get cookie from domain schedule.hololive.tv
cookie_local = {}
resp = req.get("https://schedule.hololive.tv/lives/all", headers=headers)
cookie_local = resp.cookies
# Set the timezone as UTC in cookie to get schedule in UTC timezone
cookie_local.set("timezone", "UTC", domain="schedule.hololive.tv")
# Get HTML response of the schedule webpage
def get_html():
resp = req.get("https://schedule.hololive.tv/lives/all",
cookies=cookie_local)
return resp
# Get the nodes contain schedule info
# (The real live schedule is a div tag which class is 'tab-content')
def get_raw_schedule(html):
soup = BeautifulSoup(html.text, "lxml")
return soup.find_all(class_="tab-content")
# Traverse all tag nodes and classify them as tags contain date,
# time, VTuber's name and liveroom link, using class-id
def tag_classify(tag):
if(tag.has_attr("class")):
class_list = tag['class']
# Tags contain date strings always with a class-id 'holodule navbar-text'
if('holodule' in class_list
and 'navbar-text' in class_list):
return "date"
# Tags contain time strings always with a class-id contains 'datetime'
elif('datetime' in class_list):
return "time"
# Tags contain VTuber name always with a class-id contains 'text-right name'
elif('col' in class_list and 'text-right' in class_list and 'name' in class_list):
return "name"
# Tags contain liveroom link always with a class-id contains 'thumbnail'
elif('thumbnail' in class_list):
return "link"
else:
return "others"
else:
return "others"
# Confirm if the VTuber is streaming now
# (The VTubers who are streaming will have a red border around the liveroom info card on the schedule webpage)
def is_streaming(tag):
if(tag.has_attr("style")):
style_list = tag['style']
if('border: 3px red solid' in style_list):
return True
else:
return False
else:
return False
# Format the strings from tag nodes
def format_string(string):
return string.replace("\n", "").replace("\t", "").replace("\r", "").replace("None", "").replace(" ", "")
# Confirm if a VTuber's live is not started
# (The liveroom about to start will have strings contains 'scheduledStartTime' in their webpages)
def is_upcoming(tag):
start = time.time()
resp = req.get(tag['href'])
upcoming_flag = re.search("scheduledStartTime", resp.text)
if(upcoming_flag is not None):
end = time.time()
print("module is_upcoming: ")
print(end-start)
return True
else:
end = time.time()
print("module is_upcoming: ")
print(end-start)
return False
# Auto detect timezone and convert UTC time (on the webpage) to user's loacl time
def utc_2_localtime(utc):
utc_t = datetime.datetime.strptime(utc, "%m/%d %H:%M")
local_timestamp = time.time()
local_time = datetime.datetime.fromtimestamp(local_timestamp)
utc_time = datetime.datetime.utcfromtimestamp(local_timestamp)
offset = local_time - utc_time
local = utc_t + offset
return (datetime.datetime.strftime(local, "%m/%d %H:%M"))
# Get current time
def get_current_time():
timestamp = time.time()
local = datetime.datetime.fromtimestamp(timestamp)
return (datetime.datetime.strftime(local, "%m/%d %H:%M"))
# Get the tag nodes contain schedule info
raw_schedule = get_raw_schedule(get_html())
# Date status (changed when analyse new date)
date = "date_dummy_string"
schedule = [] # Blank schedule list
live = {} # Blank liveroom dictionary
timezone = time.strftime("%z", time.localtime()) # User's timezone
# Analyse tag nodes
for tag in raw_schedule[0].find_all():
# Tags contain date string detected (like '06/30(日)'), update date value
if(tag_classify(tag) == "date"):
date = format_string(tag.string)[0:5] # Drop week info
# Tags contain time string detected (like '14:00'),
# combine date and time as a key in the dictionary
elif(tag_classify(tag) == "time"):
for time_string in tag.strings:
if(time_string.replace("\n", "").replace("\t", "").replace("\r", "").replace("None", "").replace(" ", "") is not ""):
live['time'] = utc_2_localtime(
date+" "+format_string(time_string))
# Streaming time is further than current time,
# which means the stream is not beginning
if(live['time'] > get_current_time()):
live['status'] = 'upcoming'
# Tags contain VTuber's name string detected (like 'Risu'),
# insert the name as a key in the dictionary
elif(tag_classify(tag) == "name"):
live['host'] = format_string(tag.string)
# Tags contain liveroom link detected,
# get the status of the liveroom (Stream over, Streaming now or Stream will start)
# and insert different key in the dictionary
elif(tag_classify(tag) == "link"):
live['link'] = tag['href']
if(is_streaming(tag) is True):
live['status'] = 'streaming'
else:
live['status'] = 'over'
# If all keys of a dictionary is inserted, append it into the schedule list
if(len(live) == 4):
schedule.append(live)
live = {} # Clear the dictionary for new info
end = time.time()
time_taken = str(end - start)
# Print in the BitBar
print("▶️")
print("---")
print("Click to jump to hololive offical schedule website... | href=https://schedule.hololive.tv")
print("---")
print("Updated in " + time_taken + " seconds")
print("---")
print("Streaming now (Click to jump to the chatroom in your web browser)")
for stream_live in schedule:
if(stream_live['status'] == 'streaming'):
print("🔴 " + stream_live['host'] + emoji.get(
str(stream_live['host']), "") + " | href=" + stream_live['link'])
print("---")
print("Upcoming (Auto detected timezone is UTC" + timezone + ")")
for upcoming_live in schedule:
if(upcoming_live['status'] == 'upcoming'):
print(upcoming_live['time']+" "+upcoming_live['host'] + emoji.get(str(upcoming_live['host']), "") +
" | href="+upcoming_live['link'])
print("---")
print("Streaming over")
for over_live in schedule:
if(over_live['status'] == 'over'):
print(over_live['time']+" "+over_live['host'] + emoji.get(str(over_live['host']), "") +
" | href="+over_live['link'])