diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt index c4529f4b49..7378f43a8f 100644 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/online/HttpSource.kt @@ -43,15 +43,16 @@ abstract class HttpSource : CatalogueSource { open val versionId = 1 /** - * Id of the source. By default it uses a generated id using the first 16 characters (64 bits) - * of the MD5 of the string: sourcename/language/versionId - * Note the generated id sets the sign bit to 0. + * ID of the source. By default it uses a generated id using the first 16 characters (64 bits) + * of the MD5 of the string `"${name.lowercase()}/$lang/$versionId"`. + * + * The ID is generated by the [generateId] function, which can be reused if needed + * to generate outdated IDs for cases where the source name or language needs to + * be changed but migrations can be avoided. + * + * Note: the generated ID sets the sign bit to `0`. */ - override val id by lazy { - val key = "${name.lowercase()}/$lang/$versionId" - val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) - (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE - } + override val id by lazy { generateId(name, lang, versionId) } /** * Headers used for requests. @@ -64,6 +65,28 @@ abstract class HttpSource : CatalogueSource { open val client: OkHttpClient get() = network.client + /** + * Generates a unique ID for the source based on the provided [name], [lang] and + * [versionId]. It will use the first 16 characters (64 bits) of the MD5 of the string + * `"${name.lowercase()}/$lang/$versionId"`. + * + * Note: the generated ID sets the sign bit to `0`. + * + * Can be used to generate outdated IDs, such as when the source name or language + * needs to be changed but migrations can be avoided. + * + * @since extensions-lib 1.5 + * @param name [String] the name of the source + * @param lang [String] the language of the source + * @param versionId [Int] the version ID of the source + * @return a unique ID for the source + */ + protected fun generateId(name: String, lang: String, versionId: Int): Long { + val key = "${name.lowercase()}/$lang/$versionId" + val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) + return (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE + } + /** * Headers builder for requests. Implementations can override this method for custom headers. */