Beispiel #1
0
 def __init__(self, *args, **kwargs):
     # maybe the answer for nexdef for basic subscribers
     self.use_wired_web = kwargs.get('use_wired_web')
     ymd_tuple = kwargs.get('ymd_tuple')
     time_shift = kwargs.get('time_shift')
     self.international = kwargs.get('international')
     self.cfg = kwargs.get('cfg')
     # Default to today
     if not ymd_tuple:
         now = datetime.datetime.now()
         dif = datetime.timedelta(1)
         # Now, we want the day to go until, say, 9 am the next
         # morning. This needs to be worked out, still...
         if now.hour < 9:
             now = now - dif
         ymd_tuple = (now.year, now.month, now.day)
     self.year = ymd_tuple[0]
     self.month = ymd_tuple[1]
     self.day = ymd_tuple[2]
     self.shift = time_shift
     self.http = MLBHttp(accept_gzip=True)
     self.grid = "http://gdx.mlb.com/components/game/mlb/year_"\
         + padstr(self.year)\
         + "/month_" + padstr(self.month)\
         + "/day_" + padstr(self.day) + "/grid.xml"
     self.multiangle = "http://gdx.mlb.com/components/game/mlb/year_"\
         + padstr(self.year)\
         + "/month_" + padstr(self.month)\
         + "/day_" + padstr(self.day) + "/multi_angle_epg.xml"
     self.log = MLBLog(LOGFILE)
     self.data = []
     self.error_str = "Something went wrong.  A more descriptive error should be here."
Beispiel #2
0
 def __init__(self, user, passwd, debug=False):
     self.user = user
     if self.user is None:
         # if user= is commented out, cfg.get() returns None, normalize this
         self.user = ""
     self.passwd = passwd
     self.auth = True
     self.logged_in = None
     self.cookie_jar = None
     self.cookies = {}
     self.debug = debug
     if COOKIE_DEBUG:
         self.debug = True
     self.log = MLBLog(LOGFILE)
     try:
         self.session_key = self.readSessionKey()
         if self.debug:
             self.log.write("LOGIN> Read session key from file: " +
                            str(self.session_key))
     except:
         self.session_key = None
Beispiel #3
0
 def __init__(self, user, passwd, debug=False):
     self.user = user
     if self.user is None:
         # if user= is commented out, cfg.get() returns None, normalize this
         self.user = ""
     self.passwd = passwd
     self.auth = True
     self.logged_in = None
     self.cookie_jar = None
     self.cookies = {}
     self.debug = debug
     if COOKIE_DEBUG:
         self.debug = True
     self.log = MLBLog(LOGFILE)
     self.log.write('MLBSession BEGIN')
     try:
         self.session_key = self.readSessionKey()
         self.log.write('init() session-key : ' + self.session_key)
     except:
         #raise
         self.log.write('init() session-key : None')
         self.session_key = None
Beispiel #4
0
 def __init__(self,user,passwd,debug=False):
     self.user = user
     if self.user is None:
         # if user= is commented out, cfg.get() returns None, normalize this
         self.user = ""
     self.passwd = passwd
     self.auth = True
     self.logged_in = None
     self.cookie_jar = None
     self.cookies = {}
     self.debug = debug
     if COOKIE_DEBUG:
         self.debug = True
     self.log = MLBLog(LOGFILE)
     try:
         self.session_key = self.readSessionKey()
         if self.debug:
             self.log.write("LOGIN> Read session key from file: " + str(self.session_key))
     except:
         self.session_key = None
Beispiel #5
0
 def __init__(self,user,passwd,debug=False):
     self.user = user
     if self.user is None:
         # if user= is commented out, cfg.get() returns None, normalize this
         self.user = ""
     self.passwd = passwd
     self.auth = True
     self.logged_in = None
     self.cookie_jar = None
     self.cookies = {}
     self.debug = debug
     if COOKIE_DEBUG:
         self.debug = True
     self.log = MLBLog(LOGFILE)
     self.log.write('MLBSession BEGIN')
     try:
         self.session_key = self.readSessionKey()
         self.log.write('init() session-key : ' + self.session_key)
     except:
         #raise
         self.log.write('init() session-key : None')
         self.session_key = None
