@@ -5,6 +5,7 @@ import android.net.Uri
5
5
import android.util.Log
6
6
import com.apkupdater.data.ui.AppInstalled
7
7
import com.apkupdater.data.ui.AppUpdate
8
+ import com.apkupdater.data.ui.Link
8
9
import com.apkupdater.data.ui.PlaySource
9
10
import com.apkupdater.data.ui.getPackageNames
10
11
import com.apkupdater.data.ui.getVersion
@@ -14,71 +15,115 @@ import com.apkupdater.util.play.NativeDeviceInfoProvider
14
15
import com.apkupdater.util.play.PlayHttpClient
15
16
import com.aurora.gplayapi.data.models.App
16
17
import com.aurora.gplayapi.data.models.AuthData
18
+ import com.aurora.gplayapi.data.models.File
17
19
import com.aurora.gplayapi.helpers.AppDetailsHelper
18
20
import com.aurora.gplayapi.helpers.PurchaseHelper
21
+ import com.aurora.gplayapi.helpers.SearchHelper
19
22
import com.google.gson.Gson
23
+ import kotlinx.coroutines.CoroutineScope
24
+ import kotlinx.coroutines.Dispatchers
25
+ import kotlinx.coroutines.FlowPreview
20
26
import kotlinx.coroutines.flow.catch
27
+ import kotlinx.coroutines.flow.debounce
28
+ import kotlinx.coroutines.flow.filter
21
29
import kotlinx.coroutines.flow.flow
30
+ import kotlinx.coroutines.flow.launchIn
31
+ import kotlinx.coroutines.flow.onEach
22
32
23
33
34
+ @OptIn(FlowPreview ::class )
24
35
class PlayRepository (
25
36
private val context : Context ,
26
37
private val gson : Gson ,
27
38
private val prefs : Prefs
28
39
) {
29
- private suspend fun auth (): AuthData {
40
+ companion object {
41
+ const val AUTH_URL = " https://auroraoss.com/api/auth"
42
+ }
43
+
44
+ init {
45
+ // TODO: Needs testing.
46
+ PlayHttpClient .responseCode
47
+ .filter { it == 401 }
48
+ .debounce(60 * 5 * 1_000 )
49
+ .onEach { runCatching { refreshAuth() }.getOrNull() }
50
+ .launchIn(CoroutineScope (Dispatchers .IO ))
51
+ }
52
+
53
+ private fun refreshAuth (): AuthData {
54
+ val properties = NativeDeviceInfoProvider (context).getNativeDeviceProperties()
55
+ val playResponse = PlayHttpClient .postAuth(AUTH_URL , gson.toJson(properties).toByteArray())
56
+ if (playResponse.isSuccessful) {
57
+ val authData = gson.fromJson(String (playResponse.responseBytes), AuthData ::class .java)
58
+ prefs.playAuthData.put(authData)
59
+ return authData
60
+ }
61
+ throw IllegalStateException (" Auth not successful." )
62
+ }
63
+
64
+ private fun auth (): AuthData {
30
65
val savedData = prefs.playAuthData.get()
31
66
if (savedData.email.isEmpty()) {
32
- val properties = NativeDeviceInfoProvider (context).getNativeDeviceProperties()
33
- val playResponse = PlayHttpClient .postAuth(
34
- " https://auroraoss.com/api/auth" ,
35
- gson.toJson(properties).toByteArray()
36
- )
37
- if (playResponse.isSuccessful) {
38
- val authData = gson.fromJson(String (playResponse.responseBytes), AuthData ::class .java)
39
- prefs.playAuthData.put(authData)
40
- return authData
41
- }
42
- throw IllegalStateException (" Auth not successful." )
67
+ return refreshAuth()
43
68
}
44
69
return savedData
45
70
}
46
71
47
72
suspend fun search (text : String ) = flow {
48
73
if (text.contains(" " ) || ! text.contains(" ." )) {
49
- emit(Result .success(emptyList()))
50
- return @flow
74
+ // Normal Search
75
+ val authData = auth()
76
+ val updates = SearchHelper (authData)
77
+ .using(PlayHttpClient )
78
+ .searchResults(text)
79
+ .appList
80
+ .take(5 )
81
+ .map { it.toAppUpdate(::getInstallFiles) }
82
+ emit(Result .success(updates))
83
+ } else {
84
+ // Package Name Search
85
+ val authData = auth()
86
+ val update = AppDetailsHelper (authData)
87
+ .using(PlayHttpClient )
88
+ .getAppByPackageName(text)
89
+ .toAppUpdate(::getInstallFiles)
90
+ emit(Result .success(listOf (update)))
51
91
}
52
- val authData = auth()
53
- val app = AppDetailsHelper (authData)
54
- .using(PlayHttpClient )
55
- .getAppByPackageName(text)
56
- val update = app.toAppUpdate(PurchaseHelper (authData))
57
- emit(Result .success(listOf (update)))
58
92
}.catch {
59
93
emit(Result .failure(it))
60
- Log .e(" PlayRepository" , " Error searching." , it)
94
+ Log .e(" PlayRepository" , " Error searching for $text ." , it)
61
95
}
62
96
63
97
suspend fun updates (apps : List <AppInstalled >) = flow {
64
98
val authData = auth()
65
99
val details = AppDetailsHelper (authData)
66
100
.using(PlayHttpClient )
67
101
.getAppByPackageName(apps.getPackageNames())
68
- val purchaseHelper = PurchaseHelper (authData)
69
102
val updates = details
70
103
.filter { it.versionCode > apps.getVersionCode(it.packageName) }
71
- .map { it.toAppUpdate(purchaseHelper, apps.getVersion(it.packageName), apps.getVersionCode(it.packageName)) }
104
+ .map {
105
+ it.toAppUpdate(
106
+ ::getInstallFiles,
107
+ apps.getVersion(it.packageName),
108
+ apps.getVersionCode(it.packageName)
109
+ )
110
+ }
72
111
emit(updates)
73
112
}.catch {
74
113
emit(emptyList())
75
- Log .e(" AptoideRepository " , " Error looking for updates." , it)
114
+ Log .e(" PlayRepository " , " Error looking for updates." , it)
76
115
}
77
116
117
+ private fun getInstallFiles (app : App ) = PurchaseHelper (auth())
118
+ .using(PlayHttpClient )
119
+ .purchase(app.packageName, app.versionCode, app.offerType)
120
+ .filter { it.type == File .FileType .BASE || it.type == File .FileType .SPLIT }
121
+ .map { it.url }
122
+
78
123
}
79
124
80
125
fun App.toAppUpdate (
81
- purchaseHelper : PurchaseHelper ,
126
+ getInstallFiles : ( App ) -> List < String > ,
82
127
oldVersion : String = "",
83
128
oldVersionCode : Long = 0L
84
129
) = AppUpdate (
@@ -90,6 +135,6 @@ fun App.toAppUpdate(
90
135
oldVersionCode,
91
136
PlaySource ,
92
137
Uri .parse(iconArtwork.url),
93
- purchaseHelper.purchase(packageName, versionCode, offerType).joinToString( " , " ) { it.url },
138
+ Link . Play { getInstallFiles( this ) },
94
139
whatsNew = changes
95
140
)
0 commit comments