Skip to content

Commit

Permalink
- allow choosing deps.list.txt from device storage
Browse files Browse the repository at this point in the history
  • Loading branch information
lmj0011 committed Jul 3, 2020
1 parent b5d3bc8 commit d2ce859
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 85 deletions.
4 changes: 2 additions & 2 deletions app/deps.list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ androidx.appcompat:appcompat:1.1.0
androidx.core:core-ktx:1.3.0
com.google.android.material:material:1.1.0
androidx.constraintlayout:constraintlayout:1.1.3
androidx.navigation:navigation-fragment:2.2.2
androidx.navigation:navigation-fragment-ktx:2.2.2
androidx.navigation:navigation-fragment:2.3.0
androidx.navigation:navigation-fragment-ktx:2.3.0
androidx.navigation:navigation-ui:2.3.0
androidx.navigation:navigation-ui-ktx:2.3.0
androidx.swiperefreshlayout:swiperefreshlayout:1.1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package name.lmj0011.jetpackreleasetracker.helpers

object Const {
const val PICK_DEPS_LIST_TXT = 3000
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
package name.lmj0011.jetpackreleasetracker.ui.projectsyncs

import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.appcompat.widget.SearchView
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
import br.com.simplepass.loadingbutton.presentation.State
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.*
import name.lmj0011.jetpackreleasetracker.MainActivity
import name.lmj0011.jetpackreleasetracker.R
import name.lmj0011.jetpackreleasetracker.database.AppDatabase
import name.lmj0011.jetpackreleasetracker.database.ProjectSync
import name.lmj0011.jetpackreleasetracker.databinding.FragmentCreateProjectSyncBinding
import name.lmj0011.jetpackreleasetracker.databinding.FragmentProjectSyncsBinding
import name.lmj0011.jetpackreleasetracker.helpers.Util
import name.lmj0011.jetpackreleasetracker.helpers.adapters.ProjectSyncListAdapter
import name.lmj0011.jetpackreleasetracker.helpers.Const
import name.lmj0011.jetpackreleasetracker.helpers.factories.ProjectSyncViewModelFactory
import name.lmj0011.jetpackreleasetracker.helpers.interfaces.SearchableRecyclerView
import timber.log.Timber

class CreateProjectSyncFragment : Fragment()
{
Expand Down Expand Up @@ -67,6 +60,8 @@ class CreateProjectSyncFragment : Fragment()
}
})

binding.pickDepsListTxtImageButton.setOnClickListener { openDepsTxtFile() }

mainActivity.hideFab()

return binding.root
Expand All @@ -88,6 +83,19 @@ class CreateProjectSyncFragment : Fragment()
return super.onOptionsItemSelected(item)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (requestCode == Const.PICK_DEPS_LIST_TXT) {
// The result data contains a URI for the document or directory that
// the user selected.
data?.data?.let {
binding.depsUrlEditText.setText(it.toString())
}
}

}

private fun saveButtonOnClickListener(v: View) {
var projectName = binding.projectNameEditText.text.toString()
var projectDepListUrl = binding.depsUrlEditText.text.toString()
Expand All @@ -101,4 +109,13 @@ class CreateProjectSyncFragment : Fragment()
binding.createProjectSyncCircularProgressButton.startAnimation()

}

private fun openDepsTxtFile() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/plain"
}

startActivityForResult(intent, Const.PICK_DEPS_LIST_TXT)
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,27 @@
package name.lmj0011.jetpackreleasetracker.ui.projectsyncs

import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.view.*
import android.widget.TextView
import androidx.appcompat.widget.SearchView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
import br.com.simplepass.loadingbutton.presentation.State
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.*
import name.lmj0011.jetpackreleasetracker.MainActivity
import name.lmj0011.jetpackreleasetracker.R
import name.lmj0011.jetpackreleasetracker.database.AppDatabase
import name.lmj0011.jetpackreleasetracker.database.ProjectSync
import name.lmj0011.jetpackreleasetracker.databinding.FragmentCreateProjectSyncBinding
import name.lmj0011.jetpackreleasetracker.databinding.FragmentEditProjectSyncBinding
import name.lmj0011.jetpackreleasetracker.databinding.FragmentProjectSyncsBinding
import name.lmj0011.jetpackreleasetracker.helpers.Util
import name.lmj0011.jetpackreleasetracker.helpers.adapters.ProjectSyncListAdapter
import name.lmj0011.jetpackreleasetracker.helpers.Const
import name.lmj0011.jetpackreleasetracker.helpers.factories.ProjectSyncViewModelFactory
import name.lmj0011.jetpackreleasetracker.helpers.interfaces.SearchableRecyclerView
import timber.log.Timber

