Migrate a Mihon source¶
Katari continues to load selected legacy Mihon extension API families for compatibility. That support is not the authoring API for new Katari extensions. A migrated extension should depend only on entry-source-api and use Entry-native models from end to end.
Contract mapping¶
Mihon source-api |
Katari entry-source-api |
|---|---|
Source |
UnifiedSource |
CatalogueSource |
EntryCatalogueSource |
HttpSource |
EntryHttpSource or EntryImageHttpSource |
SourceFactory |
EntrySourceFactory |
SManga |
SEntry |
SChapter |
SEntryChapter |
MangasPage |
EntryPageResult<SEntry> |
FilterList / Filter |
EntryFilterList / EntryFilter |
Page |
EntryImagePage inside EntryMedia.ImagePages |
| RxJava return values | Kotlin suspending functions |
Do not keep source-api as a second dependency merely to reuse its models. Convert the implementation fully or isolate temporary conversion outside the published Entry extension.
Recommended migration order¶
- Replace the Gradle dependency with
entry-source-apias shown in getting started. - Replace
SourceFactorywithEntrySourceFactory. - Move catalogue methods to suspending
UnifiedSourcemethods. - Convert listing and detail parsers from
SMangatoSEntry. - Set
SEntry.typefor every returned item. - Convert chapter or episode models to
SEntryChapter. - Replace page or video APIs with
getMedia()returningEntryMedia. - Replace filters and preferences with their Entry equivalents.
- Remove all imports from
eu.kanade.tachiyomi.source.*except thesource.entrypackage.
Replace RxJava at the boundary¶
Legacy sources commonly returned Observable or Single. Entry sources expose suspend functions instead:
override suspend fun getContentDetails(entry: SEntry): SEntry {
return client.newCall(detailsRequest(entry)).awaitSuccess().use { response ->
parseDetails(response, entry)
}
}
Keep cancellation cooperative by using the suspending network helpers supplied by the SDK rather than blocking a coroutine thread.
Make type and media explicit¶
Mihon's models imply that every catalogue item is manga-like. Katari separates entry metadata from the media returned for a chapter.
For image content:
For playback content:
Do not select behavior from the extension package, factory, or catalogue name. Set the type on the entry and return the media that the chapter actually resolves.
Preserve identity¶
Migration should not silently create duplicate sources or library entries. Preserve the existing source ID and stable entry and chapter URLs whenever the new implementation represents the same provider data.
If the old source inherited an ID generated from HttpSource, check the resulting ID before changing its name, language, or version inputs. An explicit id is safer when the public name must change.
Factory example¶
A single migrated factory may return several source implementations, including sources that expose different content types:
class ExampleFactory : EntrySourceFactory {
override fun createSources(): List<UnifiedSource> = listOf(
ExampleComicsSource(),
ExampleVideoSource(),
)
}
There is no extension-level manga or anime declaration. Katari derives catalogue language from the returned sources and behavior from their entries and capabilities.