Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import re
- try: ###su python 2.5 non esiste il modulo io
- import io, gzip
- except:
- import cStringIO, gzip
- import subprocess
- import base64, random
- try:
- import http.client as client
- except:
- import httplib as client
- #####################################################################################
- #
- # rai.py - version 0.4a
- #
- #####################################################################################
- #
- # License GNU GPLv2
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- ####################################################################################
- #
- #
- # USAGE python3 rai.py [-vlcdir=<dir>][-uagent=<user-agent>][--ttAuth=<encoded>][-progs=(<xml_filepath>)][(channel|video_on_demand)]
- #
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Notice:
- # channel = RaiUno | RaiDue | RaiTre | RaiQuattro
- # RaiNews24 | RaiSport+ | RaiStoria | RaiEdu | RaiGulp
- # RaiSatExtra | RaiSatPremium | RaiSatCinema | RaiSatYoyo
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # Change Log
- # + 0.4a
- # - Updated ttAuth generation algorithm
- # - Improved efficency in "encode" functions
- # - Arguments management moved from "mms()" inner code into an explicit "arguments()" function
- # - The importable module is refactored from "mms()" to "playerURL()" now
- # - Defined an "authCode()" function witch returns ttAuth code
- # - Deprecated old "encode" functions
- # + 0.4
- # - Add tv channel programs list support (XML Format)
- # - Can now be imported as module, exposing "mms()"
- # - Add ttAuth argument useful for external software integration
- # - Bugfix in vlcdir argument: now automatically appends '/' character
- # - Refactoring
- # + 0.3
- # - Add Video-On-demand support
- # - Update of key in encode2 function
- # - Bugfix in encode2 fucntion: j-index rotation is setted by key length
- # - Refactoring
- #
- # + 0.2
- # - Update of ttAuth generation algorithm
- #
- # + 0.1
- # - Creation of ttAuth
- vlc_dir = "/Applications/VLC.app/Contents/MacOS" ###la directory di default di vlc per mac
- progs_file = "programs.xml"
- chan_name = ""
- ttAuth = ""
- stream = ""
- agent = "NSPlayer/11.08.0005.0000" ###un tentativo di camuffarsi da moonlight
- isVoD = False
- isPrograms = False
- urls = {
- "RaiUno": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=983",
- "RaiDue": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=984",
- "RaiTre": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=986",
- "Rai4": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=75708",
- "RaiSatCinema": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=72381",
- "RaiSatExtra": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=72382",
- "RaiSatPremium": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=72383",
- "RaiSatYoYo": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=72384",
- "RaiScuola": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=24268",
- "RaiStoria": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=24269",
- "RaiNews24": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=1",
- "RaiGulp": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=4119",
- "RaiSport+": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=4145",
- "RaiMed": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=87127",
- "EuroNews": "http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=113784",
- #"TG1" "http://link.rai.it/x/vod/ue/wmx/ultimo_tg1.asx",
- #"TG2" "http://link.rai.it/x/vod/ue/wmx/ultimo_tg2.asx",
- #"TG3" "http://link.rai.it/x/vod/ue/wmx/ultimo_tg3.asx",
- }
- def videoURL(pageURL):
- re_page = "^http://(?P<host>[a-zA-Z0-9]*\.([a-zA-Z0-9]*\.)+[a-zA-Z0-9]*)(?P<path>/[\w\-\+\~\%\#\.\/\?\=]*)"
- match_page = re.match(re_page, pageURL).groupdict()
- page_connection = client.HTTPConnection(match_page["host"])
- page_connection.putrequest("POST", match_page["path"])
- page_connection.putheader("User-Agent", agent)
- page_connection.putheader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
- page_connection.putheader("Accept-Language", "it-it,it;q=0.8,en-us;q=0.5,en;q=0.3")
- page_connection.putheader("Accept-Encoding", "gzip,deflate")
- page_connection.putheader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
- page_connection.putheader("Keep-Alive", "115")
- page_connection.putheader("Connection", "keep-alive")
- page_connection.putheader("Cookie", "volume=0,5; ns_cookietest=true; ns_session=true")
- page_connection.putheader("Cache-Control", "max-age=0")
- page_connection.endheaders()
- page_response = page_connection.getresponse().read()
- page_connection.close()
- page = str(gzip.GzipFile(fileobj=io.BytesIO(page_response)).read(), "utf8")
- return re.search("(?P<video>http://mediapolis.rai.it.*)\"", page).groupdict()["video"]
- def streamURL(pageURL):
- re_url = "^http://(?P<host>[a-zA-Z0-9]*\.([a-zA-Z0-9]*\.)+[a-zA-Z0-9]*)(?P<path>/[\w\-\+\~\%\#\.\/]*)\?cont\=(?P<chanid>\w*)"
- match_url = re.match(re_url, pageURL).groupdict()
- global ttAuth
- if ttAuth == "":
- ttAuth = authCode(match_url["chanid"])
- asx_connection = client.HTTPConnection(match_url["host"])
- asx_connection.putrequest("POST", match_url["path"]+"?cont="+match_url["chanid"])
- asx_connection.putheader("User-Agent", agent)
- asx_connection.putheader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
- asx_connection.putheader("Accept-Language", "it-it,it;q=0.8,en-us;q=0.5,en;q=0.3")
- asx_connection.putheader("Accept-Encoding", "gzip,deflate")
- asx_connection.putheader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
- asx_connection.putheader("Connection", "keep-alive")
- asx_connection.putheader("Keep-Alive", "115")
- asx_connection.putheader("viaurl", "www.rai.tv")
- asx_connection.putheader("ttAuth", ttAuth)
- asx_connection.putheader("Content-Length", "0")
- asx_connection.endheaders()
- asx_response = asx_connection.getresponse().read()
- asx_connection.close()
- try: ###niente bytes su python 2.5
- asx = bytes.decode(asx_response)
- except:
- asx = str.decode(asx_response)
- return re.search("(?P<mms>mms://.*)\"", asx).groupdict()["mms"]
- def raiDate():
- date_connection = client.HTTPConnection("videowall.rai.it")
- date_connection.putrequest("GET", "/cgi-bin/date")
- date_connection.putheader("User-Agent", agent)
- date_connection.putheader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
- date_connection.putheader("Accept-Language", "it-it,it;q=0.8,en-us;q=0.5,en;q=0.3")
- date_connection.putheader("Accept-Encoding", "gzip,deflate")
- date_connection.putheader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
- date_connection.putheader("Connection", "keep-alive")
- date_connection.putheader("Keep-Alive", "115")
- date_connection.endheaders()
- date_response = date_connection.getresponse().read()
- date_connection.close();
- try: ###niente bytes su python 2.5
- return bytes.decode(date_response[:len(date_response)-1])
- except:
- return str.decode(date_response[:len(date_response)-1])
- def raiPrograms(host, chan_name):
- if chan_name == "RaiQuattro": chan_name = "Rai4"
- if chan_name == "RaiSport+": chan_name = "RaiSportSatellite"
- if chan_name == "RaiStoria": chan_name = "RAIEDU2"
- if chan_name == "RaiSatExtra": chan_name = "Extra"
- if chan_name == "RaiSatPremium": chan_name = "Premium"
- if chan_name == "RaiSatCinema": chan_name = "CinemaWorld"
- if chan_name == "RaiSatYoyo": chan_name = "Yoyo"
- xml_connection = client.HTTPConnection(host)
- xml_connection.putrequest("GET", "/dl/portale/html/palinsesti/static/"+chan_name+".html")
- xml_connection.putheader("User-Agent", agent)
- xml_connection.putheader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
- xml_connection.putheader("Accept-Language", "it-it,it;q=0.8,en-us;q=0.5,en;q=0.3")
- xml_connection.putheader("Accept-Encoding", "gzip,deflate")
- xml_connection.putheader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
- xml_connection.putheader("Keep-Alive", "115")
- xml_connection.putheader("Connection", "keep-alive")
- xml_connection.endheaders()
- xml_response = xml_connection.getresponse().read()
- xml_connection.close()
- return str(gzip.GzipFile(fileobj=io.BytesIO(xml_response)).read(), "utf8")
- def encode1(token):
- rnd = random.randint(0,10)
- return ''.join(chr(ord(ch) ^ rnd) for ch in token) + ";" + str(rnd)
- def encode2(token, key="hMrxuE2T8V0WRW0VmHaKMoFwy1XRc+hK7eBX2tTLVTw="):
- return encode2b(token, key)
- #DEPRECATED
- def encode2a(token, key="hMrxuE2T8V0WRW0VmHaKMoFwy1XRc+hK7eBX2tTLVTw="):
- encoded = ""
- i, j, lenkey = 0, 0, len(key)
- for ch in token:
- encoded += chr(ord(token[i]) ^ ord(key[j]))
- i, j = (i+1), (j+1)%lenkey
- return encoded
- def encode2b(token, key="hMrxuE2T8V0WRW0VmHaKMoFwy1XRc+hK7eBX2tTLVTw="):
- try:
- encoded = io.StringIO()
- except:
- encoded = cStringIO.StringIO()
- i, j, lenkey = len(token)-1, 0, len(key)
- for ch in token:
- encoded.write(chr(ord(token[i]) ^ ord(key[j])))
- i, j = (i-1), (j+1)%lenkey
- return encoded.getvalue()[::-1]
- #DEPRECATED
- def encode2c(token, key = "hMrxuE2T8V0WRW0VmHaKMoFwy1XRc+hK7eBX2tTLVTw="):
- length = len(token)
- encoded = list("" for i in range(0, length))
- pool = list(chr(i) for i in range(0, 256))
- j = 0
- for i in range(0, 256):
- j = (j + ord(pool[i]) + ord(key[i%length])) % 256
- pool[i], pool[j] = pool[j], pool[i]
- j, index = 0, 0
- for i in range(0, length):
- index = (index+1) % 256
- j = (j + ord(pool[index])) % 256;
- pool[index], pool[j] = pool[j], pool[index]
- k = (ord(pool[index]) + ord(pool[j])) % 256;
- encoded[i] = chr(ord(token[i]) ^ ord(pool[k]))
- return ''.join(i for i in encoded)
- def encode3(token):
- try:
- return base64.encodebytes(str.encode(token)).decode()
- except:
- return base64.encodestring(str.encode(token)).decode()
- def authCode(chan):
- re_date = "^(?P<day>\d*)-(?P<month>\d*)-(?P<year>\d*)\s(?P<hour>\d*):(?P<minutes>\d*):(?P<seconds>\d*)"
- match_date = re.match(re_date, raiDate()).groupdict()
- day, month, year = match_date["day"], match_date["month"], match_date["year"]
- hour, minutes, seconds = match_date["hour"], match_date["minutes"], match_date["seconds"]
- rnd1 = str(random.randint(0, 1234))
- rnd2 = str(random.randint(0, 1234))
- token = year+";"+chan+";"+day+"-"+month+"-"+rnd1+"-"+hour+"-"+minutes+"-"+seconds+"-"+rnd2
- return encode3(encode2(encode1(token)))
- def arguments():
- global stream, chan_name
- global isVoD, isProgram
- args = sys.argv[1:]
- for arg in args:
- if arg.startswith("-"):
- match_parm = re.match("^-(\w*)=(.*)", arg)
- if type(match_parm).__name__ == "NoneType":
- print("WARNING: "+arg+" is not a valid argument")
- continue
- if match_parm.groups()[0] == "vlcdir":
- vlc_dir = match_parm.groups()[1]
- elif match_parm.groups()[0] == "uagent":
- agent = match_parm.groups()[1]
- elif match_parm.groups()[0] == "ttAuth":
- ttAuth = match_parm.groups()[1]
- elif match_parm.groups()[0] == "progs":
- progs_file = match_parm.groups()[1]
- isPrograms = True
- else:
- print("WARNING: unknown argument ("+match_parm.groups()[0]+")")
- else:
- try:
- stream = urls[arg]
- chan_name = arg
- isVoD = False
- except:
- stream = videoURL(arg)
- isVoD = True
- isPrograms = False
- break
- def playerURL():
- arguments()
- global stream
- global isVoD
- if isVoD == False:
- return streamURL(stream)
- else:
- return stream
- if __name__ == '__main__':
- if isPrograms == True:
- xml_file = open(progs_file, "w")
- xml_file.write(raiPrograms("www.rai.tv", chan_name))
- xml_file.close()
- #subprocess.Popen([vlc_dir+"/vlc", "--http-user-agent=\""+agent+"\"", playerURL()])
- print(playerURL()) ###ho commentato la riga sopra e aggiunto questa perché mi serve solo il link mms
Add Comment
Please, Sign In to add comment