Skip to content

Commit 674e704

Browse files
Update to 1.17
1 parent bd6ec4e commit 674e704

File tree

5 files changed

+57
-35
lines changed

5 files changed

+57
-35
lines changed

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 1.17
2+
3+
- Retool can now handle No-Intro DATs that reference an XSD file.
4+
15
# 1.16
26

37
- The `<name>` tag in the output DAT header has been changed so CLRMAMEPro

modules/classes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ def __init__(self, contents='', name='Unknown', description='Unknown', version='
2525
self.version = version
2626
self.author = author
2727
self.url = url
28+
self.datafile_tag = ''
2829
self.dat_manager_directives = []
30+
self.is_dtd = False
2931
self.contents = contents
3032
self.user_options = user_options
3133
self.end = end

modules/output.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ def write_dat_file(input_dat, user_input, output_file_name, stats, titles, dat_n
350350

351351
release = []
352352

353-
for region in region_list:
353+
for region in sorted(region_list):
354354
for language in sorted(language_list):
355355
release.append(f'\n\t\t<release name="{html.escape(final_name, quote=False)}" region="{region}" language="{language}"/>')
356356

modules/xml.py

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ def process_input_dat(dat_file, is_folder, gui=False):
553553
sys.exit()
554554

555555
# Check for a valid Redump XML DAT that follows the Logiqx dtd
556-
validation_tags = ['<datafile>', '<?xml', '<game', '<header']
556+
validation_tags = ['<datafile', '<?xml', '<game', '<header']
557557

558558
for i, validation_tag in enumerate(validation_tags):
559559
validation_tags[i] = bool(list(filter(lambda x: validation_tag in x, input_dat.contents)))
@@ -565,6 +565,15 @@ def process_input_dat(dat_file, is_folder, gui=False):
565565
# Remove unexpected XML declarations from the file to avoid DTD check failures
566566
if bool(re.search('<\?xml.*?>', line)) == True:
567567
input_dat.contents[i] = input_dat.contents[i].replace(re.search('<\?xml.*?>', input_dat.contents[0])[0], '<?xml version="1.0"?>')
568+
569+
# Check if the LogiqX DTD is present
570+
if '<!DOCTYPE datafile PUBLIC "-//Logiqx//DTD ROM Management Datafile//EN"' in line:
571+
input_dat.is_dtd = True
572+
573+
# Grab <datafile> tag in case an XSD reference is present
574+
if '<datafile' in line:
575+
input_dat.datafile_tag = line.strip()
576+
568577
# Capture, then remove CLRMAMEPro and Romcenter declarations to avoid DTD check failures
569578
if bool(re.search('.*?<(clrmamepro|romcenter).*?>', line)) == True:
570579
input_dat.dat_manager_directives.append(input_dat.contents[i])
@@ -584,43 +593,46 @@ def process_input_dat(dat_file, is_folder, gui=False):
584593

585594
input_dat.contents = ''.join(input_dat.contents)
586595

587-
try:
588-
with open('datafile.dtd') as dtdfile:
589-
dtd = etree.DTD(dtdfile)
590-
try:
591-
root = etree.XML(input_dat.contents)
592-
593-
if dtd.validate(root) == False:
596+
if 'datafile.dtd' in input_dat.contents:
597+
try:
598+
with open('datafile.dtd') as dtdfile:
599+
dtd = etree.DTD(dtdfile)
600+
try:
601+
root = etree.XML(input_dat.contents)
602+
603+
if dtd.validate(root) == False:
604+
print('failed.')
605+
printwrap(
606+
f'{Font.error_bold}* Error: {Font.error}DAT file '
607+
f'violates Logiqx DTD. '
608+
f'{dtd.error_log.last_error}.'
609+
f'{next_status}{Font.end}', 'error')
610+
if is_folder == False:
611+
sys.exit()
612+
else:
613+
return 'end_batch'
614+
except etree.XMLSyntaxError as e:
594615
print('failed.')
595616
printwrap(
596-
f'{Font.error_bold}* Error: {Font.error}DAT file '
597-
f'violates Logiqx DTD. '
598-
f'{dtd.error_log.last_error}.'
599-
f'{next_status}{Font.end}', 'error')
617+
f'{Font.error_bold}* Error: {Font.error}DAT file is '
618+
f'malformed. {e}.{next_status}{Font.end}', 'error')
600619
if is_folder == False:
601620
sys.exit()
602621
else:
603622
return 'end_batch'
604-
except etree.XMLSyntaxError as e:
605-
print('failed.')
606-
printwrap(
607-
f'{Font.error_bold}* Error: {Font.error}DAT file is '
608-
f'malformed. {e}.{next_status}{Font.end}', 'error')
609-
if is_folder == False:
610-
sys.exit()
611623
else:
612-
return 'end_batch'
624+
if gui == False:
625+
print('done.')
626+
627+
except OSError as e:
628+
printwrap(f'{Font.error_bold}* Error: {str(e)}{next_status}{Font.end}',
629+
'error')
630+
if is_folder == False:
631+
raise
613632
else:
614-
if gui == False:
615-
print('file is a Logiqx DAT file.')
616-
617-
except OSError as e:
618-
printwrap(f'{Font.error_bold}* Error: {str(e)}{next_status}{Font.end}',
619-
'error')
620-
if is_folder == False:
621-
raise
622-
else:
623-
return 'end_batch'
633+
return 'end_batch'
634+
elif gui == False:
635+
print('done.')
624636
else:
625637
print('failed.')
626638

@@ -729,11 +741,15 @@ def header(input_dat, new_title_count, user_input, version):
729741

730742
rom_header_str: str = ''.join(sorted(rom_header))
731743

744+
dtd_line = ''
745+
746+
if input_dat.is_dtd:
747+
dtd_line = '\n<!DOCTYPE datafile PUBLIC "-//Logiqx//DTD ROM Management Datafile//EN" "https://raw.githubusercontent.com/unexpectedpanda/retool/main/datafile.dtd">'
748+
732749
header = [
733750
'<?xml version="1.0"?>',
734-
'\n<!DOCTYPE datafile PUBLIC "-//Logiqx//DTD ROM Management Datafile//EN" '
735-
'"https://raw.githubusercontent.com/unexpectedpanda/retool/main/datafile.dtd">',
736-
'\n<datafile>',
751+
f'{dtd_line}',
752+
f'\n{input_dat.datafile_tag}',
737753
'\n\t<header>',
738754
name,
739755
description,

retool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
# Require at least Python 3.8
3232
assert sys.version_info >= (3, 8)
3333

34-
__version__ = '1.16'
34+
__version__ = '1.17'
3535

3636
def main(gui_input=''):
3737

0 commit comments

Comments
 (0)