forked from grayaii/rom_cleaner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clean_roms.py
160 lines (144 loc) · 7.12 KB
/
clean_roms.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import os, sys, argparse
import operator
class ALL_ROMS():
def __init__(self, root_dir, delete):
self.root_dir = root_dir
self.delete = delete
self.roms = {}
def get_roms(self):
rom_list = 'roms.txt'
if os.path.exists(rom_list):
print('using cached list from: {}'.format(rom_list))
with open(rom_list, 'r') as fd:
game_list = [line.strip() for line in fd.readlines()]
else:
game_list = []
for dirname, dirnames, filenames in os.walk(self.root_dir):
# print path to all filenames.
for filename in filenames:
aFile = os.path.join(dirname, filename)
game_list.append(aFile)
with open(rom_list, 'w') as fd:
for f in game_list:
fd.write('{}\n'.format(f))
return game_list
def add_rom(self, rom_obj):
if rom_obj.stripped_filename not in self.roms:
self.roms[rom_obj.stripped_filename] = {}
self.roms[rom_obj.stripped_filename]['roms'] = []
self.roms[rom_obj.stripped_filename]['roms'].append(rom_obj)
def clean(self):
total_files = 0
for stripped_filename, roms in self.roms.items():
if len(roms['roms']) > 1:
print(stripped_filename)
have_marked = False
delete_txt = 'OK'
for r in sorted(roms['roms'], key=lambda x: x.weight, reverse=True):
total_files += 1
print('\t:{}:{}:{}'.format(delete_txt, r.weight, r.base_filename))
if have_marked is True and self.delete is True:
print('\tDeleting: {}'.format(r.full_path_filename))
os.remove(r.full_path_filename)
if have_marked is False:
have_marked = True
delete_txt = 'KO'
print('total unique files: {}'.format(len(self.roms)))
print('total files : {}'.format(total_files))
class Rom():
def __init__(self, full_path_filename):
# super mario (hack) (!).nes:
self.full_path_filename = full_path_filename
self.base_filename, \
self.stripped_filename, \
self.tokens, \
self.base_filename = self.describe_rom(full_path_filename)
self.weight = self.calculate_weight()
# Helper function:
def find(self, s, ch):
return [i for i, ltr in enumerate(s) if ltr == ch]
# Extraction tags:
def describe_rom(self, full_path_filename):
# Return variables:
ret_base_filename = ''
ret_stripped_filename = ''
ret_tokens = []
ret_base_filename = os.path.basename(full_path_filename)
# Get all the tokens:
s_p = self.find(ret_base_filename, '(')
e_p = self.find(ret_base_filename, ')')
s_b = self.find(ret_base_filename, '[')
e_b = self.find(ret_base_filename, ']')
for i in range(len(s_p)):
ret_tokens.append(ret_base_filename[s_p[i]:e_p[i] + 1])
for i in range(len(s_b)):
ret_tokens.append(ret_base_filename[s_b[i]:e_b[i] + 1])
ret_stripped_filename = ret_base_filename
for m in ret_tokens:
ret_stripped_filename = ret_stripped_filename.replace(m, '')
ret_stripped_filename = ret_stripped_filename[:-4].strip() + ret_base_filename[-4:]
return ret_base_filename, ret_stripped_filename, ret_tokens, ret_base_filename
# Calculate a weight for easy sorting:
def calculate_weight(self):
# http://www.theisozone.com/tutorials/other/general/know-your-roms-a-guide-to-identifying-the-symbols/
priorities = [
{'token': '[a]', 'weight': 9, 'description': 'Alternate'},
{'token': '[b]', 'weight': -99, 'description': 'Bad Dump'},
{'token': '[BF]', 'weight': 7, 'description': 'Bung Fix'},
{'token': '[c]', 'weight': 8, 'description': 'Cracked'},
{'token': '[f]', 'weight': 6, 'description': 'Other Fix'},
{'token': '[h]', 'weight': 5, 'description': 'Hack'},
{'token': '[o]', 'weight': 10, 'description': 'Overdump'},
{'token': '[p]', 'weight': 4, 'description': 'Pirate'},
{'token': '[t]', 'weight': 3, 'description': 'Trained'},
{'token': '[T]', 'weight': 2, 'description': 'Translation'},
{'token': '(Unl)', 'weight': 1, 'description': 'Unlicensed'},
{'token': '[x]', 'weight': -99, 'description': 'Bad Checksum'},
{'token': '[!]', 'weight': 100, 'description': 'Verified Good Dump'},
{'token': '(a)', 'weight': 80, 'description': 'Australian'},
{'token': '(C)', 'weight': 0, 'description': 'Chinese'},
{'token': '(E)', 'weight': 85, 'description': 'Europe'},
{'token': '(F)', 'weight': 0, 'description': 'French'},
{'token': '(FN)', 'weight': 0, 'description': 'Finland'},
{'token': '(G)', 'weight': 0, 'description': 'German'},
{'token': '(GR)', 'weight': 0, 'description': 'Greece'},
{'token': '(HK)', 'weight': 0, 'description': 'Hong Kong'},
{'token': '(I)', 'weight': 0, 'description': 'Italian'},
{'token': '(J)', 'weight': 0, 'description': 'Japan'},
{'token': '(K)', 'weight': 0, 'description': 'Korean'},
{'token': '(NL)', 'weight': 0, 'description': 'Dutch'},
{'token': '(PD)', 'weight': 80, 'description': 'Public Domain'},
{'token': '(S)', 'weight': 0, 'description': 'Spanish'},
{'token': '(SW)', 'weight': 0, 'description': 'Sweden'},
{'token': '(U)', 'weight': 95, 'description': 'USA'},
{'token': '(UK)', 'weight': 90, 'description': 'England'},
{'token': '(Unk)', 'weight': 0, 'description': 'Unknown Country'},
{'token': '(-)', 'weight': 0, 'description': 'Unknown Country'},
{'token': '(Sachen-USA)', 'weight':10, 'description': 'found it'},
{'token': '(Sachen-English)', 'weight':10, 'description': 'found it'}]
high_token_penalty = -2 * len(self.tokens)
token_value = 0
for token in self.tokens:
for priority in priorities:
if token.lower() == priority['token'].lower():
token_value += priority['weight']
return token_value + high_token_penalty
# Parse command line args:
def parseArgs():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--rom_dir', help='Location where your roms are stored', default='y://')
parser.add_argument('--delete', help='WARNING: setting this will delete the roms!', action='store_true')
args = parser.parse_args()
return args
if __name__ == "__main__":
# parse args:
args = parseArgs()
# create the ALL_ROMS class:
all_roms = ALL_ROMS(args.rom_dir, args.delete)
# get the list of games:
game_list = all_roms.get_roms()
# create a rom object for each file:
for full_path_filename in game_list:
all_roms.add_rom(Rom(full_path_filename))
all_roms.clean()
print('all done!')