home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / xbmc-9.11.exe / scripts / AppleMovieTrailers / resources / showtimes_scrapers / Google / showtimesScraper.py
Encoding:
Python Source  |  2008-08-06  |  10.9 KB  |  272 lines

  1. # -*- coding: utf-8 -*-
  2.  
  3. """
  4. Scraper for http://www.google.com/movies
  5.  
  6. Nuka1195
  7. """
  8.  
  9. import sys
  10. import os
  11.  
  12. try:
  13.     import xbmc
  14. except:
  15.     pass
  16.  
  17. from sgmllib import SGMLParser
  18. import urllib
  19. import datetime
  20.  
  21. __title__ = "Google"
  22. __credit__ = "Nuka1195"
  23.  
  24.  
  25. class _TheaterListParser( SGMLParser ):
  26.     """ 
  27.         Parser Class: parses an html document for opening date 
  28.     """
  29.     def __init__( self ):
  30.         SGMLParser.__init__( self )
  31.  
  32.     def reset( self ):
  33.         SGMLParser.reset( self )
  34.         self.theater_list = {}
  35.         self.current_theater = ""
  36.         self.theater_id = None
  37.         self.theater_name_found = False
  38.  
  39.     def start_a( self, attrs ):
  40.         for key, value in attrs:
  41.             if ( key == "href" and "&tid=" in value ):
  42.                 self.theater_id = value
  43.                 self.current_theater = ""
  44.  
  45.     def end_a( self ):
  46.         if ( self.theater_id is not None ):
  47.             self.theater_list[ self.current_theater ] = [ "", "", "", "http://www.google.com%s" % self.theater_id ]
  48.             self.theater_name_found = True
  49.             self.theater_id = None
  50.  
  51.     def handle_data( self, text ):
  52.         if ( self.theater_id is not None ):
  53.             self.current_theater += text
  54.         elif ( text == "Map" ):
  55.             phone = self.theater_list[ self.current_theater ][ 0 ].find( " - " )
  56.             self.theater_list[ self.current_theater ][ 2 ] = self.theater_list[ self.current_theater ][ 0 ][ phone + 3 : -2 ].strip()
  57.             self.theater_list[ self.current_theater ][ 0 ] = self.theater_list[ self.current_theater ][ 0 ][ : phone ]
  58.             self.theater_name_found = False
  59.         elif ( self.theater_name_found ):
  60.             self.theater_list[ self.current_theater ][ 0 ] += "%s " % text.strip()
  61.  
  62.  
  63. class _OpeningDateParser( SGMLParser ):
  64.     """ 
  65.         Parser Class: parses an html document for opening date 
  66.     """
  67.     def __init__( self ):
  68.         SGMLParser.__init__( self )
  69.  
  70.     def reset( self ):
  71.         SGMLParser.reset( self )
  72.         self.url = None
  73.  
  74.     def start_a( self, attrs ):
  75.         for key, value in attrs:
  76.             if ( key == "href" and value.startswith( "/movies?near=" ) and self.url is None ):
  77.                 self.url = value
  78.  
  79.  
  80. class _ShowtimesParser( SGMLParser ):
  81.     """ 
  82.         Parser Class: parses an html document for movie showtimes and date
  83.         - creates a key { theater: [#:##] }
  84.         - formats date (dayofweek, month day, year)
  85.     """
  86.     def __init__( self ):
  87.         SGMLParser.__init__( self )
  88.  
  89.     def reset( self ):
  90.         SGMLParser.reset( self )
  91.         self.theaters = {}
  92.         self.current_theater = ""
  93.         self.theater_id = ""
  94.         self.theater_set = False
  95.         self.start_theaters = False
  96.         self.showtimes_date = str( datetime.date.today() )
  97.         self.showtimes_date_found = False
  98.  
  99.     def start_a( self, attrs ):
  100.         for key, value in attrs:
  101.             if ( key == "href" and value.startswith( "/movies?near=" ) ):
  102.                 self.theater_id = value
  103.                 self.current_theater = ""
  104.             elif ( key == "href" and value.startswith( "http://www.google.com/url" ) and not self.showtimes_date_found ):
  105.                 s = value.find( "date%3D" )
  106.                 if ( s >= 0 ):
  107.                     self.showtimes_date  = value[ s + 7 : s +17 ]
  108.                     self.showtimes_date_found = True
  109.  
  110.     def end_a( self ):
  111.         if ( self.start_theaters ):
  112.             if ( self.theater_id ):
  113.                 self.theaters[ self.current_theater ] = [ "", "", "", "http://www.google.com%s" % self.theater_id ]
  114.                 self.theater_id = ""
  115.                 self.theater_set = True
  116.  
  117.     def handle_data( self, text ):
  118.         if ( self.start_theaters and text.strip() ):
  119.             if ( self.theater_id ):
  120.                 self.current_theater += text
  121.             elif ( text.strip()[ 0 ].isdigit() and ":" in text ):
  122.                 if ( self.theaters[ self.current_theater ][ 1 ] ):
  123.                     self.theaters[ self.current_theater ][ 1 ] += ", "
  124.                 self.theaters[ self.current_theater ][ 1 ] += text.strip()
  125.                 self.theater_set = False
  126.             elif ( self.theater_set and text != "Map" and text != "Trailer" and text != "IMDb" ):#and not text.endswith( " - " ) ):
  127.                 self.theaters[ self.current_theater ][ 0 ] += "%s " % text.strip()
  128.             elif ( self.theater_set ):
  129.                 self.theaters[ self.current_theater ][ 0 ] = self.theaters[ self.current_theater ][ 0 ][ : -2 ].strip()
  130.         elif ( text == "Show more movies" or text == "Show more films" or text == "Show more theaters" ):
  131.             self.start_theaters = True
  132.             self.theater_id = ""
  133.  
  134.  
  135. class ShowtimesFetcher:
  136.     """ 
  137.         *REQUIRED: Fetcher Class for www.google.com/movies
  138.         - returns a key { theater: [#:##] } and date of showtimes
  139.     """
  140.     def __init__( self ):
  141.         self.base_url = "http://www.google.com"
  142.         try:
  143.             self.date_format = xbmc.getRegion( "datelong" ).replace( "DDDD", "%A" ).replace( "MMMM", "%B" ).replace( "D", "%d" ).replace( "YYYY", "%Y" )
  144.         except:
  145.             self.date_format = "%A, %B %d, %Y"
  146.  
  147.     def get_showtimes( self, movie, location ):
  148.         """ *REQUIRED: Returns showtimes for each theater in your local """
  149.         movie = self._format_param( movie.encode( "utf-8" ) )
  150.         location = self._format_param( location )
  151.         date, showtimes = self._fetch_showtimes( self.base_url + "/movies?q=%s&near=%s" % ( movie, location, ) )
  152.         if ( showtimes is None or not showtimes ):
  153.             theaters = self._get_theater_list( self.base_url + "/movies?near=%s" % ( location, ) )
  154.             return None, theaters
  155.         else:
  156.             date = datetime.date( int( date.split( "-" )[ 0 ] ), int( date.split( "-" )[ 1 ] ), int( date.split( "-" )[ 2 ] ) ).strftime( self.date_format )
  157.             return date, showtimes
  158.     
  159.     def get_selection( self, url ):
  160.         """ *REQUIRED: Returns movies for the selected theater """
  161.         date, showtimes = self._fetch_showtimes( url )
  162.         date = datetime.date( int( date.split( "-" )[ 0 ] ), int( date.split( "-" )[ 1 ] ), int( date.split( "-" )[ 2 ] ) ).strftime( self.date_format )
  163.         return date, showtimes
  164.  
  165.     def _fetch_showtimes( self, url ):
  166.         """ Fetch showtimes if available else return a list of theaters """
  167.         try:
  168.             showtimes_date = None
  169.             # Open url or local file (if debug)
  170.             if ( not debug ):
  171.                 usock = urllib.urlopen( url )
  172.             else:
  173.                 usock = open( os.path.join( os.getcwd().replace( ";", "" ), "showtimes_source.txt" ), "r" )
  174.             htmlSource = usock.read()
  175.             usock.close()
  176.             if ( htmlSource.find( "No showtimes were found" ) >= 0 ):
  177.                 htmlSource, showtimes_date = self._get_first_date( htmlSource )
  178.             # Save htmlSource to a file for testing scraper (if debugWrite)
  179.             if ( debugWrite ):
  180.                 file_object = open( os.path.join( os.getcwd().replace( ";", "" ), "showtimes_source.txt" ), "w" )
  181.                 file_object.write( htmlSource )
  182.                 file_object.close()
  183.             if ( htmlSource.find( "Movie Reviews" ) >= 0 ):
  184.                 raise
  185.             # Parse htmlSource for showtimes
  186.             parser = _ShowtimesParser()
  187.             parser.feed( htmlSource )
  188.             parser.close()
  189.             date = ( showtimes_date, parser.showtimes_date, )[ showtimes_date is None ]
  190.             return date, parser.theaters
  191.         except:
  192.             return None, None
  193.         
  194.     def _format_param( self, param ):
  195.         """ Converts param to the form expected by www.google.com/movies """
  196.         result = urllib.quote_plus( param )
  197.         return result
  198.  
  199.     def _get_first_date( self, htmlSource ):
  200.         try:
  201.             if ( debugWrite ):
  202.                 file_object = open( os.path.join( os.getcwd().replace( ";", "" ), "showtimes_source2.txt" ), "w" )
  203.                 file_object.write( htmlSource )
  204.                 file_object.close()
  205.             parser = _OpeningDateParser()
  206.             parser.feed( htmlSource )
  207.             parser.close()
  208.             date = None
  209.             if ( parser.url is not None ):
  210.                 if ( not debug ):
  211.                     usock = urllib.urlopen( self.base_url + parser.url )
  212.                 else:
  213.                     usock = open( os.path.join( os.getcwd().replace( ";", "" ), "showtimes_source2.txt" ), "r" )
  214.                 htmlSource = usock.read()
  215.                 usock.close()
  216.                 date = parser.showtimes_date
  217.         except:
  218.             pass
  219.         return htmlSource, date
  220.         
  221.     def _get_theater_list( self, url ):
  222.         try:
  223.             if ( not debug ):
  224.                 usock = urllib.urlopen( url )
  225.             else:
  226.                 usock = open( os.path.join( os.getcwd().replace( ";", "" ), "showtimes_source3.txt" ), "r" )
  227.             htmlSource = usock.read()
  228.             usock.close()
  229.             parser = _TheaterListParser()
  230.             parser.feed( htmlSource )
  231.             parser.close()
  232.             if ( debugWrite ):
  233.                 file_object = open( os.path.join( os.getcwd().replace( ";", "" ), "showtimes_source3.txt" ), "w" )
  234.                 file_object.write( htmlSource )
  235.                 file_object.close()
  236.             return parser.theater_list
  237.         except:
  238.             return None
  239.  
  240.  
  241. # used for testing only
  242. debug = False
  243. debugWrite = False
  244.  
  245. if ( __name__ == "__main__" ):
  246.     # used to test get_lyrics() 
  247.     movie = [ "The Seeker: the Dark is Rising", "el cantante", "Rush Hour 3", "The Simpsons Movie", "Transformers", "I Now Pronounce You Chuck & Larry", "Transformers", "I Now Pronounce You Chuck & Larry" ]
  248.     location = [ "detroit", "Houston", "detroit", "new york", "London", "Toronto", "33102", "W2 4YL", "T1A 3T9" ]
  249.     url = [ "http://www.google.com/movies?near=London&tid=6642f6f298729f38" ]
  250.     for cnt in range( 1 ):
  251.         #date, theaters = ShowtimesFetcher().get_showtimes( movie[ cnt ], location[ cnt ] )
  252.         date, theaters = ShowtimesFetcher().get_selection( url[ cnt ] )
  253.  
  254.         # print the results
  255.         print "====================================================="
  256.         print "Showtimes for %s Movie: %s - Location: %s" % ( date, movie[ cnt ], location[ cnt ], )
  257.         print
  258.         if ( theaters ):
  259.             theater_names = theaters.keys()
  260.             theater_names.sort()
  261.             for theater in theater_names:
  262.                 print theater
  263.                 print theaters[ theater ][ 0 ]#s[theater]
  264.                 print theaters[ theater ][ 1 ]#s[theater]
  265.                 print theaters[ theater ][ 2 ]#s[theater]
  266.                 print theaters[ theater ][ 3 ]#s[theater]
  267.                 print
  268.         else:
  269.             print "No showtimes found!"
  270.         print "====================================================="
  271.         print
  272.