diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 31704d1d..fbec6134 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -135,7 +135,6 @@ dependencies { implementation(project(":owncloud")) implementation(project(":permissions")) implementation(project(":preferences")) - implementation(project(":rssparser")) implementation(project(":search")) implementation(project(":transition")) implementation(project(":unitconverter")) diff --git a/database/schemas/de.mm20.launcher2.database.AppDatabase/14.json b/database/schemas/de.mm20.launcher2.database.AppDatabase/14.json index 111bb63d..a80330c7 100644 --- a/database/schemas/de.mm20.launcher2.database.AppDatabase/14.json +++ b/database/schemas/de.mm20.launcher2.database.AppDatabase/14.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 14, - "identityHash": "89c214d548f80f5c25612f5e6ebf9725", + "identityHash": "7e492b4e6f9b150fd7a36e3e028650e8", "entities": [ { "tableName": "forecasts", @@ -346,39 +346,6 @@ "indices": [], "foreignKeys": [] }, - { - "tableName": "Plugin", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`packageName` TEXT NOT NULL, `data` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`packageName`, `data`))", - "fields": [ - { - "fieldPath": "packageName", - "columnName": "packageName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "packageName", - "data" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, { "tableName": "Widget", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` TEXT NOT NULL, `data` TEXT NOT NULL, `height` INTEGER NOT NULL, `position` INTEGER NOT NULL, `label` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)", @@ -433,7 +400,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '89c214d548f80f5c25612f5e6ebf9725')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7e492b4e6f9b150fd7a36e3e028650e8')" ] } } \ No newline at end of file diff --git a/database/schemas/de.mm20.launcher2.database.AppDatabase/15.json b/database/schemas/de.mm20.launcher2.database.AppDatabase/15.json new file mode 100644 index 00000000..62c8b7b4 --- /dev/null +++ b/database/schemas/de.mm20.launcher2.database.AppDatabase/15.json @@ -0,0 +1,406 @@ +{ + "formatVersion": 1, + "database": { + "version": 15, + "identityHash": "7e492b4e6f9b150fd7a36e3e028650e8", + "entities": [ + { + "tableName": "forecasts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timestamp` INTEGER NOT NULL, `temperature` REAL NOT NULL, `minTemp` REAL NOT NULL, `maxTemp` REAL NOT NULL, `pressure` REAL NOT NULL, `humidity` REAL NOT NULL, `icon` INTEGER NOT NULL, `condition` TEXT NOT NULL, `clouds` INTEGER NOT NULL, `windSpeed` REAL NOT NULL, `windDirection` REAL NOT NULL, `rain` REAL NOT NULL, `snow` REAL NOT NULL, `night` INTEGER NOT NULL, `location` TEXT NOT NULL, `provider` TEXT NOT NULL, `providerUrl` TEXT NOT NULL, `rainProbability` INTEGER NOT NULL, `snowProbability` INTEGER NOT NULL, `updateTime` INTEGER NOT NULL, PRIMARY KEY(`timestamp`))", + "fields": [ + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "temperature", + "columnName": "temperature", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "minTemp", + "columnName": "minTemp", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "maxTemp", + "columnName": "maxTemp", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "pressure", + "columnName": "pressure", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "humidity", + "columnName": "humidity", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "condition", + "columnName": "condition", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "clouds", + "columnName": "clouds", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "windSpeed", + "columnName": "windSpeed", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "windDirection", + "columnName": "windDirection", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "precipitation", + "columnName": "rain", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "snow", + "columnName": "snow", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "night", + "columnName": "night", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "location", + "columnName": "location", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "provider", + "columnName": "provider", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "providerUrl", + "columnName": "providerUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "precipProbability", + "columnName": "rainProbability", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "snowProbability", + "columnName": "snowProbability", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "updateTime", + "columnName": "updateTime", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "timestamp" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Searchable", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `searchable` TEXT NOT NULL, `launchCount` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `hidden` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "serializedSearchable", + "columnName": "searchable", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "launchCount", + "columnName": "launchCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pinPosition", + "columnName": "pinned", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hidden", + "columnName": "hidden", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Websearch", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`urlTemplate` TEXT NOT NULL, `label` TEXT NOT NULL, `color` INTEGER NOT NULL, `icon` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT)", + "fields": [ + { + "fieldPath": "urlTemplate", + "columnName": "urlTemplate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Currency", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`symbol` TEXT NOT NULL, `value` REAL NOT NULL, `lastUpdate` INTEGER NOT NULL, PRIMARY KEY(`symbol`))", + "fields": [ + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "lastUpdate", + "columnName": "lastUpdate", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "symbol" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Icons", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` TEXT NOT NULL, `componentName` TEXT, `drawable` TEXT, `iconPack` TEXT NOT NULL, `scale` REAL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)", + "fields": [ + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "componentName", + "columnName": "componentName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "drawable", + "columnName": "drawable", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "iconPack", + "columnName": "iconPack", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "scale", + "columnName": "scale", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "IconPack", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `packageName` TEXT NOT NULL, `version` TEXT NOT NULL, `scale` REAL NOT NULL, PRIMARY KEY(`packageName`))", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "packageName", + "columnName": "packageName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "scale", + "columnName": "scale", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "packageName" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Widget", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` TEXT NOT NULL, `data` TEXT NOT NULL, `height` INTEGER NOT NULL, `position` INTEGER NOT NULL, `label` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)", + "fields": [ + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "height", + "columnName": "height", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7e492b4e6f9b150fd7a36e3e028650e8')" + ] + } +} \ No newline at end of file diff --git a/database/src/main/java/de/mm20/launcher2/database/AppDatabase.kt b/database/src/main/java/de/mm20/launcher2/database/AppDatabase.kt index 67cc6f7e..5088bb12 100644 --- a/database/src/main/java/de/mm20/launcher2/database/AppDatabase.kt +++ b/database/src/main/java/de/mm20/launcher2/database/AppDatabase.kt @@ -15,8 +15,7 @@ import de.mm20.launcher2.database.entities.* CurrencyEntity::class, IconEntity::class, IconPackEntity::class, - PluginEntity::class, - WidgetEntity::class], version = 14, exportSchema = true) + WidgetEntity::class], version = 15, exportSchema = true) @TypeConverters(ComponentNameConverter::class, StringListConverter::class) abstract class AppDatabase : RoomDatabase() { @@ -54,7 +53,8 @@ abstract class AppDatabase : RoomDatabase() { Migration_10_11(), Migration_11_12(), Migration_12_13(), - Migration_13_14() + Migration_13_14(), + Migration_14_15() ).build() if (_instance == null) _instance = instance return instance @@ -143,5 +143,8 @@ class Migration_13_14 : Migration(13, 14) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("DROP TABLE IF EXISTS `Plugins`;") } - +} +class Migration_14_15 : Migration(14, 15) { + override fun migrate(database: SupportSQLiteDatabase) { + } } \ No newline at end of file diff --git a/database/src/main/java/de/mm20/launcher2/database/entities/PluginEntity.kt b/database/src/main/java/de/mm20/launcher2/database/entities/PluginEntity.kt deleted file mode 100644 index f43e7188..00000000 --- a/database/src/main/java/de/mm20/launcher2/database/entities/PluginEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package de.mm20.launcher2.database.entities - -import androidx.room.Entity - -@Entity(tableName = "Plugin", primaryKeys = ["packageName", "data"]) -data class PluginEntity( - val packageName: String, - val data: String, - val type: String -) \ No newline at end of file diff --git a/rssparser/.gitignore b/rssparser/.gitignore deleted file mode 100644 index 796b96d1..00000000 --- a/rssparser/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/rssparser/build.gradle.kts b/rssparser/build.gradle.kts deleted file mode 100644 index ced59f1b..00000000 --- a/rssparser/build.gradle.kts +++ /dev/null @@ -1,40 +0,0 @@ -plugins { - id("com.android.library") - id("kotlin-android") -} - -android { - compileSdk = sdk.versions.compileSdk.get().toInt() - - defaultConfig { - minSdk = sdk.versions.minSdk.get().toInt() - targetSdk = sdk.versions.targetSdk.get().toInt() - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = "1.8" - } -} - -dependencies { - implementation(libs.kotlin.stdlib) - implementation(libs.okhttp) -} diff --git a/rssparser/proguard-rules.pro b/rssparser/proguard-rules.pro deleted file mode 100644 index 2f9dc5a4..00000000 --- a/rssparser/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle.kts. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/rssparser/src/main/AndroidManifest.xml b/rssparser/src/main/AndroidManifest.xml deleted file mode 100644 index a0d58e07..00000000 --- a/rssparser/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/rssparser/src/main/java/de/mm20/rssparser/Article.kt b/rssparser/src/main/java/de/mm20/rssparser/Article.kt deleted file mode 100644 index a49b4bac..00000000 --- a/rssparser/src/main/java/de/mm20/rssparser/Article.kt +++ /dev/null @@ -1,52 +0,0 @@ -package de.mm20.rssparser - -/** - * Represents an of the RSS feed. - * A channel may contain any number of s. An item may represent a "story" -- much like a story - * in a newspaper or magazine; if so its description is a synopsis of the story, and the link points - * to the full story. An item may also be complete in itself, if so, the description contains the - * text (entity-encoded HTML is allowed), and the link and title may be omitted. All elements of an - * item are optional, however at least one of title or description must be present. - */ -data class Article( - /** - * The title of the item. - */ - val title: String, - /** - * The URL of the item. - */ - val link: String, - /** - * The item synopsis. - */ - val description: String, - /** - * Email address of the author of the item. - */ - val author: String?, - /** - * Includes the item in one or more categories. - */ - val categories: List, - /** - * URL of a page for comments relating to the item. - */ - val comments: String?, - /** - * Describes a media object that is attached to the item. - */ - val enclosure: String?, - /** - * A string that uniquely identifies the item. - */ - val guid: String?, - /** - * Indicates when the item was published. - */ - val pubDate: Long?, - /** - * The RSS channel that the item came from. - */ - val source: String? -) diff --git a/rssparser/src/main/java/de/mm20/rssparser/DayOfWeek.kt b/rssparser/src/main/java/de/mm20/rssparser/DayOfWeek.kt deleted file mode 100644 index 73cedba8..00000000 --- a/rssparser/src/main/java/de/mm20/rssparser/DayOfWeek.kt +++ /dev/null @@ -1,5 +0,0 @@ -package de.mm20.rssparser - -enum class DayOfWeek { - SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY -} diff --git a/rssparser/src/main/java/de/mm20/rssparser/Exceptions.kt b/rssparser/src/main/java/de/mm20/rssparser/Exceptions.kt deleted file mode 100644 index 8b42ae67..00000000 --- a/rssparser/src/main/java/de/mm20/rssparser/Exceptions.kt +++ /dev/null @@ -1,3 +0,0 @@ -package de.mm20.rssparser - -class InvalidFeedException(message: String? = null) : Exception(message) \ No newline at end of file diff --git a/rssparser/src/main/java/de/mm20/rssparser/FeedInfo.kt b/rssparser/src/main/java/de/mm20/rssparser/FeedInfo.kt deleted file mode 100644 index e6cbaa56..00000000 --- a/rssparser/src/main/java/de/mm20/rssparser/FeedInfo.kt +++ /dev/null @@ -1,84 +0,0 @@ -package de.mm20.rssparser - -data class FeedInfo( - /** - * The name of the channel. It's how people refer to your service. If you have an HTML - * website that contains the same information as your RSS file, the title of your channel - * should be the same as the title of your website. - */ - val title: String, - /** - * The URL to the HTML website corresponding to the channel. - */ - val link: String, - /** - * Phrase or sentence describing the channel. - */ - val description: String, - /** - * The language the channel is written in. This allows aggregators to group all Italian - * language sites, for example, on a single page. A list of allowable values for this - * element, as provided by Netscape, is - * [here](http://backend.userland.com/stories/storyReader$16). You may also use - * [values defined](http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes) by the - * W3C. - */ - val language: String?, - /** - * Copyright notice for content in the channel. - */ - val copyright: String?, - /** - * Email address for person responsible for editorial content. - */ - val managingEditor: String?, - /** - * Email address for person responsible for technical issues relating to channel. - */ - val webMaster: String?, - /** - * The publication date for the content in the channel. For example, the New York Times - * publishes on a daily basis, the publication date flips once every 24 hours. That's when - * the pubDate of the channel changes. - */ - val pubDate: Long?, - /** - * The last time the content of the channel changed. - */ - val lastBuildDate: Long?, - /** - * Specify one or more categories that the channel belongs to. - */ - val category: List, - /** - * A string indicating the program used to generate the channel. - */ - val generator: String?, - /** - * A URL that points to the documentation for the format used in the RSS file. It's probably - * a pointer to [this page](https://validator.w3.org/feed/docs/rss2.html). It's for people - * who might stumble across an RSS file on a Web server 25 years from now and wonder what it - * is. - */ - val docs: String?, - /** - * ttl stands for time to live. It's a number of minutes that indicates how long a channel - * can be cached before refreshing from the source. More info - * [here](https://validator.w3.org/feed/docs/rss2.html#ltttlgtSubelementOfLtchannelgt). - */ - val ttl: Int?, - /** - * Specifies a GIF, JPEG or PNG image that can be displayed with the channel. - */ - val image: String?, - /** - * A hint for aggregators telling them which hours they can skip. More info - * [here](http://backend.userland.com/skipHoursDays#skiphours). - */ - val skipHours: List, - /** - * A hint for aggregators telling them which days they can skip. More info - * [here](http://backend.userland.com/skipHoursDays#skipdays). - */ - val skipDays: List -) \ No newline at end of file diff --git a/rssparser/src/main/java/de/mm20/rssparser/RssParser.kt b/rssparser/src/main/java/de/mm20/rssparser/RssParser.kt deleted file mode 100644 index 6bf8f0d9..00000000 --- a/rssparser/src/main/java/de/mm20/rssparser/RssParser.kt +++ /dev/null @@ -1,133 +0,0 @@ -package de.mm20.rssparser - -import okhttp3.OkHttpClient -import okhttp3.Request -import org.w3c.dom.Element -import org.xml.sax.SAXException -import java.io.IOException -import java.text.ParseException -import java.text.SimpleDateFormat -import java.util.* -import javax.xml.parsers.DocumentBuilderFactory - -class RssParser( - var url: String -) { - - lateinit var articles: List
- private set - - lateinit var feedInfo: FeedInfo - private set - - /** - * Fetches the feed from server and parses it. - * Do not call this in main thread. - * After this you can access [feedInfo] and [articles] - * @return the list of articles in that RSS feed - * @throws InvalidFeedException if the url does not point to a valid RSS2.0 feed - * @throws java.io.IOException if the feed url does not exist or there was an error downloading it - */ - @Throws(InvalidFeedException::class, IOException::class) - fun loadFeed() { - val articles = mutableListOf
() - try { - val request = Request.Builder().url(url).build() - val client = OkHttpClient() - val feedStream = client.newCall(request).execute().body?.byteStream() - ?: throw IOException() - val document = DocumentBuilderFactory - .newInstance() - .newDocumentBuilder() - .parse(feedStream) - - val rootElement = document.documentElement - - if (rootElement.tagName != "rss" || rootElement.getAttribute("version") != "2.0") { - throw InvalidFeedException("Document is not an RSS 2.0 feed") - } - val dateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ROOT) - feedInfo = FeedInfo( - title = document.getElementsByTagName("title").item(0)?.textContent ?: url, - link = document.getElementsByTagName("link").item(0)?.textContent ?: url, - description = document.getElementsByTagName("description").item(0)?.textContent - ?: "", - language = document.getElementsByTagName("language").item(0)?.textContent, - copyright = document.getElementsByTagName("copyright").item(0)?.textContent, - managingEditor = document.getElementsByTagName("managingEditor").item(0)?.textContent, - webMaster = document.getElementsByTagName("webMaster").item(0)?.textContent, - pubDate = parseDate(document.getElementsByTagName("pubDate") - .item(0)?.textContent ?: "", dateFormat), - lastBuildDate = parseDate(document.getElementsByTagName("lastBuildDate") - .item(0)?.textContent ?: "", dateFormat), - category = document.getElementsByTagName("category").run { - (0 until length).mapNotNull { item(it).textContent } - }, - generator = document.getElementsByTagName("generator").item(0)?.textContent, - docs = document.getElementsByTagName("docs").item(0)?.textContent, - ttl = document.getElementsByTagName("generator").item(0)?.textContent?.toIntOrNull(), - image = (document.getElementsByTagName("image") - .item(0)as? Element) - ?.getElementsByTagName("url") - ?.item(0)?.textContent, - skipHours = (document.getElementsByTagName("skipHours") as? Element) - ?.getElementsByTagName("hour")?.run { - (0 until length).mapNotNull { item(it)?.textContent?.toIntOrNull() } - } ?: emptyList(), - skipDays = (document.getElementsByTagName("skipDays") as? Element) - ?.getElementsByTagName("day")?.run { - (0 until length).mapNotNull { getWeekday(item(it)?.textContent) } - } ?: emptyList() - ) - val items = document.getElementsByTagName("item") - - for (i in 0 until items.length) { - val item = items.item(i) as? Element ?: continue - val article = Article( - title = item.getElementsByTagName("title").item(0)?.textContent ?: continue, - link = item.getElementsByTagName("link").item(0)?.textContent ?: "", - description = item.getElementsByTagName("description").item(0)?.textContent - ?: "", - author = item.getElementsByTagName("author").item(0)?.textContent, - categories = document.getElementsByTagName("category").run { - (0 until length).mapNotNull { item(it).textContent } - }, - comments = item.getElementsByTagName("comments").item(0)?.textContent, - enclosure = item.getElementsByTagName("enclosure").item(0)?.textContent, - guid = item.getElementsByTagName("guid").item(0)?.textContent, - pubDate = parseDate(item.getElementsByTagName("pubDate").item(0)?.textContent - ?: "", dateFormat), - source = item.getElementsByTagName("source").item(0)?.textContent - ) - articles.add(article) - } - - } catch (e: SAXException) { - throw InvalidFeedException() - } catch (e: IOException) { - throw IOException(e) - } - this.articles = articles - } - - private fun parseDate(date: String, dateFormat: SimpleDateFormat): Long? { - return try { - dateFormat.parse(date)?.time - } catch (e: ParseException) { - null - } - } - - private fun getWeekday(day: String?): DayOfWeek? { - return when (day) { - "Sunday" -> DayOfWeek.SUNDAY - "Monday" -> DayOfWeek.MONDAY - "Tuesday" -> DayOfWeek.TUESDAY - "Wednesday" -> DayOfWeek.WEDNESDAY - "Thursday" -> DayOfWeek.SATURDAY - "Friday" -> DayOfWeek.FRIDAY - "Saturday" -> DayOfWeek.SATURDAY - else -> null - } - } -} \ No newline at end of file diff --git a/rssparser/src/main/res/values/strings.xml b/rssparser/src/main/res/values/strings.xml deleted file mode 100644 index 33be6f21..00000000 --- a/rssparser/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - RSSParser - diff --git a/settings.gradle.kts b/settings.gradle.kts index ce12d11e..c99d48f8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,7 +30,6 @@ include(":i18n") include(":database") include(":ktx") include(":app") -include(":rssparser") include(":permissions") include(":ui") include(":compat")