Skip to content

Commit fb001d4

Browse files
author
xy
committed
Where is It? XML Report decoding - proof of concept
fix path copied to clipboard
1 parent a168011 commit fb001d4

File tree

1 file changed

+161
-1
lines changed

1 file changed

+161
-1
lines changed

src/librer.py

+161-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
from librer_images import librer_image
4949

5050
from shutil import rmtree
51+
from re import compile as re_compile
52+
5153
from dialogs import *
5254
from core import *
5355

@@ -495,6 +497,7 @@ def file_cascade_post():
495497

496498
self_file_cascade_add_separator()
497499
self_file_cascade_add_command(label = 'Import record ...', accelerator='Ctrl+I', command = self.record_import,image = self.ico_record_import,compound='left')
500+
self_file_cascade_add_command(label = 'Import "Where Is It?" xml ...', command = self.record_import_wii,image = self.ico_empty,compound='left')
498501
self_file_cascade_add_separator()
499502
self_file_cascade_add_command(label = 'Find ...',command = self.finder_wrapper_show, accelerator="Ctrl+F",image = self.ico_find,compound='left',state = 'normal' if self.sel_item is not None and self.current_record else 'disabled')
500503
self_file_cascade_add_separator()
@@ -1785,6 +1788,163 @@ def record_repack(self):
17851788
self.find_clear()
17861789
self.info_dialog_on_main.show('Repacking finished.','Check repacked record\nDelete original record manually if you want.')
17871790

