Advertisement
Ftagn92

Recalbox Favoris

May 13th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 19.35 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Mon May 14 01:17:02 2018
  4.  
  5. @author: Sandro
  6. """
  7.  
  8. #Imports
  9. import sys, os, shutil, re
  10. import xml.etree.cElementTree as ET
  11. import hashlib
  12. import datetime, time
  13. def main():
  14.     if len(sys.argv) < 5:
  15.         '''
  16.        Je vérifie la présence des paramètres obligatoires
  17.        1. Répertoire des ROMS (chemin réseau accepté, exemple \\RECALBOX\SHARE\ROMS)
  18.        2. Action
  19.                backup : sauve les favoris en local
  20.                restore : recrée chaque fichier gamelist (toujours en local) avec les favoris correctement flagués
  21.        3. Liste des sections à sauvegarder / restaurer, en une seule chaîne, délimiteurs inutiles
  22.                favorite
  23.                hidden
  24.                playcount
  25.                lastplayed
  26.                Exemple : hidden_playcount, favoritehidden, lastplayed___hidden___playcount_favorite, etc
  27.        4. hash : Hashing des roms pour plus de sécurité / nohash : Pas de hashing (pratique pour des packs de roms dans d'autres langue ou de version différente)
  28.        5. En local ou en REMOTE (écrase ou pas les gamelist de la recalbox). Par défaut en local
  29.        '''
  30.         print("Usage: {} <path to ROMS directory> <backup/restore> <section1_section2_etc> <hash/nohash>".format(sys.argv[0]))
  31.         print("Example :  {} \\RECALBOX\SHARE\ROMS backup favorite_hidden_playcount_lastplayed hash".format(sys.argv[0]))
  32.         print("Example :  {} \\RECALBOX\SHARE\ROMS restore favorite_hidden hash".format(sys.argv[0]))
  33.         print("Example :  {} \\RECALBOX\SHARE\ROMS restore favorite nohash".format(sys.argv[0]))
  34.         print("Add REMOTE to write gamelists to the recalbox (existing gamelists will be renamed and timestamped)")
  35.         print("REMOTE is accepted only with restore action")
  36.         print("Use REMOTE at your own risk.")
  37.         exit()
  38.     #Initialisation
  39.     path_roms = sys.argv[1]
  40.     action = sys.argv[2]
  41.     sections = sys.argv[3]
  42.     hashing = sys.argv[4]
  43.     try:
  44.         remote = sys.argv[5]
  45.     except:
  46.         remote = 'local'
  47.     str_MD5 = ''
  48.     if ((hashing.find('hash') == -1) and (hashing.find('nohash') == -1)):
  49.         print("Wrong hashing parameter :  only accept hash or nohash")
  50.         exit()
  51.     #Quelles sections on traite ?
  52.     backup_favorite = (sections.find('favorite') > -1)
  53.     backup_hidden = (sections.find('hidden') > -1)
  54.     backup_playcount = (sections.find('playcount') > -1)
  55.     backup_lastplayed = (sections.find('lastplayed') > -1)
  56.     if action == "backup":
  57.         for chemin in os.listdir(path_roms):
  58.             if os.path.isfile(path_roms+'/'+chemin)==False:
  59.                 if os.path.exists(path_roms+'/'+chemin+'/gamelist.xml')==True:
  60.                     print(path_roms+'/'+chemin)
  61.                     if os.path.exists('./'+chemin)==False:
  62.                         os.mkdir('./'+chemin)
  63.                     #favorite
  64.                     if backup_favorite:
  65.                         if os.path.exists('./'+chemin+'/favoris.txt')==True:
  66.                             os.remove('./'+chemin+'/favoris.txt')
  67.                     #hidden
  68.                     if backup_hidden:
  69.                         if os.path.exists('./'+chemin+'/hidden.txt')==True:
  70.                             os.remove('./'+chemin+'/hidden.txt')
  71.                     #playcount
  72.                     if backup_playcount:
  73.                         if os.path.exists('./'+chemin+'/playcount.txt')==True:
  74.                             os.remove('./'+chemin+'/playcount.txt')
  75.                     #lastplayed
  76.                     if backup_lastplayed:
  77.                         if os.path.exists('./'+chemin+'/lastplayed.txt')==True:
  78.                             os.remove('./'+chemin+'/lastplayed.txt')                        
  79.                     tree = ET.parse(path_roms+'/'+chemin+'/gamelist.xml')
  80.                     racine = tree.getroot()
  81.                     for jeu in racine:
  82.                         fav_yes_no = ''
  83.                         nom_jeu = ''
  84.                         lastplayed = ''
  85.                         playcount = ''
  86.                         hidden = ''
  87.                         MD5_OK = False
  88.                         backup = False
  89.                         for cherche_nom in jeu:
  90.                             #Premier passage pour le nom
  91.                             if cherche_nom.tag == 'path':
  92.                                 nom_jeu = cherche_nom.text
  93.                         for element in jeu:
  94.                             #2eme passage pour les données à sauvegarder
  95.                             if backup_favorite == True:
  96.                                 if element.tag == 'favorite':
  97.                                     fav_yes_no = element.text
  98.                                     if fav_yes_no == 'true':
  99.                                         print("- favorite")
  100.                                         if MD5_OK == False:
  101.                                             #On ne calcule le hash qu'une fois
  102.                                             str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  103.                                             MD5_OK = True
  104.                                         with open('./'+chemin+"/favoris.txt", "a") as myfile:
  105.                                             myfile.write(str_MD5+'\t'+nom_jeu+'\n')
  106.                                         backup = True
  107.                             if backup_hidden == True:
  108.                                 if element.tag == 'hidden':
  109.                                     hidden = element.text
  110.                                     if hidden == 'true':
  111.                                         print("- hidden")
  112.                                         if MD5_OK == False:
  113.                                             #On ne calcule le hash qu'une fois
  114.                                             str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  115.                                             MD5_OK = True
  116.                                         with open('./'+chemin+"/hidden.txt", "a") as myfile:
  117.                                             myfile.write(str_MD5+'\t'+nom_jeu+'\n')
  118.                                         backup = True
  119.                             if backup_playcount == True:
  120.                                 if element.tag == 'playcount':
  121.                                     playcount = element.text
  122.                                     print("- playcount: "+str(playcount))
  123.                                     if MD5_OK == False:
  124.                                         #On ne calcule le hash qu'une fois
  125.                                         str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  126.                                         MD5_OK = True
  127.                                     with open('./'+chemin+"/playcount.txt", "a") as myfile:
  128.                                         myfile.write(str_MD5+'\t'+playcount+'\t'+nom_jeu+'\n')
  129.                                     backup = True
  130.                             if backup_lastplayed == True:
  131.                                 if element.tag == 'lastplayed':
  132.                                     lastplayed = element.text
  133.                                     print("- lastplayed: "+str(lastplayed))
  134.                                     if MD5_OK == False:
  135.                                         #On ne calcule le hash qu'une fois
  136.                                         str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  137.                                         MD5_OK = True
  138.                                     with open('./'+chemin+"/lastplayed.txt", "a") as myfile:
  139.                                         myfile.write(str_MD5+'\t'+lastplayed+'\t'+nom_jeu+'\n')
  140.                                     backup = True
  141.                         if backup == True:
  142.                             print(str_MD5+'\t'+nom_jeu)
  143.                             print('-'*32)
  144.     if action == "restore":
  145.         for chemin in os.listdir('.'):
  146.                 if os.path.isfile('./'+chemin)==False:
  147.                     #C'est un répertoire de sauvegarde
  148.                     if os.path.exists(path_roms+'/'+chemin+'/gamelist.xml')==True:
  149.                         #On rapatrie la gamelist de la recalbox pour faire les modifs
  150.                         if os.path.exists('./'+chemin+'/gamelist.xml')==True:
  151.                             #On supprime un essai précédent s'il existe
  152.                             os.remove('./'+chemin+'/gamelist.xml')
  153.                         shutil.copyfile(path_roms+'/'+chemin+'/gamelist.xml', './'+chemin+'/gamelist.xml')
  154.                         print('./'+chemin+'/gamelist.xml')
  155.                         tree = ET.parse(path_roms+'/'+chemin+'/gamelist.xml')
  156.                         racine = tree.getroot()
  157.                         for jeu in racine:
  158.                             restore = False
  159.                             MD5_OK = False
  160.                             nom_jeu = ''
  161.                             for cherche_nom in jeu:
  162.                                 if cherche_nom.tag == 'path':
  163.                                     nom_jeu = cherche_nom.text
  164.                             #favorite
  165.                             if backup_favorite:
  166.                                 if os.path.exists('./'+chemin+'/favoris.txt')==True:
  167.                                     #On a des favoris sauvegardés
  168.                                     with open('./'+chemin+'/favoris.txt') as f:
  169.                                         favoris = f.readlines()
  170.                                     bingo = False
  171.                                     for ligne in favoris:  
  172.                                         if ligne.find('\t'+nom_jeu+'\n') > -1:
  173.                                             #Le jeu est retenu
  174.                                             str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  175.                                             MD5_OK = True
  176.                                             if ligne == (str_MD5+'\t'+nom_jeu+'\n'):
  177.                                                 bingo = True
  178.                                                 break
  179.                                     if bingo == True:
  180.                                         #Pour chaque jeu retenu
  181.                                         print("- favorite")
  182.                                         restore = True
  183.                                         restore_favorite = False
  184.                                         for element in jeu:
  185.                                             if element.tag == 'favorite':
  186.                                                 #il y a déjà une section favorite
  187.                                                 restore_favorite = True
  188.                                                 if element.text == 'false':
  189.                                                     #On l'update
  190.                                                     element.text = 'true'
  191.                                                 break
  192.                                         if restore_favorite == False:
  193.                                             #Il n'y avait pas de section favorite, on la crée
  194.                                             favori  = ET.SubElement(jeu,"favorite")
  195.                                             favori.text = "true"
  196.                             #hidden
  197.                             if backup_hidden:
  198.                                 if os.path.exists('./'+chemin+'/hidden.txt')==True:
  199.                                     #On a des jeux cachés sauvegardés
  200.                                     with open('./'+chemin+'/hidden.txt') as f:
  201.                                         hidden = f.readlines()
  202.                                     bingo = False
  203.                                     for ligne in hidden:  
  204.                                         if ligne.find('\t'+nom_jeu+'\n') > -1:
  205.                                             #Le jeu est retenu
  206.                                             str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  207.                                             MD5_OK = True
  208.                                             if ligne == (str_MD5+'\t'+nom_jeu+'\n'):
  209.                                                 bingo = True
  210.                                                 break
  211.                                     if bingo == True:
  212.                                         #Pour chaque jeu retenu
  213.                                         print("- hidden")
  214.                                         restore = True
  215.                                         restore_hidden = False
  216.                                         for element in jeu:
  217.                                             if element.tag == 'hidden':
  218.                                                 #il y a déjà une section hidden
  219.                                                 restore_hidden = True
  220.                                                 if element.text == 'false':
  221.                                                     #On l'update
  222.                                                     element.text = 'true'
  223.                                                 break
  224.                                         if restore_hidden == False:
  225.                                             #Il n'y avait pas de section hidden, on la crée
  226.                                             cache  = ET.SubElement(jeu,"hidden")
  227.                                             cache.text = "true"
  228.                             #playcount
  229.                             if backup_playcount:
  230.                                 if os.path.exists('./'+chemin+'/playcount.txt')==True:
  231.                                     #On a des compteurs sauvegardés
  232.                                     with open('./'+chemin+'/playcount.txt') as f:
  233.                                         playcount = f.readlines()
  234.                                     bingo = False
  235.                                     total = 0
  236.                                     for ligne in playcount:  
  237.                                         if ligne.find('\t'+nom_jeu+'\n') > -1:
  238.                                             #Le jeu est retenu
  239.                                             str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  240.                                             MD5_OK = True
  241.                                             if ligne[:32] == (str_MD5):
  242.                                                 liste = re.split(r'\t+', ligne)
  243.                                                 total = liste[1]
  244.                                                 print("- playcount : " + total)
  245.                                                 bingo = True
  246.                                                 break
  247.                                     if bingo == True:
  248.                                         #Pour chaque jeu retenu
  249.                                         restore = True
  250.                                         restore_playcount = False
  251.                                         for element in jeu:
  252.                                             if element.tag == 'playcount':
  253.                                                 #il y a déjà une section playcount
  254.                                                 restore_playcount = True
  255.                                                 #On l'update
  256.                                                 element.text = total
  257.                                                 break
  258.                                         if restore_playcount == False:
  259.                                             #Il n'y avait pas de section playcount, on la crée
  260.                                             compte  = ET.SubElement(jeu,"playcount")
  261.                                             compte.text = total
  262.                             #lastplayed
  263.                             if backup_lastplayed:
  264.                                 if os.path.exists('./'+chemin+'/lastplayed.txt')==True:
  265.                                     #On a des timestamp sauvegardés
  266.                                     with open('./'+chemin+'/lastplayed.txt') as f:
  267.                                         lastplayed = f.readlines()
  268.                                     bingo = False
  269.                                     temps = 0
  270.                                     for ligne in lastplayed:  
  271.                                         if ligne.find('\t'+nom_jeu+'\n') > -1:
  272.                                             #Le jeu est retenu
  273.                                             str_MD5 = calcul_MD5(path_roms+'/'+chemin+'/'+nom_jeu, hashing)
  274.                                             MD5_OK = True
  275.                                             if ligne[:32] == (str_MD5):
  276.                                                 liste = re.split(r'\t+', ligne)
  277.                                                 temps = liste[1]
  278.                                                 print("- lastplayed : " + temps)
  279.                                                 bingo = True
  280.                                                 break
  281.                                     if bingo == True:
  282.                                         #Pour chaque jeu retenu
  283.                                         restore = True
  284.                                         restore_lastplayed = False
  285.                                         for element in jeu:
  286.                                             if element.tag == 'lastplayed':
  287.                                                 #il y a déjà une section lastplayed
  288.                                                 restore_lastplayed = True
  289.                                                 #On l'update
  290.                                                 element.text = temps
  291.                                                 break
  292.                                         if restore_lastplayed == False:
  293.                                             #Il n'y avait pas de section lastplayed, on la crée
  294.                                             compte  = ET.SubElement(jeu,"lastplayed")
  295.                                             compte.text = temps
  296.                             if restore == True:
  297.                                 print(str_MD5+'\t'+nom_jeu)
  298.                                 print('-'*32)
  299.                         tree.write(open('./'+chemin+'/gamelist.xml', 'wb'),encoding="UTF-8",xml_declaration=True)
  300.                         if remote == 'REMOTE':
  301.                             ts = time.time()
  302.                             st = datetime.datetime.fromtimestamp(ts).strftime('_%Y%m%d_%H%M%S_')
  303.                             os.rename(path_roms+'/'+chemin+'/gamelist.xml',path_roms+'/'+chemin+'/gamelist_'+st+'.xml')
  304.                             shutil.copyfile('./'+chemin+'/gamelist.xml', path_roms+'/'+chemin+'/gamelist.xml')
  305.                             print('gamelist.xml -> '+ path_roms+'/'+chemin+'/gamelist.xml')
  306.                                                
  307. def calcul_MD5(chemin, hash_ou_pas):
  308.     BUF_SIZE = 65536
  309.     if hash_ou_pas == 'hash':
  310.         try:
  311.             md5 = hashlib.md5()
  312.             with open(chemin, 'rb') as f:
  313.                 while True:
  314.                     data = f.read(BUF_SIZE)
  315.                     if not data:
  316.                         break
  317.                     md5.update(data)
  318.             MD5_final = md5.hexdigest()
  319.         except:
  320.             print('ROM absente : '+ chemin)
  321.             MD5_final = '00000000000000000000000000000000'
  322.     else:
  323.         MD5_final = '00000000000000000000000000000000'
  324.     return MD5_final
  325.  
  326. if __name__ == "__main__":
  327.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement