Guest User

op-helper.py by C-Anon

a guest
Sep 28th, 2022
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.19 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # op-helper.py for making threads on /vt/
  3. # Released under MIT License, software is provided as-is and all that crap.
  4. # By C-Anon
  5.  
  6. import re, json, urllib.request
  7. import datetime, time
  8.  
  9.  
  10. ##########################
  11. #   CONFIGURATION
  12.  
  13. # Ignore streams if they're set this amount of days from now (or more)
  14. ignore_days = 10
  15.  
  16. # Sort streams by starting timestamp
  17. sort_streams = False
  18.  
  19. # Show timezones
  20. show_timezones = True
  21.  
  22. # If true, data is output to a file instead of the terminal
  23. output_to_file = True
  24. outfname = 'op-helper.txt'
  25.  
  26. # Channel data
  27. #   The format is channel ID followed by a space, then followed
  28. #   by the name of the channel. Empty lines are ignored
  29. channel_data = """
  30. UC8P3OkWBUsrk93f1pV0b5bQ Ageha Himeragi
  31. UCEnhASxlFG-ZPCpYDTYIQZA Charo Nemurime
  32. UCAx0YWXJgyvXx5oDvrDaN_A Himari Inumaki
  33. UCvm34tgJ0ZaKzTinWVyXpcA Himea D'Almaria
  34. UC6tSB9TnO0f01OBeo9UEJZA Hina Misora
  35. UCVtuciDzkjxCP_O7r-0QhXQ Ito Shinonome
  36. UCJePO0Zl-zZTqjpHO82RNNA Lia Mitsurugi
  37. UCN3mosAMYBdogyQovOhPrxA Luna Rurine
  38. UClXfBZMVxt-JgNMaHGr5NMQ Mahiru Kumaboshi
  39. UCUUjykb68Lf85CbWX6gAmog Mireille Kuuma
  40. UCM6iy_rSgSMbFjx10Z6VVGA Miu Hizuki
  41. UCIm8pnnTNhCgGAtNxrQQv-g Yue Saohime
  42.  
  43. """
  44.  
  45. # Timezone data
  46. #   You can specify timezones to display along with the other information.
  47. #   The format is the name of the timezone followed by a space, then followed
  48. #   by the number of hours from UTC (e.g. Mexico City timezone is GMT-5 in summer)
  49. #
  50. #   This might need to be adjusted as countries adopt and abandon daylight savings time
  51. #   throughout the year.
  52. timezone_data = """
  53. MEX -5
  54. ARG -3
  55. ESP 2
  56. JAP 9
  57. """
  58.  
  59. #   END OF CONFIGURATION
  60. ##########################
  61.  
  62. now = time.time
  63.  
  64. def getStreams(channel_id, channel_owner):
  65.     url = 'https://www.youtube.com/channel/%s/' % (channel_id)
  66.     headers = {
  67.         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0',
  68.         'Accept-Language': 'en-US,en;q=0.5'
  69.     }
  70.  
  71.     try:
  72.         req = urllib.request.Request(url, headers=headers)
  73.         conn = urllib.request.urlopen(req)
  74.     except (urllib.error.URLError, ValueError) as e:
  75.         print("Error! Couldn't retrieve URL. ", str(e).capitalize())
  76.         return
  77.     response = conn.read().decode('utf-8')
  78.     temp = re.findall('<script nonce="[^"]+">var ytInitialData = (.*?);</script>', response)
  79.     if not temp:
  80.         return
  81.  
  82.     streams = {}
  83.     json_obj = json.loads(temp[0])
  84.     first_tab = json_obj['contents']['twoColumnBrowseResultsRenderer']['tabs'][0]
  85.     for section in first_tab['tabRenderer']['content']['sectionListRenderer']['contents']:
  86.         if 'shelfRenderer' not in section['itemSectionRenderer']['contents'][0]:
  87.             continue
  88.         shelf_type = section['itemSectionRenderer']['contents'][0]['shelfRenderer']['title']['runs'][0]['text']
  89.         if  shelf_type not in ['Live now', 'Upcoming live streams']:
  90.             continue
  91.  
  92.         if 'expandedShelfContentsRenderer' not in section['itemSectionRenderer']['contents'][0]['shelfRenderer']['content']:
  93.             row = section['itemSectionRenderer']['contents'][0]['shelfRenderer']['content']['horizontalListRenderer']['items']
  94.             vrname = 'gridVideoRenderer'
  95.         else:
  96.             row = section['itemSectionRenderer']['contents'][0]['shelfRenderer']['content']['expandedShelfContentsRenderer']['items']
  97.             vrname = 'videoRenderer'
  98.         for elem in row:
  99.             new_stream = {'videoId': '', 'type'   : '', 'start'  : '', 'title'  : '', 'owner':''}
  100.             if shelf_type == "Live now":
  101.                 new_stream['videoId'] = elem[vrname]['videoId']
  102.                 new_stream['type']    = "live"
  103.                 new_stream['start']   = ""
  104.                 new_stream['owner']   = channel_owner
  105.                 new_stream['title']   = elem[vrname]['title']['simpleText']
  106.                 if 'live' not in streams:
  107.                     streams['live'] = [new_stream]
  108.                 else:
  109.                     streams['live'].append(new_stream)
  110.             else:
  111.                 new_stream['videoId'] = elem[vrname]['videoId']
  112.                 new_stream['type']    = "upcoming"
  113.                 new_stream['start']   = elem[vrname]['upcomingEventData']['startTime']
  114.                 new_stream['owner']   = channel_owner
  115.                 new_stream['title']   = elem[vrname]['title']['simpleText']
  116.                 if 'upcoming' not in streams:
  117.                     streams['upcoming'] = [new_stream]
  118.                 else:
  119.                     streams['upcoming'].append(new_stream)
  120.     return streams
  121.  
  122. def getTimeString(ts):
  123.     ret = ""
  124.     last_date = ""
  125.     for tz in timezones:
  126.         dts = ts + (tz['delta'] * 3600)
  127.         dts = datetime.datetime.utcfromtimestamp(dts)
  128.         date = datetime.datetime.strftime(dts, '%Y-%m-%d')
  129.         if last_date != date:
  130.             ret += date + " "
  131.         ret += datetime.datetime.strftime(dts, '%H:%M') + " " + tz['name'] + " "
  132.         last_date = date
  133.     return ret
  134.  
  135. def log(txt):
  136.     if output_to_file and fp:
  137.         fp.write(txt + "\n")
  138.     else:
  139.         print(txt)
  140.  
  141. channels = []
  142. for line in channel_data.splitlines():
  143.     if not line or line == "":
  144.         continue
  145.     tmp = line.split(' ')
  146.     channels.append({'channelId': tmp[0], 'channelOwner': " ".join(tmp[1:])})
  147.  
  148. timezones = []
  149. for line in timezone_data.splitlines():
  150.     if not line or line == "":
  151.         continue
  152.     tmp = line.split(' ')
  153.     timezones.append({'name': tmp[0], 'delta': float(tmp[1])})
  154.  
  155. # Sort timezones
  156. timezones = sorted(timezones, key=lambda kv: kv['delta'])
  157.  
  158. live_streams = []
  159. upcoming_streams = []
  160. # Retrieve information from channels
  161. for chan in channels:
  162.     print("Retrieving %s channel (%s)" % (chan['channelOwner'], chan['channelId']))
  163.     streams = getStreams(chan['channelId'], chan['channelOwner'])
  164.     if not streams:
  165.         continue
  166.     if 'live' in streams:
  167.         live_streams += streams['live']
  168.     if 'upcoming' in streams:
  169.         upcoming_streams += streams['upcoming']
  170.  
  171. if output_to_file:
  172.     fp = open(outfname, 'w', encoding='utf-8')
  173.  
  174. live_streams = sorted(live_streams, key=lambda kv: kv['owner'])
  175. if live_streams:
  176.     log('LIVE STREAMS:\n')
  177.     last_owner = ""
  178.     for stream in live_streams:
  179.         if stream['owner'] != last_owner:
  180.             log(stream['owner'])
  181.         log(stream['title'])
  182.         log("https://youtu.be/%s\n" % stream['videoId'])
  183.         last_owner = stream['owner']
  184. log("\n")
  185. if sort_streams:
  186.     upcoming_streams = sorted(upcoming_streams, key=lambda kv: kv['start'])
  187. if upcoming_streams:
  188.     log('UPCOMING STREAMS:\n')
  189.     last_owner = ''
  190.     for stream in upcoming_streams:
  191.         # If upcoming stream is more than 'ignore_days' days away, ignore it
  192.         if now() + (60 * 60 * 24 * ignore_days) < int(stream['start']):
  193.             continue
  194.  
  195.         timestr = getTimeString(int(stream['start']))
  196.         if stream['owner'] != last_owner:
  197.             log(stream['owner'])
  198.         log(stream['title'])
  199.         log("https://youtu.be/%s" % (stream['videoId']))
  200.         if show_timezones:
  201.             log(timestr)
  202.         log("")
  203.         last_owner = stream['owner']
  204. if output_to_file:
  205.     print("Output to file %s" % outfname)
  206.  
Advertisement
Add Comment
Please, Sign In to add comment