Skip to content

Commit 41a1eae

Browse files
author
Kazuki Suzuki Przyborowski
committed
Update pyfoxfile.py
1 parent 3a12172 commit 41a1eae

1 file changed

Lines changed: 148 additions & 7 deletions

File tree

pyfoxfile.py

Lines changed: 148 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ def _is_printable(ch):
346346
__use_ini_name__ = "foxfile.ini"
347347
__use_json_file__ = False
348348
__use_json_name__ = "foxfile.json"
349+
if(__use_ini_file__ and __use_json_name__):
350+
__use_json_name__ = False
349351
if('PYARCHIVEFILE_CONFIG_FILE' in os.environ and os.path.exists(os.environ['PYARCHIVEFILE_CONFIG_FILE']) and __use_env_file__):
350352
scriptconf = os.environ['PYARCHIVEFILE_CONFIG_FILE']
351353
else:
@@ -356,6 +358,10 @@ def _is_printable(ch):
356358
scriptconf = ""
357359
if os.path.exists(scriptconf):
358360
__config_file__ = scriptconf
361+
elif(__use_ini_file__ and not __use_json_file__):
362+
__config_file__ = os.path.join(os.path.dirname(os.path.realpath(__file__)), __use_ini_name__)
363+
elif(not __use_ini_file__ and __use_json_file__):
364+
__config_file__ = os.path.join(os.path.dirname(os.path.realpath(__file__)), __use_json_name__)
359365
else:
360366
__config_file__ = os.path.join(os.path.dirname(os.path.realpath(__file__)), __use_ini_name__)
361367
if __use_ini_file__ and os.path.exists(__config_file__):
@@ -371,21 +377,156 @@ def decode_unicode_escape(value):
371377
__include_defaults__ = config.getboolean('config', 'includedef')
372378
__use_inmemfile__ = config.getboolean('config', 'inmemfile')
373379
# Loop through all sections
380+
# Loop through all sections
374381
for section in config.sections():
382+
if section == "config":
383+
continue
384+
375385
required_keys = [
376-
"len", "hex", "ver", "name",
386+
"len", "hex", "ver", "name",
377387
"magic", "delimiter", "extension",
378388
"newstyle", "advancedlist", "altinode"
379389
]
380-
if section != "config" and all(key in config[section] for key in required_keys):
381-
delim = decode_unicode_escape(config.get(section, 'delimiter'))
382-
if(not is_only_nonprintable(delim)):
383-
delim = "\x00" * len("\x00")
384-
__file_format_multi_dict__.update( { decode_unicode_escape(config.get(section, 'magic')): {'format_name': decode_unicode_escape(config.get(section, 'name')), 'format_magic': decode_unicode_escape(config.get(section, 'magic')), 'format_len': config.getint(section, 'len'), 'format_hex': config.get(section, 'hex'), 'format_delimiter': delim, 'format_ver': config.get(section, 'ver'), 'new_style': config.getboolean(section, 'newstyle'), 'use_advanced_list': config.getboolean(section, 'advancedlist'), 'use_alt_inode': config.getboolean(section, 'altinode'), 'format_extension': decode_unicode_escape(config.get(section, 'extension')) } } )
390+
391+
# Py2+Py3 compatible key presence check
392+
has_all_required = all(config.has_option(section, key) for key in required_keys)
393+
if not has_all_required:
394+
continue
395+
396+
delim = decode_unicode_escape(config.get(section, 'delimiter'))
397+
if (not is_only_nonprintable(delim)):
398+
delim = "\x00" * len("\x00")
399+
400+
__file_format_multi_dict__.update({
401+
decode_unicode_escape(config.get(section, 'magic')): {
402+
'format_name': decode_unicode_escape(config.get(section, 'name')),
403+
'format_magic': decode_unicode_escape(config.get(section, 'magic')),
404+
'format_len': config.getint(section, 'len'),
405+
'format_hex': config.get(section, 'hex'),
406+
'format_delimiter': delim,
407+
'format_ver': config.get(section, 'ver'),
408+
'new_style': config.getboolean(section, 'newstyle'),
409+
'use_advanced_list': config.getboolean(section, 'advancedlist'),
410+
'use_alt_inode': config.getboolean(section, 'altinode'),
411+
'format_extension': decode_unicode_escape(config.get(section, 'extension')),
412+
}
413+
})
385414
if not __file_format_multi_dict__ and not __include_defaults__:
386415
__include_defaults__ = True
416+
elif __use_json_file__ and os.path.exists(__config_file__):
417+
# Prefer ujson/simplejson if available (you already have this import block above)
418+
with open(__config_file__, 'rb') as f:
419+
raw = f.read()
420+
421+
# Ensure we get a unicode string for json.loads on both Py2 and Py3
422+
if sys.version_info[0] < 3:
423+
text = raw.decode('utf-8') # Py2 bytes -> unicode
424+
else:
425+
text = raw if isinstance(raw, str) else raw.decode('utf-8')
426+
427+
cfg = json.loads(text)
428+
429+
# --- helpers: coerce + decode like your INI path ---
430+
def decode_unicode_escape(value):
431+
if sys.version_info[0] < 3: # Python 2
432+
if isinstance(value, unicode): # noqa: F821 (Py2 only)
433+
return value.encode('utf-8').decode('unicode_escape')
434+
elif isinstance(value, str):
435+
return value.decode('unicode_escape')
436+
else:
437+
return value
438+
else: # Python 3
439+
if isinstance(value, str):
440+
return bytes(value, 'UTF-8').decode('unicode_escape')
441+
else:
442+
return value
443+
444+
def _to_bool(v):
445+
# handle true/false, 1/0, and "true"/"false"/"1"/"0"
446+
if isinstance(v, bool):
447+
return v
448+
if isinstance(v, (int, float)):
449+
return bool(v)
450+
if isinstance(v, (str,)):
451+
lv = v.strip().lower()
452+
if lv in ('true', 'yes', '1'):
453+
return True
454+
if lv in ('false', 'no', '0'):
455+
return False
456+
return bool(v)
457+
458+
def _to_int(v, default=0):
459+
try:
460+
return int(v)
461+
except Exception:
462+
return default
463+
464+
def _get(section_dict, key, default=None):
465+
return section_dict.get(key, default)
466+
467+
# --- read global config (like INI's [config]) ---
468+
cfg_config = cfg.get('config', {}) or {}
469+
__file_format_default__ = decode_unicode_escape(_get(cfg_config, 'default', ''))
470+
__program_name__ = decode_unicode_escape(_get(cfg_config, 'proname', ''))
471+
__include_defaults__ = _to_bool(_get(cfg_config, 'includedef', False))
472+
__use_inmemfile__ = _to_bool(_get(cfg_config, 'inmemfile', False))
473+
474+
# --- iterate format sections (everything except "config") ---
475+
required_keys = [
476+
"len", "hex", "ver", "name",
477+
"magic", "delimiter", "extension",
478+
"newstyle", "advancedlist", "altinode"
479+
]
480+
481+
for section_name, section in cfg.items():
482+
if section_name == 'config' or not isinstance(section, dict):
483+
continue
484+
485+
# check required keys present
486+
if not all(k in section for k in required_keys):
487+
continue
488+
489+
# pull + coerce values
490+
magic = decode_unicode_escape(_get(section, 'magic', ''))
491+
name = decode_unicode_escape(_get(section, 'name', ''))
492+
fmt_len = _to_int(_get(section, 'len', 0))
493+
fmt_hex = decode_unicode_escape(_get(section, 'hex', ''))
494+
fmt_ver = decode_unicode_escape(_get(section, 'ver', ''))
495+
delim = decode_unicode_escape(_get(section, 'delimiter', ''))
496+
new_style = _to_bool(_get(section, 'newstyle', False))
497+
adv_list = _to_bool(_get(section, 'advancedlist', False))
498+
alt_inode = _to_bool(_get(section, 'altinode', False))
499+
extension = decode_unicode_escape(_get(section, 'extension', ''))
500+
501+
# keep your delimiter validation semantics
502+
if not is_only_nonprintable(delim):
503+
delim = "\x00" * len("\x00") # same as your INI branch
504+
505+
__file_format_multi_dict__.update({
506+
magic: {
507+
'format_name': name,
508+
'format_magic': magic,
509+
'format_len': fmt_len,
510+
'format_hex': fmt_hex,
511+
'format_delimiter': delim,
512+
'format_ver': fmt_ver,
513+
'new_style': new_style,
514+
'use_advanced_list': adv_list,
515+
'use_alt_inode': alt_inode,
516+
'format_extension': extension,
517+
}
518+
})
519+
520+
# mirror your INI logic
521+
if not __file_format_multi_dict__ and not __include_defaults__:
522+
__include_defaults__ = True
387523
elif __use_ini_file__ and not os.path.exists(__config_file__):
388-
__use_ini_file__ = True
524+
__use_ini_file__ = False
525+
__use_json_file__ = False
526+
__include_defaults__ = True
527+
elif __use_json_file__ and not os.path.exists(__config_file__):
528+
__use_json_file__ = False
529+
__use_ini_file__ = False
389530
__include_defaults__ = True
390531
if not __use_ini_file__ and not __include_defaults__:
391532
__include_defaults__ = True

0 commit comments

Comments
 (0)