Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # op-helper.py for making threads on /vt/
- # Released under MIT License, software is provided as-is and all that crap.
- # By C-Anon
- import re, json, urllib.request
- import datetime, time
- ##########################
- # CONFIGURATION
- # Ignore streams if they're set this amount of days from now (or more)
- ignore_days = 10
- # Sort streams by starting timestamp
- sort_streams = False
- # Show timezones
- show_timezones = True
- # If true, data is output to a file instead of the terminal
- output_to_file = True
- outfname = 'op-helper.txt'
- # Channel data
- # The format is channel ID followed by a space, then followed
- # by the name of the channel. Empty lines are ignored
- channel_data = """
- UC8P3OkWBUsrk93f1pV0b5bQ Ageha Himeragi
- UCEnhASxlFG-ZPCpYDTYIQZA Charo Nemurime
- UCAx0YWXJgyvXx5oDvrDaN_A Himari Inumaki
- UCvm34tgJ0ZaKzTinWVyXpcA Himea D'Almaria
- UC6tSB9TnO0f01OBeo9UEJZA Hina Misora
- UCVtuciDzkjxCP_O7r-0QhXQ Ito Shinonome
- UCJePO0Zl-zZTqjpHO82RNNA Lia Mitsurugi
- UCN3mosAMYBdogyQovOhPrxA Luna Rurine
- UClXfBZMVxt-JgNMaHGr5NMQ Mahiru Kumaboshi
- UCUUjykb68Lf85CbWX6gAmog Mireille Kuuma
- UCM6iy_rSgSMbFjx10Z6VVGA Miu Hizuki
- UCIm8pnnTNhCgGAtNxrQQv-g Yue Saohime
- """
- # Timezone data
- # You can specify timezones to display along with the other information.
- # The format is the name of the timezone followed by a space, then followed
- # by the number of hours from UTC (e.g. Mexico City timezone is GMT-5 in summer)
- #
- # This might need to be adjusted as countries adopt and abandon daylight savings time
- # throughout the year.
- timezone_data = """
- MEX -5
- ARG -3
- ESP 2
- JAP 9
- """
- # END OF CONFIGURATION
- ##########################
- now = time.time
- def getStreams(channel_id, channel_owner):
- url = 'https://www.youtube.com/channel/%s/' % (channel_id)
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0',
- 'Accept-Language': 'en-US,en;q=0.5'
- }
- try:
- req = urllib.request.Request(url, headers=headers)
- conn = urllib.request.urlopen(req)
- except (urllib.error.URLError, ValueError) as e:
- print("Error! Couldn't retrieve URL. ", str(e).capitalize())
- return
- response = conn.read().decode('utf-8')
- temp = re.findall('<script nonce="[^"]+">var ytInitialData = (.*?);</script>', response)
- if not temp:
- return
- streams = {}
- json_obj = json.loads(temp[0])
- first_tab = json_obj['contents']['twoColumnBrowseResultsRenderer']['tabs'][0]
- for section in first_tab['tabRenderer']['content']['sectionListRenderer']['contents']:
- if 'shelfRenderer' not in section['itemSectionRenderer']['contents'][0]:
- continue
- shelf_type = section['itemSectionRenderer']['contents'][0]['shelfRenderer']['title']['runs'][0]['text']
- if shelf_type not in ['Live now', 'Upcoming live streams']:
- continue
- if 'expandedShelfContentsRenderer' not in section['itemSectionRenderer']['contents'][0]['shelfRenderer']['content']:
- row = section['itemSectionRenderer']['contents'][0]['shelfRenderer']['content']['horizontalListRenderer']['items']
- vrname = 'gridVideoRenderer'
- else:
- row = section['itemSectionRenderer']['contents'][0]['shelfRenderer']['content']['expandedShelfContentsRenderer']['items']
- vrname = 'videoRenderer'
- for elem in row:
- new_stream = {'videoId': '', 'type' : '', 'start' : '', 'title' : '', 'owner':''}
- if shelf_type == "Live now":
- new_stream['videoId'] = elem[vrname]['videoId']
- new_stream['type'] = "live"
- new_stream['start'] = ""
- new_stream['owner'] = channel_owner
- new_stream['title'] = elem[vrname]['title']['simpleText']
- if 'live' not in streams:
- streams['live'] = [new_stream]
- else:
- streams['live'].append(new_stream)
- else:
- new_stream['videoId'] = elem[vrname]['videoId']
- new_stream['type'] = "upcoming"
- new_stream['start'] = elem[vrname]['upcomingEventData']['startTime']
- new_stream['owner'] = channel_owner
- new_stream['title'] = elem[vrname]['title']['simpleText']
- if 'upcoming' not in streams:
- streams['upcoming'] = [new_stream]
- else:
- streams['upcoming'].append(new_stream)
- return streams
- def getTimeString(ts):
- ret = ""
- last_date = ""
- for tz in timezones:
- dts = ts + (tz['delta'] * 3600)
- dts = datetime.datetime.utcfromtimestamp(dts)
- date = datetime.datetime.strftime(dts, '%Y-%m-%d')
- if last_date != date:
- ret += date + " "
- ret += datetime.datetime.strftime(dts, '%H:%M') + " " + tz['name'] + " "
- last_date = date
- return ret
- def log(txt):
- if output_to_file and fp:
- fp.write(txt + "\n")
- else:
- print(txt)
- channels = []
- for line in channel_data.splitlines():
- if not line or line == "":
- continue
- tmp = line.split(' ')
- channels.append({'channelId': tmp[0], 'channelOwner': " ".join(tmp[1:])})
- timezones = []
- for line in timezone_data.splitlines():
- if not line or line == "":
- continue
- tmp = line.split(' ')
- timezones.append({'name': tmp[0], 'delta': float(tmp[1])})
- # Sort timezones
- timezones = sorted(timezones, key=lambda kv: kv['delta'])
- live_streams = []
- upcoming_streams = []
- # Retrieve information from channels
- for chan in channels:
- print("Retrieving %s channel (%s)" % (chan['channelOwner'], chan['channelId']))
- streams = getStreams(chan['channelId'], chan['channelOwner'])
- if not streams:
- continue
- if 'live' in streams:
- live_streams += streams['live']
- if 'upcoming' in streams:
- upcoming_streams += streams['upcoming']
- if output_to_file:
- fp = open(outfname, 'w', encoding='utf-8')
- live_streams = sorted(live_streams, key=lambda kv: kv['owner'])
- if live_streams:
- log('LIVE STREAMS:\n')
- last_owner = ""
- for stream in live_streams:
- if stream['owner'] != last_owner:
- log(stream['owner'])
- log(stream['title'])
- log("https://youtu.be/%s\n" % stream['videoId'])
- last_owner = stream['owner']
- log("\n")
- if sort_streams:
- upcoming_streams = sorted(upcoming_streams, key=lambda kv: kv['start'])
- if upcoming_streams:
- log('UPCOMING STREAMS:\n')
- last_owner = ''
- for stream in upcoming_streams:
- # If upcoming stream is more than 'ignore_days' days away, ignore it
- if now() + (60 * 60 * 24 * ignore_days) < int(stream['start']):
- continue
- timestr = getTimeString(int(stream['start']))
- if stream['owner'] != last_owner:
- log(stream['owner'])
- log(stream['title'])
- log("https://youtu.be/%s" % (stream['videoId']))
- if show_timezones:
- log(timestr)
- log("")
- last_owner = stream['owner']
- if output_to_file:
- print("Output to file %s" % outfname)
Advertisement
Add Comment
Please, Sign In to add comment