1111import  sys 
1212
1313__author__  =  "Foxlet" 
14- __copyright__  =  "Copyright 2018 , FurCode Project" 
14+ __copyright__  =  "Copyright 2019 , FurCode Project" 
1515__license__  =  "GPLv3" 
16- __version__  =  "1.2 " 
16+ __version__  =  "1.3 " 
1717
1818logging .basicConfig (format = '%(asctime)-15s %(message)s' , level = logging .INFO )
1919logger  =  logging .getLogger ('webactivity' )
@@ -50,11 +50,13 @@ def check_directory(path):
5050
5151
5252class  SoftwareService :
53-  # macOS 10.14 ships  in 4 different catalogs from SoftwareScan 
53+  # macOS 10.15 is available  in 4 different catalogs from SoftwareScan 
5454 catalogs  =  {"CustomerSeed" :"https://swscan.apple.com/content/catalogs/others/index-10.15customerseed-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" ,
5555 "DeveloperSeed" :"https://swscan.apple.com/content/catalogs/others/index-10.15seed-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" ,
5656 "PublicSeed" :"https://swscan.apple.com/content/catalogs/others/index-10.15beta-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" ,
57-  "PublicRelease" :"https://swscan.apple.com/content/catalogs/others/index-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" }
57+  "PublicRelease" :"https://swscan.apple.com/content/catalogs/others/index-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" ,
58+  "PublicRelease14" :"https://swscan.apple.com/content/catalogs/others/index-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" ,
59+  "PublicRelease13" :"https://swscan.apple.com/content/catalogs/others/index-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog" }
5860
5961 def  __init__ (self , catalog_id ):
6062 self .catalog_url  =  self .catalogs .get (catalog_id , self .catalogs ["PublicRelease" ])
@@ -67,38 +69,42 @@ def getcatalog(self):
6769 return  catalog_raw .text .encode ('UTF-8' )
6870
6971 def  getosinstall (self ):
70-  if  (sys .version_info  >  (3 , 0 )):
71-  root  =  plistlib .readPlistFromBytes (self .catalog_data )
72+  # Load catalogs based on Py3/2 lib 
73+  if  sys .version_info  >  (3 , 0 ):
74+  root  =  plistlib .loads (self .catalog_data )
7275 else :
7376 root  =  plistlib .readPlistFromString (self .catalog_data )
77+ 
78+  # Iterate to find valid OSInstall packages 
79+  ospackages  =  []
7480 products  =  root ['Products' ]
7581 for  product  in  products :
76-  if  'ExtendedMetaInfo'  in  products [product ]:
77-  IAMetaInfo  =  products [product ]['ExtendedMetaInfo' ]
78-  if  'InstallAssistantPackageIdentifiers'  in  IAMetaInfo :
79-  IAPackageID  =  IAMetaInfo ['InstallAssistantPackageIdentifiers' ]
80-  if  IAPackageID ['OSInstall' ] ==  'com.apple.mpkg.OSInstall' :
81-  return  product 
82+  if  products .get (product , {}).get ('ExtendedMetaInfo' , {}).get ('InstallAssistantPackageIdentifiers' , {}).get ('OSInstall' , {}) ==  'com.apple.mpkg.OSInstall' :
83+  ospackages .append (product )
84+  return  ospackages 
8285
8386
8487class  MacOSProduct :
8588 def  __init__ (self , catalog , product_id ):
86-  if  ( sys .version_info  >  (3 , 0 ) ):
87-  root  =  plistlib .readPlistFromBytes (catalog )
89+  if  sys .version_info  >  (3 , 0 ):
90+  root  =  plistlib .loads (catalog )
8891 else :
8992 root  =  plistlib .readPlistFromString (catalog )
9093 products  =  root ['Products' ]
9194 self .date  =  root ['IndexDate' ]
9295 self .product  =  products [product_id ]
9396
94-  def  fetchpackages (self , path ):
97+  def  fetchpackages (self , path ,  keyword = None ):
9598 Filesystem .check_directory (path )
9699 packages  =  self .product ['Packages' ]
97-  for  item  in  packages :
98-  if  "BaseSystem"  in  item .get ("URL" ):
100+  if  keyword :
101+  for  item  in  packages :
102+  if  keyword  in  item .get ("URL" ):
103+  Filesystem .download_file (item .get ("URL" ), item .get ("Size" ), path )
104+  else :
105+  for  item  in  packages :
99106 Filesystem .download_file (item .get ("URL" ), item .get ("Size" ), path )
100107
101- 
102108@click .command () 
103109@click .option ('-o' , '--output-dir' , default = "BaseSystem/" , help = "Target directory for package output." ) 
104110@click .option ('-c' , '--catalog-id' , default = "PublicRelease" , help = "Name of catalog." ) 
@@ -109,23 +115,24 @@ def fetchmacos(output_dir="BaseSystem/", catalog_id="PublicRelease", product_id=
109115 remote  =  SoftwareService (catalog_id )
110116 catalog  =  remote .getcatalog ()
111117
112-  # Get  the current macOS  package 
118+  # If latest is used, find  the latest OSInstall  package 
113119 if  latest :
114-  product_id  =  remote .getosinstall ()
120+  product_id  =  remote .getosinstall ()[ - 1 ] 
115121 else :
116122 if  product_id  ==  "" :
117123 print ("You must provide a Product ID (or pass the -l flag) to continue." )
118124 exit (1 )
119-  product_id  =  product_id 
125+ 
126+  # Fetch the given Product ID 
120127 try :
121-  update  =  MacOSProduct (catalog , product_id )
128+  product  =  MacOSProduct (catalog , product_id )
122129 except  KeyError :
123130 print ("Product ID {} could not be found." .format (product_id ))
124131 exit (1 )
125132 logging .info ("Selected macOS Product: {}" .format (product_id ))
126133
127134 # Download package to disk 
128-  update .fetchpackages (output_dir )
135+  product .fetchpackages (output_dir ,  keyword = "BaseSystem" )
129136
130137if  __name__  ==  "__main__" :
131138 fetchmacos ()
0 commit comments