#!/usr/bin/env python3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  argparse 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  json 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  os 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  pathlib 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  xml . etree . ElementTree  as  ET 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  typing  import  cast 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  requests 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TRANSLATIONS_DIR  =  pathlib . Path ( __file__ ) . resolve ( ) . parent 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TRANSLATIONS_LANGUAGES  =  TRANSLATIONS_DIR  /  " languages.json " 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OPENAI_MODEL  =  " gpt-4 " 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OPENAI_API_KEY  =  os . environ . get ( " OPENAI_API_KEY " ) 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								OPENAI_PROMPT  =  " You are a professional translator from English to  {language}  (ISO 639 language code).  "  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                " The following sentence or word is in the GUI of a software called openpilot, translate it accordingly. " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  get_language_files ( languages :  list [ str ]  =  None )  - >  dict [ str ,  pathlib . Path ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  files  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with  open ( TRANSLATIONS_LANGUAGES )  as  fp : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    language_dict  =  json . load ( fp ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  filename  in  language_dict . values ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      path  =  TRANSLATIONS_DIR  /  f " { filename } .ts " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      language  =  path . stem . split ( " main_ " ) [ 1 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  languages  is  None  or  language  in  languages : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        files [ language ]  =  path 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  files 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  translate_phrase ( text :  str ,  language :  str )  - >  str : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  response  =  requests . post ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " https://api.openai.com/v1/chat/completions " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    json = { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      " model " :  OPENAI_MODEL , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      " messages " :  [ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " role " :  " system " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " content " :  OPENAI_PROMPT . format ( language = language ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " role " :  " user " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " content " :  text , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      " temperature " :  0.8 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      " max_tokens " :  1024 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      " top_p " :  1 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    headers = { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      " Authorization " :  f " Bearer  { OPENAI_API_KEY } " , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      " Content-Type " :  " application/json " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  400  < =  response . status_code  <  600 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  requests . HTTPError ( f ' Error  { response . status_code } :  { response . json ( ) } ' ,  response = response ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  data  =  response . json ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  cast ( str ,  data [ " choices " ] [ 0 ] [ " message " ] [ " content " ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  translate_file ( path :  pathlib . Path ,  language :  str ,  all_ :  bool )  - >  None : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tree  =  ET . parse ( path ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  root  =  tree . getroot ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  context  in  root . findall ( " ./context " ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    name  =  context . find ( " name " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  name  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      raise  ValueError ( " name not found " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( f " Context:  { name . text } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  message  in  context . findall ( " ./message " ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      source  =  message . find ( " source " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      translation  =  message . find ( " translation " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  source  is  None  or  translation  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        raise  ValueError ( " source or translation not found " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  not  all_  and  translation . attrib . get ( " type " )  !=  " unfinished " : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      llm_translation  =  translate_phrase ( cast ( str ,  source . text ) ,  language ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      print ( f " Source:  { source . text } \n "  + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f " Current translation:  { translation . text } \n "  + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            f " LLM translation:  { llm_translation } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      translation . text  =  llm_translation 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with  path . open ( " w " ,  encoding = " utf-8 " )  as  fp : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fp . write ( ' <?xml version= " 1.0 "  encoding= " utf-8 " ?> \n '  + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             ' <!DOCTYPE TS> \n '  + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								             ET . tostring ( root ,  encoding = " utf-8 " ) . decode ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  main ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  arg_parser  =  argparse . ArgumentParser ( " Auto translate " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  group  =  arg_parser . add_mutually_exclusive_group ( required = True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  group . add_argument ( " -a " ,  " --all-files " ,  action = " store_true " ,  help = " Translate all files " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  group . add_argument ( " -f " ,  " --file " ,  nargs = " + " ,  help = " Translate the selected files. (Example: -f fr de) " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  arg_parser . add_argument ( " -t " ,  " --all-translations " ,  action = " store_true " ,  default = False ,  help = " Translate all sections. (Default: only unfinished) " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  args  =  arg_parser . parse_args ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  OPENAI_API_KEY  is  None : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( " OpenAI API key is missing. (Hint: use `export OPENAI_API_KEY=YOUR-KEY` before you run the script). \n "  + 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          " If you don ' t have one go to: https://beta.openai.com/account/api-keys. " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    exit ( 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  files  =  get_language_files ( None  if  args . all_files  else  args . file ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  args . file : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    missing_files  =  set ( args . file )  -  set ( files ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  len ( missing_files ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( f " No language files found:  { missing_files } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      exit ( 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( f " Translation mode:  { ' all '  if  args . all_translations  else  ' only unfinished ' } . Files:  { list ( files ) } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  lang ,  path  in  files . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( f " Translate  { lang }  ( { path } ) " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    translate_file ( path ,  lang ,  args . all_translations ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  main ( )