import json import urllib.parse import sys from collections import defaultdict def make_obtainium_link(app): payload = { "id": app["id"], "url": app["url"], "author": app["author"], "name": app["name"], "otherAssetUrls": app.get("otherAssetUrls"), "apkUrls": app.get("apkUrls"), "preferredApkIndex": app.get("preferredApkIndex"), "additionalSettings": app.get("additionalSettings"), "categories": app.get("categories"), "overrideSource": app.get("overrideSource"), "allowIdChange": app.get("allowIdChange"), } encoded = urllib.parse.quote(json.dumps(payload), safe="") return f"http://apps.obtainium.imranr.dev/redirect.html?r=obtainium://app/{encoded}" def get_display_name(app): return app.get("meta", {}).get("nameOverride") or app.get("name", "") def get_application_url(app): return app.get("meta", {}).get("urlOverride") or app.get("url", "") def should_include_app(app, variant): """Determine if an app should be included based on variant and meta fields.""" meta = app.get("meta", {}) # HIGHEST PRIORITY: Global exclusion overrides everything if meta.get("excludeFromExport", False): return False # SECOND PRIORITY: Variant-specific inclusion/exclusion if variant == "standard": # Default: include in standard return meta.get("includeInStandard", True) elif variant == "dual-screen": # Default: include in dual screen return meta.get("includeInDualScreen", True) return True def generate_category_tables(apps): # Categorize apps categorized = defaultdict(list) for app in apps: categories = app.get("categories", []) for category in categories: categorized[category].append(app) markdown_sections = ["## Applications\n"] for category in sorted(categorized.keys()): markdown_sections.append(f"### {category}\n") markdown_sections.append( "| Application Name | Add to Obtainium | Included in export json? | Included in DS json? |" ) markdown_sections.append( "|------------------|------------------|---------------------------|----------------------|" ) apps_in_category = sorted(categorized[category], key=get_display_name) for app in apps_in_category: meta = app.get("meta", {}) if meta.get("excludeFromTable", False): continue display_name = ( f'{get_display_name(app)}' ) obtainium_link = make_obtainium_link(app) badge_md = f'Add to Obtainium!' include_standard = "✅" if should_include_app(app, "standard") else "❌" include_dual_screen = ( "✅" if should_include_app(app, "dual-screen") else "❌" ) markdown_sections.append( f"| {display_name} | {badge_md} | {include_standard} | {include_dual_screen} |" ) markdown_sections.append("") # blank line between sections return "\n".join(markdown_sections) def main(input_file, output_file): with open(input_file, "r", encoding="utf-8") as f: data = json.load(f) apps = data.get("apps", []) markdown = generate_category_tables(apps) with open(output_file, "w", encoding="utf-8") as f: f.write(markdown) print(f"✅ Category-based markdown table written to {output_file}") if __name__ == "__main__": if len(sys.argv) != 3: print("Usage: python generate-table.py input.json output.md") sys.exit(1) main(sys.argv[1], sys.argv[2])