1
0
mirror of https://github.com/ultrasonic/ultrasonic synced 2025-03-13 10:00:23 +01:00

Merge pull request from Maxmystere/check-server-features

Implement server feature checking
This commit is contained in:
Nite 2021-06-01 15:37:56 +02:00 committed by GitHub
commit 0a886d7095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 149 additions and 38 deletions
ultrasonic/src/main
java/org/moire/ultrasonic/util
kotlin/org/moire/ultrasonic
res
values-cs
values-de
values-es
values-fr
values-hu
values-it
values-nl
values-pl
values-pt-rBR
values-pt
values-ru
values-zh-rCN
values

@ -594,16 +594,16 @@ public class Util
}
private static void showDialog(Context context, int icon, int titleId, int messageId)
// The AlertDialog requires an Activity context, app context is not enough
// See https://stackoverflow.com/questions/5436822/
public static void showDialog(Context context, int icon, int titleId, String message)
{
new AlertDialog.Builder(context).setIcon(icon).setTitle(titleId).setMessage(messageId).setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int i)
{
dialog.dismiss();
}
}).show();
new AlertDialog.Builder(context)
.setIcon(icon)
.setTitle(titleId)
.setMessage(message)
.setPositiveButton(R.string.common_ok, (dialog, i) -> dialog.dismiss())
.show();
}

@ -29,7 +29,9 @@ import androidx.preference.PreferenceManager
import com.google.android.material.navigation.NavigationView
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.java.KoinJavaComponent.inject
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.fragment.OnBackPressedHandler
@ -368,10 +370,18 @@ class NavigationActivity : AppCompatActivity() {
}
private fun setMenuForServerSetting() {
val visibility = !isOffline()
chatMenuItem?.isVisible = visibility
bookmarksMenuItem?.isVisible = visibility
sharesMenuItem?.isVisible = visibility
podcastsMenuItem?.isVisible = visibility
if (isOffline()) {
chatMenuItem?.isVisible = false
bookmarksMenuItem?.isVisible = false
sharesMenuItem?.isVisible = false
podcastsMenuItem?.isVisible = false
return
}
val activeServerProvider: ActiveServerProvider by inject()
val activeServer = activeServerProvider.getActiveServer()
chatMenuItem?.isVisible = activeServer.chatSupport != false
bookmarksMenuItem?.isVisible = activeServer.bookmarkSupport != false
sharesMenuItem?.isVisible = activeServer.shareSupport != false
podcastsMenuItem?.isVisible = activeServer.podcastSupport != false
}
}

