I asked ChatGPT to replace requests with urlib3:
#!/usr/bin/python
import urllib3
import json
from datetime import datetime, timedelta, timezone
import xml.etree.ElementTree as ET
import socket
import io
# CONFIG #############################################################################################
SOCKET = "/config/epggrab/xmltv.sock" # Path to your UNIX socket
######################################################################################################
now = datetime.now(timezone.utc)
start_time = now - timedelta(
minutes=now.minute % 30, seconds=now.second, microseconds=now.microsecond
)
stop_time = start_time + timedelta(hours=8)
epg_begin = start_time.strftime("%Y-%m-%dT%H:%M:%S-00:00")
epg_end = stop_time.strftime("%Y-%m-%dT%H:%M:%S-00:00")
# Initialize urllib3 PoolManager
http = urllib3.PoolManager()
# Fetch data using urllib3
url = f"https://api.pluto.tv/v2/channels?start={epg_begin}&stop={epg_end}"
response = http.request('GET', url)
data = json.loads(response.data.decode('utf-8'))
m3u = "#EXTM3U\n"
root = ET.Element("tv")
programmes = []
for channel in data:
channel_element = ET.SubElement(root, "channel", id="pluto-" + channel["_id"])
ET.SubElement(channel_element, "display-name").text = channel["name"]
ET.SubElement(channel_element, "channel-number").text = str(channel["number"])
ET.SubElement(channel_element, "icon").text = channel.get("colorLogoPNG", {}).get(
"path", ""
)
m3u += f'#EXTINF:-1 tvg-ID="{"pluto-" + channel["_id"]}" tvg-chno="{channel["number"]}" tvg-name="{channel["name"]}" tvg-logo="{channel.get("colorLogoPNG", {}).get("path", "")}", {channel["name"]}\n'
m3u += (
f"pipe://streamlink 'https://pluto.tv/live-tv/{channel['_id']}' best --stdout\n"
)
for programme in channel["timelines"]:
programme_data = {
"start": programme["start"],
"stop": programme["stop"],
"channel": "pluto-" + channel["_id"],
"title": programme["title"],
"episode": programme.get("episode", {}),
}
programmes.append(programme_data)
for programme in programmes:
start_time = datetime.fromisoformat(programme["start"]).strftime(
"%Y%m%d%H%M%S +0000"
)
stop_time = datetime.fromisoformat(programme["stop"]).strftime("%Y%m%d%H%M%S +0000")
programme_element = ET.SubElement(
root,
"programme",
start=start_time,
stop=stop_time,
channel=programme["channel"],
)
ET.SubElement(programme_element, "title").text = programme.get("title", "Untitled")
ET.SubElement(programme_element, "sub-title").text = programme["episode"].get(
"name", ""
)
ET.SubElement(programme_element, "desc").text = programme["episode"].get(
"description", ""
)
ET.SubElement(programme_element, "episode-num").text = (
f'S{programme["episode"].get("season", 0)}E{programme["episode"].get("number", 0)}'
)
ET.SubElement(programme_element, "category").text = programme["episode"].get(
"genre", ""
)
ET.SubElement(programme_element, "category").text = programme["episode"].get(
"subGenre", ""
)
ET.SubElement(programme_element, "category").text = programme.get("category", "")
tree = ET.ElementTree(root)
ET.indent(tree, space="\t", level=0)
xml_bytes = io.BytesIO()
tree.write(xml_bytes, encoding="UTF-8", xml_declaration=True)
try:
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
s.connect(SOCKET)
xml_bytes.seek(0)
s.sendall(xml_bytes.read())
except:
pass
with open("pluto.xmltv", "wb") as file:
tree.write(file, encoding="utf-8", xml_declaration=True)
print(m3u)
Give it a try.
While requests is included with most versions of Python, I think urlib3 is even more common.