@ -1,13 +1,16 @@ 
			
		
	
		
			
				
					#!/usr/bin/env python3  
			
		
	
		
			
				
					import  argparse  
			
		
	
		
			
				
					from  collections  import  defaultdict  
			
		
	
		
			
				
					import  difflib  
			
		
	
		
			
				
					import  pickle  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					from  selfdrive . car . docs  import  get_all_car_info  
			
		
	
		
			
				
					from  selfdrive . car . docs_definitions  import  Column  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					FOOTNOTE_TAG  =  " <sup> {} </sup> "  
			
		
	
		
			
				
					STAR_ICON  =  ' <a href= " ## " ><img valign= " top "  src= " https://raw.githubusercontent.com/commaai/openpilot/master/docs/assets/icon-star- {} .svg "  width= " 22 "  /></a> '  
			
		
	
		
			
				
					COLUMNS  =  " | "  +  " | " . join ( [ column . value  for  column  in  Column ] )  +  " | "  
			
		
	
		
			
				
					COLUMN_HEADER  =  " |---|---|---|:---:|:---:|:---:|:---:|:---:|  "  
			
		
	
		
			
				
					COLUMN_HEADER  =  " |---|---|---|:---:|:---:|:---:|:---:| "  
			
		
	
		
			
				
					ARROW_SYMBOL  =  " ➡️  "  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -16,69 +19,84 @@ def load_base_car_info(path): 
			
		
	
		
			
				
					    return  pickle . load ( f )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					def  get_star_diff ( base_car ,  new_car ) :  
			
		
	
		
			
				
					  return  [ column  for  column ,  value  in  base_car . row . items ( )  if  value  !=  new_car . row [ column ] ]   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					def  match_cars ( base_cars ,  new_cars ) :  
			
		
	
		
			
				
					  """ Matches CarInfo by name similarity and finds additions and removals """   
			
		
	
		
			
				
					  changes  =  [ ]   
			
		
	
		
			
				
					  additions  =  [ ]   
			
		
	
		
			
				
					  for  new  in  new_cars :   
			
		
	
		
			
				
					    closest_match  =  difflib . get_close_matches ( new . name ,  [ b . name  for  b  in  base_cars ] ,  cutoff = 0. ) [ 0 ]   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					def  format_row ( builder ) :  
			
		
	
		
			
				
					  return  " | "  +  " | " . join ( builder )  +  " | "   
			
		
	
		
			
				
					    if  closest_match  not  in  [ c [ 1 ] . name  for  c  in  changes ] :   
			
		
	
		
			
				
					      changes . append ( ( new ,  next ( car  for  car  in  base_cars  if  car . name  ==  closest_match ) ) )   
			
		
	
		
			
				
					    else :   
			
		
	
		
			
				
					      additions . append ( new )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  removals  =  [ b  for  b  in  base_cars  if  b . name  not  in  [ c [ 1 ] . name  for  c  in  changes ] ]   
			
		
	
		
			
				
					  return  changes ,  additions ,  removals   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					def  print_car_info_diff ( path ) :  
			
		
	
		
			
				
					  base_car_info  =  { f " { i . make }   { i . model } " :  i  for  i  in  load_base_car_info ( path ) }   
			
		
	
		
			
				
					  new_car_info  =  { f " { i . make }   { i . model } " :  i  for  i  in  get_all_car_info ( ) }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  tier_changes  =  [ ]   
			
		
	
		
			
				
					  star_changes  =  [ ]   
			
		
	
		
			
				
					  removals  =  [ ]   
			
		
	
		
			
				
					  additions  =  [ ]   
			
		
	
		
			
				
					def  build_column_diff ( base_car ,  new_car ) :  
			
		
	
		
			
				
					  row_builder  =  [ ]   
			
		
	
		
			
				
					  for  column  in  Column :   
			
		
	
		
			
				
					    base_column  =  base_car . get_column ( column ,  STAR_ICON ,  FOOTNOTE_TAG )   
			
		
	
		
			
				
					    new_column  =  new_car . get_column ( column ,  STAR_ICON ,  FOOTNOTE_TAG )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  # Changes (tier + stars)   
			
		
	
		
			
				
					  for  base_car_model ,  base_car  in  base_car_info . items ( ) :   
			
		
	
		
			
				
					    if  base_car_mod el not  in  n ew_car_info  :   
			
		
	
		
			
				
					      continue   
			
		
	
		
			
				
					    if  base_column  !=  new_column :    
			
		
	
		
			
				
					      row_builder . append ( f " { base_column }   { ARROW_SYMBOL }   { new_column } " )    
			
		
	
		
			
				
					    els e :   
			
		
	
		
			
				
					      row_builder . append ( new_column )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    new_car  =  new_car_info [ base_car_model ]    
			
		
	
		
			
				
					  return  format_row ( row_builder )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # Tier changes   
			
		
	
		
			
				
					    if  base_car . tier  !=  new_car . tier :   
			
		
	
		
			
				
					      tier_changes . append ( f " - Tier for  { base_car . make }   { base_car . model }  changed! ( { base_car . tier . name . title ( ) }   { ARROW_SYMBOL }   { new_car . tier . name . title ( ) } ) " )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # Star changes   
			
		
	
		
			
				
					    diff  =  get_star_diff ( base_car ,  new_car )   
			
		
	
		
			
				
					    if  not  len ( diff ) :   
			
		
	
		
			
				
					      continue   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    row_builder  =  [ ]   
			
		
	
		
			
				
					    for  column  in  list ( Column ) :   
			
		
	
		
			
				
					      if  column  not  in  diff :   
			
		
	
		
			
				
					        row_builder . append ( new_car . get_column ( column ,  STAR_ICON ,  " {} " ) )   
			
		
	
		
			
				
					      else :   
			
		
	
		
			
				
					        row_builder . append ( base_car . get_column ( column ,  STAR_ICON ,  " {} " )  +  ARROW_SYMBOL  +  new_car . get_column ( column ,  STAR_ICON ,  " {} " ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    star_changes . append ( format_row ( row_builder ) )   
			
		
	
		
			
				
					def  format_row ( builder ) :  
			
		
	
		
			
				
					  return  " | "  +  " | " . join ( builder )  +  " | "   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  # Removals   
			
		
	
		
			
				
					  for  model  in  set ( base_car_info )  -  set ( new_car_info ) :   
			
		
	
		
			
				
					    car_info  =  base_car_info [ model ]   
			
		
	
		
			
				
					    removals . append ( format_row ( [ car_info . get_column ( column ,  STAR_ICON ,  " {} " )  for  column  in  Column ] ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  # Additions   
			
		
	
		
			
				
					  for  model  in  set ( new_car_info )  -  set ( base_car_info ) :   
			
		
	
		
			
				
					    car_info  =  new_car_info [ model ]   
			
		
	
		
			
				
					    additions . append ( format_row ( [ car_info . get_column ( column ,  STAR_ICON ,  " {} " )  for  column  in  Column ] ) )   
			
		
	
		
			
				
					def  print_car_info_diff ( path ) :  
			
		
	
		
			
				
					  base_car_info  =  defaultdict ( list )   
			
		
	
		
			
				
					  new_car_info  =  defaultdict ( list )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  for  car  in  load_base_car_info ( path ) :   
			
		
	
		
			
				
					    base_car_info [ car . car_fingerprint ] . append ( car )   
			
		
	
		
			
				
					  for  car  in  get_all_car_info ( ) :   
			
		
	
		
			
				
					    new_car_info [ car . car_fingerprint ] . append ( car )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  changes  =  defaultdict ( list )   
			
		
	
		
			
				
					  for  base_car_model ,  base_cars  in  base_car_info . items ( ) :   
			
		
	
		
			
				
					    # Match car info changes, and get additions and removals   
			
		
	
		
			
				
					    new_cars  =  new_car_info [ base_car_model ]   
			
		
	
		
			
				
					    car_changes ,  car_additions ,  car_removals  =  match_cars ( base_cars ,  new_cars )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # Removals   
			
		
	
		
			
				
					    for  car_info  in  car_removals :   
			
		
	
		
			
				
					      changes [ " removals " ] . append ( format_row ( [ car_info . get_column ( column ,  STAR_ICON ,  FOOTNOTE_TAG )  for  column  in  Column ] ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    # Additions   
			
		
	
		
			
				
					    for  car_info  in  car_additions :   
			
		
	
		
			
				
					      changes [ " additions " ] . append ( format_row ( [ car_info . get_column ( column ,  STAR_ICON ,  FOOTNOTE_TAG )  for  column  in  Column ] ) )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    for  new_car ,  base_car  in  car_changes :   
			
		
	
		
			
				
					      # Tier changes   
			
		
	
		
			
				
					      if  base_car . tier  !=  new_car . tier :   
			
		
	
		
			
				
					        changes [ " tier " ] . append ( f " - Tier for  { base_car . make }   { base_car . model }  changed! ( { base_car . tier . name . title ( ) }   { ARROW_SYMBOL }   { new_car . tier . name . title ( ) } ) " )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					      # Column changes   
			
		
	
		
			
				
					      row_diff  =  build_column_diff ( base_car ,  new_car )   
			
		
	
		
			
				
					      if  ARROW_SYMBOL  in  row_diff :   
			
		
	
		
			
				
					        changes [ " column " ] . append ( row_diff )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  # Print diff   
			
		
	
		
			
				
					  if  len ( star_changes )  or  len ( tier_changes )  or  len ( removals )  or  len ( additions ) :   
			
		
	
		
			
				
					  if  any ( len ( c )  for  c  in  changes . values ( ) ) :   
			
		
	
		
			
				
					    markdown_builder  =  [ " ### ⚠️ ️  " ]   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    for  title ,  category  in  ( ( " ## 🏅 Tier Changes " ,  tier_changes ) ,  ( " ## 🔀 Star Changes " ,  star_changes ) ,  ( " ## ❌ Removed " ,  removals ) ,  ( " ## ➕ Added " ,  additions ) ) :   
			
		
	
		
			
				
					      if  len ( category ) :   
			
		
	
		
			
				
					    for  title ,  category  in  ( ( " ## 🏅 Tier Changes " ,  " tier " ) ,  ( " ## 🔀 Column Changes " ,  " column "  ) ,  ( " ## ❌ Removed " ,  " " ) ,  ( " ## ➕ Added " ,  " " ) ) :   
			
		
	
		
			
				
					      if  len ( changes [ c ategory ] ) :   
			
		
	
		
			
				
					        markdown_builder . append ( title )   
			
		
	
		
			
				
					        if  " Tier "  not  in  title :   
			
		
	
		
			
				
					          markdown_builder . append ( COLUMNS )   
			
		
	
		
			
				
					          markdown_builder . append ( COLUMN_HEADER )   
			
		
	
		
			
				
					        markdown_builder . extend ( category )   
			
		
	
		
			
				
					        markdown_builder . extend ( changes [ c ategory ] )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    print ( " \n " . join ( markdown_builder ) )