@ -8,7 +8,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
/**
* Room Database to be used to store data for Ultrasonic
*/
@Database(entities = [ServerSetting::class], version = 2)
@Database(entities = [ServerSetting::class], version = 3)
abstract class AppDatabase : RoomDatabase() {
/**
@ -24,3 +24,20 @@ val MIGRATION_1_2: Migration = object : Migration(1, 2) {
)
}
}
val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"ALTER TABLE ServerSetting ADD COLUMN chatSupport INTEGER"
)
database.execSQL(
"ALTER TABLE ServerSetting ADD COLUMN bookmarkSupport INTEGER"
)
database.execSQL(
"ALTER TABLE ServerSetting ADD COLUMN shareSupport INTEGER"
)
database.execSQL(
"ALTER TABLE ServerSetting ADD COLUMN podcastSupport INTEGER"
)
}
}

@ -29,7 +29,11 @@ data class ServerSetting(
@ColumnInfo(name = "allowSelfSignedCertificate") var allowSelfSignedCertificate: Boolean,
@ColumnInfo(name = "ldapSupport") var ldapSupport: Boolean,
@ColumnInfo(name = "musicFolderId") var musicFolderId: String?,
@ColumnInfo(name = "minimumApiVersion") var minimumApiVersion: String?
@ColumnInfo(name = "minimumApiVersion") var minimumApiVersion: String?,
@ColumnInfo(name = "chatSupport") var chatSupport: Boolean? = null,
@ColumnInfo(name = "bookmarkSupport") var bookmarkSupport: Boolean? = null,
@ColumnInfo(name = "shareSupport") var shareSupport: Boolean? = null,
@ColumnInfo(name = "podcastSupport") var podcastSupport: Boolean? = null
) {
constructor() : this (
-1, 0, "", "", "", "", false, false, false, null, null

@ -7,6 +7,7 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.moire.ultrasonic.data.AppDatabase
import org.moire.ultrasonic.data.MIGRATION_1_2
import org.moire.ultrasonic.data.MIGRATION_2_3
import org.moire.ultrasonic.fragment.ServerSettingsModel
import org.moire.ultrasonic.util.Util
@ -25,6 +26,7 @@ val appPermanentStorage = module {
"ultrasonic-database"
)
.addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3)
.fallbackToDestructiveMigrationOnDowngrade()
.build()
}

@ -11,8 +11,10 @@ import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.textfield.TextInputLayout
import java.io.IOException
import java.net.MalformedURLException
import java.net.URL
import java.util.Locale
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.moire.ultrasonic.BuildConfig
@ -20,14 +22,17 @@ import org.moire.ultrasonic.R
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ServerSetting
import org.moire.ultrasonic.service.ApiCallResponseChecker
import org.moire.ultrasonic.service.MusicServiceFactory
import org.moire.ultrasonic.service.SubsonicRESTException
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.ErrorDialog
import org.moire.ultrasonic.util.ModalBackgroundTask
import org.moire.ultrasonic.util.Util
import retrofit2.Response
import timber.log.Timber
/**
@ -295,14 +300,41 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
* Tests if the network connection to the entered Server Settings can be made
*/
private fun testConnection() {
val task: ModalBackgroundTask<Boolean> = object : ModalBackgroundTask<Boolean>(
val task: ModalBackgroundTask<String> = object : ModalBackgroundTask<String>(
activity,
false
) {
fun boolToMark(value: Boolean?): String {
if (value == null)
return ""
return if (value) "✔️" else ""
}
fun getProgress(): String {
return String.format(
"""
|%s - ${resources.getString(R.string.button_bar_chat)}
|%s - ${resources.getString(R.string.button_bar_bookmarks)}
|%s - ${resources.getString(R.string.button_bar_shares)}
|%s - ${resources.getString(R.string.button_bar_podcasts)}
""".trimMargin(),
boolToMark(currentServerSetting!!.chatSupport),
boolToMark(currentServerSetting!!.bookmarkSupport),
boolToMark(currentServerSetting!!.shareSupport),
boolToMark(currentServerSetting!!.podcastSupport)
)
}
@Throws(Throwable::class)
override fun doInBackground(): Boolean {
updateProgress(R.string.settings_testing_connection)
override fun doInBackground(): String {
currentServerSetting!!.chatSupport = null
currentServerSetting!!.bookmarkSupport = null
currentServerSetting!!.shareSupport = null
currentServerSetting!!.podcastSupport = null
updateProgress(getProgress())
val configuration = SubsonicClientConfiguration(
currentServerSetting!!.url,
currentServerSetting!!.userName,
@ -330,17 +362,62 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
pingResponse = subsonicApiClient.api.ping().execute()
ApiCallResponseChecker.checkResponseSuccessful(pingResponse)
val licenseResponse = subsonicApiClient.api.getLicense().execute()
ApiCallResponseChecker.checkResponseSuccessful(licenseResponse)
return licenseResponse.body()!!.license.valid
currentServerSetting!!.chatSupport = isServerFunctionAvailable {
subsonicApiClient.api.getChatMessages().execute()
}
override fun done(licenseValid: Boolean) {
if (licenseValid) {
Util.toast(activity, R.string.settings_testing_ok)
} else {
Util.toast(activity, R.string.settings_testing_unlicensed)
updateProgress(getProgress())
currentServerSetting!!.bookmarkSupport = isServerFunctionAvailable {
subsonicApiClient.api.getBookmarks().execute()
}
updateProgress(getProgress())
currentServerSetting!!.shareSupport = isServerFunctionAvailable {
subsonicApiClient.api.getShares().execute()
}
updateProgress(getProgress())
currentServerSetting!!.podcastSupport = isServerFunctionAvailable {
subsonicApiClient.api.getPodcasts().execute()
}
updateProgress(getProgress())
val licenseResponse = subsonicApiClient.api.getLicense().execute()
ApiCallResponseChecker.checkResponseSuccessful(licenseResponse)
if (!licenseResponse.body()!!.license.valid) {
return getProgress() + "\n" +
resources.getString(R.string.settings_testing_unlicensed)
}
return getProgress()
}
override fun done(responseString: String) {
var dialogText = responseString
if (arrayOf(
currentServerSetting!!.chatSupport,
currentServerSetting!!.bookmarkSupport,
currentServerSetting!!.shareSupport,
currentServerSetting!!.podcastSupport
).any { x -> x == false }
) {
dialogText = String.format(
Locale.ROOT,
"%s\n\n%s",
responseString,
resources.getString(R.string.server_editor_disabled_feature)
)
}
Util.showDialog(
activity,
android.R.drawable.ic_dialog_info,
R.string.settings_testing_ok,
dialogText
)
}
override fun error(error: Throwable) {
@ -359,6 +436,18 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
task.execute()
}
private fun isServerFunctionAvailable(function: () -> Response<out SubsonicResponse>): Boolean {
return try {
val response = function()
ApiCallResponseChecker.checkResponseSuccessful(response)
true
} catch (_: IOException) {
false
} catch (_: SubsonicRESTException) {
false
}
}
/**
* Finishes the Activity, after confirmation from the user if needed
*/

@ -297,7 +297,6 @@
<string name="settings.show_track_number">Zobrazovat číslo skladby</string>
<string name="settings.show_track_number_summary">Připojovat číslo skladby při zobrazování skladby</string>
<string name="settings.test_connection_title">Test připojení</string>
<string name="settings.testing_connection">Testuji připojení&#8230;</string>
<string name="settings.testing_ok">Připojení je v pořádku</string>
<string name="settings.testing_unlicensed">Připojení je v pořádku. Server bez licence.</string>
<string name="settings.theme_light">Světlý</string>

@ -296,7 +296,6 @@
<string name="settings.show_track_number">Titelnummer anzeigen</string>
<string name="settings.show_track_number_summary">Titel mit Nummer anzeigen</string>
<string name="settings.test_connection_title">Verbindung testen</string>
<string name="settings.testing_connection">Teste Verbindung&#8230;</string>
<string name="settings.testing_ok">Verbindung OK</string>
<string name="settings.testing_unlicensed">Verbindung OK, Server nicht lizensiert.</string>
<string name="settings.theme_light">Hell</string>

@ -309,7 +309,6 @@
<string name="settings.show_track_number">Mostrar número de pista</string>
<string name="settings.show_track_number_summary">Incluir el número de pista cuando se muestre una canción</string>
<string name="settings.test_connection_title">Comprobar conexión</string>
<string name="settings.testing_connection">Comprobado conexión&#8230;</string>
<string name="settings.testing_ok">La conexión es correcta</string>
<string name="settings.testing_unlicensed">La conexión es correcta. Servidor sin licencia.</string>
<string name="settings.theme_light">Claro</string>

@ -297,7 +297,6 @@
<string name="settings.show_track_number">Afficher le numéro du titre</string>
<string name="settings.show_track_number_summary">Inclure son numero lors de l\'affichage d\'un titre</string>
<string name="settings.test_connection_title">Tester la connexion</string>
<string name="settings.testing_connection">Connexion en cours de test&#8230;</string>
<string name="settings.testing_ok">Connexion correcte</string>
<string name="settings.testing_unlicensed">Connexion correcte. Serveur sans licence.</string>
<string name="settings.theme_light">Clair</string>
@ -499,5 +498,6 @@
<string name="feature_flags_five_star_rating_description">Utiliser un système de notation à base d\'étoiles pour les morceaux
au lieu de simplement mettre en avant les morceaux.
</string>
<string name="server_editor.disabled_feature">Une ou plusieurs fonctionnalités ont été désactivées car le serveur ne les prend pas en charge.\nVous pouvez réexécuter ce test à tout moment.</string>
</resources>

@ -297,7 +297,6 @@
<string name="settings.show_track_number">Sorszám megjelenítése</string>
<string name="settings.show_track_number_summary">Dalok sorszámának megjelenítése.</string>
<string name="settings.test_connection_title">Kapcsolat tesztelése</string>
<string name="settings.testing_connection">Kapcsolat tesztelése&#8230;</string>
<string name="settings.testing_ok">Kapcsolat OK!</string>
<string name="settings.testing_unlicensed">Kapcsolat OK! A kiszolgálónak nincs licence!</string>
<string name="settings.theme_light">Világos</string>

@ -289,7 +289,6 @@
<string name="settings.show_track_number">Visualizza numero traccia</string>
<string name="settings.show_track_number_summary">Includi numero traccia quando visualizzi una canzone</string>
<string name="settings.test_connection_title">Prova Connessione</string>
<string name="settings.testing_connection">Collaudo connessione&#8230;</string>
<string name="settings.testing_ok">Connessione OK</string>
<string name="settings.testing_unlicensed">Connessione OK. Server senza licenza.</string>
<string name="settings.theme_light">Chiaro</string>

@ -307,7 +307,6 @@
<string name="settings.show_track_number">Itemnummer tonen</string>
<string name="settings.show_track_number_summary">Itemnummer tonen tijdens tonen van nummers</string>
<string name="settings.test_connection_title">Verbinding testen</string>
<string name="settings.testing_connection">Bezig met testen van verbinding&#8230;</string>
<string name="settings.testing_ok">Verbinding is goed</string>
<string name="settings.testing_unlicensed">Verbinding is goed; geen serverlicentie.</string>
<string name="settings.theme_light">Licht</string>

@ -295,7 +295,6 @@
<string name="settings.show_track_number">Wyświetlaj numer utworu</string>
<string name="settings.show_track_number_summary">Dołącza numer utworu podczas wyświetlania utworu</string>
<string name="settings.test_connection_title">Testuj połączenie</string>
<string name="settings.testing_connection">Trwa testowanie połączenia&#8230;</string>
<string name="settings.testing_ok">Połączenie jest OK</string>
<string name="settings.testing_unlicensed">Połączenie jest OK. Brak licencji na serwerze.</string>
<string name="settings.theme_light">Jasny</string>

@ -297,7 +297,6 @@
<string name="settings.show_track_number">Mostrar o Número da Faixa</string>
<string name="settings.show_track_number_summary">Incluir o número da faixa quando mostrando uma música</string>
<string name="settings.test_connection_title">Teste de Conexão</string>
<string name="settings.testing_connection">Testando conexão&#8230;</string>
<string name="settings.testing_ok">Conexão OK</string>
<string name="settings.testing_unlicensed">Conexão OK. Servidor não licenciado.</string>
<string name="settings.theme_light">Claro</string>

@ -295,7 +295,6 @@
<string name="settings.show_track_number">Mostrar o Número da Faixa</string>
<string name="settings.show_track_number_summary">Incluir o número da faixa quando mostrando uma música</string>
<string name="settings.test_connection_title">Teste de Conexão</string>
<string name="settings.testing_connection">Testando conexão&#8230;</string>
<string name="settings.testing_ok">Conexão OK</string>
<string name="settings.testing_unlicensed">Conexão OK. Servidor não licenciado.</string>
<string name="settings.theme_light">Claro</string>

@ -290,7 +290,6 @@
<string name="settings.show_track_number">Показать номер трека</string>
<string name="settings.show_track_number_summary">Включить номер дорожки при отображении песни</string>
<string name="settings.test_connection_title">Тестовое соединение</string>
<string name="settings.testing_connection">Тестирование соединения&#8230;</string>
<string name="settings.testing_ok">Успешное соединение</string>
<string name="settings.testing_unlicensed">Успешное соединение. Сервер нелицензионный.</string>
<string name="settings.theme_light">Светлая</string>

@ -220,7 +220,6 @@
<string name="settings.show_notification">显示通知</string>
<string name="settings.show_notification_always">总是显示通知</string>
<string name="settings.test_connection_title">测试连接</string>
<string name="settings.testing_connection">测试连接&#8230;</string>
<string name="settings.testing_ok">连接正常</string>
<string name="settings.testing_unlicensed">连接正常, 服务器未授权。</string>
<string name="settings.theme_title">主题</string>

@ -311,7 +311,6 @@
<string name="settings.show_track_number">Show Track Number</string>
<string name="settings.show_track_number_summary">Include track number when displaying a song</string>
<string name="settings.test_connection_title">Test Connection</string>
<string name="settings.testing_connection">Testing connection&#8230;</string>
<string name="settings.testing_ok">Connection is OK</string>
<string name="settings.testing_unlicensed">Connection is OK. Server unlicensed.</string>
<string name="settings.theme_light">Light</string>
@ -462,6 +461,7 @@
<string name="server_menu.move_down">Move down</string>
<string name="server_editor.authentication">Authentication</string>
<string name="server_editor.advanced">Advanced settings</string>
<string name="server_editor.disabled_feature">One or more features were disabled because the server doesn\'t support them.\nYou can run this test again anytime.</string>
<plurals name="select_album_n_songs">
<item quantity="one">1 song</item>