diff --git a/app.py b/app.py index a947484..a4bc8b8 100644 --- a/app.py +++ b/app.py @@ -941,10 +941,23 @@ def process_ig(): return redirect(url_for('view_igs')) name, version = services.parse_package_filename(filename) - if not name: # Add fallback naming if parse fails - name = filename[:-4].replace('_', '.') # Basic guess - version = 'unknown' - logger.warning(f"Using fallback naming for {filename} -> {name}#{version}") + if not name or not version: + # Filename didn't encode name/version (e.g. "package.tgz") — read package.json inside + try: + with tarfile.open(tgz_path, "r:gz") as _tar: + _pkg_member = _tar.getmember("package/package.json") + with _tar.extractfile(_pkg_member) as _f: + _pkg_data = json.loads(_f.read().decode('utf-8-sig')) + name = _pkg_data.get('name', name) or name + version = _pkg_data.get('version', version) or version + logger.info(f"Resolved name/version from package.json: {name}#{version}") + except Exception as _e: + logger.warning(f"Could not read package.json from {filename}: {_e}") + if not name: + name = filename[:-4].replace('_', '.') + if not version: + version = 'unknown' + logger.warning(f"Using package.json/fallback naming for {filename} -> {name}#{version}") try: logger.info(f"Starting processing for {name}#{version} from file {filename}") diff --git a/services.py b/services.py index 0b96538..fd2ceb6 100644 --- a/services.py +++ b/services.py @@ -452,6 +452,22 @@ def get_additional_registries(): return feeds # --- END MODIFIED FUNCTION --- +def _read_name_version_from_tgz(tgz_path, fallback_name=None, fallback_version=None): + """Read package name and version from package/package.json inside a .tgz archive.""" + try: + with tarfile.open(tgz_path, "r:gz") as tar: + member = tar.getmember("package/package.json") + with tar.extractfile(member) as f: + data = json.loads(f.read().decode('utf-8-sig')) + name = data.get('name', fallback_name) or fallback_name + version = data.get('version', fallback_version) or fallback_version + logger.info(f"Read name/version from package.json in {os.path.basename(tgz_path)}: {name}#{version}") + return name, version + except Exception as e: + logger.warning(f"Could not read package.json from {tgz_path}: {e}") + return fallback_name, fallback_version + + def import_manual_package_and_dependencies(input_source, version=None, dependency_mode='recursive', is_file=False, is_url=False, resolve_dependencies=True): """ Import a FHIR Implementation Guide package manually, cloning import_package_and_dependencies. @@ -492,10 +508,16 @@ def import_manual_package_and_dependencies(input_source, version=None, dependenc results['errors'].append(f"File not found: {tgz_path}") return results name, version = parse_package_filename(os.path.basename(tgz_path)) + if not name or not version: + name, version = _read_name_version_from_tgz(tgz_path, name, version) if not name: name = os.path.splitext(os.path.basename(tgz_path))[0] + if not version: version = "unknown" target_filename = construct_tgz_filename(name, version) + if not target_filename: + results['errors'].append(f"Could not determine valid name/version for {os.path.basename(tgz_path)}") + return results target_path = os.path.join(download_dir, target_filename) shutil.copy(tgz_path, target_path) results['downloaded'][name, version] = target_path @@ -505,8 +527,11 @@ def import_manual_package_and_dependencies(input_source, version=None, dependenc results['errors'].append(f"Failed to download package from URL: {input_source}") return results name, version = parse_package_filename(os.path.basename(tgz_path)) + if not name or not version: + name, version = _read_name_version_from_tgz(tgz_path, name, version) if not name: name = os.path.splitext(os.path.basename(tgz_path))[0] + if not version: version = "unknown" results['downloaded'][name, version] = tgz_path else: