diff --git a/.github/workflows/assemble-test-lint.yml b/.github/workflows/assemble-test-lint.yml index 26a84ca156..02fcec2309 100644 --- a/.github/workflows/assemble-test-lint.yml +++ b/.github/workflows/assemble-test-lint.yml @@ -21,11 +21,11 @@ jobs: steps: - name: Check out - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - name: Set up JDK 17 - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set up JDK 21 + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: - java-version: '17' + java-version: '21' distribution: 'temurin' cache: gradle @@ -53,11 +53,11 @@ jobs: steps: - name: Check out - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - name: Set up JDK 17 - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set up JDK 21 + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: - java-version: '17' + java-version: '21' distribution: 'temurin' cache: gradle @@ -73,7 +73,7 @@ jobs: run: ./gradlew :app:lintAmazonRelease - name: Upload lint reports - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 if: ${{ always() }} # also upload of lint errors with: name: Lint reports diff --git a/.gitignore b/.gitignore index b758183295..df1056c0cc 100644 --- a/.gitignore +++ b/.gitignore @@ -41,12 +41,16 @@ $RECYCLE.BIN/ !.idea/codeStyleSettings.xml !.idea/codeStyles !.idea/copyright +!.idea/inspectionProfiles !.idea/scopes ### Gradle .gradle/ build/ +## Kotlin +.kotlin/ + ## Proguard unused.txt diff --git a/.idea/inspectionProfiles/Android_Lint.xml b/.idea/inspectionProfiles/Android_Lint.xml new file mode 100644 index 0000000000..8d350b24dd --- /dev/null +++ b/.idea/inspectionProfiles/Android_Lint.xml @@ -0,0 +1,1004 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000..5b8a5a9b9e --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,73 @@ + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e07e54b8c9..3976f81541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,47 @@ 📝 = Notable change. Releases marked with 🧪 (or previously with the "beta" suffix) were released on -[the beta program](https://github.com/UweTrottmann/SeriesGuide/wiki/Beta) only. +[the preview program](https://www.seriesgui.de/help/how-to/basics/preview) only. + +## Version 2024.5 + +* 🌟 Shows: add a note to a show, synced with SeriesGuide Cloud or Trakt (VIP only). +* 🌟 Movies: add link to all release dates. +* 🔧 Shows: increase resolution of episode images. + +### 2024.5.4 - 2024-12-13 + +* 🔨 Trakt: retry if show not yet in Trakt profile failed to upload during initial sync. +* 📝 Latest user interface translations from Crowdin. + +### 2024.5.3 - 2024-12-11 🧪 + +* 🔧 Shows: revert to search symbol for primary button on discover screen. +* 🔧 Lists: ask for confirmation before deleting a list, actually call it delete instead of "just" + remove. +* 📝 Latest user interface translations from Crowdin. + +### 2024.5.2 - 2024-12-04 🧪 + +* 🔧 Shows: when viewing the stream or purchase provider filters, the reset button is shown as + disabled when no provider is selected. Also tabs are renamed and display icons to differentiate + filter from sort options. +* 🔨 Show scrollbars for show filter and sort options. +* 🔧 Use common "Sort by" action name. +* 🔧 Android 15: turn predictive back animation back on after more issues are resolved. +* 📝 Latest user interface translations from Crowdin. + +### 2024.5.1 - 2024-11-21 🧪 + +* 🌟 Shows: add a note to a show, synced with SeriesGuide Cloud or Trakt (VIP only). +* 🔧 Shows: increase resolution of episode images. +* 🔧 Shows: also use plus symbol for button on discover screen to be consistent. + +### 2024.5.0 - 2024-11-06 🧪 + +* 🌟 Movies: add link to all release dates. +* 🔧 Overview: use local number format for absolute episode number. +* 📝 Latest user interface translations from Crowdin. ## Version 2024.4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d11f86b33..7cf88e4dc7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,32 @@ # Contributing -**Note:** This work is licensed under the [Apache License 2.0](LICENSE.txt). -If you contribute any +ℹ️ This work is licensed under the [Apache License 2.0](LICENSE.txt). +If you contribute any [non-trivial](http://www.gnu.org/prep/maintain/maintain.html#Legally-Significant) patches or translations make sure you have read it and agree with it. -#### Would you like to contribute code? +**Would you like to contribute code?** + +ℹ️ If you want to contribute larger changes, please talk to me first (comment on a related issue +or create one). Otherwise, it is likely I won't accept your merge request. 1. [Fork SeriesGuide](https://github.com/UweTrottmann/SeriesGuide/fork) and clone your fork. -2. See the notes about [building](#building) the app below. +2. See the notes about [building](#building) the app below. Take the [guidelines of this project](/docs/guidelines.md) into account. 3. Create a new branch ([using GitHub](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/) or the command `git checkout -b descriptive-branch-name dev`). 4. Make [great commits](http://robots.thoughtbot.com/post/48933156625/5-useful-tips-for-a-better-commit-message). For non-trivial changes, add a copyright line at the top of the files you edited. 5. [Start a pull request](https://github.com/UweTrottmann/SeriesGuide/compare) and reference [issues](https://github.com/UweTrottmann/SeriesGuide/issues) if needed. -#### No code! -* You can [discuss or submit bug reports](https://github.com/UweTrottmann/SeriesGuide/issues). -* You can [suggest features](https://discuss.seriesgui.de). -* You can [translate the app](https://crowdin.com/project/seriesguide-translations). +**No code!** + +- You can [discuss or submit bug reports](https://github.com/UweTrottmann/SeriesGuide/issues). +- You can [suggest features](https://discuss.seriesgui.de). +- You can [translate the app](https://crowdin.com/project/seriesguide-translations). ## Building -- `dev` is the main development and [test release](https://github.com/UweTrottmann/SeriesGuide/wiki/Beta) branch. -- `main` has always the latest [stable version](https://seriesgui.de). +- `dev` contains the latest changes. +- `main` contains the latest stable version. To get started: @@ -34,20 +38,23 @@ To get started: Debug builds should just work. -### TMDB, trakt -To add shows or movies you need to create an API key for [TMDB](https://www.themoviedb.org/settings/api) -and OAuth credentials for [trakt](https://trakt.tv/oauth/applications). +### TMDB, Trakt + +To add shows or movies you need to create an API key for [TMDB](https://www.themoviedb.org/settings/api) +and OAuth credentials for [Trakt](https://trakt.tv/oauth/applications). Place them in `secret.properties` in the project directory (where `settings.gradle` is): -``` +```text SG_TMDB_API_KEY= SG_TRAKT_CLIENT_ID= SG_TRAKT_CLIENT_SECRET= ``` ### Release + To release some additional `secret.properties` values might be necessary: -``` + +```text # Play Store in-app billing public key SG_IAP_KEY_A= SG_IAP_KEY_B= diff --git a/README.md b/README.md index 6d1bb99144..2c5146a543 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,14 @@ Android app to help you keep track of your favorite TV shows and movies.