Beispiel #6
0
class MiLBMediaStream(MediaStream):

    def __init__(self, stream, session, cfg, coverage=None, 
                 streamtype='video', start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
	self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_librtmp   = self.cfg.get('use_librtmp')
        self.speed         = self.cfg.get('speed')

        # milbtv is one flavor: vanilla. Not even French vanilla.
        self.use_nexdef = False
        self.streamtype = 'video'
       
        # Install the cookie received from MLBLogin and used for subsequent 
        # media requests.  This part should resolve the issue of login 
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            ( self.call_letters,
              self.team_id,
              self.content_id,
              self.event_id ) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        self.scenario = 'FLASH_1000K_640X360'
        self.subject = 'LIVE_EVENT_COVERAGE'

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this 
        # url need to be changed to reflect that?
        self.base_url='http://www.milb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?' 


    def createMediaRequest(self,stream):
        if stream == None:
            self.error_str = "No event-id present to create media request."
            raise

        try:
            sessionKey = urllib.unquote(self.session.cookies['ftmu'])
        except:
            sessionKey = None
      
        # Query values
        query_values = {
            'contentId': self.content_id,
            'sessionKey': sessionKey,
            'fingerprint': urllib.unquote(self.session.cookies['fprt']),
            'identityPointId': self.session.cookies['ipid'],
            'playbackScenario': self.scenario,
            'subject': self.subject
        }
        # Build query
        url = self.base_url + urllib.urlencode(query_values)
        
        # And make the request
        req = urllib2.Request(url)
        response = urllib2.urlopen(req)
        reply = xml.dom.minidom.parse(response)
        return reply

    def locateMedia(self):
        game_url = None
        # 1. Make initial media request -- receive a reply with available media
        # 2. Update the session with current cookie values/session key.
        # 3. Get the content_list that matches the requested stream
        # 4. Strip out blacked out content or content that is not authorized.

        #reply = self.createMediaRequest(self.stream)
        #content_list = self.parseMediaReply(reply)
        game_url = self.requestSpecificMedia()
        #self.updateSession(reply)
        return game_url


    def updateSession(self,reply):
        try:
            self.session_key = reply.getElementsByTagName('session-key')[0].childNodes[0].data
            self.session_keys['ftmu'] = self.session_key
            self.session.writeSessionKey(self.session_key)
        except:
            pass


    def parseMediaReply(self,reply):
        
        # If status is not successful, make it easier to determine why
        status_code = str(reply.getElementsByTagName('status-code')[0].childNodes[0].data)
        if status_code != "1":
            self.log.write("UNSUCCESSFUL MEDIA REQUEST: status-code: %s , event-id = %s\n" % (status_code , self.event_id))
            self.log.write("See %s for XML response.\n"%ERRORLOG_1)
            err1 = open(ERRORLOG_1, 'w')
            reply.writexml(err1)
            err1.close()
            self.error_str = SOAPCODES[status_code]
            raise Exception,self.error_str
        else:
            self.log.write("SUCCESSFUL MEDIA REQUEST: status-code: %s , event-id = %s\n" % (status_code , self.event_id))
            self.log.write("See %s for XML response.\n"%MEDIALOG_1)
            med1 = open(MEDIALOG_1,'w')
            reply.writexml(med1)
            med1.close()

        # determine blackout status
        #self.determineBlackoutStatus(reply)

        # and now the meat of the parsing...
        content_list = []

        for content in reply.getElementsByTagName('user-verified-content'):
            type = content.getElementsByTagName('type')[0].childNodes[0].data
            if type != self.streamtype:
               continue
            content_id = content.getElementsByTagName('content-id')[0].childNodes[0].data
            if content_id != self.content_id:
                continue

            # First, collect all the domain-attributes
            dict = {}

            for node in content.getElementsByTagName('domain-attribute'):
                name = str(node.getAttribute('name'))
                value = node.childNodes[0].data
                dict[name] = value
            # There are a series of checks to trim the content list
            # 1. Trim out 'in-market' listings like Yankees On Yes
            if dict.has_key('coverage_type'):
                if 'in-market' in dict['coverage_type']:
                    continue
            # 2. Trim out all non-English language broadcasts
            if dict.has_key('language'):
                if dict['language'] != 'EN':
                    continue
            # 3. For post-season, trim out multi-angle listings
            if self.cfg.get('postseason'):
                if dict['in_epg'] != 'mlb_multiangle_epg':
                    continue
            else:
                if dict['in_epg'] == 'mlb_multiangle_epg':
                    continue
            # 4. Get coverage association and call_letters
            try:
                cov_pat = re.compile(r'([0-9][0-9]*)')
                coverage = re.search(cov_pat, dict['coverage_association']).groups()[0]
            except:
                 coverage = None
            try:
                call_letters = dict['call_letters']
            except:
                if self.cfg.get('postseason') == False:
                    raise Exception,repr(dict)
                else:
                    call_letters = 'MiLB'
            for media in content.getElementsByTagName('user-verified-media-item'):
                state = media.getElementsByTagName('state')[0].childNodes[0].data
                scenario = media.getElementsByTagName('playback-scenario')[0].childNodes[0].data
                if scenario == self.scenario and \
                    state in ('MEDIA_ARCHIVE', 'MEDIA_ON', 'MEDIA_OFF'):
                    content_list.append( ( call_letters, coverage, content_id, self.event_id ) )
        return content_list
 

    def determineBlackoutStatus(self,reply):
        # Determine the blackout status
        try:
            blackout_status = reply.getElementsByTagName('blackout')[0].childNodes[0].data
        except:
            blackout_status = reply.getElementsByTagName('blackout-status')[0]
            try:
                success_status = blackout_status.getElementsByTagName('successStatus')
                blackout_status = None
            except:
                try:
                    location_status = blackout_status.getElementsByTagName('locationCannotBeDeterminedStatus')
                except:
                    blackout_status = 'LOCATION CANNOT BE DETERMINED.'

        media_type = reply.getElementsByTagName('type')[0].childNodes[0].data
        media_state = reply.getElementsByTagName('state')[0].childNodes[0].data
        self.media_state = media_state
      
        if blackout_status is not None and self.streamtype == 'video':
            inmarket_pat = re.compile(r'INMARKET')
            if re.search(inmarket_pat,blackout_status) is not None:
                pass
            elif media_state == 'MEDIA_ON' and not self.postseason:
                self.log.write('MEDIA STREAM BLACKOUT.  See %s for XML response.' % BLACKFILE)
                self.error_str = 'BLACKOUT: ' + str(blackout_status)
                bf = open(BLACKFILE, 'w')
                reply.writexml(bf)
                bf.close()
                raise Exception,self.error_str

    def selectCoverage(self,content_list):
        # now iterate over the content_list with the following rules:
        # 1. if coverage association is zero, use it (likely a national broadcast)
        # 2. if preferred coverage is available use it
        # 3. if coverage association is non-zero and preferred not available, then what?
        for content in content_list:
            ( call_letters, coverage, content_id , event_id ) = content
            if coverage == '0':
                self.content_id = content_id
                self.call_letters = call_letters
            elif coverage == self.coverage:
                self.content_id = content_id
                self.call_letters = call_letters
        # if we preferred coverage and national coverage not available,
        # select any coverage available
        if self.content_id is None:
            try:
                ( call_letters, coverage, content_id, event_id ) = content_list[0]
                self.content_id = content_id
                self.call_letters = call_letters
            except:
                self.content_id = None
                self.call_letters = None
        if self.content_id is None:
            self.error_str = "Requested stream is not available."
            self.error_str += "\n\nRequested coverage association: " + str(self.coverage)
            self.error_str += "\n\nAvailable content list = \n" + repr(content_list)
            raise Exception,self.error_str
        if self.debug:
            self.log.write("DEBUG>> writing soap response\n")
            self.log.write(repr(reply) + '\n')
        if self.content_id is None:
            self.error_str = "Requested stream is not yet available."
            raise Exception,self.error_str
        if self.debug:
            self.log.write("DEBUG>> soap event-id:" + str(self.stream) + '\n')
            self.log.write("DEBUG>> soap content-id:" + str(self.content_id) + '\n')

    def requestSpecificMedia(self):
        query_values = {
            'subject': self.subject,
            'identityPointId': self.session.cookies['ipid'],
            'contentId': self.content_id,
            'playbackScenario': self.scenario,
            'fingerprint': urllib.unquote(self.session.cookies['fprt'])
        }
        try:
            sessionkey = urllib.unquote(self.session.cookies['ftmu'])
            query_values['sessionKey'] = sessionkey
        except:
            sessionkey = None
        url = self.base_url + urllib.urlencode(query_values)
        req = urllib2.Request(url)
        response = urllib2.urlopen(req)
        reply = parse(response)

        status_code = str(reply.getElementsByTagName('status-code')[0].childNodes[0].data)
        if status_code != "1":
            # candidate for new procedure: this code block of writing
            # unsuccessful xml responses is being repeated...
            self.log.write("DEBUG (SOAPCODES!=1)>> writing unsuccessful soap response event_id = " + str(self.event_id) + " contend-id = " + self.content_id + "\n")
            df = open('/tmp/unsuccessful.xml','w')
            reply.writexml(df)
            df.close()
            df = open('/tmp/unsuccessful.xml')
            msg = df.read()
            df.close()
            self.error_str = SOAPCODES[status_code]
            raise Exception,self.error_str
        try:
            self.session_key = reply.getElementsByTagName('session-key')[0].childNodes[0].data
            self.session.cookies['ftmu'] = self.session_key
            self.session.writeSessionKey(self.session_key)
        except:
            #raise
            self.session_key = None
        try:
            game_url = reply.getElementsByTagName('url')[0].childNodes[0].data
        except:
            self.error_str = "Stream URL not found in reply.  Stream may not be available yet."
            df = open(ERRORLOG_2,'w')
            reply.writexml(df)
            df.close()
            raise Exception,self.error_str
        else:
            df = open(MEDIALOG_2,'w')
            reply.writexml(df)
            df.close()
        self.log.write("DEBUG>> URL received: " + game_url + '\n')
        return game_url


    def parseFmsCloudResponse(self,url):
        auth_pat = re.compile(r'auth=(.*)')
        self.auth_chunk = '?auth=' + re.search(auth_pat,url).groups()[0]
        out = ''
        req = urllib2.Request(url)
        handle = urllib2.urlopen(req)
        rsp = parse(handle)
        rtmp_base = rsp.getElementsByTagName('meta')[0].getAttribute('base')
        for elem in rsp.getElementsByTagName('video'):
            speed = int(elem.getAttribute('system-bitrate'))/1000
            if int(self.speed) == int(speed):
               vid_src = elem.getAttribute('src').replace('mp4:','/')
               out = rtmp_base + vid_src
        return out


    def prepareMediaStreamer(self,game_url):
        #if self.streamtype in ( 'video', ):
        #    game_url = self.parseFmsCloudResponse(game_url)
        return self.prepareFmsUrl(game_url)


    # finally some url processing routines
    def prepareFmsUrl(self,game_url):
        try:
            #play_path_pat = re.compile(r'ondemand\/(.*)\?')
            play_path_pat = re.compile(r'ondemand\/(.*)$')
            self.play_path = re.search(play_path_pat,game_url).groups()[0]
            app_pat = re.compile(r'ondemand\/(.*)\?(.*)$')
            querystring = re.search(app_pat,game_url).groups()[1]
            self.app = "ondemand?_fcs_vhost=cp118053.edgefcs.net&akmfv=1.6" + querystring
            # not sure if we need this
            try:
                req = urllib2.Request('http://cp118053.edgefcs.net/fcs/ident')
                page = urllib2.urlopen(req)
                fp = parse(page)
                ip = fp.getElementsByTagName('ip')[0].childNodes[0].data
                self.tc_url = 'http://' + str(ip) + ':1935/' + self.app
            except:
                self.tc_url = None
        except:
            self.play_path = None
        try:
            live_pat = re.compile(r'live\/milb')
            if re.search(live_pat,game_url):
                if self.streamtype == 'audio':
                    auth_pat = re.compile(r'auth=(.*)')
                    self.auth_chunk = '?auth=' + re.search(auth_pat,game_url).groups()[0]
                    live_sub_pat = re.compile(r'live\/mlb_audio(.*)\?')
                    self.sub_path = re.search(live_sub_pat,game_url).groups()[0]
                    self.sub_path = 'mlb_audio' + self.sub_path
                    live_play_pat = re.compile(r'live\/mlb_audio(.*)$')
                    self.play_path = re.search(live_play_pat,game_url).groups()[0]
                    self.play_path = 'mlb_audio' + self.play_path
                    app_auth = self.auth_chunk.replace('?','&')
                    self.app = "live?_fcs_vhost=cp153281.live.edgefcs.net&akmfv=1.6&aifp=v0006" + app_auth
                else:
                    try:
                        live_sub_pat = re.compile(r'live\/milb_encap_rm(.*)')
                        self.sub_path = re.search(live_sub_pat,game_url).groups()[0]
                        self.sub_path = 'milb_encap_rm' + self.sub_path
                    except Exception,detail:
                        self.error_str = 'Could not parse the stream subscribe path: ' + str(detail)
                        raise Exception,self.error_str
                    try:
                        live_path_pat = re.compile(r'live\/milb_encap_rm(.*)$')
                        self.play_path = re.search(live_path_pat,game_url).groups()[0]
                        self.play_path = 'milb_encap_rm' + self.play_path
                    except Exception,detail:
                        self.error_str = 'Could not parse the stream play path: ' + str(detail)
                        raise Exception,self.error_str
                    sec_pat = re.compile(r'mlbsecurelive')
                    if re.search(sec_pat,game_url) is not None:
                        self.app = 'mlbsecurelive-live'
                    else:
                        self.app = 'live?_fcs_vhost=cp118053.live.edgefcs.net&akmfv=1.6'
            if self.debug:
                self.log.write("DEBUG>> sub_path = " + str(self.sub_path) + "\n")
                self.log.write("DEBUG>> play_path = " + str(self.play_path) + "\n")
                self.log.write("DEBUG>> app = " + str(self.app) + "\n")
Beispiel #7
0
class MLBSession:

    def __init__(self,user,passwd,debug=False):
        self.user = user
        if self.user is None:
            # if user= is commented out, cfg.get() returns None, normalize this
            self.user = ""
        self.passwd = passwd
        self.auth = True
        self.logged_in = None
        self.cookie_jar = None
        self.cookies = {}
        self.debug = debug
        if COOKIE_DEBUG:
            self.debug = True
        self.log = MLBLog(LOGFILE)
        self.log.write('MLBSession BEGIN')
        try:
            self.session_key = self.readSessionKey()
            self.log.write('init() session-key : ' + self.session_key)
        except:
            #raise
            self.log.write('init() session-key : None')
            self.session_key = None

    def readSessionKey(self):
        sk = open(SESSIONKEY,"r")
        self.session_key = sk.read()
        sk.close()
        return self.session_key

    def writeSessionKey(self,session_key):
        self.session_key = session_key
        self.log.write('writeSessionKey(): ' + str(self.session_key))
        sk = open(SESSIONKEY,"w")
        sk.write(self.session_key)
        sk.close()
        return self.session_key

    def extractCookies(self):
        for c in self.cookie_jar:
            self.cookies[c.name] = c.value
        self.printCookies()

    def printCookies(self):
        self.log.write('printCookies() : ')
        for name in self.cookies.keys():
            if name in ('fprt', 'ftmu', 'ipid'):
                self.log.write(str(name) + ' = ' + str(self.cookies[name]))

    def readCookieFile(self):
        self.cookie_jar = cookielib.LWPCookieJar()
        if self.cookie_jar != None:
            if os.path.isfile(COOKIEFILE):
                self.cookie_jar.load(COOKIEFILE,ignore_discard=IGNORE_DISCARD)
                if self.debug:
                    self.log.write('readCookieFile:\n')
                self.extractCookies()
            else:
                raise MLBNoCookieFileError
        else:
            self.error_str = "Couldn't open cookie jar"
            raise Exception,self.error_str

    def login(self):
        try:
            self.readCookieFile()
        except MLBNoCookieFileError:
            #pass
            if self.debug:
                self.log.write("LOGIN> No cookie file")
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie_jar))
        urllib2.install_opener(opener)

        # First visit the login page and get the session cookie
        callback = str(int(time.time() * 1000))
        login_url = 'http://mlb.mlb.com/account/quick_login_hdr.jsp?'\
            'successRedirect=http://mlb.mlb.com/shared/account/v2/login_success.jsp'\
            '%3Fcallback%3Dl' + callback + '&callback=l' + callback + \
            '&stylesheet=/style/account_management/myAccountMini.css&submitImage='\
            '/shared/components/gameday/v4/images/btn-login.gif&'\
            'errorRedirect=http://mlb.mlb.com/account/quick_login_hdr.jsp%3Ferror'\
            '%3Dtrue%26successRedirect%3Dhttp%253A%252F%252Fmlb.mlb.com%252Fshared'\
            '%252Faccount%252Fv2%252Flogin_success.jsp%25253Fcallback%25253Dl' +\
            callback + '%26callback%3Dl' + callback + '%26stylesheet%3D%252Fstyle'\
            '%252Faccount_management%252FmyAccountMini.css%26submitImage%3D%252F'\
            'shared%252Fcomponents%252Fgameday%252Fv4%252Fimages%252Fbtn-login.gif'\
            '%26errorRedirect%3Dhttp%3A//mlb.mlb.com/account/quick_login_hdr.jsp'\
            '%253Ferror%253Dtrue%2526successRedirect%253Dhttp%25253A%25252F%25252F'\
            'mlb.mlb.com%25252Fshared%25252Faccount%25252Fv2%25252Flogin_success.jsp'\
            '%2525253Fcallback%2525253Dl' + callback + '%2526callback%253Dl' +\
            callback + '%2526stylesheet%253D%25252Fstyle%25252Faccount_management'\
            '%25252FmyAccountMini.css%2526submitImage%253D%25252Fshared%25252F'\
            'components%25252Fgameday%25252Fv4%25252Fimages%25252Fbtn-login.gif'
        txheaders = {'User-agent' : USERAGENT}
        data = None
        req = urllib2.Request(login_url,data,txheaders)
        # we might have cookie info by now??
        if self.user=="":
            return

        try:
            handle = urllib2.urlopen(req)
        except:
            self.error_str = 'Error occurred in HTTP request to login page'
            raise Exception, self.error_str
        try:
            if self.debug:
                self.log.write('pre-login:'******'Did we receive a cookie from the wizard?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE,ignore_discard=IGNORE_DISCARD)

        rdata = handle.read()

        # now authenticate
        auth_values = {'emailAddress' : self.user,
                       'password' : self.passwd,
                       'submit.x' : 25,
                       'submit.y' : 7}
        g = re.search('name="successRedirect" value="(?P<successRedirect>[^"]+)"', rdata)
        auth_values['successRedirect'] = g.group('successRedirect')
        g = re.search('name="errorRedirect" value="(?P<errorRedirect>[^"]+)"', rdata)
        auth_values['errorRedirect'] = g.group('errorRedirect')
        auth_data = urllib.urlencode(auth_values)
        auth_url = 'https://secure.mlb.com/account/topNavLogin.jsp'
        req = urllib2.Request(auth_url,auth_data,txheaders)
        try:
            handle = urllib2.urlopen(req)
            self.cookie_jar.save(COOKIEFILE,ignore_discard=IGNORE_DISCARD)
            if self.debug:
                self.log.write('post-login: (this gets saved to file)')
            self.extractCookies()
        except:
            self.error_str = 'Error occurred in HTTP request to auth page'
            raise Exception, self.error_str
        auth_page = handle.read()
        #if self.debug:
        #    self.log.write('Did we receive a cookie from authenticate?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE,ignore_discard=IGNORE_DISCARD)
        try:
           loggedin = re.search('Login Success', auth_page).groups()
           self.log.write('Logged in successfully!\n')
           self.logged_in = True
        except:
           self.error_str = 'Login was unsuccessful.'
           self.log.write(auth_page)
           os.remove(COOKIEFILE)
           raise MLBAuthError, self.error_str
Beispiel #8
0
    def __init__(self, stream, session, cfg, coverage=None, 
                 streamtype='video', start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
	self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_nexdef    = self.cfg.get('use_nexdef')
        self.postseason    = self.cfg.get('postseason')
        self.use_librtmp   = self.cfg.get('use_librtmp')
        # EXPERIMENTAL: make this a default now
        #self.use_wired_web = self.cfg.get('use_wired_web')
        self.use_wired_web = 1
        self.max_bps       = int(self.cfg.get('max_bps'))
        self.min_bps       = int(self.cfg.get('min_bps'))
        # allow max_bps and min_bps to be specified in kbps
        if self.min_bps < 128000:
            self.min_bps *= 1000
        if self.max_bps < 128000:
            self.max_bps *= 1000
        self.speed         = self.cfg.get('speed')
        self.adaptive      = self.cfg.get('adaptive_stream')

       
        # Install the cookie received from MLBLogin and used for subsequent 
        # media requests.  This part should resolve the issue of login 
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            ( self.call_letters,
              self.team_id,
              self.content_id,
              self.event_id ) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        try:
            self.session_key = self.session.session_key
        except:
            self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        if self.streamtype in ( 'audio', 'alt_audio' ):
            self.scenario = "AUDIO_FMS_32K"
            self.subject  = "MLBCOM_GAMEDAY_AUDIO"
        else:
            if self.use_nexdef:
                if self.use_wired_web:
                    self.scenario = 'HTTP_CLOUD_WIRED_WEB'
                else:
                    self.scenario = 'HTTP_CLOUD_WIRED'
            else:
                self.scenario = 'FMS_CLOUD'
            #self.subject  = "LIVE_EVENT_COVERAGE"
            self.subject = "MLBTV"

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this 
        # url need to be changed to reflect that?
        self.base_url='https://secure.mlb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?' 
Beispiel #9
0
class MediaStream:
    def __init__(self,
                 stream,
                 session,
                 cfg,
                 coverage=None,
                 streamtype='video',
                 start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
        self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_nexdef = self.cfg.get('use_nexdef')
        self.postseason = self.cfg.get('postseason')
        self.use_librtmp = self.cfg.get('use_librtmp')
        self.use_wired_web = self.cfg.get('use_wired_web')
        self.max_bps = int(self.cfg.get('max_bps'))
        self.min_bps = int(self.cfg.get('min_bps'))
        # allow max_bps and min_bps to be specified in kbps
        if self.min_bps < 128000:
            self.min_bps *= 1000
        if self.max_bps < 128000:
            self.max_bps *= 1000
        self.speed = self.cfg.get('speed')
        self.adaptive = self.cfg.get('adaptive_stream')

        # Install the cookie received from MLBLogin and used for subsequent
        # media requests.  This part should resolve the issue of login
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(
                urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            (self.call_letters, self.team_id, self.content_id,
             self.event_id) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        try:
            self.session_key = self.session.session_key
        except:
            self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        if self.streamtype in ('audio', 'alt_audio'):
            self.scenario = "AUDIO_FMS_32K"
            self.subject = "MLBCOM_GAMEDAY_AUDIO"
        else:
            if self.use_nexdef:
                if self.use_wired_web:
                    self.scenario = 'HTTP_CLOUD_WIRED_WEB'
                else:
                    self.scenario = 'HTTP_CLOUD_WIRED'
            else:
                self.scenario = 'FMS_CLOUD'
            #self.subject  = "LIVE_EVENT_COVERAGE"
            self.subject = "MLBTV"

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this
        # url need to be changed to reflect that?
        self.base_url = 'https://secure.mlb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?'

    def createMediaRequest(self, stream):
        if stream == None:
            self.error_str = "No event-id present to create media request."
            raise

        try:
            #sessionKey = urllib.unquote(self.session.cookies['ftmu'])
            sessionKey = self.session.session_key
        except:
            sessionKey = None

        # Query values
        query_values = {
            'eventId': self.event_id,
            'sessionKey': sessionKey,
            'fingerprint': urllib.unquote(self.session.cookies['fprt']),
            'identityPointId': self.session.cookies['ipid'],
            'playbackScenario': self.scenario,
            'subject': self.subject
        }
        # Build query
        url = self.base_url + urllib.urlencode(query_values)

        # And make the request
        req = urllib2.Request(url)
        try:
            response = urllib2.urlopen(req)
        except urllib2.HTTPError, err:
            self.log.write("Error (%s) for URL: %s" % (err.code, url))
            raise
        reply = xml.dom.minidom.parse(response)
        return reply
Beispiel #10
0
class MLBSession:
    def __init__(self, user, passwd, debug=False):
        self.user = user
        if self.user is None:
            # if user= is commented out, cfg.get() returns None, normalize this
            self.user = ""
        self.passwd = passwd
        self.auth = True
        self.logged_in = None
        self.cookie_jar = None
        self.cookies = {}
        self.debug = debug
        if COOKIE_DEBUG:
            self.debug = True
        self.log = MLBLog(LOGFILE)
        self.log.write('MLBSession BEGIN')
        try:
            self.session_key = self.readSessionKey()
            self.log.write('init() session-key : ' + self.session_key)
        except:
            #raise
            self.log.write('init() session-key : None')
            self.session_key = None

    def readSessionKey(self):
        sk = open(SESSIONKEY, "r")
        self.session_key = sk.read()
        sk.close()
        return self.session_key

    def writeSessionKey(self, session_key):
        self.session_key = session_key
        self.log.write('writeSessionKey(): ' + str(self.session_key))
        sk = open(SESSIONKEY, "w")
        sk.write(self.session_key)
        sk.close()
        return self.session_key

    def extractCookies(self):
        for c in self.cookie_jar:
            self.cookies[c.name] = c.value
        self.printCookies()

    def printCookies(self):
        self.log.write('printCookies() : ')
        for name in self.cookies.keys():
            if name in ('fprt', 'ftmu', 'ipid'):
                self.log.write(str(name) + ' = ' + str(self.cookies[name]))

    def readCookieFile(self):
        self.cookie_jar = cookielib.LWPCookieJar()
        if self.cookie_jar != None:
            if os.path.isfile(COOKIEFILE):
                self.cookie_jar.load(COOKIEFILE, ignore_discard=IGNORE_DISCARD)
                if self.debug:
                    self.log.write('readCookieFile:\n')
                self.extractCookies()
            else:
                raise MLBNoCookieFileError
        else:
            self.error_str = "Couldn't open cookie jar"
            raise Exception, self.error_str

    def login(self):
        try:
            self.readCookieFile()
        except MLBNoCookieFileError:
            #pass
            if self.debug:
                self.log.write("LOGIN> No cookie file")
        opener = urllib2.build_opener(
            urllib2.HTTPCookieProcessor(self.cookie_jar))
        urllib2.install_opener(opener)

        # First visit the login page and get the session cookie
        callback = str(int(time.time() * 1000))
        login_url = 'http://mlb.mlb.com/account/quick_login_hdr.jsp?'\
            'successRedirect=http://mlb.mlb.com/shared/account/v2/login_success.jsp'\
            '%3Fcallback%3Dl' + callback + '&callback=l' + callback + \
            '&stylesheet=/style/account_management/myAccountMini.css&submitImage='\
            '/shared/components/gameday/v4/images/btn-login.gif&'\
            'errorRedirect=http://mlb.mlb.com/account/quick_login_hdr.jsp%3Ferror'\
            '%3Dtrue%26successRedirect%3Dhttp%253A%252F%252Fmlb.mlb.com%252Fshared'\
            '%252Faccount%252Fv2%252Flogin_success.jsp%25253Fcallback%25253Dl' +\
            callback + '%26callback%3Dl' + callback + '%26stylesheet%3D%252Fstyle'\
            '%252Faccount_management%252FmyAccountMini.css%26submitImage%3D%252F'\
            'shared%252Fcomponents%252Fgameday%252Fv4%252Fimages%252Fbtn-login.gif'\
            '%26errorRedirect%3Dhttp%3A//mlb.mlb.com/account/quick_login_hdr.jsp'\
            '%253Ferror%253Dtrue%2526successRedirect%253Dhttp%25253A%25252F%25252F'\
            'mlb.mlb.com%25252Fshared%25252Faccount%25252Fv2%25252Flogin_success.jsp'\
            '%2525253Fcallback%2525253Dl' + callback + '%2526callback%253Dl' +\
            callback + '%2526stylesheet%253D%25252Fstyle%25252Faccount_management'\
            '%25252FmyAccountMini.css%2526submitImage%253D%25252Fshared%25252F'\
            'components%25252Fgameday%25252Fv4%25252Fimages%25252Fbtn-login.gif'
        txheaders = {'User-agent': USERAGENT}
        data = None
        req = urllib2.Request(login_url, data, txheaders)
        # we might have cookie info by now??
        if self.user == "":
            return

        try:
            handle = urllib2.urlopen(req)
        except:
            self.error_str = 'Error occurred in HTTP request to login page'
            raise Exception, self.error_str
        try:
            if self.debug:
                self.log.write('pre-login:'******'Did we receive a cookie from the wizard?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE, ignore_discard=IGNORE_DISCARD)

        rdata = handle.read()

        # now authenticate
        auth_values = {
            'emailAddress': self.user,
            'password': self.passwd,
            'submit.x': 25,
            'submit.y': 7
        }
        g = re.search(
            'name="successRedirect" value="(?P<successRedirect>[^"]+)"', rdata)
        auth_values['successRedirect'] = g.group('successRedirect')
        g = re.search('name="errorRedirect" value="(?P<errorRedirect>[^"]+)"',
                      rdata)
        auth_values['errorRedirect'] = g.group('errorRedirect')
        auth_data = urllib.urlencode(auth_values)
        auth_url = 'https://secure.mlb.com/account/topNavLogin.jsp'
        req = urllib2.Request(auth_url, auth_data, txheaders)
        try:
            handle = urllib2.urlopen(req)
            self.cookie_jar.save(COOKIEFILE, ignore_discard=IGNORE_DISCARD)
            if self.debug:
                self.log.write('post-login: (this gets saved to file)')
            self.extractCookies()
        except:
            self.error_str = 'Error occurred in HTTP request to auth page'
            raise Exception, self.error_str
        auth_page = handle.read()
        #if self.debug:
        #    self.log.write('Did we receive a cookie from authenticate?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE, ignore_discard=IGNORE_DISCARD)
        try:
            loggedin = re.search('Login Success', auth_page).groups()
            self.log.write('Logged in successfully!\n')
            self.logged_in = True
        except:
            self.error_str = 'Login was unsuccessful.'
            self.log.write(auth_page)
            os.remove(COOKIEFILE)
            raise MLBAuthError, self.error_str
Beispiel #11
0
    def __init__(self,
                 stream,
                 session,
                 cfg,
                 coverage=None,
                 streamtype='video',
                 start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
        self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_librtmp = self.cfg.get('use_librtmp')
        self.speed = self.cfg.get('speed')

        # milbtv is one flavor: vanilla. Not even French vanilla.
        self.use_nexdef = False
        self.streamtype = 'video'

        # Install the cookie received from MLBLogin and used for subsequent
        # media requests.  This part should resolve the issue of login
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(
                urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            (self.call_letters, self.team_id, self.content_id,
             self.event_id) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        self.scenario = 'FLASH_1000K_640X360'
        self.subject = 'LIVE_EVENT_COVERAGE'

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this
        # url need to be changed to reflect that?
        self.base_url = 'http://www.milb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?'
Beispiel #12
0
class MiLBMediaStream(MediaStream):
    def __init__(self,
                 stream,
                 session,
                 cfg,
                 coverage=None,
                 streamtype='video',
                 start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
        self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_librtmp = self.cfg.get('use_librtmp')
        self.speed = self.cfg.get('speed')

        # milbtv is one flavor: vanilla. Not even French vanilla.
        self.use_nexdef = False
        self.streamtype = 'video'

        # Install the cookie received from MLBLogin and used for subsequent
        # media requests.  This part should resolve the issue of login
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(
                urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            (self.call_letters, self.team_id, self.content_id,
             self.event_id) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        self.scenario = 'FLASH_1000K_640X360'
        self.subject = 'LIVE_EVENT_COVERAGE'

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this
        # url need to be changed to reflect that?
        self.base_url = 'http://www.milb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?'

    def createMediaRequest(self, stream):
        if stream == None:
            self.error_str = "No event-id present to create media request."
            raise

        try:
            sessionKey = urllib.unquote(self.session.cookies['ftmu'])
        except:
            sessionKey = None

        # Query values
        query_values = {
            'contentId': self.content_id,
            'sessionKey': sessionKey,
            'fingerprint': urllib.unquote(self.session.cookies['fprt']),
            'identityPointId': self.session.cookies['ipid'],
            'playbackScenario': self.scenario,
            'subject': self.subject
        }
        # Build query
        url = self.base_url + urllib.urlencode(query_values)

        # And make the request
        req = urllib2.Request(url)
        response = urllib2.urlopen(req)
        reply = xml.dom.minidom.parse(response)
        return reply

    def locateMedia(self):
        game_url = None
        # 1. Make initial media request -- receive a reply with available media
        # 2. Update the session with current cookie values/session key.
        # 3. Get the content_list that matches the requested stream
        # 4. Strip out blacked out content or content that is not authorized.

        #reply = self.createMediaRequest(self.stream)
        #content_list = self.parseMediaReply(reply)
        game_url = self.requestSpecificMedia()
        #self.updateSession(reply)
        return game_url

    def updateSession(self, reply):
        try:
            self.session_key = reply.getElementsByTagName(
                'session-key')[0].childNodes[0].data
            self.session_keys['ftmu'] = self.session_key
            self.session.writeSessionKey(self.session_key)
        except:
            pass

    def parseMediaReply(self, reply):

        # If status is not successful, make it easier to determine why
        status_code = str(
            reply.getElementsByTagName('status-code')[0].childNodes[0].data)
        if status_code != "1":
            self.log.write(
                "UNSUCCESSFUL MEDIA REQUEST: status-code: %s , event-id = %s\n"
                % (status_code, self.event_id))
            self.log.write("See %s for XML response.\n" % ERRORLOG_1)
            err1 = open(ERRORLOG_1, 'w')
            reply.writexml(err1)
            err1.close()
            self.error_str = SOAPCODES[status_code]
            raise Exception, self.error_str
        else:
            self.log.write(
                "SUCCESSFUL MEDIA REQUEST: status-code: %s , event-id = %s\n" %
                (status_code, self.event_id))
            self.log.write("See %s for XML response.\n" % MEDIALOG_1)
            med1 = open(MEDIALOG_1, 'w')
            reply.writexml(med1)
            med1.close()

        # determine blackout status
        #self.determineBlackoutStatus(reply)

        # and now the meat of the parsing...
        content_list = []

        for content in reply.getElementsByTagName('user-verified-content'):
            type = content.getElementsByTagName('type')[0].childNodes[0].data
            if type != self.streamtype:
                continue
            content_id = content.getElementsByTagName(
                'content-id')[0].childNodes[0].data
            if content_id != self.content_id:
                continue

            # First, collect all the domain-attributes
            dict = {}

            for node in content.getElementsByTagName('domain-attribute'):
                name = str(node.getAttribute('name'))
                value = node.childNodes[0].data
                dict[name] = value
            # There are a series of checks to trim the content list
            # 1. Trim out 'in-market' listings like Yankees On Yes
            if dict.has_key('coverage_type'):
                if 'in-market' in dict['coverage_type']:
                    continue
            # 2. Trim out all non-English language broadcasts
            if dict.has_key('language'):
                if dict['language'] != 'EN':
                    continue
            # 3. For post-season, trim out multi-angle listings
            if self.cfg.get('postseason'):
                if dict['in_epg'] != 'mlb_multiangle_epg':
                    continue
            else:
                if dict['in_epg'] == 'mlb_multiangle_epg':
                    continue
            # 4. Get coverage association and call_letters
            try:
                cov_pat = re.compile(r'([0-9][0-9]*)')
                coverage = re.search(cov_pat,
                                     dict['coverage_association']).groups()[0]
            except:
                coverage = None
            try:
                call_letters = dict['call_letters']
            except:
                if self.cfg.get('postseason') == False:
                    raise Exception, repr(dict)
                else:
                    call_letters = 'MiLB'
            for media in content.getElementsByTagName(
                    'user-verified-media-item'):
                state = media.getElementsByTagName(
                    'state')[0].childNodes[0].data
                scenario = media.getElementsByTagName(
                    'playback-scenario')[0].childNodes[0].data
                if scenario == self.scenario and \
                    state in ('MEDIA_ARCHIVE', 'MEDIA_ON', 'MEDIA_OFF'):
                    content_list.append(
                        (call_letters, coverage, content_id, self.event_id))
        return content_list

    def determineBlackoutStatus(self, reply):
        # Determine the blackout status
        try:
            blackout_status = reply.getElementsByTagName(
                'blackout')[0].childNodes[0].data
        except:
            blackout_status = reply.getElementsByTagName('blackout-status')[0]
            try:
                success_status = blackout_status.getElementsByTagName(
                    'successStatus')
                blackout_status = None
            except:
                try:
                    location_status = blackout_status.getElementsByTagName(
                        'locationCannotBeDeterminedStatus')
                except:
                    blackout_status = 'LOCATION CANNOT BE DETERMINED.'

        media_type = reply.getElementsByTagName('type')[0].childNodes[0].data
        media_state = reply.getElementsByTagName('state')[0].childNodes[0].data
        self.media_state = media_state

        if blackout_status is not None and self.streamtype == 'video':
            inmarket_pat = re.compile(r'INMARKET')
            if re.search(inmarket_pat, blackout_status) is not None:
                pass
            elif media_state == 'MEDIA_ON' and not self.postseason:
                self.log.write(
                    'MEDIA STREAM BLACKOUT.  See %s for XML response.' %
                    BLACKFILE)
                self.error_str = 'BLACKOUT: ' + str(blackout_status)
                bf = open(BLACKFILE, 'w')
                reply.writexml(bf)
                bf.close()
                raise Exception, self.error_str

    def selectCoverage(self, content_list):
        # now iterate over the content_list with the following rules:
        # 1. if coverage association is zero, use it (likely a national broadcast)
        # 2. if preferred coverage is available use it
        # 3. if coverage association is non-zero and preferred not available, then what?
        for content in content_list:
            (call_letters, coverage, content_id, event_id) = content
            if coverage == '0':
                self.content_id = content_id
                self.call_letters = call_letters
            elif coverage == self.coverage:
                self.content_id = content_id
                self.call_letters = call_letters
        # if we preferred coverage and national coverage not available,
        # select any coverage available
        if self.content_id is None:
            try:
                (call_letters, coverage, content_id,
                 event_id) = content_list[0]
                self.content_id = content_id
                self.call_letters = call_letters
            except:
                self.content_id = None
                self.call_letters = None
        if self.content_id is None:
            self.error_str = "Requested stream is not available."
            self.error_str += "\n\nRequested coverage association: " + str(
                self.coverage)
            self.error_str += "\n\nAvailable content list = \n" + repr(
                content_list)
            raise Exception, self.error_str
        if self.debug:
            self.log.write("DEBUG>> writing soap response\n")
            self.log.write(repr(reply) + '\n')
        if self.content_id is None:
            self.error_str = "Requested stream is not yet available."
            raise Exception, self.error_str
        if self.debug:
            self.log.write("DEBUG>> soap event-id:" + str(self.stream) + '\n')
            self.log.write("DEBUG>> soap content-id:" + str(self.content_id) +
                           '\n')

    def requestSpecificMedia(self):
        query_values = {
            'subject': self.subject,
            'identityPointId': self.session.cookies['ipid'],
            'contentId': self.content_id,
            'playbackScenario': self.scenario,
            'fingerprint': urllib.unquote(self.session.cookies['fprt'])
        }
        try:
            sessionkey = urllib.unquote(self.session.cookies['ftmu'])
            query_values['sessionKey'] = sessionkey
        except:
            sessionkey = None
        url = self.base_url + urllib.urlencode(query_values)
        req = urllib2.Request(url)
        response = urllib2.urlopen(req)
        reply = parse(response)

        status_code = str(
            reply.getElementsByTagName('status-code')[0].childNodes[0].data)
        if status_code != "1":
            # candidate for new procedure: this code block of writing
            # unsuccessful xml responses is being repeated...
            self.log.write(
                "DEBUG (SOAPCODES!=1)>> writing unsuccessful soap response event_id = "
                + str(self.event_id) + " contend-id = " + self.content_id +
                "\n")
            df = open('/tmp/unsuccessful.xml', 'w')
            reply.writexml(df)
            df.close()
            df = open('/tmp/unsuccessful.xml')
            msg = df.read()
            df.close()
            self.error_str = SOAPCODES[status_code]
            raise Exception, self.error_str
        try:
            self.session_key = reply.getElementsByTagName(
                'session-key')[0].childNodes[0].data
            self.session.cookies['ftmu'] = self.session_key
            self.session.writeSessionKey(self.session_key)
        except:
            #raise
            self.session_key = None
        try:
            game_url = reply.getElementsByTagName('url')[0].childNodes[0].data
        except:
            self.error_str = "Stream URL not found in reply.  Stream may not be available yet."
            df = open(ERRORLOG_2, 'w')
            reply.writexml(df)
            df.close()
            raise Exception, self.error_str
        else:
            df = open(MEDIALOG_2, 'w')
            reply.writexml(df)
            df.close()
        self.log.write("DEBUG>> URL received: " + game_url + '\n')
        return game_url

    def parseFmsCloudResponse(self, url):
        auth_pat = re.compile(r'auth=(.*)')
        self.auth_chunk = '?auth=' + re.search(auth_pat, url).groups()[0]
        out = ''
        req = urllib2.Request(url)
        handle = urllib2.urlopen(req)
        rsp = parse(handle)
        rtmp_base = rsp.getElementsByTagName('meta')[0].getAttribute('base')
        for elem in rsp.getElementsByTagName('video'):
            speed = int(elem.getAttribute('system-bitrate')) / 1000
            if int(self.speed) == int(speed):
                vid_src = elem.getAttribute('src').replace('mp4:', '/')
                out = rtmp_base + vid_src
        return out

    def prepareMediaStreamer(self, game_url):
        #if self.streamtype in ( 'video', ):
        #    game_url = self.parseFmsCloudResponse(game_url)
        return self.prepareFmsUrl(game_url)

    # finally some url processing routines
    def prepareFmsUrl(self, game_url):
        try:
            #play_path_pat = re.compile(r'ondemand\/(.*)\?')
            play_path_pat = re.compile(r'ondemand\/(.*)$')
            self.play_path = re.search(play_path_pat, game_url).groups()[0]
            app_pat = re.compile(r'ondemand\/(.*)\?(.*)$')
            querystring = re.search(app_pat, game_url).groups()[1]
            self.app = "ondemand?_fcs_vhost=cp118053.edgefcs.net&akmfv=1.6" + querystring
            # not sure if we need this
            try:
                req = urllib2.Request('http://cp118053.edgefcs.net/fcs/ident')
                page = urllib2.urlopen(req)
                fp = parse(page)
                ip = fp.getElementsByTagName('ip')[0].childNodes[0].data
                self.tc_url = 'http://' + str(ip) + ':1935/' + self.app
            except:
                self.tc_url = None
        except:
            self.play_path = None
        try:
            live_pat = re.compile(r'live\/milb')
            if re.search(live_pat, game_url):
                if self.streamtype == 'audio':
                    auth_pat = re.compile(r'auth=(.*)')
                    self.auth_chunk = '?auth=' + re.search(
                        auth_pat, game_url).groups()[0]
                    live_sub_pat = re.compile(r'live\/mlb_audio(.*)\?')
                    self.sub_path = re.search(live_sub_pat,
                                              game_url).groups()[0]
                    self.sub_path = 'mlb_audio' + self.sub_path
                    live_play_pat = re.compile(r'live\/mlb_audio(.*)$')
                    self.play_path = re.search(live_play_pat,
                                               game_url).groups()[0]
                    self.play_path = 'mlb_audio' + self.play_path
                    app_auth = self.auth_chunk.replace('?', '&')
                    self.app = "live?_fcs_vhost=cp153281.live.edgefcs.net&akmfv=1.6&aifp=v0006" + app_auth
                else:
                    try:
                        live_sub_pat = re.compile(r'live\/milb_encap_rm(.*)')
                        self.sub_path = re.search(live_sub_pat,
                                                  game_url).groups()[0]
                        self.sub_path = 'milb_encap_rm' + self.sub_path
                    except Exception, detail:
                        self.error_str = 'Could not parse the stream subscribe path: ' + str(
                            detail)
                        raise Exception, self.error_str
                    try:
                        live_path_pat = re.compile(r'live\/milb_encap_rm(.*)$')
                        self.play_path = re.search(live_path_pat,
                                                   game_url).groups()[0]
                        self.play_path = 'milb_encap_rm' + self.play_path
                    except Exception, detail:
                        self.error_str = 'Could not parse the stream play path: ' + str(
                            detail)
                        raise Exception, self.error_str
                    sec_pat = re.compile(r'mlbsecurelive')
                    if re.search(sec_pat, game_url) is not None:
                        self.app = 'mlbsecurelive-live'
                    else:
                        self.app = 'live?_fcs_vhost=cp118053.live.edgefcs.net&akmfv=1.6'
            if self.debug:
                self.log.write("DEBUG>> sub_path = " + str(self.sub_path) +
                               "\n")
                self.log.write("DEBUG>> play_path = " + str(self.play_path) +
                               "\n")
                self.log.write("DEBUG>> app = " + str(self.app) + "\n")
Beispiel #13
0
class MediaStream:

    def __init__(self, stream, session, cfg, coverage=None, 
                 streamtype='video', start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
        self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_nexdef    = self.cfg.get('use_nexdef')
        self.postseason    = self.cfg.get('postseason')
        self.use_librtmp   = self.cfg.get('use_librtmp')
        # EXPERIMENTAL: make this a default now
		#self.use_wired_web = 1
        self.use_wired_web = self.cfg.get('use_wired_web')
        self.max_bps       = int(self.cfg.get('max_bps'))
        self.min_bps       = int(self.cfg.get('min_bps'))
        # allow max_bps and min_bps to be specified in kbps
        if self.min_bps < 128000:
            self.min_bps *= 1000
        if self.max_bps < 128000:
            self.max_bps *= 1000
        self.speed         = self.cfg.get('speed')
        self.adaptive      = self.cfg.get('adaptive_stream')

       
        # Install the cookie received from MLBLogin and used for subsequent 
        # media requests.  This part should resolve the issue of login 
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            ( self.call_letters,
              self.team_id,
              self.content_id,
              self.event_id ) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        try:
            self.session_key = self.session.session_key
        except:
            self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        if self.streamtype in ( 'audio', 'alt_audio' ):
            self.scenario = "AUDIO_FMS_32K"
            self.subject  = "MLBCOM_GAMEDAY_AUDIO"
        else:
            if self.use_nexdef:
                if self.use_wired_web:
                    self.scenario = 'HTTP_CLOUD_WIRED_WEB'
                else:
                    self.scenario = 'HTTP_CLOUD_WIRED'
            else:
                self.scenario = 'FMS_CLOUD'
            #self.subject  = "LIVE_EVENT_COVERAGE"
            self.subject = "MLBTV"

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this 
        # url need to be changed to reflect that?
        # self.base_url= 'https://mlb-ws-mf.media.mlb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?' # 😉
        self.base_url='https://secure.mlb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?' 


    def createMediaRequest(self,stream):
        if stream == None:
            self.error_str = "No event-id present to create media request."
            raise

        try:
            # sessionKey = urllib.unquote(self.session.cookies['ftmu'])
            sessionKey = self.session.session_key
        except:
            sessionKey = None
      
        # Query values
        query_values = {
            'eventId': self.event_id,
            'sessionKey': sessionKey,
            'fingerprint': urllib.unquote(self.session.cookies['fprt']),
            'identityPointId': self.session.cookies['ipid'],
            # 'playbackScenario': 'HTTP_CLOUD_TABLET_60', # 😉
            # 'subject': 'LIVE_EVENT_COVERAGE', # 😉
            # 'platform': 'IPAD', # 😉
            # 'postalCode': '{{postalCode}}', # 😉
            # 'country': '{{country}}', # 😉
            # 'latitude': '{{latitude}}', # 😉
            # 'longitude': '{{longitude}}' # 😉
            'playbackScenario': self.scenario,
            'subject': self.subject
        }
        # Build query
        url = self.base_url + urllib.urlencode(query_values)

        # And make the request
        req = urllib2.Request(url)
        try:
            response = urllib2.urlopen(req)
        except urllib2.HTTPError, err:
            self.log.write("Error (%s) for URL: %s" % ( err.code, url ))
            raise
        reply = xml.dom.minidom.parse(response)
        return reply
Beispiel #14
0
    def __init__(self, stream, session, cfg, coverage=None, 
                 streamtype='video', start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
	self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_librtmp   = self.cfg.get('use_librtmp')
        self.speed         = self.cfg.get('speed')

        # milbtv is one flavor: vanilla. Not even French vanilla.
        self.use_nexdef = False
        self.streamtype = 'video'
       
        # Install the cookie received from MLBLogin and used for subsequent 
        # media requests.  This part should resolve the issue of login 
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            ( self.call_letters,
              self.team_id,
              self.content_id,
              self.event_id ) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        self.scenario = 'FLASH_1000K_640X360'
        self.subject = 'LIVE_EVENT_COVERAGE'

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this 
        # url need to be changed to reflect that?
        self.base_url='http://www.milb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?' 
Beispiel #15
0
class MiLBSession:
    def __init__(self, user, passwd, debug=False):
        self.user = user
        if self.user is None:
            # if user= is commented out, cfg.get() returns None, normalize this
            self.user = ""
        self.passwd = passwd
        self.auth = True
        self.logged_in = None
        self.cookie_jar = None
        self.cookies = {}
        self.debug = debug
        if COOKIE_DEBUG:
            self.debug = True
        self.log = MLBLog(LOGFILE)
        try:
            self.session_key = self.readSessionKey()
            if self.debug:
                self.log.write("LOGIN> Read session key from file: " +
                               str(self.session_key))
        except:
            self.session_key = None

    def readSessionKey(self):
        sk = open(SESSIONKEY, "r")
        self.session_key = sk.read()
        sk.close()
        return session_key

    def writeSessionKey(self, session_key):
        if self.debug:
            self.log.write('Writing session-key to file: ' +
                           str(self.session_key) + '\n')
        sk = open(SESSIONKEY, "w")
        sk.write(session_key)
        sk.close()
        return session_key

    def extractCookies(self):
        for c in self.cookie_jar:
            self.cookies[c.name] = c.value
        self.printCookies()

    def printCookies(self):
        if self.debug:
            self.log.write('Printing relevant cookie morsels...\n')
            for name in self.cookies.keys():
                if name in ('fprt', 'ftmu', 'ipid'):
                    self.log.write(str(name) + ' = ' + str(self.cookies[name]))
                    self.log.write('\n')

    def readCookieFile(self):
        self.cookie_jar = cookielib.LWPCookieJar()
        if self.cookie_jar != None:
            if os.path.isfile(COOKIEFILE):
                self.cookie_jar.load(COOKIEFILE, ignore_discard=IGNORE_DISCARD)
                if self.debug:
                    self.log.write('readCookieFile:\n')
                self.extractCookies()
            else:
                raise MLBNoCookieFileError
        else:
            self.error_str = "Couldn't open cookie jar"
            raise Exception, self.error_str

    def login(self):
        try:
            self.readCookieFile()
        except MLBNoCookieFileError:
            #pass
            if self.debug:
                self.log.write("LOGIN> No cookie file")
        opener = urllib2.build_opener(
            urllib2.HTTPCookieProcessor(self.cookie_jar))
        urllib2.install_opener(opener)

        # First visit the login page and get the session cookie
        login_url = 'https://secure.milb.com/enterworkflow.do?flowId=registration.profile'
        txheaders = {'User-agent': USERAGENT}
        data = None
        req = urllib2.Request(login_url, data, txheaders)
        # we might have cookie info by now??
        if self.user == "":
            return

        try:
            handle = urllib2.urlopen(req)
        except:
            self.error_str = 'Error occurred in HTTP request to login page'
            raise Exception, self.error_str
        try:
            if self.debug:
                self.log.write('pre-login:\n')
            self.extractCookies()
        except Exception, detail:
            raise Exception, detail
        #if self.debug:
        #    self.log.write('Did we receive a cookie from the wizard?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE, ignore_discard=IGNORE_DISCARD)

        rdata = handle.read()

        # now authenticate
        auth_values = {
            'uri': '/account/login_register.jsp',
            'registrationAction': 'identify',
            'emailAddress': self.user,
            'password': self.passwd
        }
        success_pat = re.compile(
            r'Account Management - Profile | MiLB.com Account |')
        auth_data = urllib.urlencode(auth_values)
        auth_url = 'https://secure.milb.com/authenticate.do'
        req = urllib2.Request(auth_url, auth_data, txheaders)
        try:
            handle = urllib2.urlopen(req)
            self.cookie_jar.save(COOKIEFILE, ignore_discard=IGNORE_DISCARD)
            if self.debug:
                self.log.write('post-login: (this gets saved to file)\n')
            self.extractCookies()
        except:
            self.error_str = 'Error occurred in HTTP request to auth page'
            raise Exception, self.error_str
        auth_page = handle.read()
        #if self.debug:
        #    self.log.write('Did we receive a cookie from authenticate?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE, ignore_discard=IGNORE_DISCARD)
        try:
            loggedin = re.search(success_pat, auth_page).groups()
            self.log.write('Logged in successfully!\n')
            self.logged_in = True
        except:
            self.error_str = 'Login was unsuccessful.'
            self.log.write(auth_page)
            os.remove(COOKIEFILE)
            raise MLBAuthError, self.error_str
Beispiel #16
0
    def __init__(self,
                 stream,
                 session,
                 cfg,
                 coverage=None,
                 streamtype='video',
                 start_time=0):
        # Initialize basic object from instance variables
        self.stream = stream
        self.session = session
        self.cfg = cfg
        if coverage == None:
            self.coverage = 0
        else:
            self.coverage = coverage
        self.start_time = start_time
        self.streamtype = streamtype

        # Need a few config items
        self.use_nexdef = self.cfg.get('use_nexdef')
        self.postseason = self.cfg.get('postseason')
        self.use_librtmp = self.cfg.get('use_librtmp')
        # EXPERIMENTAL: make this a default now
        #self.use_wired_web = self.cfg.get('use_wired_web')
        self.use_wired_web = 1
        self.max_bps = int(self.cfg.get('max_bps'))
        self.min_bps = int(self.cfg.get('min_bps'))
        # allow max_bps and min_bps to be specified in kbps
        if self.min_bps < 128000:
            self.min_bps *= 1000
        if self.max_bps < 128000:
            self.max_bps *= 1000
        self.speed = self.cfg.get('speed')
        self.adaptive = self.cfg.get('adaptive_stream')

        # Install the cookie received from MLBLogin and used for subsequent
        # media requests.  This part should resolve the issue of login
        # restriction errors when each MediaStream request was its own login/
        # logout sequence.
        try:
            opener = urllib2.build_opener(
                urllib2.HTTPCookieProcessor(self.session.cookie_jar))
            urllib2.install_opener(opener)
        except:
            raise

        self.log = MLBLog(LOGFILE)
        self.error_str = "What happened here?\nPlease enable debug with the d key and try your request again."

        # Break the stream argument into its components used for media location
        # requests.
        try:
            (self.call_letters, self.team_id, self.content_id,
             self.event_id) = self.stream
        except:
            self.error_str = "No stream available for selected game."

        self.log.write(str(datetime.datetime.now()) + '\n')
        try:
            self.session_key = self.session.session_key
        except:
            self.session_key = None
        self.debug = cfg.get('debug')

        # The request format depends on the streamtype
        if self.streamtype in ('audio', 'alt_audio'):
            self.scenario = "AUDIO_FMS_32K"
            self.subject = "MLBCOM_GAMEDAY_AUDIO"
        else:
            if self.use_nexdef:
                if self.use_wired_web:
                    self.scenario = 'HTTP_CLOUD_WIRED_WEB'
                else:
                    self.scenario = 'HTTP_CLOUD_WIRED'
            else:
                self.scenario = 'FMS_CLOUD'
            #self.subject  = "LIVE_EVENT_COVERAGE"
            self.subject = "MLBTV"

        # Media response needs to be parsed into components below.
        self.auth_chunk = None
        self.play_path = None
        self.tc_url = None
        self.app = None
        self.rtmp_url = None
        self.rtmp_host = None
        self.rtmp_port = None
        self.sub_path = None

        # TODO: Has this findUserVerifiedEvent been updated?  Does this
        # url need to be changed to reflect that?
        self.base_url = 'https://secure.mlb.com/pubajaxws/bamrest/MediaService2_0/op-findUserVerifiedEvent/v-2.3?'
Beispiel #17
0
class MiLBSession:

    def __init__(self,user,passwd,debug=False):
        self.user = user
        if self.user is None:
            # if user= is commented out, cfg.get() returns None, normalize this
            self.user = ""
        self.passwd = passwd
        self.auth = True
        self.logged_in = None
        self.cookie_jar = None
        self.cookies = {}
        self.debug = debug
        if COOKIE_DEBUG:
            self.debug = True
        self.log = MLBLog(LOGFILE)
        try:
            self.session_key = self.readSessionKey()
            if self.debug:
                self.log.write("LOGIN> Read session key from file: " + str(self.session_key))
        except:
            self.session_key = None

    def readSessionKey(self):
        sk = open(SESSIONKEY,"r")
        self.session_key = sk.read()
        sk.close()
        return session_key

    def writeSessionKey(self,session_key):
        if self.debug:
            self.log.write('Writing session-key to file: ' + str(self.session_key) + '\n')
        sk = open(SESSIONKEY,"w")
        sk.write(session_key)
        sk.close()
        return session_key

    def extractCookies(self):
        for c in self.cookie_jar:
            self.cookies[c.name] = c.value
        self.printCookies()

    def printCookies(self):
        if self.debug:
            self.log.write('Printing relevant cookie morsels...\n')
            for name in self.cookies.keys():
                if name in ('fprt', 'ftmu', 'ipid'):
                    self.log.write(str(name) + ' = ' + str(self.cookies[name]))
                    self.log.write('\n')

    def readCookieFile(self):
        self.cookie_jar = cookielib.LWPCookieJar()
        if self.cookie_jar != None:
            if os.path.isfile(COOKIEFILE):
                self.cookie_jar.load(COOKIEFILE,ignore_discard=IGNORE_DISCARD)
                if self.debug:
                    self.log.write('readCookieFile:\n')
                self.extractCookies()
            else:
                raise MLBNoCookieFileError
        else:
            self.error_str = "Couldn't open cookie jar"
            raise Exception,self.error_str

    def login(self):
        try:
            self.readCookieFile()
        except MLBNoCookieFileError:
            #pass
            if self.debug:
                self.log.write("LOGIN> No cookie file")
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie_jar))
        urllib2.install_opener(opener)

        # First visit the login page and get the session cookie
        login_url = 'https://secure.milb.com/enterworkflow.do?flowId=registration.profile'
        txheaders = {'User-agent' : USERAGENT}
        data = None
        req = urllib2.Request(login_url,data,txheaders)
        # we might have cookie info by now??
        if self.user=="":
            return

        try:
            handle = urllib2.urlopen(req)
        except:
            self.error_str = 'Error occurred in HTTP request to login page'
            raise Exception, self.error_str
        try:
            if self.debug:
                self.log.write('pre-login:\n')
            self.extractCookies()
        except Exception,detail:
            raise Exception,detail
        #if self.debug:
        #    self.log.write('Did we receive a cookie from the wizard?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE,ignore_discard=IGNORE_DISCARD)

        rdata = handle.read()

        # now authenticate
        auth_values = {'uri' : '/account/login_register.jsp',
                       'registrationAction' : 'identify',
                       'emailAddress' : self.user,
                       'password' : self.passwd
                      }
        success_pat = re.compile(r'Account Management - Profile | MiLB.com Account |')
        auth_data = urllib.urlencode(auth_values)
        auth_url = 'https://secure.milb.com/authenticate.do'
        req = urllib2.Request(auth_url,auth_data,txheaders)
        try:
            handle = urllib2.urlopen(req)
            self.cookie_jar.save(COOKIEFILE,ignore_discard=IGNORE_DISCARD)
            if self.debug:
                self.log.write('post-login: (this gets saved to file)\n')
            self.extractCookies()
        except:
            self.error_str = 'Error occurred in HTTP request to auth page'
            raise Exception, self.error_str
        auth_page = handle.read()
        #if self.debug:
        #    self.log.write('Did we receive a cookie from authenticate?\n')
        #    for index, cookie in enumerate(self.cookie_jar):
        #        print >> self.log, index, ' : ' , cookie
        self.cookie_jar.save(COOKIEFILE,ignore_discard=IGNORE_DISCARD)
        try:
           loggedin = re.search(success_pat, auth_page).groups()
           self.log.write('Logged in successfully!\n')
           self.logged_in = True
        except:
           self.error_str = 'Login was unsuccessful.'
           self.log.write(auth_page)
           os.remove(COOKIEFILE)
           raise MLBAuthError, self.error_str