Skip to content

Commit

Permalink
created dogmazic version for playstore
Browse files Browse the repository at this point in the history
  • Loading branch information
icefields committed May 28, 2024
1 parent db4cc6f commit 7262bb1
Show file tree
Hide file tree
Showing 50 changed files with 1,279 additions and 257 deletions.
15 changes: 14 additions & 1 deletion .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified app/FDroid/release/app-FDroid-release.apk
Binary file not shown.
Binary file modified app/FDroid/release/baselineProfiles/0/app-FDroid-release.dm
Binary file not shown.
Binary file modified app/FDroid/release/baselineProfiles/1/app-FDroid-release.dm
Binary file not shown.
4 changes: 2 additions & 2 deletions app/FDroid/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 55,
"versionName": "1.00-55-fdroid",
"versionCode": 56,
"versionName": "1.00-56-fdroid",
"outputFile": "app-FDroid-release.apk"
}
],
Expand Down
37 changes: 29 additions & 8 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ plugins {
id("com.google.devtools.ksp")
}

val composeVersion = "1.6.6" // rootProject.extra.get("compose_version") as String
val lifecycleVersion = "2.7.0"
val composeVersion = "1.6.7" // rootProject.extra.get("compose_version") as String
val lifecycleVersion = "2.8.0"
val retrofit2Version = "2.9.0"
val coroutinesVersion = "1.7.3"
val exoplayerVersion = "2.19.1"
Expand All @@ -37,6 +37,7 @@ android {
val ampachePass = properties.getProperty("AMPACHE_PASSWORD")
val ampacheUrl = properties.getProperty("AMPACHE_URL")
val ampacheUrlLocal = properties.getProperty("LOCAL_STABLE_URL")
val dogmazicUrl = properties.getProperty("DOGMAZIC_URL")
val dogmazicPass = properties.getProperty("DOGMAZIC_PASSWORD")
val dogmazicUser = properties.getProperty("DOGMAZIC_USER")
val dogmazicEmail = properties.getProperty("DOGMAZIC_EMAIL")
Expand All @@ -54,9 +55,9 @@ android {
applicationId = "luci.sixsixsix.powerampache2"
minSdk = 28
targetSdk = 34
versionCode = 56
versionName = "1.00-56"
val versionQuote = "This version is powered by financial debt"
versionCode = 57
versionName = "1.00-57"
val versionQuote = "This version is powered by Pluto the planet"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand All @@ -75,6 +76,10 @@ android {
buildConfigField("String", "LOCAL_NEXTCLOUD_URL", localNextcloudUrl)
buildConfigField("String", "DEBUG_LOCAL_STABLE_URL", ampacheUrlLocal)
buildConfigField("String", "DEBUG_LOCAL_DEVELOPMENT_URL", localDevUrl)
buildConfigField("String", "DOGMAZIC_URL", dogmazicUrl)
buildConfigField("String", "DEFAULT_SERVER_URL", "\"\"")
buildConfigField("boolean", "FORCE_LOGIN_DIALOG_ON_ALL_VERSIONS", "true")
buildConfigField("boolean", "DEMO_VERSION", "false")
}

buildTypes {
Expand Down Expand Up @@ -149,13 +154,15 @@ android {
val flavourGithub = "Github"
val flavourFDroid = "FDroid"
val flavourPlayStore = "PlayStore"
val flavourPlayStoreFree = "PlayStoreFree"

flavorDimensions += "ampache"
productFlavors {
create(flavourGithub) {
dimension = "ampache"

buildConfigField("boolean", "SHOW_LOGIN_SERVER_VERSION_WARNING", "true")
buildConfigField("boolean", "HIDE_DONATION", "false")
buildConfigField("String", "URL_ERROR_LOG", "\"https://pastebin.com/api/\"")
buildConfigField("String", "PASTEBIN_API_KEY", pastebinApiKey)
}
Expand All @@ -165,6 +172,7 @@ android {
versionNameSuffix = "-fdroid"

buildConfigField("boolean", "SHOW_LOGIN_SERVER_VERSION_WARNING", "true")
buildConfigField("boolean", "HIDE_DONATION", "false")
buildConfigField("String", "URL_ERROR_LOG", "\"https://pastebin.com/api/\"")
buildConfigField("String", "PASTEBIN_API_KEY", pastebinApiKey)
}
Expand All @@ -174,7 +182,20 @@ android {
versionNameSuffix = "-play"

buildConfigField("boolean", "SHOW_LOGIN_SERVER_VERSION_WARNING", "true")
buildConfigField("String", "URL_ERROR_LOG", errorLogUrl)
buildConfigField("boolean", "HIDE_DONATION", "true")
buildConfigField("String", "URL_ERROR_LOG", "\"https://pastebin.com/api/\"")
buildConfigField("String", "PASTEBIN_API_KEY", pastebinApiKey)
}
create(flavourPlayStoreFree) {
dimension = "ampache"
applicationIdSuffix = ".free"
versionNameSuffix = "-free"

buildConfigField("boolean", "SHOW_LOGIN_SERVER_VERSION_WARNING", "true")
buildConfigField("boolean", "HIDE_DONATION", "true")
buildConfigField("boolean", "DEMO_VERSION", "true")
buildConfigField("String", "DEFAULT_SERVER_URL", dogmazicUrl)
buildConfigField("String", "URL_ERROR_LOG", "\"https://pastebin.com/api/\"")
buildConfigField("String", "PASTEBIN_API_KEY", pastebinApiKey)
}
}
Expand Down Expand Up @@ -206,7 +227,7 @@ android {
}

dependencies {
implementation("androidx.core:core-ktx:1.13.0")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
implementation("androidx.activity:activity-compose:1.9.0")
implementation("androidx.media:media:1.7.0")
Expand All @@ -221,7 +242,7 @@ dependencies {
implementation("androidx.compose.ui:ui-graphics:$composeVersion")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleVersion")
implementation("com.google.accompanist:accompanist-flowlayout:0.17.0")
implementation("androidx.paging:paging-compose:3.3.0-beta01")
implementation("androidx.paging:paging-compose:3.3.0")
implementation("androidx.activity:activity-compose:1.9.0")
implementation("com.google.accompanist:accompanist-swiperefresh:0.24.2-alpha")
implementation("androidx.lifecycle:lifecycle-runtime-compose:$lifecycleVersion")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/**
* Copyright (C) 2024 Antonio Tari
*
* This file is a part of Power Ampache 2
* Ampache Android client application
* @author Antonio Tari
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http:https://www.gnu.org/licenses/>.
*
*/
package luci.sixsixsix.powerampache2.data

import android.app.Application
import androidx.lifecycle.asFlow
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map
import androidx.media3.common.PlaybackException
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.HttpDataSource
import com.google.gson.Gson
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import luci.sixsixsix.mrlog.L
import luci.sixsixsix.powerampache2.BuildConfig
import luci.sixsixsix.powerampache2.BuildConfig.ENABLE_ERROR_LOG
import luci.sixsixsix.powerampache2.BuildConfig.URL_ERROR_LOG
import luci.sixsixsix.powerampache2.R
import luci.sixsixsix.powerampache2.common.Resource
import luci.sixsixsix.powerampache2.common.getVersionInfoString
import luci.sixsixsix.powerampache2.data.local.MusicDatabase
import luci.sixsixsix.powerampache2.data.remote.ErrorHandlerApi
import luci.sixsixsix.powerampache2.data.remote.MainNetwork
import luci.sixsixsix.powerampache2.domain.errors.ErrorHandler
import luci.sixsixsix.powerampache2.domain.errors.ErrorType
import luci.sixsixsix.powerampache2.domain.errors.MusicException
import luci.sixsixsix.powerampache2.domain.errors.ScrobbleException
import luci.sixsixsix.powerampache2.domain.errors.ServerUrlNotInitializedException
import luci.sixsixsix.powerampache2.domain.errors.UserNotEnabledException
import luci.sixsixsix.powerampache2.player.MusicPlaylistManager
import retrofit2.HttpException
import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton

@OptIn(DelicateCoroutinesApi::class)
@Singleton
class ErrorHandlerImpl @Inject constructor(
private val playlistManager: MusicPlaylistManager,
private val db: MusicDatabase,
private val api: ErrorHandlerApi,
private val applicationContext: Application
): ErrorHandler {

private var isErrorHandlingEnabled = ENABLE_ERROR_LOG

init {
GlobalScope.launch {
db.dao.settingsLiveData()
.map { it?.enableRemoteLogging }
.distinctUntilChanged()
.asFlow()
.filterNotNull().collectLatest {
if (it != isErrorHandlingEnabled) {
isErrorHandlingEnabled = it
L.e("ERROR hand enabled? $isErrorHandlingEnabled")
}
}
}
}

@androidx.annotation.OptIn(UnstableApi::class)
override suspend fun <T> invoke(
label: String,
e: Throwable,
fc: FlowCollector<Resource<T>>?,
onError: (message: String, e: Throwable) -> Unit
) {
// Blocking errors for server url not initialized
// this is an exception generated by the interceptor for when a url has not yet been
// initialized by the user
if (e is MusicException && e.musicError.isServerUrlNotInitialized()) {
L("ServerUrlNotInitializedException")
fc?.emit(Resource.Loading(false))
return
}

val exceptionString = try { Gson().toJson(e) } catch (jsonException: Exception) { "$e" }

var readableMessage: String? = null
StringBuilder(label)
.append(if (label.isBlank()) "" else " - ")
.append(
when (e) {
is UserNotEnabledException -> {
L("aaaa user not enabled $exceptionString")
readableMessage = "User not enabled, please check your email for the account confirmation link or enable the user from the server"
"PlaybackException \n $exceptionString"
}
is HttpDataSource.InvalidResponseCodeException -> {
readableMessage = "Problem connecting to the server or data source. \nPlay a different track or check your connection\nResponse code: ${e.responseCode}"
"HttpDataSource.InvalidResponseCodeException \n$label\n $exceptionString"
}

is HttpDataSource.HttpDataSourceException -> {
readableMessage = "Problem connecting to the server or data source. \nPlay a different track or check your connection"
"HttpDataSource.HttpDataSourceException \n$readableMessage\n $exceptionString"
}

is PlaybackException -> {
readableMessage =
if (exceptionString.lowercase().contains("User disabled".lowercase())) exceptionString else
"Issues playing this track. The issue could be related to your connection, the file might be corrupt, or overall trouble communicating with your server.\nIf this is an offline track please try delete and re-download"

"PlaybackException \n$readableMessage\n $exceptionString"
}

is IOException -> {
readableMessage = applicationContext.getString(R.string.error_io_exception)
"cannot load data IOException $exceptionString"
}

is HttpException -> {
readableMessage = e.localizedMessage
"cannot load data HttpException $exceptionString"
}

is ServerUrlNotInitializedException ->
"ServerUrlNotInitializedException $exceptionString"
is ScrobbleException -> {
readableMessage = ""
""
}
is MusicException -> {
when (e.musicError.getErrorType()) {
ErrorType.ACCOUNT -> {
// clear session and try to autologin using the saved credentials
db.dao.clearSession()
readableMessage = e.musicError.errorMessage
}

ErrorType.EMPTY ->
readableMessage =
applicationContext.getString(R.string.error_empty_result)

ErrorType.DUPLICATE ->
readableMessage =
applicationContext.getString(R.string.error_duplicate)

ErrorType.Other ->
readableMessage = e.musicError.errorMessage

ErrorType.SYSTEM ->
readableMessage = e.musicError.errorMessage
}
e.musicError.toString()
}

else -> {
readableMessage = e.localizedMessage
"generic exception $exceptionString"
}
}
).toString().apply {
// check on error on the emitted data for detailed logging
fc?.emit(Resource.Error(message = this, exception = e))
// log and report error here
logError(e, this)
playlistManager.updateErrorLogMessage(this)
// readable message here
readableMessage?.let {
// TODO find a better way to not show verbose info
// ie. session expired for timestamp
if (e is HttpException || e is IOException) {
playlistManager.updateUserMessage(applicationContext.getString(R.string.error_offline))
} else if (!readableMessage.lowercase().contains("timestamp") &&
!readableMessage.lowercase().contains("expired") &&
!readableMessage.lowercase().contains("session")) {
playlistManager.updateUserMessage(readableMessage)
} else if (e is UserNotEnabledException) {
playlistManager.updateUserMessage(readableMessage)
}
}
onError(this, e)
L.e(readableMessage, e)
}
}

override suspend fun logError(e: Throwable, message: String) = logError(message = "${e.stackTraceToString()}\n$message")

override suspend fun logError(message: String) {
try {
if (isErrorHandlingEnabled && !URL_ERROR_LOG.isNullOrBlank()) {
api.sendErrorReport(apiPasteCode = "${getVersionInfoString(applicationContext)}\n$message")
}
} catch (e: Exception) {
if (e is HttpException)
L.e(e.stackTraceToString(), e.message(), e.localizedMessage, e.code(), e.response())
else
L.e(e.stackTraceToString(), e.localizedMessage)
}
}
}
Loading

0 comments on commit 7262bb1

Please sign in to comment.