daily pastebin goal
28%
SHARE
TWEET

fightpass script

a guest Jan 25th, 2016 486 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python3
  2.  
  3. """
  4.   A simple little script for getting at the m3u8 for ufc.tv videos
  5.   For free and ethical stream viewing free from proprietary players
  6.  
  7.   Doesn't circumvent geo-blocks or login requirements
  8.   You can get around the ufc.tv geo blocks via DNS proxies
  9.  
  10.   I have this saved as ufctv in a bin dir on my $PATH, so I can call it from wherever
  11.  
  12.   To login, run: ufctv login
  13.   That will begin an interactive login prompt
  14.   The login details themselves aren't saved, just the cookies for the session
  15.   And the active session is reset any time you login with the "Keep Me Signed In" box anywhere else
  16.  
  17.   To get a video's m3u8: ufctv m3u8 $UFCTV-URL
  18.   So for example if I want to go back and watch Belfort vs Hendo 3
  19.   % ufctv m3u8 http://www.ufc.tv/video/belfort-vs-henderson-3
  20.   From there you an do what you wish with the m3u8!
  21.  
  22.   You may wish to pipe the result direct to mpv (which lets you seek around and switch between qualities)
  23.   % ufctv m3u8 http://www.ufc.tv/video/belfort-vs-henderson-3 | xargs mpv
  24.  
  25.   Or start ripping with livestreamer
  26.   % ufctv m3u8 http://www.ufc.tv/video/belfort-vs-henderson-3 | xargs -I M3U8 livestreamer hlsvariant://M3U8 best -o belf-vs-hend.ts
  27.   You can also rip the stream with ffmpeg, though I've found livestreamer does it a bit cleaner
  28.  
  29.   You may also wish to expand the program to add commands to do this for you instead of via shell piping
  30. """
  31.  
  32. import argparse
  33. import getpass
  34. import json
  35. import os
  36. import pickle
  37. import re
  38. import subprocess
  39. import sys
  40.  
  41. from requests import session
  42.  
  43. def main():
  44.     parser = argparse.ArgumentParser(description=
  45.         """
  46.         This is a command line tool to help enjoy quality UFC Fight Pass
  47.         content in an ethical manner that respects your freedoms
  48.         """)
  49.  
  50.     parser.add_argument('operation',
  51.         choices=['login', 'm3u8'])
  52.  
  53.     parser.add_argument('rest', nargs='*')
  54.  
  55.     args = parser.parse_args()
  56.  
  57.     op = args.operation
  58.     if op == 'login':
  59.         return ufctv_login()
  60.  
  61.     if len(args.rest) < 1:
  62.         print("Missing argument: video_url", file=sys.stderr)
  63.         return 1
  64.  
  65.     vid_url = args.rest[0]
  66.     uri = get_m3u8(vid_url)
  67.     if uri is None:
  68.         return 2
  69.  
  70.     if args.operation == 'm3u8':
  71.         print(uri)
  72.         return 0
  73.  
  74. def fake_mobile_session():
  75.     with session() as c:
  76.         load_cookies(c)
  77.         c.headers.update({'User-Agent': (
  78.             "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)"
  79.             " AppleWebKit/528.18 (KHTML, like Gecko)"
  80.             " Version/4.0 Mobile/7A341 Safari/528.16")})
  81.         return c
  82.  
  83. def get_m3u8_by_id(session, vid_id):
  84.     puburi = "http://www.ufc.tv/service/publishpoint?type=video&id={}&format=json"
  85.     r = session.get(puburi.format(vid_id))
  86.     stream_info = json.loads(r.text)
  87.     if 'path' not in stream_info:
  88.         return None
  89.     return stream_info['path'].replace("_iphone", "")
  90.  
  91. def get_m3u8(uri):
  92.     with fake_mobile_session() as c:
  93.         r = c.get(uri)
  94.  
  95.         vid_id = find_video_id(r.text)
  96.         if vid_id is None:
  97.             print("Failed to find video ID in page.", file=sys.stderr)
  98.             return None
  99.  
  100.         if not logged_in(r.text):
  101.             print("Goof Alert: You are not logged in to UFC.TV", file=sys.stderr)
  102.  
  103.         if not video_allowed(r.text):
  104.             print("Video is not available", file=sys.stderr)
  105.             return None
  106.  
  107.         res = get_m3u8_by_id(c, vid_id)
  108.         save_cookies(c)
  109.         return res
  110.  
  111. ufctv_sesssion_path = os.path.expanduser("~/.ufctv")
  112.  
  113. def save_cookies(session):
  114.     with open(ufctv_sesssion_path, 'wb') as f:
  115.         pickle.dump(session.cookies, f)
  116.  
  117. def load_cookies(session):
  118.     if not os.path.isfile(ufctv_sesssion_path):
  119.         print("No saved cookies file found -- starting from scratch", file=sys.stderr)
  120.         return
  121.  
  122.     with open(ufctv_sesssion_path, 'rb') as f:
  123.         session.cookies.update(pickle.load(f))
  124.  
  125. def video_allowed(page_html):
  126.     return '<div class="noAccess">' not in page_html
  127.  
  128. def logged_in(page_html):
  129.     return "Sign Out" in page_html
  130.  
  131. def ufctv_login():
  132.     with fake_mobile_session() as c:
  133.         login(c)
  134.         save_cookies(c)
  135.  
  136. def login(sesh):
  137.     username = input("Please enter your ufc.tv username: ")
  138.     password = getpass.getpass("Please enter your ufc.tv password: ")
  139.     longchoice = input("Tick the 'Keep Me Signed In' box for a long lasting session? [y/n] ")
  140.     longsesh = 'true' if longchoice is 'y' else 'false'
  141.  
  142.     login = {
  143.         'username': username,
  144.         'password': password,
  145.         'cookielink': longsesh
  146.     }
  147.  
  148.     r = sesh.post("https://www.ufc.tv/secure/authenticate", data=login)
  149.  
  150.     if 'loginsuccess' not in r.text:
  151.         print("Login failure -- full response:\n{}\n".format(r.text), file=sys.stderr)
  152.         return False
  153.  
  154.     return True
  155.  
  156. def find_video_id(page_html):
  157.     m = re.search("rel=\"image_src\" href=\".*?([0-9]+?)_.*?\.jpg\"", page_html)
  158.     if m is None:
  159.         return m
  160.     return m.group(1)
  161.  
  162. if __name__ == "__main__":
  163.     sys.exit(main())
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top