class EditProjectSyncFragment : Fragment()
{
Expand Down Expand Up @@ -111,6 +102,8 @@ class EditProjectSyncFragment : Fragment()

projectSyncsViewModel.setProjectSync(requireArguments().getLong(getString(R.string.key_project_sync_id_bundle_property)))

binding.pickDepsListTxtImageButton.setOnClickListener { openDepsTxtFile() }

mainActivity.hideFab()

return binding.root
Expand Down Expand Up @@ -152,6 +145,19 @@ class EditProjectSyncFragment : Fragment()
c.applyTo(parentLayout)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (requestCode == Const.PICK_DEPS_LIST_TXT) {
// The result data contains a URI for the document or directory that
// the user selected.
data?.data?.let {
binding.depsUrlEditText.setText(it.toString())
}
}

}

private fun saveButtonOnClickListener(v: View? = null) {
project?.let {
it.name = binding.projectNameEditText.text.toString()
Expand All @@ -164,4 +170,13 @@ class EditProjectSyncFragment : Fragment()
binding.editProjectSaveCircularProgressButton.startAnimation()
mainActivity.hideKeyBoard(binding.editProjectSaveCircularProgressButton)
}

private fun openDepsTxtFile() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/plain"
}

startActivityForResult(intent, Const.PICK_DEPS_LIST_TXT)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package name.lmj0011.jetpackreleasetracker.ui.projectsyncs

import android.app.Application
import android.net.Uri
import android.util.Patterns
import androidx.core.net.toFile
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.core.FuelError
import com.github.kittinunf.fuel.core.ResponseResultOf
import com.vdurmont.semver4j.Semver
import kotlinx.coroutines.*
import name.lmj0011.jetpackreleasetracker.database.AndroidXArtifact
import name.lmj0011.jetpackreleasetracker.database.ProjectSync
import name.lmj0011.jetpackreleasetracker.database.ProjectSyncDao
import timber.log.Timber
Expand Down Expand Up @@ -108,84 +112,100 @@ class ProjectSyncsViewModel(
project.upToDateCount = 0

return uiScope.launch(Dispatchers.IO) {
lateinit var res: ResponseResultOf<ByteArray>
var res: ResponseResultOf<ByteArray>? = null
var localByteArray: ByteArray? = null

try {
// ref: https://github.com/kittinunf/fuel/blob/master/fuel/README.md#blocking-responses
res = Fuel.get(project.depsListUrl).response()
Timber.d("project.depsListUrl: ${project.depsListUrl}")

if(Patterns.WEB_URL.matcher(project.depsListUrl).matches()) {
// ref: https://github.com/kittinunf/fuel/blob/master/fuel/README.md#blocking-responses
res = Fuel.get(project.depsListUrl).response()
Timber.d("path is a web url")
} else {
val inputStream = getApplication<Application>()
.applicationContext.contentResolver.openInputStream(Uri.parse(project.depsListUrl))
localByteArray = inputStream?.readBytes()
Timber.d("path is NOT a web url")
}
} catch (ex: Throwable) {
errorMessages.postValue(ex.message)
return@launch
}

val artifacts = database.getAllAndroidXArtifacts()

val (data, error) = res.third

error?.let { err -> errorMessages.postValue(err.message) }

when {
data is ByteArray -> {
val str = String(data)
val strLines = str.lines()
var resultProjectDepsMap: MutableMap<String, MutableList<String>> = mutableMapOf()

strLines.forEach {
val lib = it.split(':')
if (lib.size == 3) { // should only be 3 elements
val groupId = lib[0]
val artifactId = lib[1]
val versionId = lib[2]

if(resultProjectDepsMap["$groupId"] == null) resultProjectDepsMap["$groupId"] = mutableListOf()

artifacts.find { artifact ->
artifact.name == "$groupId:$artifactId"
}?.let { artifact ->

val str = if(project.stableVersionsOnly) {
if (Semver(artifact.latestStableVersion, Semver.SemverType.LOOSE).isGreaterThan(versionId)) {
project.outdatedCount = project.outdatedCount.plus(1)
"$artifactId:$versionId -> ${artifact.latestStableVersion}\n"
} else {
project.upToDateCount = project.upToDateCount.plus(1)
"$artifactId:$versionId\n"
}
} else {
if (Semver(artifact.latestVersion, Semver.SemverType.LOOSE).isGreaterThan(versionId)) {
project.outdatedCount = project.outdatedCount.plus(1)
"$artifactId:$versionId -> ${artifact.latestVersion}\n"
}else {
project.upToDateCount = project.upToDateCount.plus(1)
"$artifactId:$versionId\n"
}
}

resultProjectDepsMap["$groupId"]?.add(str)
}
res?.third?.component1() is ByteArray -> {
val data = res.third.component1()!!
parseDependencyList(String(data), project, artifacts)
}
localByteArray is ByteArray -> {
parseDependencyList(String(localByteArray), project, artifacts)
}
res?.third?.component2() is FuelError -> {
val error = res.third.component2()!!
errorMessages.postValue(error.message)
error.exception.let { Timber.e(it) }
}
}

this@ProjectSyncsViewModel.database.upsert(project)
}
}

private fun parseDependencyList(depsList: String, project: ProjectSync, artifacts: MutableList<AndroidXArtifact>) {
val strLines = depsList.lines()
var resultProjectDepsMap: MutableMap<String, MutableList<String>> = mutableMapOf()

strLines.forEach {
val lib = it.split(':')
if (lib.size == 3) { // should only be 3 elements
val groupId = lib[0]
val artifactId = lib[1]
val versionId = lib[2]

if(resultProjectDepsMap["$groupId"] == null) resultProjectDepsMap["$groupId"] = mutableListOf()

artifacts.find { artifact ->
artifact.name == "$groupId:$artifactId"
}?.let { artifact ->

val str = if(project.stableVersionsOnly) {
if (Semver(artifact.latestStableVersion, Semver.SemverType.LOOSE).isGreaterThan(versionId)) {
project.outdatedCount = project.outdatedCount.plus(1)
"$artifactId:$versionId -> ${artifact.latestStableVersion}\n"
} else {
project.upToDateCount = project.upToDateCount.plus(1)
"$artifactId:$versionId\n"
}
} else {
if (Semver(artifact.latestVersion, Semver.SemverType.LOOSE).isGreaterThan(versionId)) {
project.outdatedCount = project.outdatedCount.plus(1)
"$artifactId:$versionId -> ${artifact.latestVersion}\n"
}else {
project.upToDateCount = project.upToDateCount.plus(1)
"$artifactId:$versionId\n"
}
}

// remove non-androidx entries
val keysToDelete = resultProjectDepsMap.keys.filter { str ->
!str.contains("androidx.")
}
resultProjectDepsMap["$groupId"]?.add(str)
}

keysToDelete.forEach { str ->
resultProjectDepsMap.remove(str)
}

projectDepsMap.postValue(resultProjectDepsMap)
}
error is FuelError -> {
error.exception?.let { Timber.e(it) }
}
}
}

this@ProjectSyncsViewModel.database.upsert(project)
// remove non-androidx entries
val keysToDelete = resultProjectDepsMap.keys.filter { str ->
!str.contains("androidx.")
}

keysToDelete.forEach { str ->
resultProjectDepsMap.remove(str)
}

projectDepsMap.postValue(resultProjectDepsMap)
}

fun test() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
</vector>
11 changes: 10 additions & 1 deletion app/src/main/res/layout/fragment_create_project_sync.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="URL to Dependencies List"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@+id/pickDepsListTxtImageButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/projectNameEditText" />

Expand Down Expand Up @@ -62,6 +62,15 @@
app:layout_constraintTop_toBottomOf="@+id/depsUrlEditText"
app:spinning_bar_color="@android:color/white" />

<ImageButton
android:id="@+id/pickDepsListTxtImageButton"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@+id/depsUrlEditText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/depsUrlEditText"
app:srcCompat="@drawable/ic_baseline_insert_drive_file_24" />


</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Loading

0 comments on commit d2ce859

Please sign in to comment.