From 34509b5daad833693f00eeb20b7e11ccd6f02446 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 24 May 2026 12:20:30 +0200 Subject: [PATCH] refactor database structure: remove feed collections and the ability to store multiple uris per feed --- .../main/kotlin/de/unixwork/rssreader/App.kt | 2 +- .../kotlin/de/unixwork/rssreader/Database.kt | 280 +++++++----------- .../main/kotlin/de/unixwork/rssreader/Feed.kt | 26 +- .../de/unixwork/rssreader/FeedCollection.kt | 27 -- .../de/unixwork/rssreader/FeedConfig.kt | 54 ++-- .../kotlin/de/unixwork/rssreader/FeedGroup.kt | 2 +- .../kotlin/de/unixwork/rssreader/FeedList.kt | 8 +- .../de/unixwork/rssreader/FeedSourceList.kt | 9 +- .../main/kotlin/de/unixwork/rssreader/Item.kt | 2 +- .../de/unixwork/rssreader/MainWindow.kt | 19 +- 10 files changed, 174 insertions(+), 255 deletions(-) delete mode 100644 rss-application/src/main/kotlin/de/unixwork/rssreader/FeedCollection.kt diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt index 17c5b7b..b29fc47 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt @@ -36,7 +36,7 @@ object App : Application { fun syncCurrent() { window?.feedList?.currentFeed?.let { - SyncJob({ Database.getCollectionFeeds(it)}).sync() { + SyncJob({ Database.getFeed(it.id)?.let { mutableListOf(it)} ?: mutableListOf() }).sync() { window?.reload() } } diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt index ea65113..d1b0087 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt @@ -54,26 +54,19 @@ object Database { """.trimIndent()) createStmt.addBatch(""" - CREATE TABLE feedcollections ( - feedcollection_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, + CREATE TABLE feeds ( + feed_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, group_id INT NOT NULL REFERENCES groups(group_id) ON DELETE CASCADE, pos INT default 0, - internal_browser INT default 0, name VARCHAR, - update_interval INT, - max_item_age INT DEFAULT 0, - item_state_mode INT DEFAULT 0, - add_url_param VARCHAR - ) - """.trimIndent()) - - createStmt.addBatch(""" - CREATE TABLE feeds( - feed_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, - feedcollection_id INT NOT NULL REFERENCES feedcollections(feedcollection_id) ON DELETE CASCADE, url VARCHAR NOT NULL, auth_user VARCHAR, auth_password VARCHAR, + internal_browser INT default 0, + update_interval INT, + max_item_age INT DEFAULT 0, + item_state_mode INT DEFAULT 0, + add_url_param VARCHAR, certpath VARCHAR, last_update TIMESTAMP, disabled BOOLEAN DEFAULT FALSE @@ -115,8 +108,11 @@ object Database { select g.group_id, g.name as group_name, - f.feedcollection_id, + f.feed_id, f.name as feed_name, + f.url as feed_url, + f.auth_user, + f.auth_password, f.update_interval, f.max_item_age, f.item_state_mode, @@ -124,9 +120,9 @@ object Database { f.add_url_param, c.unread_count from groups g - left join feedcollections f on g.group_id = f.group_id - left join (select feedcollection_id, count(*) as unread_count from items I inner join feeds F on I.feed_id = F.feed_id - where I.is_read = false group by feedcollection_id) C on f.feedcollection_id = C.feedcollection_id + left join feeds f on g.group_id = f.group_id + left join (select f.feed_id, count(*) as unread_count from items I inner join feeds F on I.feed_id = F.feed_id + where I.is_read = false group by f.feed_id) C on f.feed_id = C.feed_id order by g.pos, f.pos """.trimIndent()) @@ -134,8 +130,11 @@ object Database { while(rs.next()) { val groupId = rs.getInt("group_id") val groupName = rs.getString("group_name") - val feedId = rs.getInt("feedcollection_id") + val feedId = rs.getInt("feed_id") val feedName = rs.getString("feed_name") + val auth_user = rs.getString("auth_user") + val auth_password = rs.getString("auth_password") + val feedUrl = rs.getString("feed_url") val updateInterval = rs.getLong("update_interval") val maxItemAge = rs.getInt("max_item_age") val internalBrowser = rs.getBoolean("internal_browser") @@ -149,7 +148,9 @@ object Database { } if(feedId != null && feedName != null) { - val feed = FeedCollection(feedId, feedName) + val feed = Feed(feedId, feedName, feedUrl) + feed.user = auth_user + feed.password = auth_password feed.updateInterval = updateInterval feed.maxItemAge = maxItemAge feed.itemStateMode = itemStateMode @@ -167,15 +168,15 @@ object Database { return groups } - public fun swapFeedCollectionPos(feed1: FeedCollection, feed2: FeedCollection) { + public fun swapFeedPos(feed1: Feed, feed2: Feed) { val sql = """ - update feedcollections set + update feeds set pos = case - when feedcollection_id = ?1 then (SELECT pos from feedcollections where feedcollection_id = ?2) - when feedcollection_id = ?2 then (SELECT pos from feedcollections where feedcollection_id = ?1) + when feed_id = ?1 then (SELECT pos from feeds where feed_id = ?2) + when feed_id = ?2 then (SELECT pos from feeds where feed_id = ?1) else pos end - where feedcollection_id in (?1, ?2) + where feed_id in (?1, ?2) """.trimIndent() dataSource.connection.use { conn -> @@ -227,165 +228,90 @@ object Database { return FeedGroup(context, groupId, name) } - public fun newFeeds( + public fun newFeed( parent: FeedGroup, name: String, - uris: Collection, + uri: String, user: String? = null, password: String? = null, cert: String? = null, internalBrowser: Boolean = false, updateInterval: Long = 0, maxItemAge: Int = 0, - itemStateMode: Int = 0) : FeedCollection + itemStateMode: Int = 0) : Feed { - var feedcollectionId = -1 - var feedCol: FeedCollection + var feedId = -1 + var feed: Feed dataSource.connection.use { connection -> connection.prepareStatement(""" - insert into feedcollections (group_id, pos, name, update_interval, max_item_age, item_state_mode) select ?, coalesce(max(pos), 0)+1, ?, ?, ?, ? from feedcollections + insert into feeds(group_id, pos, name, url, auth_user, auth_password, internal_browser, update_interval, max_item_age, item_state_mode) + select ?, coalesce(max(pos), 0)+1, ?, ?, ?, ?, ?, ?, ?, ? from feeds """.trimIndent(), Statement.RETURN_GENERATED_KEYS).use { stmt -> stmt.setInt(1, parent.id) stmt.setString(2, name) - stmt.setLong(3, updateInterval) - stmt.setInt(4, maxItemAge) - stmt.setInt(5, itemStateMode) + stmt.setString(3, uri) + stmt.setString(4, user) + stmt.setString(5, password) + stmt.setBoolean(6, internalBrowser) + stmt.setLong(7, updateInterval) + stmt.setInt(8, maxItemAge) + stmt.setInt(9, itemStateMode) stmt.execute() stmt.generatedKeys.use { rs -> if(rs.next()) { - feedcollectionId = rs.getInt(1) + feedId = rs.getInt(1) } else { throw Exception("Insert FeedCollection failed") } } } - feedCol = FeedCollection(feedcollectionId, name) - - uris.forEach { uri -> - connection.prepareStatement(""" - insert into feeds (feedcollection_id, url, auth_user, auth_password, certpath) values - (?, ?, ?, ?, ?) - """.trimIndent()).use { stmt -> - stmt.setInt(1, feedcollectionId) - stmt.setString(2, uri) - stmt.setString(3, user) - stmt.setString(4, password) - stmt.setString(5, cert) - - stmt.execute() - } - } + feed = Feed(feedId, name, uri) + parent.feeds.add(feed) } - parent.feeds.add(feedCol) - return feedCol + return feed } - public fun updateFeedCollection( - feed: FeedCollection, - uris: Collection, - user: String? = null, - password: String? = null, - cert: String? = null) + public fun updateFeed(feed: Feed) { dataSource.connection.use { conn -> conn.prepareStatement(""" - update feedcollections set - internal_browser = ?, + update feeds set name = ?, + url = ?, + auth_user = ?, + auth_password = ?, + internal_browser = ?, update_interval = ?, max_item_age = ?, - item_state_mode = ?, - add_url_param = ? - where feedcollection_id = ? + item_state_mode = ? + where feed_id = ? """.trimIndent()).use { stmt -> - stmt.setBoolean(1, feed.internalBrowser) - stmt.setString(2, feed.name) - stmt.setLong(3, feed.updateInterval) - stmt.setInt(4, feed.maxItemAge) - stmt.setInt(5, feed.itemStateMode) - stmt.setString(6, feed.addUrlParam) - stmt.setInt(7, feed.id) + stmt.setString(1, feed.name) + stmt.setString(2, feed.uri) + stmt.setString(3, feed.user) + stmt.setString(4, feed.password) + stmt.setBoolean(5, feed.internalBrowser) + stmt.setLong(6, feed.updateInterval) + stmt.setInt(7, feed.maxItemAge) + stmt.setInt(8, feed.itemStateMode) + stmt.setInt(9, feed.id) stmt.execute() } - - var updateList = true - // check if the old and new list only contain a single uri - if(uris.size == 1) { - conn.prepareStatement("select count(*) from feeds where feedcollection_id = ? and disabled = FALSE").use { stmt -> - stmt.setInt(1, feed.id) - stmt.executeQuery().use { rs -> - if(rs.next() && rs.getInt(1) == 1) { - updateList = false - } - } - } - } - - if(updateList) { - // disable all feeds first and then re-activate all feeds from the uri list - conn.prepareStatement(""" - update feeds set auth_user = ?, auth_password = ?, certpath = ?, disabled = TRUE - where feedcollection_id = ? - """.trimIndent()).use { stmt -> - stmt.setString(1, user) - stmt.setString(2, password) - stmt.setString(3, cert) - stmt.setInt(4, feed.id) - stmt.execute() - } - - // merge url list - uris.forEach { uri -> - conn.prepareStatement(""" - merge into feeds f - using (select cast(? as int) as feedcollection_id, cast(? as varchar) as url) v - on (f.feedcollection_id = v.feedcollection_id and f.url = v.url) - when matched then update set - f.disabled = false - when not matched then insert(feedcollection_id, url, auth_user, auth_password, certpath) - values (v.feedcollection_id, v.url, ?, ?, ?) - """.trimMargin()).use { stmt -> - stmt.setInt(1, feed.id) - stmt.setString(2, uri) - stmt.setString(3, user) - stmt.setString(4, password) - stmt.setString(5, cert) - stmt.execute() - } - } - } else { - // just update the single feed - conn.prepareStatement(""" - update feeds set - url = ?, - auth_user = ?, - auth_password = ?, - certpath = ? - where feedcollection_id = ? - """.trimIndent()).use { stmt -> - stmt.setString(1, uris.first()) - stmt.setString(2, user) - stmt.setString(3, password) - stmt.setString(4, cert) - stmt.setInt(5, feed.id) - stmt.execute() - } - } } } - public fun getItems(feedCollection: FeedCollection, maxItems: Int) : MutableList { + public fun getItems(feed: Feed, maxItems: Int) : MutableList { val items = mutableListOf() dataSource.connection.use { conn -> conn.prepareStatement(""" select I.*, F.URL from items I inner join feeds F on I.feed_id = F.feed_id - where F.feedcollection_id = ? order by pub_date desc limit ? + where F.feed_id = ? order by pub_date desc limit ? """.trimIndent()).use { stmt -> - stmt.setInt(1, feedCollection.id) + stmt.setInt(1, feed.id) stmt.setInt(2, maxItems) stmt.executeQuery().use { rs -> while(rs.next()) { @@ -401,11 +327,11 @@ object Database { item.guid = rs.getString("guid") item.contentText = rs.getString("contentText") item.contentHtml = rs.getString("contentHTML") - item.feedName = feedCollection.name + item.feedName = feed.name item.feedUrl = rs.getString("URL") item.isRead = rs.getBoolean("is_read") item.isBookmark = rs.getBoolean("is_bookmarked") - item.collection = feedCollection + item.collection = feed items.add(item) } } @@ -424,12 +350,12 @@ object Database { stmt.executeQuery().use { rs -> while(rs.next()) { val id = rs.getInt("feed_id") - val feedCollectionId = rs.getInt("feedcollection_id") + val name = rs.getString("name") val url = rs.getString("url") val authUser = rs.getString("auth_user") val authPassword = rs.getString("auth_password") val certPath = rs.getString("certpath") - val feed = Feed(id, feedCollectionId, url) + val feed = Feed(id, name, url) feed.user = authUser feed.password = authPassword feed.certpath = certPath @@ -442,53 +368,53 @@ object Database { return feeds } - public fun getCollectionFeeds(feed: FeedCollection) : MutableList { - val feeds = mutableListOf() + public fun getFeed(id: Int) : Feed? { + var feed: Feed? = null; dataSource.connection.use { conn -> conn.prepareStatement(""" - select * from feeds where feedcollection_id = ? and disabled = FALSE + select * from feeds where feed_id = ? and disabled = FALSE """.trimIndent()).use { stmt -> - stmt.setInt(1, feed.id) + stmt.setInt(1, id) stmt.executeQuery().use { rs -> while(rs.next()) { val id = rs.getInt("feed_id") - val feedCollectionId = rs.getInt("feedcollection_id") + val name = rs.getString("name") val url = rs.getString("url") val authUser = rs.getString("auth_user") val authPassword = rs.getString("auth_password") val certPath = rs.getString("certpath") - val feed = Feed(id, feedCollectionId, url) + feed = Feed(id, name, url) feed.user = authUser feed.password = authPassword feed.certpath = certPath - feeds.add(feed) + break } } } } - return feeds + return feed } + public fun getGroupFeeds(group: FeedGroup) : MutableList { val feeds = mutableListOf() dataSource.connection.use { conn -> conn.prepareStatement(""" - select f.* from feeds f - inner join feedcollections c on f.feedcollection_id = c.feedcollection_id - where c.group_id = ? and disabled = FALSE + select * from feeds + where group_id = ? and disabled = FALSE """.trimIndent()).use { stmt -> stmt.setInt(1, group.id) stmt.executeQuery().use { rs -> while(rs.next()) { val id = rs.getInt("feed_id") - val feedCollectionId = rs.getInt("feedcollection_id") + val name = rs.getString("name") val url = rs.getString("url") val authUser = rs.getString("auth_user") val authPassword = rs.getString("auth_password") val certPath = rs.getString("certpath") - val feed = Feed(id, feedCollectionId, url) + val feed = Feed(id, name, url) feed.user = authUser feed.password = authPassword feed.certpath = certPath @@ -500,12 +426,12 @@ object Database { return feeds } - public fun deleteFeedCollection(feedCollection: FeedCollection) { + public fun deleteFeed(feed: Feed) { dataSource.connection.use { conn -> conn.prepareStatement(""" - delete from feedcollections where feedcollection_id = ? + delete from feeds where feed_id = ? """.trimIndent()).use { stmt -> - stmt.setInt(1, feedCollection.id) + stmt.setInt(1, feed.id) stmt.execute() } } @@ -522,11 +448,11 @@ object Database { } } - public fun moveFeedCollections(from: FeedGroup, to: FeedGroup) { + public fun moveFeeds(from: FeedGroup, to: FeedGroup) { dataSource.connection.use { conn -> // move conn.prepareStatement(""" - update feedcollections set group_id = ? where group_id = ? + update feeds set group_id = ? where group_id = ? """.trimIndent()).use { stmt -> stmt.setInt(1, to.id) stmt.setInt(2, from.id) @@ -540,21 +466,20 @@ object Database { dataSource.connection.use { conn -> conn.prepareStatement(""" - select f.* from feeds f - inner join feedcollections c on f.feedcollection_id = c.feedcollection_id - where datediff(ss, coalesce(last_update, '1970-01-01'), now()) + 45 > case when c.update_interval > 0 then c.update_interval else ? end + select * from feeds + where datediff(ss, coalesce(last_update, '1970-01-01'), now()) + 45 > case when update_interval > 0 then update_interval else ? end and disabled = FALSE """.trimIndent()).use { stmt -> stmt.setInt(1, defaultInterval) stmt.executeQuery().use { rs -> while(rs.next()) { val id = rs.getInt("feed_id") - val feedCollectionId = rs.getInt("feedcollection_id") + val name = rs.getString("name") val url = rs.getString("url") val authUser = rs.getString("auth_user") val authPassword = rs.getString("auth_password") val certPath = rs.getString("certpath") - val feed = Feed(id, feedCollectionId, url) + val feed = Feed(id, name, url) feed.user = authUser feed.password = authPassword feed.certpath = certPath @@ -631,13 +556,13 @@ object Database { } } - public fun updateFeedReadState(feedCollection: FeedCollection, read: Boolean) { + public fun updateFeedReadState(feed: Feed, read: Boolean) { dataSource.connection.use { conn -> conn.prepareStatement(""" - update items set is_read = ? where feed_id in (select feed_id from feeds where feedcollection_id = ?) + update items set is_read = ? where feed_id = ? """.trimIndent()).use { stmt -> stmt.setBoolean(1, read) - stmt.setInt(2, feedCollection.id) + stmt.setInt(2, feed.id) stmt.execute() } } @@ -648,7 +573,6 @@ object Database { conn.prepareStatement(""" update items set is_read = ? where feed_id in ( select feed_id from feeds f - inner join feedcollections c on f.feedcollection_id = c.feedcollection_id where group_id = ?) """.trimIndent()).use { stmt -> stmt.setBoolean(1, read) @@ -674,9 +598,8 @@ object Database { dataSource.connection.use { conn -> conn.prepareStatement(""" select - datediff(ss, now(), min(dateadd(ss, case when c.update_interval = 0 then ? else c.update_interval end, coalesce(last_update, '1970-01-01')))) as next_update_in - from feeds f - inner join feedcollections c on f.feedcollection_id = c.feedcollection_id; + datediff(ss, now(), min(dateadd(ss, case when update_interval = 0 then ? else update_interval end, coalesce(last_update, '1970-01-01')))) as next_update_in + from feeds; """.trimIndent()).use { stmt -> stmt.setInt(1, defaultUpdateInterval) stmt.executeQuery().use { rs -> @@ -695,16 +618,15 @@ object Database { delete from items where item_id in ( select item_id from (select i.item_id, - c.name, + f.name, f.feed_id, - c.max_item_age, - datediff('dd', coalesce(updated, pub_date), now()) as age, - case when c.max_item_age > 0 then c.max_item_age else ? end as max_age + f.max_item_age, + datediff('dd', coalesce(updated, pub_date), now()) as age, + case when f.max_item_age > 0 then f.max_item_age else ? end as max_age from items i - inner join feeds f on i.feed_id = f.feed_id - inner join feedcollections c on f.feedcollection_id = c.feedcollection_id + inner join feeds f on i.feed_id = f.feed_id where i.is_bookmarked = false - and c.max_item_age >= 0) + and f.max_item_age >= 0) where max_age > 0 and age > max_age ) """.trimIndent()).use { stmt -> diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/Feed.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/Feed.kt index e952d26..3ec5dff 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/Feed.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/Feed.kt @@ -3,12 +3,34 @@ package de.unixwork.rssreader import java.time.Instant -class Feed(id: Int, feedCollectionId: Int, uri: String) { +class Feed(id: Int, name: String, uri: String) { val id = id - val feedCollectionId = feedCollectionId + var name = name val uri = uri var user: String? = null var password: String? = null var certpath: String? = null + + var items = mutableListOf() + + var updateInterval: Long = 0 + var itemStateMode = 0 + var unreadItemsCount = 0 + var internalBrowser = false + var maxItemAge = 0 + + var itemsLoaded = false + var itemsLoading = false + + var addUrlParam: String? = null + var lastUpdate: Instant? = null + + // Is this FeedCollection actually a FeedGroup? + // In that case, id is the FeedGroup id + var isGroup = false + + fun updateReadStatus(isRead: Boolean) { + items.forEach { it.isRead = isRead } + } } diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedCollection.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedCollection.kt deleted file mode 100644 index a1ba7ed..0000000 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedCollection.kt +++ /dev/null @@ -1,27 +0,0 @@ -package de.unixwork.rssreader - -import de.unixwork.ui.Document - -class FeedCollection(id: Int, name: String) { - val id = id - var name = name - var updateInterval: Long = 0 - var itemStateMode = 0 - var unreadItemsCount = 0 - var internalBrowser = false - var maxItemAge = 0 - - var items = mutableListOf() - var itemsLoaded = false - var itemsLoading = false - - var addUrlParam: String? = null - - // Is this FeedCollection actually a FeedGroup? - // In that case, id is the FeedGroup id - var isGroup = false - - fun updateReadStatus(isRead: Boolean) { - items.forEach { it.isRead = isRead } - } -} \ No newline at end of file diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedConfig.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedConfig.kt index 6af8395..2094001 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedConfig.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedConfig.kt @@ -1,22 +1,19 @@ package de.unixwork.rssreader -import de.unixwork.ui.Text.passwordfield import de.unixwork.ui.UiObject import de.unixwork.ui.UiInteger import de.unixwork.ui.UiList import de.unixwork.ui.UiString -import de.unixwork.ui.UiText import de.unixwork.ui.kotlin.* -import de.unixwork.ui.kotlin.openFileDialog class FeedConfig(obj: UiObject) { val window = obj - var feedCollection: FeedCollection? = null + var feed: Feed? = null val groups: UiList val name: UiString - val urls: UiText + val uri: UiString val user: UiString val password: UiString val cert: UiString @@ -37,7 +34,7 @@ class FeedConfig(obj: UiObject) { init { groups = window.list() name = window.string() - urls = window.text() + uri = window.string() readstatus = window.list() user = window.string() password = window.string() @@ -82,8 +79,8 @@ class FeedConfig(obj: UiObject) { textfield(value = name, hexpand = true, colspan = 2) } row { - rlabel("URLs", overrideDefaults = true, hfill = true) // overrideDefaults for disabling default vfill - textarea(value = urls, hexpand = true, vexpand = true, vfill = true, colspan = 2, styleClass = "ui-entry-box") + rlabel("URI") + textfield(value = uri, hexpand = true, colspan = 2) } } } @@ -158,10 +155,10 @@ class FeedConfig(obj: UiObject) { groups.selectedIndex = groups.indexOf(it) } - feedCollection?.let { initUI(it) } + feed?.let { initUI(it) } } - private fun initUI(feed: FeedCollection) { + private fun initUI(feed: Feed) { name.setString(feed.name) readstatus.selectedIndex = feed.itemStateMode when(feed.maxItemAge) { @@ -186,27 +183,26 @@ class FeedConfig(obj: UiObject) { maxItemAge.setIntValue(feed.maxItemAge) } - val feeds = Database.getCollectionFeeds(feed) - val uris = feeds.map { it.uri }.joinToString("\n") + uri.setString(feed.uri) - urls.setText(uris) - - if(feeds.isNotEmpty()) { - user.setString(feeds[0].user) - password.setString(feeds[0].password) - } + user.setString(feed.user) + password.setString(feed.password) } - fun addFeed() { + fun addFeed() : Boolean { val parent = groups.selected val feedName = name.toString() - val urlStr = urls.toString() - val uris = urlStr.split("\n").map { it.trim() }.filter { it.isNotBlank() } + val uri = uri.toString() var itemStateMode = readstatus.selectedIndex val internalBrowser = itemContent.selectedIndex == 1 var autoDelete = autoDeleteOptions.selectedIndex var maxItemAge = maxItemAge.intValue() var updateIntv = updateInterval.longValue() + + if(feedName.isBlank()) { + return false + } + if(!customUpdateInterval.booleanValue()) { updateIntv = 0 } @@ -220,7 +216,7 @@ class FeedConfig(obj: UiObject) { if(itemStateMode < 0 || itemStateMode > 2) { itemStateMode = 0 } - println("groupSel: ${groups.selectedIndex}, feedName: $feedName, urlStr: $urlStr") + println("groupSel: ${groups.selectedIndex}, feedName: $feedName, uri: $uri") var u:String? = user.toString() var p:String? = password.toString() @@ -233,10 +229,10 @@ class FeedConfig(obj: UiObject) { parent?.let { FeedConfig.PreviousGroup = it try { - val feedCol = Database.newFeeds( + val feedCol = Database.newFeed( parent = it, name = feedName, - uris = uris, + uri = uri, user = u, password = p, cert = null, //cert.toString(), @@ -254,11 +250,13 @@ class FeedConfig(obj: UiObject) { e.printStackTrace() } } + + return true } public fun updateFeed() { val feedName = name.toString() - val urlStr = urls.toString() + val urlStr = uri.toString() val uris = urlStr.split("\n").map { it.trim() }.filter { it.isNotBlank() } var itemStateMode = readstatus.selectedIndex val internalBrowser = itemContent.selectedIndex == 1 @@ -289,14 +287,16 @@ class FeedConfig(obj: UiObject) { p = null } - feedCollection?.let { + feed?.let { it.name = feedName it.updateInterval = updateIntv it.itemStateMode = itemStateMode it.internalBrowser = internalBrowser it.maxItemAge = maxItemAge + it.user = u + it.password = p try { - Database.updateFeedCollection(it, uris, u, p, null) + Database.updateFeed(it) } catch (e: Exception) { e.printStackTrace() } diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedGroup.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedGroup.kt index f9294fb..2be40b2 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedGroup.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedGroup.kt @@ -5,5 +5,5 @@ import de.unixwork.ui.Context class FeedGroup(context: Context, id: Int, name: String) { val id = id val name: String = name - val feeds = context.list() + val feeds = context.list() } \ No newline at end of file diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedList.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedList.kt index 98ee71a..0053a65 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedList.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedList.kt @@ -29,12 +29,12 @@ class FeedList(window: MainWindow) : Document() { val filter = integer("filter") // Feed that is currently shown - var currentFeed: FeedCollection? = null + var currentFeed: Feed? = null var currentItem: Item? = null // Currently requested feed - var showFeed: FeedCollection? = null + var showFeed: Feed? = null - fun loadFeed(feed: FeedCollection) { + fun loadFeed(feed: Feed) { if(feed.itemStateMode > 0 && feed.unreadItemsCount > 0) { // Only reset the unread counter if the feed is not already opened // This is necessary to have a reliable counter in the sourcelist after a sync job finishes @@ -95,7 +95,7 @@ class FeedList(window: MainWindow) : Document() { } } - val collection = FeedCollection(group.id, "") + val collection = Feed(group.id, "", "") collection.isGroup = true showFeed = collection diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt index 0e479a6..292d364 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/FeedSourceList.kt @@ -5,7 +5,6 @@ import de.unixwork.ui.SubList import de.unixwork.ui.kotlin.ToolkitDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.IO import kotlinx.coroutines.launch class FeedSourceList : Document() { @@ -15,7 +14,7 @@ class FeedSourceList : Document() { init { groups = Database.getFeedTree(this) groups.forEach { - val sublist = SubList() + val sublist = SubList() sublist.header = it.name sublist.value = it.feeds feeds.add(sublist) @@ -23,7 +22,7 @@ class FeedSourceList : Document() { } fun addFeedGroup(group: FeedGroup) { - val sublist = SubList() + val sublist = SubList() sublist.header = group.name sublist.value = group.feeds feeds.add(sublist) @@ -61,7 +60,7 @@ class FeedSourceList : Document() { } GlobalScope.launch(Dispatchers.IO) { - Database.swapFeedCollectionPos(f1, f2) + Database.swapFeedPos(f1, f2) } } @@ -107,7 +106,7 @@ class FeedSourceList : Document() { // get the current feed tree val groupUpdate = Database.getFeedTree(this@FeedSourceList) // create a map that contains all feed collections - val index = mutableMapOf() + val index = mutableMapOf() groupUpdate.forEach { it.feeds.forEach { feed -> index[feed.id] = feed diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/Item.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/Item.kt index b70bd0d..3e67e33 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/Item.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/Item.kt @@ -24,7 +24,7 @@ class Item(id: Int) { val date: Instant? get() = updated ?: pubDate - var collection: FeedCollection? = null + var collection: Feed? = null fun getContent(): Content { contentHtml?.let { diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt index 673b88b..acc616c 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/MainWindow.kt @@ -61,7 +61,8 @@ class MainWindow() { if(evt.sublistIndex >= 0) { SyncJob({ if(feedIndex >= 0) { - Database.getCollectionFeeds(sourceList.groups[evt.sublistIndex].feeds[feedIndex]) + val feed = Database.getFeed(sourceList.groups[evt.sublistIndex].feeds[feedIndex].id) + feed?.let { mutableListOf(it)} ?: mutableListOf() } else { Database.getGroupFeeds(sourceList.groups[evt.sublistIndex]) } @@ -74,7 +75,7 @@ class MainWindow() { val evt = event.subListEventData val feedIndex = evt.rowIndex if(evt.sublistIndex >= 0) { - var feeds:List = sourceList.groups[evt.sublistIndex].feeds + var feeds:List = sourceList.groups[evt.sublistIndex].feeds if(feedIndex >= 0) { feeds = listOf(sourceList.groups[evt.sublistIndex].feeds[feedIndex]) } @@ -125,7 +126,7 @@ class MainWindow() { { event -> if(event.intValue == 2) { GlobalScope.launch(Dispatchers.IO) { - Database.deleteFeedCollection(feedCollection) + Database.deleteFeed(feedCollection) } sourceList.groups[evt.sublistIndex].feeds.remove(feedCollection) sourceList.groups[evt.sublistIndex].feeds.update() @@ -151,7 +152,7 @@ class MainWindow() { GlobalScope.launch(Dispatchers.IO) { if(move!!.booleanValue() && groups!!.selected != null) { // move and delete - Database.moveFeedCollections(feedGroup, groups!!.selected) + Database.moveFeeds(feedGroup, groups!!.selected) } Database.deleteFeedGroup(feedGroup) } @@ -227,7 +228,7 @@ class MainWindow() { } } ) - { elm: FeedCollection?, i, sublist -> + { elm: Feed?, i, sublist -> val item = SubListItem() item.buttonIcon = "view-more" item.buttonMenu = sidebarContextMenu @@ -384,7 +385,9 @@ class MainWindow() { height = 450, onClick = { ev -> if(ev.intValue == 4) { - feedConfig?.addFeed() + if(feedConfig?.addFeed() == false) { + return@dialogWindow + } } ev.`object`.close() }, @@ -446,7 +449,7 @@ class MainWindow() { window.show() } - fun editFeedDialog(collection: FeedCollection) { + fun editFeedDialog(collection: Feed) { var feedConfig: FeedConfig? = null val w = dialogWindow( parent = window, @@ -467,7 +470,7 @@ class MainWindow() { }, ui = null) feedConfig = FeedConfig(w) - feedConfig.feedCollection = collection + feedConfig.feed = collection feedConfig.createUI() w.show() } -- 2.47.3