diff --git a/README.md b/README.md
index 3e74096..bdd1004 100644
--- a/README.md
+++ b/README.md
@@ -25,36 +25,59 @@ The maintainer of Obtainium also hosts a collection of Crowdsourced app configur
1. Visit this page on your android emulation device
1. Click the "Add to Obtainium!" links of the emulators you wish to track
-| Application Name | Category | Add to Obtainium | Included in export json? |
-|------------------|----------|------------------|--------------------------|
-| Azahar | Emulator | Add to Obtainium! | ✅ |
-| +AzaharPlus+ | Emulator | Add to Obtainium! | ❌ |
-| Cemu | Emulator | Add to Obtainium! | ✅ |
-| Citron | Emulator | Add to Obtainium! | ✅ |
-| Dolphin Emulator (Dev build) | Emulator | Add to Obtainium! | ❌ |
-| Dolphin Emulator | Emulator | Add to Obtainium! | ✅ |
-| DuckStation (Beta) | Emulator | Add to Obtainium! | ✅ |
-| Eden | Emulator | Add to Obtainium! | ✅ |
-| melonDS | Emulator | Add to Obtainium! | ✅ |
-| melonDS Nightly | Emulator | Add to Obtainium! | ❌ |
-| PPSSPP | Emulator | Add to Obtainium! | ✅ |
-| RetroArch AArch64 (Stable) | Emulator | Add to Obtainium! | ✅ |
-| RetroArch AArch64 (Nightly) | Emulator | Add to Obtainium! | ❌ |
-| RPCSX | Emulator | Add to Obtainium! | ✅ |
-| ScummVM | Emulator | Add to Obtainium! | ✅ |
-| Winlator | Emulator | Add to Obtainium! | ✅ |
-| Vita3K | Emulator | Add to Obtainium! | ✅ |
-| Vita3K ZX | Emulator | Add to Obtainium! | ✅ |
-| NetherSX2 Classic | Emulator | Add to Obtainium! | ✅ |
-| NetherSX2 Classic (Pre-Release) | Emulator | Add to Obtainium! | ❌ |
-| Artemis | Streaming | Add to Obtainium! | ✅ |
-| Moonlight | Streaming | Add to Obtainium! | ✅ |
-| Syncthing-Fork | Utilities | Add to Obtainium! | ✅ |
-| ES-DE Android Apps | Utilities | Add to Obtainium! | ✅ |
-| AdrenoToolsDrivers | Track Only | Add to Obtainium! | ✅ |
-| Obtainium Emulation Pack | Track Only | Add to Obtainium! | ✅ |
-| Daijishō | Frontend | Add to Obtainium! | ✅ |
-| Pegasus | Frontend | Add to Obtainium! | ✅ |
+## Applications
+### Emulator
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| +AzaharPlus+ | Add to Obtainium! | ❌ |
+| Azahar | Add to Obtainium! | ✅ |
+| Cemu | Add to Obtainium! | ✅ |
+| Citron | Add to Obtainium! | ✅ |
+| Dolphin Emulator | Add to Obtainium! | ✅ |
+| Dolphin Emulator (Dev build) | Add to Obtainium! | ❌ |
+| DuckStation (Beta) | Add to Obtainium! | ✅ |
+| Eden | Add to Obtainium! | ✅ |
+| NetherSX2 Classic | Add to Obtainium! | ✅ |
+| NetherSX2 Classic (Pre-Release) | Add to Obtainium! | ❌ |
+| PPSSPP | Add to Obtainium! | ✅ |
+| RPCSX | Add to Obtainium! | ✅ |
+| RetroArch AArch64 (Nightly) | Add to Obtainium! | ❌ |
+| RetroArch AArch64 (Stable) | Add to Obtainium! | ✅ |
+| ScummVM | Add to Obtainium! | ✅ |
+| Vita3K | Add to Obtainium! | ✅ |
+| Vita3K ZX | Add to Obtainium! | ✅ |
+| Winlator | Add to Obtainium! | ✅ |
+| melonDS | Add to Obtainium! | ✅ |
+| melonDS Nightly | Add to Obtainium! | ❌ |
+
+### Frontend
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| Daijishō | Add to Obtainium! | ✅ |
+| Pegasus | Add to Obtainium! | ✅ |
+
+### Streaming
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| Artemis | Add to Obtainium! | ✅ |
+| Moonlight | Add to Obtainium! | ✅ |
+
+### Track Only
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| AdrenoToolsDrivers | Add to Obtainium! | ✅ |
+| Obtainium Emulation Pack | Add to Obtainium! | ✅ |
+
+### Utilities
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| ES-DE Android Apps | Add to Obtainium! | ✅ |
+| Syncthing-Fork | Add to Obtainium! | ✅ |
## FAQ
diff --git a/pages/table.md b/pages/table.md
index b81ed79..455eb12 100644
--- a/pages/table.md
+++ b/pages/table.md
@@ -1,30 +1,53 @@
-| Application Name | Category | Add to Obtainium | Included in export json? |
-|------------------|----------|------------------|--------------------------|
-| Azahar | Emulator | Add to Obtainium! | ✅ |
-| +AzaharPlus+ | Emulator | Add to Obtainium! | ❌ |
-| Cemu | Emulator | Add to Obtainium! | ✅ |
-| Citron | Emulator | Add to Obtainium! | ✅ |
-| Dolphin Emulator (Dev build) | Emulator | Add to Obtainium! | ❌ |
-| Dolphin Emulator | Emulator | Add to Obtainium! | ✅ |
-| DuckStation (Beta) | Emulator | Add to Obtainium! | ✅ |
-| Eden | Emulator | Add to Obtainium! | ✅ |
-| melonDS | Emulator | Add to Obtainium! | ✅ |
-| melonDS Nightly | Emulator | Add to Obtainium! | ❌ |
-| PPSSPP | Emulator | Add to Obtainium! | ✅ |
-| RetroArch AArch64 (Stable) | Emulator | Add to Obtainium! | ✅ |
-| RetroArch AArch64 (Nightly) | Emulator | Add to Obtainium! | ❌ |
-| RPCSX | Emulator | Add to Obtainium! | ✅ |
-| ScummVM | Emulator | Add to Obtainium! | ✅ |
-| Winlator | Emulator | Add to Obtainium! | ✅ |
-| Vita3K | Emulator | Add to Obtainium! | ✅ |
-| Vita3K ZX | Emulator | Add to Obtainium! | ✅ |
-| NetherSX2 Classic | Emulator | Add to Obtainium! | ✅ |
-| NetherSX2 Classic (Pre-Release) | Emulator | Add to Obtainium! | ❌ |
-| Artemis | Streaming | Add to Obtainium! | ✅ |
-| Moonlight | Streaming | Add to Obtainium! | ✅ |
-| Syncthing-Fork | Utilities | Add to Obtainium! | ✅ |
-| ES-DE Android Apps | Utilities | Add to Obtainium! | ✅ |
-| AdrenoToolsDrivers | Track Only | Add to Obtainium! | ✅ |
-| Obtainium Emulation Pack | Track Only | Add to Obtainium! | ✅ |
-| Daijishō | Frontend | Add to Obtainium! | ✅ |
-| Pegasus | Frontend | Add to Obtainium! | ✅ |
\ No newline at end of file
+## Applications
+### Emulator
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| +AzaharPlus+ | Add to Obtainium! | ❌ |
+| Azahar | Add to Obtainium! | ✅ |
+| Cemu | Add to Obtainium! | ✅ |
+| Citron | Add to Obtainium! | ✅ |
+| Dolphin Emulator | Add to Obtainium! | ✅ |
+| Dolphin Emulator (Dev build) | Add to Obtainium! | ❌ |
+| DuckStation (Beta) | Add to Obtainium! | ✅ |
+| Eden | Add to Obtainium! | ✅ |
+| NetherSX2 Classic | Add to Obtainium! | ✅ |
+| NetherSX2 Classic (Pre-Release) | Add to Obtainium! | ❌ |
+| PPSSPP | Add to Obtainium! | ✅ |
+| RPCSX | Add to Obtainium! | ✅ |
+| RetroArch AArch64 (Nightly) | Add to Obtainium! | ❌ |
+| RetroArch AArch64 (Stable) | Add to Obtainium! | ✅ |
+| ScummVM | Add to Obtainium! | ✅ |
+| Vita3K | Add to Obtainium! | ✅ |
+| Vita3K ZX | Add to Obtainium! | ✅ |
+| Winlator | Add to Obtainium! | ✅ |
+| melonDS | Add to Obtainium! | ✅ |
+| melonDS Nightly | Add to Obtainium! | ❌ |
+
+### Frontend
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| Daijishō | Add to Obtainium! | ✅ |
+| Pegasus | Add to Obtainium! | ✅ |
+
+### Streaming
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| Artemis | Add to Obtainium! | ✅ |
+| Moonlight | Add to Obtainium! | ✅ |
+
+### Track Only
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| AdrenoToolsDrivers | Add to Obtainium! | ✅ |
+| Obtainium Emulation Pack | Add to Obtainium! | ✅ |
+
+### Utilities
+
+| Application Name | Add to Obtainium | Included in export json? |
+|------------------|------------------|---------------------------|
+| ES-DE Android Apps | Add to Obtainium! | ✅ |
+| Syncthing-Fork | Add to Obtainium! | ✅ |
diff --git a/scripts/generate-table.py b/scripts/generate-table.py
index efeef06..4317f9c 100644
--- a/scripts/generate-table.py
+++ b/scripts/generate-table.py
@@ -1,6 +1,7 @@
import json
import urllib.parse
import sys
+from collections import defaultdict
def make_obtainium_link(app):
@@ -11,38 +12,59 @@ def make_obtainium_link(app):
"name": app["name"],
"preferredApkIndex": app.get("preferredApkIndex", 0),
"additionalSettings": app.get("additionalSettings", ""),
- "categories": app.get("categories", []),
- "overrideSource": app.get("overrideSource", ""),
}
encoded = urllib.parse.quote(json.dumps(payload), safe="")
return f"http://apps.obtainium.imranr.dev/redirect.html?r=obtainium://app/{encoded}"
-# ❌
-def generate_markdown_table(apps):
- rows = []
- header = (
- "| Application Name | Category | Add to Obtainium | Included in export json? |"
- )
- divider = (
- "|------------------|----------|------------------|--------------------------|"
- )
- rows.append(header)
- rows.append(divider)
+def get_sort_name(app):
+ return app.get("meta", {}).get("nameOverride") or app.get("name", "")
+
+def get_display_name(app):
+ return app.get("meta", {}).get("nameOverride") or app.get("name", "")
+
+
+def generate_category_tables(apps):
+ # Categorize apps
+ categorized = defaultdict(list)
for app in apps:
- meta = app.get("meta", {})
- if meta.get("excludeFromTable", False):
- continue
+ categories = app.get("categories", [])
+ for category in categories:
+ categorized[category].append(app)
- name = meta.get("nameOverride", app.get("name", ""))
- category = ", ".join(app.get("categories", []))
- obtainium_link = make_obtainium_link(app)
- badge_md = f'Add to Obtainium!'
- isIncludedInJson = "❌" if meta.get("excludeFromExport") else "✅"
- rows.append(f"| {name} | {category} | {badge_md} | {isIncludedInJson} |")
+ markdown_sections = ["## Applications"]
- return "\n".join(rows)
+ for category in sorted(categorized.keys()):
+ markdown_sections.append(f"### {category}\n")
+ markdown_sections.append(
+ "| Application Name | Add to Obtainium | Included in export json? |"
+ )
+ markdown_sections.append(
+ "|------------------|------------------|---------------------------|"
+ )
+
+ apps_in_category = sorted(categorized[category], key=get_sort_name)
+
+ for app in apps_in_category:
+ meta = app.get("meta", {})
+ if meta.get("excludeFromTable", False):
+ continue
+
+ display_name = get_display_name(app)
+ obtainium_link = make_obtainium_link(app)
+ badge_md = f'Add to Obtainium!'
+ include_json = (
+ "❌" if app.get("meta", {}).get("excludeFromExport") else "✅"
+ )
+
+ markdown_sections.append(
+ f"| {display_name} | {badge_md} | {include_json} |"
+ )
+
+ markdown_sections.append("") # blank line between sections
+
+ return "\n".join(markdown_sections)
def main(input_file, output_file):
@@ -50,17 +72,17 @@ def main(input_file, output_file):
data = json.load(f)
apps = data.get("apps", [])
- markdown = generate_markdown_table(apps)
+ markdown = generate_category_tables(apps)
with open(output_file, "w", encoding="utf-8") as f:
f.write(markdown)
- print(f"✅ Markdown table written to {output_file}")
+ print(f"✅ Category-based markdown table written to {output_file}")
if __name__ == "__main__":
if len(sys.argv) != 3:
- print("Usage: python json_to_markdown.py input.json output.md")
+ print("Usage: python json_to_markdown_by_category.py input.json output.md")
sys.exit(1)
main(sys.argv[1], sys.argv[2])