home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / xbmc-9.11.exe / scripts / AppleMovieTrailers / resources / lib / utilities.py < prev   
Encoding:
Python Source  |  2009-11-03  |  14.3 KB  |  313 lines

  1. """
  2. Catchall module for shared functions and constants
  3.  
  4. Nuka1195
  5. """
  6.  
  7. import sys
  8. import os
  9. import xbmc
  10. import xbmcgui
  11.  
  12. DEBUG_MODE = 0
  13.  
  14. _ = sys.modules[ "__main__" ].__language__
  15. __scriptname__ = sys.modules[ "__main__" ].__scriptname__
  16. __version__ = sys.modules[ "__main__" ].__version__
  17. __svn_revision__ = sys.modules[ "__main__" ].__svn_revision__
  18.  
  19. # comapatble versions
  20. DATABASE_VERSIONS = ( "pre-0.99.7.1", "pre-0.99.7.2", "pre-0.99.7.3", )
  21. SETTINGS_VERSIONS = DATABASE_VERSIONS
  22. # special categories
  23. GENRES = -1
  24. STUDIOS = -2
  25. ACTORS = -3
  26. FAVORITES = -6
  27. DOWNLOADED = -7
  28. HD_TRAILERS = -8
  29. NO_TRAILER_URLS = -9
  30. WATCHED = -10
  31. RECENTLY_ADDED = -11
  32. MULTIPLE_TRAILERS = -12
  33. CUSTOM_SEARCH = -99
  34. # base paths
  35. BASE_DATA_PATH = os.path.join( xbmc.translatePath( "special://masterprofile/" ), "script_data", __scriptname__ )
  36. BASE_SETTINGS_PATH = os.path.join( xbmc.translatePath( "special://profile/" ), "script_data", os.path.basename( os.getcwd() ), "settings.txt" )
  37. BASE_DATABASE_PATH = os.path.join( xbmc.translatePath( "special://profile/" ), "script_data", os.path.basename( os.getcwd() ), "AMT.db" )
  38. BASE_RESOURCE_PATH = sys.modules[ "__main__" ].BASE_RESOURCE_PATH
  39. # special button codes
  40. SELECT_ITEM = ( 11, 256, 61453, )
  41. EXIT_SCRIPT = ( 247, 275, 61467, )
  42. CANCEL_DIALOG = EXIT_SCRIPT + ( 216, 257, 61448, )
  43. TOGGLE_DISPLAY = ( 216, 257, 61448, )
  44. CONTEXT_MENU = ( 229, 261, 61533, )
  45. MOVEMENT_UP = ( 166, 270, 61478, )
  46. MOVEMENT_DOWN = ( 167, 271, 61480, )
  47. MOVEMENT = ( 166, 167, 168, 169, 270, 271, 272, 273, 61477, 61478, 61479, 61480, )
  48. # special action codes
  49. ACTION_SELECT_ITEM = ( 7, )
  50. ACTION_EXIT_SCRIPT = ( 10, )
  51. ACTION_CANCEL_DIALOG = ACTION_EXIT_SCRIPT + ( 9, )
  52. ACTION_TOGGLE_DISPLAY = ( 9, )
  53. ACTION_CONTEXT_MENU = ( 117, )
  54. ACTION_MOVEMENT_UP = ( 3, )
  55. ACTION_MOVEMENT_DOWN = ( 4, )
  56. ACTION_MOVEMENT = ( 1, 2, 3, 4, )
  57. # Log status codes
  58. LOG_ERROR, LOG_INFO, LOG_NOTICE, LOG_DEBUG = range( 1, 5 )
  59.  
  60.  
  61. def _create_base_paths():
  62.     """ creates the base folders """
  63.     new = False
  64.     # create the main cache and database paths
  65.     if ( not os.path.isdir( BASE_DATA_PATH ) ):
  66.         os.makedirs( BASE_DATA_PATH )
  67.         new = True
  68.     if ( not os.path.isdir( os.path.dirname( BASE_SETTINGS_PATH ) ) ):
  69.         os.makedirs( os.path.dirname( BASE_SETTINGS_PATH ) )
  70.     return new
  71. INSTALL_PLUGIN = _create_base_paths()
  72.  
  73. def install_plugin( plugin_list, message=False ):
  74.     # setup the plugins to install
  75.     plugins = os.listdir( os.path.join( BASE_RESOURCE_PATH, "plugins" ) )
  76.     plugins.sort()
  77.     ok = True
  78.     for plugin in plugin_list:
  79.         # get the correct plugin message block start
  80.         if ( message ):
  81.             ok = xbmcgui.Dialog().yesno( plugins[ plugin ], _( 750 ), "", "", _( 712 ), _( 711 ), )
  82.         if ( ok ):
  83.             try:
  84.                 # we use "U:\\" for linux, windows and osx for platform mode
  85.                 drive = xbmc.translatePath( "special://home/" )
  86.                 # get the thumbnail the user chooses
  87.                 thumbnail_copy_path = get_browse_dialog( default=os.path.join( BASE_RESOURCE_PATH, "plugins", plugins[ plugin ], "thumbnails", "thumbs", "default.tbn" ), heading="%s - %s" % ( _( 710 ), plugins[ plugin ], ), dlg_type=2, mask=".tbn", use_thumbs=True )
  88.                 # create the progress dialog
  89.                 dialog = xbmcgui.DialogProgress()
  90.                 dialog.create( plugins[ plugin ] )
  91.                 dialog.update(-1, _( 725 ), "", _( 67 ) )
  92.                 from shutil import copytree, rmtree, copyfile
  93.                 # the main plugin path to install to
  94.                 plugin_install_path = os.path.join( drive, "plugins", "video", plugins[ plugin ] )
  95.                 # path where plugin is copied from
  96.                 plugin_copy_path = os.path.join( BASE_RESOURCE_PATH, "plugins", plugins[ plugin ] )
  97.                 # we need pysqlite2 for database access
  98.                 pysqlite2_install_path = os.path.join( drive, "plugins", "video", plugins[ plugin ], "pysqlite2" )
  99.                 # path where pysqlite2 is copied from
  100.                 env = ( os.environ.get( "OS", "win32" ), "win32", )[ os.environ.get( "OS", "win32" ) == "xbox" ]
  101.                 pysqlite2_copy_path = os.path.join( BASE_RESOURCE_PATH, "platform_libraries", env, "pysqlite2" )
  102.                 # remove an existing install if it exists
  103.                 if ( os.path.isdir( plugin_install_path ) ):
  104.                     rmtree( plugin_install_path )
  105.                 # copy our main directory
  106.                 copytree( plugin_copy_path, plugin_install_path )
  107.                 # copy pysqlite2
  108.                 copytree( pysqlite2_copy_path, pysqlite2_install_path )
  109.                 # default.tbn install path
  110.                 thumbnail_install_path = os.path.join( drive, "plugins", "video", plugins[ plugin ], "default.tbn" )
  111.                 # folder.jpg install path (probably not needed)
  112.                 folderjpg_install_path = os.path.join( drive, "plugins", "video", plugins[ plugin ], "folder.jpg" )
  113.                 # get the cached thumb name
  114.                 cached_thumbnail = xbmc.getCacheThumbName( os.path.join( drive, "plugins", "video", plugins[ plugin ] + "\\" ) )
  115.                 # cached thumb path (we delete the existing, so our plugin re-caches the new thumb)
  116.                 cached_thumbnail_path = os.path.join( xbmc.translatePath( "special://profile/" ), "Thumbnails", "Programs", cached_thumbnail )
  117.                 # get the root cached thumb name
  118.                 root_cached_thumbnail = xbmc.getCacheThumbName( "plugin://video/"+ plugins[ plugin ] + "/" )
  119.                 # root cached thumb path (deleting does not work, so we overwrite the existing)
  120.                 root_cached_thumbnail_path = os.path.join( xbmc.translatePath( "special://profile/" ), "Thumbnails", "Programs", root_cached_thumbnail )
  121.                 # copy default.tbn
  122.                 copyfile( thumbnail_copy_path, thumbnail_install_path )
  123.                 # copy folder.jpg (probably not needed)
  124.                 copyfile( thumbnail_copy_path, folderjpg_install_path )
  125.                 # copy default.tbn for our root folder (deleting never refreshes it)
  126.                 copyfile( thumbnail_copy_path, root_cached_thumbnail_path )
  127.                 # delete our cached thumbnail
  128.                 if ( os.path.isfile( cached_thumbnail_path ) ):
  129.                     os.remove( cached_thumbnail_path )
  130.                 dialog.close()
  131.                 # TODO: enable this once webserver does not need to be running
  132.                 """
  133.                 # add the bookmark to sources.xml
  134.                 addbookmark = xbmcgui.Dialog().yesno( plugins[ plugin ], _( 723 ), _( 724 ), "", _( 712 ), _( 714 ) )
  135.                 if ( addbookmark ):
  136.                     xbmc.executehttpapi( "Config(addbookmark,video,%s,plugin://video/%s/)" % ( plugins[ plugin ], plugins[ plugin ], ) )
  137.                 else:
  138.                 """
  139.             except:
  140.                 # oops notify user an error occurred
  141.                 dialog.close()
  142.                 import traceback
  143.                 traceback.print_exc()
  144.                 ok = xbmcgui.Dialog().ok( plugins[ plugin ], _( 730 ) )
  145.                 return
  146.     if ( ok ):
  147.         # inform user of installation procedure for plugin
  148.         ok = xbmcgui.Dialog().ok( plugins[ plugin ], _( 720 ), _( 721 ), _( 722 ) )
  149.  
  150. def get_keyboard( default="", heading="", hidden=False ):
  151.     """ shows a keyboard and returns a value """
  152.     keyboard = xbmc.Keyboard( default, heading, hidden )
  153.     keyboard.doModal()
  154.     if ( keyboard.isConfirmed() ):
  155.         return keyboard.getText()
  156.     return default
  157.  
  158. def get_numeric_dialog( default="", heading="", dlg_type=3 ):
  159.     """ shows a numeric dialog and returns a value
  160.         - 0 : ShowAndGetNumber        (default format: #)
  161.         - 1 : ShowAndGetDate            (default format: DD/MM/YYYY)
  162.         - 2 : ShowAndGetTime            (default format: HH:MM)
  163.         - 3 : ShowAndGetIPAddress    (default format: #.#.#.#)
  164.     """
  165.     dialog = xbmcgui.Dialog()
  166.     value = dialog.numeric( dlg_type, heading, default )
  167.     return value
  168.  
  169. def get_browse_dialog( default="", heading="", dlg_type=1, shares="files", mask="", use_thumbs=False, treat_as_folder=False ):
  170.     """ shows a browse dialog and returns a value
  171.         - 0 : ShowAndGetDirectory
  172.         - 1 : ShowAndGetFile
  173.         - 2 : ShowAndGetImage
  174.         - 3 : ShowAndGetWriteableDirectory
  175.     """
  176.     dialog = xbmcgui.Dialog()
  177.     value = dialog.browse( dlg_type, heading, shares, mask, use_thumbs, treat_as_folder, default )
  178.     return value
  179.  
  180. def LOG( status, _class_, format, *args ):
  181.     if ( DEBUG_MODE >= status ):
  182.         _function_ = "(%s) %s::%s" % ( sys._getframe( 1 ).f_code.co_filename, _class_, sys._getframe( 1 ).f_code.co_name, )
  183.         xbmc.output( "%s: %s - %s\n" % ( ( "ERROR", "INFO", "NOTICE", "DEBUG", )[ status - 1 ], _function_, format % args, ) )
  184.  
  185. def get_custom_sql():
  186.     try:
  187.         query = ""
  188.         file_object = open( os.path.join( BASE_DATA_PATH, "custom.sql" ), "r" )
  189.         query = file_object.read()
  190.         file_object.close()
  191.     except:
  192.         pass
  193.     return query
  194.  
  195. def save_custom_sql( query ):
  196.     try:
  197.         file_object = open( os.path.join( BASE_DATA_PATH, "custom.sql" ), "w" )
  198.         file_object.write( query )
  199.         file_object.close()
  200.         return True
  201.     except:
  202.         return False
  203.  
  204. def make_legal_filepath( path, compatible=False, extension=True, conf=True, save_end=False ):
  205.     # xbox, win32 and linux have different filenaming requirements
  206.     environment = os.environ.get( "OS", "xbox" )
  207.     # first we normalize the path (win32 and xbox support / as path separators)
  208.     if ( environment == "win32" or environment == "xbox" ):
  209.         path = path.replace( "\\", "/" )
  210.     # split our drive letter
  211.     drive, tail = os.path.splitdrive( path )
  212.     # split the rest of the path
  213.     parts = tail.split( "/" )
  214.     # if this is a linux path and compatible is true set the drive
  215.     if ( not drive and parts[ 0 ].endswith( ":" ) and len( parts[ 0 ] ) == 2 and compatible ):
  216.         drive = parts[ 0 ]
  217.         parts[ 0 ] = ""
  218.     # here is where we make the filepath valid
  219.     if ( environment == "xbox" or environment == "win32" or compatible ):
  220.         # win32 and xbox invalid characters
  221.         illegal_characters = """,*=|<>?;:"+"""
  222.         # enumerate through and make each part valid
  223.         for count, part in enumerate( parts ):
  224.             tmp_name = ""
  225.             for char in part:
  226.                 # if char's ord() value is > 127 or an illegal character remove it
  227.                 if ( char in illegal_characters or ord( char ) > 127 ): char = ""
  228.                 tmp_name += char
  229.             if ( environment == "xbox" or compatible ):
  230.                 # we need to trim the part if it's larger than 42, we need to account for ".conf"
  231.                 if ( len( tmp_name ) > 42 - ( conf * 5 ) ):
  232.                     # special handling of the last part with extension
  233.                     if ( count == len( parts ) - 1 and extension == True ):
  234.                         # split the part into filename and extention
  235.                         filename, ext = os.path.splitext( tmp_name )
  236.                         # do we need to save the last two characters of the part for file number (eg _1, _2...)
  237.                         if ( save_end ):
  238.                             tmp_name = filename[ : 35 - len( ext ) ] + filename[ -2 : ]
  239.                         else:
  240.                             tmp_name = filename[ : 37 - len( ext ) ]
  241.                         tmp_name = "%s%s" % ( tmp_name.strip(), ext )
  242.                     # not the last part so just trim the length
  243.                     else:
  244.                         tmp_name = tmp_name[ : 42 ].strip()
  245.             # add our validated part to our list
  246.             parts[ count ] = tmp_name
  247.     # join the parts into a valid path, we use forward slash to remain os neutral
  248.     filepath = drive + "/".join( parts )
  249.     # win32 needs to be encoded to utf-8
  250.     if ( environment == "win32" ):
  251.         return filepath.encode( "utf-8" )
  252.     else:
  253.         return filepath
  254.  
  255.  
  256. class Settings:
  257.     def get_settings( self, defaults=False ):
  258.         """ read settings """
  259.         try:
  260.             settings = {}
  261.             if ( defaults ): raise
  262.             settings_file = open( BASE_SETTINGS_PATH, "r" )
  263.             settings = eval( settings_file.read() )
  264.             settings_file.close()
  265.             if ( settings[ "version" ] not in SETTINGS_VERSIONS ):
  266.                 raise
  267.         except:
  268.             settings = self._use_defaults( settings, save=( defaults == False ) )
  269.         return settings
  270.  
  271.     def _use_defaults( self, current_settings=None, save=True ):
  272.         """ setup default values if none obtained """
  273.         LOG( LOG_NOTICE, self.__class__.__name__, "[used default settings]" )
  274.         settings = {}
  275.         defaults = {  
  276.             "skin": "Default",
  277.             "trailer_quality": 2,
  278.             "mode": 0,
  279.             "save_folder": xbmc.translatePath( "special://profile/" ),
  280.             "thumbnail_display": 0,
  281.             "fade_thumb": True,
  282.             "startup_category_id": 10,
  283.             "shortcut1": 10,
  284.             "shortcut2": RECENTLY_ADDED,
  285.             "shortcut3": FAVORITES,
  286.             "refresh_newest": False,
  287.             "videoplayer_displayresolution": 10,
  288.             "use_simple_search": True,
  289.             "match_whole_words": False,
  290.             "showtimes_local": "33102",
  291.             "showtimes_scraper": "Google",
  292.             "auto_play_all": False,
  293.             "refresh_trailers": False,
  294.             }
  295.         for key, value in defaults.items():
  296.             # add default values for missing settings
  297.             settings[ key ] = current_settings.get( key, defaults[ key ] )
  298.         settings[ "version" ] = __version__
  299.         if ( save ):
  300.             ok = self.save_settings( settings )
  301.         return settings
  302.  
  303.     def save_settings( self, settings ):
  304.         """ save settings """
  305.         try:
  306.             settings_file = open( BASE_SETTINGS_PATH, "w" )
  307.             settings_file.write( repr( settings ) )
  308.             settings_file.close()
  309.             return True
  310.         except:
  311.             LOG( LOG_ERROR, "%s (rev: %s) %s::%s (%d) [%s]", __scriptname__, __svn_revision__, self.__class__.__name__, sys.exc_info()[ 2 ].tb_frame.f_code.co_name, sys.exc_info()[ 2 ].tb_lineno, sys.exc_info()[ 1 ], )
  312.             return False
  313.