Working config for WebDAV
This commit is contained in:
parent
83be0fa5fb
commit
308092415b
@ -14,10 +14,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.thegrizzlylabs.sardineandroid.impl.SardineException
|
||||
import it.danieleverducci.lunatracker.SettingsActivity
|
||||
import it.danieleverducci.lunatracker.adapters.LunaEventRecyclerAdapter
|
||||
import it.danieleverducci.lunatracker.entities.Logbook
|
||||
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||
import it.danieleverducci.lunatracker.entities.LunaEventType
|
||||
import it.danieleverducci.lunatracker.repository.FileLogbookRepository
|
||||
import it.danieleverducci.lunatracker.repository.LocalSettingsRepository
|
||||
import it.danieleverducci.lunatracker.repository.LogbookLoadedListener
|
||||
import it.danieleverducci.lunatracker.repository.LogbookRepository
|
||||
@ -42,7 +44,7 @@ class MainActivity : AppCompatActivity() {
|
||||
loadLogbook()
|
||||
handler.postDelayed(updateListRunnable, 1000*60)
|
||||
}
|
||||
lateinit var logbookRepo: LogbookRepository
|
||||
var logbookRepo: LogbookRepository? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -52,11 +54,6 @@ class MainActivity : AppCompatActivity() {
|
||||
if (webDavCredentials == null) {
|
||||
TODO("Not supported ATM (TODO: apply settings)")
|
||||
}
|
||||
logbookRepo = WebDAVLogbookRepository( // TODO: support also FileLogbookRepository
|
||||
webDavCredentials[0],
|
||||
webDavCredentials[1],
|
||||
webDavCredentials[2]
|
||||
)
|
||||
|
||||
handler = Handler(mainLooper)
|
||||
adapter = LunaEventRecyclerAdapter(this)
|
||||
@ -114,7 +111,6 @@ class MainActivity : AppCompatActivity() {
|
||||
fun showSettings() {
|
||||
val i = Intent(this, SettingsActivity::class.java)
|
||||
startActivity(i)
|
||||
|
||||
}
|
||||
|
||||
fun showLogbook() {
|
||||
@ -127,6 +123,21 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
val settingsRepository = LocalSettingsRepository(this)
|
||||
if (settingsRepository.loadDataRepository() == LocalSettingsRepository.DATA_REPO.WEBDAV) {
|
||||
val webDavCredentials = settingsRepository.loadWebdavCredentials()
|
||||
if (webDavCredentials == null) {
|
||||
throw IllegalStateException("Corrupted local settings: repo is webdav, but no webdav login data saved")
|
||||
}
|
||||
logbookRepo = WebDAVLogbookRepository(
|
||||
webDavCredentials[0],
|
||||
webDavCredentials[1],
|
||||
webDavCredentials[2]
|
||||
)
|
||||
} else {
|
||||
logbookRepo = FileLogbookRepository()
|
||||
}
|
||||
|
||||
// Update list dates
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
@ -190,7 +201,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
// Load data
|
||||
progressIndicator.visibility = View.VISIBLE
|
||||
logbookRepo.loadLogbook(this, object: LogbookLoadedListener{
|
||||
logbookRepo?.loadLogbook(this, object: LogbookLoadedListener{
|
||||
override fun onLogbookLoaded(lb: Logbook) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
@ -201,16 +212,37 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
override fun onIOError(error: IOException) {
|
||||
onRepoError(error) // TODO: Meaningful message
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_network_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onWebDAVError(error: SardineException) {
|
||||
onRepoError(error) // TODO: Meaningful message
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
if(error.toString().contains("401")) {
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_webdav_error_denied), Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_webdav_error_generic) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onJSONError(error: JSONException) {
|
||||
onRepoError(error) // TODO: Meaningful message
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_json_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onError(error: Exception) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_generic_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -233,7 +265,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
progressIndicator.visibility = View.VISIBLE
|
||||
logbook.logs.add(0, event)
|
||||
logbookRepo.saveLogbook(this, logbook, object: LogbookSavedListener{
|
||||
logbookRepo?.saveLogbook(this, logbook, object: LogbookSavedListener{
|
||||
override fun onLogbookSaved() {
|
||||
Log.d(TAG, "Logbook saved")
|
||||
runOnUiThread({
|
||||
@ -244,8 +276,47 @@ class MainActivity : AppCompatActivity() {
|
||||
})
|
||||
}
|
||||
|
||||
override fun onError(error: String) {
|
||||
Log.e(TAG, "ERROR: Logbook was NOT saved!")
|
||||
override fun onIOError(error: IOException) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_network_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
onAddError(event, error.toString())
|
||||
})
|
||||
}
|
||||
|
||||
override fun onWebDAVError(error: SardineException) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
if(error.toString().contains("401")) {
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_webdav_error_denied), Toast.LENGTH_SHORT).show()
|
||||
onAddError(event, error.toString())
|
||||
} else {
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_webdav_error_generic) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
onAddError(event, error.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onJSONError(error: JSONException) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_json_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
onAddError(event, error.toString())
|
||||
})
|
||||
}
|
||||
|
||||
override fun onError(error: Exception) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@MainActivity, getString(R.string.settings_generic_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
onAddError(event, error.toString())
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun onAddError(event: LunaEvent, error: String) {
|
||||
Log.e(TAG, "Logbook was NOT saved!")
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
|
||||
@ -256,7 +327,4 @@ class MainActivity : AppCompatActivity() {
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package it.danieleverducci.lunatracker
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.PersistableBundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.RadioButton
|
||||
import android.widget.TextView
|
||||
@ -10,15 +8,12 @@ import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.thegrizzlylabs.sardineandroid.impl.SardineException
|
||||
import it.danieleverducci.lunatracker.entities.Logbook
|
||||
import it.danieleverducci.lunatracker.repository.FileLogbookRepository
|
||||
import it.danieleverducci.lunatracker.repository.LocalSettingsRepository
|
||||
import it.danieleverducci.lunatracker.repository.LogbookLoadedListener
|
||||
import it.danieleverducci.lunatracker.repository.WebDAVLogbookRepository
|
||||
import okio.IOException
|
||||
import org.json.JSONException
|
||||
|
||||
class SettingsActivity : AppCompatActivity() {
|
||||
open class SettingsActivity : AppCompatActivity() {
|
||||
protected lateinit var settingsRepository: LocalSettingsRepository
|
||||
protected lateinit var radioDataLocal: RadioButton
|
||||
protected lateinit var radioDataWebDAV: RadioButton
|
||||
@ -71,75 +66,53 @@ class SettingsActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
// Try to connect to WebDAV and check if the save file already exists
|
||||
val logbookRepo = WebDAVLogbookRepository(
|
||||
val webDAVLogbookRepo = WebDAVLogbookRepository(
|
||||
textViewWebDAVUrl.text.toString(),
|
||||
textViewWebDAVUser.text.toString(),
|
||||
textViewWebDAVPass.text.toString()
|
||||
)
|
||||
progressIndicator.visibility = View.VISIBLE
|
||||
logbookRepo.loadLogbook(this, object: LogbookLoadedListener {
|
||||
override fun onLogbookLoaded(logbook: Logbook) {
|
||||
webDAVLogbookRepo.createLogbook(this, object: WebDAVLogbookRepository.LogbookCreatedListener{
|
||||
override fun onLogbookCreated() {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
// Save file does exist. Settings valid. Save.
|
||||
saveSettings()
|
||||
Toast.makeText(this@SettingsActivity, R.string.settings_webdav_creation_ok, Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onIOError(error: IOException) {
|
||||
// Unable to reach network
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@SettingsActivity, getString(R.string.settings_network_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onWebDAVError(error: SardineException) {
|
||||
// Save file does not exist, upload the local one
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
if (error.toString().contains("401")) {
|
||||
if(error.toString().contains("401")) {
|
||||
Toast.makeText(this@SettingsActivity, getString(R.string.settings_webdav_error_denied), Toast.LENGTH_SHORT).show()
|
||||
} else if (error.toString().contains("404")) {
|
||||
// Connection successful, but no existing save. Upload the local one.
|
||||
val fileLogbookRepo = FileLogbookRepository()
|
||||
fileLogbookRepo.loadLogbook(this@SettingsActivity, object: LogbookLoadedListener {
|
||||
override fun onLogbookLoaded(logbook: Logbook) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onIOError(error: IOException) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onWebDAVError(error: SardineException) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onJSONError(error: JSONException) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onError(error: Exception) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
Toast.makeText(this@SettingsActivity, getString(R.string.settings_webdav_error_generic) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onJSONError(error: JSONException) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
// Save file exists, but is corrupted
|
||||
Toast.makeText(this@SettingsActivity, getString(R.string.settings_json_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onError(error: Exception) {
|
||||
runOnUiThread({
|
||||
progressIndicator.visibility = View.INVISIBLE
|
||||
Toast.makeText(this@SettingsActivity, getString(R.string.settings_generic_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,17 @@ class FileLogbookRepository: LogbookRepository {
|
||||
}
|
||||
|
||||
override fun loadLogbook(context: Context, listener: LogbookLoadedListener) {
|
||||
try {
|
||||
listener.onLogbookLoaded(loadLogbook(context))
|
||||
} catch (e: FileNotFoundException) {
|
||||
Log.d(TAG, "No logbook file found")
|
||||
listener.onIOError(e)
|
||||
}
|
||||
}
|
||||
|
||||
fun loadLogbook(context: Context): Logbook {
|
||||
val logbook = Logbook()
|
||||
val file = File(context.getFilesDir(), "data.json")
|
||||
try {
|
||||
val json = FileInputStream(file).bufferedReader().use { it.readText() }
|
||||
val ja = JSONArray(json)
|
||||
for (i in 0 until ja.length()) {
|
||||
@ -25,11 +33,7 @@ class FileLogbookRepository: LogbookRepository {
|
||||
val evt = LunaEvent.fromJson(jo)
|
||||
logbook.logs.add(evt)
|
||||
}
|
||||
} catch (e: FileNotFoundException) {
|
||||
Log.d(TAG, "No logbook file found")
|
||||
listener.onIOError(e)
|
||||
}
|
||||
listener.onLogbookLoaded(logbook)
|
||||
return logbook
|
||||
}
|
||||
|
||||
override fun saveLogbook(
|
||||
|
@ -8,7 +8,7 @@ class LocalSettingsRepository(val context: Context) {
|
||||
companion object {
|
||||
val SHARED_PREFS_FILE_NAME = "lunasettings"
|
||||
val SHARED_PREFS_BB_CONTENT = "bbcontent"
|
||||
val SHARED_PREFS_DATA_REPO = "webdav_url"
|
||||
val SHARED_PREFS_DATA_REPO = "data_repo"
|
||||
val SHARED_PREFS_DAV_URL = "webdav_url"
|
||||
val SHARED_PREFS_DAV_USER = "webdav_user"
|
||||
val SHARED_PREFS_DAV_PASS = "webdav_password"
|
||||
|
@ -21,5 +21,8 @@ interface LogbookLoadedListener {
|
||||
|
||||
interface LogbookSavedListener {
|
||||
fun onLogbookSaved()
|
||||
fun onError(error: String)
|
||||
fun onIOError(error: IOException)
|
||||
fun onWebDAVError(error: SardineException)
|
||||
fun onJSONError(error: JSONException)
|
||||
fun onError(error: Exception)
|
||||
}
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.Runnable
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.net.SocketTimeoutException
|
||||
import kotlin.io.bufferedReader
|
||||
@ -31,16 +32,7 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
||||
override fun loadLogbook(context: Context, listener: LogbookLoadedListener) {
|
||||
Thread(Runnable {
|
||||
try {
|
||||
val inputStream = sardine.get("$webDavURL/$FILE_NAME")
|
||||
val json = inputStream.bufferedReader().use(BufferedReader::readText)
|
||||
inputStream.close()
|
||||
val ja = JSONArray(json)
|
||||
val logbook = Logbook()
|
||||
for (i in 0 until ja.length()) {
|
||||
val jo = ja.getJSONObject(i)
|
||||
val evt = LunaEvent.fromJson(jo)
|
||||
logbook.logs.add(evt)
|
||||
}
|
||||
val logbook = loadLogbook(context)
|
||||
listener.onLogbookLoaded(logbook)
|
||||
} catch (e: SardineException) {
|
||||
Log.e(TAG, e.toString())
|
||||
@ -60,8 +52,45 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun loadLogbook(context: Context): Logbook {
|
||||
val inputStream = sardine.get("$webDavURL/$FILE_NAME")
|
||||
val json = inputStream.bufferedReader().use(BufferedReader::readText)
|
||||
inputStream.close()
|
||||
val ja = JSONArray(json)
|
||||
val logbook = Logbook()
|
||||
for (i in 0 until ja.length()) {
|
||||
val jo = ja.getJSONObject(i)
|
||||
val evt = LunaEvent.fromJson(jo)
|
||||
logbook.logs.add(evt)
|
||||
}
|
||||
return logbook
|
||||
}
|
||||
|
||||
override fun saveLogbook(context: Context, logbook: Logbook, listener: LogbookSavedListener) {
|
||||
Thread(Runnable {
|
||||
try {
|
||||
saveLogbook(context, logbook)
|
||||
listener.onLogbookSaved()
|
||||
} catch (e: SardineException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onWebDAVError(e)
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onIOError(e)
|
||||
} catch (e: SocketTimeoutException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onIOError(e)
|
||||
} catch (e: JSONException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onJSONError(e)
|
||||
} catch (e: Exception) {
|
||||
listener.onError(e)
|
||||
}
|
||||
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun saveLogbook(context: Context, logbook: Logbook) {
|
||||
// Lock logbook on WebDAV to avoid concurrent changes
|
||||
//sardine.lock(getUrl())
|
||||
// Reload logbook from WebDAV
|
||||
@ -74,17 +103,64 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
||||
for (l in logbook.logs) {
|
||||
ja.put(l.toJson())
|
||||
}
|
||||
try {
|
||||
sardine.put(getUrl(), ja.toString().toByteArray())
|
||||
listener.onLogbookSaved()
|
||||
} catch (e: SardineException) {
|
||||
listener.onError(e.toString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to server and check if a logbook already exists.
|
||||
* If it does not exist, try to upload the local one (or create a new one).
|
||||
*/
|
||||
fun createLogbook(context: Context, listener: LogbookCreatedListener) {
|
||||
Thread(Runnable {
|
||||
try {
|
||||
loadLogbook(context)
|
||||
listener.onLogbookCreated()
|
||||
} catch (e: SardineException) {
|
||||
if (e.toString().contains("404")) {
|
||||
// Connection successful, but no existing save. Upload the local one.
|
||||
try {
|
||||
val flr = FileLogbookRepository()
|
||||
val logbook = flr.loadLogbook(context)
|
||||
saveLogbook(context, logbook)
|
||||
Log.d(TAG, "Local logbook file found, uploaded")
|
||||
listener.onLogbookCreated()
|
||||
} catch (e: FileNotFoundException) {
|
||||
Log.d(TAG, "No local logbook file found, uploading empty file")
|
||||
saveLogbook(context, Logbook())
|
||||
listener.onLogbookCreated()
|
||||
} catch (e: SardineException) {
|
||||
Log.e(TAG, "Unable to upload logbook: $e")
|
||||
listener.onWebDAVError(e)
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onWebDAVError(e)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onIOError(e)
|
||||
} catch (e: SocketTimeoutException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onIOError(e)
|
||||
} catch (e: JSONException) {
|
||||
Log.e(TAG, e.toString())
|
||||
listener.onJSONError(e)
|
||||
} catch (e: Exception) {
|
||||
listener.onError(e)
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun getUrl(): String {
|
||||
return "$webDavURL/$FILE_NAME"
|
||||
}
|
||||
|
||||
|
||||
interface LogbookCreatedListener {
|
||||
fun onLogbookCreated()
|
||||
fun onIOError(error: okio.IOException)
|
||||
fun onWebDAVError(error: SardineException)
|
||||
fun onJSONError(error: JSONException)
|
||||
fun onError(error: Exception)
|
||||
}
|
||||
}
|
@ -54,8 +54,10 @@
|
||||
<string name="settings_storage_dav_user">Username</string>
|
||||
<string name="settings_storage_dav_pass">Password</string>
|
||||
<string name="settings_network_error">Impossibile raggiungere il server: </string>
|
||||
<string name="settings_webdav_error_denied">Nome utente o password sbagliati</string>
|
||||
<string name="settings_webdav_error_denied">Nome utente o password WebDAV sbagliati</string>
|
||||
<string name="settings_webdav_error_generic">Si è verificato un errore tentando di accedere al server WebDAV:</string>
|
||||
<string name="settings_webdav_creation_error_generic">Impossibile creare un file di salvataggio sul server WebDAV:</string>
|
||||
<string name="settings_webdav_creation_ok">Connessione al server WebDAV avvenuta con successo</string>
|
||||
<string name="settings_json_error">Sul server esiste un salvataggio, ma è corrotto o illeggibile. Cancellare il file </string>
|
||||
<string name="settings_generic_error">Si è verificato un errore: </string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user