- Download • - Support the dev • + Download • + Support the devContributingAnnouncements & Help

- + diff --git a/RELEASING.md b/RELEASING.md index b83a2a5b01..9c1cfdaecf 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,12 +1,13 @@ # Release process -- If stable, create `release-` branch. If beta, stay on `dev`. -- Optional: Update translations. -- Change version code and name in [`build.gradle.kts`](/build.gradle.kts). -- Amend [`CHANGELOG.md`](/CHANGELOG.md). -- Deploy to test device. -- Push to GitHub and check build succeeds, tests are green and Lint file is OK. - +- If it does not exist, create a `release-` branch +- Merge latest changes from `dev` +- Optional: Update translations +- Change version code and name in [`build.gradle.kts`](/build.gradle.kts) +- Update [`CHANGELOG.md`](/CHANGELOG.md) +- Push to GitHub +- If it does not exist, create a merge request against `main` +- Check build succeeds, tests are green and lint output is as expected ## Play Store (testing + production) @@ -14,13 +15,14 @@ - Publish to alpha channel, test. Published to beta channel: + - Tag like `v12.0.3`. Published to production: -- Download universal APK from Play Store and attach to GitHub tag. +- Download universal APK from Play Store and attach to GitHub tag. -## Amazon App Store (stable only) +## Amazon App Store (production only) -- `assembleAmazonRelease` +- `bundleAmazonRelease` - Test update on test device. diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 78f8caf668..1c26a31191 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -11,6 +11,11 @@ val sgCompileSdk: Int by rootProject.extra val sgMinSdk: Int by rootProject.extra val sgTargetSdk: Int by rootProject.extra +tasks.withType(JavaCompile::class.java).configureEach { + // Suppress JDK 21 warning about deprecated, but not yet removed, source and target value 8 support + options.compilerArgs.add("-Xlint:-options") +} + android { namespace = "com.battlelancer.seriesguide.api" compileSdk = sgCompileSdk diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fc68ea694a..2b19970b07 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,6 +5,7 @@ plugins { id("com.android.application") kotlin("android") kotlin("kapt") + alias(libs.plugins.compose.compiler) } if (project.file("google-services.json").exists()) { @@ -21,6 +22,11 @@ val sgTargetSdk: Int by rootProject.extra val sgVersionCode: Int by rootProject.extra val sgVersionName: String by rootProject.extra +tasks.withType(JavaCompile::class.java).configureEach { + // Suppress JDK 21 warning about deprecated, but not yet removed, source and target value 8 support + options.compilerArgs.add("-Xlint:-options") +} + android { namespace = "com.battlelancer.seriesguide" compileSdk = sgCompileSdk @@ -29,7 +35,7 @@ android { buildFeatures { buildConfig = true - // https://developer.android.com/jetpack/compose/interop/adding + // https://developer.android.com/develop/ui/compose/setup compose = true // https://firebase.google.com/support/release-notes/android viewBinding = true @@ -39,6 +45,7 @@ android { minSdk = sgMinSdk targetSdk = sgTargetSdk + // Prevent plugin from generating PNGs, use compat loading instead https://developer.android.com/studio/write/vector-asset-studio#sloption vectorDrawables.useSupportLibrary = true testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -65,16 +72,12 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } - composeOptions { - // https://developer.android.com/jetpack/androidx/releases/compose-kotlin - kotlinCompilerExtensionVersion = "1.5.14" // For Kotlin 1.9.24 - } - kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8.toString() // Using experimental flatMapLatest for Paging 3 // Using experimental Material 3 compose APIs - freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi,androidx.compose.material3.ExperimentalMaterial3Api" + freeCompilerArgs = + freeCompilerArgs + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi,androidx.compose.material3.ExperimentalMaterial3Api" } lint { @@ -95,7 +98,8 @@ android { productFlavors { create("pure") { - isDefault = true // Make Studio select this by default, it often resets (after updates, randomly) + // Make Studio select this by default, it often resets (after updates, randomly) + isDefault = true applicationId = "com.battlelancer.seriesguide" versionCode = sgVersionCode @@ -155,6 +159,9 @@ android { // Based on https://docs.oracle.com/en/java/javase/17/docs/specs/jar/jar.html#jar-index // only used by network applications like applets, so safe to exclude. excludes += "/META-INF/INDEX.LIST" + // Exclude Coroutines debug file + // https://github.com/Kotlin/kotlinx.coroutines?tab=readme-ov-file#avoiding-including-the-debug-infrastructure-in-the-resulting-apk + excludes += "DebugProbesKt.bin" } } } @@ -164,7 +171,6 @@ kapt { arguments { arg("eventBusIndex", "com.battlelancer.seriesguide.SgEventBusIndex") arg("room.schemaLocation", "$projectDir/schemas") - arg("room.incremental", "true") } } @@ -204,7 +210,7 @@ dependencies { // Optional - Integration with activities implementation(libs.androidx.activity.compose) // Optional - Integration with ViewModels - implementation( libs.androidx.lifecycle.compose) + implementation(libs.androidx.lifecycle.compose) // ViewModel and LiveData implementation(libs.androidx.lifecycle.livedata) @@ -219,6 +225,8 @@ dependencies { implementation(libs.androidx.room.ktx) // Paging 3 Integration implementation(libs.androidx.room.paging) + // KSP appears deprecated. KSP 2 is still under development. + //noinspection KaptUsageInsteadOfKsp kapt(libs.androidx.room.compiler) implementation(libs.dagger) diff --git a/app/schemas/com.battlelancer.seriesguide.provider.SgRoomDatabase/54.json b/app/schemas/com.battlelancer.seriesguide.provider.SgRoomDatabase/54.json new file mode 100644 index 0000000000..4bd82e33fc --- /dev/null +++ b/app/schemas/com.battlelancer.seriesguide.provider.SgRoomDatabase/54.json @@ -0,0 +1,1653 @@ +{ + "formatVersion": 1, + "database": { + "version": 54, + "identityHash": "37e698b27a2494936bc264752cbf9943", + "entities": [ + { + "tableName": "series", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER NOT NULL, `series_slug` TEXT, `seriestitle` TEXT NOT NULL, `series_title_noarticle` TEXT, `overview` TEXT, `airstime` INTEGER, `airsdayofweek` INTEGER, `series_airtime` TEXT, `series_timezone` TEXT, `firstaired` TEXT, `genres` TEXT, `network` TEXT, `rating` REAL, `series_rating_votes` INTEGER, `series_rating_user` INTEGER, `runtime` TEXT, `status` TEXT, `contentrating` TEXT, `next` TEXT, `poster` TEXT, `series_poster_small` TEXT, `series_nextairdate` INTEGER, `nexttext` TEXT, `imdbid` TEXT, `series_trakt_id` INTEGER, `series_favorite` INTEGER NOT NULL, `series_syncenabled` INTEGER NOT NULL, `series_hidden` INTEGER NOT NULL, `series_lastupdate` INTEGER NOT NULL, `series_lastedit` INTEGER NOT NULL, `series_lastwatchedid` INTEGER NOT NULL, `series_lastwatched_ms` INTEGER NOT NULL, `series_language` TEXT, `series_unwatched_count` INTEGER NOT NULL, `series_notify` INTEGER NOT NULL, PRIMARY KEY(`_id`))", + "fields": [ + { + "fieldPath": "tvdbId", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "series_slug", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "seriestitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "titleNoArticle", + "columnName": "series_title_noarticle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "overview", + "columnName": "overview", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "releaseTime", + "columnName": "airstime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "releaseWeekDay", + "columnName": "airsdayofweek", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "releaseCountry", + "columnName": "series_airtime", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "releaseTimeZone", + "columnName": "series_timezone", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstRelease", + "columnName": "firstaired", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "genres", + "columnName": "genres", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "network", + "columnName": "network", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ratingGlobal", + "columnName": "rating", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingVotes", + "columnName": "series_rating_votes", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingUser", + "columnName": "series_rating_user", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "runtime", + "columnName": "runtime", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentRating", + "columnName": "contentrating", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nextEpisode", + "columnName": "next", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "poster", + "columnName": "poster", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "posterSmall", + "columnName": "series_poster_small", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nextAirdateMs", + "columnName": "series_nextairdate", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nextText", + "columnName": "nexttext", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "imdbId", + "columnName": "imdbid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "traktId", + "columnName": "series_trakt_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "favorite", + "columnName": "series_favorite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hexagonMergeComplete", + "columnName": "series_syncenabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hidden", + "columnName": "series_hidden", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastUpdatedMs", + "columnName": "series_lastupdate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastEditedSec", + "columnName": "series_lastedit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastWatchedEpisodeId", + "columnName": "series_lastwatchedid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastWatchedMs", + "columnName": "series_lastwatched_ms", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "language", + "columnName": "series_language", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "unwatchedCount", + "columnName": "series_unwatched_count", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notify", + "columnName": "series_notify", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "seasons", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER, `combinednr` INTEGER, `series_id` TEXT, `watchcount` INTEGER, `willaircount` INTEGER, `noairdatecount` INTEGER, `seasonposter` TEXT, `season_totalcount` INTEGER, PRIMARY KEY(`_id`), FOREIGN KEY(`series_id`) REFERENCES `series`(`_id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "tvdbId", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "number", + "columnName": "combinednr", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "showTvdbId", + "columnName": "series_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "watchCount", + "columnName": "watchcount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notReleasedCount", + "columnName": "willaircount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "noReleaseDateCount", + "columnName": "noairdatecount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tags", + "columnName": "seasonposter", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "totalCount", + "columnName": "season_totalcount", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_seasons_series_id", + "unique": false, + "columnNames": [ + "series_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_seasons_series_id` ON `${TABLE_NAME}` (`series_id`)" + } + ], + "foreignKeys": [ + { + "table": "series", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "series_id" + ], + "referencedColumns": [ + "_id" + ] + } + ] + }, + { + "tableName": "episodes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER NOT NULL, `episodetitle` TEXT NOT NULL, `episodedescription` TEXT, `episodenumber` INTEGER NOT NULL, `season` INTEGER NOT NULL, `dvdnumber` REAL, `season_id` INTEGER NOT NULL, `series_id` INTEGER NOT NULL, `watched` INTEGER NOT NULL, `plays` INTEGER, `directors` TEXT, `gueststars` TEXT, `writers` TEXT, `episodeimage` TEXT, `episode_firstairedms` INTEGER NOT NULL, `episode_collected` INTEGER NOT NULL, `rating` REAL, `episode_rating_votes` INTEGER, `episode_rating_user` INTEGER, `episode_imdbid` TEXT, `episode_lastedit` INTEGER NOT NULL, `absolute_number` INTEGER, `episode_lastupdate` INTEGER NOT NULL, PRIMARY KEY(`_id`), FOREIGN KEY(`season_id`) REFERENCES `seasons`(`_id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`series_id`) REFERENCES `series`(`_id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "tvdbId", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "episodetitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "overview", + "columnName": "episodedescription", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "number", + "columnName": "episodenumber", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "season", + "columnName": "season", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dvdNumber", + "columnName": "dvdnumber", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "seasonTvdbId", + "columnName": "season_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "showTvdbId", + "columnName": "series_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "watched", + "columnName": "watched", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "plays", + "columnName": "plays", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "directors", + "columnName": "directors", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "guestStars", + "columnName": "gueststars", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "writers", + "columnName": "writers", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "image", + "columnName": "episodeimage", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstReleasedMs", + "columnName": "episode_firstairedms", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "collected", + "columnName": "episode_collected", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ratingGlobal", + "columnName": "rating", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingVotes", + "columnName": "episode_rating_votes", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingUser", + "columnName": "episode_rating_user", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "imdbId", + "columnName": "episode_imdbid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastEditedSec", + "columnName": "episode_lastedit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absoluteNumber", + "columnName": "absolute_number", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastUpdatedSec", + "columnName": "episode_lastupdate", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_episodes_season_id", + "unique": false, + "columnNames": [ + "season_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_episodes_season_id` ON `${TABLE_NAME}` (`season_id`)" + }, + { + "name": "index_episodes_series_id", + "unique": false, + "columnNames": [ + "series_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_episodes_series_id` ON `${TABLE_NAME}` (`series_id`)" + } + ], + "foreignKeys": [ + { + "table": "seasons", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "season_id" + ], + "referencedColumns": [ + "_id" + ] + }, + { + "table": "series", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "series_id" + ], + "referencedColumns": [ + "_id" + ] + } + ] + }, + { + "tableName": "sg_show", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `series_tmdb_id` INTEGER, `series_tvdb_id` INTEGER, `series_slug` TEXT, `series_trakt_id` INTEGER, `series_title` TEXT NOT NULL, `series_title_noarticle` TEXT, `series_overview` TEXT, `series_airstime` INTEGER, `series_airsdayofweek` INTEGER, `series_country` TEXT, `series_timezone` TEXT, `series_firstaired` TEXT, `series_genres` TEXT, `series_network` TEXT, `series_imdbid` TEXT, `series_rating_tmdb` REAL, `series_rating_tmdb_votes` INTEGER, `series_rating` REAL, `series_rating_votes` INTEGER, `series_rating_user` INTEGER, `series_runtime` INTEGER, `series_status` INTEGER, `series_contentrating` TEXT, `series_next` TEXT, `series_poster` TEXT, `series_poster_small` TEXT, `series_nextairdate` INTEGER, `series_nexttext` TEXT, `series_lastupdate` INTEGER NOT NULL, `series_lastedit` INTEGER NOT NULL, `series_lastwatchedid` INTEGER NOT NULL, `series_lastwatched_ms` INTEGER NOT NULL, `series_language` TEXT, `series_unwatched_count` INTEGER NOT NULL, `series_favorite` INTEGER NOT NULL, `series_hidden` INTEGER NOT NULL, `series_notify` INTEGER NOT NULL, `series_syncenabled` INTEGER NOT NULL, `series_custom_release_time` INTEGER, `series_custom_day_offset` INTEGER, `series_custom_timezone` TEXT, `series_user_note` TEXT, `series_user_note_trakt_id` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tmdbId", + "columnName": "series_tmdb_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tvdbId", + "columnName": "series_tvdb_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "slug", + "columnName": "series_slug", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "traktId", + "columnName": "series_trakt_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "series_title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "titleNoArticle", + "columnName": "series_title_noarticle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "overview", + "columnName": "series_overview", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "releaseTime", + "columnName": "series_airstime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "releaseWeekDay", + "columnName": "series_airsdayofweek", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "releaseCountry", + "columnName": "series_country", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "releaseTimeZone", + "columnName": "series_timezone", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstRelease", + "columnName": "series_firstaired", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "genres", + "columnName": "series_genres", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "network", + "columnName": "series_network", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "imdbId", + "columnName": "series_imdbid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ratingTmdb", + "columnName": "series_rating_tmdb", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingTmdbVotes", + "columnName": "series_rating_tmdb_votes", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingTrakt", + "columnName": "series_rating", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingTraktVotes", + "columnName": "series_rating_votes", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingUser", + "columnName": "series_rating_user", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "runtime", + "columnName": "series_runtime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "status", + "columnName": "series_status", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "contentRating", + "columnName": "series_contentrating", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nextEpisode", + "columnName": "series_next", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "poster", + "columnName": "series_poster", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "posterSmall", + "columnName": "series_poster_small", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nextAirdateMs", + "columnName": "series_nextairdate", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "nextText", + "columnName": "series_nexttext", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdatedMs", + "columnName": "series_lastupdate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastEditedSec", + "columnName": "series_lastedit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastWatchedEpisodeId", + "columnName": "series_lastwatchedid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastWatchedMs", + "columnName": "series_lastwatched_ms", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "language", + "columnName": "series_language", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "unwatchedCount", + "columnName": "series_unwatched_count", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "favorite", + "columnName": "series_favorite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hidden", + "columnName": "series_hidden", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notify", + "columnName": "series_notify", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hexagonMergeComplete", + "columnName": "series_syncenabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customReleaseTime", + "columnName": "series_custom_release_time", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "customReleaseDayOffset", + "columnName": "series_custom_day_offset", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "customReleaseTimeZone", + "columnName": "series_custom_timezone", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "userNote", + "columnName": "series_user_note", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "userNoteTraktId", + "columnName": "series_user_note_trakt_id", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_sg_show_series_tmdb_id", + "unique": false, + "columnNames": [ + "series_tmdb_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_show_series_tmdb_id` ON `${TABLE_NAME}` (`series_tmdb_id`)" + }, + { + "name": "index_sg_show_series_tvdb_id", + "unique": false, + "columnNames": [ + "series_tvdb_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_show_series_tvdb_id` ON `${TABLE_NAME}` (`series_tvdb_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "sg_season", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `series_id` INTEGER NOT NULL, `season_tmdb_id` TEXT, `season_tvdb_id` INTEGER, `season_number` INTEGER, `season_name` TEXT, `season_order` INTEGER NOT NULL, `season_watchcount` INTEGER, `season_willaircount` INTEGER, `season_noairdatecount` INTEGER, `season_totalcount` INTEGER, `season_tags` TEXT, FOREIGN KEY(`series_id`) REFERENCES `sg_show`(`_id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "showId", + "columnName": "series_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tmdbId", + "columnName": "season_tmdb_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tvdbId", + "columnName": "season_tvdb_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "numberOrNull", + "columnName": "season_number", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "season_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "order", + "columnName": "season_order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notWatchedReleasedOrNull", + "columnName": "season_watchcount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notWatchedToBeReleasedOrNull", + "columnName": "season_willaircount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "notWatchedNoReleaseOrNull", + "columnName": "season_noairdatecount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "totalOrNull", + "columnName": "season_totalcount", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tags", + "columnName": "season_tags", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_sg_season_series_id", + "unique": false, + "columnNames": [ + "series_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_season_series_id` ON `${TABLE_NAME}` (`series_id`)" + } + ], + "foreignKeys": [ + { + "table": "sg_show", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "series_id" + ], + "referencedColumns": [ + "_id" + ] + } + ] + }, + { + "tableName": "sg_episode", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `season_id` INTEGER NOT NULL, `series_id` INTEGER NOT NULL, `episode_tmdb_id` INTEGER, `episode_tvdb_id` INTEGER, `episode_title` TEXT, `episode_description` TEXT, `episode_number` INTEGER NOT NULL, `episode_absolute_number` INTEGER, `episode_season_number` INTEGER NOT NULL, `episode_order` INTEGER NOT NULL, `episode_dvd_number` REAL, `episode_watched` INTEGER NOT NULL, `episode_plays` INTEGER, `episode_collected` INTEGER NOT NULL, `episode_directors` TEXT, `episode_gueststars` TEXT, `episode_writers` TEXT, `episode_image` TEXT, `episode_firstairedms` INTEGER NOT NULL, `episode_rating_tmdb` REAL, `episode_rating_tmdb_votes` INTEGER, `episode_rating` REAL, `episode_rating_votes` INTEGER, `episode_rating_user` INTEGER, `episode_imdbid` TEXT, `episode_lastedit` INTEGER NOT NULL, `episode_lastupdate` INTEGER NOT NULL, FOREIGN KEY(`series_id`) REFERENCES `sg_show`(`_id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "seasonId", + "columnName": "season_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "showId", + "columnName": "series_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tmdbId", + "columnName": "episode_tmdb_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tvdbId", + "columnName": "episode_tvdb_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "episode_title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "overview", + "columnName": "episode_description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "number", + "columnName": "episode_number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absoluteNumber", + "columnName": "episode_absolute_number", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "season", + "columnName": "episode_season_number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "episode_order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dvdNumber", + "columnName": "episode_dvd_number", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "watched", + "columnName": "episode_watched", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "plays", + "columnName": "episode_plays", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "collected", + "columnName": "episode_collected", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "directors", + "columnName": "episode_directors", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "guestStars", + "columnName": "episode_gueststars", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "writers", + "columnName": "episode_writers", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "image", + "columnName": "episode_image", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstReleasedMs", + "columnName": "episode_firstairedms", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ratingTmdb", + "columnName": "episode_rating_tmdb", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingTmdbVotes", + "columnName": "episode_rating_tmdb_votes", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingTrakt", + "columnName": "episode_rating", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingTraktVotes", + "columnName": "episode_rating_votes", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingUser", + "columnName": "episode_rating_user", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "imdbId", + "columnName": "episode_imdbid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastEditedSec", + "columnName": "episode_lastedit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastUpdatedSec", + "columnName": "episode_lastupdate", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_sg_episode_season_id", + "unique": false, + "columnNames": [ + "season_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_episode_season_id` ON `${TABLE_NAME}` (`season_id`)" + }, + { + "name": "index_sg_episode_series_id", + "unique": false, + "columnNames": [ + "series_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_episode_series_id` ON `${TABLE_NAME}` (`series_id`)" + } + ], + "foreignKeys": [ + { + "table": "sg_show", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "series_id" + ], + "referencedColumns": [ + "_id" + ] + } + ] + }, + { + "tableName": "lists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `list_id` TEXT NOT NULL, `list_name` TEXT NOT NULL, `list_order` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "listId", + "columnName": "list_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "list_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "list_order", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_lists_list_id", + "unique": true, + "columnNames": [ + "list_id" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_lists_list_id` ON `${TABLE_NAME}` (`list_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "listitems", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `list_item_id` TEXT NOT NULL, `item_ref_id` TEXT NOT NULL, `item_type` INTEGER NOT NULL, `list_id` TEXT, FOREIGN KEY(`list_id`) REFERENCES `lists`(`list_id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "listItemId", + "columnName": "list_item_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "itemRefId", + "columnName": "item_ref_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "item_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "listId", + "columnName": "list_id", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_listitems_list_item_id", + "unique": true, + "columnNames": [ + "list_item_id" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_listitems_list_item_id` ON `${TABLE_NAME}` (`list_item_id`)" + }, + { + "name": "index_listitems_list_id", + "unique": false, + "columnNames": [ + "list_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_listitems_list_id` ON `${TABLE_NAME}` (`list_id`)" + } + ], + "foreignKeys": [ + { + "table": "lists", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "list_id" + ], + "referencedColumns": [ + "list_id" + ] + } + ] + }, + { + "tableName": "movies", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `movies_tmdbid` INTEGER NOT NULL, `movies_imdbid` TEXT, `movies_title` TEXT, `movies_title_noarticle` TEXT, `movies_poster` TEXT, `movies_genres` TEXT, `movies_overview` TEXT, `movies_released` INTEGER, `movies_runtime` INTEGER, `movies_trailer` TEXT, `movies_certification` TEXT, `movies_incollection` INTEGER, `movies_inwatchlist` INTEGER, `movies_plays` INTEGER, `movies_watched` INTEGER, `movies_rating_tmdb` REAL, `movies_rating_votes_tmdb` INTEGER, `movies_rating_trakt` INTEGER, `movies_rating_votes_trakt` INTEGER, `movies_rating_user` INTEGER, `movies_last_updated` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tmdbId", + "columnName": "movies_tmdbid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "imdbId", + "columnName": "movies_imdbid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "movies_title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "titleNoArticle", + "columnName": "movies_title_noarticle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "poster", + "columnName": "movies_poster", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "genres", + "columnName": "movies_genres", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "overview", + "columnName": "movies_overview", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "releasedMs", + "columnName": "movies_released", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "runtimeMin", + "columnName": "movies_runtime", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "trailer", + "columnName": "movies_trailer", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "certification", + "columnName": "movies_certification", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "inCollection", + "columnName": "movies_incollection", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "inWatchlist", + "columnName": "movies_inwatchlist", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "plays", + "columnName": "movies_plays", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "watched", + "columnName": "movies_watched", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingTmdb", + "columnName": "movies_rating_tmdb", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "ratingVotesTmdb", + "columnName": "movies_rating_votes_tmdb", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingTrakt", + "columnName": "movies_rating_trakt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingVotesTrakt", + "columnName": "movies_rating_votes_trakt", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ratingUser", + "columnName": "movies_rating_user", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastUpdated", + "columnName": "movies_last_updated", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_movies_movies_tmdbid", + "unique": true, + "columnNames": [ + "movies_tmdbid" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_movies_movies_tmdbid` ON `${TABLE_NAME}` (`movies_tmdbid`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "activity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `activity_episode` TEXT NOT NULL, `activity_show` TEXT NOT NULL, `activity_time` INTEGER NOT NULL, `activity_type` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "episodeTvdbOrTmdbId", + "columnName": "activity_episode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "showTvdbOrTmdbId", + "columnName": "activity_show", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timestampMs", + "columnName": "activity_time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "activity_type", + "columnName": "activity_type", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_activity_activity_episode_activity_type", + "unique": true, + "columnNames": [ + "activity_episode", + "activity_type" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_activity_activity_episode_activity_type` ON `${TABLE_NAME}` (`activity_episode`, `activity_type`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "jobs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `job_created_at` INTEGER, `job_type` INTEGER, `job_extras` BLOB)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "createdMs", + "columnName": "job_created_at", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "job_type", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "extras", + "columnName": "job_extras", + "affinity": "BLOB", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_jobs_job_created_at", + "unique": true, + "columnNames": [ + "job_created_at" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_jobs_job_created_at` ON `${TABLE_NAME}` (`job_created_at`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "sg_watch_provider", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `provider_id` INTEGER NOT NULL, `provider_name` TEXT NOT NULL, `display_priority` INTEGER NOT NULL, `logo_path` TEXT NOT NULL, `type` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `filter_local` INTEGER NOT NULL DEFAULT false)", + "fields": [ + { + "fieldPath": "_id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "provider_id", + "columnName": "provider_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "provider_name", + "columnName": "provider_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "display_priority", + "columnName": "display_priority", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "logo_path", + "columnName": "logo_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "filter_local", + "columnName": "filter_local", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "false" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "_id" + ] + }, + "indices": [ + { + "name": "index_sg_watch_provider_provider_id_type", + "unique": true, + "columnNames": [ + "provider_id", + "type" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_sg_watch_provider_provider_id_type` ON `${TABLE_NAME}` (`provider_id`, `type`)" + }, + { + "name": "index_sg_watch_provider_provider_name", + "unique": false, + "columnNames": [ + "provider_name" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_watch_provider_provider_name` ON `${TABLE_NAME}` (`provider_name`)" + }, + { + "name": "index_sg_watch_provider_display_priority", + "unique": false, + "columnNames": [ + "display_priority" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_watch_provider_display_priority` ON `${TABLE_NAME}` (`display_priority`)" + }, + { + "name": "index_sg_watch_provider_enabled", + "unique": false, + "columnNames": [ + "enabled" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_watch_provider_enabled` ON `${TABLE_NAME}` (`enabled`)" + }, + { + "name": "index_sg_watch_provider_type", + "unique": false, + "columnNames": [ + "type" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_sg_watch_provider_type` ON `${TABLE_NAME}` (`type`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "sg_watch_provider_show_mappings", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`provider_id` INTEGER NOT NULL, `show_id` INTEGER NOT NULL, PRIMARY KEY(`provider_id`, `show_id`))", + "fields": [ + { + "fieldPath": "provider_id", + "columnName": "provider_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "show_id", + "columnName": "show_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "provider_id", + "show_id" + ] + }, + "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, '37e698b27a2494936bc264752cbf9943')" + ] + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/battlelancer/seriesguide/provider/DefaultValuesTest.java b/app/src/androidTest/java/com/battlelancer/seriesguide/provider/DefaultValuesTest.java index c010e8e281..49254919c5 100644 --- a/app/src/androidTest/java/com/battlelancer/seriesguide/provider/DefaultValuesTest.java +++ b/app/src/androidTest/java/com/battlelancer/seriesguide/provider/DefaultValuesTest.java @@ -128,6 +128,8 @@ public void showDefaultValuesImport() { assertThat(show.getCustomReleaseTime()).isNull(); assertThat(show.getCustomReleaseDayOffset()).isNull(); assertThat(show.getCustomReleaseTimeZone()).isNull(); + assertThat(show.getUserNote()).isNull(); + assertThat(show.getUserNoteTraktId()).isNull(); } @Test diff --git a/app/src/androidTest/java/com/battlelancer/seriesguide/shows/tools/ShowTestHelper.kt b/app/src/androidTest/java/com/battlelancer/seriesguide/shows/tools/ShowTestHelper.kt index 41ae184c77..1b0c1494d0 100644 --- a/app/src/androidTest/java/com/battlelancer/seriesguide/shows/tools/ShowTestHelper.kt +++ b/app/src/androidTest/java/com/battlelancer/seriesguide/shows/tools/ShowTestHelper.kt @@ -41,7 +41,9 @@ object ShowTestHelper { posterSmall = "poster.jpg", // set desired language, might not be the content language if fallback used above. language = LanguageTools.LANGUAGE_EN, - lastUpdatedMs = System.currentTimeMillis() // now + lastUpdatedMs = System.currentTimeMillis(), // now + userNote = null, + userNoteTraktId = null ) } diff --git a/app/src/androidTest/java/com/battlelancer/seriesguide/ui/ShowsActivityTest.java b/app/src/androidTest/java/com/battlelancer/seriesguide/ui/ShowsActivityTest.java index a16a712ab8..a729833974 100644 --- a/app/src/androidTest/java/com/battlelancer/seriesguide/ui/ShowsActivityTest.java +++ b/app/src/androidTest/java/com/battlelancer/seriesguide/ui/ShowsActivityTest.java @@ -64,7 +64,7 @@ public void testAddShowAndSetWatchedThenReturn() { // Open discover screen ViewInteraction floatingActionButton = onView( - allOf(withId(R.id.buttonShowsAdd), isDisplayed())); + allOf(withId(R.id.buttonShowsFloating), isDisplayed())); floatingActionButton.perform(click()); // Added a sleep statement to match the app's execution delay. diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3266a7186b..798b53ddeb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,13 +41,12 @@ -