Skip to content

Commit

Permalink
Merge pull request #182 from marc31/add_download_file
Browse files Browse the repository at this point in the history
download file from snapshot
  • Loading branch information
lhns authored Aug 14, 2023
2 parents 5124493 + f419878 commit 90e92fe
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 3 deletions.
21 changes: 21 additions & 0 deletions app/src/main/java/de/lolhens/resticui/restic/ResticRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,25 @@ abstract class ResticRepo(
format.decodeFromString<ResticBackupSummary>(json)
}
}

fun restore(
snapshotId: ResticSnapshotId,
downloadPath: File,
file: ResticFile,
): CompletableFuture<String> {

val args = listOf(
"--json",
"restore",
"${snapshotId.id}:${file.path.parent}",
"--target",
downloadPath.path.toString(),
"--include",
file.path.name
)

return restic(args).thenApply { (out, _) ->
out.joinToString("\n")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import androidx.fragment.app.Fragment
import de.lolhens.resticui.BackupManager
import de.lolhens.resticui.databinding.FragmentSettingsBinding
import de.lolhens.resticui.ui.InputDialogUtil
import de.lolhens.resticui.util.DirectoryChooser
import de.lolhens.resticui.util.HostnameUtil
import android.content.Context

class SettingsFragment : Fragment() {
private var _binding: FragmentSettingsBinding? = null
Expand Down Expand Up @@ -55,6 +57,24 @@ class SettingsFragment : Fragment() {
}
}

val context = requireContext()
val sharedPref = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)

binding.textDl.text = sharedPref?.getString("dl_path", "") ?: ""

val directoryChooser = DirectoryChooser.newInstance()

directoryChooser.register(this, requireContext()) { path ->
val editor = sharedPref?.edit()
editor?.putString("dl_path", path)
editor?.apply()
binding.textDl.text = path
}

binding.buttonDlEdit.setOnClickListener {
directoryChooser.openDialog()
}

val restic = BackupManager.instance(requireContext()).restic

binding.buttonHostnameEdit.setOnClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ package de.lolhens.resticui.ui.snapshot
import android.app.AlertDialog
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.view.*
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.AdapterView
import android.widget.BaseAdapter
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import de.lolhens.resticui.BackupManager
import de.lolhens.resticui.R
import de.lolhens.resticui.config.RepoConfigId
import de.lolhens.resticui.databinding.FragmentSnapshotBinding
import de.lolhens.resticui.restic.ResticFile
import de.lolhens.resticui.restic.ResticRepo
import de.lolhens.resticui.restic.ResticSnapshotId
import de.lolhens.resticui.ui.Formatters
import java.io.File
Expand Down Expand Up @@ -89,7 +93,10 @@ class SnapshotFragment : Fragment() {
it.path.relativeTo(snapshotRootPath).path.isNotEmpty()
}
),
snapshotRootPath
resticRepo,
snapshotId,
snapshotRootPath,
binding.progressDl
)

binding.listFilesSnapshot.onItemClickListener =
Expand Down Expand Up @@ -161,7 +168,10 @@ class SnapshotFragment : Fragment() {
class SnapshotFilesListAdapter(
private val context: Context,
private val files: ArrayList<ResticFile>,
private val rootPath: File
private val resticRepo: ResticRepo,
private val snapshotId: ResticSnapshotId,
private val rootPath: File,
private val progressDl: ProgressBar
) : BaseAdapter() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val pathNameText: TextView = view.findViewById(R.id.pathname)
Expand Down Expand Up @@ -218,6 +228,60 @@ class SnapshotFilesListAdapter(
holder.pathNameText.text = pathString
holder.fileDateText.text = dateString

// Add a click listener to initiate download
holder.itemView.setOnClickListener {
if (file.type == "file") {
// Path where the downloaded file will be saved on the device
val sharedPref = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
val downloadPathString = sharedPref?.getString("dl_path", "") ?: ""
val downloadPath = File(downloadPathString)

if (!(downloadPath.exists() && downloadPath.isDirectory)) {
AlertDialog.Builder(context)
.setTitle(R.string.alert_download_file_title)
.setMessage(R.string.alert_download_file_no_dest_dir)
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else {
AlertDialog.Builder(context)
.setTitle(R.string.alert_download_file_title)
.setMessage(context.getString(R.string.alert_download_file_message, file.path.name, downloadPathString))
.setPositiveButton(android.R.string.ok) { _, _ ->
downloadFile(file, downloadPath)
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
}
}
}

return view
}

// Function to handle file download
private fun downloadFile(file: ResticFile, downloadPath: File) {
progressDl.visibility = VISIBLE
resticRepo.restore(snapshotId, downloadPath, file)
.handle { content, throwable ->
val handler = Handler(context.mainLooper)
handler.post {
if (content != null) {
// Notify the user that the download is complete
// You can use a Toast or other UI element to display this message
showToast("File downloaded")
} else {
throwable?.printStackTrace()

// Notify the user that an error occurred during download
showToast("Failed to download")
}
progressDl.visibility = GONE
}
}
}

private fun showToast(message: String) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}

}
47 changes: 46 additions & 1 deletion app/src/main/res/layout/fragment_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,51 @@

</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/group_dl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/group_dns">

<TextView
android:id="@+id/text_dl_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="Donwload Directory"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/text_dl"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="8dp"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="@+id/button_dl_edit"
app:layout_constraintEnd_toStartOf="@+id/button_dl_edit"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_dl_description" />

<Button
android:id="@+id/button_dl_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:text="Edit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_dl_description" />

</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/group_utils"
android:layout_width="match_parent"
Expand All @@ -111,7 +156,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/group_dns">
app:layout_constraintTop_toBottomOf="@+id/group_dl">

<TextView
android:id="@+id/text_utils_description"
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/res/layout/fragment_snapshot.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progress_snapshot" />

<ProgressBar
android:id="@+id/progress_dl"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progress_snapshot" />

<TextView
android:id="@+id/text_snapshot_id_long"
android:layout_width="0dp"
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
<string name="alert_backup_cancel_message">Do you want to cancel the Backup?</string>
<string name="alert_delete_snapshot_title">Delete Snapshot</string>
<string name="alert_delete_snapshot_message">Do you want to delete this Snapshot?</string>
<string name="alert_download_file_title">Download File</string>
<string name="alert_download_file_message">
Do you want to download this file: "%s"
here: "%s" ?
</string>
<string name="alert_download_file_no_dest_dir">Before proceeding, ensure that you have chosen a valid download folder in the settings.</string>
<string name="notification_channel_backup">Restic Backup</string>
<string name="notification_backup_title">Restic Backup</string>
<string name="notification_backup_progress_message">Backup in Progress…</string>
Expand Down

0 comments on commit 90e92fe

Please sign in to comment.