archiving community contributions on YouTube: unpublished captions, title and description translations and caption credits
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

83 linhas
2.8 KiB

  1. from os import system
  2. from os.path import isfile
  3. HEROKU = False
  4. if isfile("../Procfile") and isfile("../requirements.txt"):
  5. print("Heroku detected... using 20 threads instead of 50.")
  6. HEROKU = True
  7. if HEROKU:
  8. if not "aioquic" in open("../requirements.txt").read():
  9. print("Installing aioquic on this Heroku instance since it wasn't installed on deploy...")
  10. system("python3 -m pip install --user aioquic")
  11. import asyncio
  12. from typing import cast
  13. from urllib.parse import urlparse
  14. from aioquic.h3.connection import H3_ALPN
  15. from aioquic.asyncio.client import connect
  16. from aioquic.quic.configuration import QuicConfiguration
  17. from http3_base import HttpClient, prepare_response, perform_http_request
  18. from urllib.parse import urlparse
  19. class HTTP3Response:
  20. def __init__(self, input) -> None:
  21. headers, content, url, redirect = input
  22. self.content = content
  23. try:
  24. self.text = content.decode()
  25. except:
  26. print("Text decoding error")
  27. self.text = ""
  28. self.headers = {}
  29. for k, v in headers.items():
  30. self.headers[k.decode()] = v.decode()
  31. try:
  32. self.status_code = int(headers[b":status"])
  33. self.url = url
  34. except:
  35. print("Status code not included as header, defaulting to 200")
  36. self.status_code = 200
  37. self.ok = self.status_code < 400
  38. async def main(address, headers={}):
  39. parsed = urlparse(address)
  40. configuration = QuicConfiguration(
  41. is_client=True, alpn_protocols=H3_ALPN
  42. )
  43. async with connect(parsed.netloc, port=443, configuration=configuration, create_protocol=HttpClient) as client:
  44. client = cast(HttpClient, client)
  45. redirect = False
  46. while True:
  47. events = await perform_http_request(client=client, url=address, headers=headers)
  48. oheaders, ocontent = prepare_response(events)
  49. statuscode = int(oheaders[b":status"])
  50. if statuscode >= 300 and statuscode < 400 and b"location" in oheaders.keys():
  51. redirect = True
  52. origurl = address
  53. parsedorig = urlparse(origurl)
  54. address = oheaders[b"location"].decode()
  55. parsednew = urlparse(address)
  56. if not parsednew.scheme and not parsednew.netloc:
  57. address = parsedorig.scheme + "://" + parsedorig.netloc + address
  58. else:
  59. break
  60. return HTTP3Response((oheaders, ocontent, address, redirect))
  61. def get(url, headers={}, params={}):
  62. plist = []
  63. for item in params:
  64. k, v = item
  65. plist.append(str(k)+"="+str(v))
  66. if plist:
  67. pstring = "?"+"&".join(plist)
  68. else:
  69. pstring = ""
  70. url = url+pstring
  71. loop = asyncio.new_event_loop()
  72. return loop.run_until_complete(main(url, headers=headers))