1791+
@restore_status_line
1792+
@block_actions_processing
1793+
@gui_block
1794+
def record_import_wii(self):
1795+
initialdir = self.last_dir if self.last_dir else self.cwd
1796+
1797+
if import_filenames := askopenfilenames(initialdir=self.last_dir,parent = self.main,title='Choose "Where Is It?" Report xml file to import', defaultextension=".xml",filetypes=[("XML Files","*.xml"),("All Files","*.*")]):
1798+
self.last_dir = dirname(import_filenames[0])
1799+
try:
1800+
re_obj_item = re_compile(r'<ITEM ItemType="([^"]+)">')
1801+
re_obj_item_end = re_compile(r'/ITEM>')
1802+
1803+
re_obj_name = re_compile(r'<NAME>(.+)</NAME>')
1804+
re_obj_ext = re_compile(r'<EXT>(.+)</EXT>')
1805+
re_obj_size = re_compile(r'<SIZE>(.+)</SIZE>')
1806+
re_obj_date = re_compile(r'<DATE>(.+)</DATE>')
1807+
re_obj_disk_name = re_compile(r'<DISK_NAME>(.+)</DISK_NAME>')
1808+
re_obj_disk_type = re_compile(r'<DISK_TYPE>(.+)</DISK_TYPE>')
1809+
re_obj_disk_num = re_compile(r'<DISK_NUM>(.+)</DISK_NUM>')
1810+
re_obj_disk_location = re_compile(r'<DISK_LOCATION>(.+)</DISK_LOCATION>')
1811+
re_obj_path = re_compile(r'<PATH>(.+)</PATH>')
1812+
re_obj_time = re_compile(r'<TIME>(.+)</TIME>')
1813+
re_obj_crc = re_compile(r'<CRC>(.+)</CRC>')
1814+
re_obj_category = re_compile(r'<CATEGORY>(.+)</CATEGORY>')
1815+
re_obj_flag = re_compile(r'<FLAG>(.+)</FLAG>')
1816+
re_obj_desc = re_compile(r'<DESCRIPTION>(.+)</DESCRIPTION>')
1817+
re_obj_desc_begin = re_compile(r'<DESCRIPTION>(.*)')
1818+
re_obj_desc_end = re_compile(r'(.*)</DESCRIPTION>')
1819+
1820+
l=0
1821+
in_item=False
1822+
in_description=False
1823+
1824+
demo_str = '*** DEMO ***'
1825+
1826+
#known_discs = set()
1827+
#known_items = set()
1828+
1829+
wii_paths_dict = {}
1830+
1831+
def print_dir_structure(file_handle,curr_dict_ref,indent=''):
1832+
try:
1833+
for key,val in curr_dict_ref.items():
1834+
if not indent:
1835+
file_handle.write('\n==================================\n')
1836+
file_handle.write(indent + str(key) + '\n')
1837+
print_dir_structure(file_handle,val,indent + ' ')
1838+
except Exception as e:
1839+
pass
1840+
1841+
def wii_paths_dict_add(path_elem,curr_dict_ref):
1842+
if path_elem not in curr_dict_ref:
1843+
curr_dict_ref[path_elem] = {}
1844+
1845+
return curr_dict_ref[path_elem]
1846+
1847+
for import_filename in import_filenames:
1848+
with open(import_filename,"rt") as f:
1849+
for line in f:
1850+
if match := re_obj_item.search(line):
1851+
in_item=True
1852+
in_description=False
1853+
item={}
1854+
item['description'] = []
1855+
1856+
item['type']=match.group(1)
1857+
elif match := re_obj_item_end.search(line):
1858+
in_item=False
1859+
in_description=False
1860+
1861+
if item['disk_name']!=demo_str and item['path']!=demo_str:
1862+
path_splitted = [item['disk_name'] + ':'] + item['path'].strip('\\').split('\\')
1863+
path_splitted_len = len(path_splitted)
1864+
#print(f'{path_splitted=}')
1865+
1866+
next_dict = wii_paths_dict
1867+
for ps_i in range(path_splitted_len):
1868+
next_dict = wii_paths_dict_add(path_splitted[ps_i],next_dict)
1869+
1870+
elif match := re_obj_name.search(line):
1871+
item['name']=match.group(1)
1872+
elif match := re_obj_ext.search(line):
1873+
item['ext']=match.group(1)
1874+
elif match := re_obj_size.search(line):
1875+
item['size']=match.group(1)
1876+
elif match := re_obj_date.search(line):
1877+
item['date']=match.group(1)
1878+
elif match := re_obj_disk_name.search(line):
1879+
item['disk_name']=match.group(1)
1880+
elif match := re_obj_disk_type.search(line):
1881+
item['disk_type']=match.group(1)
1882+
elif match := re_obj_disk_num.search(line):
1883+
item['disk_num']=match.group(1)
1884+
elif match := re_obj_disk_location.search(line):
1885+
item['disk_loc']=match.group(1)
1886+
elif match := re_obj_path.search(line):
1887+
item['path']=match.group(1)
1888+
elif match := re_obj_time.search(line):
1889+
item['time']=match.group(1)
1890+
elif match := re_obj_crc.search(line):
1891+
item['crc']=match.group(1)
1892+
elif match := re_obj_category.search(line):
1893+
item['category']=match.group(1)
1894+
elif match := re_obj_flag.search(line):
1895+
item['flag']=match.group(1)
1896+
elif match := re_obj_desc.search(line):
1897+
item['desc']=match.group(1)
1898+
elif match := re_obj_desc_begin.search(line):
1899+
in_description=True
1900+
item['description'].append(match.group(1))
1901+
elif match := re_obj_desc_end.search(line):
1902+
in_description=False
1903+
item['description'].append(match.group(1))
1904+
item['description'] = tuple(item['description'])
1905+
elif in_description:
1906+
item['description'].append(line)
1907+
elif lstrip:=line.strip():
1908+
#pass
1909+
print('IGNORING:',lstrip)
1910+
1911+
l+=1
1912+
1913+
1914+
#xml_content = fb.read().decode('utf-8', errors='replace')
1915+
1916+
#print(f'{xml_content=}')
1917+
1918+
#root = ET.fromstring(xml_content)
1919+
1920+
#<ITEM ItemType="Folder">
1921+
# <NAME>$Recycle.Bin</NAME>
1922+
# <SIZE>1918697428</SIZE>
1923+
# <DATE>2023-04-27</DATE>
1924+
# <DISK_NAME>c</DISK_NAME>
1925+
# <DISK_TYPE>Hard disk</DISK_TYPE>
1926+
# <PATH>\</PATH>
1927+
# <DESCRIPTION><![CDATA[*** DEMO ***]]></DESCRIPTION>
1928+
# <DISK_NUM>1</DISK_NUM>
1929+
# <TIME>12:55:08</TIME>
1930+
# <CRC>0</CRC>
1931+
#</ITEM>
1932+
1933+
1934+
#librer_core.wii_xml_import(root,self.single_record_show)
1935+
#print('done.',l,'known_items_len:',len(known_items))
1936+
1937+
#proof of concept
1938+
if poc_file_path := asksaveasfilename(initialdir=self.last_dir,parent = self.main, initialfile = 'decoded_wii.txt',defaultextension=".txt",filetypes=[("Text Files","*.txt"),("All Files","*.*")]):
1939+
self.last_dir = dirname(poc_file_path)
1940+
with open(poc_file_path,'w') as fw:
1941+
fw.write('Where Is It? - report decoding - proof of concept\n')
1942+
fw.write('=================================================\n\n')
1943+
print_dir_structure(fw,wii_paths_dict)
1944+
1945+
except Exception as ie:
1946+
print(f'WII Import error:{ie}')
1947+
17881948
@restore_status_line
17891949
@block_actions_processing
17901950
@gui_block
@@ -3882,7 +4042,7 @@ def clip_copy_full_path_with_file(self):
38824042
record = self.item_to_record[record_item]
38834043

38844044
self.main.clipboard_clear()
3885-
self.main.clipboard_append(record.header.scan_path + sep + sep.join(subpath_list))
4045+
self.main.clipboard_append(normpath(sep.join([record.header.scan_path,sep.join(subpath_list)])))
38864046

38874047
self.status('Full path copied to clipboard')
38884048

0 commit comments

Comments
 (0)