Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/src/main/java/com/philkes/notallyx/data/dao/CommonDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ abstract class CommonDao(private val database: NotallyDatabase) {
baseNotes: List<BaseNote>,
labels: List<Label>,
readCorrupted: Int,
checkDuplicates: Boolean,
): ImportResult {
val dao = database.getBaseNoteDao()
// Insert notes, splitting oversized text notes instead of truncating
var insertedCount = 0
var duplicates = 0
baseNotes.forEach { note ->
// Skip duplicates: same title and same content
val duplicateId = findDuplicateId(note)
val duplicateId = if (checkDuplicates) findDuplicateId(note) else null
if (duplicateId == null) {
if (note.type == Type.NOTE && note.body.length > MAX_BODY_CHAR_LENGTH) {
NoteSplitUtils.splitAndInsertForImport(note, dao)
Expand Down Expand Up @@ -93,6 +94,7 @@ abstract class CommonDao(private val database: NotallyDatabase) {
originalIds: List<Long>,
labels: List<Label>,
readCorrupted: Int,
checkDuplicates: Boolean,
): ImportResult {
val baseNoteDao = database.getBaseNoteDao()

Expand All @@ -105,7 +107,7 @@ abstract class CommonDao(private val database: NotallyDatabase) {
var duplicates = 0
for (i in baseNotes.indices) {
val original = baseNotes[i]
val duplicateId = findDuplicateId(original)
val duplicateId = if (checkDuplicates) findDuplicateId(original) else null
if (duplicateId != null) {
// Map the old id to the existing duplicate and do not insert
val oldId = originalIds.getOrNull(i)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import com.philkes.notallyx.data.imports.FOLDER_OR_FILE_MIMETYPE
import com.philkes.notallyx.data.imports.ImportProgress
import com.philkes.notallyx.data.imports.ImportSource
import com.philkes.notallyx.data.imports.txt.APPLICATION_TEXT_MIME_TYPES
import com.philkes.notallyx.databinding.DialogTextInputBinding
import com.philkes.notallyx.databinding.DialogImportBinding
import com.philkes.notallyx.databinding.FragmentSettingsBinding
import com.philkes.notallyx.presentation.activity.main.MainActivity
import com.philkes.notallyx.presentation.format
Expand Down Expand Up @@ -150,7 +150,7 @@ class SettingsFragment : Fragment() {
importRawDatabaseActivityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
result.data?.data?.let { model.importRawDatabase(it) }
result.data?.data?.let { model.importRawDatabase(it, false) }
}
Comment thread
Crustack marked this conversation as resolved.
}
importOtherActivityResultLauncher =
Expand Down Expand Up @@ -247,7 +247,7 @@ class SettingsFragment : Fragment() {
}

MIME_TYPE_ZIP -> {
val layout = DialogTextInputBinding.inflate(layoutInflater, null, false)
val layout = DialogImportBinding.inflate(layoutInflater, null, false)
val password = model.preferences.backupPassword.value
layout.InputText.apply {
if (password != PASSWORD_EMPTY) {
Expand All @@ -266,7 +266,8 @@ class SettingsFragment : Fragment() {
.setPositiveButton(R.string.import_backup) { dialog, _ ->
dialog.cancel()
val usedPassword = layout.InputText.text.toString()
model.importZipBackup(uri, usedPassword)
val checkDuplicates = layout.CheckDuplicates.isChecked
model.importZipBackup(uri, usedPassword, checkDuplicates)
}
.setCancelButton()
.show()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,28 +411,30 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) {
}
}

fun importRawDatabase(uri: Uri) {
fun importRawDatabase(uri: Uri, checkDuplicates: Boolean) {
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
app.log(TAG, throwable = throwable)
app.showToast("${app.getString(R.string.invalid_backup)}: ${throwable.message}")
}

viewModelScope.launch(exceptionHandler) {
val importResult =
withContext(Dispatchers.IO) { app.importRawDatabase(uri, importProgress) }
withContext(Dispatchers.IO) {
app.importRawDatabase(uri, checkDuplicates, importProgress)
}
app.showToast(app.toMessage(importResult))
}
}

fun importZipBackup(uri: Uri, password: String) {
fun importZipBackup(uri: Uri, password: String, checkDuplicates: Boolean) {
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
app.log(TAG, throwable = throwable)
app.showToast("${app.getString(R.string.invalid_backup)}: ${throwable.message}")
}

val backupDir = app.getBackupDir()
viewModelScope.launch(exceptionHandler) {
app.importZip(uri, backupDir, password, importProgress)
app.importZip(uri, backupDir, password, checkDuplicates, importProgress)
}
}

Expand All @@ -451,7 +453,7 @@ class BaseNoteModel(private val app: Application) : AndroidViewModel(app) {
{ "InputStream for '$uri' is null" },
)
val (baseNotes, labels) = stream.readAsBackup()
commonDao.importBackup(baseNotes, labels, 0)
commonDao.importBackup(baseNotes, labels, 0, false)
}
Comment thread
Crustack marked this conversation as resolved.
app.showToast(app.toMessage(result))
}
Expand Down
14 changes: 12 additions & 2 deletions app/src/main/java/com/philkes/notallyx/utils/ErrorActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.philkes.notallyx.utils.backup.copyDatabase
import com.philkes.notallyx.utils.backup.exportAsZip
import com.philkes.notallyx.utils.backup.exportRawDatabase
import com.philkes.notallyx.utils.backup.importRawDatabase
import java.io.File
import java.util.Date
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -199,15 +200,24 @@ class ErrorActivity : AppCompatActivity() {
lifecycleScope.launch(exceptionHandler) {
val importResult =
withContext(Dispatchers.IO) {
// Safety copy of internal database
val (_, databaseCopy) =
copyDatabase(suffix = "_BEFORE_REIMPORT")
copyDatabase(
suffix = "_BACKUP_BEFORE_REIMPORT"
)
databaseCopy.copyToLarge(
File(
getLogsDir(),
"${NotallyDatabase.DATABASE_NAME}_BACKUP_BEFORE_REIMPORT.sqlite",
),
overwrite = true,
)
deleteDatabase(NotallyDatabase.DATABASE_NAME)
NotallyDatabase.clearInstance(
this@ErrorActivity
)
application.importRawDatabase(
uri,
false,
Comment thread
Crustack marked this conversation as resolved.
backupProgress,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ fun getOptionalColumns(db: SQLiteDatabase, tableName: String): Array<String> {

suspend fun ContextWrapper.importRawDatabase(
dbFileUri: Uri,
checkDuplicates: Boolean,
importProgress: MutableLiveData<Progress>? = null,
): ImportResult {
val tempDbFile = File(cacheDir, DATABASE_NAME + "_IMPORT")
Expand All @@ -107,7 +108,7 @@ suspend fun ContextWrapper.importRawDatabase(
inputStream.copyToFile(tempDbFile)
val (baseNotes, originalIds, labels, corruptedNotes) =
readBaseNotes(tempDbFile, importProgress)
val import = import(baseNotes, originalIds, labels, corruptedNotes)
val import = import(baseNotes, originalIds, labels, corruptedNotes, checkDuplicates)
importProgress?.postValue(ImportProgress(inProgress = false))
return import
}
Expand Down Expand Up @@ -162,6 +163,7 @@ suspend fun ContextWrapper.importZip(
zipFileUri: Uri,
databaseFolder: File,
zipPassword: String,
checkDuplicates: Boolean,
progress: MutableLiveData<Progress>? = null,
) {
progress?.postValue(ImportProgress(indeterminate = true))
Expand Down Expand Up @@ -263,7 +265,7 @@ suspend fun ContextWrapper.importZip(
}
}
}
import(baseNotes, originalIds, labels, corruptedNotes)
import(baseNotes, originalIds, labels, corruptedNotes, checkDuplicates)
}
databaseFolder.clearDirectory()
showToast(toMessage(result))
Expand All @@ -284,10 +286,13 @@ private suspend fun ContextWrapper.import(
originalIds: List<Long>,
labels: List<Label>,
readCorrupted: Int,
checkDuplicates: Boolean,
): ImportResult {
val notallyDatabase = NotallyDatabase.getDatabase(this, observePreferences = false).value
val importResult =
notallyDatabase.getCommonDao().importBackup(baseNotes, originalIds, labels, readCorrupted)
notallyDatabase
.getCommonDao()
.importBackup(baseNotes, originalIds, labels, readCorrupted, checkDuplicates)
val notesToRemind = notallyDatabase.getBaseNoteDao().getAllWithRemindersOrPinned()
cancelPinAndReminders(notesToRemind)
pinAndScheduleReminders(notesToRemind)
Expand Down
47 changes: 47 additions & 0 deletions app/src/main/res/layout/dialog_import.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:orientation="vertical">

<TextView
android:id="@+id/Message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:visibility="gone" />

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/InputTextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense"
>

<EditText
android:id="@+id/InputText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingBottom="8dp"
android:maxLines="1"
android:layout_gravity="center_horizontal"
android:singleLine="true"
android:scrollHorizontally="true"
android:textSize="16sp"
android:contentDescription="Input"/>

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/CheckDuplicates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/check_duplicates"
android:checked="true"
/>

</LinearLayout>
3 changes: 2 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<string name="change_color_message">Pick a color or create a new one.\nYou can also edit a Color by long pressing it.</string>
<string name="change_note">Change Note</string>
<string name="check_all_items">Check all items</string>
<string name="check_duplicates">Check for duplicates</string>
<string name="choose_another_folder">Choose another folder</string>
<string name="choose_folder">Choose folder</string>
<string name="choose_other_app">Choose which app to import from</string>
Expand Down Expand Up @@ -323,7 +324,7 @@
<string name="redo">Redo</string>
<string name="reimport_database">Reimport DB</string>
<string name="reimport_database_failed">Reimporting Database failed</string>
<string name="reimport_database_message">You can now try to reimport a raw database. This deletes the current corrupted database and then tries to import the raw database by skipping corrupted notes if possible</string>
<string name="reimport_database_message">You can now try to reimport the raw database. This deletes the current corrupted database (a backup will be stored in \'Android/media/com.philkes.notallyx/logs\') and then tries to import the raw database by skipping corrupted notes if possible</string>
<string name="reminder_no_repetition">No repetition</string>
<string name="reminders">Reminders</string>
<string name="remove_link">Remove Link</string>
Expand Down
Binary file modified app/translations.xlsx
Binary file not shown.