mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Easier initial setup for server URLs (#300)
Use the server scoring API when adding a new server. This allows just entering a hostname or IP address without the scheme (`http`/`https`) or port in most cases. Note: non-standard ports would still need to be provided Closes #5 Closes #296
This commit is contained in:
parent
df8ec83841
commit
df78b42bac
2 changed files with 72 additions and 36 deletions
|
|
@ -12,6 +12,7 @@ import com.github.damontecres.wholphin.data.model.JellyfinServer
|
||||||
import com.github.damontecres.wholphin.services.NavigationManager
|
import com.github.damontecres.wholphin.services.NavigationManager
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||||
import com.github.damontecres.wholphin.ui.showToast
|
import com.github.damontecres.wholphin.ui.showToast
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
|
@ -23,6 +24,8 @@ import org.jellyfin.sdk.Jellyfin
|
||||||
import org.jellyfin.sdk.api.client.HttpClientOptions
|
import org.jellyfin.sdk.api.client.HttpClientOptions
|
||||||
import org.jellyfin.sdk.api.client.extensions.quickConnectApi
|
import org.jellyfin.sdk.api.client.extensions.quickConnectApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.systemApi
|
import org.jellyfin.sdk.api.client.extensions.systemApi
|
||||||
|
import org.jellyfin.sdk.discovery.RecommendedServerInfoScore
|
||||||
|
import org.jellyfin.sdk.discovery.RecommendedServerIssue
|
||||||
import org.jellyfin.sdk.model.serializer.toUUID
|
import org.jellyfin.sdk.model.serializer.toUUID
|
||||||
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -130,48 +133,81 @@ class SwitchServerViewModel
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addServer(serverUrl: String) {
|
fun addServer(inputUrl: String) {
|
||||||
addServerState.value = LoadingState.Loading
|
addServerState.value = LoadingState.Loading
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
try {
|
try {
|
||||||
val serverInfo by jellyfin
|
val scores =
|
||||||
.createApi(serverUrl)
|
jellyfin.discovery.getRecommendedServers(inputUrl).sortedBy { it.score }
|
||||||
.systemApi
|
val bestServer =
|
||||||
.getPublicSystemInfo()
|
scores.firstOrNull { it.score != RecommendedServerInfoScore.BAD }
|
||||||
val id = serverInfo.id?.toUUIDOrNull()
|
val serverInfo = bestServer?.systemInfo?.getOrNull()
|
||||||
if (id != null && serverInfo.startupWizardCompleted == true) {
|
if (bestServer != null && serverInfo != null) {
|
||||||
val server =
|
val serverUrl = bestServer.address
|
||||||
JellyfinServer(
|
|
||||||
id = id,
|
val id = serverInfo.id?.toUUIDOrNull()
|
||||||
name = serverInfo.serverName,
|
|
||||||
url = serverUrl,
|
if (id != null && serverInfo.startupWizardCompleted == true) {
|
||||||
version = serverInfo.version,
|
val server =
|
||||||
)
|
JellyfinServer(
|
||||||
serverRepository.addAndChangeServer(server)
|
id = id,
|
||||||
val quickConnect =
|
name = serverInfo.serverName,
|
||||||
jellyfin
|
url = serverUrl,
|
||||||
.createApi(serverUrl)
|
version = serverInfo.version,
|
||||||
.quickConnectApi
|
)
|
||||||
.getQuickConnectEnabled()
|
serverRepository.addAndChangeServer(server)
|
||||||
.content
|
val quickConnect =
|
||||||
withContext(Dispatchers.Main) {
|
jellyfin
|
||||||
serverQuickConnect.value =
|
.createApi(serverUrl)
|
||||||
serverQuickConnect.value!!.toMutableMap().apply {
|
.quickConnectApi
|
||||||
put(id, quickConnect)
|
.getQuickConnectEnabled()
|
||||||
}
|
.content
|
||||||
}
|
withContext(Dispatchers.Main) {
|
||||||
withContext(Dispatchers.Main) {
|
serverQuickConnect.value =
|
||||||
addServerState.value = LoadingState.Success
|
serverQuickConnect.value!!.toMutableMap().apply {
|
||||||
navigationManager.navigateTo(Destination.UserList(server))
|
put(id, quickConnect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
addServerState.value = LoadingState.Success
|
||||||
|
navigationManager.navigateTo(Destination.UserList(server))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
addServerState.value =
|
||||||
|
LoadingState.Error("Server returned invalid response")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
withContext(Dispatchers.Main) {
|
Timber.w("Error connecting with %s: %s", inputUrl, scores)
|
||||||
addServerState.value =
|
// No good server candidate
|
||||||
LoadingState.Error("Server returned invalid response")
|
val errors =
|
||||||
}
|
scores.joinToString("\n") {
|
||||||
|
val issues =
|
||||||
|
it.issues.firstOrNull()?.let {
|
||||||
|
when (it) {
|
||||||
|
is RecommendedServerIssue.InvalidProductName,
|
||||||
|
is RecommendedServerIssue.MissingSystemInfo,
|
||||||
|
-> "Invalid server info"
|
||||||
|
|
||||||
|
is RecommendedServerIssue.SecureConnectionFailed,
|
||||||
|
is RecommendedServerIssue.ServerUnreachable,
|
||||||
|
is RecommendedServerIssue.SlowResponse,
|
||||||
|
-> "Unable to connect"
|
||||||
|
|
||||||
|
RecommendedServerIssue.MissingVersion,
|
||||||
|
is RecommendedServerIssue.OutdatedServerVersion,
|
||||||
|
is RecommendedServerIssue.UnsupportedServerVersion,
|
||||||
|
-> "Unsupported server version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"${it.address} - $issues"
|
||||||
|
}
|
||||||
|
val message = "Error, tried addresses:\n$errors"
|
||||||
|
addServerState.setValueOnMain(LoadingState.Error(message))
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
Timber.w(ex, "Error creating API for $serverUrl")
|
Timber.w(ex, "Error creating API for $inputUrl")
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
addServerState.value =
|
addServerState.value =
|
||||||
LoadingState.Error(exception = ex)
|
LoadingState.Error(exception = ex)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
<string name="download_and_update"><![CDATA[Download & Update]]></string>
|
<string name="download_and_update"><![CDATA[Download & Update]]></string>
|
||||||
<string name="downloading">Downloading…</string>
|
<string name="downloading">Downloading…</string>
|
||||||
<string name="enabled">Enabled</string>
|
<string name="enabled">Enabled</string>
|
||||||
<string name="enter_server_url">Enter Server IP or URL including port</string>
|
<string name="enter_server_url">Enter Server IP or URL</string>
|
||||||
<string name="episodes">Episodes</string>
|
<string name="episodes">Episodes</string>
|
||||||
<string name="error_loading_collection">Error loading collection %1$s</string>
|
<string name="error_loading_collection">Error loading collection %1$s</string>
|
||||||
<string name="external_track">External</string>
|
<string name="external_track">External</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue