forked from Louvorg/ReaderForSelfoss-multiplatform
Compare commits
11 Commits
v122123461
...
v122123483
Author | SHA1 | Date | |
---|---|---|---|
7420adeb5c | |||
316027ca3b | |||
9d58fba5c9 | |||
284c19ef89 | |||
7cfd17231a | |||
527830a5ae | |||
c4ed30f594 | |||
156c1681cf | |||
3593fbca78 | |||
430fc8e8cb | |||
4fce19bad4 |
22
.drone.yml
22
.drone.yml
@ -3,27 +3,34 @@ type: docker
|
||||
name: test
|
||||
|
||||
steps:
|
||||
- name: AnylyseBuildTest
|
||||
- name: BuildAndTest
|
||||
image: mingc/android-build-box:latest
|
||||
commands:
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Configure gradle..."
|
||||
- mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true\npushCache=false\nsystemProp.org.gradle.internal.http.connectionTimeout=180000\nsystemProp.org.gradle.internal.http.socketTimeout=180000" >> ~/.gradle/gradle.properties
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Analysing..."
|
||||
- ./gradlew sonarqube -Dsonar.projectKey=RFS2 -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Building..."
|
||||
- ./gradlew build -x test
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Testing..."
|
||||
- echo "---------------------------------------------------------"
|
||||
- ./gradlew test
|
||||
- ./gradlew koverMergedXmlReport
|
||||
environment:
|
||||
SONAR_HOST_URL:
|
||||
from_secret: sonarScannerHostUrl
|
||||
SONAR_LOGIN:
|
||||
from_secret: sonarScannerLogin
|
||||
- name: Analyse
|
||||
image: kytay/sonar-node-plugin
|
||||
settings:
|
||||
sonar_host:
|
||||
from_secret: sonarScannerHostUrl
|
||||
sonar_token:
|
||||
from_secret: sonarScannerLogin
|
||||
use_node_version: 16.18.1
|
||||
sonar_debug: true
|
||||
sonar_project_settings: ./sonar-project.properties
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
@ -88,9 +95,12 @@ steps:
|
||||
- name: build
|
||||
image: mingc/android-build-box:latest
|
||||
commands:
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Fetch tags..."
|
||||
- git fetch --tags
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Configure gradle..."
|
||||
- mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true\npushCache=false\nsystemProp.org.gradle.internal.http.connectionTimeout=180000\nsystemProp.org.gradle.internal.http.socketTimeout=180000" >> ~/.gradle/gradle.properties
|
||||
- mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=false\npushCache=false\nsystemProp.org.gradle.internal.http.connectionTimeout=180000\nsystemProp.org.gradle.internal.http.socketTimeout=180000" >> ~/.gradle/gradle.properties
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Generate APK"
|
||||
- ./gradlew :androidApp:assembleGithubConfigRelease -P pushCache=false
|
||||
|
@ -8,6 +8,7 @@ plugins {
|
||||
kotlin("android")
|
||||
kotlin("kapt")
|
||||
id("com.mikepenz.aboutlibraries.plugin")
|
||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
||||
}
|
||||
|
||||
fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
||||
|
@ -70,7 +70,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
private lateinit var fab: FloatingActionButton
|
||||
private lateinit var textAlignment: String
|
||||
private var _binding: FragmentArticleBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val binding get() = _binding
|
||||
|
||||
override val di : DI by closestDI()
|
||||
private val repository: Repository by instance()
|
||||
@ -113,13 +113,13 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
|
||||
refreshAlignment()
|
||||
|
||||
fab = binding.fab
|
||||
fab = binding!!.fab
|
||||
|
||||
fab.backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.colorAccent))
|
||||
|
||||
fab.rippleColor = resources.getColor(R.color.colorAccentDark)
|
||||
|
||||
val floatingToolbar: FloatingToolbar = binding.floatingToolbar
|
||||
val floatingToolbar: FloatingToolbar = binding!!.floatingToolbar
|
||||
floatingToolbar.attachFab(fab)
|
||||
|
||||
floatingToolbar.background = ColorDrawable(resources.getColor(R.color.colorAccent))
|
||||
@ -167,35 +167,35 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
floatingToolbar.show()
|
||||
}
|
||||
|
||||
binding.source.text = contentSource
|
||||
binding!!.source.text = contentSource
|
||||
if (typeface != null) {
|
||||
binding.source.typeface = typeface
|
||||
binding!!.source.typeface = typeface
|
||||
}
|
||||
|
||||
if (contentText.isEmptyOrNullOrNullString()) {
|
||||
getContentFromMercury()
|
||||
} else {
|
||||
binding.titleView.text = contentTitle
|
||||
binding!!.titleView.text = contentTitle
|
||||
if (typeface != null) {
|
||||
binding.titleView.typeface = typeface
|
||||
binding!!.titleView.typeface = typeface
|
||||
}
|
||||
|
||||
htmlToWebview()
|
||||
|
||||
if (!contentImage.isEmptyOrNullOrNullString() && context != null) {
|
||||
binding.imageView.visibility = View.VISIBLE
|
||||
binding!!.imageView.visibility = View.VISIBLE
|
||||
Glide
|
||||
.with(requireContext())
|
||||
.asBitmap()
|
||||
.load(contentImage)
|
||||
.apply(RequestOptions.fitCenterTransform())
|
||||
.into(binding.imageView)
|
||||
.into(binding!!.imageView)
|
||||
} else {
|
||||
binding.imageView.visibility = View.GONE
|
||||
binding!!.imageView.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
binding.nestedScrollView.setOnScrollChangeListener(
|
||||
binding!!.nestedScrollView.setOnScrollChangeListener(
|
||||
NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
|
||||
if (scrollY > oldScrollY) {
|
||||
floatingToolbar.hide()
|
||||
@ -224,7 +224,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
.show()
|
||||
}
|
||||
|
||||
return binding.root
|
||||
return binding!!.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -242,16 +242,16 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
|
||||
private fun getContentFromMercury() {
|
||||
if (repository.isNetworkAvailable()) {
|
||||
binding.progressBar.visibility = View.VISIBLE
|
||||
binding!!.progressBar.visibility = View.VISIBLE
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
try {
|
||||
val response = mercuryApi.query(url)
|
||||
if (response.success && response.data != null && !response.data?.content.isNullOrEmpty()) {
|
||||
binding.titleView.text = response.data!!.title.orEmpty()
|
||||
binding!!.titleView.text = response.data!!.title.orEmpty()
|
||||
try {
|
||||
if (typeface != null) {
|
||||
binding.titleView.typeface = typeface
|
||||
binding!!.titleView.typeface = typeface
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.sendSilentlyWithAcraWithName("getContentFromMercury > typeface")
|
||||
@ -275,7 +275,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
|
||||
if (!response.data?.lead_image_url.isNullOrEmpty() && context != null) {
|
||||
try {
|
||||
binding.imageView.visibility = View.VISIBLE
|
||||
binding!!.imageView.visibility = View.VISIBLE
|
||||
try {
|
||||
Glide
|
||||
.with(requireContext())
|
||||
@ -284,7 +284,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
response.data!!.lead_image_url.orEmpty()
|
||||
)
|
||||
.apply(RequestOptions.fitCenterTransform())
|
||||
.into(binding.imageView)
|
||||
.into(binding!!.imageView)
|
||||
} catch (e: Exception) {
|
||||
e.sendSilentlyWithAcraWithName("getContentFromMercury > glide lead image")
|
||||
}
|
||||
@ -292,12 +292,12 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
e.sendSilentlyWithAcraWithName("getContentFromMercury > outside glide lead image")
|
||||
}
|
||||
} else {
|
||||
binding.imageView.visibility = View.GONE
|
||||
binding!!.imageView.visibility = View.GONE
|
||||
}
|
||||
|
||||
try {
|
||||
binding.nestedScrollView.scrollTo(0, 0)
|
||||
binding.progressBar.visibility = View.GONE
|
||||
binding!!.nestedScrollView.scrollTo(0, 0)
|
||||
binding!!.progressBar.visibility = View.GONE
|
||||
} catch (e: Exception) {
|
||||
e.sendSilentlyWithAcraWithName("getContentFromMercury > scrollview")
|
||||
}
|
||||
@ -320,8 +320,8 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
val a: TypedArray = requireContext().obtainStyledAttributes(resId, attrs)
|
||||
|
||||
|
||||
binding.webcontent.settings.standardFontFamily = a.getString(0)
|
||||
binding.webcontent.visibility = View.VISIBLE
|
||||
binding!!.webcontent.settings.standardFontFamily = a.getString(0)
|
||||
binding!!.webcontent.visibility = View.VISIBLE
|
||||
|
||||
val colorOnSurface = TypedValue()
|
||||
requireContext().theme.resolveAttribute(R.attr.colorOnSurface, colorOnSurface, true)
|
||||
@ -329,14 +329,14 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
val colorSurface = TypedValue()
|
||||
requireContext().theme.resolveAttribute(R.attr.colorSurface, colorSurface, true)
|
||||
|
||||
binding.webcontent.settings.useWideViewPort = true
|
||||
binding.webcontent.settings.loadWithOverviewMode = true
|
||||
binding.webcontent.settings.javaScriptEnabled = false
|
||||
binding!!.webcontent.settings.useWideViewPort = true
|
||||
binding!!.webcontent.settings.loadWithOverviewMode = true
|
||||
binding!!.webcontent.settings.javaScriptEnabled = false
|
||||
|
||||
binding.webcontent.webViewClient = object : WebViewClient() {
|
||||
binding!!.webcontent.webViewClient = object : WebViewClient() {
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun shouldOverrideUrlLoading(view: WebView?, url : String): Boolean {
|
||||
if (binding.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||
if (binding!!.webcontent.hitTestResult.type != WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||
requireContext().startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
||||
}
|
||||
return true
|
||||
@ -380,9 +380,9 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
}
|
||||
})
|
||||
|
||||
binding.webcontent.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event)}
|
||||
binding!!.webcontent.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event)}
|
||||
|
||||
binding.webcontent.settings.layoutAlgorithm =
|
||||
binding!!.webcontent.settings.layoutAlgorithm =
|
||||
WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||
|
||||
var baseUrl: String? = null
|
||||
@ -413,7 +413,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
""
|
||||
}
|
||||
|
||||
binding.webcontent.loadDataWithBaseURL(
|
||||
binding!!.webcontent.loadDataWithBaseURL(
|
||||
baseUrl,
|
||||
"""<html>
|
||||
|<head>
|
||||
@ -466,17 +466,17 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
}
|
||||
|
||||
fun scrollDown() {
|
||||
val height = binding.nestedScrollView.measuredHeight
|
||||
binding.nestedScrollView.smoothScrollBy(0, height/2)
|
||||
val height = binding!!.nestedScrollView.measuredHeight
|
||||
binding!!.nestedScrollView.smoothScrollBy(0, height/2)
|
||||
}
|
||||
|
||||
fun scrollUp() {
|
||||
val height = binding.nestedScrollView.measuredHeight
|
||||
binding.nestedScrollView.smoothScrollBy(0, -height/2)
|
||||
val height = binding!!.nestedScrollView.measuredHeight
|
||||
binding!!.nestedScrollView.smoothScrollBy(0, -height/2)
|
||||
}
|
||||
|
||||
private fun openInBrowserAfterFailing() {
|
||||
binding.progressBar.visibility = View.GONE
|
||||
binding!!.progressBar.visibility = View.GONE
|
||||
requireActivity().openInBrowserAsNewTask(this@ArticleFragment.item)
|
||||
}
|
||||
|
||||
@ -495,10 +495,10 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
}
|
||||
|
||||
fun performClick(): Boolean {
|
||||
if (binding.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
|
||||
binding.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||
if (binding!!.webcontent.hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE ||
|
||||
binding!!.webcontent.hitTestResult.type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
|
||||
|
||||
val position : Int = allImages.indexOf(binding.webcontent.hitTestResult.extra)
|
||||
val position : Int = allImages.indexOf(binding!!.webcontent.hitTestResult.extra)
|
||||
|
||||
val intent = Intent(activity, ImageActivity::class.java)
|
||||
intent.putExtra("allImages", allImages)
|
||||
|
@ -105,7 +105,7 @@
|
||||
<string name="new_items_notification_text">%1$d new items loaded.</string>
|
||||
<string name="pref_switch_notify_new_items">Notify on new items synced.</string>
|
||||
<string name="shortcut_offline">Offline</string>
|
||||
<string name="pref_api_timeout">Api Timeout</string>
|
||||
<string name="pref_api_timeout">Api Timeout (seconds)</string>
|
||||
<string name="pref_header_experimental">Experimental</string>
|
||||
<string name="webview_dialog_issue_message">Webview not available. Disabling the article viewer to avoid any future crashes. Will load articles inside of your browser from now on.</string>
|
||||
<string name="webview_dialog_issue_title">Webview issue</string>
|
||||
|
@ -369,14 +369,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
val (tags, tagsDB) = prepareTags()
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
@ -396,17 +389,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_with_sources_update_disabled() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
val (tags, tagsDB) = prepareTags()
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
every { appSettingsService.isItemCachingEnabled() } returns true
|
||||
|
||||
@ -426,17 +409,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_with_items_caching_disabled() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
val (tags, _) = prepareTags()
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
|
||||
@ -453,17 +426,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_with_sources_update_and_items_caching_disabled() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
val (tags, tagsDB) = prepareTags()
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
|
||||
@ -482,17 +445,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_without_connection() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
val (tags, tagsDB) = prepareTags()
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||
every { appSettingsService.isItemCachingEnabled() } returns true
|
||||
|
||||
@ -510,17 +463,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_without_connection_and_items_caching_disabled() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
prepareTags()
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||
|
||||
@ -537,17 +480,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_without_connection_and_sources_update_disabled() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
val (tags, tagsDB) = prepareTags()
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
every { appSettingsService.isItemCachingEnabled() } returns true
|
||||
|
||||
@ -565,17 +498,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_tags_without_connection_and_sources_update_and_items_caching_disabled() {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
val (_, tagsDB) = prepareTags()
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
|
||||
@ -590,8 +513,36 @@ class RepositoryTest {
|
||||
verify(atLeast = 1) { db.tagsQueries.tags().executeAsList() }
|
||||
}
|
||||
|
||||
private fun prepareTags(): Pair<List<SelfossModel.Tag>, List<TAG>> {
|
||||
val tags = listOf(
|
||||
SelfossModel.Tag("test", "red", 6),
|
||||
SelfossModel.Tag("second", "yellow", 0)
|
||||
)
|
||||
val tagsDB = listOf(
|
||||
TAG("test_DB", "red", 6),
|
||||
TAG("second_DB", "yellow", 0)
|
||||
)
|
||||
|
||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||
return Pair(tags, tagsDB)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun get_sources() {
|
||||
val (sources, sourcesDB) = prepareSources()
|
||||
initializeRepository()
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
testSources = repository.getSources()
|
||||
}
|
||||
|
||||
assertSame(sources, testSources)
|
||||
assertNotEquals(sourcesDB.map { it.toView() }, testSources)
|
||||
coVerify(exactly = 1) { api.sources() }
|
||||
}
|
||||
|
||||
private fun prepareSources(): Pair<ArrayList<SelfossModel.Source>, List<SOURCE>> {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
@ -631,60 +582,15 @@ class RepositoryTest {
|
||||
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository()
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
testSources = repository.getSources()
|
||||
}
|
||||
|
||||
assertSame(sources, testSources)
|
||||
assertNotEquals(sourcesDB.map { it.toView() }, testSources)
|
||||
coVerify(exactly = 1) { api.sources() }
|
||||
return Pair(sources, sourcesDB)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun get_sources_with_sources_update_disabled() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second DB source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val (sources, sourcesDB) = prepareSources()
|
||||
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
every { appSettingsService.isItemCachingEnabled() } returns true
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository()
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -701,47 +607,10 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_sources_with_items_caching_disabled() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val (sources, _) = prepareSources()
|
||||
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository()
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -755,47 +624,10 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_sources_with_sources_update_and_items_caching_disabled() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val (sources, _) = prepareSources()
|
||||
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository()
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -809,45 +641,7 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_sources_without_connection() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First DB source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
val (_, sourcesDB) = prepareSources()
|
||||
initializeRepository(MutableStateFlow(false))
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -861,47 +655,10 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_sources_without_connection_and_items_caching_disabled() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First DB source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
prepareSources()
|
||||
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository(MutableStateFlow(false))
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -915,47 +672,10 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_sources_without_connection_and_sources_update_disabled() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First DB source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val (_, sourcesDB) = prepareSources()
|
||||
|
||||
every { appSettingsService.isItemCachingEnabled() } returns true
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository(MutableStateFlow(false))
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -969,47 +689,10 @@ class RepositoryTest {
|
||||
|
||||
@Test
|
||||
fun get_sources_without_connection_and_items_caching_and_sources_update_disabled() {
|
||||
val sources = arrayListOf(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SelfossModel.Source(
|
||||
2,
|
||||
"Second source",
|
||||
listOf("second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val sourcesDB = listOf(
|
||||
SOURCE(
|
||||
"1",
|
||||
"First DB source",
|
||||
"Test,second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
),
|
||||
SOURCE(
|
||||
"2",
|
||||
"Second source",
|
||||
"second",
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
||||
)
|
||||
)
|
||||
val (_, sourcesDB) = prepareSources()
|
||||
|
||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||
initializeRepository(MutableStateFlow(false))
|
||||
var testSources: List<SelfossModel.Source>?
|
||||
runBlocking {
|
||||
@ -1302,16 +985,7 @@ class RepositoryTest {
|
||||
)
|
||||
|
||||
initializeRepository()
|
||||
repository.setTagFilter(SelfossModel.Tag("Tag", "read", 0))
|
||||
repository.setSourceFilter(SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
))
|
||||
repository.searchFilter = "search"
|
||||
prepareSearch()
|
||||
runBlocking {
|
||||
repository.tryToCacheItemsAndGetNewOnes()
|
||||
}
|
||||
@ -1325,16 +999,7 @@ class RepositoryTest {
|
||||
StatusAndData(success = false, data = generateTestApiItem())
|
||||
|
||||
initializeRepository()
|
||||
repository.setTagFilter(SelfossModel.Tag("Tag", "read", 0))
|
||||
repository.setSourceFilter(SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
))
|
||||
repository.searchFilter = "search"
|
||||
prepareSearch()
|
||||
runBlocking {
|
||||
repository.tryToCacheItemsAndGetNewOnes()
|
||||
}
|
||||
@ -1348,20 +1013,26 @@ class RepositoryTest {
|
||||
StatusAndData(success = false, data = generateTestApiItem())
|
||||
|
||||
initializeRepository(MutableStateFlow(false))
|
||||
repository.setTagFilter(SelfossModel.Tag("Tag", "read", 0))
|
||||
repository.setSourceFilter(SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
))
|
||||
repository.searchFilter = "search"
|
||||
prepareSearch()
|
||||
runBlocking {
|
||||
repository.tryToCacheItemsAndGetNewOnes()
|
||||
}
|
||||
|
||||
coVerify(exactly = 0) { api.getItems(any(), 0, null, null, null, null, 200) }
|
||||
}
|
||||
|
||||
private fun prepareSearch() {
|
||||
repository.setTagFilter(SelfossModel.Tag("Tag", "read", 0))
|
||||
repository.setSourceFilter(
|
||||
SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
)
|
||||
)
|
||||
repository.searchFilter = "search"
|
||||
}
|
||||
}
|
@ -11,12 +11,10 @@ plugins {
|
||||
id("com.android.library").version("7.3.1").apply(false)
|
||||
kotlin("android").version("1.7.20").apply(false)
|
||||
kotlin("multiplatform").version("1.7.20").apply(false)
|
||||
id("org.sonarqube").version("3.4.0.2513").apply(false)
|
||||
id("com.mikepenz.aboutlibraries.plugin").version("10.5.1").apply(false)
|
||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
||||
}
|
||||
|
||||
apply(plugin = "org.sonarqube")
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
@ -30,3 +28,7 @@ allprojects {
|
||||
tasks.register("clean", Delete::class) {
|
||||
delete(rootProject.buildDir)
|
||||
}
|
||||
|
||||
koverMerged {
|
||||
enable()
|
||||
}
|
@ -10,6 +10,7 @@ plugins {
|
||||
id("com.android.library")
|
||||
id("com.squareup.sqldelight")
|
||||
kotlin("plugin.serialization") version "1.4.10"
|
||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
@ -1,15 +1,6 @@
|
||||
package bou.amine.apps.readerforselfossv2.model
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
class MercuryModel {
|
||||
|
||||
@ -20,138 +11,4 @@ class MercuryModel {
|
||||
val lead_image_url: String?,
|
||||
val url: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Tag(
|
||||
val tag: String,
|
||||
val color: String,
|
||||
val unread: Int
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class Stats(
|
||||
val total: Int,
|
||||
val unread: Int,
|
||||
val starred: Int
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Spout(
|
||||
val name: String,
|
||||
val description: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ApiVersion(
|
||||
val version: String?,
|
||||
val apiversion: String?
|
||||
) {
|
||||
fun getApiMajorVersion() : Int {
|
||||
var versionNumber = 0
|
||||
if (apiversion != null) {
|
||||
versionNumber = apiversion.substringBefore(".").toInt()
|
||||
}
|
||||
return versionNumber
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Source(
|
||||
val id: Int,
|
||||
val title: String,
|
||||
@Serializable(with = TagsListSerializer::class)
|
||||
val tags: List<String>,
|
||||
val spout: String,
|
||||
val error: String,
|
||||
val icon: String?
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Item(
|
||||
val id: Int,
|
||||
val datetime: String,
|
||||
val title: String,
|
||||
val content: String,
|
||||
@Serializable(with = BooleanSerializer::class)
|
||||
var unread: Boolean,
|
||||
@Serializable(with = BooleanSerializer::class)
|
||||
var starred: Boolean,
|
||||
val thumbnail: String?,
|
||||
val icon: String?,
|
||||
val link: String,
|
||||
val sourcetitle: String,
|
||||
@Serializable(with = TagsListSerializer::class)
|
||||
val tags: List<String>
|
||||
) {
|
||||
// TODO: maybe find a better way to handle these kind of urls
|
||||
fun getLinkDecoded(): String {
|
||||
var stringUrl: String
|
||||
stringUrl =
|
||||
if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
|
||||
if (link.contains("&url=")) {
|
||||
link.substringAfter("&url=")
|
||||
} else {
|
||||
this.link.replace("&", "&")
|
||||
}
|
||||
} else {
|
||||
this.link.replace("&", "&")
|
||||
}
|
||||
|
||||
// handle :443 => https
|
||||
if (stringUrl.contains(":443")) {
|
||||
stringUrl = stringUrl.replace(":443", "").replace("http://", "https://")
|
||||
}
|
||||
|
||||
// handle url not starting with http
|
||||
if (stringUrl.startsWith("//")) {
|
||||
stringUrl = "http:$stringUrl"
|
||||
}
|
||||
|
||||
return stringUrl
|
||||
}
|
||||
|
||||
fun sourceAndDateText(): String =
|
||||
this.sourcetitle.getHtmlDecoded() + DateUtils.parseRelativeDate(this.datetime)
|
||||
|
||||
fun toggleStar(): Item {
|
||||
this.starred = !this.starred
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this seems to be super slow.
|
||||
object TagsListSerializer : KSerializer<List<String>> {
|
||||
override fun deserialize(decoder: Decoder): List<String> {
|
||||
return when(val json = ((decoder as JsonDecoder).decodeJsonElement())) {
|
||||
is JsonArray -> json.toList().map { it.toString() }
|
||||
else -> json.toString().split(",")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor("tags", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: List<String>) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
object BooleanSerializer : KSerializer<Boolean> {
|
||||
override fun deserialize(decoder: Decoder): Boolean {
|
||||
val json = ((decoder as JsonDecoder).decodeJsonElement()).jsonPrimitive
|
||||
return if (json.booleanOrNull != null) {
|
||||
json.boolean
|
||||
} else {
|
||||
json.int == 1
|
||||
}
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor("b", PrimitiveKind.BOOLEAN)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,36 +229,14 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
||||
): SuccessResponse =
|
||||
maybeResponse(
|
||||
if (appSettingsService.getApiVersion() > 1) {
|
||||
createSource2(title, url, spout, tags, filter)
|
||||
createSource("tags[]", title, url, spout, tags, filter)
|
||||
} else {
|
||||
createSource(title, url, spout, tags, filter)
|
||||
createSource("tags", title, url, spout, tags, filter)
|
||||
}
|
||||
)
|
||||
|
||||
private suspend fun createSource(
|
||||
title: String,
|
||||
url: String,
|
||||
spout: String,
|
||||
tags: String,
|
||||
filter: String
|
||||
): HttpResponse =
|
||||
client.submitForm(
|
||||
url = url("/source"),
|
||||
formParameters = Parameters.build {
|
||||
// TODO: test this
|
||||
if (!shouldHavePostLogin()) {
|
||||
append("username", appSettingsService.getUserName())
|
||||
append("password", appSettingsService.getPassword())
|
||||
}
|
||||
append("title", title)
|
||||
append("url", url)
|
||||
append("spout", spout)
|
||||
append("tags", tags)
|
||||
append("filter", filter)
|
||||
}
|
||||
)
|
||||
|
||||
private suspend fun createSource2(
|
||||
tagsParamName: String,
|
||||
title: String,
|
||||
url: String,
|
||||
spout: String,
|
||||
@ -275,7 +253,7 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
||||
append("title", title)
|
||||
append("url", url)
|
||||
append("spout", spout)
|
||||
append("tags[]", tags)
|
||||
append(tagsParamName, tags)
|
||||
append("filter", filter)
|
||||
}
|
||||
)
|
||||
|
@ -84,7 +84,13 @@ class AppSettingsService {
|
||||
}
|
||||
|
||||
private fun refreshItemsNumber() {
|
||||
_itemsNumber = settings.getString(API_ITEMS_NUMBER, "20").toInt()
|
||||
_itemsNumber = try {
|
||||
settings.getString(API_ITEMS_NUMBER, "20").toInt()
|
||||
} catch (e: Exception) {
|
||||
settings.remove(API_ITEMS_NUMBER)
|
||||
20
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getApiTimeout(): Long {
|
||||
@ -94,9 +100,21 @@ class AppSettingsService {
|
||||
return _apiTimeout!!
|
||||
}
|
||||
|
||||
private fun secToMs(n: Long) = n * 1000
|
||||
|
||||
private fun refreshApiTimeout() {
|
||||
val settingsTimeout = settings.getLong(API_TIMEOUT, HttpTimeout.INFINITE_TIMEOUT_MS)
|
||||
_apiTimeout = if (settingsTimeout > 0) settingsTimeout else HttpTimeout.INFINITE_TIMEOUT_MS
|
||||
_apiTimeout = secToMs(try {
|
||||
val settingsTimeout = settings.getString(API_TIMEOUT, "60")
|
||||
if (settingsTimeout.toLong() > 0) {
|
||||
settingsTimeout.toLong()
|
||||
} else {
|
||||
settings.remove(API_TIMEOUT)
|
||||
60
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
settings.remove(API_TIMEOUT)
|
||||
60
|
||||
})
|
||||
}
|
||||
|
||||
private fun refreshBaseUrl() {
|
||||
|
5
sonar-project.properties
Normal file
5
sonar-project.properties
Normal file
@ -0,0 +1,5 @@
|
||||
sonar.projectKey=RFS2
|
||||
sonar.coverage.jacoco.xmlReportPaths=build/reports/kover/merged/xml/report.xml
|
||||
sonar.sourceEncoding=UTF-8
|
||||
sonar.sources=.
|
||||
sonar.exclusions=shared/src/iosArm64Main/**, shared/src/iosX64Main/**, docs/**
|
Reference in New Issue
Block a user