[App] Refactor app core modules, use Timber for logging (#205)

* [App] Fix config migration issues

* Move .sync to .core

* Move .firebase, .network, .managers, .receivers, .sync to .core

* Replace HyperLog with Timber

* Cleanup logs every 7 days

* Rename NotificationChannelManager, reformat App

* Create FirebaseManager, ShortcutManager
This commit is contained in:
Kuba Szczodrzyński 2024-07-01 22:35:11 +02:00 committed by GitHub
parent 77e1acbb1e
commit e1dbc2f050
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
151 changed files with 3324 additions and 858 deletions

View File

@ -240,11 +240,11 @@ dependencies {
implementation "com.github.ChuckerTeam.Chucker:library:3.5.2" // https://github.com/ChuckerTeam/chucker implementation "com.github.ChuckerTeam.Chucker:library:3.5.2" // https://github.com/ChuckerTeam/chucker
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2" // https://github.com/antonKozyriatskyi/CircularProgressIndicator implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2" // https://github.com/antonKozyriatskyi/CircularProgressIndicator
implementation "com.github.bassaer:chatmessageview:2.0.1" // https://github.com/bassaer/ChatMessageView implementation "com.github.bassaer:chatmessageview:2.0.1" // https://github.com/bassaer/ChatMessageView
implementation "com.github.hypertrack:hyperlog-android:0.0.10" // https://github.com/hypertrack/hyperlog-android
implementation "com.github.smuyyh:JsonViewer:V1.0.6" // https://github.com/smuyyh/JsonViewer implementation "com.github.smuyyh:JsonViewer:V1.0.6" // https://github.com/smuyyh/JsonViewer
implementation "com.github.underwindfall.PowerPermission:powerpermission-coroutines:1.4.0" // https://github.com/underwindfall/PowerPermission implementation "com.github.underwindfall.PowerPermission:powerpermission-coroutines:1.4.0" // https://github.com/underwindfall/PowerPermission
implementation "com.github.underwindfall.PowerPermission:powerpermission:1.4.0" // https://github.com/underwindfall/PowerPermission implementation "com.github.underwindfall.PowerPermission:powerpermission:1.4.0" // https://github.com/underwindfall/PowerPermission
implementation "com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31" // https://github.com/wulkanowy/uonet-request-signer implementation "com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31" // https://github.com/wulkanowy/uonet-request-signer
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation "com.jaredrummler:colorpicker:1.1.0" implementation "com.jaredrummler:colorpicker:1.1.0"
implementation "io.coil-kt:coil:1.1.1" implementation "io.coil-kt:coil:1.1.1"
implementation "me.dm7.barcodescanner:zxing:1.9.8" implementation "me.dm7.barcodescanner:zxing:1.9.8"

View File

@ -37,7 +37,7 @@
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider -keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
-keep class pl.szczodrzynski.edziennik.data.config.AppData { *; } -keep class pl.szczodrzynski.edziennik.data.config.AppData { *; }
-keep class pl.szczodrzynski.edziennik.data.config.AppData$** { *; } -keep class pl.szczodrzynski.edziennik.data.config.AppData$** { *; }
-keep class pl.szczodrzynski.edziennik.utils.managers.TextStylingManager$HtmlMode { *; } -keep class pl.szczodrzynski.edziennik.core.manager.TextStylingManager$HtmlMode { *; }
-keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); } -keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); }
-keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); } -keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); }

File diff suppressed because it is too large Load Diff

View File

