# Multi-APK Batch Extraction Workflow

Extract systems from multiple competitor APKs into a unified engine directory, organized by function not by app.

## When to Use

User provides 2-5 APKs from CachyOS (or another machine) and wants to copy patterns into a target app. Goal is organized source files ready to port — not a build or a single audit.

## Workflow

### 1. SCP APKs from remote machine

```bash
ssh cachyos 'find ~/Documents ~/Downloads ~/Desktop -name "*.apk" -type f'
scp cachyos:"apk1.apk" /tmp/apk-analysis/
scp cachyos:"apk2.apk" /tmp/apk-analysis/
```

### 2. Batch decompile (background, parallel)

```bash
cd /tmp/apk-analysis
mkdir -p app1-jadx app2-jadx
jadx --show-bad-code -d app1-jadx app1.apk ...
jadx --show-bad-code -d app2-jadx app2.apk ...
```

### 3. Quick triage — read manifests first

For each APK:
- `grep -l "LEANBACK_LAUNCHER\|leanback" AndroidManifest.xml` → TV app
- Check `minSdkVersion`, `targetSdkVersion`
- Check app class, package name
- Identify: Firebase? Ads? Debrid? Scraping? API-based?
- If heavily ProGuarded (single-letter class names like `o.ActivityC2294Hy`), skip — unreadable

### 4. Identify extraction targets per app

| App type | What to extract | Priority |
|---|---|---|
| **Scraper VOD** (Streamflix) | Provider interface + implementations, extractors, models, HTTP client, Jsoup converter | 🔥 |
| **Debrid client** (STRMR) | All debrid providers (RD/Premiumize/AD/ED/TorBox), Stremio addon protocol, Trakt sync, Android TV channels | 🔥 |
| **API-based streaming** (ONstreamz) | Full API contract (request + response models), TV UI fragments, player | 🔥 |
| **IPTV** (Netfly TV) | API endpoint map, entity schemas, IJKPlayer setup, download manager | High |
| **Official streaming** (Netflix) | Generally skip — heavily ProGuarded | Low |

### 5. Create organized directory structure

```
scraper-engine/
├── providers/         ← scraper implementations
├── extractors/        ← video hoster resolvers
├── models/            ← data models
├── utils/             ← HTTP client, crypto, Jsoup
│
└── strmr/
    ├── debrid/        ← RealDebrid, Premiumize, AllDebrid, EasyDebrid, TorBox
    │   ├── *ApiService.java     → API endpoints
    │   ├── *Repository.java     → OAuth, magnet, unrestrict, cache
    │   ├── *AccountDao.java     → Room token storage
    │   ├── *Account.java        → Account entity
    │   └── model/               → JSON response models per provider
    ├── stremio/        ← Stremio addon protocol
    │   ├── StremioManifest.java → Manifest schema
    │   ├── StremioStream.java   → Stream response
    │   ├── AddonCatalogClient.java → Catalog API
    │   ├── AddonStreamClient.java  → Stream API
    │   ├── AddonRepository.java    → Install/uninstall/refresh
    │   └── data/model/addon/    → Config, bundles, injection
    ├── trakt/          ← Trakt integration
    │   ├── TraktApiService.java → All endpoints
    │   ├── TraktScrobbleRepository.java → Scrobble pipeline
    │   ├── TraktSyncRepository.java    → Collection/history/watchlist sync
    │   └── data/model/trakt/   → 50+ Trakt models
    ├── auth/           ← Supabase, Google auth
    ├── player/         ← ExoPlayer, playback service, resume
    ├── channels/       ← Android TV home channel
    ├── settings/       ← Settings screens
    └── models/         ← Room entities
│
└── onstreamz/
    ├── api/request/    ← Auth, watchlist, ratings, continue-watch
    ├── api/response/   ← Home, movies, series, episodes, streaming, subs
    ├── models/         ← Domain models + StreamSource, SubtitleSource
    ├── player/         ← TvPlayerActivity, MediaService
    └── ui/             ← All TV fragments (30+)
```

### 6. Extraction commands (cp, not grep)

```bash
SRC=/path/to/jadx/sources/com/strmr/ps
DEST=/tmp/scraper-engine/strmr

# Debrid APIs + repos
cp "$SRC/data/remote/api/RealDebridApiService.java" "$DEST/debrid/"
cp "$SRC/data/remote/api/PremiumizeApiService.java" "$DEST/debrid/"
# ... copy all relevant files

# Stremio addon protocol
cp "$SRC/data/model/addon/"*.java "$DEST/stremio/"
cp "$SRC/data/remote/Addon*Client.java" "$DEST/stremio/"

# Trakt
cp "$SRC/data/model/trakt/"*.java "$DEST/trakt/"
cp "$SRC/data/repository/Trakt*.java" "$DEST/trakt/"
```

