added RSS parser and simple news reader. Clicking on title opens website

remotes/origin/devel
yattoz 2019-12-08 13:27:55 +01:00
parent 122970f015
commit 99961e8a4e
5 changed files with 58 additions and 8 deletions

View File

@ -69,12 +69,15 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.preference:preference:1.1.0'
// jsoup HTML parser library @ https://jsoup.org/ // jsoup HTML parser library @ https://jsoup.org/
// implementation 'org.jsoup:jsoup:1.12.1' // implementation 'org.jsoup:jsoup:1.12.1'
// RSS parser library @ https://github.com/prof18/RSS-Parser
implementation 'com.prof.rssparser:rssparser:2.0.4'
def work_version = "2.2.0" def work_version = "2.2.0"
implementation "androidx.work:work-runtime-ktx:$work_version" implementation "androidx.work:work-runtime-ktx:$work_version"

View File

@ -7,6 +7,7 @@ class News {
var text: String = "" var text: String = ""
var header: String = "" var header: String = ""
var author: String = "" var author: String = ""
var link: String = ""
var date: Date = Date() var date: Date = Date()
override fun toString() : String override fun toString() : String

View File

@ -1,17 +1,21 @@
package fr.forum_thalie.tsumugi.ui.news package fr.forum_thalie.tsumugi.ui.news
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.TextView import android.widget.TextView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.startActivity
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.core.widget.TextViewCompat import androidx.core.widget.TextViewCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import fr.forum_thalie.tsumugi.R import fr.forum_thalie.tsumugi.R
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class NewsAdapter(private val dataSet: ArrayList<News> class NewsAdapter(private val dataSet: ArrayList<News>, private val c: Context
/*, /*,
context: Context, context: Context,
resource: Int, resource: Int,
@ -45,6 +49,11 @@ class NewsAdapter(private val dataSet: ArrayList<News>
val author = holder.itemView.findViewById<TextView>(R.id.news_author) val author = holder.itemView.findViewById<TextView>(R.id.news_author)
val header = holder.itemView.findViewById<TextView>(R.id.news_header) val header = holder.itemView.findViewById<TextView>(R.id.news_header)
title.text = dataSet[position].title title.text = dataSet[position].title
title.setOnClickListener {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(dataSet[position].link)
c.startActivity(i)
}
text.text = HtmlCompat.fromHtml(dataSet[position].text, HtmlCompat.FROM_HTML_MODE_LEGACY) text.text = HtmlCompat.fromHtml(dataSet[position].text, HtmlCompat.FROM_HTML_MODE_LEGACY)
header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ") header.text = HtmlCompat.fromHtml(dataSet[position].header, HtmlCompat.FROM_HTML_MODE_LEGACY).replace(Regex("\n"), " ")
author.text = "| ${dataSet[position].author}" author.text = "| ${dataSet[position].author}"

View File

@ -29,7 +29,7 @@ class NewsFragment : Fragment() {
val root = inflater.inflate(R.layout.fragment_news, container, false) as androidx.swiperefreshlayout.widget.SwipeRefreshLayout val root = inflater.inflate(R.layout.fragment_news, container, false) as androidx.swiperefreshlayout.widget.SwipeRefreshLayout
viewManager = LinearLayoutManager(context) viewManager = LinearLayoutManager(context)
viewAdapter = NewsAdapter(newsViewModel.newsArray) viewAdapter = NewsAdapter(newsViewModel.newsArray, context!!)
recyclerView = root.findViewById<RecyclerView>(R.id.news_recycler).apply { recyclerView = root.findViewById<RecyclerView>(R.id.news_recycler).apply {
// use this setting to improve performance if you know that changes // use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView // in content do not change the layout size of the RecyclerView

View File

@ -3,21 +3,28 @@ package fr.forum_thalie.tsumugi.ui.news
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.prof.rssparser.Parser
import fr.forum_thalie.tsumugi.Async import fr.forum_thalie.tsumugi.Async
import fr.forum_thalie.tsumugi.tag import fr.forum_thalie.tsumugi.tag
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.net.URL import java.net.URL
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.math.max
import kotlin.math.min
class NewsViewModel : ViewModel() { class NewsViewModel : ViewModel() {
val newsArray : ArrayList<News> = ArrayList() val newsArray : ArrayList<News> = ArrayList()
private val urlToScrape = "https://r-a-d.io/api/news" private val urlToScrape = "https://tsumugi.forum-thalie.fr/?feed=rss2"
private val scrape : (Any?) -> Unit = private val scrape : (Any?) -> Unit =
{ {
@ -41,12 +48,42 @@ class NewsViewModel : ViewModel() {
} }
} }
private val viewModelJob = Job()
private val coroutineScope = CoroutineScope(Dispatchers.Main + viewModelJob)
fun fetch(root: androidx.swiperefreshlayout.widget.SwipeRefreshLayout? = null, viewAdapter: RecyclerView.Adapter<*>? = null) fun fetch(root: androidx.swiperefreshlayout.widget.SwipeRefreshLayout? = null, viewAdapter: RecyclerView.Adapter<*>? = null)
{ {
val post : (parameter: Any?) -> Unit = { val maxNumberOfArticles = 5
root?.isRefreshing = false coroutineScope.launch(Dispatchers.Main) {
viewAdapter?.notifyDataSetChanged() Log.d(tag, "launching coroutine")
try {
val parser = Parser()
val articleList = parser.getArticles(urlToScrape)
newsArray.clear()
for (i in 0 until min(articleList.size, maxNumberOfArticles))
{
val item = articleList[i]
Log.d(tag, "i = $i / ${articleList.size}")
val news = News()
news.title = item.title ?: ""
news.link = item.link ?: urlToScrape
news.author = item.author ?: ""
news.text = item.content ?: ""
news.header = item.description ?: ""
//val formatter6 = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
//news.date = formatter6.parse(item.pubDate ?: Date().toString()) ?: Date()
Log.d(tag, "$news - ${item.pubDate}")
newsArray.add(news)
}
// The list contains all article's data. For example you can use it for your adapter.
root?.isRefreshing = false
viewAdapter?.notifyDataSetChanged()
} catch (e: Exception) {
// Handle the exception
}
} }
Async(scrape, post)
} }
} }