@ -173,7 +173,7 @@
| | \ \ __/ (_| __/ |\ V / __/ | \__ \ | | \ \ __/ (_| __/ |\ V / __/ | \__ \
|_| \_\___|\___\___|_| \_/ \___|_| |___/ |_| \_\___|\___\___|_| \_/ \___|_| |___/
--> -->
<receiver android:name=".receivers.UserPresentReceiver" <receiver android:name=".core.receiver.UserPresentReceiver"
android:enabled="true" android:enabled="true"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
@ -186,7 +186,7 @@
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" /> <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.SzkolnyReceiver" <receiver android:name=".core.receiver.SzkolnyReceiver"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="pl.szczodrzynski.edziennik.SZKOLNY_MAIN" /> <action android:name="pl.szczodrzynski.edziennik.SZKOLNY_MAIN" />
@ -201,7 +201,7 @@
|_____/ \___|_| \_/ |_|\___\___||___/ |_____/ \___|_| \_/ |_|\___\___||___/
--> -->
<service android:name=".data.api.ApiService" android:foregroundServiceType="dataSync"/> <service android:name=".data.api.ApiService" android:foregroundServiceType="dataSync"/>
<service android:name=".data.firebase.MyFirebaseService" <service android:name=".core.firebase.MyFirebaseService"
android:exported="false" android:foregroundServiceType="dataSync"> android:exported="false" android:foregroundServiceType="dataSync">
<intent-filter android:priority="10000000"> <intent-filter android:priority="10000000">
<action android:name="com.google.firebase.MESSAGING_EVENT" /> <action android:name="com.google.firebase.MESSAGING_EVENT" />

View File

@ -4,12 +4,6 @@
package pl.szczodrzynski.edziennik package pl.szczodrzynski.edziennik
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Build
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
@ -20,12 +14,7 @@ import cat.ereza.customactivityoncrash.config.CaocConfig
import com.chuckerteam.chucker.api.ChuckerCollector import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager import com.chuckerteam.chucker.api.RetentionManager
import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions
import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.messaging.FirebaseMessaging
import com.google.gson.Gson import com.google.gson.Gson
import com.hypertrack.hyperlog.HyperLog
import com.mikepenz.iconics.Iconics import com.mikepenz.iconics.Iconics
import im.wangchao.mhttp.MHttp import im.wangchao.mhttp.MHttp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -36,41 +25,39 @@ import kotlinx.coroutines.withContext
import me.leolin.shortcutbadger.ShortcutBadger import me.leolin.shortcutbadger.ShortcutBadger
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.data.config.AppData import pl.szczodrzynski.edziennik.core.manager.AttendanceManager
import pl.szczodrzynski.edziennik.data.config.Config import pl.szczodrzynski.edziennik.core.manager.AvailabilityManager
import pl.szczodrzynski.edziennik.core.manager.BuildManager
import pl.szczodrzynski.edziennik.core.manager.EventManager
import pl.szczodrzynski.edziennik.core.manager.FirebaseManager
import pl.szczodrzynski.edziennik.core.manager.GradesManager
import pl.szczodrzynski.edziennik.core.manager.LoggingManager
import pl.szczodrzynski.edziennik.core.manager.MessageManager
import pl.szczodrzynski.edziennik.core.manager.NoteManager
import pl.szczodrzynski.edziennik.core.manager.NotificationManager
import pl.szczodrzynski.edziennik.core.manager.PermissionManager
import pl.szczodrzynski.edziennik.core.manager.ShortcutManager
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager
import pl.szczodrzynski.edziennik.core.manager.TimetableManager
import pl.szczodrzynski.edziennik.core.manager.UiManager
import pl.szczodrzynski.edziennik.core.manager.UpdateManager
import pl.szczodrzynski.edziennik.core.manager.UserActionManager
import pl.szczodrzynski.edziennik.core.network.DumbCookieJar
import pl.szczodrzynski.edziennik.core.work.SyncWorker
import pl.szczodrzynski.edziennik.core.work.UpdateWorker
import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
import pl.szczodrzynski.edziennik.data.config.AppData
import pl.szczodrzynski.edziennik.data.config.Config
import pl.szczodrzynski.edziennik.data.db.AppDb import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.data.enums.LoginType import pl.szczodrzynski.edziennik.data.enums.LoginType
import pl.szczodrzynski.edziennik.ext.DAY
import pl.szczodrzynski.edziennik.ext.MS
import pl.szczodrzynski.edziennik.ext.putExtras
import pl.szczodrzynski.edziennik.network.SSLProviderInstaller import pl.szczodrzynski.edziennik.network.SSLProviderInstaller
import pl.szczodrzynski.edziennik.network.cookie.DumbCookieJar
import pl.szczodrzynski.edziennik.sync.SyncWorker
import pl.szczodrzynski.edziennik.sync.UpdateWorker
import pl.szczodrzynski.edziennik.ui.base.CrashActivity import pl.szczodrzynski.edziennik.ui.base.CrashActivity
import pl.szczodrzynski.edziennik.data.enums.NavTarget
import pl.szczodrzynski.edziennik.utils.DebugLogFormat
import pl.szczodrzynski.edziennik.utils.PermissionChecker import pl.szczodrzynski.edziennik.utils.PermissionChecker
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import pl.szczodrzynski.edziennik.utils.managers.AttendanceManager
import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager
import pl.szczodrzynski.edziennik.utils.managers.BuildManager
import pl.szczodrzynski.edziennik.utils.managers.EventManager
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
import pl.szczodrzynski.edziennik.utils.managers.MessageManager
import pl.szczodrzynski.edziennik.utils.managers.NoteManager
import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager
import pl.szczodrzynski.edziennik.utils.managers.PermissionManager
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager
import pl.szczodrzynski.edziennik.utils.managers.UiManager
import pl.szczodrzynski.edziennik.utils.managers.TimetableManager
import pl.szczodrzynski.edziennik.utils.managers.UpdateManager
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.system.exitProcess import kotlin.system.exitProcess
@ -81,7 +68,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
lateinit var db: AppDb lateinit var db: AppDb
private set private set
lateinit var config: Config lateinit var config: Config
// private set // for LabFragment
// private set // for LabFragment
lateinit var profile: Profile lateinit var profile: Profile
private set private set
lateinit var data: AppData lateinit var data: AppData
@ -98,11 +86,14 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
val availabilityManager by lazy { AvailabilityManager(this) } val availabilityManager by lazy { AvailabilityManager(this) }
val buildManager by lazy { BuildManager(this) } val buildManager by lazy { BuildManager(this) }
val eventManager by lazy { EventManager(this) } val eventManager by lazy { EventManager(this) }
val firebaseManager by lazy { FirebaseManager(this) }
val gradesManager by lazy { GradesManager(this) } val gradesManager by lazy { GradesManager(this) }
val loggingManager by lazy { LoggingManager(this) }
val messageManager by lazy { MessageManager(this) } val messageManager by lazy { MessageManager(this) }
val noteManager by lazy { NoteManager(this) } val noteManager by lazy { NoteManager(this) }
val notificationChannelsManager by lazy { NotificationChannelsManager(this) } val notificationManager by lazy { NotificationManager(this) }
val permissionManager by lazy { PermissionManager(this) } val permissionManager by lazy { PermissionManager(this) }
val shortcutManager by lazy { ShortcutManager(this) }
val textStylingManager by lazy { TextStylingManager(this) } val textStylingManager by lazy { TextStylingManager(this) }
val timetableManager by lazy { TimetableManager(this) } val timetableManager by lazy { TimetableManager(this) }
val uiManager by lazy { UiManager(this) } val uiManager by lazy { UiManager(this) }
@ -125,8 +116,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
override val workManagerConfiguration: Configuration = Configuration.Builder() override val workManagerConfiguration: Configuration = Configuration.Builder()
.setMinimumLoggingLevel(Log.VERBOSE) .setMinimumLoggingLevel(Log.VERBOSE)
.build() .build()
val permissionChecker by lazy { PermissionChecker(this) } val permissionChecker by lazy { PermissionChecker(this) }
val gson by lazy { Gson() } val gson by lazy { Gson() }
@ -155,7 +146,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
if (devMode) { if (devMode) {
if (enableChucker) { if (enableChucker) {
val chuckerCollector = ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR) val chuckerCollector =
ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR)
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector) val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
builder.addInterceptor(chuckerInterceptor) builder.addInterceptor(chuckerInterceptor)
} }
@ -170,6 +162,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
MHttp.instance().customOkHttpClient(http) MHttp.instance().customOkHttpClient(http)
} }
val cookieJar by lazy { DumbCookieJar(this) } val cookieJar by lazy { DumbCookieJar(this) }
/* _____ _ _ /* _____ _ _
@ -180,7 +173,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___| |_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
__/ | __/ |
|__*/ |__*/
val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" } val deviceId: String by lazy {
Settings.Secure.getString(
contentResolver,
Settings.Secure.ANDROID_ID
) ?: ""
}
private var unreadBadgesAvailable = true private var unreadBadgesAvailable = true
/* _____ _ /* _____ _
@ -191,225 +189,77 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
\___/|_| |_|\_____|_| \___|\__,_|\__\__*/ \___/|_| |_|\_____|_| \___|\__,_|\__\__*/
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
CaocConfig.Builder.create()
.backgroundMode(CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM)
.enabled(true)
.showErrorDetails(true)
.showRestartButton(true)
.logErrorOnRestart(true)
.trackActivities(true)
.minTimeBetweenCrashesMs(60*1000)
.errorDrawable(R.drawable.ic_rip)
.restartActivity(MainActivity::class.java)
.errorActivity(CrashActivity::class.java)
.apply()
Iconics.init(applicationContext)
Iconics.respectFontBoundsDefault = true
// initialize companion object values // initialize Timber to enable basic logging
Timber.plant(loggingManager.logcatTree)
Timber.i("Initializing Szkolny.eu app v${BuildConfig.VERSION_NAME}")
// initialize core objects
AppData.read(this) AppData.read(this)
App.db = AppDb(this) App.db = AppDb(this)
// read and migrate global config
App.config = Config(this) App.config = Config(this)
App.config.migrate() App.config.migrate()
// add database logging to Timber
Timber.plant(loggingManager.databaseTree)
Timber.i("Initialized Szkolny.eu app v${BuildConfig.VERSION_NAME}")
devMode = config.devMode ?: BuildConfig.DEBUG devMode = config.devMode ?: BuildConfig.DEBUG
if (config.devModePassword != null) if (config.devModePassword != null)
checkDevModePassword() checkDevModePassword()
enableChucker = config.enableChucker ?: devMode enableChucker = config.enableChucker ?: devMode
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
CaocConfig.Builder.create()
.backgroundMode(CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM)
.enabled(true)
.showErrorDetails(true)
.showRestartButton(true)
.logErrorOnRestart(true)
.trackActivities(true)
.minTimeBetweenCrashesMs(60 * 1000)
.errorDrawable(R.drawable.ic_rip)
.restartActivity(MainActivity::class.java)
.errorActivity(CrashActivity::class.java)
.apply()
Iconics.init(applicationContext)
Iconics.respectFontBoundsDefault = true
Signing.getCert(this)
Utils.initializeStorageDir(this)
buildHttp()
uiManager.applyNightMode() uiManager.applyNightMode()
uiManager.applyLanguage(this) uiManager.applyLanguage(this)
if (devMode) {
HyperLog.initialize(this)
HyperLog.setLogLevel(Log.VERBOSE)
HyperLog.setLogFormat(DebugLogFormat(this))
}
if (!profileLoadById(config.lastProfileId)) { if (!profileLoadById(config.lastProfileId)) {
val success = db.profileDao().firstId?.let { profileLoadById(it) } val success = db.profileDao().firstId?.let { profileLoadById(it) }
if (success != true) if (success != true)
profileLoad(Profile(0, 0, LoginType.TEMPLATE, "")) profileLoad(Profile(0, 0, LoginType.TEMPLATE, ""))
} }
buildHttp() launch(Dispatchers.Default) {
buildManager.fetchInstalledTime()
firebaseManager.initializeApps()
loggingManager.cleanupIfNeeded()
loggingManager.cleanupHyperLogDatabase()
notificationManager.registerAllChannels()
shortcutManager.createShortcuts()
Signing.getCert(this) SSLProviderInstaller.install(applicationContext, this@App::buildHttp)
Utils.initializeStorageDir(this)
launch { if (config.sync.enabled)
withContext(Dispatchers.Default) { SyncWorker.scheduleNext(this@App, false)
SSLProviderInstaller.install(applicationContext, this@App::buildHttp) else
SyncWorker.cancelNext(this@App)
if (config.sync.enabled) if (config.sync.notifyAboutUpdates)
SyncWorker.scheduleNext(this@App, false) UpdateWorker.scheduleNext(this@App, false)
else else
SyncWorker.cancelNext(this@App) UpdateWorker.cancelNext(this@App)
}
if (config.sync.notifyAboutUpdates) db.metadataDao().countUnseen().observeForever { count: Int ->
UpdateWorker.scheduleNext(this@App, false) if (unreadBadgesAvailable)
else unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
UpdateWorker.cancelNext(this@App)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
val shortcutManager = getSystemService(ShortcutManager::class.java)
val shortcutTimetable = ShortcutInfo.Builder(this@App, "item_timetable")
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_timetable))
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
.putExtras("fragmentId" to NavTarget.TIMETABLE))
.build()
val shortcutAgenda = ShortcutInfo.Builder(this@App, "item_agenda")
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_agenda))
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
.putExtras("fragmentId" to NavTarget.AGENDA))
.build()
val shortcutGrades = ShortcutInfo.Builder(this@App, "item_grades")
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_grades))
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
.putExtras("fragmentId" to NavTarget.GRADES))
.build()
val shortcutHomework = ShortcutInfo.Builder(this@App, "item_homeworks")
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_homework))
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
.putExtras("fragmentId" to NavTarget.HOMEWORK))
.build()
val shortcutMessages = ShortcutInfo.Builder(this@App, "item_messages")
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_messages))
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
.putExtras("fragmentId" to NavTarget.MESSAGES))
.build()
shortcutManager.dynamicShortcuts = listOf(
shortcutTimetable,
shortcutAgenda,
shortcutGrades,
shortcutHomework,
shortcutMessages
)
} // shortcuts - end
notificationChannelsManager.registerAllChannels()
if (config.appInstalledTime == 0L)
try {
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
config.appRateSnackbarTime = config.appInstalledTime + 7 * DAY * MS
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
val pushMobidziennikApp = FirebaseApp.initializeApp(
this@App,
FirebaseOptions.Builder()
.setProjectId("mobidziennik")
.setStorageBucket("mobidziennik.appspot.com")
.setDatabaseUrl("https://mobidziennik.firebaseio.com")
.setGcmSenderId("747285019373")
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
.build(),
"Mobidziennik2"
)
val pushLibrusApp = FirebaseApp.initializeApp(
this@App,
FirebaseOptions.Builder()
.setProjectId("synergiadru")
.setStorageBucket("synergiadru.appspot.com")
.setDatabaseUrl("https://synergiadru.firebaseio.com")
.setGcmSenderId("513056078587")
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
.setApplicationId("1:513056078587:android:1e29083b760af544")
.build(),
"Librus"
)
val pushVulcanApp = FirebaseApp.initializeApp(
this@App,
FirebaseOptions.Builder()
.setProjectId("dzienniczekplus")
.setStorageBucket("dzienniczekplus.appspot.com")
.setDatabaseUrl("https://dzienniczekplus.firebaseio.com")
.setGcmSenderId("987828170337")
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
.build(),
"Vulcan"
)
val pushVulcanHebeApp = FirebaseApp.initializeApp(
this@App,
FirebaseOptions.Builder()
.setProjectId("dzienniczekplus")
.setStorageBucket("dzienniczekplus.appspot.com")
.setDatabaseUrl("https://dzienniczekplus.firebaseio.com")
.setGcmSenderId("987828170337")
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
.setApplicationId("1:987828170337:android:7e16404b9e5deaaa")
.build(),
"VulcanHebe"
)
try {
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult ->
val token = instanceIdResult.token
d("Firebase", "Got App token: $token")
config.sync.tokenApp = token
}
FirebaseInstanceId.getInstance(pushMobidziennikApp).instanceId.addOnSuccessListener { instanceIdResult ->
val token = instanceIdResult.token
d("Firebase", "Got Mobidziennik2 token: $token")
if (token != config.sync.tokenMobidziennik) {
config.sync.tokenMobidziennik = token
config.sync.tokenMobidziennikList = listOf()
}
}
FirebaseInstanceId.getInstance(pushLibrusApp).instanceId.addOnSuccessListener { instanceIdResult ->
val token = instanceIdResult.token
d("Firebase", "Got Librus token: $token")
if (token != config.sync.tokenLibrus) {
config.sync.tokenLibrus = token
config.sync.tokenLibrusList = listOf()
}
}
FirebaseInstanceId.getInstance(pushVulcanApp).instanceId.addOnSuccessListener { instanceIdResult ->
val token = instanceIdResult.token
d("Firebase", "Got Vulcan token: $token")
if (token != config.sync.tokenVulcan) {
config.sync.tokenVulcan = token
config.sync.tokenVulcanList = listOf()
}
}
FirebaseInstanceId.getInstance(pushVulcanHebeApp).instanceId.addOnSuccessListener { instanceIdResult ->
val token = instanceIdResult.token
d("Firebase", "Got VulcanHebe token: $token")
if (token != config.sync.tokenVulcanHebe) {
config.sync.tokenVulcanHebe = token
config.sync.tokenVulcanHebeList = listOf()
}
}
FirebaseMessaging.getInstance().subscribeToTopic(packageName)
} catch (e: IllegalStateException) {
e.printStackTrace()
}
}
db.metadataDao().countUnseen().observeForever { count: Int ->
if (unreadBadgesAvailable)
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
}
} }
} }
@ -418,7 +268,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
App.config.lastProfileId = profile.id App.config.lastProfileId = profile.id
try { try {
App.data = AppData.get(profile.loginStoreType) App.data = AppData.get(profile.loginStoreType)
d("App", "Loaded AppData: ${App.data}") Timber.d("Loaded AppData: ${App.data}")
// apply newly-added config overrides, if not changed by the user yet // apply newly-added config overrides, if not changed by the user yet
for ((key, value) in App.data.configOverrides) { for ((key, value) in App.data.configOverrides) {
val config = App.profile.config val config = App.profile.config
@ -426,7 +276,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
config[key] = value config[key] = value
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("App", "Cannot load AppData", e) Timber.e(e, "Cannot load AppData")
Toast.makeText(this, R.string.app_cannot_load_data, Toast.LENGTH_LONG).show() Toast.makeText(this, R.string.app_cannot_load_data, Toast.LENGTH_LONG).show()
exitProcess(0) exitProcess(0)
} }
@ -439,6 +289,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
} }
return false return false
} }
fun profileLoad(profileId: Int, onSuccess: (profile: Profile) -> Unit) { fun profileLoad(profileId: Int, onSuccess: (profile: Profile) -> Unit) {
launch { launch {
val success = withContext(Dispatchers.Default) { val success = withContext(Dispatchers.Default) {
@ -450,6 +301,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
profileLoadLast(onSuccess) profileLoadLast(onSuccess)
} }
} }
fun profileLoadLast(onSuccess: (profile: Profile) -> Unit) { fun profileLoadLast(onSuccess: (profile: Profile) -> Unit) {
launch { launch {
val success = withContext(Dispatchers.Default) { val success = withContext(Dispatchers.Default) {
@ -457,12 +309,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
} }
if (!success) { if (!success) {
EventBus.getDefault().post(ProfileListEmptyEvent()) EventBus.getDefault().post(ProfileListEmptyEvent())
} } else {
else {
onSuccess(profile) onSuccess(profile)
} }
} }
} }
fun profileSave() = profileSave(profile) fun profileSave() = profileSave(profile)
fun profileSave(profile: Profile) { fun profileSave(profile: Profile) {
if (profile.id == profileId) if (profile.id == profileId)
@ -474,9 +326,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
fun checkDevModePassword() { fun checkDevModePassword() {
devMode = devMode || try { devMode = devMode || try {
Utils.AESCrypt.decrypt("nWFVxY65Pa8/aRrT7EylNAencmOD+IxUY2Gg/beiIWY=", config.devModePassword) == "ok here you go it's enabled now" Utils.AESCrypt.decrypt(
"nWFVxY65Pa8/aRrT7EylNAencmOD+IxUY2Gg/beiIWY=",
config.devModePassword
) == "ok here you go it's enabled now"
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
false false
} }
} }

View File

@ -45,10 +45,10 @@ import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.data.enums.FeatureType import pl.szczodrzynski.edziennik.data.enums.FeatureType
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent import pl.szczodrzynski.edziennik.core.work.AppManagerDetectedEvent
import pl.szczodrzynski.edziennik.sync.SyncWorker import pl.szczodrzynski.edziennik.core.work.SyncWorker
import pl.szczodrzynski.edziennik.sync.UpdateStateEvent import pl.szczodrzynski.edziennik.core.work.UpdateStateEvent
import pl.szczodrzynski.edziennik.sync.UpdateWorker import pl.szczodrzynski.edziennik.core.work.UpdateWorker
import pl.szczodrzynski.edziennik.ui.base.MainSnackbar import pl.szczodrzynski.edziennik.ui.base.MainSnackbar
import pl.szczodrzynski.edziennik.data.enums.NavTarget import pl.szczodrzynski.edziennik.data.enums.NavTarget
import pl.szczodrzynski.edziennik.data.enums.NavTargetLocation import pl.szczodrzynski.edziennik.data.enums.NavTargetLocation
@ -66,9 +66,8 @@ import pl.szczodrzynski.edziennik.ui.login.LoginActivity
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
import pl.szczodrzynski.edziennik.utils.* import pl.szczodrzynski.edziennik.utils.*
import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.core.manager.AvailabilityManager.Error.Type
import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type import pl.szczodrzynski.edziennik.core.manager.UserActionManager
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.navlib.* import pl.szczodrzynski.navlib.*
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
@ -76,6 +75,7 @@ import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
import pl.szczodrzynski.navlib.drawer.NavDrawer import pl.szczodrzynski.navlib.drawer.NavDrawer
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
import timber.log.Timber
import java.io.IOException import java.io.IOException
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -123,18 +123,19 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
d(TAG, "Activity created") Timber.i("Activity created")
app.uiManager.applyTheme(this) app.uiManager.applyTheme(this)
app.uiManager.applyLanguage(this) app.uiManager.applyLanguage(this)
app.buildManager.validateBuild(this) app.buildManager.validateBuild(this)
if (App.profileId == 0) { if (App.profileId == 0) {
Timber.i("Profile is not loaded")
onProfileListEmptyEvent(ProfileListEmptyEvent()) onProfileListEmptyEvent(ProfileListEmptyEvent())
return return
} }
d(TAG, "Profile is valid, inflating views") Timber.i("Profile is valid, inflating views")
setContentView(b.root) setContentView(b.root)
@ -542,7 +543,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onProfileListEmptyEvent(event: ProfileListEmptyEvent) { fun onProfileListEmptyEvent(event: ProfileListEmptyEvent) {
d(TAG, "Profile list is empty. Launch LoginActivity.")
app.config.loginFinished = false app.config.loginFinished = false
startActivity(Intent(this, LoginActivity::class.java)) startActivity(Intent(this, LoginActivity::class.java))
finish() finish()
@ -617,7 +617,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
try { try {
startActivity(Intent(Settings.ACTION_SETTINGS)) startActivity(Intent(Settings.ACTION_SETTINGS))
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
Toast.makeText(this, R.string.app_manager_open_failed, Toast.LENGTH_SHORT) Toast.makeText(this, R.string.app_manager_open_failed, Toast.LENGTH_SHORT)
.show() .show()
} }
@ -665,11 +665,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
fun handleIntent(extras: Bundle?) { fun handleIntent(extras: Bundle?) {
d(TAG, "handleIntent() {") Timber.d("handleIntent() ${extras?.keySet()}")
extras?.keySet()?.forEach { key ->
d(TAG, " \"$key\": " + extras.get(key))
}
d(TAG, "}")
val intentProfileId = extras.getIntOrNull("profileId").takePositive() val intentProfileId = extras.getIntOrNull("profileId").takePositive()
var intentNavTarget = extras.getEnum<NavTarget>("fragmentId") var intentNavTarget = extras.getEnum<NavTarget>("fragmentId")
@ -783,17 +779,17 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
override fun onStart() { override fun onStart() {
d(TAG, "Activity started") Timber.i("Activity started")
super.onStart() super.onStart()
} }
override fun onStop() { override fun onStop() {
d(TAG, "Activity stopped") Timber.i("Activity stopped")
super.onStop() super.onStop()
} }
override fun onResume() { override fun onResume() {
d(TAG, "Activity resumed") Timber.i("Activity resumed")
val filter = IntentFilter() val filter = IntentFilter()
filter.addAction(Intent.ACTION_MAIN) filter.addAction(Intent.ACTION_MAIN)
ContextCompat.registerReceiver( ContextCompat.registerReceiver(
@ -807,14 +803,14 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
override fun onPause() { override fun onPause() {
d(TAG, "Activity paused") Timber.i("Activity paused")
unregisterReceiver(intentReceiver) unregisterReceiver(intentReceiver)
EventBus.getDefault().unregister(this) EventBus.getDefault().unregister(this)
super.onPause() super.onPause()
} }
override fun onDestroy() { override fun onDestroy() {
d(TAG, "Activity destroyed") Timber.i("Activity destroyed")
super.onDestroy() super.onDestroy()
} }
@ -868,7 +864,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
args: Bundle? = null, args: Bundle? = null,
skipBeforeNavigate: Boolean = false, skipBeforeNavigate: Boolean = false,
): Boolean { ): Boolean {
d(TAG, "navigate(profileId = ${profile?.id ?: profileId}, target = ${navTarget?.name}, args = $args)") Timber.d("navigate(profileId = ${profile?.id ?: profileId}, target = ${navTarget?.name}, args = $args)")
if (!(skipBeforeNavigate || navTarget == this.navTarget) && !canNavigate()) { if (!(skipBeforeNavigate || navTarget == this.navTarget) && !canNavigate()) {
bottomSheet.close() bottomSheet.close()
drawer.close() drawer.close()
@ -901,7 +897,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
args: Bundle?, args: Bundle?,
profileChanged: Boolean, profileChanged: Boolean,
) { ) {
d(TAG, "navigateImpl(profileId = ${profile.id}, target = ${navTarget.name}, args = $args)") Timber.d("navigateImpl(profileId = ${profile.id}, target = ${navTarget.name}, args = $args)")
if (navTarget.featureType != null && !profile.hasUIFeature(navTarget.featureType)) { if (navTarget.featureType != null && !profile.hasUIFeature(navTarget.featureType)) {
navigateImpl(profile, NavTarget.HOME, args, profileChanged) navigateImpl(profile, NavTarget.HOME, args, profileChanged)
@ -954,7 +950,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
navView.bottomBar.fabExtended = false navView.bottomBar.fabExtended = false
navView.bottomBar.setFabOnClickListener(null) navView.bottomBar.setFabOnClickListener(null)
d("NavDebug", "Navigating from ${this.navTarget.name} to ${navTarget.name}") Timber.d("Navigating from ${this.navTarget.name} to ${navTarget.name}")
val fragment = navTarget.fragmentClass?.getDeclaredConstructor()?.newInstance() ?: return val fragment = navTarget.fragmentClass?.getDeclaredConstructor()?.newInstance() ?: return
fragment.arguments = arguments fragment.arguments = arguments
@ -1014,9 +1010,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
} }
d("NavDebug", "Current fragment ${navTarget.name}, back stack:") Timber.d("Current fragment ${navTarget.name}, back stack:")
navBackStack.forEachIndexed { index, item -> navBackStack.forEachIndexed { index, item ->
d("NavDebug", " - $index: ${item.first.name}") Timber.d(" - $index: ${item.first.name}")
} }
transaction.replace(R.id.fragment, fragment) transaction.replace(R.id.fragment, fragment)
@ -1099,8 +1095,8 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
else else
BitmapDrawable.createFromPath(it) BitmapDrawable.createFromPath(it)
} }
} catch (e: IOException) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
} }
} }
@ -1141,7 +1137,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
fun setDrawerItems() { fun setDrawerItems() {
d("NavDebug", "setDrawerItems() app.profile = ${app.profile}") Timber.d("setDrawerItems() app.profile = ${app.profile}")
val drawerItems = arrayListOf<IDrawerItem<*>>() val drawerItems = arrayListOf<IDrawerItem<*>>()
val drawerItemsMore = arrayListOf<IDrawerItem<*>>() val drawerItemsMore = arrayListOf<IDrawerItem<*>>()
val drawerItemsBottom = arrayListOf<IDrawerItem<*>>() val drawerItemsBottom = arrayListOf<IDrawerItem<*>>()

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
class FirebaseSendException(reason: String?) : Exception(reason) { class FirebaseSendException(reason: String?) : Exception(reason) {
companion object { companion object {

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.PendingIntent import android.app.PendingIntent
@ -14,6 +14,7 @@ import com.google.firebase.iid.zzaz
import com.google.firebase.messaging.zzc import com.google.firebase.messaging.zzc
import com.google.gson.JsonObject import com.google.gson.JsonObject
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import timber.log.Timber
import java.util.* import java.util.*
import com.google.firebase.messaging.zzo.zza as logNotificationOpen import com.google.firebase.messaging.zzo.zza as logNotificationOpen
import com.google.firebase.messaging.zzo.zza as logNotificationReceived import com.google.firebase.messaging.zzo.zza as logNotificationReceived
@ -44,7 +45,7 @@ open class FirebaseService : zzc() {
try { try {
it.send() it.send()
} catch (e: CanceledException) { } catch (e: CanceledException) {
Log.e(TAG, "Notification pending intent canceled") Timber.e("Notification pending intent canceled")
} }
} }
@ -59,7 +60,7 @@ open class FirebaseService : zzc() {
final override fun zzc(intent: Intent?) { final override fun zzc(intent: Intent?) {
val action = intent?.action val action = intent?.action
val json = intent?.toJsonObject() val json = intent?.toJsonObject()
Log.d(TAG, "zzc Intent(action=$action, extras=$json)") Timber.d("zzc Intent(action=$action, extras=$json)")
if (action == null || json == null) if (action == null || json == null)
return return
@ -73,12 +74,13 @@ open class FirebaseService : zzc() {
onNewToken(json.getString("token")) onNewToken(json.getString("token"))
} }
"com.google.android.c2dm.intent.RECEIVE", "com.google.android.c2dm.intent.RECEIVE",
"com.google.firebase.messaging.RECEIVE_DIRECT_BOOT" -> { "com.google.firebase.messaging.RECEIVE_DIRECT_BOOT",
-> {
val messageId = json.getString("google.message_id") val messageId = json.getString("google.message_id")
if (messageId != null) { if (messageId != null) {
// send back an acknowledgement to Google Play Services // send back an acknowledgement to Google Play Services
val ackBundle = Bundle( val ackBundle = Bundle(
"google.message_id" to messageId "google.message_id" to messageId
) )
zzad.zza(this).zza(2, ackBundle) zzad.zza(this).zza(2, ackBundle)
} }
@ -86,7 +88,7 @@ open class FirebaseService : zzc() {
// and add it to queue // and add it to queue
if (messageId.isNotNullNorEmpty()) { if (messageId.isNotNullNorEmpty()) {
if (messageQueue.contains(messageId)) { if (messageQueue.contains(messageId)) {
Log.d(TAG, "Received duplicate message: $messageId") Timber.d("Received duplicate message: $messageId")
return return
} }
if (messageQueue.size >= 10) if (messageQueue.size >= 10)
@ -97,7 +99,7 @@ open class FirebaseService : zzc() {
processMessage(messageId, json, intent) processMessage(messageId, json, intent)
} }
else -> { else -> {
Log.d(TAG, "Unknown intent action: $action") Timber.d("Unknown intent action: $action")
} }
} }
} }
@ -128,7 +130,7 @@ open class FirebaseService : zzc() {
) )
} }
else -> { else -> {
Log.w(TAG, "Received message with unknown type: $it") Timber.w("Received message with unknown type: $it")
return return
} }
} }

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
@ -11,6 +11,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import timber.log.Timber
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
class MyFirebaseService : FirebaseService(), CoroutineScope { class MyFirebaseService : FirebaseService(), CoroutineScope {
@ -25,17 +26,13 @@ class MyFirebaseService : FirebaseService(), CoroutineScope {
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
override fun onNewToken(token: String?) { override fun onNewToken(token: String?) {
Log.d(TAG, "Got new token: $token") Timber.d("Got new token: $token")
app.config.sync.tokenApp = token app.config.sync.tokenApp = token
} }
override fun onMessageReceived(message: Message) { override fun onMessageReceived(message: Message) {
launch(Dispatchers.Default) { launch(Dispatchers.Default) {
Log.d(TAG, "Message received from ${message.from}: $message") Timber.d("Message received from ${message.from}: $message")
app.getSharedPreferences("firebase_service_log", Context.MODE_PRIVATE).edit().apply {
putString(System.currentTimeMillis().toString(), message.toString())
apply()
}
val profiles = app.db.profileDao().profilesForFirebaseNow val profiles = app.db.profileDao().profilesForFirebaseNow
when (message.from) { when (message.from) {
"640759989760" -> SzkolnyAppFirebase(app, profiles, message) "640759989760" -> SzkolnyAppFirebase(app, profiles, message)

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
import com.google.gson.JsonParser import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-11. * Copyright (c) Kuba Szczodrzyński 2020-1-11.
*/ */
package pl.szczodrzynski.edziennik.data.firebase package pl.szczodrzynski.edziennik.core.firebase
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-4-28. * Copyright (c) Kuba Szczodrzyński 2020-4-28.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import com.mikepenz.iconics.typeface.IIcon import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2021-9-18. * Copyright (c) Kuba Szczodrzyński 2021-9-18.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.BuildConfig import pl.szczodrzynski.edziennik.BuildConfig

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2021-3-27. * Copyright (c) Kuba Szczodrzyński 2021-3-27.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.text.TextUtils import android.text.TextUtils
@ -20,7 +20,9 @@ import pl.szczodrzynski.edziennik.BuildConfig
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
import pl.szczodrzynski.edziennik.ext.DAY
import pl.szczodrzynski.edziennik.ext.Intent import pl.szczodrzynski.edziennik.ext.Intent
import pl.szczodrzynski.edziennik.ext.MS
import pl.szczodrzynski.edziennik.ext.asBoldSpannable import pl.szczodrzynski.edziennik.ext.asBoldSpannable
import pl.szczodrzynski.edziennik.ext.asColoredSpannable import pl.szczodrzynski.edziennik.ext.asColoredSpannable
import pl.szczodrzynski.edziennik.ext.concat import pl.szczodrzynski.edziennik.ext.concat
@ -34,7 +36,7 @@ import pl.szczodrzynski.edziennik.ext.resolveColor
import pl.szczodrzynski.edziennik.ext.toJsonObject import pl.szczodrzynski.edziennik.ext.toJsonObject
import pl.szczodrzynski.edziennik.ui.base.BuildInvalidActivity import pl.szczodrzynski.edziennik.ui.base.BuildInvalidActivity
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
import java.time.ZonedDateTime import java.time.ZonedDateTime
@ -101,6 +103,18 @@ class BuildManager(val app: App) : CoroutineScope {
else -> Update.Type.RELEASE else -> Update.Type.RELEASE
} }
fun fetchInstalledTime() {
if (app.config.appInstalledTime != 0L)
return
try {
app.config.appInstalledTime =
app.packageManager.getPackageInfo(app.packageName, 0).firstInstallTime
app.config.appRateSnackbarTime = app.config.appInstalledTime + 7 * DAY * MS
} catch (e: PackageManager.NameNotFoundException) {
Timber.e(e)
}
}
fun showVersionDialog(activity: AppCompatActivity) { fun showVersionDialog(activity: AppCompatActivity) {
val yes = activity.getString(R.string.yes) val yes = activity.getString(R.string.yes)
val no = activity.getString(R.string.no) val no = activity.getString(R.string.no)
@ -235,7 +249,7 @@ class BuildManager(val app: App) : CoroutineScope {
fun validateBuild(activity: AppCompatActivity) { fun validateBuild(activity: AppCompatActivity) {
launch { launch {
gitRemote = getRemoteRepo() gitRemote = getRemoteRepo()
d("BuildManager", "isSigned = $isSigned, buildType = $buildType, buildFlavor = $buildFlavor, remote = $gitRemote") Timber.d("isSigned = $isSigned, buildType = $buildType, buildFlavor = $buildFlavor, remote = $gitRemote")
// officially signed package // officially signed package
if (isSigned) if (isSigned)

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-4-3. * Copyright (c) Kuba Szczodrzyński 2020-4-3.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isVisible import androidx.core.view.isVisible

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) Kuba Szczodrzyński 2024-7-1.
*/
package pl.szczodrzynski.edziennik.core.manager
import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions
import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.messaging.FirebaseMessaging
import pl.szczodrzynski.edziennik.App
import timber.log.Timber
class FirebaseManager(val app: App) {
data class Instance(
val name: String,
val projectId: String,
val projectNumber: String,
val apiKey: String,
val applicationId: String,
val onToken: (token: String) -> Unit,
)
private val instances = listOf(
Instance(
name = "Mobidziennik",
projectId = "mobidziennik",
projectNumber = "747285019373",
apiKey = "AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE",
applicationId = "f6341bf7b158621d",
onToken = {
app.config.sync.tokenMobidziennik = it
app.config.sync.tokenMobidziennikList = listOf()
},
),
Instance(
name = "Librus",
projectId = "synergiadru",
projectNumber = "513056078587",
apiKey = "AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o",
applicationId = "1e29083b760af544",
onToken = {
app.config.sync.tokenLibrus = it
app.config.sync.tokenLibrusList = listOf()
},
),
Instance(
name = "Vulcan",
projectId = "dzienniczekplus",
projectNumber = "987828170337",
apiKey = "AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA",
applicationId = "ac97431a0a4578c3",
onToken = {
app.config.sync.tokenVulcan = it
app.config.sync.tokenVulcanList = listOf()
},
),
Instance(
name = "VulcanHebe",
projectId = "dzienniczekplus",
projectNumber = "987828170337",
apiKey = "AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA",
applicationId = "7e16404b9e5deaaa",
onToken = {
app.config.sync.tokenVulcanHebe = it
app.config.sync.tokenVulcanHebeList = listOf()
},
),
)
fun initializeApps() {
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { result ->
val token = result.token
Timber.i("Got App token: $token")
app.config.sync.tokenApp = token
}
FirebaseMessaging.getInstance().subscribeToTopic(app.packageName)
instances.forEach {
val options = FirebaseOptions.Builder()
.setProjectId(it.projectId)
.setStorageBucket("${it.projectId}.appspot.com")
.setDatabaseUrl("https://${it.projectId}.firebaseio.com")
.setGcmSenderId(it.projectNumber)
.setApiKey(it.apiKey)
.setApplicationId("1:${it.projectNumber}:android:${it.applicationId}")
.build()
val instance = FirebaseApp.initializeApp(app, options, it.name)
FirebaseInstanceId.getInstance(instance).instanceId.addOnSuccessListener { result ->
val token = result.token
Timber.i("Got ${it.name} token: $token")
if (token != app.config["token${it.name}"])
it.onToken(token)
}
}
}
}

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-3-1. * Copyright (c) Kuba Szczodrzyński 2020-3-1.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.content.Context import android.content.Context
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) Kuba Szczodrzyński 2024-7-1.
*/
package pl.szczodrzynski.edziennik.core.manager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.entity.LogEntry
import pl.szczodrzynski.edziennik.ext.DAY
import pl.szczodrzynski.edziennik.ext.MS
import pl.szczodrzynski.edziennik.ext.ignore
import timber.log.Timber
class LoggingManager(val app: App) : CoroutineScope {
companion object {
private const val CLEANUP_INTERVAL = 2 * DAY * MS
private const val CLEANUP_MAX_AGE = 7 * DAY * MS
}
override val coroutineContext = Job() + Dispatchers.IO
val logcatTree = object : Timber.DebugTree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
super.log(
priority = priority,
tag = tag?.substringBefore("$")?.let { "Szkolny/$it" },
message = message,
t = t,
)
}
}
val databaseTree = object : Timber.DebugTree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) = launch {
val entry = LogEntry(
timestamp = System.currentTimeMillis(),
priority = priority,
tag = tag?.substringBefore("$"),
message = message,
)
app.db.logDao().add(entry)
}.ignore()
}
suspend fun cleanupIfNeeded(force: Boolean = false) {
if (!force && System.currentTimeMillis() - app.config.lastLogCleanupTime < CLEANUP_INTERVAL)
return
withContext(Dispatchers.IO) {
val timestamp = System.currentTimeMillis() - CLEANUP_MAX_AGE
Timber.i("Cleaning logs older than $timestamp")
app.db.logDao().clearBefore(timestamp)
}
app.config.lastLogCleanupTime = System.currentTimeMillis()
}
fun cleanupHyperLogDatabase() {
try {
app.deleteDatabase("com.hypertrack.common.device_logs.db")
} catch (e: Exception) {
Timber.e(e)
}
}
}

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2021-10-7. * Copyright (c) Kuba Szczodrzyński 2021-10-7.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
@ -30,8 +30,8 @@ import pl.szczodrzynski.edziennik.ext.setText
import pl.szczodrzynski.edziennik.ui.messages.MessagesUtils import pl.szczodrzynski.edziennik.ui.messages.MessagesUtils
import pl.szczodrzynski.edziennik.utils.TextInputKeyboardEdit import pl.szczodrzynski.edziennik.utils.TextInputKeyboardEdit
import pl.szczodrzynski.edziennik.utils.html.BetterHtml import pl.szczodrzynski.edziennik.utils.html.BetterHtml
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.HtmlMode.ORIGINAL import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.ORIGINAL
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.StylingConfig import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.StylingConfig
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.span.BoldSpan import pl.szczodrzynski.edziennik.utils.span.BoldSpan

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2021-10-17. * Copyright (c) Kuba Szczodrzyński 2021-10-17.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-2-15.
*/
package pl.szczodrzynski.edziennik.core.manager
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat.*
import androidx.core.app.NotificationManagerCompat.*
import pl.szczodrzynski.edziennik.R
class NotificationManager(val c: Context) {
data class Channel(
val id: Int,
val key: String,
val name: String,
val description: String,
val importance: Int,
val priority: Int,
val quiet: Boolean = false,
val lightColor: Int? = null
)
fun registerAllChannels() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return
val manager = c.getSystemService(NotificationManager::class.java)
val registered = manager.notificationChannels.map { it.id }.toSet()
val all = all.map { it.key }.toSet()
val toRegister = all - registered
val toDelete = registered - all
for (key in toRegister) {
val channel = this.all.firstOrNull { it.key == key } ?: continue
manager.createNotificationChannel(NotificationChannel(key, channel.name, channel.importance).apply {
description = channel.description
if (channel.quiet) {
enableVibration(false)
setSound(null, null)
}
channel.lightColor?.let {
enableLights(true)
lightColor = it
}
})
}
for (key in toDelete) {
if (key.contains("chucker"))
continue
manager.deleteNotificationChannel(key)
}
}
val sync = Channel(
1,
"pl.szczodrzynski.edziennik.SYNC",
c.getString(R.string.notification_channel_get_data_name),
c.getString(R.string.notification_channel_get_data_desc),
IMPORTANCE_MIN,
PRIORITY_MIN,
quiet = true
)
val data = Channel(
50,
"pl.szczodrzynski.edziennik.DATA",
c.getString(R.string.notification_channel_notifications_name),
c.getString(R.string.notification_channel_notifications_desc),
IMPORTANCE_HIGH,
PRIORITY_MAX,
lightColor = 0xff2196f3.toInt()
)
val dataQuiet = Channel(
60,
"pl.szczodrzynski.edziennik.DATA_QUIET",
c.getString(R.string.notification_channel_notifications_quiet_name),
c.getString(R.string.notification_channel_notifications_quiet_desc),
IMPORTANCE_LOW,
PRIORITY_LOW,
quiet = true
)
val updates = Channel(
100,
"pl.szczodrzynski.edziennik.UPDATES",
c.getString(R.string.notification_channel_updates_name),
c.getString(R.string.notification_channel_updates_desc),
IMPORTANCE_DEFAULT,
PRIORITY_DEFAULT
)
val userAttention = Channel(
200,
"pl.szczodrzynski.edziennik.USER_ATTENTION",
c.getString(R.string.notification_channel_user_attention_name),
c.getString(R.string.notification_channel_user_attention_desc),
IMPORTANCE_DEFAULT,
PRIORITY_DEFAULT
)
val all by lazy { listOf(
sync,
data,
dataQuiet,
updates,
userAttention
) }
}

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-4-7. * Copyright (c) Kuba Szczodrzyński 2020-4-7.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.Manifest import android.Manifest
import android.content.Intent import android.content.Intent

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) Kuba Szczodrzyński 2024-7-1.
*/
package pl.szczodrzynski.edziennik.core.manager
import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Build
import androidx.core.content.getSystemService
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.enums.NavTarget
import pl.szczodrzynski.edziennik.ext.putExtras
class ShortcutManager(val app: App) {
data class Shortcut(
val id: String,
val label: Int,
val icon: Int,
val target: NavTarget,
)
private val shortcuts = listOf(
Shortcut(
id = "item_timetable",
label = R.string.shortcut_timetable,
icon = R.mipmap.ic_shortcut_timetable,
target = NavTarget.TIMETABLE,
),
Shortcut(
id = "item_agenda",
label = R.string.shortcut_agenda,
icon = R.mipmap.ic_shortcut_agenda,
target = NavTarget.AGENDA,
),
Shortcut(
id = "item_grades",
label = R.string.shortcut_grades,
icon = R.mipmap.ic_shortcut_grades,
target = NavTarget.GRADES,
),
Shortcut(
id = "item_homeworks",
label = R.string.shortcut_homework,
icon = R.mipmap.ic_shortcut_homework,
target = NavTarget.HOMEWORK,
),
Shortcut(
id = "item_messages",
label = R.string.shortcut_messages,
icon = R.mipmap.ic_shortcut_messages,
target = NavTarget.MESSAGES,
),
)
fun createShortcuts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
app.getSystemService<ShortcutManager>()?.dynamicShortcuts = shortcuts.map {
ShortcutInfo.Builder(app, it.id)
.setShortLabel(app.getString(it.label))
.setLongLabel(app.getString(it.label))
.setIcon(Icon.createWithResource(app, it.icon))
.setIntent(
Intent(Intent.ACTION_MAIN, null, app, MainActivity::class.java)
.putExtras("fragmentId" to it.target)
)
.build()
}
}
}
}

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2021-10-7. * Copyright (c) Kuba Szczodrzyński 2021-10-7.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.Spanned import android.text.Spanned
@ -31,7 +31,7 @@ import pl.szczodrzynski.edziennik.ext.replaceSpan
import pl.szczodrzynski.edziennik.ui.dialogs.StyledTextDialog import pl.szczodrzynski.edziennik.ui.dialogs.StyledTextDialog
import pl.szczodrzynski.edziennik.utils.TextInputKeyboardEdit import pl.szczodrzynski.edziennik.utils.TextInputKeyboardEdit
import pl.szczodrzynski.edziennik.utils.html.BetterHtml import pl.szczodrzynski.edziennik.utils.html.BetterHtml
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.HtmlMode.* import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.*
import pl.szczodrzynski.edziennik.utils.span.BoldSpan import pl.szczodrzynski.edziennik.utils.span.BoldSpan
import pl.szczodrzynski.edziennik.utils.span.ItalicSpan import pl.szczodrzynski.edziennik.utils.span.ItalicSpan

View File

@ -2,11 +2,9 @@
* Copyright (c) Kuba Szczodrzyński 2020-3-10. * Copyright (c) Kuba Szczodrzyński 2020-3-10.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.content.Context import android.content.Context
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.widget.TextView import android.widget.TextView
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -15,11 +13,8 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Lesson import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.full.LessonFull import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.ext.resolveAttr
import pl.szczodrzynski.edziennik.ext.setText import pl.szczodrzynski.edziennik.ext.setText
import pl.szczodrzynski.edziennik.ext.setTintColor
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
import pl.szczodrzynski.navlib.getColorFromAttr
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
class TimetableManager(val app: App) : CoroutineScope { class TimetableManager(val app: App) : CoroutineScope {

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2024-6-26. * Copyright (c) Kuba Szczodrzyński 2024-6-26.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
@ -17,7 +17,7 @@ import pl.szczodrzynski.edziennik.data.enums.Theme
import pl.szczodrzynski.edziennik.data.enums.Theme.Mode import pl.szczodrzynski.edziennik.data.enums.Theme.Mode
import pl.szczodrzynski.edziennik.data.enums.Theme.Type import pl.szczodrzynski.edziennik.data.enums.Theme.Type
import pl.szczodrzynski.edziennik.ext.isNightMode import pl.szczodrzynski.edziennik.ext.isNightMode
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.util.Locale import java.util.Locale
class UiManager(val app: App) { class UiManager(val app: App) {
@ -63,7 +63,7 @@ class UiManager(val app: App) {
) { ) {
color = Theme.BLUE color = Theme.BLUE
} }
d(TAG, "Applying theme $color($type, $mode)") Timber.d("Applying theme $color($type, $mode)")
color.styleRes[type to mode] ?: color.styleRes[Type.M3 to Mode.DAYNIGHT]!! color.styleRes[type to mode] ?: color.styleRes[Type.M3 to Mode.DAYNIGHT]!!
} }
activity.setTheme(themeRes) activity.setTheme(themeRes)

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2022-10-22. * Copyright (c) Kuba Szczodrzyński 2022-10-22.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-2-15. * Copyright (c) Kuba Szczodrzyński 2020-2-15.
*/ */
package pl.szczodrzynski.edziennik.utils.managers package pl.szczodrzynski.edziennik.core.manager
import android.app.NotificationManager import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
@ -24,7 +24,7 @@ import pl.szczodrzynski.edziennik.ui.login.oauth.OAuthLoginActivity
import pl.szczodrzynski.edziennik.ui.login.oauth.OAuthLoginResult import pl.szczodrzynski.edziennik.ui.login.oauth.OAuthLoginResult
import pl.szczodrzynski.edziennik.ui.login.recaptcha.RecaptchaActivity import pl.szczodrzynski.edziennik.ui.login.recaptcha.RecaptchaActivity
import pl.szczodrzynski.edziennik.ui.login.recaptcha.RecaptchaResult import pl.szczodrzynski.edziennik.ui.login.recaptcha.RecaptchaResult
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class UserActionManager(val app: App) { class UserActionManager(val app: App) {
companion object { companion object {
@ -55,7 +55,7 @@ class UserActionManager(val app: App) {
) )
val notification = val notification =
NotificationCompat.Builder(app, app.notificationChannelsManager.userAttention.key) NotificationCompat.Builder(app, app.notificationManager.userAttention.key)
.setContentTitle(app.getString(R.string.notification_user_action_required_title)) .setContentTitle(app.getString(R.string.notification_user_action_required_title))
.setContentText(text) .setContentText(text)
.setSmallIcon(R.drawable.ic_error_outline) .setSmallIcon(R.drawable.ic_error_outline)
@ -82,7 +82,7 @@ class UserActionManager(val app: App) {
event: UserActionRequiredEvent, event: UserActionRequiredEvent,
callback: UserActionCallback, callback: UserActionCallback,
) { ) {
d(TAG, "Running user action (${event.type}) with params: ${event.params}") Timber.d("Running user action (${event.type}) with params: ${event.params}")
val isSuccessful = when (event.type) { val isSuccessful = when (event.type) {
UserActionRequiredEvent.Type.RECAPTCHA -> executeRecaptcha(activity, event, callback) UserActionRequiredEvent.Type.RECAPTCHA -> executeRecaptcha(activity, event, callback)
UserActionRequiredEvent.Type.OAUTH -> executeOauth(activity, event, callback) UserActionRequiredEvent.Type.OAUTH -> executeOauth(activity, event, callback)

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-3-24. * Copyright (c) Kuba Szczodrzyński 2020-3-24.
*/ */
package pl.szczodrzynski.edziennik.network.cookie package pl.szczodrzynski.edziennik.core.network
import okhttp3.Cookie import okhttp3.Cookie
import okhttp3.HttpUrl import okhttp3.HttpUrl

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-3-24. * Copyright (c) Kuba Szczodrzyński 2020-3-24.
*/ */
package pl.szczodrzynski.edziennik.network.cookie package pl.szczodrzynski.edziennik.core.network
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2019-10-1. * Copyright (c) Kuba Szczodrzyński 2019-10-1.
*/ */
package pl.szczodrzynski.edziennik.receivers package pl.szczodrzynski.edziennik.core.receiver
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context

View File

@ -1,4 +1,4 @@
package pl.szczodrzynski.edziennik.receivers; package pl.szczodrzynski.edziennik.core.receiver;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;

View File

@ -1,3 +1,3 @@
package pl.szczodrzynski.edziennik.sync package pl.szczodrzynski.edziennik.core.work
class AppManagerDetectedEvent(val failedWorkTimestamps: List<Long>) class AppManagerDetectedEvent(val failedWorkTimestamps: List<Long>)

View File

@ -1,4 +1,4 @@
package pl.szczodrzynski.edziennik.sync package pl.szczodrzynski.edziennik.core.work
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
@ -6,7 +6,7 @@ import androidx.work.*
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
import pl.szczodrzynski.edziennik.ext.formatDate import pl.szczodrzynski.edziennik.ext.formatDate
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(context, params) { class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(context, params) {
@ -38,7 +38,7 @@ class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(co
val syncInterval = app.config.sync.interval.toLong() val syncInterval = app.config.sync.interval.toLong()
val syncAt = System.currentTimeMillis() + syncInterval*1000 val syncAt = System.currentTimeMillis() + syncInterval*1000
d(TAG, "Scheduling work at ${syncAt.formatDate()}") Timber.d("Scheduling work at ${syncAt.formatDate()}")
val constraints = Constraints.Builder() val constraints = Constraints.Builder()
.setRequiredNetworkType( .setRequiredNetworkType(
@ -61,14 +61,14 @@ class SyncWorker(val context: Context, val params: WorkerParameters) : Worker(co
* Cancel any scheduled sync job. * Cancel any scheduled sync job.
*/ */
fun cancelNext(app: App) { fun cancelNext(app: App) {
d(TAG, "Cancelling work by tag $TAG") Timber.d("Cancelling work by tag $TAG")
WorkManager.getInstance(app).cancelAllWorkByTag(TAG) WorkManager.getInstance(app).cancelAllWorkByTag(TAG)
//WorkManager.getInstance(app).pruneWork() // do not prune the work in order to look for failed tasks //WorkManager.getInstance(app).pruneWork() // do not prune the work in order to look for failed tasks
} }
} }
override fun doWork(): Result { override fun doWork(): Result {
d(TAG, "Running worker ID ${params.id}") Timber.d("Running worker ID ${params.id}")
EdziennikTask.sync().enqueue(context) EdziennikTask.sync().enqueue(context)
rescheduleNext(context as App) rescheduleNext(context as App)
return Result.success() return Result.success()

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2022-10-22. * Copyright (c) Kuba Szczodrzyński 2022-10-22.
*/ */
package pl.szczodrzynski.edziennik.sync package pl.szczodrzynski.edziennik.core.work
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-18. * Copyright (c) Kuba Szczodrzyński 2020-1-18.
*/ */
package pl.szczodrzynski.edziennik.sync package pl.szczodrzynski.edziennik.core.work
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
import pl.szczodrzynski.edziennik.ext.DAY import pl.szczodrzynski.edziennik.ext.DAY
import pl.szczodrzynski.edziennik.ext.formatDate import pl.szczodrzynski.edziennik.ext.formatDate
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -43,7 +44,7 @@ class UpdateWorker(val context: Context, val params: WorkerParameters) : Worker(
val syncInterval = 4 * DAY; val syncInterval = 4 * DAY;
val syncAt = System.currentTimeMillis() + syncInterval*1000 val syncAt = System.currentTimeMillis() + syncInterval*1000
Utils.d(TAG, "Scheduling work at ${syncAt.formatDate()}") Timber.d("Scheduling work at ${syncAt.formatDate()}")
val constraints = Constraints.Builder() val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) .setRequiredNetworkType(NetworkType.CONNECTED)
@ -62,7 +63,7 @@ class UpdateWorker(val context: Context, val params: WorkerParameters) : Worker(
* Cancel any scheduled sync job. * Cancel any scheduled sync job.
*/ */
fun cancelNext(app: App) { fun cancelNext(app: App) {
Utils.d(TAG, "Cancelling work by tag $TAG") Timber.d("Cancelling work by tag $TAG")
WorkManager.getInstance(app).cancelAllWorkByTag(TAG) WorkManager.getInstance(app).cancelAllWorkByTag(TAG)
} }
} }
@ -72,7 +73,7 @@ class UpdateWorker(val context: Context, val params: WorkerParameters) : Worker(
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
override fun doWork(): Result { override fun doWork(): Result {
Utils.d(TAG, "Running worker ID ${params.id}") Timber.d("Running worker ID ${params.id}")
val app = context as App val app = context as App
if (!app.config.sync.notifyAboutUpdates) { if (!app.config.sync.notifyAboutUpdates) {
return Result.success() return Result.success()

View File

@ -2,7 +2,7 @@
* Copyright (c) Kuba Szczodrzyński 2020-1-18. * Copyright (c) Kuba Szczodrzyński 2020-1-18.
*/ */
package pl.szczodrzynski.edziennik.sync package pl.szczodrzynski.edziennik.core.work
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.AsyncTask import android.os.AsyncTask
@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.ext.MINUTE import pl.szczodrzynski.edziennik.ext.MINUTE
import pl.szczodrzynski.edziennik.ext.formatDate import pl.szczodrzynski.edziennik.ext.formatDate
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
object WorkerUtils { object WorkerUtils {
/** /**
@ -26,27 +27,27 @@ object WorkerUtils {
val workManager = WorkManager.getInstance(app) as WorkManagerImpl val workManager = WorkManager.getInstance(app) as WorkManagerImpl
val scheduledWork = workManager.workDatabase.workSpecDao().getScheduledWork().toMutableList() val scheduledWork = workManager.workDatabase.workSpecDao().getScheduledWork().toMutableList()
scheduledWork.forEach { scheduledWork.forEach {
Utils.d("WorkerUtils", "Work: ${it.id} at ${it.calculateNextRunTime().formatDate()}. State = ${it.state} (finished = ${it.state.isFinished})") Timber.d("Work: ${it.id} at ${it.calculateNextRunTime().formatDate()}. State = ${it.state} (finished = ${it.state.isFinished})")
} }
// remove finished work and other than SyncWorker // remove finished work and other than SyncWorker
scheduledWork.removeAll { it.workerClassName != SyncWorker::class.java.canonicalName || it.isPeriodic || it.state.isFinished } scheduledWork.removeAll { it.workerClassName != SyncWorker::class.java.canonicalName || it.isPeriodic || it.state.isFinished }
Utils.d("WorkerUtils", "Found ${scheduledWork.size} unfinished work") Timber.d("Found ${scheduledWork.size} unfinished work")
// remove all enqueued work that had to (but didn't) run at some point in the past (at least 1min ago) // remove all enqueued work that had to (but didn't) run at some point in the past (at least 1min ago)
val failedWork = scheduledWork.filter { it.state == WorkInfo.State.ENQUEUED && it.calculateNextRunTime() < System.currentTimeMillis() - 1 * MINUTE * 1000 } val failedWork = scheduledWork.filter { it.state == WorkInfo.State.ENQUEUED && it.calculateNextRunTime() < System.currentTimeMillis() - 1 * MINUTE * 1000 }
Utils.d("WorkerUtils", "${failedWork.size} work requests failed to start (out of ${scheduledWork.size} requests)") Timber.d("${failedWork.size} work requests failed to start (out of ${scheduledWork.size} requests)")
if (rescheduleIfFailedFound) { if (rescheduleIfFailedFound) {
if (failedWork.isNotEmpty()) { if (failedWork.isNotEmpty()) {
Utils.d("WorkerUtils", "App Manager detected!") Timber.d("App Manager detected!")
EventBus.getDefault().postSticky(AppManagerDetectedEvent(failedWork.map { it.calculateNextRunTime() })) EventBus.getDefault().postSticky(AppManagerDetectedEvent(failedWork.map { it.calculateNextRunTime() }))
} }
if (scheduledWork.size - failedWork.size < 1) { if (scheduledWork.size - failedWork.size < 1) {
Utils.d("WorkerUtils", "No pending work found, scheduling next:") Timber.d("No pending work found, scheduling next:")
onReschedule() onReschedule()
} }
} else { } else {
Utils.d("WorkerUtils", "NOT rescheduling: waiting to open the activity") Timber.d("NOT rescheduling: waiting to open the activity")
if (scheduledWork.size < 1) { if (scheduledWork.size < 1) {
Utils.d("WorkerUtils", "No work found *at all*, scheduling next:") Timber.d("No work found *at all*, scheduling next:")
onReschedule() onReschedule()
} }
} }

View File

@ -23,7 +23,7 @@ import pl.szczodrzynski.edziennik.data.api.task.IApiTask
import pl.szczodrzynski.edziennik.data.api.task.SzkolnyTask import pl.szczodrzynski.edziennik.data.api.task.SzkolnyTask
import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.ext.toApiError import pl.szczodrzynski.edziennik.ext.toApiError
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -76,7 +76,7 @@ class ApiService : Service() {
private val taskCallback = object : EdziennikCallback { private val taskCallback = object : EdziennikCallback {
override fun onCompleted() { override fun onCompleted() {
lastEventTime = System.currentTimeMillis() lastEventTime = System.currentTimeMillis()
d(TAG, "Task $taskRunningId (profile $taskProfileId) finished in ${System.currentTimeMillis()-taskStartTime}") Timber.d("Task $taskRunningId (profile $taskProfileId) finished in ${System.currentTimeMillis()-taskStartTime}")
EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId)) EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId))
clearTask() clearTask()
@ -93,12 +93,12 @@ class ApiService : Service() {
override fun onError(apiError: ApiError) { override fun onError(apiError: ApiError) {
lastEventTime = System.currentTimeMillis() lastEventTime = System.currentTimeMillis()
d(TAG, "Task $taskRunningId threw an error - $apiError") Timber.d("Task $taskRunningId threw an error - $apiError")
apiError.profileId = taskProfileId apiError.profileId = taskProfileId
EventBus.getDefault().postSticky(ApiTaskErrorEvent(apiError)) EventBus.getDefault().postSticky(ApiTaskErrorEvent(apiError))
errorList.add(apiError) errorList.add(apiError)
apiError.throwable?.printStackTrace() Timber.e(apiError.throwable)
if (apiError.isCritical) { if (apiError.isCritical) {
taskRunning?.cancel() taskRunning?.cancel()
@ -119,7 +119,7 @@ class ApiService : Service() {
taskProgress = 0f taskProgress = 0f
taskProgress += step taskProgress += step
taskProgress = min(100f, taskProgress) taskProgress = min(100f, taskProgress)
d(TAG, "Task $taskRunningId progress: ${taskProgress.roundToInt()}%") Timber.d("Task $taskRunningId progress: ${taskProgress.roundToInt()}%")
EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText)) EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText))
notification.setProgress(taskProgress).post() notification.setProgress(taskProgress).post()
} }
@ -127,7 +127,7 @@ class ApiService : Service() {
override fun onStartProgress(stringRes: Int) { override fun onStartProgress(stringRes: Int) {
lastEventTime = System.currentTimeMillis() lastEventTime = System.currentTimeMillis()
taskProgressText = getString(stringRes) taskProgressText = getString(stringRes)
d(TAG, "Task $taskRunningId progress: $taskProgressText") Timber.d("Task $taskRunningId progress: $taskProgressText")
EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText)) EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText))
notification.setProgressText(taskProgressText).post() notification.setProgressText(taskProgressText).post()
} }
@ -166,7 +166,7 @@ class ApiService : Service() {
taskProgress = -1f taskProgress = -1f
taskProgressText = task.taskName taskProgressText = task.taskName
d(TAG, "Executing task $taskRunningId - ${task::class.java.name}") Timber.d("Executing task $taskRunningId - ${task::class.java.name}")
// update the notification // update the notification
notification.setCurrentTask(taskRunningId, taskProgressText).post() notification.setCurrentTask(taskRunningId, taskProgressText).post()
@ -200,7 +200,7 @@ class ApiService : Service() {
if (System.currentTimeMillis() - lastEventTime > 30*1000 if (System.currentTimeMillis() - lastEventTime > 30*1000
|| taskCancelTries >= 3) { || taskCancelTries >= 3) {
val time = System.currentTimeMillis() - lastEventTime val time = System.currentTimeMillis() - lastEventTime
d(TAG, "!!! Task $taskRunningId froze for $time ms. $taskRunning") Timber.d("!!! Task $taskRunningId froze for $time ms. $taskRunning")
clearTask() clearTask()
return true return true
} }
@ -245,7 +245,7 @@ class ApiService : Service() {
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onApiTask(task: IApiTask) { fun onApiTask(task: IApiTask) {
EventBus.getDefault().removeStickyEvent(task) EventBus.getDefault().removeStickyEvent(task)
d(TAG, task.toString()) Timber.d(task.toString())
if (task is EdziennikTask) { if (task is EdziennikTask) {
// fix for duplicated tasks, thank you EventBus // fix for duplicated tasks, thank you EventBus
@ -270,10 +270,10 @@ class ApiService : Service() {
else { else {
taskQueue += task taskQueue += task
} }
d(TAG, "EventBus received an IApiTask: $task") Timber.d("EventBus received an IApiTask: $task")
d(TAG, "Current queue:") Timber.d("Current queue:")
taskQueue.forEach { taskQueue.forEach {
d(TAG, " - $it") Timber.d(" - $it")
} }
runTask() runTask()
} }
@ -281,7 +281,7 @@ class ApiService : Service() {
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onTaskCancelRequest(request: TaskCancelRequest) { fun onTaskCancelRequest(request: TaskCancelRequest) {
EventBus.getDefault().removeStickyEvent(request) EventBus.getDefault().removeStickyEvent(request)
d(TAG, request.toString()) Timber.d(request.toString())
taskCancelTries++ taskCancelTries++
taskCancelled = true taskCancelled = true
@ -291,7 +291,7 @@ class ApiService : Service() {
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onServiceCloseRequest(request: ServiceCloseRequest) { fun onServiceCloseRequest(request: ServiceCloseRequest) {
EventBus.getDefault().removeStickyEvent(request) EventBus.getDefault().removeStickyEvent(request)
d(TAG, request.toString()) Timber.d(request.toString())
serviceClosed = true serviceClosed = true
taskCancelled = true taskCancelled = true
@ -306,19 +306,19 @@ class ApiService : Service() {
____) | __/ | \ V /| | (_| __/ | (_) \ V / __/ | | | | | (_| | __/\__ \ ____) | __/ | \ V /| | (_| __/ | (_) \ V / __/ | | | | | (_| | __/\__ \
|_____/ \___|_| \_/ |_|\___\___| \___/ \_/ \___|_| |_| |_|\__,_|\___||__*/ |_____/ \___|_| \_/ |_|\___\___| \___/ \_/ \___|_| |_| |_|\__,_|\___||__*/
override fun onCreate() { override fun onCreate() {
d(TAG, "Service created") Timber.d("Service created")
EventBus.getDefault().register(this) EventBus.getDefault().register(this)
notification.setIdle().setCloseAction() notification.setIdle().setCloseAction()
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
d(TAG, "Foreground service onStartCommand") Timber.d("Foreground service onStartCommand")
startForeground(app.notificationChannelsManager.sync.id, notification.notification) startForeground(app.notificationManager.sync.id, notification.notification)
return START_NOT_STICKY return START_NOT_STICKY
} }
override fun onDestroy() { override fun onDestroy() {
d(TAG, "Service destroyed") Timber.d("Service destroyed")
serviceClosed = true serviceClosed = true
EventBus.getDefault().unregister(this) EventBus.getDefault().unregister(this)
} }

View File

@ -14,7 +14,7 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.ext.Bundle import pl.szczodrzynski.edziennik.ext.Bundle
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver import pl.szczodrzynski.edziennik.core.receiver.SzkolnyReceiver
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -138,7 +138,7 @@ class EdziennikNotification(val app: App) {
fun post() { fun post() {
if (serviceClosed) if (serviceClosed)
return return
notificationManager.notify(app.notificationChannelsManager.sync.id, notification) notificationManager.notify(app.notificationManager.sync.id, notification)
} }
} }

View File

@ -30,8 +30,8 @@ import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.ext.isBeforeYear import pl.szczodrzynski.edziennik.ext.isBeforeYear
import pl.szczodrzynski.edziennik.ext.shouldArchive import pl.szczodrzynski.edziennik.ext.shouldArchive
import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.core.manager.AvailabilityManager.Error.Type
import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type import timber.log.Timber
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) { open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
companion object { companion object {
@ -80,16 +80,16 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
internal fun run(app: App, taskCallback: EdziennikCallback) { internal fun run(app: App, taskCallback: EdziennikCallback) {
profile?.let { profile -> profile?.let { profile ->
if (profile.archived) { if (profile.archived) {
d(TAG, "The profile $profileId is archived") Timber.d("The profile $profileId is archived")
taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED)) taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED))
return return
} }
else if (profile.shouldArchive()) { else if (profile.shouldArchive()) {
d(TAG, "The profile $profileId's year ended on ${profile.dateYearEnd}, archiving") Timber.d("The profile $profileId's year ended on ${profile.dateYearEnd}, archiving")
ProfileArchiver(app, profile) ProfileArchiver(app, profile)
} }
if (profile.isBeforeYear()) { if (profile.isBeforeYear()) {
d(TAG, "The profile $profileId's school year has not started yet; aborting sync") Timber.d("The profile $profileId's school year has not started yet; aborting sync")
cancel() cancel()
taskCallback.onCompleted() taskCallback.onCompleted()
return return
@ -143,7 +143,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
} }
override fun cancel() { override fun cancel() {
d(TAG, "Task ${toString()} cancelling...") Timber.d("Task ${toString()} cancelling...")
edziennikInterface?.cancel() edziennikInterface?.cancel()
} }

View File

@ -9,8 +9,8 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.data.enums.LoginType import pl.szczodrzynski.edziennik.data.enums.LoginType
import pl.szczodrzynski.edziennik.ext.Intent import pl.szczodrzynski.edziennik.ext.Intent
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import timber.log.Timber
class ProfileArchiver(val app: App, val profile: Profile) { class ProfileArchiver(val app: App, val profile: Profile) {
companion object { companion object {
@ -20,14 +20,14 @@ class ProfileArchiver(val app: App, val profile: Profile) {
init { init {
if (profile.archiveId == null) if (profile.archiveId == null)
profile.archiveId = profile.id profile.archiveId = profile.id
d(TAG, "Processing ${profile.name}#${profile.id}, archiveId = ${profile.archiveId}") Timber.d("Processing ${profile.name}#${profile.id}, archiveId = ${profile.archiveId}")
profile.archived = true profile.archived = true
app.db.profileDao().add(profile) app.db.profileDao().add(profile)
//app.db.metadataDao().setAllSeen(profile.id, true) //app.db.metadataDao().setAllSeen(profile.id, true)
app.db.notificationDao().clear(profile.id) app.db.notificationDao().clear(profile.id)
app.db.endpointTimerDao().clear(profile.id) app.db.endpointTimerDao().clear(profile.id)
d(TAG, "Archived profile ${profile.id} saved") Timber.d("Archived profile ${profile.id} saved")
profile.archived = false profile.archived = false
// guess the nearest school year // guess the nearest school year
@ -48,7 +48,7 @@ class ProfileArchiver(val app: App, val profile: Profile) {
profile.subname = "Nowy rok szkolny - ${profile.studentSchoolYearStart}" profile.subname = "Nowy rok szkolny - ${profile.studentSchoolYearStart}"
profile.studentClassName = null profile.studentClassName = null
d(TAG, "New profile ID for ${profile.name}: ${profile.id}") Timber.d("New profile ID for ${profile.name}: ${profile.id}")
when (profile.loginStoreType) { when (profile.loginStoreType) {
LoginType.LIBRUS -> { LoginType.LIBRUS -> {
@ -79,7 +79,7 @@ class ProfileArchiver(val app: App, val profile: Profile) {
LoginType.TEMPLATE -> {} LoginType.TEMPLATE -> {}
} }
d(TAG, "Processed student data: ${profile.studentData}") Timber.d("Processed student data: ${profile.studentData}")
app.db.profileDao().add(profile) app.db.profileDao().add(profile)

View File

@ -29,7 +29,7 @@ import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -67,10 +67,10 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
} }
private fun login(loginMethod: LoginMethod? = null, afterLogin: (() -> Unit)? = null) { private fun login(loginMethod: LoginMethod? = null, afterLogin: (() -> Unit)? = null) {
d(TAG, "Trying to login with ${data.targetLoginMethods}") Timber.d("Trying to login with ${data.targetLoginMethods}")
if (internalErrorList.isNotEmpty()) { if (internalErrorList.isNotEmpty()) {
d(TAG, " - Internal errors:") Timber.d(" - Internal errors:")
internalErrorList.forEach { d(TAG, " - code $it") } internalErrorList.forEach { Timber.d(" - code $it") }
} }
loginMethod?.let { data.prepareFor(it) } loginMethod?.let { data.prepareFor(it) }
afterLogin?.let { this.afterLogin = it } afterLogin?.let { this.afterLogin = it }
@ -80,10 +80,10 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
} }
private fun data() { private fun data() {
d(TAG, "Endpoint IDs: ${data.targetEndpoints}") Timber.d("Endpoint IDs: ${data.targetEndpoints}")
if (internalErrorList.isNotEmpty()) { if (internalErrorList.isNotEmpty()) {
d(TAG, " - Internal errors:") Timber.d(" - Internal errors:")
internalErrorList.forEach { d(TAG, " - code $it") } internalErrorList.forEach { Timber.d(" - code $it") }
} }
afterLogin?.invoke() ?: LibrusData(data) { afterLogin?.invoke() ?: LibrusData(data) {
completed() completed()
@ -158,7 +158,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
override fun firstLogin() { LibrusFirstLogin(data) { completed() } } override fun firstLogin() { LibrusFirstLogin(data) { completed() } }
override fun cancel() { override fun cancel() {
d(TAG, "Cancelled") Timber.d("Cancelled")
data.cancel() data.cancel()
} }

View File

@ -12,7 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.net.HttpURLConnection.* import java.net.HttpURLConnection.*
open class LibrusApi(open val data: DataLibrus, open val lastSync: Long?) { open class LibrusApi(open val data: DataLibrus, open val lastSync: Long?) {
@ -28,7 +28,7 @@ open class LibrusApi(open val data: DataLibrus, open val lastSync: Long?) {
fun apiGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, ignoreErrors: List<Int> = emptyList(), onSuccess: (json: JsonObject) -> Unit) { fun apiGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, ignoreErrors: List<Int> = emptyList(), onSuccess: (json: JsonObject) -> Unit) {
d(tag, "Request: Librus/Api - ${if (data.fakeLogin) FAKE_LIBRUS_API else LIBRUS_API_URL}/$endpoint") Timber.tag(tag).d("Request: Librus/Api - ${if (data.fakeLogin) FAKE_LIBRUS_API else LIBRUS_API_URL}/$endpoint")
val callback = object : JsonCallbackHandler() { val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) { override fun onSuccess(json: JsonObject?, response: Response?) {

View File

@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.Librus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaInfo import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.LibrusSynergiaInfo
import pl.szczodrzynski.edziennik.data.db.entity.Message import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) { class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
companion object { companion object {
@ -41,7 +42,7 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
} }
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) { private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync") Timber.d("Using endpoint $endpointId. Last sync time = $lastSync")
when (endpointId) { when (endpointId) {
/** /**
* API * API

View File

@ -20,7 +20,7 @@ import org.jsoup.parser.Parser
import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.io.File import java.io.File
import java.io.StringWriter import java.io.StringWriter
import javax.xml.parsers.DocumentBuilderFactory import javax.xml.parsers.DocumentBuilderFactory
@ -43,7 +43,7 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
fun messagesGet(tag: String, module: String, method: Int = POST, fun messagesGet(tag: String, module: String, method: Int = POST,
parameters: Map<String, Any>? = null, onSuccess: (doc: Document) -> Unit) { parameters: Map<String, Any>? = null, onSuccess: (doc: Document) -> Unit) {
d(tag, "Request: Librus/Messages - $LIBRUS_MESSAGES_URL/$module") Timber.tag(tag).d("Request: Librus/Messages - $LIBRUS_MESSAGES_URL/$module")
val callback = object : TextCallbackHandler() { val callback = object : TextCallbackHandler() {
override fun onSuccess(text: String?, response: Response?) { override fun onSuccess(text: String?, response: Response?) {
@ -127,7 +127,7 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
fun messagesGetJson(tag: String, module: String, method: Int = POST, fun messagesGetJson(tag: String, module: String, method: Int = POST,
parameters: Map<String, Any>? = null, onSuccess: (json: JsonObject?) -> Unit) { parameters: Map<String, Any>? = null, onSuccess: (json: JsonObject?) -> Unit) {
d(tag, "Request: Librus/Messages - $LIBRUS_MESSAGES_URL/$module") Timber.tag(tag).d("Request: Librus/Messages - $LIBRUS_MESSAGES_URL/$module")
val callback = object : TextCallbackHandler() { val callback = object : TextCallbackHandler() {
override fun onSuccess(text: String?, response: Response?) { override fun onSuccess(text: String?, response: Response?) {
@ -211,7 +211,7 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
fun sandboxGet(tag: String, action: String, parameters: Map<String, Any>? = null, fun sandboxGet(tag: String, action: String, parameters: Map<String, Any>? = null,
onSuccess: (json: JsonObject) -> Unit) { onSuccess: (json: JsonObject) -> Unit) {
d(tag, "Request: Librus/Messages - $LIBRUS_SANDBOX_URL$action") Timber.tag(tag).d("Request: Librus/Messages - $LIBRUS_SANDBOX_URL$action")
val callback = object : JsonCallbackHandler() { val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) { override fun onSuccess(json: JsonObject?, response: Response?) {
@ -256,7 +256,7 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
method: Int = GET, method: Int = GET,
onProgress: (written: Long, total: Long) -> Unit) { onProgress: (written: Long, total: Long) -> Unit) {
d(tag, "Request: Librus/Messages - $url") Timber.tag(tag).d("Request: Librus/Messages - $url")
val callback = object : FileCallbackHandler(targetFile) { val callback = object : FileCallbackHandler(targetFile) {
override fun onSuccess(file: File?, response: Response?) { override fun onSuccess(file: File?, response: Response?) {

View File

@ -8,7 +8,7 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.net.HttpURLConnection import java.net.HttpURLConnection
open class LibrusPortal(open val data: DataLibrus) { open class LibrusPortal(open val data: DataLibrus) {
@ -24,7 +24,7 @@ open class LibrusPortal(open val data: DataLibrus) {
fun portalGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject, response: Response?) -> Unit) { fun portalGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject, response: Response?) -> Unit) {
d(tag, "Request: Librus/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_PORTAL else LIBRUS_PORTAL_URL}$endpoint") Timber.tag(tag).d("Request: Librus/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_PORTAL else LIBRUS_PORTAL_URL}$endpoint")
val callback = object : JsonCallbackHandler() { val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) { override fun onSuccess(json: JsonObject?, response: Response?) {
@ -59,8 +59,8 @@ open class LibrusPortal(open val data: DataLibrus) {
if (response?.code() == HttpURLConnection.HTTP_OK) { if (response?.code() == HttpURLConnection.HTTP_OK) {
try { try {
onSuccess(json, response) onSuccess(json, response)
} catch (e: NullPointerException) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
data.error(ApiError(tag, EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN) data.error(ApiError(tag, EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN)
.withResponse(response) .withResponse(response)
.withThrowable(e) .withThrowable(e)

View File

@ -10,7 +10,7 @@ import im.wangchao.mhttp.callback.TextCallbackHandler
import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) { open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
companion object { companion object {
@ -25,7 +25,7 @@ open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
fun synergiaGet(tag: String, endpoint: String, method: Int = GET, fun synergiaGet(tag: String, endpoint: String, method: Int = GET,
parameters: Map<String, Any> = emptyMap(), onSuccess: (text: String) -> Unit) { parameters: Map<String, Any> = emptyMap(), onSuccess: (text: String) -> Unit) {
d(tag, "Request: Librus/Synergia - $LIBRUS_SYNERGIA_URL/$endpoint") Timber.tag(tag).d("Request: Librus/Synergia - $LIBRUS_SYNERGIA_URL/$endpoint")
val callback = object : TextCallbackHandler() { val callback = object : TextCallbackHandler() {
override fun onSuccess(text: String?, response: Response?) { override fun onSuccess(text: String?, response: Response?) {
@ -91,7 +91,7 @@ open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
} }
fun redirectUrlGet(tag: String, url: String, onSuccess: (url: String) -> Unit) { fun redirectUrlGet(tag: String, url: String, onSuccess: (url: String) -> Unit) {
d(tag, "Request: Librus/Synergia - $url") Timber.tag(tag).d("Request: Librus/Synergia - $url")
val callback = object : TextCallbackHandler() { val callback = object : TextCallbackHandler() {
override fun onSuccess(text: String?, response: Response) { override fun onSuccess(text: String?, response: Response) {

View File

@ -16,10 +16,10 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.data.enums.MetadataType import pl.szczodrzynski.edziennik.data.enums.MetadataType
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
import timber.log.Timber
class LibrusApiTimetables(override val data: DataLibrus, class LibrusApiTimetables(override val data: DataLibrus,
override val lastSync: Long?, override val lastSync: Long?,
@ -71,7 +71,7 @@ class LibrusApiTimetables(override val data: DataLibrus,
} }
} }
d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate") Timber.d("Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate")
if (data.timetableNotPublic) data.timetableNotPublic = false if (data.timetableNotPublic) data.timetableNotPublic = false

View File

@ -8,6 +8,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class LibrusLogin(val data: DataLibrus, val onSuccess: () -> Unit) { class LibrusLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
companion object { companion object {
@ -43,7 +44,7 @@ class LibrusLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
onSuccess(null) onSuccess(null)
return return
} }
Utils.d(TAG, "Using login method $loginMethod") Timber.d("Using login method $loginMethod")
when (loginMethod) { when (loginMethod) {
LoginMethod.LIBRUS_PORTAL -> { LoginMethod.LIBRUS_PORTAL -> {
data.startProgress(R.string.edziennik_progress_login_librus_portal) data.startProgress(R.string.edziennik_progress_login_librus_portal)

View File

@ -17,7 +17,7 @@ import pl.szczodrzynski.edziennik.data.enums.LoginMode
import pl.szczodrzynski.edziennik.ext.getInt import pl.szczodrzynski.edziennik.ext.getInt
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.ext.getUnixDate import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.net.HttpURLConnection.* import java.net.HttpURLConnection.*
@Suppress("ConvertSecondaryConstructorToPrimary") @Suppress("ConvertSecondaryConstructorToPrimary")
@ -171,7 +171,7 @@ class LibrusLoginApi {
} }
private fun synergiaGetToken() { private fun synergiaGetToken() {
d(TAG, "Request: Librus/Login/Api - $LIBRUS_API_TOKEN_URL") Timber.d("Request: Librus/Login/Api - $LIBRUS_API_TOKEN_URL")
Request.builder() Request.builder()
.url(LIBRUS_API_TOKEN_URL) .url(LIBRUS_API_TOKEN_URL)
@ -192,7 +192,7 @@ class LibrusLoginApi {
.enqueue() .enqueue()
} }
private fun synergiaRefreshToken() { private fun synergiaRefreshToken() {
d(TAG, "Request: Librus/Login/Api - $LIBRUS_API_TOKEN_URL") Timber.d("Request: Librus/Login/Api - $LIBRUS_API_TOKEN_URL")
Request.builder() Request.builder()
.url(LIBRUS_API_TOKEN_URL) .url(LIBRUS_API_TOKEN_URL)
@ -211,7 +211,7 @@ class LibrusLoginApi {
.enqueue() .enqueue()
} }
private fun jstGetToken() { private fun jstGetToken() {
d(TAG, "Request: Librus/Login/Api - $LIBRUS_API_TOKEN_JST_URL") Timber.d("Request: Librus/Login/Api - $LIBRUS_API_TOKEN_JST_URL")
Request.builder() Request.builder()
.url(LIBRUS_API_TOKEN_JST_URL) .url(LIBRUS_API_TOKEN_JST_URL)
@ -233,7 +233,7 @@ class LibrusLoginApi {
.enqueue() .enqueue()
} }
private fun jstRefreshToken() { private fun jstRefreshToken() {
d(TAG, "Request: Librus/Login/Api - $LIBRUS_API_TOKEN_JST_URL") Timber.d("Request: Librus/Login/Api - $LIBRUS_API_TOKEN_JST_URL")
Request.builder() Request.builder()
.url(LIBRUS_API_TOKEN_JST_URL) .url(LIBRUS_API_TOKEN_JST_URL)

View File

@ -14,7 +14,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.LibrusRecaptchaHelpe
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.ext.getUnixDate import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.io.StringWriter import java.io.StringWriter
import javax.xml.parsers.DocumentBuilderFactory import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys import javax.xml.transform.OutputKeys
@ -108,7 +108,7 @@ class LibrusLoginMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
* XML (Flash messages website) login method. Uses a Synergia login and password. * XML (Flash messages website) login method. Uses a Synergia login and password.
*/ */
private fun loginWithCredentials() { private fun loginWithCredentials() {
d(TAG, "Request: Librus/Login/Messages - $LIBRUS_MESSAGES_URL/Login") Timber.d("Request: Librus/Login/Messages - $LIBRUS_MESSAGES_URL/Login")
val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
val doc = docBuilder.newDocument() val doc = docBuilder.newDocument()
@ -152,7 +152,7 @@ class LibrusLoginMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
* A login method using the Synergia website (/wiadomosci2 Auto Login). * A login method using the Synergia website (/wiadomosci2 Auto Login).
*/ */
private fun loginWithSynergia(url: String = "https://synergia.librus.pl/wiadomosci2") { private fun loginWithSynergia(url: String = "https://synergia.librus.pl/wiadomosci2") {
d(TAG, "Request: Librus/Login/Messages - $url") Timber.d("Request: Librus/Login/Messages - $url")
Request.builder() Request.builder()
.url(url) .url(url)

View File

@ -14,7 +14,7 @@ import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.enums.LoginMode import pl.szczodrzynski.edziennik.data.enums.LoginMode
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.net.HttpURLConnection.* import java.net.HttpURLConnection.*
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
@ -63,7 +63,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
}} }}
private fun authorize(url: String, referer: String? = null) { private fun authorize(url: String, referer: String? = null) {
d(TAG, "Request: Librus/Login/Portal - $url") Timber.d("Request: Librus/Login/Portal - $url")
Request.builder() Request.builder()
.url(url) .url(url)
@ -176,7 +176,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
return return
} }
d(TAG, "Request: Librus/Login/Portal - $url") Timber.d("Request: Librus/Login/Portal - $url")
val recaptchaCode = data.arguments?.getString("recaptchaCode") ?: data.loginStore.getLoginData("recaptchaCode", null) val recaptchaCode = data.arguments?.getString("recaptchaCode") ?: data.loginStore.getLoginData("recaptchaCode", null)
val recaptchaTime = data.arguments?.getLong("recaptchaTime") ?: data.loginStore.getLoginData("recaptchaTime", 0L) val recaptchaTime = data.arguments?.getLong("recaptchaTime") ?: data.loginStore.getLoginData("recaptchaTime", 0L)
@ -239,7 +239,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
} }
private fun accessToken(code: String?, refreshToken: String?) { private fun accessToken(code: String?, refreshToken: String?) {
d(TAG, "Request: Librus/Login/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_TOKEN else LIBRUS_TOKEN_URL}") Timber.d("Request: Librus/Login/Portal - ${if (data.fakeLogin) FAKE_LIBRUS_TOKEN else LIBRUS_TOKEN_URL}")
val onSuccess = { json: JsonObject, response: Response? -> val onSuccess = { json: JsonObject, response: Response? ->
data.portalAccessToken = json.getString("access_token") data.portalAccessToken = json.getString("access_token")

View File

@ -15,7 +15,7 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.ext.getUnixDate import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.net.HttpURLConnection import java.net.HttpURLConnection
class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusApi(data, null) { class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusApi(data, null) {
@ -58,7 +58,7 @@ class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Un
* A login method using the Synergia API (AutoLoginToken endpoint). * A login method using the Synergia API (AutoLoginToken endpoint).
*/ */
private fun loginWithApi() { private fun loginWithApi() {
d(TAG, "Request: Librus/Login/Synergia - $LIBRUS_API_URL/AutoLoginToken") Timber.d("Request: Librus/Login/Synergia - $LIBRUS_API_URL/AutoLoginToken")
val onSuccess = { json: JsonObject -> val onSuccess = { json: JsonObject ->
loginWithToken(json.getString("Token")) loginWithToken(json.getString("Token"))
@ -73,7 +73,7 @@ class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Un
return return
} }
d(TAG, "Request: Librus/Login/Synergia - " + LIBRUS_SYNERGIA_TOKEN_LOGIN_URL.replace("TOKEN", token) + "/uczen/widok/centrum_powiadomien") Timber.d("Request: Librus/Login/Synergia - " + LIBRUS_SYNERGIA_TOKEN_LOGIN_URL.replace("TOKEN", token) + "/uczen/widok/centrum_powiadomien")
val callback = object : TextCallbackHandler() { val callback = object : TextCallbackHandler() {
override fun onSuccess(json: String?, response: Response?) { override fun onSuccess(json: String?, response: Response?) {

View File

@ -9,7 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusPortal
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.enums.LoginMode import pl.szczodrzynski.edziennik.data.enums.LoginMode
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class SynergiaTokenExtractor(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusPortal(data) { class SynergiaTokenExtractor(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusPortal(data) {
companion object { companion object {
@ -45,7 +45,7 @@ class SynergiaTokenExtractor(override val data: DataLibrus, val onSuccess: () ->
val accountLogin = data.apiLogin ?: return false val accountLogin = data.apiLogin ?: return false
data.portalAccessToken ?: return false data.portalAccessToken ?: return false
d(TAG, "Request: Librus/SynergiaTokenExtractor - ${if (data.fakeLogin) FAKE_LIBRUS_ACCOUNT else LIBRUS_ACCOUNT_URL}$accountLogin") Timber.d("Request: Librus/SynergiaTokenExtractor - ${if (data.fakeLogin) FAKE_LIBRUS_ACCOUNT else LIBRUS_ACCOUNT_URL}$accountLogin")
val onSuccess = { json: JsonObject, response: Response? -> val onSuccess = { json: JsonObject, response: Response? ->
// synergiaAccount is executed when a synergia token needs a refresh // synergiaAccount is executed when a synergia token needs a refresh

View File

@ -23,7 +23,7 @@ import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -63,10 +63,10 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
} }
private fun login(loginMethod: LoginMethod? = null, afterLogin: (() -> Unit)? = null) { private fun login(loginMethod: LoginMethod? = null, afterLogin: (() -> Unit)? = null) {
d(TAG, "Trying to login with ${data.targetLoginMethods}") Timber.d("Trying to login with ${data.targetLoginMethods}")
if (internalErrorList.isNotEmpty()) { if (internalErrorList.isNotEmpty()) {
d(TAG, " - Internal errors:") Timber.d(" - Internal errors:")
internalErrorList.forEach { d(TAG, " - code $it") } internalErrorList.forEach { Timber.d(" - code $it") }
} }
loginMethod?.let { data.prepareFor(it) } loginMethod?.let { data.prepareFor(it) }
afterLogin?.let { this.afterLogin = it } afterLogin?.let { this.afterLogin = it }
@ -76,10 +76,10 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
} }
private fun data() { private fun data() {
d(TAG, "Endpoint IDs: ${data.targetEndpoints}") Timber.d("Endpoint IDs: ${data.targetEndpoints}")
if (internalErrorList.isNotEmpty()) { if (internalErrorList.isNotEmpty()) {
d(TAG, " - Internal errors:") Timber.d(" - Internal errors:")
internalErrorList.forEach { d(TAG, " - code $it") } internalErrorList.forEach { Timber.d(" - code $it") }
} }
afterLogin?.invoke() ?: MobidziennikData(data) { afterLogin?.invoke() ?: MobidziennikData(data) {
completed() completed()
@ -138,7 +138,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
override fun firstLogin() { MobidziennikFirstLogin(data) { completed() } } override fun firstLogin() { MobidziennikFirstLogin(data) { completed() } }
override fun cancel() { override fun cancel() {
d(TAG, "Cancelled") Timber.d("Cancelled")
data.cancel() data.cancel()
} }

View File

@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api.Mobid
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api2.MobidziennikApi2Main import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api2.MobidziennikApi2Main
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.* import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.*
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class MobidziennikData(val data: DataMobidziennik, val onSuccess: () -> Unit) { class MobidziennikData(val data: DataMobidziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -38,7 +39,7 @@ class MobidziennikData(val data: DataMobidziennik, val onSuccess: () -> Unit) {
} }
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) { private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync") Timber.d("Using endpoint $endpointId. Last sync time = $lastSync")
when (endpointId) { when (endpointId) {
ENDPOINT_MOBIDZIENNIK_API_MAIN -> { ENDPOINT_MOBIDZIENNIK_API_MAIN -> {
data.startProgress(R.string.edziennik_progress_endpoint_data) data.startProgress(R.string.edziennik_progress_endpoint_data)

View File

@ -11,7 +11,7 @@ import im.wangchao.mhttp.callback.TextCallbackHandler
import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.io.File import java.io.File
open class MobidziennikWeb(open val data: DataMobidziennik, open val lastSync: Long?) { open class MobidziennikWeb(open val data: DataMobidziennik, open val lastSync: Long?) {
@ -52,7 +52,7 @@ open class MobidziennikWeb(open val data: DataMobidziennik, open val lastSync: L
) { ) {
val url = fullUrl ?: "https://${data.loginServerName}.mobidziennik.pl$endpoint" val url = fullUrl ?: "https://${data.loginServerName}.mobidziennik.pl$endpoint"
d(tag, "Request: Mobidziennik/Web - $url") Timber.tag(tag).d("Request: Mobidziennik/Web - $url")
if (data.webSessionKey == null) { if (data.webSessionKey == null) {
data.error(TAG, ERROR_MOBIDZIENNIK_WEB_NO_SESSION_KEY) data.error(TAG, ERROR_MOBIDZIENNIK_WEB_NO_SESSION_KEY)
@ -128,7 +128,7 @@ open class MobidziennikWeb(open val data: DataMobidziennik, open val lastSync: L
onProgress: (written: Long, total: Long) -> Unit) { onProgress: (written: Long, total: Long) -> Unit) {
val url = "https://${data.loginServerName}.mobidziennik.pl$action" val url = "https://${data.loginServerName}.mobidziennik.pl$action"
d(tag, "Request: Mobidziennik/Web - $url") Timber.tag(tag).d("Request: Mobidziennik/Web - $url")
if (data.webSessionKey == null) { if (data.webSessionKey == null) {
data.error(TAG, ERROR_MOBIDZIENNIK_WEB_NO_SESSION_KEY) data.error(TAG, ERROR_MOBIDZIENNIK_WEB_NO_SESSION_KEY)

View File

@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.enums.MetadataType import pl.szczodrzynski.edziennik.data.enums.MetadataType
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import timber.log.Timber
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -45,8 +46,8 @@ class MobidziennikApiEvents(val data: DataMobidziennik, rows: List<String>) {
val format = SimpleDateFormat("yyyyMMddHHmmss", Locale.US) val format = SimpleDateFormat("yyyyMMddHHmmss", Locale.US)
val addedDate = try { val addedDate = try {
format.parse(cols[7]).time format.parse(cols[7]).time
} catch (e: ParseException) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
System.currentTimeMillis() System.currentTimeMillis()
} }

View File

@ -17,6 +17,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class MobidziennikApi2Main(val data: DataMobidziennik, class MobidziennikApi2Main(val data: DataMobidziennik,
val lastSync: Long?, val lastSync: Long?,
@ -33,7 +34,7 @@ class MobidziennikApi2Main(val data: DataMobidziennik,
get() = data.profile get() = data.profile
init { init {
Utils.d(TAG, "Request: Mobidziennik/Api2/Main - https://${data.loginServerName}.mobidziennik.pl/api2/logowanie") Timber.d("Request: Mobidziennik/Api2/Main - https://${data.loginServerName}.mobidziennik.pl/api2/logowanie")
val callback = object : JsonCallbackHandler() { val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) { override fun onSuccess(json: JsonObject?, response: Response?) {

View File

@ -25,10 +25,10 @@ import pl.szczodrzynski.edziennik.ext.dateToSemester
import pl.szczodrzynski.edziennik.ext.fixName import pl.szczodrzynski.edziennik.ext.fixName
import pl.szczodrzynski.edziennik.ext.get import pl.szczodrzynski.edziennik.ext.get
import pl.szczodrzynski.edziennik.ext.singleOrNull import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
import timber.log.Timber
class MobidziennikWebAttendance(override val data: DataMobidziennik, class MobidziennikWebAttendance(override val data: DataMobidziennik,
override val lastSync: Long?, override val lastSync: Long?,
@ -156,7 +156,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
} }
} }
d(TAG, "Done in ${System.currentTimeMillis()-start} ms (request ${start-requestTime} ms)") Timber.d("Done in ${System.currentTimeMillis()-start} ms (request ${start-requestTime} ms)")
onSuccess() onSuccess()
} }

View File

@ -8,6 +8,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class MobidziennikLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) { class MobidziennikLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -43,7 +44,7 @@ class MobidziennikLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) {
onSuccess(null) onSuccess(null)
return return
} }
Utils.d(TAG, "Using login method $loginMethod") Timber.d("Using login method $loginMethod")
when (loginMethod) { when (loginMethod) {
LoginMethod.MOBIDZIENNIK_WEB -> { LoginMethod.MOBIDZIENNIK_WEB -> {
data.startProgress(R.string.edziennik_progress_login_mobidziennik_web) data.startProgress(R.string.edziennik_progress_login_mobidziennik_web)

View File

@ -19,6 +19,7 @@ import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.ext.isNotNullNorBlank import pl.szczodrzynski.edziennik.ext.isNotNullNorBlank
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class MobidziennikLoginApi2(val data: DataMobidziennik, val onSuccess: () -> Unit) { class MobidziennikLoginApi2(val data: DataMobidziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -54,7 +55,7 @@ class MobidziennikLoginApi2(val data: DataMobidziennik, val onSuccess: () -> Uni
}} }}
private fun loginWithCredentials() { private fun loginWithCredentials() {
Utils.d(TAG, "Request: Mobidziennik/Login/Api2 - https://mobidziennik.pl/logowanie") Timber.d("Request: Mobidziennik/Login/Api2 - https://mobidziennik.pl/logowanie")
val callback = object : JsonCallbackHandler() { val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) { override fun onSuccess(json: JsonObject?, response: Response?) {

View File

@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.getUnixDate import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit) { class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -36,7 +36,7 @@ class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit
}} }}
private fun loginWithCredentials() { private fun loginWithCredentials() {
d(TAG, "Request: Mobidziennik/Login/Web - https://${data.loginServerName}.mobidziennik.pl/api/") Timber.d("Request: Mobidziennik/Login/Web - https://${data.loginServerName}.mobidziennik.pl/api/")
val callback = object : TextCallbackHandler() { val callback = object : TextCallbackHandler() {
override fun onSuccess(text: String?, response: Response?) { override fun onSuccess(text: String?, response: Response?) {

View File

@ -25,6 +25,7 @@ import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
import java.io.File import java.io.File
class Podlasie(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Podlasie(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
@ -58,8 +59,8 @@ class Podlasie(val app: App, val profile: Profile?, val loginStore: LoginStore,
override fun sync(featureTypes: Set<FeatureType>?, onlyEndpoints: Set<Int>?, arguments: JsonObject?) { override fun sync(featureTypes: Set<FeatureType>?, onlyEndpoints: Set<Int>?, arguments: JsonObject?) {
data.arguments = arguments data.arguments = arguments
data.prepare(PodlasieFeatures, featureTypes, onlyEndpoints) data.prepare(PodlasieFeatures, featureTypes, onlyEndpoints)
Utils.d(TAG, "LoginMethod IDs: ${data.targetLoginMethods}") Timber.d("LoginMethod IDs: ${data.targetLoginMethods}")
Utils.d(TAG, "Endpoint IDs: ${data.targetEndpoints}") Timber.d("Endpoint IDs: ${data.targetEndpoints}")
PodlasieLogin(data) { PodlasieLogin(data) {
PodlasieData(data) { PodlasieData(data) {
completed() completed()
@ -133,7 +134,7 @@ class Podlasie(val app: App, val profile: Profile?, val loginStore: LoginStore,
} }
override fun cancel() { override fun cancel() {
Utils.d(TAG, "Cancelled") Timber.d("Cancelled")
data.cancel() data.cancel()
} }

View File

@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.ext.getInt
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.toHexString import pl.szczodrzynski.edziennik.ext.toHexString
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
import java.security.MessageDigest import java.security.MessageDigest
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -34,7 +35,7 @@ open class PodlasieApi(open val data: DataPodlasie, open val lastSync: Long?) {
fun apiGet(tag: String, endpoint: String, onSuccess: (json: JsonObject) -> Unit) { fun apiGet(tag: String, endpoint: String, onSuccess: (json: JsonObject) -> Unit) {
val url = PODLASIE_API_URL + endpoint val url = PODLASIE_API_URL + endpoint
Utils.d(tag, "Request: Podlasie/Api - $url") Timber.tag(tag).d("Request: Podlasie/Api - $url")
if (data.apiToken == null) { if (data.apiToken == null) {
data.error(tag, ERROR_PODLASIE_API_NO_TOKEN) data.error(tag, ERROR_PODLASIE_API_NO_TOKEN)

View File

@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.ENDPOINT_PODLASIE_API_MAIN import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.ENDPOINT_PODLASIE_API_MAIN
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.api.PodlasieApiMain import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.api.PodlasieApiMain
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class PodlasieData(val data: DataPodlasie, val onSuccess: () -> Unit) { class PodlasieData(val data: DataPodlasie, val onSuccess: () -> Unit) {
companion object { companion object {
@ -37,7 +38,7 @@ class PodlasieData(val data: DataPodlasie, val onSuccess: () -> Unit) {
} }
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) { private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync") Timber.d("Using endpoint $endpointId. Last sync time = $lastSync")
when (endpointId) { when (endpointId) {
ENDPOINT_PODLASIE_API_MAIN -> { ENDPOINT_PODLASIE_API_MAIN -> {
data.startProgress(R.string.edziennik_progress_endpoint_data) data.startProgress(R.string.edziennik_progress_endpoint_data)

View File

@ -8,6 +8,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class PodlasieLogin(val data: DataPodlasie, val onSuccess: () -> Unit) { class PodlasieLogin(val data: DataPodlasie, val onSuccess: () -> Unit) {
companion object { companion object {
@ -43,7 +44,7 @@ class PodlasieLogin(val data: DataPodlasie, val onSuccess: () -> Unit) {
onSuccess(null) onSuccess(null)
return return
} }
Utils.d(TAG, "Using login method $loginMethod") Timber.d("Using login method $loginMethod")
when (loginMethod) { when (loginMethod) {
LoginMethod.PODLASIE_API -> { LoginMethod.PODLASIE_API -> {
data.startProgress(R.string.edziennik_progress_login_podlasie_api) data.startProgress(R.string.edziennik_progress_login_podlasie_api)

View File

@ -22,7 +22,7 @@ import pl.szczodrzynski.edziennik.data.enums.FeatureType
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class Template(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Template(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
companion object { companion object {
@ -55,8 +55,8 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
override fun sync(featureTypes: Set<FeatureType>?, onlyEndpoints: Set<Int>?, arguments: JsonObject?) { override fun sync(featureTypes: Set<FeatureType>?, onlyEndpoints: Set<Int>?, arguments: JsonObject?) {
data.arguments = arguments data.arguments = arguments
data.prepare(TemplateFeatures, featureTypes, onlyEndpoints) data.prepare(TemplateFeatures, featureTypes, onlyEndpoints)
d(TAG, "LoginMethod IDs: ${data.targetLoginMethods}") Timber.d("LoginMethod IDs: ${data.targetLoginMethods}")
d(TAG, "Endpoint IDs: ${data.targetEndpoints}") Timber.d("Endpoint IDs: ${data.targetEndpoints}")
TemplateLogin(data) { TemplateLogin(data) {
TemplateData(data) { TemplateData(data) {
completed() completed()
@ -99,7 +99,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
} }
override fun cancel() { override fun cancel() {
d(TAG, "Cancelled") Timber.d("Cancelled")
data.cancel() data.cancel()
} }

View File

@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.api.TemplateA
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web.TemplateWebSample import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web.TemplateWebSample
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web.TemplateWebSample2 import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web.TemplateWebSample2
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class TemplateData(val data: DataTemplate, val onSuccess: () -> Unit) { class TemplateData(val data: DataTemplate, val onSuccess: () -> Unit) {
companion object { companion object {
@ -41,7 +42,7 @@ class TemplateData(val data: DataTemplate, val onSuccess: () -> Unit) {
} }
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) { private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync") Timber.d("Using endpoint $endpointId. Last sync time = $lastSync")
when (endpointId) { when (endpointId) {
ENDPOINT_TEMPLATE_WEB_SAMPLE -> { ENDPOINT_TEMPLATE_WEB_SAMPLE -> {
data.startProgress(R.string.edziennik_progress_endpoint_student_info) data.startProgress(R.string.edziennik_progress_endpoint_student_info)

View File

@ -8,6 +8,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class TemplateLogin(val data: DataTemplate, val onSuccess: () -> Unit) { class TemplateLogin(val data: DataTemplate, val onSuccess: () -> Unit) {
companion object { companion object {
@ -43,7 +44,7 @@ class TemplateLogin(val data: DataTemplate, val onSuccess: () -> Unit) {
onSuccess(null) onSuccess(null)
return return
} }
Utils.d(TAG, "Using login method $loginMethod") Timber.d("Using login method $loginMethod")
when (loginMethod) { when (loginMethod) {
LoginMethod.TEMPLATE_WEB -> { LoginMethod.TEMPLATE_WEB -> {
data.startProgress(R.string.edziennik_progress_login_template_web) data.startProgress(R.string.edziennik_progress_login_template_web)

View File

@ -21,7 +21,7 @@ import pl.szczodrzynski.edziennik.data.enums.FeatureType
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class Usos( class Usos(
val app: App, val app: App,
@ -55,8 +55,8 @@ class Usos(
) { ) {
data.arguments = arguments data.arguments = arguments
data.prepare(UsosFeatures, featureTypes, onlyEndpoints) data.prepare(UsosFeatures, featureTypes, onlyEndpoints)
d(TAG, "LoginMethod IDs: ${data.targetLoginMethods}") Timber.d("LoginMethod IDs: ${data.targetLoginMethods}")
d(TAG, "Endpoint IDs: ${data.targetEndpoints}") Timber.d("Endpoint IDs: ${data.targetEndpoints}")
UsosLogin(data) { UsosLogin(data) {
UsosData(data) { UsosData(data) {
completed() completed()
@ -79,7 +79,7 @@ class Usos(
} }
override fun cancel() { override fun cancel() {
d(TAG, "Cancelled") Timber.d("Cancelled")
data.cancel() data.cancel()
} }

View File

@ -19,7 +19,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLoginApi import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLoginApi
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.net.HttpURLConnection.* import java.net.HttpURLConnection.*
import java.util.UUID import java.util.UUID
@ -89,7 +89,7 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) {
onSuccess: (data: T, response: Response?) -> Unit, onSuccess: (data: T, response: Response?) -> Unit,
) { ) {
val url = "${data.instanceUrl}services/$service" val url = "${data.instanceUrl}services/$service"
d(tag, "Request: Usos/Api - $url") Timber.tag(tag).d("Request: Usos/Api - $url")
val formData = mutableMapOf<String, String>() val formData = mutableMapOf<String, String>()
if (params != null) if (params != null)

View File

@ -5,13 +5,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web.TemplateWebSample
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.* import pl.szczodrzynski.edziennik.data.api.edziennik.usos.*
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiCourses import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiCourses
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiTerms import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiTerms
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiTimetable import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiTimetable
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiUser import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiUser
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class UsosData(val data: DataUsos, val onSuccess: () -> Unit) { class UsosData(val data: DataUsos, val onSuccess: () -> Unit) {
companion object { companion object {
@ -40,7 +39,7 @@ class UsosData(val data: DataUsos, val onSuccess: () -> Unit) {
} }
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) { private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync") Timber.d("Using endpoint $endpointId. Last sync time = $lastSync")
when (endpointId) { when (endpointId) {
ENDPOINT_USOS_API_USER -> { ENDPOINT_USOS_API_USER -> {
data.startProgress(R.string.edziennik_progress_endpoint_student_info) data.startProgress(R.string.edziennik_progress_endpoint_student_info)

View File

@ -7,7 +7,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.usos.login
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class UsosLogin(val data: DataUsos, val onSuccess: () -> Unit) { class UsosLogin(val data: DataUsos, val onSuccess: () -> Unit) {
companion object { companion object {
@ -43,7 +43,7 @@ class UsosLogin(val data: DataUsos, val onSuccess: () -> Unit) {
onSuccess(null) onSuccess(null)
return return
} }
d(TAG, "Using login method $loginMethod") Timber.d("Using login method $loginMethod")
when (loginMethod) { when (loginMethod) {
LoginMethod.USOS_API -> { LoginMethod.USOS_API -> {
data.startProgress(R.string.edziennik_progress_login_usos_api) data.startProgress(R.string.edziennik_progress_login_usos_api)

View File

@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) { class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) {
companion object { companion object {
@ -71,7 +71,7 @@ class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) {
} }
private fun login() { private fun login() {
d(TAG, "Login to ${data.schoolId} with ${data.oauthLoginResponse}") Timber.d("Login to ${data.schoolId} with ${data.oauthLoginResponse}")
val authorizeResponse = data.oauthLoginResponse?.fromQueryString() val authorizeResponse = data.oauthLoginResponse?.fromQueryString()
?: return // checked in init {} ?: return // checked in init {}

View File

@ -34,7 +34,7 @@ import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
import java.io.File import java.io.File
class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
@ -78,10 +78,10 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
return return
} }
d(TAG, "Trying to login with ${data.targetLoginMethods}") Timber.d("Trying to login with ${data.targetLoginMethods}")
if (internalErrorList.isNotEmpty()) { if (internalErrorList.isNotEmpty()) {
d(TAG, " - Internal errors:") Timber.d(" - Internal errors:")
internalErrorList.forEach { d(TAG, " - code $it") } internalErrorList.forEach { Timber.d(" - code $it") }
} }
loginMethod?.let { data.prepareFor(it) } loginMethod?.let { data.prepareFor(it) }
afterLogin?.let { this.afterLogin = it } afterLogin?.let { this.afterLogin = it }
@ -91,10 +91,10 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
} }
private fun data() { private fun data() {
d(TAG, "Endpoint IDs: ${data.targetEndpoints}") Timber.d("Endpoint IDs: ${data.targetEndpoints}")
if (internalErrorList.isNotEmpty()) { if (internalErrorList.isNotEmpty()) {
d(TAG, " - Internal errors:") Timber.d(" - Internal errors:")
internalErrorList.forEach { d(TAG, " - code $it") } internalErrorList.forEach { Timber.d(" - code $it") }
} }
afterLogin?.invoke() ?: VulcanData(data) { afterLogin?.invoke() ?: VulcanData(data) {
completed() completed()
@ -179,7 +179,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
override fun firstLogin() { VulcanFirstLogin(data) { completed() } } override fun firstLogin() { VulcanFirstLogin(data) { completed() } }
override fun cancel() { override fun cancel() {
d(TAG, "Cancelled") Timber.d("Cancelled")
data.cancel() data.cancel()
} }

View File

@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.*
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.web.VulcanWebLuckyNumber import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.web.VulcanWebLuckyNumber
import pl.szczodrzynski.edziennik.data.db.entity.Message import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) { class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
companion object { companion object {
@ -82,7 +83,7 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
} }
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) { private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync") Timber.d("Using endpoint $endpointId. Last sync time = $lastSync")
when (endpointId) { when (endpointId) {
ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS -> { ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS -> {
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number) data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)

View File

@ -22,9 +22,9 @@ import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
import pl.szczodrzynski.edziennik.data.db.entity.Subject import pl.szczodrzynski.edziennik.data.db.entity.Subject
import pl.szczodrzynski.edziennik.data.db.entity.Teacher import pl.szczodrzynski.edziennik.data.db.entity.Teacher
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import timber.log.Timber
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.HttpURLConnection.HTTP_NOT_FOUND import java.net.HttpURLConnection.HTTP_NOT_FOUND
import java.net.URLEncoder import java.net.URLEncoder
@ -189,7 +189,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
) { ) {
val url = "${if (baseUrl) data.apiUrl else data.fullApiUrl}$endpoint" val url = "${if (baseUrl) data.apiUrl else data.fullApiUrl}$endpoint"
d(tag, "Request: Vulcan/Hebe - $url") Timber.tag(tag).d("Request: Vulcan/Hebe - $url")
val privateKey = data.hebePrivateKey val privateKey = data.hebePrivateKey
val publicHash = data.hebePublicHash val publicHash = data.hebePublicHash

View File

@ -18,6 +18,7 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import timber.log.Timber
import java.io.File import java.io.File
import java.net.HttpURLConnection import java.net.HttpURLConnection
@ -269,7 +270,7 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
else -> "uonetplus" else -> "uonetplus"
} + ".${data.webHost}/${data.symbol}/$endpoint" } + ".${data.webHost}/${data.symbol}/$endpoint"
Utils.d(tag, "Request: Vulcan/WebMain - $url") Timber.tag(tag).d("Request: Vulcan/WebMain - $url")
val payload = JsonObject() val payload = JsonObject()
parameters.map { (name, value) -> parameters.map { (name, value) ->

View File

@ -25,9 +25,9 @@ import pl.szczodrzynski.edziennik.ext.getBoolean
import pl.szczodrzynski.edziennik.ext.getInt import pl.szczodrzynski.edziennik.ext.getInt
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
import timber.log.Timber
class VulcanHebeTimetable( class VulcanHebeTimetable(
override val data: DataVulcan, override val data: DataVulcan,
@ -107,8 +107,7 @@ class VulcanHebeTimetable(
date.stepForward(0, 0, 1) date.stepForward(0, 0, 1)
} }
d( Timber.d(
TAG,
"Clearing lessons between ${dateFrom.stringY_m_d} and ${dateTo.stringY_m_d}" "Clearing lessons between ${dateFrom.stringY_m_d} and ${dateTo.stringY_m_d}"
) )

View File

@ -8,6 +8,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.enums.LoginMethod import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class VulcanLogin(val data: DataVulcan, val onSuccess: () -> Unit) { class VulcanLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
companion object { companion object {
@ -43,7 +44,7 @@ class VulcanLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
onSuccess(null) onSuccess(null)
return return
} }
Utils.d(TAG, "Using login method $loginMethod") Timber.d("Using login method $loginMethod")
when (loginMethod) { when (loginMethod) {
LoginMethod.VULCAN_WEB_MAIN -> { LoginMethod.VULCAN_WEB_MAIN -> {
data.startProgress(R.string.edziennik_progress_login_vulcan_web_main) data.startProgress(R.string.edziennik_progress_login_vulcan_web_main)

View File

@ -22,6 +22,7 @@ import pl.szczodrzynski.edziennik.data.enums.LoginMethod
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import timber.log.Timber
abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) { abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) {
companion object { companion object {
@ -159,11 +160,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
} }
} }
private fun d(message: String) {
if (DEBUG)
Utils.d(TAG, message)
}
fun clear() { fun clear() {
loginMethods.clear() loginMethods.clear()
@ -201,7 +197,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
return // return on first login return // return on first login
val totalStart = System.currentTimeMillis() val totalStart = System.currentTimeMillis()
var startTime = System.currentTimeMillis() var startTime = System.currentTimeMillis()
d("Saving data to DB") Timber.d("Saving data to DB")
profile.userCode = generateUserCode() profile.userCode = generateUserCode()
@ -233,7 +229,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
} }
} }
d("Profiles saved in ${System.currentTimeMillis()-startTime} ms") Timber.d("Profiles saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
// always present and not empty, during every sync // always present and not empty, during every sync
@ -250,7 +246,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
db.gradeCategoryDao().clear(profileId) db.gradeCategoryDao().clear(profileId)
db.gradeCategoryDao().addAll(gradeCategories.values()) db.gradeCategoryDao().addAll(gradeCategories.values())
d("Maps saved in ${System.currentTimeMillis()-startTime} ms") Timber.d("Maps saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
// may be empty - extracted from DB on demand, by an endpoint // may be empty - extracted from DB on demand, by an endpoint
@ -267,12 +263,12 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
if (librusLessons.size > 0) if (librusLessons.size > 0)
db.librusLessonDao().addAll(librusLessons.values()) db.librusLessonDao().addAll(librusLessons.values())
d("On-demand maps saved in ${System.currentTimeMillis()-startTime} ms") Timber.d("On-demand maps saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
// clear DB with DataRemoveModels added by endpoints // clear DB with DataRemoveModels added by endpoints
for (model in toRemove) { for (model in toRemove) {
d("Clearing DB with $model") Timber.d("Clearing DB with $model")
when (model) { when (model) {
is DataRemoveModel.Timetable -> model.commit(profileId, db.timetableDao()) is DataRemoveModel.Timetable -> model.commit(profileId, db.timetableDao())
is DataRemoveModel.Grades -> model.commit(profileId, db.gradeDao()) is DataRemoveModel.Grades -> model.commit(profileId, db.gradeDao())
@ -281,7 +277,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
} }
} }
d("DB cleared in ${System.currentTimeMillis()-startTime} ms") Timber.d("DB cleared in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
if (metadataList.isNotEmpty()) if (metadataList.isNotEmpty())
@ -289,7 +285,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
if (setSeenMetadataList.isNotEmpty()) if (setSeenMetadataList.isNotEmpty())
db.metadataDao().setSeen(setSeenMetadataList) db.metadataDao().setSeen(setSeenMetadataList)
d("Metadata saved in ${System.currentTimeMillis()-startTime} ms") Timber.d("Metadata saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
db.timetableDao().putAll(lessonList, removeNotKept = true) db.timetableDao().putAll(lessonList, removeNotKept = true)
@ -310,9 +306,9 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
if (messageRecipientIgnoreList.isNotEmpty()) if (messageRecipientIgnoreList.isNotEmpty())
db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList) db.messageRecipientDao().addAllIgnore(messageRecipientIgnoreList)
d("Other data saved in ${System.currentTimeMillis()-startTime} ms") Timber.d("Other data saved in ${System.currentTimeMillis()-startTime} ms")
d("Total save time: ${System.currentTimeMillis()-totalStart} ms") Timber.d("Total save time: ${System.currentTimeMillis()-totalStart} ms")
} }
fun setSyncNext(endpointId: Int, syncIn: Long? = null, forceFeatureType: FeatureType? = null, syncAt: Long? = null) { fun setSyncNext(endpointId: Int, syncIn: Long? = null, forceFeatureType: FeatureType? = null, syncAt: Long? = null) {
@ -339,7 +335,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
abstract fun generateUserCode(): String abstract fun generateUserCode(): String
fun cancel() { fun cancel() {
d("Cancelled") Timber.d("Cancelled")
cancelled = true cancelled = true
saveData() saveData()
} }

View File

@ -10,6 +10,7 @@ import android.content.pm.PackageManager
import android.util.Base64 import android.util.Base64
import pl.szczodrzynski.edziennik.BuildConfig import pl.szczodrzynski.edziennik.BuildConfig
import pl.szczodrzynski.edziennik.ext.sha256 import pl.szczodrzynski.edziennik.ext.sha256
import timber.log.Timber
import java.security.MessageDigest import java.security.MessageDigest
object Signing { object Signing {
@ -32,7 +33,7 @@ object Signing {
appCertificate = Base64.encodeToString(md.digest(), Base64.NO_WRAP) appCertificate = Base64.encodeToString(md.digest(), Base64.NO_WRAP)
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
} }
}} }}

View File

@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.EdziennikNotification
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
import timber.log.Timber
class ErrorReportTask : IApiTask(-1) { class ErrorReportTask : IApiTask(-1) {
override fun prepare(app: App) { override fun prepare(app: App) {
@ -23,7 +24,7 @@ class ErrorReportTask : IApiTask(-1) {
fun run(app: App, taskCallback: EdziennikCallback, notification: EdziennikNotification, errorList: MutableList<ApiError>) { fun run(app: App, taskCallback: EdziennikCallback, notification: EdziennikNotification, errorList: MutableList<ApiError>) {
errorList.forEach { error -> errorList.forEach { error ->
Utils.d(ApiService.TAG, "Error ${error.tag} profile ${error.profileId}: code ${error.errorCode}") Timber.d("Error ${error.tag} profile ${error.profileId}: code ${error.errorCode}")
} }
errorList.clear() errorList.clear()

View File

@ -51,7 +51,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
else else
it.setDefaults(NotificationCompat.DEFAULT_ALL) it.setDefaults(NotificationCompat.DEFAULT_ALL)
} }
.setGroup(if (quiet) app.notificationChannelsManager.dataQuiet.key else app.notificationChannelsManager.data.key) .setGroup(if (quiet) app.notificationManager.dataQuiet.key else app.notificationManager.data.key)
} }
private fun buildSummaryText(summaryCounts: Map<NotificationType, Int>): CharSequence { private fun buildSummaryText(summaryCounts: Map<NotificationType, Int>): CharSequence {
@ -79,7 +79,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
MainActivity::class.java, MainActivity::class.java,
"fragmentId" to NavTarget.NOTIFICATIONS "fragmentId" to NavTarget.NOTIFICATIONS
) )
val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag()) val summaryIntent = PendingIntent.getActivity(app, app.notificationManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag())
// On Nougat or newer - show maximum 8 notifications // On Nougat or newer - show maximum 8 notifications
// On Marshmallow or older - show maximum 4 notifications // On Marshmallow or older - show maximum 4 notifications
@ -95,7 +95,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
} }
// Create a summary to show *instead* of notifications // Create a summary to show *instead* of notifications
val combined = NotificationCompat.Builder(app, app.notificationChannelsManager.data.key) val combined = NotificationCompat.Builder(app, app.notificationManager.data.key)
.setContentTitle(app.getString(R.string.app_name)) .setContentTitle(app.getString(R.string.app_name))
.setContentText(buildSummaryText(summaryCounts)) .setContentText(buildSummaryText(summaryCounts))
.setTicker(newNotificationsText) .setTicker(newNotificationsText)
@ -128,7 +128,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
// Less than 8 notifications // Less than 8 notifications
val notifications = nList.map { val notifications = nList.map {
summaryCounts[it.type] = summaryCounts.getOrDefault(it.type, 0) + 1 summaryCounts[it.type] = summaryCounts.getOrDefault(it.type, 0) + 1
NotificationCompat.Builder(app, app.notificationChannelsManager.data.key) NotificationCompat.Builder(app, app.notificationManager.data.key)
.setContentTitle(it.profileName ?: app.getString(R.string.app_name)) .setContentTitle(it.profileName ?: app.getString(R.string.app_name))
.setContentText(it.text) .setContentText(it.text)
.setSubText(if (it.type == NotificationType.SERVER_MESSAGE) null else it.title) .setSubText(if (it.type == NotificationType.SERVER_MESSAGE) null else it.title)
@ -155,7 +155,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val summary = NotificationCompat.Builder(app, app.notificationChannelsManager.data.key) val summary = NotificationCompat.Builder(app, app.notificationManager.data.key)
.setContentTitle(newNotificationsText) .setContentTitle(newNotificationsText)
.setContentText(buildSummaryText(summaryCounts)) .setContentText(buildSummaryText(summaryCounts))
.setTicker(newNotificationsText) .setTicker(newNotificationsText)
@ -170,7 +170,7 @@ class PostNotifications(val app: App, nList: List<AppNotification>) {
.setAutoCancel(true) .setAutoCancel(true)
.build() .build()
notificationManager.notify(app.notificationChannelsManager.data.id, summary) notificationManager.notify(app.notificationManager.data.id, summary)
} }
} }
}} }}

View File

@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
import pl.szczodrzynski.edziennik.data.db.entity.Notification import pl.szczodrzynski.edziennik.data.db.entity.Notification
import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.ext.HOUR import pl.szczodrzynski.edziennik.ext.HOUR
import pl.szczodrzynski.edziennik.utils.Utils.d import timber.log.Timber
class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-1) { class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-1) {
companion object { companion object {
@ -49,7 +49,7 @@ class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-
notifications.sharedEventNotifications() notifications.sharedEventNotifications()
} }
} }
d(TAG, "Created ${notificationList.count()} notifications.") Timber.d("Created ${notificationList.count()} notifications.")
// filter notifications // filter notifications
notificationList notificationList
@ -70,7 +70,7 @@ class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-
// post all notifications // post all notifications
PostNotifications(app, notificationList) PostNotifications(app, notificationList)
d(TAG, "SzkolnyTask: finished in ${System.currentTimeMillis()-startTime} ms.") Timber.d("SzkolnyTask: finished in ${System.currentTimeMillis()-startTime} ms.")
taskCallback.onCompleted() taskCallback.onCompleted()
} }
} }

View File

@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.enums.LoginType import pl.szczodrzynski.edziennik.data.enums.LoginType
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.mergeWith import pl.szczodrzynski.edziennik.ext.mergeWith
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.HtmlMode import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode
data class AppData( data class AppData(
val configOverrides: Map<String, String>, val configOverrides: Map<String, String>,

View File

@ -4,14 +4,14 @@
package pl.szczodrzynski.edziennik.data.config package pl.szczodrzynski.edziennik.data.config
import android.util.Log
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.entity.ConfigEntry import pl.szczodrzynski.edziennik.data.db.entity.ConfigEntry
import pl.szczodrzynski.edziennik.ext.takePositive import timber.log.Timber
import pl.szczodrzynski.edziennik.utils.Utils.d
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
abstract class BaseConfig<T>( abstract class BaseConfig<T>(
@ -32,6 +32,7 @@ abstract class BaseConfig<T>(
val values = hashMapOf<String, String?>() val values = hashMapOf<String, String?>()
private var currentDataVersion: Int by config<Int>("dataVersion") { private var currentDataVersion: Int by config<Int>("dataVersion") {
Timber.d("Initializing ${this::class.java.simpleName} version $dataVersion")
currentDataVersion = dataVersion currentDataVersion = dataVersion
dataVersion dataVersion
} }
@ -45,15 +46,19 @@ abstract class BaseConfig<T>(
entries = app.db.configDao().getAllNow() entries = app.db.configDao().getAllNow()
values.clear() values.clear()
for ((profileId, key, value) in entries!!) { for ((profileId, key, value) in entries!!) {
if (profileId.takePositive() != this.profileId) if (profileId != (this.profileId ?: -1))
continue continue
values[key] = value values[key] = value
Timber.v("Loaded ${this::class.java.simpleName} profile $profileId key $key value $value")
} }
} }
fun migrate() { fun migrate() {
if (this.dataVersion == this.currentDataVersion) if (this.dataVersion == this.currentDataVersion) {
Timber.d("Config ${this::class.java.simpleName} is up to date (${this.currentDataVersion})")
return return
}
Timber.i("Migrating ${this::class.java.simpleName} ${this.currentDataVersion} -> ${this.dataVersion}")
var dataVersion = this.currentDataVersion var dataVersion = this.currentDataVersion
while (dataVersion < this.dataVersion) { while (dataVersion < this.dataVersion) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@ -70,7 +75,7 @@ abstract class BaseConfig<T>(
operator fun set(key: String, value: String?) { operator fun set(key: String, value: String?) {
values[key] = value values[key] = value
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
d(TAG, "Setting config value ($profileId): $key = $value") Timber.i("Setting config value ($profileId): $key = $value")
app.db.configDao().add(ConfigEntry(profileId ?: -1, key, value)) app.db.configDao().add(ConfigEntry(profileId ?: -1, key, value))
} }
} }

View File

@ -10,20 +10,20 @@ import pl.szczodrzynski.edziennik.BuildConfig
import pl.szczodrzynski.edziennik.data.config.migration.ConfigMigration11 import pl.szczodrzynski.edziennik.data.config.migration.ConfigMigration11
import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
import pl.szczodrzynski.edziennik.data.config.migration.ConfigMigration13 import pl.szczodrzynski.edziennik.data.config.migration.ConfigMigration14
import pl.szczodrzynski.edziennik.data.enums.NavTarget import pl.szczodrzynski.edziennik.data.enums.NavTarget
import pl.szczodrzynski.edziennik.data.enums.Theme import pl.szczodrzynski.edziennik.data.enums.Theme
import pl.szczodrzynski.edziennik.ext.HOUR import pl.szczodrzynski.edziennik.ext.HOUR
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.ORDER_BY_DATE_DESC
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
class Config(app: App) : BaseConfig<Config>(app, profileId = null) { class Config(app: App) : BaseConfig<Config>(app, profileId = null) {
override val dataVersion = 13 override val dataVersion = 14
override val migrations override val migrations
get() = mapOf( get() = mapOf(
11 to ConfigMigration11(), 11 to ConfigMigration11(),
13 to ConfigMigration13(), 14 to ConfigMigration14(),
) )
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf() private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
@ -58,6 +58,7 @@ class Config(app: App) : BaseConfig<Config>(app, profileId = null) {
var apiKeyCustom by config<String?>(null) var apiKeyCustom by config<String?>(null)
var appInstalledTime by config<Long>(0L) var appInstalledTime by config<Long>(0L)
var appRateSnackbarTime by config<Long>(0L) var appRateSnackbarTime by config<Long>(0L)
var lastLogCleanupTime by config<Long>(0L)
var appVersion by config<Int>(BuildConfig.VERSION_CODE) var appVersion by config<Int>(BuildConfig.VERSION_CODE)
var validation by config<String?>(null, "buildValidation") var validation by config<String?>(null, "buildValidation")

View File

@ -4,15 +4,14 @@
package pl.szczodrzynski.edziennik.data.config package pl.szczodrzynski.edziennik.data.config
import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import timber.log.Timber
import java.lang.reflect.ParameterizedType import java.lang.reflect.ParameterizedType
import java.lang.reflect.WildcardType import java.lang.reflect.WildcardType
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
@ -108,8 +107,7 @@ class ConfigDelegate<T>(
value = config[key]?.let(::deserialize) value = config[key]?.let(::deserialize)
} catch (e: Exception) { } catch (e: Exception) {
value = getDefault() value = getDefault()
d(TAG, "Couldn't deserialize '$key'") Timber.e(e, "Couldn't deserialize '$key'")
e.printStackTrace()
} }
if (value == null && !nullable) if (value == null && !nullable)
value = getDefault() value = getDefault()

View File

@ -14,8 +14,8 @@ import pl.szczodrzynski.edziennik.data.db.entity.ConfigEntry
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
import pl.szczodrzynski.edziennik.data.enums.NotificationType import pl.szczodrzynski.edziennik.data.enums.NotificationType
import pl.szczodrzynski.edziennik.ui.home.HomeCardModel import pl.szczodrzynski.edziennik.ui.home.HomeCardModel
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.COLOR_MODE_WEIGHTED
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_ALL_GRADES
class ProfileConfig( class ProfileConfig(
app: App, app: App,

View File

@ -19,7 +19,7 @@ import pl.szczodrzynski.edziennik.data.enums.Theme.TEAL
import pl.szczodrzynski.edziennik.data.enums.Theme.Type.M3 import pl.szczodrzynski.edziennik.data.enums.Theme.Type.M3
import pl.szczodrzynski.edziennik.ext.toJsonArray import pl.szczodrzynski.edziennik.ext.toJsonArray
class ConfigMigration13 : BaseMigration<Config>() { class ConfigMigration14 : BaseMigration<Config>() {
override fun migrate(config: Config) = config.apply { override fun migrate(config: Config) = config.apply {
get("theme")?.toIntOrNull()?.let { get("theme")?.toIntOrNull()?.let {
@ -65,7 +65,7 @@ class ConfigMigration13 : BaseMigration<Config>() {
try { try {
ui.miniMenuButtons = it.map { id -> NavTarget.getById(id.asInt) }.toSet() ui.miniMenuButtons = it.map { id -> NavTarget.getById(id.asInt) }.toSet()
} catch (e: Exception) { } catch (e: Exception) {
ui.miniMenuButtons = NavTarget.getDefaultConfig() ui.miniMenuButtons = ui.miniMenuButtons
} }
} }
} }

View File

@ -29,7 +29,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
FeedbackMessage::class, FeedbackMessage::class,
Message::class, Message::class,
MessageRecipient::class, MessageRecipient::class,
DebugLog::class, LogEntry::class,
EndpointTimer::class, EndpointTimer::class,
LessonRange::class, LessonRange::class,
Notification::class, Notification::class,
@ -42,7 +42,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
TimetableManual::class, TimetableManual::class,
Note::class, Note::class,
Metadata::class Metadata::class
], version = 100) ], version = 101)
@TypeConverters( @TypeConverters(
ConverterTime::class, ConverterTime::class,
ConverterDate::class, ConverterDate::class,
@ -71,7 +71,7 @@ abstract class AppDb : RoomDatabase() {
abstract fun feedbackMessageDao(): FeedbackMessageDao abstract fun feedbackMessageDao(): FeedbackMessageDao
abstract fun messageDao(): MessageDao abstract fun messageDao(): MessageDao
abstract fun messageRecipientDao(): MessageRecipientDao abstract fun messageRecipientDao(): MessageRecipientDao
abstract fun debugLogDao(): DebugLogDao abstract fun logDao(): LogDao
abstract fun endpointTimerDao(): EndpointTimerDao abstract fun endpointTimerDao(): EndpointTimerDao
abstract fun lessonRangeDao(): LessonRangeDao abstract fun lessonRangeDao(): LessonRangeDao
abstract fun notificationDao(): NotificationDao abstract fun notificationDao(): NotificationDao
@ -187,6 +187,7 @@ abstract class AppDb : RoomDatabase() {
Migration98(), Migration98(),
Migration99(), Migration99(),
Migration100(), Migration100(),
Migration101(),
).allowMainThreadQueries().build() ).allowMainThreadQueries().build()
} }
} }

View File

@ -1,16 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao;
import androidx.room.Dao;
import androidx.room.Insert;
import pl.szczodrzynski.edziennik.data.db.entity.DebugLog;
@Dao
public interface DebugLogDao {
@Insert
void add(DebugLog debugLog);
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) Kuba Szczodrzyński 2024-7-1.
*/
package pl.szczodrzynski.edziennik.data.db.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import pl.szczodrzynski.edziennik.data.db.entity.LogEntry
@Dao
interface LogDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun add(entry: LogEntry)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun addAll(list: List<LogEntry>)
@Query("DELETE FROM logs")
suspend fun clear()
@Query("DELETE FROM logs WHERE timestamp < :timestamp")
suspend fun clearBefore(timestamp: Long)
}

View File

@ -1,23 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.entity;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import static pl.szczodrzynski.edziennik.utils.Utils.d;
@Entity(tableName = "debugLogs")
public class DebugLog {
@PrimaryKey(autoGenerate = true)
public int id;
public String text;
public DebugLog(String text) {
d("DebugLog", text);
this.text = text;
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) Kuba Szczodrzyński 2024-7-1.
*/
package pl.szczodrzynski.edziennik.data.db.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "logs")
data class LogEntry(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(index = true)
val timestamp: Long,
val priority: Int,
val tag: String?,
val message: String,
)

View File

@ -18,6 +18,7 @@ import pl.szczodrzynski.edziennik.data.enums.NotificationType
import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.ext.putExtras import pl.szczodrzynski.edziennik.ext.putExtras
import pl.szczodrzynski.edziennik.data.enums.NavTarget import pl.szczodrzynski.edziennik.data.enums.NavTarget
import timber.log.Timber
@Entity(tableName = "notifications") @Entity(tableName = "notifications")
data class Notification( data class Notification(
@ -74,8 +75,8 @@ data class Notification(
intent.putExtra(key, primitive.asString) intent.putExtra(key, primitive.asString)
} }
} }
} catch (e: NullPointerException) { } catch (e: Exception) {
e.printStackTrace() Timber.e(e)
} }
} }

Some files were not shown because too many files have changed in this diff Show More