Prefer `cp` with explicit file lists over wildcards — avoids copying useless obfuscated inner classes.

### 7. Verify extraction

```bash
find /tmp/scraper-engine -type f \( -name "*.java" -o -name "*.kt" \) | wc -l
# Target: 500-800 files for a 3-APK session
du -sh /tmp/scraper-engine
# Typical: 10-15 MB
```

## Key Systems to Extract (Ranked)

| System | Source App | What you get | File count |
|---|---|---|---|
| Scraper providers | Streamflix | 45 site scrapers + 82 video extractors | 135 |
| Debrid APIs | STRMR | RealDebrid/Premiumize/AllDebrid/EasyDebrid/TorBox | 170 |
| Stremio addon protocol | STRMR | Full addon client (manifest, catalog, stream, search, subs) | 55 |
| Trakt scrobbling | STRMR | Scrobble, sync, lists, ratings, history | 150 |
| API contract | ONstreamz | 15 request + 43 response JSON models | 58 |
| TV UI fragments | ONstreamz | 30 Leanback fragments + custom views | 30 |
| Android TV channels | STRMR | Home channel manager, image provider, catalog workers | 4 |
| Auth | STRMR | Supabase device link, Google auth, biometric | 10 |
| Player | STRMR+ONstreamz | ExoPlayer, foreground service, resume, settings | 15 |

## Per-APK Extraction Checklists

### STRMR (`com.strmr.ps`) — Debrid streaming app
- [ ] `debrid/` — All 5 provider APIs + repos + entities + models
- [ ] `stremio/` — Addon clients, manifests, repository, entities
- [ ] `trakt/` — Model, auth, scrobble, sync, media repos, UI
- [ ] `auth/` — Supabase login, Google auth, feature gates
- [ ] `player/` — VideoPlayerActivity, PlaybackService, resume entity
- [ ] `channels/` — HomeChannelManager, CatalogRefreshWorker
- [ ] `settings/` — SettingsActivity, DeviceManagementActivity
- [ ] `models/` — All Room entities + DAOs

### ONstreamz (`com.martsnew.tv`) — API streaming app
- [ ] `api/request/` — All 15 request models
- [ ] `api/response/` — All 43 response models
- [ ] `models/` — Domain models, StreamSource, SubtitleSource
- [ ] `player/` — TvPlayerActivity, MediaService
- [ ] `ui/` — All 30 TV fragments + custom views

### Netfly TV (`xyz.netfly.*`) — IPTV app
- [ ] API endpoint map (60 routes with `psk_app_nf_*` keys)
- [ ] Entity schemas (VideoInfoEntity, CmsVideoSource, etc.)
- [ ] IJKPlayer setup + gesture controls
- [ ] Download service
- [ ] 34-screen activity map

### Streamflix (`com.streamflixreborn.*`) — Scraper VOD
- [ ] `providers/` — All 45 site scrapers + Provider interface
- [ ] `extractors/` — All 82 video hoster resolvers + Extractor base
- [ ] `models/` — Video, Movie, TvShow, Episode, Season, etc.
- [ ] `utils/` — NetworkClient with DoH + Cloudflare bypass
- [ ] `jsoup-converter/` — Retrofit Jsoup converter module

## Pitfalls

- **ProGuard = skip**: If jadx output shows single-letter package names (`o/a.java`, `o/HF.java`), the app is unreadable. Extract nothing.
- **Obfuscated inner classes**: jadx generates tons of `Class$1$2$3.java` anonymous inner classes. When copying, only grab the main files and their `_Factory` variants if DI-injected.
- **Moshi adapter files**: `*JsonAdapter.java` files are auto-generated by Moshi's codegen. Skip them — you just need the annotated model class.
- **Room _Impl files**: Auto-generated by Room. Only copy the interface/abstract DAO + entity, not the `_Impl.java`.
- **Hilt/Dagger inner classes**: Hundreds of `Dagger*_*Component*` files. Don't copy them — the pattern is what matters (how the app wires DI).
- **Only main branch matters**: When a provider/extractor fails at runtime, it's because the scraped site changed its HTML structure. The fix is updating CSS selectors — not re-extracting from an older APK.
