diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index b0926a9f8..42afc78fa 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -39,12 +39,12 @@ plugins {
}
android {
- compileSdk = 34
+ compileSdk = 35
defaultConfig {
applicationId = "com.forcetower.uefs"
minSdk = 21
- targetSdk = 34
+ targetSdk = 35
val (code, name) = buildVersion()
versionCode = code
versionName = name
@@ -112,15 +112,15 @@ android {
mapsKey = "AIzaSyAIb0g7GrjLgOwRqmKHhBxbxWKjct8IF8Y"
}
getByName("release") {
+ manifestPlaceholders += mapOf("crashlyticsEnabled" to true)
signingConfig = signingConfigs.getByName("release")
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
isMinifyEnabled = true
- manifestPlaceholders += mapOf("crashlyticsEnabled" to true)
resValue("string", "google_maps_key", mapsKey)
}
getByName("debug") {
- applicationIdSuffix = ".debug"
manifestPlaceholders += mapOf("crashlyticsEnabled" to false)
+ applicationIdSuffix = ".debug"
resValue("string", "google_maps_key", "AIzaSyAIb0g7GrjLgOwRqmKHhBxbxWKjct8IF8Y")
}
}
@@ -133,7 +133,7 @@ android {
kapt {
correctErrorTypes = true
javacOptions {
- option("-Xmaxerrs", 1000)
+ option("-Xmaxerrs", "1000")
}
}
@@ -232,7 +232,6 @@ dependencies {
implementation(libs.play.services.games.v2)
implementation(libs.play.services.auth)
implementation(libs.play.services.location)
- implementation(libs.billing)
implementation(libs.review.ktx)
implementation(libs.app.update.ktx)
implementation(libs.feature.delivery.ktx)
@@ -250,6 +249,14 @@ dependencies {
implementation(libs.taptargetview)
implementation(libs.play.services.maps)
implementation(libs.materialdatetimepicker)
+ implementation(libs.markwon.core)
+ implementation(libs.markwon.ext.latex)
+ implementation(libs.markwon.ext.strikethrough)
+ implementation(libs.markwon.html)
+ implementation(libs.markwon.image)
+ implementation(libs.markwon.image.glide)
+ implementation(libs.markwon.linkify)
+
testImplementation(libs.junit)
testImplementation(libs.mockk)
testImplementation(libs.androidx.core.testing)
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 280bc771e..812d01bc4 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -68,6 +68,10 @@
## This was needed because of the CallAdapter. I dont use it anymore, so...
# -keep,allowshrinking class androidx.lifecycle.LiveData
+-keep class com.caverock.androidsvg.** { *; }
+-dontwarn com.caverock.androidsvg.**
+-dontwarn pl.droidsonroids.gif.GifDrawable
+
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.conscrypt.Conscrypt$Version
diff --git a/app/schemas/com.forcetower.uefs.core.storage.database.UDatabase/56.json b/app/schemas/com.forcetower.uefs.core.storage.database.UDatabase/56.json
new file mode 100644
index 000000000..47725d7dc
--- /dev/null
+++ b/app/schemas/com.forcetower.uefs.core.storage.database.UDatabase/56.json
@@ -0,0 +1,3251 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 56,
+ "identityHash": "247db668ab54e74671c4844334d9722f",
+ "entities": [
+ {
+ "tableName": "AccessToken",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` TEXT NOT NULL, `token` TEXT NOT NULL, `refreshToken` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "token",
+ "columnName": "token",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "refreshToken",
+ "columnName": "refreshToken",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Access",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, `valid` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "username",
+ "columnName": "username",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "password",
+ "columnName": "password",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "valid",
+ "columnName": "valid",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Profile",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `email` TEXT, `score` REAL NOT NULL, `calc_score` REAL NOT NULL, `course` INTEGER, `imageUrl` TEXT, `sagres_id` INTEGER NOT NULL, `uuid` TEXT NOT NULL, `me` INTEGER NOT NULL, `mocked` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "score",
+ "columnName": "score",
+ "affinity": "REAL",
+ "notNull": true
+ },
+ {
+ "fieldPath": "calcScore",
+ "columnName": "calc_score",
+ "affinity": "REAL",
+ "notNull": true
+ },
+ {
+ "fieldPath": "course",
+ "columnName": "course",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "imageUrl",
+ "columnName": "imageUrl",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sagresId",
+ "columnName": "sagres_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "me",
+ "columnName": "me",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "mocked",
+ "columnName": "mocked",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Profile_sagres_id",
+ "unique": true,
+ "columnNames": [
+ "sagres_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Profile_sagres_id` ON `${TABLE_NAME}` (`sagres_id`)"
+ },
+ {
+ "name": "index_Profile_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Profile_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Semester",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `sagres_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `codename` TEXT NOT NULL, `start` INTEGER, `end` INTEGER, `start_class` INTEGER, `end_class` INTEGER)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sagresId",
+ "columnName": "sagres_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "codename",
+ "columnName": "codename",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "start",
+ "columnName": "start",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "end",
+ "columnName": "end",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "startClass",
+ "columnName": "start_class",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "endClass",
+ "columnName": "end_class",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Semester_sagres_id",
+ "unique": true,
+ "columnNames": [
+ "sagres_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semester_sagres_id` ON `${TABLE_NAME}` (`sagres_id`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Message",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `content` TEXT NOT NULL, `sagres_id` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `sender_profile` INTEGER NOT NULL, `sender_name` TEXT, `notified` INTEGER NOT NULL, `discipline` TEXT, `uuid` TEXT NOT NULL, `code_discipline` TEXT, `html` INTEGER NOT NULL, `date_string` TEXT, `processing_time` INTEGER, `hash_message` INTEGER, `attachmentName` TEXT, `attachmentLink` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sagresId",
+ "columnName": "sagres_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "timestamp",
+ "columnName": "timestamp",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderProfile",
+ "columnName": "sender_profile",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderName",
+ "columnName": "sender_name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "notified",
+ "columnName": "notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "discipline",
+ "columnName": "discipline",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "codeDiscipline",
+ "columnName": "code_discipline",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "html",
+ "columnName": "html",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "dateString",
+ "columnName": "date_string",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "processingTime",
+ "columnName": "processing_time",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "hashMessage",
+ "columnName": "hash_message",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "attachmentName",
+ "columnName": "attachmentName",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "attachmentLink",
+ "columnName": "attachmentLink",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Message_hash_message",
+ "unique": true,
+ "columnNames": [
+ "hash_message"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Message_hash_message` ON `${TABLE_NAME}` (`hash_message`)"
+ },
+ {
+ "name": "index_Message_sagres_id",
+ "unique": true,
+ "columnNames": [
+ "sagres_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Message_sagres_id` ON `${TABLE_NAME}` (`sagres_id`)"
+ },
+ {
+ "name": "index_Message_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Message_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "CalendarItem",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `message` TEXT NOT NULL, `date` TEXT NOT NULL, `uuid` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "message",
+ "columnName": "message",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_CalendarItem_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_CalendarItem_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Discipline",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `code` TEXT NOT NULL, `credits` INTEGER NOT NULL, `department` TEXT, `resume` TEXT, `short_text` TEXT, `uuid` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "code",
+ "columnName": "code",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "credits",
+ "columnName": "credits",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "department",
+ "columnName": "department",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "resume",
+ "columnName": "resume",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "shortText",
+ "columnName": "short_text",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Discipline_code",
+ "unique": true,
+ "columnNames": [
+ "code"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Discipline_code` ON `${TABLE_NAME}` (`code`)"
+ },
+ {
+ "name": "index_Discipline_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Discipline_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Class",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `discipline_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `status` TEXT, `final_score` REAL, `partial_score` REAL, `uuid` TEXT NOT NULL, `missedClasses` INTEGER NOT NULL, `lastClass` TEXT NOT NULL, `nextClass` TEXT NOT NULL, `schedule_only` INTEGER NOT NULL, FOREIGN KEY(`discipline_id`) REFERENCES `Discipline`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`semester_id`) REFERENCES `Semester`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "disciplineId",
+ "columnName": "discipline_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "status",
+ "columnName": "status",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "finalScore",
+ "columnName": "final_score",
+ "affinity": "REAL",
+ "notNull": false
+ },
+ {
+ "fieldPath": "partialScore",
+ "columnName": "partial_score",
+ "affinity": "REAL",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "missedClasses",
+ "columnName": "missedClasses",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastClass",
+ "columnName": "lastClass",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "nextClass",
+ "columnName": "nextClass",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "scheduleOnly",
+ "columnName": "schedule_only",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Class_semester_id",
+ "unique": false,
+ "columnNames": [
+ "semester_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_Class_semester_id` ON `${TABLE_NAME}` (`semester_id`)"
+ },
+ {
+ "name": "index_Class_discipline_id_semester_id",
+ "unique": true,
+ "columnNames": [
+ "discipline_id",
+ "semester_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Class_discipline_id_semester_id` ON `${TABLE_NAME}` (`discipline_id`, `semester_id`)"
+ },
+ {
+ "name": "index_Class_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Class_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "Discipline",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "discipline_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "Semester",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "semester_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "ClassGroup",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `class_id` INTEGER NOT NULL, `group` TEXT NOT NULL, `teacher` TEXT, `credits` INTEGER NOT NULL, `uuid` TEXT NOT NULL, `draft` INTEGER NOT NULL, `ignored` INTEGER NOT NULL, `teacher_id` INTEGER, `sagresId` INTEGER, `teacherEmail` TEXT, FOREIGN KEY(`class_id`) REFERENCES `Class`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`teacher_id`) REFERENCES `Teacher`(`uid`) ON UPDATE CASCADE ON DELETE SET NULL )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "group",
+ "columnName": "group",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "credits",
+ "columnName": "credits",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "draft",
+ "columnName": "draft",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ignored",
+ "columnName": "ignored",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherId",
+ "columnName": "teacher_id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sagresId",
+ "columnName": "sagresId",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "teacherEmail",
+ "columnName": "teacherEmail",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_ClassGroup_class_id_group",
+ "unique": true,
+ "columnNames": [
+ "class_id",
+ "group"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassGroup_class_id_group` ON `${TABLE_NAME}` (`class_id`, `group`)"
+ },
+ {
+ "name": "index_ClassGroup_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassGroup_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ },
+ {
+ "name": "index_ClassGroup_teacher_id",
+ "unique": false,
+ "columnNames": [
+ "teacher_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassGroup_teacher_id` ON `${TABLE_NAME}` (`teacher_id`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "Class",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "class_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "Teacher",
+ "onDelete": "SET NULL",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "teacher_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "ClassAbsence",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `class_id` INTEGER NOT NULL, `profile_id` INTEGER NOT NULL, `sequence` INTEGER NOT NULL, `description` TEXT NOT NULL, `date` TEXT NOT NULL, `grouping` TEXT NOT NULL, `uuid` TEXT NOT NULL, `notified` INTEGER NOT NULL, FOREIGN KEY(`class_id`) REFERENCES `Class`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`profile_id`) REFERENCES `Profile`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "profileId",
+ "columnName": "profile_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sequence",
+ "columnName": "sequence",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "grouping",
+ "columnName": "grouping",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notified",
+ "columnName": "notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_ClassAbsence_profile_id",
+ "unique": false,
+ "columnNames": [
+ "profile_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassAbsence_profile_id` ON `${TABLE_NAME}` (`profile_id`)"
+ },
+ {
+ "name": "index_ClassAbsence_class_id",
+ "unique": false,
+ "columnNames": [
+ "class_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassAbsence_class_id` ON `${TABLE_NAME}` (`class_id`)"
+ },
+ {
+ "name": "index_ClassAbsence_class_id_profile_id_sequence_grouping",
+ "unique": true,
+ "columnNames": [
+ "class_id",
+ "profile_id",
+ "sequence",
+ "grouping"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassAbsence_class_id_profile_id_sequence_grouping` ON `${TABLE_NAME}` (`class_id`, `profile_id`, `sequence`, `grouping`)"
+ },
+ {
+ "name": "index_ClassAbsence_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassAbsence_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "Class",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "class_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "Profile",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "profile_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "ClassLocation",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `group_id` INTEGER NOT NULL, `profile_id` INTEGER NOT NULL, `starts_at` TEXT NOT NULL, `ends_at` TEXT NOT NULL, `day` TEXT NOT NULL, `room` TEXT, `modulo` TEXT, `campus` TEXT, `uuid` TEXT NOT NULL, `hidden_on_schedule` INTEGER NOT NULL, `startsAtInt` INTEGER NOT NULL, `endsAtInt` INTEGER NOT NULL, `dayInt` INTEGER NOT NULL, FOREIGN KEY(`group_id`) REFERENCES `ClassGroup`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`profile_id`) REFERENCES `Profile`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "groupId",
+ "columnName": "group_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "profileId",
+ "columnName": "profile_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "startsAt",
+ "columnName": "starts_at",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "endsAt",
+ "columnName": "ends_at",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "day",
+ "columnName": "day",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "room",
+ "columnName": "room",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "modulo",
+ "columnName": "modulo",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "campus",
+ "columnName": "campus",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hiddenOnSchedule",
+ "columnName": "hidden_on_schedule",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "startsAtInt",
+ "columnName": "startsAtInt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "endsAtInt",
+ "columnName": "endsAtInt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "dayInt",
+ "columnName": "dayInt",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_ClassLocation_group_id_day_starts_at_ends_at_profile_id",
+ "unique": true,
+ "columnNames": [
+ "group_id",
+ "day",
+ "starts_at",
+ "ends_at",
+ "profile_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassLocation_group_id_day_starts_at_ends_at_profile_id` ON `${TABLE_NAME}` (`group_id`, `day`, `starts_at`, `ends_at`, `profile_id`)"
+ },
+ {
+ "name": "index_ClassLocation_profile_id",
+ "unique": false,
+ "columnNames": [
+ "profile_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassLocation_profile_id` ON `${TABLE_NAME}` (`profile_id`)"
+ },
+ {
+ "name": "index_ClassLocation_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassLocation_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "ClassGroup",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "group_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "Profile",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "profile_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "ClassItem",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `group_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `situation` TEXT, `subject` TEXT, `date` TEXT, `number_of_materials` INTEGER NOT NULL, `material_links` TEXT NOT NULL, `is_new` INTEGER NOT NULL, `uuid` TEXT NOT NULL, FOREIGN KEY(`group_id`) REFERENCES `ClassGroup`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "groupId",
+ "columnName": "group_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "number",
+ "columnName": "number",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "situation",
+ "columnName": "situation",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "numberOfMaterials",
+ "columnName": "number_of_materials",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "materialLinks",
+ "columnName": "material_links",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isNew",
+ "columnName": "is_new",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_ClassItem_group_id_number",
+ "unique": true,
+ "columnNames": [
+ "group_id",
+ "number"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassItem_group_id_number` ON `${TABLE_NAME}` (`group_id`, `number`)"
+ },
+ {
+ "name": "index_ClassItem_number_of_materials",
+ "unique": false,
+ "columnNames": [
+ "number_of_materials"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassItem_number_of_materials` ON `${TABLE_NAME}` (`number_of_materials`)"
+ },
+ {
+ "name": "index_ClassItem_situation",
+ "unique": false,
+ "columnNames": [
+ "situation"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassItem_situation` ON `${TABLE_NAME}` (`situation`)"
+ },
+ {
+ "name": "index_ClassItem_date",
+ "unique": false,
+ "columnNames": [
+ "date"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassItem_date` ON `${TABLE_NAME}` (`date`)"
+ },
+ {
+ "name": "index_ClassItem_is_new",
+ "unique": false,
+ "columnNames": [
+ "is_new"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassItem_is_new` ON `${TABLE_NAME}` (`is_new`)"
+ },
+ {
+ "name": "index_ClassItem_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassItem_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "ClassGroup",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "group_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "ClassMaterial",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `group_id` INTEGER NOT NULL, `class_item_id` INTEGER, `name` TEXT NOT NULL, `link` TEXT NOT NULL, `is_new` INTEGER NOT NULL, `uuid` TEXT NOT NULL, `notified` INTEGER NOT NULL, FOREIGN KEY(`group_id`) REFERENCES `ClassGroup`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`class_item_id`) REFERENCES `ClassItem`(`uid`) ON UPDATE CASCADE ON DELETE SET NULL )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "groupId",
+ "columnName": "group_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classItemId",
+ "columnName": "class_item_id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "link",
+ "columnName": "link",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isNew",
+ "columnName": "is_new",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notified",
+ "columnName": "notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_ClassMaterial_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassMaterial_name` ON `${TABLE_NAME}` (`name`)"
+ },
+ {
+ "name": "index_ClassMaterial_link",
+ "unique": false,
+ "columnNames": [
+ "link"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassMaterial_link` ON `${TABLE_NAME}` (`link`)"
+ },
+ {
+ "name": "index_ClassMaterial_group_id",
+ "unique": false,
+ "columnNames": [
+ "group_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassMaterial_group_id` ON `${TABLE_NAME}` (`group_id`)"
+ },
+ {
+ "name": "index_ClassMaterial_class_item_id",
+ "unique": false,
+ "columnNames": [
+ "class_item_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassMaterial_class_item_id` ON `${TABLE_NAME}` (`class_item_id`)"
+ },
+ {
+ "name": "index_ClassMaterial_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassMaterial_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ },
+ {
+ "name": "index_ClassMaterial_is_new",
+ "unique": false,
+ "columnNames": [
+ "is_new"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassMaterial_is_new` ON `${TABLE_NAME}` (`is_new`)"
+ },
+ {
+ "name": "index_ClassMaterial_name_link_group_id",
+ "unique": true,
+ "columnNames": [
+ "name",
+ "link",
+ "group_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassMaterial_name_link_group_id` ON `${TABLE_NAME}` (`name`, `link`, `group_id`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "ClassGroup",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "group_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "ClassItem",
+ "onDelete": "SET NULL",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "class_item_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "Grade",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` TEXT, `grade` TEXT, `grouping` INTEGER NOT NULL, `groupingName` TEXT NOT NULL, `notified` INTEGER NOT NULL, FOREIGN KEY(`class_id`) REFERENCES `Class`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "grade",
+ "columnName": "grade",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "grouping",
+ "columnName": "grouping",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "groupingName",
+ "columnName": "groupingName",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notified",
+ "columnName": "notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Grade_class_id",
+ "unique": false,
+ "columnNames": [
+ "class_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_Grade_class_id` ON `${TABLE_NAME}` (`class_id`)"
+ },
+ {
+ "name": "index_Grade_name_class_id_grouping",
+ "unique": true,
+ "columnNames": [
+ "name",
+ "class_id",
+ "grouping"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Grade_name_class_id_grouping` ON `${TABLE_NAME}` (`name`, `class_id`, `grouping`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "Class",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "class_id"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "Course",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `description` TEXT, `image` TEXT, `since` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "image",
+ "columnName": "image",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "since",
+ "columnName": "since",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "SagresDocument",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` TEXT NOT NULL, `name` TEXT NOT NULL, `downloaded` INTEGER NOT NULL, `downloading` INTEGER NOT NULL, `date` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "downloaded",
+ "columnName": "downloaded",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "downloading",
+ "columnName": "downloading",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_SagresDocument_type",
+ "unique": true,
+ "columnNames": [
+ "type"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_SagresDocument_type` ON `${TABLE_NAME}` (`type`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "SyncRegistry",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `uuid` TEXT NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER, `completed` INTEGER NOT NULL, `success` INTEGER NOT NULL, `error` INTEGER NOT NULL, `executor` TEXT NOT NULL, `message` TEXT NOT NULL, `networkType` INTEGER NOT NULL, `network` TEXT NOT NULL, `skipped` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "start",
+ "columnName": "start",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "end",
+ "columnName": "end",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "completed",
+ "columnName": "completed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "success",
+ "columnName": "success",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "executor",
+ "columnName": "executor",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "message",
+ "columnName": "message",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "networkType",
+ "columnName": "networkType",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "network",
+ "columnName": "network",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "skipped",
+ "columnName": "skipped",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_SyncRegistry_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_SyncRegistry_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ },
+ {
+ "name": "index_SyncRegistry_start",
+ "unique": true,
+ "columnNames": [
+ "start"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_SyncRegistry_start` ON `${TABLE_NAME}` (`start`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Teacher",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `email` TEXT, `sagresId` INTEGER, `department` TEXT, `uuid` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sagresId",
+ "columnName": "sagresId",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "department",
+ "columnName": "department",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Teacher_uuid",
+ "unique": true,
+ "columnNames": [
+ "uuid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Teacher_uuid` ON `${TABLE_NAME}` (`uuid`)"
+ },
+ {
+ "name": "index_Teacher_sagresId",
+ "unique": true,
+ "columnNames": [
+ "sagresId"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Teacher_sagresId` ON `${TABLE_NAME}` (`sagresId`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "SDemandOffer",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `id` TEXT NOT NULL, `code` TEXT NOT NULL, `name` TEXT NOT NULL, `selected` INTEGER NOT NULL, `category` TEXT NOT NULL, `hours` INTEGER NOT NULL, `completed` INTEGER NOT NULL, `available` INTEGER NOT NULL, `current` INTEGER NOT NULL, `selectable` INTEGER NOT NULL, `unavailable` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "code",
+ "columnName": "code",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "selected",
+ "columnName": "selected",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "category",
+ "columnName": "category",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hours",
+ "columnName": "hours",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "completed",
+ "columnName": "completed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "available",
+ "columnName": "available",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "current",
+ "columnName": "current",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "selectable",
+ "columnName": "selectable",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unavailable",
+ "columnName": "unavailable",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "SagresFlags",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `demand_open` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "demandOpen",
+ "columnName": "demand_open",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Contributor",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `login` TEXT NOT NULL, `total` INTEGER NOT NULL, `name` TEXT NOT NULL, `image` TEXT, `link` TEXT, `url` TEXT, `bio` TEXT, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "login",
+ "columnName": "login",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "total",
+ "columnName": "total",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "image",
+ "columnName": "image",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "link",
+ "columnName": "link",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "url",
+ "columnName": "url",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "bio",
+ "columnName": "bio",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_Contributor_login",
+ "unique": true,
+ "columnNames": [
+ "login"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Contributor_login` ON `${TABLE_NAME}` (`login`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "ServiceRequest",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service` TEXT NOT NULL, `date` TEXT NOT NULL, `amount` INTEGER NOT NULL, `situation` TEXT NOT NULL, `value` TEXT NOT NULL, `observation` TEXT NOT NULL, `notify` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "service",
+ "columnName": "service",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "amount",
+ "columnName": "amount",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "situation",
+ "columnName": "situation",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "value",
+ "columnName": "value",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "observation",
+ "columnName": "observation",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notify",
+ "columnName": "notify",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "service_uniqueness",
+ "unique": true,
+ "columnNames": [
+ "service",
+ "date"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `service_uniqueness` ON `${TABLE_NAME}` (`service`, `date`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Account",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, `imageUrl` TEXT, `username` TEXT NOT NULL, `email` TEXT, `darkThemeEnabled` INTEGER NOT NULL, `darkThemeInvites` INTEGER NOT NULL, `grouping` INTEGER, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "imageUrl",
+ "columnName": "imageUrl",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "username",
+ "columnName": "username",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "darkThemeEnabled",
+ "columnName": "darkThemeEnabled",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "darkThemeInvites",
+ "columnName": "darkThemeInvites",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "grouping",
+ "columnName": "grouping",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "STeacher",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`teacherId` INTEGER NOT NULL, `name` TEXT NOT NULL, `imageUrl` TEXT, PRIMARY KEY(`teacherId`))",
+ "fields": [
+ {
+ "fieldPath": "teacherId",
+ "columnName": "teacherId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "imageUrl",
+ "columnName": "imageUrl",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "teacherId"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_STeacher_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_STeacher_name` ON `${TABLE_NAME}` (`name`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "SDiscipline",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`disciplineId` INTEGER NOT NULL, `department` TEXT NOT NULL, `departmentName` TEXT, `code` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`disciplineId`))",
+ "fields": [
+ {
+ "fieldPath": "disciplineId",
+ "columnName": "disciplineId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "department",
+ "columnName": "department",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "departmentName",
+ "columnName": "departmentName",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "code",
+ "columnName": "code",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "disciplineId"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_SDiscipline_code_department",
+ "unique": true,
+ "columnNames": [
+ "code",
+ "department"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_SDiscipline_code_department` ON `${TABLE_NAME}` (`code`, `department`)"
+ },
+ {
+ "name": "index_SDiscipline_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_SDiscipline_name` ON `${TABLE_NAME}` (`name`)"
+ },
+ {
+ "name": "index_SDiscipline_code",
+ "unique": false,
+ "columnNames": [
+ "code"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_SDiscipline_code` ON `${TABLE_NAME}` (`code`)"
+ },
+ {
+ "name": "index_SDiscipline_department",
+ "unique": false,
+ "columnNames": [
+ "department"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_SDiscipline_department` ON `${TABLE_NAME}` (`department`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "SStudent",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `name` TEXT NOT NULL, `imageUrl` TEXT, `course` INTEGER, `courseName` TEXT, `me` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "userId",
+ "columnName": "userId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "imageUrl",
+ "columnName": "imageUrl",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "course",
+ "columnName": "course",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "courseName",
+ "columnName": "courseName",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "me",
+ "columnName": "me",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_SStudent_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_SStudent_name` ON `${TABLE_NAME}` (`name`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "EvaluationEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `referencedId` INTEGER NOT NULL, `name` TEXT NOT NULL, `extra` TEXT, `image` TEXT, `type` INTEGER NOT NULL, `searchable` TEXT NOT NULL, `comp1` TEXT, `comp2` TEXT, `referenceLong1` INTEGER, `referenceLong2` INTEGER)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "referencedId",
+ "columnName": "referencedId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "extra",
+ "columnName": "extra",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "image",
+ "columnName": "image",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "searchable",
+ "columnName": "searchable",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "comp1",
+ "columnName": "comp1",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "comp2",
+ "columnName": "comp2",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "referenceLong1",
+ "columnName": "referenceLong1",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "referenceLong2",
+ "columnName": "referenceLong2",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_EvaluationEntity_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_EvaluationEntity_name` ON `${TABLE_NAME}` (`name`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Flowchart",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `courseId` INTEGER NOT NULL, `description` TEXT NOT NULL, `lastUpdated` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "courseId",
+ "columnName": "courseId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastUpdated",
+ "columnName": "lastUpdated",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "FlowchartSemester",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `flowchartId` INTEGER NOT NULL, `order` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`flowchartId`) REFERENCES `Flowchart`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "flowchartId",
+ "columnName": "flowchartId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "order",
+ "columnName": "order",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_FlowchartSemester_flowchartId",
+ "unique": false,
+ "columnNames": [
+ "flowchartId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_FlowchartSemester_flowchartId` ON `${TABLE_NAME}` (`flowchartId`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "Flowchart",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "flowchartId"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "FlowchartDiscipline",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `disciplineId` INTEGER NOT NULL, `type` TEXT NOT NULL, `mandatory` INTEGER NOT NULL, `semesterId` INTEGER NOT NULL, `completed` INTEGER NOT NULL, `participating` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`disciplineId`) REFERENCES `Discipline`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`semesterId`) REFERENCES `FlowchartSemester`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "disciplineId",
+ "columnName": "disciplineId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "mandatory",
+ "columnName": "mandatory",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semesterId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "completed",
+ "columnName": "completed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "participating",
+ "columnName": "participating",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_FlowchartDiscipline_disciplineId",
+ "unique": false,
+ "columnNames": [
+ "disciplineId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_FlowchartDiscipline_disciplineId` ON `${TABLE_NAME}` (`disciplineId`)"
+ },
+ {
+ "name": "index_FlowchartDiscipline_semesterId",
+ "unique": false,
+ "columnNames": [
+ "semesterId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_FlowchartDiscipline_semesterId` ON `${TABLE_NAME}` (`semesterId`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "Discipline",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "disciplineId"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "FlowchartSemester",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "semesterId"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "FlowchartRequirement",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `type` TEXT NOT NULL, `disciplineId` INTEGER NOT NULL, `requiredDisciplineId` INTEGER, `coursePercentage` REAL, `courseHours` INTEGER, `typeId` INTEGER NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`disciplineId`) REFERENCES `FlowchartDiscipline`(`id`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`requiredDisciplineId`) REFERENCES `FlowchartDiscipline`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "disciplineId",
+ "columnName": "disciplineId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "requiredDisciplineId",
+ "columnName": "requiredDisciplineId",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "coursePercentage",
+ "columnName": "coursePercentage",
+ "affinity": "REAL",
+ "notNull": false
+ },
+ {
+ "fieldPath": "courseHours",
+ "columnName": "courseHours",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "typeId",
+ "columnName": "typeId",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_FlowchartRequirement_disciplineId",
+ "unique": false,
+ "columnNames": [
+ "disciplineId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_FlowchartRequirement_disciplineId` ON `${TABLE_NAME}` (`disciplineId`)"
+ },
+ {
+ "name": "index_FlowchartRequirement_requiredDisciplineId",
+ "unique": false,
+ "columnNames": [
+ "requiredDisciplineId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_FlowchartRequirement_requiredDisciplineId` ON `${TABLE_NAME}` (`requiredDisciplineId`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "FlowchartDiscipline",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "disciplineId"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "FlowchartDiscipline",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "requiredDisciplineId"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "ProfileStatement",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `receiverId` INTEGER NOT NULL, `senderId` INTEGER NOT NULL, `senderName` TEXT, `senderPicture` TEXT, `hidden` INTEGER NOT NULL, `text` TEXT NOT NULL, `likes` INTEGER NOT NULL, `approved` INTEGER NOT NULL, `createdAt` TEXT NOT NULL, `updatedAt` TEXT NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "receiverId",
+ "columnName": "receiverId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderId",
+ "columnName": "senderId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderName",
+ "columnName": "senderName",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "senderPicture",
+ "columnName": "senderPicture",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "hidden",
+ "columnName": "hidden",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "text",
+ "columnName": "text",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "likes",
+ "columnName": "likes",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "approved",
+ "columnName": "approved",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "createdAt",
+ "columnName": "createdAt",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "updatedAt",
+ "columnName": "updatedAt",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "UserSession",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` TEXT NOT NULL, `started` INTEGER NOT NULL, `lastInteraction` INTEGER, `synced` INTEGER NOT NULL, `clickedAd` INTEGER NOT NULL, `impressionAd` INTEGER NOT NULL, PRIMARY KEY(`uid`))",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "started",
+ "columnName": "started",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastInteraction",
+ "columnName": "lastInteraction",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "synced",
+ "columnName": "synced",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "clickedAd",
+ "columnName": "clickedAd",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "impressionAd",
+ "columnName": "impressionAd",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "AffinityQuestion",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `question` TEXT NOT NULL, `answered` INTEGER NOT NULL, `synced` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "question",
+ "columnName": "question",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "answered",
+ "columnName": "answered",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "synced",
+ "columnName": "synced",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "AffinityQuestionAlternative",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `question_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, FOREIGN KEY(`question_id`) REFERENCES `AffinityQuestion`(`id`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`student_id`) REFERENCES `SStudent`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "questionId",
+ "columnName": "question_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_AffinityQuestionAlternative_student_id",
+ "unique": false,
+ "columnNames": [
+ "student_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_AffinityQuestionAlternative_student_id` ON `${TABLE_NAME}` (`student_id`)"
+ },
+ {
+ "name": "index_AffinityQuestionAlternative_question_id",
+ "unique": false,
+ "columnNames": [
+ "question_id"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_AffinityQuestionAlternative_question_id` ON `${TABLE_NAME}` (`question_id`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "AffinityQuestion",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "question_id"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "SStudent",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "student_id"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "Event",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `description` TEXT NOT NULL, `imageUrl` TEXT NOT NULL, `creatorName` TEXT NOT NULL, `creatorId` INTEGER NOT NULL, `offeredBy` TEXT NOT NULL, `startDate` TEXT NOT NULL, `endDate` TEXT NOT NULL, `location` TEXT NOT NULL, `price` REAL, `certificateHours` INTEGER, `courseId` INTEGER, `featured` INTEGER NOT NULL, `createdAt` TEXT NOT NULL, `approved` INTEGER NOT NULL, `canModify` INTEGER NOT NULL, `participating` INTEGER NOT NULL, `fakeTemp` INTEGER, `sending` INTEGER, `registerPage` TEXT, `canApprove` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "imageUrl",
+ "columnName": "imageUrl",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "creatorName",
+ "columnName": "creatorName",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "creatorId",
+ "columnName": "creatorId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "offeredBy",
+ "columnName": "offeredBy",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "startDate",
+ "columnName": "startDate",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "endDate",
+ "columnName": "endDate",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "location",
+ "columnName": "location",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "price",
+ "columnName": "price",
+ "affinity": "REAL",
+ "notNull": false
+ },
+ {
+ "fieldPath": "certificateHours",
+ "columnName": "certificateHours",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "courseId",
+ "columnName": "courseId",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "featured",
+ "columnName": "featured",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "createdAt",
+ "columnName": "createdAt",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "approved",
+ "columnName": "approved",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "canModify",
+ "columnName": "canModify",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "participating",
+ "columnName": "participating",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "fakeTemp",
+ "columnName": "fakeTemp",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sending",
+ "columnName": "sending",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "registerPage",
+ "columnName": "registerPage",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "canApprove",
+ "columnName": "canApprove",
+ "affinity": "INTEGER",
+ "notNull": true,
+ "defaultValue": "0"
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "ClassGroupTeacher",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `classGroupId` INTEGER NOT NULL, `teacherId` INTEGER NOT NULL, FOREIGN KEY(`classGroupId`) REFERENCES `ClassGroup`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`teacherId`) REFERENCES `Teacher`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classGroupId",
+ "columnName": "classGroupId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherId",
+ "columnName": "teacherId",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "uid"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_ClassGroupTeacher_classGroupId_teacherId",
+ "unique": true,
+ "columnNames": [
+ "classGroupId",
+ "teacherId"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ClassGroupTeacher_classGroupId_teacherId` ON `${TABLE_NAME}` (`classGroupId`, `teacherId`)"
+ },
+ {
+ "name": "index_ClassGroupTeacher_teacherId",
+ "unique": false,
+ "columnNames": [
+ "teacherId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassGroupTeacher_teacherId` ON `${TABLE_NAME}` (`teacherId`)"
+ },
+ {
+ "name": "index_ClassGroupTeacher_classGroupId",
+ "unique": false,
+ "columnNames": [
+ "classGroupId"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_ClassGroupTeacher_classGroupId` ON `${TABLE_NAME}` (`classGroupId`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "ClassGroup",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "classGroupId"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ },
+ {
+ "table": "Teacher",
+ "onDelete": "CASCADE",
+ "onUpdate": "CASCADE",
+ "columns": [
+ "teacherId"
+ ],
+ "referencedColumns": [
+ "uid"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "EdgeAccessToken",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accessToken` TEXT NOT NULL, `id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "accessToken",
+ "columnName": "accessToken",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "EdgeServiceAccount",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `email` TEXT, `imageUrl` TEXT, `me` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "imageUrl",
+ "columnName": "imageUrl",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "me",
+ "columnName": "me",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": false,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "EdgeParadoxSearchableItem",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `serviceId` TEXT NOT NULL, `displayName` TEXT NOT NULL, `subtitle` TEXT, `displayImage` TEXT, `type` INTEGER NOT NULL, `searchable` TEXT, `optionalReference` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "serviceId",
+ "columnName": "serviceId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "displayName",
+ "columnName": "displayName",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subtitle",
+ "columnName": "subtitle",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayImage",
+ "columnName": "displayImage",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "searchable",
+ "columnName": "searchable",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "optionalReference",
+ "columnName": "optionalReference",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "autoGenerate": true,
+ "columnNames": [
+ "id"
+ ]
+ },
+ "indices": [
+ {
+ "name": "index_EdgeParadoxSearchableItem_serviceId_type",
+ "unique": false,
+ "columnNames": [
+ "serviceId",
+ "type"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_EdgeParadoxSearchableItem_serviceId_type` ON `${TABLE_NAME}` (`serviceId`, `type`)"
+ }
+ ],
+ "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, '247db668ab54e74671c4844334d9722f')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a2137c7d9..f451135ee 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -31,7 +31,6 @@
-
diff --git a/app/src/main/assets/unes_account_why.md b/app/src/main/assets/unes_account_why.md
new file mode 100644
index 000000000..f67260e73
--- /dev/null
+++ b/app/src/main/assets/unes_account_why.md
@@ -0,0 +1,25 @@
+### Longo demais, quero resumo. (TLDR;)
+Criar conta permite que eu te dê acesso correto dentro do aplicativo sem precisar depender do portal nem de lógicas malucas para tentar descobrir quem é quem.
+
+### História
+A maioria dos processos do UNES ocorrem somente no dispositivo, e quando se trata disso, tudo que voce obteve de acesso sozinho é confiavel para ser mostrado no aplicativo.
+
+Contudo, isso muda quando as informações passam a fazer parte do "UNESverso",
+neste contexto eu preciso de alguma maneira de saber se a informação é real e se você "é realmente quem diz ser".
+
+Por isso, para te autenticar, o UNESverso precisava realizar uma série de operações que se tornaram cada vez mais complicadas, sem falar no captcha que ainda estraga muita coisa.
+
+### Mas por que isso é importante?
+Talvez voce tenha a pergunta:
+`"O UNES realmente precisa autenticar os alunos? Por que não simplesmente confiar em todos?"`
+E a resposta que tenho para isso é que a maioria esmagadora das coisas é aberta, mas, existem algumas funcionalidades onde somente uma pessoa pode acessar e editar.
+Por exemplo: editar o seu perfil colocando uma foto, validar se as informacoes contríbuidas para o Paradoxo não são duplicadas etc.
+
+### Sério? Preciso mesmo?
+A resposta para esta pergunta é não.
+
+Mas, as pessoas que optarem por criar uma conta e verificarem ela usando um email, podem passar a receber notificações de forma mais consistente, já que o servidor pode confiar na conta do portal que foi vinculada ao UNES e enviar notificações de atualização de forma assertiva.
+
+Já imaginou como seria triste receber uma notificacao: "Hoje nao tem aula", mas a notificação nao era na verdade para voce? Ou... "Eu acabei de chegar na universidade, por que nao consigo acessar o UNESverso?".
+
+Dito tudo isso, estou aberto a feedbacks, se você acha que isso não deveria ser assim ou se tem alguma sugestão, manda no email: joaopaulo761@gmail.com
diff --git a/app/src/main/java/com/forcetower/uefs/GooglePlayGamesInstance.kt b/app/src/main/java/com/forcetower/uefs/GooglePlayGamesInstance.kt
index d04c83027..37e3360bf 100644
--- a/app/src/main/java/com/forcetower/uefs/GooglePlayGamesInstance.kt
+++ b/app/src/main/java/com/forcetower/uefs/GooglePlayGamesInstance.kt
@@ -1,133 +1,135 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs
-
-import android.app.Activity
-import android.content.ContextWrapper
-import androidx.annotation.StringRes
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.preference.PreferenceManager
-import com.forcetower.core.lifecycle.Event
-import com.google.android.gms.games.PlayGames
-import kotlinx.coroutines.tasks.await
-
-class GooglePlayGamesInstance(
- private val activity: Activity
-) : ContextWrapper(activity) {
- private var playerName: String? = null
- val signInClient = PlayGames.getGamesSignInClient(activity)
- val achievementsClient = PlayGames.getAchievementsClient(activity)
-
- private val preferences = PreferenceManager.getDefaultSharedPreferences(this)
- private var playerUnlockedSwitch: Boolean = false
-
- private val _status = MutableLiveData>()
- val connectionStatus: LiveData>
- get() = _status
-
- /**
- * Deve ser chamado quando o usuário de conectar com a conta do google para que o objeto possa
- * criar todas as dependencias
- */
- fun onConnected() {
- _status.postValue(Event(GameConnectionStatus.CONNECTED))
- preferences.edit().putBoolean("google_play_games_enabled_v2", true).apply()
- unlockAchievement(R.string.achievement_comeou_o_jogo)
- if (playerUnlockedSwitch) {
- unlockAchievement(R.string.achievement_agora_eu_entendi_agora_eu_saquei)
- }
- }
-
- /**
- * Deve ser chamado quando o usuário optar por sair do jogo
- */
- fun onDisconnected() {
- _status.postValue(Event(GameConnectionStatus.DISCONNECTED))
- preferences.edit().putBoolean("google_play_games_enabled_v2", false).apply()
- }
-
- /**
- * Chame este método para desconectar o usuário do google play games
- */
- fun disconnect() {
- // removed. i guess
- }
-
- /**
- * Chame este método quando ocorrer uma troca de conta... Por causa de motivos...
- */
- fun changePlayerName(other: String) {
- playerUnlockedSwitch = playerName != null && other != playerName
- playerName = other
- if (playerUnlockedSwitch) {
- unlockAchievement(R.string.achievement_agora_eu_entendi_agora_eu_saquei)
- }
- }
-
- /**
- * Retorna se existe alguem conectado às contas do google ou não
- */
- suspend fun isConnected(): Boolean {
- return PlayGames.getGamesSignInClient(activity).isAuthenticated.await().isAuthenticated
- }
-
- /**
- * Descobre se o Google Play Games está ativado ou desativado
- */
- fun isPlayGamesEnabled(): Boolean {
- return preferences.getBoolean("google_play_games_enabled_v2", false)
- }
-
- /**
- * Desbloqueia uma conquista
- */
- fun unlockAchievement(@StringRes resource: Int) {
- unlockAchievement(getString(resource))
- }
-
- fun unlockAchievement(achievement: String) {
- achievementsClient?.unlock(achievement)
- }
-
- fun revealAchievement(@StringRes resource: Int) {
- val id = getString(resource)
- achievementsClient?.reveal(id)
- }
-
- fun incrementAchievement(@StringRes resource: Int, step: Int) {
- val id = getString(resource)
- achievementsClient?.increment(id, step)
- }
-
- fun updateProgress(@StringRes resource: Int, value: Int) {
- val id = getString(resource)
- achievementsClient?.setSteps(id, value)
- }
-
- fun updateProgress(id: String, value: Int) {
- achievementsClient?.setSteps(id, value)
- }
-}
-
-enum class GameConnectionStatus {
- CONNECTED, DISCONNECTED, LOADING
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs
+
+import android.app.Activity
+import android.content.ContextWrapper
+import androidx.annotation.StringRes
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.preference.PreferenceManager
+import com.forcetower.core.lifecycle.Event
+import com.google.android.gms.games.PlayGames
+import kotlinx.coroutines.tasks.await
+
+class GooglePlayGamesInstance(
+ private val activity: Activity
+) : ContextWrapper(activity) {
+ private var playerName: String? = null
+ val signInClient = PlayGames.getGamesSignInClient(activity)
+ val achievementsClient = PlayGames.getAchievementsClient(activity)
+
+ private val preferences = PreferenceManager.getDefaultSharedPreferences(this)
+ private var playerUnlockedSwitch: Boolean = false
+
+ private val _status = MutableLiveData>()
+ val connectionStatus: LiveData>
+ get() = _status
+
+ /**
+ * Deve ser chamado quando o usuário de conectar com a conta do google para que o objeto possa
+ * criar todas as dependencias
+ */
+ fun onConnected() {
+ _status.postValue(Event(GameConnectionStatus.CONNECTED))
+ preferences.edit().putBoolean("google_play_games_enabled_v2", true).apply()
+ unlockAchievement(R.string.achievement_comeou_o_jogo)
+ if (playerUnlockedSwitch) {
+ unlockAchievement(R.string.achievement_agora_eu_entendi_agora_eu_saquei)
+ }
+ }
+
+ /**
+ * Deve ser chamado quando o usuário optar por sair do jogo
+ */
+ fun onDisconnected() {
+ _status.postValue(Event(GameConnectionStatus.DISCONNECTED))
+ preferences.edit().putBoolean("google_play_games_enabled_v2", false).apply()
+ }
+
+ /**
+ * Chame este método para desconectar o usuário do google play games
+ */
+ fun disconnect() {
+ // removed. i guess
+ }
+
+ /**
+ * Chame este método quando ocorrer uma troca de conta... Por causa de motivos...
+ */
+ fun changePlayerName(other: String) {
+ playerUnlockedSwitch = playerName != null && other != playerName
+ playerName = other
+ if (playerUnlockedSwitch) {
+ unlockAchievement(R.string.achievement_agora_eu_entendi_agora_eu_saquei)
+ }
+ }
+
+ /**
+ * Retorna se existe alguem conectado às contas do google ou não
+ */
+ suspend fun isConnected(): Boolean {
+ return PlayGames.getGamesSignInClient(activity).isAuthenticated.await().isAuthenticated
+ }
+
+ /**
+ * Descobre se o Google Play Games está ativado ou desativado
+ */
+ fun isPlayGamesEnabled(): Boolean {
+ return preferences.getBoolean("google_play_games_enabled_v2", false)
+ }
+
+ /**
+ * Desbloqueia uma conquista
+ */
+ fun unlockAchievement(@StringRes resource: Int) {
+ unlockAchievement(getString(resource))
+ }
+
+ fun unlockAchievement(achievement: String) {
+ achievementsClient?.unlock(achievement)
+ }
+
+ fun revealAchievement(@StringRes resource: Int) {
+ val id = getString(resource)
+ achievementsClient?.reveal(id)
+ }
+
+ fun incrementAchievement(@StringRes resource: Int, step: Int) {
+ val id = getString(resource)
+ achievementsClient?.increment(id, step)
+ }
+
+ fun updateProgress(@StringRes resource: Int, value: Int) {
+ val id = getString(resource)
+ achievementsClient?.setSteps(id, value)
+ }
+
+ fun updateProgress(id: String, value: Int) {
+ achievementsClient?.setSteps(id, value)
+ }
+}
+
+enum class GameConnectionStatus {
+ CONNECTED,
+ DISCONNECTED,
+ LOADING
+}
diff --git a/app/src/main/java/com/forcetower/uefs/LaunchViewModel.kt b/app/src/main/java/com/forcetower/uefs/LaunchViewModel.kt
index 41ec54d91..0bef7b3af 100644
--- a/app/src/main/java/com/forcetower/uefs/LaunchViewModel.kt
+++ b/app/src/main/java/com/forcetower/uefs/LaunchViewModel.kt
@@ -29,8 +29,8 @@ import com.forcetower.uefs.core.task.successOr
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.forcetower.unes.usecases.auth.HasEnrolledAccessUseCase
import dev.forcetower.unes.usecases.version.NotifyNewVersionUseCase
-import kotlinx.coroutines.launch
import javax.inject.Inject
+import kotlinx.coroutines.launch
@HiltViewModel
class LaunchViewModel @Inject constructor(
diff --git a/app/src/main/java/com/forcetower/uefs/UApplication.kt b/app/src/main/java/com/forcetower/uefs/UApplication.kt
index 2b01c2188..395bf1178 100644
--- a/app/src/main/java/com/forcetower/uefs/UApplication.kt
+++ b/app/src/main/java/com/forcetower/uefs/UApplication.kt
@@ -1,122 +1,123 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs
-
-import android.app.Application
-import android.content.Context
-import android.content.SharedPreferences
-import androidx.hilt.work.HiltWorkerFactory
-import androidx.work.Configuration
-import com.forcetower.sagres.SagresNavigator
-import com.forcetower.uefs.core.constants.Constants
-import com.forcetower.uefs.core.storage.cookies.CachedCookiePersistor
-import com.forcetower.uefs.core.storage.cookies.PrefsCookiePersistor
-import com.forcetower.uefs.core.work.sync.SyncMainWorker
-import com.forcetower.uefs.feature.themeswitcher.ThemePreferencesManager
-import com.forcetower.uefs.impl.AndroidBase64Encoder
-import com.forcetower.uefs.impl.CrashlyticsTree
-import com.forcetower.uefs.impl.SharedPrefsCachePersistence
-import com.forcetower.uefs.service.NotificationHelper
-import com.google.android.gms.games.PlayGamesSdk
-import com.google.android.play.core.splitcompat.SplitCompat
-import dagger.hilt.android.HiltAndroidApp
-import okhttp3.OkHttpClient
-import timber.log.Timber
-import javax.inject.Inject
-
-@HiltAndroidApp
-class UApplication : Application(), Configuration.Provider {
- @Inject lateinit var preferences: SharedPreferences
- @Inject lateinit var workerFactory: HiltWorkerFactory
-
- var disciplineToolbarDevClickCount = 0
- var messageToolbarDevClickCount = 0
-
- override fun attachBaseContext(base: Context) {
- super.attachBaseContext(base)
- SplitCompat.install(this)
- }
-
- override fun onCreate() {
- if (BuildConfig.DEBUG) {
- Timber.plant(Timber.DebugTree())
- } else {
- Timber.plant(CrashlyticsTree())
- }
- super.onCreate()
-
- if (preferences.getBoolean("google_play_games_enabled_v2", false)) {
- PlayGamesSdk.initialize(this)
- }
- setupDayNightTheme(this)
- defineWorker()
- }
-
- private fun defineWorker() {
- val worker = preferences.getString("stg_sync_worker_type", "0")?.toIntOrNull() ?: 0
- val period = preferences.getString("stg_sync_frequency", "60")?.toIntOrNull() ?: 60
- when (worker) {
- 0 -> SyncMainWorker.createWorker(this, period)
- 1 -> Unit // SyncLinkedWorker.createWorker(period, false)
- }
- }
-
- /**
- * Inicializa o objeto de conexão com o Sagres
- */
- @Inject
- fun configureSagresNavigator(client: OkHttpClient, cachingCookie: CachedCookiePersistor) {
- val selected = preferences.getString(Constants.SELECTED_INSTITUTION_KEY, "UEFS") ?: "UEFS"
- SagresNavigator.initialize(
- PrefsCookiePersistor(this),
- cachingCookie,
- selected,
- AndroidBase64Encoder(),
- SharedPrefsCachePersistence(preferences),
- baseClient = client
- )
- }
-
- /**
- * Cria/Apaga os canais de notificação
- */
- @Inject
- fun configureNotifications() {
- NotificationHelper(this).createChannels()
- }
-
- override val workManagerConfiguration: Configuration
- get() = Configuration.Builder()
- .setWorkerFactory(workerFactory)
- .build()
-
- companion object {
- // Resetting the theme at every theme change is not a good solution
- // Find out a migration path for theme overlays to use in the future
- fun setupDayNightTheme(context: Context, resetTheme: Boolean = false) {
- ThemePreferencesManager(context).run {
- applyTheme()
- if (resetTheme) deleteSavedTheme()
- retrieveOverlay()
- }
- }
- }
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs
+
+import android.app.Application
+import android.content.Context
+import android.content.SharedPreferences
+import androidx.hilt.work.HiltWorkerFactory
+import androidx.work.Configuration
+import com.forcetower.sagres.SagresNavigator
+import com.forcetower.uefs.core.constants.Constants
+import com.forcetower.uefs.core.storage.cookies.CachedCookiePersistor
+import com.forcetower.uefs.core.storage.cookies.PrefsCookiePersistor
+import com.forcetower.uefs.core.work.sync.SyncMainWorker
+import com.forcetower.uefs.feature.themeswitcher.ThemePreferencesManager
+import com.forcetower.uefs.impl.AndroidBase64Encoder
+import com.forcetower.uefs.impl.CrashlyticsTree
+import com.forcetower.uefs.impl.SharedPrefsCachePersistence
+import com.forcetower.uefs.service.NotificationHelper
+import com.google.android.gms.games.PlayGamesSdk
+import com.google.android.play.core.splitcompat.SplitCompat
+import dagger.hilt.android.HiltAndroidApp
+import javax.inject.Inject
+import okhttp3.OkHttpClient
+import timber.log.Timber
+
+@HiltAndroidApp
+class UApplication : Application(), Configuration.Provider {
+ @Inject lateinit var preferences: SharedPreferences
+
+ @Inject lateinit var workerFactory: HiltWorkerFactory
+
+ var disciplineToolbarDevClickCount = 0
+ var messageToolbarDevClickCount = 0
+
+ override fun attachBaseContext(base: Context) {
+ super.attachBaseContext(base)
+ SplitCompat.install(this)
+ }
+
+ override fun onCreate() {
+ if (BuildConfig.DEBUG) {
+ Timber.plant(Timber.DebugTree())
+ } else {
+ Timber.plant(CrashlyticsTree())
+ }
+ super.onCreate()
+
+ if (preferences.getBoolean("google_play_games_enabled_v2", false)) {
+ PlayGamesSdk.initialize(this)
+ }
+ setupDayNightTheme(this)
+ defineWorker()
+ }
+
+ private fun defineWorker() {
+ val worker = preferences.getString("stg_sync_worker_type", "0")?.toIntOrNull() ?: 0
+ val period = preferences.getString("stg_sync_frequency", "60")?.toIntOrNull() ?: 60
+ when (worker) {
+ 0 -> SyncMainWorker.createWorker(this, period)
+ 1 -> Unit // SyncLinkedWorker.createWorker(period, false)
+ }
+ }
+
+ /**
+ * Inicializa o objeto de conexão com o Sagres
+ */
+ @Inject
+ fun configureSagresNavigator(client: OkHttpClient, cachingCookie: CachedCookiePersistor) {
+ val selected = preferences.getString(Constants.SELECTED_INSTITUTION_KEY, "UEFS") ?: "UEFS"
+ SagresNavigator.initialize(
+ PrefsCookiePersistor(this),
+ cachingCookie,
+ selected,
+ AndroidBase64Encoder(),
+ SharedPrefsCachePersistence(preferences),
+ baseClient = client
+ )
+ }
+
+ /**
+ * Cria/Apaga os canais de notificação
+ */
+ @Inject
+ fun configureNotifications() {
+ NotificationHelper(this).createChannels()
+ }
+
+ override val workManagerConfiguration: Configuration
+ get() = Configuration.Builder()
+ .setWorkerFactory(workerFactory)
+ .build()
+
+ companion object {
+ // Resetting the theme at every theme change is not a good solution
+ // Find out a migration path for theme overlays to use in the future
+ fun setupDayNightTheme(context: Context, resetTheme: Boolean = false) {
+ ThemePreferencesManager(context).run {
+ applyTheme()
+ if (resetTheme) deleteSavedTheme()
+ retrieveOverlay()
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/receiver/OnUpgradeReceiver.kt b/app/src/main/java/com/forcetower/uefs/architecture/receiver/OnUpgradeReceiver.kt
index 8c89b14fd..4f839cbd0 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/receiver/OnUpgradeReceiver.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/receiver/OnUpgradeReceiver.kt
@@ -34,6 +34,7 @@ import javax.inject.Inject
class OnUpgradeReceiver : BroadcastReceiver() {
@Inject
lateinit var preferences: SharedPreferences
+
@Inject
lateinit var repository: UpgradeRepository
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/service/bigtray/BigTrayService.kt b/app/src/main/java/com/forcetower/uefs/architecture/service/bigtray/BigTrayService.kt
index e5f3d254a..33c32342d 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/service/bigtray/BigTrayService.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/service/bigtray/BigTrayService.kt
@@ -1,110 +1,110 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.architecture.service.bigtray
-
-import android.app.Notification
-import android.app.PendingIntent
-import android.app.Service
-import android.content.Context
-import android.content.Intent
-import android.os.Build
-import androidx.core.app.ServiceCompat
-import androidx.lifecycle.LifecycleService
-import androidx.lifecycle.Observer
-import com.forcetower.uefs.core.model.bigtray.BigTrayData
-import com.forcetower.uefs.feature.bigtray.BigTrayRepository
-import com.forcetower.uefs.service.NotificationCreator
-import dagger.hilt.android.AndroidEntryPoint
-import timber.log.Timber
-import javax.inject.Inject
-
-@AndroidEntryPoint
-class BigTrayService : LifecycleService() {
- companion object {
- private const val NOTIFICATION_BIG_TRAY = 187745
- const val START_SERVICE_ACTION = "com.forcetower.uefs.bigtray.START_FOREGROUND_SERVICE"
- const val STOP_SERVICE_ACTION = "com.forcetower.uefs.bigtray.STOP_FOREGROUND_SERVICE"
-
- @JvmStatic
- fun startService(context: Context) {
- val intent = Intent(context, BigTrayService::class.java)
- context.startService(intent)
- }
- }
-
- @Inject
- lateinit var repository: BigTrayRepository
- private var running = false
- private var trayData: BigTrayData? = null
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- super.onStartCommand(intent, flags, startId)
-
- when (intent?.action) {
- START_SERVICE_ACTION -> startComponent()
- STOP_SERVICE_ACTION -> stopComponent()
- else -> startComponent()
- }
-
- return Service.START_STICKY
- }
-
- private fun stopComponent() {
- Timber.d("Stop service action")
- running = false
- ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
- stopSelf()
- }
-
- private fun startComponent() {
- if (!running) {
- running = true
- Timber.d("Start action!")
- startForeground(NOTIFICATION_BIG_TRAY, createNotification())
- repository.beginWith(7000).observe(
- this,
- Observer {
- if (trayData != it) {
- trayData = it
- startForeground(NOTIFICATION_BIG_TRAY, createNotification(it))
- }
- }
- )
- } else {
- Timber.d("Ignored new run attempt while it's already running")
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- repository.requesting = false
- running = false
- }
-
- private fun createNotification(data: BigTrayData? = null): Notification {
- val intent = Intent(this, BigTrayService::class.java).apply {
- action = STOP_SERVICE_ACTION
- }
- val flags = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0
- val pending = PendingIntent.getService(this, 0, intent, flags)
- return NotificationCreator.showBigTrayNotification(this, data, pending)
- }
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.architecture.service.bigtray
+
+import android.app.Notification
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import androidx.core.app.ServiceCompat
+import androidx.lifecycle.LifecycleService
+import androidx.lifecycle.Observer
+import com.forcetower.uefs.core.model.bigtray.BigTrayData
+import com.forcetower.uefs.feature.bigtray.BigTrayRepository
+import com.forcetower.uefs.service.NotificationCreator
+import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
+import timber.log.Timber
+
+@AndroidEntryPoint
+class BigTrayService : LifecycleService() {
+ companion object {
+ private const val NOTIFICATION_BIG_TRAY = 187745
+ const val START_SERVICE_ACTION = "com.forcetower.uefs.bigtray.START_FOREGROUND_SERVICE"
+ const val STOP_SERVICE_ACTION = "com.forcetower.uefs.bigtray.STOP_FOREGROUND_SERVICE"
+
+ @JvmStatic
+ fun startService(context: Context) {
+ val intent = Intent(context, BigTrayService::class.java)
+ context.startService(intent)
+ }
+ }
+
+ @Inject
+ lateinit var repository: BigTrayRepository
+ private var running = false
+ private var trayData: BigTrayData? = null
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ super.onStartCommand(intent, flags, startId)
+
+ when (intent?.action) {
+ START_SERVICE_ACTION -> startComponent()
+ STOP_SERVICE_ACTION -> stopComponent()
+ else -> startComponent()
+ }
+
+ return Service.START_STICKY
+ }
+
+ private fun stopComponent() {
+ Timber.d("Stop service action")
+ running = false
+ ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
+ stopSelf()
+ }
+
+ private fun startComponent() {
+ if (!running) {
+ running = true
+ Timber.d("Start action!")
+ startForeground(NOTIFICATION_BIG_TRAY, createNotification())
+ repository.beginWith(7000).observe(
+ this,
+ Observer {
+ if (trayData != it) {
+ trayData = it
+ startForeground(NOTIFICATION_BIG_TRAY, createNotification(it))
+ }
+ }
+ )
+ } else {
+ Timber.d("Ignored new run attempt while it's already running")
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ repository.requesting = false
+ running = false
+ }
+
+ private fun createNotification(data: BigTrayData? = null): Notification {
+ val intent = Intent(this, BigTrayService::class.java).apply {
+ action = STOP_SERVICE_ACTION
+ }
+ val flags = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0
+ val pending = PendingIntent.getService(this, 0, intent, flags)
+ return NotificationCreator.showBigTrayNotification(this, data, pending)
+ }
+}
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/service/discipline/DisciplineDetailsLoaderService.kt b/app/src/main/java/com/forcetower/uefs/architecture/service/discipline/DisciplineDetailsLoaderService.kt
index 7787bb32b..6a65a17e9 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/service/discipline/DisciplineDetailsLoaderService.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/service/discipline/DisciplineDetailsLoaderService.kt
@@ -39,8 +39,8 @@ import com.forcetower.uefs.core.storage.repository.DisciplineDetailsRepository
import com.forcetower.uefs.core.util.isConnectedToInternet
import com.forcetower.uefs.service.NotificationCreator
import dagger.hilt.android.AndroidEntryPoint
-import timber.log.Timber
import javax.inject.Inject
+import timber.log.Timber
@AndroidEntryPoint
class DisciplineDetailsLoaderService : LifecycleService() {
@@ -59,6 +59,7 @@ class DisciplineDetailsLoaderService : LifecycleService() {
@Inject
lateinit var repository: DisciplineDetailsRepository
+
@Inject
lateinit var preferences: SharedPreferences
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/service/firebase/FirebaseActionsService.kt b/app/src/main/java/com/forcetower/uefs/architecture/service/firebase/FirebaseActionsService.kt
index 7ad280f18..70f277546 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/service/firebase/FirebaseActionsService.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/service/firebase/FirebaseActionsService.kt
@@ -24,13 +24,13 @@ import com.forcetower.uefs.core.storage.repository.FirebaseMessageRepository
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import timber.log.Timber
-import javax.inject.Inject
@AndroidEntryPoint
class FirebaseActionsService : FirebaseMessagingService() {
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/service/sync/SyncService.kt b/app/src/main/java/com/forcetower/uefs/architecture/service/sync/SyncService.kt
index 8c6319212..949f0a8d9 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/service/sync/SyncService.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/service/sync/SyncService.kt
@@ -33,18 +33,19 @@ import com.forcetower.uefs.core.storage.repository.MicroSyncRepository
import com.forcetower.uefs.core.storage.repository.SagresSyncRepository
import com.forcetower.uefs.service.NotificationCreator
import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
-import javax.inject.Inject
@AndroidEntryPoint
class SyncService : LifecycleService() {
@Inject
lateinit var generalRepository: SagresSyncRepository
+
@Inject
lateinit var microRepository: MicroSyncRepository
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidget.kt b/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidget.kt
index 49fb9e02d..32e85b45c 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidget.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidget.kt
@@ -29,12 +29,12 @@ import com.forcetower.uefs.core.storage.repository.DisciplinesRepository
import com.forcetower.uefs.feature.shared.extensions.toTitleCase
import com.google.firebase.analytics.FirebaseAnalytics
import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
-import javax.inject.Inject
@AndroidEntryPoint
class HomeClassWidget : AppWidgetProvider() {
diff --git a/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidgetSecondary.kt b/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidgetSecondary.kt
index 9e656863a..994efdbab 100644
--- a/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidgetSecondary.kt
+++ b/app/src/main/java/com/forcetower/uefs/architecture/widget/HomeClassWidgetSecondary.kt
@@ -29,12 +29,12 @@ import com.forcetower.uefs.core.storage.repository.DisciplinesRepository
import com.forcetower.uefs.feature.shared.extensions.toTitleCase
import com.google.firebase.analytics.FirebaseAnalytics
import dagger.hilt.android.AndroidEntryPoint
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
-import javax.inject.Inject
@AndroidEntryPoint
class HomeClassWidgetSecondary : AppWidgetProvider() {
diff --git a/app/src/main/java/com/forcetower/uefs/core/billing/SkuResults.kt b/app/src/main/java/com/forcetower/uefs/core/billing/SkuResults.kt
deleted file mode 100644
index 8096d5b69..000000000
--- a/app/src/main/java/com/forcetower/uefs/core/billing/SkuResults.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.billing
-
-import com.android.billingclient.api.ProductDetails
-
-data class SkuDetailsResult(
- val responseCode: Int,
- val list: List? = null
-)
-
-data class SkuConsumeResult(
- val responseCode: Int,
- val token: String? = null
-)
diff --git a/app/src/main/java/com/forcetower/uefs/core/constants/Constants.kt b/app/src/main/java/com/forcetower/uefs/core/constants/Constants.kt
index 21c7f26f9..ddcff8cab 100644
--- a/app/src/main/java/com/forcetower/uefs/core/constants/Constants.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/constants/Constants.kt
@@ -24,7 +24,6 @@ object Constants {
const val SELECTED_INSTITUTION_KEY = "selected_institution_worker"
const val UNES_SERVICE_BASE_URL = "unes.forcetower.dev"
const val EDGE_UNES_SERVICE_BASE_URL = "edge-unes.forcetower.dev"
- private const val UNES_SERVICE_BASE_UPDATE = "unes.herokuapp.com"
const val UNES_SERVICE_URL = "https://$UNES_SERVICE_BASE_URL/api/"
const val EDGE_UNES_SERVICE_URL = "https://$EDGE_UNES_SERVICE_BASE_URL/api/"
@@ -34,8 +33,6 @@ object Constants {
val HARD_DISCIPLINES = mapOf("TEC501" to "__ANY__")
val EXECUTOR_WHITELIST = listOf("manual", "universal")
- const val ADMOB_TEST_ID = "38D27336B4D54E6E431E86E4ABEE0B20"
-
const val SERVICE_CLIENT_ID = "1"
const val SERVICE_CLIENT_SECRET = "bCP23X90J5anU0H3uxzWg0RwE6BxEo0HDkqr0PZg"
const val SERVICE_CLIENT_INSTITUTION = "uefs"
diff --git a/app/src/main/java/com/forcetower/uefs/core/effects/purchases/ScoreIncreaseEffect.kt b/app/src/main/java/com/forcetower/uefs/core/effects/purchases/ScoreIncreaseEffect.kt
index aeffb1f1d..971c801e6 100644
--- a/app/src/main/java/com/forcetower/uefs/core/effects/purchases/ScoreIncreaseEffect.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/effects/purchases/ScoreIncreaseEffect.kt
@@ -21,9 +21,9 @@
package com.forcetower.uefs.core.effects.purchases
import android.content.SharedPreferences
-import timber.log.Timber
import java.util.Calendar
import javax.inject.Inject
+import timber.log.Timber
class ScoreIncreaseEffect @Inject constructor(
private val preferences: SharedPreferences
diff --git a/app/src/main/java/com/forcetower/uefs/core/injection/module/AppModule.kt b/app/src/main/java/com/forcetower/uefs/core/injection/module/AppModule.kt
index a3185d694..aeb55d0c5 100644
--- a/app/src/main/java/com/forcetower/uefs/core/injection/module/AppModule.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/injection/module/AppModule.kt
@@ -22,7 +22,7 @@ package com.forcetower.uefs.core.injection.module
import android.content.Context
import android.content.SharedPreferences
-import android.webkit.WebSettings
+import android.os.Build
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
@@ -44,7 +44,6 @@ import dagger.Reusable
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
-import timber.log.Timber
import javax.inject.Named
import javax.inject.Singleton
@@ -105,13 +104,25 @@ object AppModule {
@Provides
@Reusable
@Named("webViewUA")
- fun provideWebViewUserAgent(context: Context): String {
- return try {
- WebSettings.getDefaultUserAgent(context)
- } catch (error: Throwable) {
- Timber.w("Failed to obtain device UserAgent")
- Timber.w("UserAgent error ${error.message}")
- "Mozilla/5.0 (Linux; Android 10; MI 9 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/123.0.6312.118 Mobile Safari/537.36"
- }
+ fun provideWebViewUserAgent(): String {
+ val agents = listOf(
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15",
+ "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36",
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.2 (a) Mobile/15E148 Safari/604.1",
+ "Mozilla/5.0 (Linux; Android 14; SM-S928B Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36",
+ "Mozilla/5.0 (Linux; Android 10; MI 9 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/123.0.6312.118 Mobile Safari/537.36",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
+ )
+ return agents.random()
+ }
+
+ @Provides
+ @Reusable
+ @Named("unesUserAgent")
+ fun provideUnesUserAgent(context: Context): String {
+ val version = context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: "0.0.-1"
+ val parts = version.split(".")
+ return "UNES/${parts[0]}.${parts[1]}.${parts[2]}.${parts[3]} (Android ${Build.VERSION.RELEASE}; Build/${Build.MODEL})"
}
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/injection/module/FirebaseCoreModule.kt b/app/src/main/java/com/forcetower/uefs/core/injection/module/FirebaseCoreModule.kt
index ee3ad546d..0d7db2773 100644
--- a/app/src/main/java/com/forcetower/uefs/core/injection/module/FirebaseCoreModule.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/injection/module/FirebaseCoreModule.kt
@@ -34,8 +34,8 @@ import dagger.Provides
import dagger.Reusable
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
-import timber.log.Timber
import javax.inject.Singleton
+import timber.log.Timber
@Module
@InstallIn(SingletonComponent::class)
diff --git a/app/src/main/java/com/forcetower/uefs/core/injection/module/NetworkModule.kt b/app/src/main/java/com/forcetower/uefs/core/injection/module/NetworkModule.kt
index a5d07aa6e..29616607a 100644
--- a/app/src/main/java/com/forcetower/uefs/core/injection/module/NetworkModule.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/injection/module/NetworkModule.kt
@@ -29,6 +29,7 @@ import com.forcetower.uefs.core.constants.Constants
import com.forcetower.uefs.core.storage.cookies.CachedCookiePersistor
import com.forcetower.uefs.core.storage.database.UDatabase
import com.forcetower.uefs.core.storage.network.EdgeService
+import com.forcetower.uefs.core.storage.network.ParadoxService
import com.forcetower.uefs.core.storage.network.UService
import com.forcetower.uefs.core.storage.network.github.GithubService
import com.forcetower.uefs.core.util.ObjectUtils
@@ -42,6 +43,12 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
+import java.net.CookieHandler
+import java.net.CookieManager
+import java.time.ZonedDateTime
+import java.util.concurrent.TimeUnit
+import javax.inject.Named
+import javax.inject.Singleton
import kotlinx.coroutines.runBlocking
import okhttp3.ConnectionSpec
import okhttp3.Interceptor
@@ -50,12 +57,6 @@ import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import timber.log.Timber
-import java.net.CookieHandler
-import java.net.CookieManager
-import java.time.ZonedDateTime
-import java.util.concurrent.TimeUnit
-import javax.inject.Named
-import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
@@ -93,10 +94,11 @@ object NetworkModule {
HttpLoggingInterceptor {
Timber.tag("ok-http").d(it)
}.apply {
- level = if (BuildConfig.DEBUG)
+ level = if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BASIC
- else
+ } else {
HttpLoggingInterceptor.Level.NONE
+ }
}
)
.addInterceptor(chuckerInterceptor)
@@ -107,7 +109,7 @@ object NetworkModule {
@Singleton
fun provideInterceptor(
database: UDatabase,
- @Named("webViewUA") userAgent: String
+ @Named("unesUserAgent") userAgent: String
) = Interceptor { chain ->
val request = chain.request()
val host = request.url.host
@@ -140,7 +142,7 @@ object NetworkModule {
val renewed = request.newBuilder().headers(newHeaders).build()
chain.proceed(renewed)
- } else {
+ } else {
val nRequest = request.newBuilder().addHeader("Accept", "application/json").build()
chain.proceed(nRequest)
}
@@ -198,12 +200,23 @@ object NetworkModule {
@Provides
@Singleton
- fun provideEdgeService(client: OkHttpClient): EdgeService {
+ fun provideEdgeService(client: OkHttpClient, gson: Gson): EdgeService {
return Retrofit.Builder()
.baseUrl(Constants.EDGE_UNES_SERVICE_URL)
.client(client)
- .addConverterFactory(GsonConverterFactory.create())
+ .addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(EdgeService::class.java)
}
+
+ @Provides
+ @Singleton
+ fun provideParadoxService(client: OkHttpClient, gson: Gson): ParadoxService {
+ return Retrofit.Builder()
+ .baseUrl(Constants.EDGE_UNES_SERVICE_URL)
+ .client(client)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build()
+ .create(ParadoxService::class.java)
+ }
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/api/UResponse.kt b/app/src/main/java/com/forcetower/uefs/core/model/api/UResponse.kt
index 55e8bdd2d..45e13e60c 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/api/UResponse.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/api/UResponse.kt
@@ -1,27 +1,27 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.model.api
-
-data class UResponse (
- val success: Boolean = false,
- val message: String? = null,
- val data: T? = null
-)
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.model.api
+
+data class UResponse(
+ val success: Boolean = false,
+ val message: String? = null,
+ val data: T? = null
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/bigtray/BigTrayData.kt b/app/src/main/java/com/forcetower/uefs/core/model/bigtray/BigTrayData.kt
index c28170e2e..48a4c303d 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/bigtray/BigTrayData.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/bigtray/BigTrayData.kt
@@ -1,133 +1,135 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.model.bigtray
-
-import androidx.core.math.MathUtils.clamp
-import com.forcetower.uefs.feature.shared.extensions.toCalendar
-import timber.log.Timber
-import java.util.Calendar
-import java.util.Calendar.SATURDAY
-import java.util.Calendar.SUNDAY
-import java.util.Objects
-
-data class BigTrayData(
- val open: Boolean,
- val quota: String,
- val error: Boolean,
- val time: Long,
- val type: String
-) {
- companion object {
- const val COFFEE = 1
- const val LUNCH = 2
- const val DINNER = 3
-
- fun error() = BigTrayData(false, "", true, System.currentTimeMillis(), "")
- fun closed() = BigTrayData(false, "0", false, System.currentTimeMillis(), "")
- fun createData(values: List) = BigTrayData(true, values[1].trim(), false, System.currentTimeMillis(), values[0].trim())
- }
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (other == null || javaClass != other.javaClass) return false
- val that = other as BigTrayData? ?: return false
- return open == that.open &&
- quota == that.quota &&
- error == that.error &&
- type == that.type
- }
-
- override fun hashCode(): Int {
- return Objects.hash(open, quota, error, type, time)
- }
-}
-
-fun BigTrayData.getNextMealType(): Int {
- val calendar = this.time.toCalendar()
- val hour = calendar.get(Calendar.HOUR_OF_DAY)
- val minutes = calendar.get(Calendar.MINUTE)
- val account = hour * 60 + minutes
-
- return when {
- account < 9.5 * 60 -> BigTrayData.COFFEE
- account < 14.5 * 60 -> BigTrayData.LUNCH
- account < 20 * 60 -> BigTrayData.DINNER
- else -> BigTrayData.COFFEE
- }
-}
-
-fun BigTrayData.getPrice(): String {
- val type = getNextMealType()
- var amount = 0
- try {
- amount = this.quota.toInt()
- } catch (e: Exception) {}
-
- return when (type) {
- BigTrayData.COFFEE -> if (amount <= 0) "R$ 4,63" else "R$ 0,50"
- BigTrayData.LUNCH -> if (amount <= 0) "R$ 8,56" else "R$ 1,00"
- BigTrayData.DINNER -> if (amount <= 0) "R$ 3,94" else "R$ 0,70"
- else -> "R$ 1,00"
- }
-}
-
-fun BigTrayData.getNextMealTime(): String {
- val calendar = this.time.toCalendar()
- val day = calendar.get(Calendar.DAY_OF_WEEK)
-
- when (getNextMealType()) {
- BigTrayData.COFFEE -> return if (day == SUNDAY) "07h30min às 09h00min" else "06h30min às 09h00min"
- BigTrayData.LUNCH -> {
- if (day == SUNDAY) return "11h30min às 13h30min"
- return if (day == SATURDAY) "11h30min às 14h00min" else "10h30min às 14h00min"
- }
- else -> {
- if (day == SUNDAY) return "17h30min às 19h00min"
- return if (day == SATURDAY) "17h30min às 19h00min" else "17h30min às 19h30min"
- }
- }
-}
-
-fun BigTrayData.isOpen(): Boolean {
- var amount = -1
- try { amount = quota.toInt() } catch (e: Exception) {}
- return open && amount != -1
-}
-
-fun BigTrayData.percentage(): Float {
- try {
- val amount = quota.toFloat()
- val type = getNextMealType()
-
- return clamp(
- amount / when (type) {
- BigTrayData.LUNCH -> 1450
- BigTrayData.DINNER -> 490
- else -> 320
- },
- 0f,
- 1f
- ) * 100
- } catch (e: Exception) {
- Timber.d(e.message)
- }
- return 0.0f
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.model.bigtray
+
+import androidx.core.math.MathUtils.clamp
+import com.forcetower.uefs.feature.shared.extensions.toCalendar
+import java.util.Calendar
+import java.util.Calendar.SATURDAY
+import java.util.Calendar.SUNDAY
+import java.util.Objects
+import timber.log.Timber
+
+data class BigTrayData(
+ val open: Boolean,
+ val quota: String,
+ val error: Boolean,
+ val time: Long,
+ val type: String
+) {
+ companion object {
+ const val COFFEE = 1
+ const val LUNCH = 2
+ const val DINNER = 3
+
+ fun error() = BigTrayData(false, "", true, System.currentTimeMillis(), "")
+ fun closed() = BigTrayData(false, "0", false, System.currentTimeMillis(), "")
+ fun createData(values: List) = BigTrayData(true, values[1].trim(), false, System.currentTimeMillis(), values[0].trim())
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || javaClass != other.javaClass) return false
+ val that = other as BigTrayData? ?: return false
+ return open == that.open &&
+ quota == that.quota &&
+ error == that.error &&
+ type == that.type
+ }
+
+ override fun hashCode(): Int {
+ return Objects.hash(open, quota, error, type, time)
+ }
+}
+
+fun BigTrayData.getNextMealType(): Int {
+ val calendar = this.time.toCalendar()
+ val hour = calendar.get(Calendar.HOUR_OF_DAY)
+ val minutes = calendar.get(Calendar.MINUTE)
+ val account = hour * 60 + minutes
+
+ return when {
+ account < 9.5 * 60 -> BigTrayData.COFFEE
+ account < 14.5 * 60 -> BigTrayData.LUNCH
+ account < 20 * 60 -> BigTrayData.DINNER
+ else -> BigTrayData.COFFEE
+ }
+}
+
+fun BigTrayData.getPrice(): String {
+ val type = getNextMealType()
+ var amount = 0
+ try {
+ amount = this.quota.toInt()
+ } catch (e: Exception) {}
+
+ return when (type) {
+ BigTrayData.COFFEE -> if (amount <= 0) "R$ 4,63" else "R$ 0,50"
+ BigTrayData.LUNCH -> if (amount <= 0) "R$ 8,56" else "R$ 1,00"
+ BigTrayData.DINNER -> if (amount <= 0) "R$ 3,94" else "R$ 0,70"
+ else -> "R$ 1,00"
+ }
+}
+
+fun BigTrayData.getNextMealTime(): String {
+ val calendar = this.time.toCalendar()
+ val day = calendar.get(Calendar.DAY_OF_WEEK)
+
+ when (getNextMealType()) {
+ BigTrayData.COFFEE -> return if (day == SUNDAY) "07h30min às 09h00min" else "06h30min às 09h00min"
+ BigTrayData.LUNCH -> {
+ if (day == SUNDAY) return "11h30min às 13h30min"
+ return if (day == SATURDAY) "11h30min às 14h00min" else "10h30min às 14h00min"
+ }
+ else -> {
+ if (day == SUNDAY) return "17h30min às 19h00min"
+ return if (day == SATURDAY) "17h30min às 19h00min" else "17h30min às 19h30min"
+ }
+ }
+}
+
+fun BigTrayData.isOpen(): Boolean {
+ var amount = -1
+ try {
+ amount = quota.toInt()
+ } catch (e: Exception) {}
+ return open && amount != -1
+}
+
+fun BigTrayData.percentage(): Float {
+ try {
+ val amount = quota.toFloat()
+ val type = getNextMealType()
+
+ return clamp(
+ amount / when (type) {
+ BigTrayData.LUNCH -> 1450
+ BigTrayData.DINNER -> 490
+ else -> 320
+ },
+ 0f,
+ 1f
+ ) * 100
+ } catch (e: Exception) {
+ Timber.d(e.message)
+ }
+ return 0.0f
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/ChangePictureDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/account/ChangePictureDTO.kt
similarity index 72%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/ChangePictureDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/account/ChangePictureDTO.kt
index 729ed51b2..a6e41f639 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/ChangePictureDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/account/ChangePictureDTO.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.account
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/SendMessagingTokenDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/account/SendMessagingTokenDTO.kt
similarity index 72%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/SendMessagingTokenDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/account/SendMessagingTokenDTO.kt
index 768b93d73..9adfc8bad 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/SendMessagingTokenDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/account/SendMessagingTokenDTO.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.account
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/ServiceAccountDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/account/ServiceAccountDTO.kt
similarity index 84%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/ServiceAccountDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/account/ServiceAccountDTO.kt
index b436b2262..b53513239 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/ServiceAccountDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/account/ServiceAccountDTO.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.account
import com.google.gson.annotations.SerializedName
@@ -11,4 +11,4 @@ data class ServiceAccountDTO(
val email: String? = null,
@SerializedName("imageUrl")
val imageUrl: String? = null
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/AssertionData.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/AssertionData.kt
similarity index 61%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/AssertionData.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/AssertionData.kt
index 6276f916a..7e0d57cce 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/AssertionData.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/AssertionData.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class AssertionData(
val flowId: String,
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/CompleteAssertionData.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/CompleteAssertionData.kt
similarity index 64%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/CompleteAssertionData.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/CompleteAssertionData.kt
index c58393033..17d43f66f 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/CompleteAssertionData.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/CompleteAssertionData.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class CompleteAssertionData(
val flowId: String,
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/EdgeAccessTokenDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EdgeAccessTokenDTO.kt
similarity index 74%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/EdgeAccessTokenDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EdgeAccessTokenDTO.kt
index 5dbe192ad..c7631bec4 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/EdgeAccessTokenDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EdgeAccessTokenDTO.kt
@@ -1,8 +1,8 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
import com.google.gson.annotations.SerializedName
data class EdgeAccessTokenDTO(
@SerializedName("accessToken")
val accessToken: String
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/EdgeLoginBody.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EdgeLoginBody.kt
similarity index 70%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/EdgeLoginBody.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EdgeLoginBody.kt
index c71d0d5bb..61dde3317 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/EdgeLoginBody.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EdgeLoginBody.kt
@@ -1,7 +1,7 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class EdgeLoginBody(
val username: String,
val password: String,
val provider: String = "SNOWPIERCER"
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/EmailLinkBodyDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EmailLinkBodyDTO.kt
similarity index 73%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/EmailLinkBodyDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EmailLinkBodyDTO.kt
index 0a4dfb0fc..be9baa650 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/EmailLinkBodyDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EmailLinkBodyDTO.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/EmailLinkConfirmDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EmailLinkConfirmDTO.kt
similarity index 80%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/EmailLinkConfirmDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EmailLinkConfirmDTO.kt
index 9745720c9..a74e48bd1 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/EmailLinkConfirmDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/EmailLinkConfirmDTO.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/LinkEmailResponseDTO.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/LinkEmailResponseDTO.kt
similarity index 75%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/LinkEmailResponseDTO.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/LinkEmailResponseDTO.kt
index 8402f8bc7..24da56b8b 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/LinkEmailResponseDTO.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/LinkEmailResponseDTO.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyAssert.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/PasskeyAssert.kt
similarity index 83%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyAssert.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/PasskeyAssert.kt
index 26ea26df1..de7bee803 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyAssert.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/PasskeyAssert.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class SimplifiedPublicKey(
val challenge: String,
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyRegister.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/PasskeyRegister.kt
similarity index 94%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyRegister.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/PasskeyRegister.kt
index 683ffcd18..ce149bc20 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyRegister.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/PasskeyRegister.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class Rp(val name: String, val id: String)
data class User(val name: String, val displayName: String, val id: String)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyCredential.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/RegisterPasskeyCredential.kt
similarity index 65%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyCredential.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/RegisterPasskeyCredential.kt
index 8cdc1251b..dd34f5ed6 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyCredential.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/RegisterPasskeyCredential.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class RegisterPasskeyCredential(
val flowId: String,
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyStart.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/RegisterPasskeyStart.kt
similarity index 62%
rename from app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyStart.kt
rename to app/src/main/java/com/forcetower/uefs/core/model/edge/auth/RegisterPasskeyStart.kt
index 972afd5c7..2e1d777ad 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyStart.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/auth/RegisterPasskeyStart.kt
@@ -1,4 +1,4 @@
-package com.forcetower.uefs.core.model.edge
+package com.forcetower.uefs.core.model.edge.auth
data class RegisterPasskeyStart(
val flowId: String,
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/EvaluationHotTopic.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/EvaluationHotTopic.kt
new file mode 100644
index 000000000..f75887a94
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/EvaluationHotTopic.kt
@@ -0,0 +1,16 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class EvaluationHotTopic(
+ @SerializedName("id")
+ val id: String,
+ @SerializedName("title")
+ val title: String,
+ @SerializedName("description")
+ val description: String,
+ @SerializedName("disciplines")
+ val disciplines: List? = null,
+ @SerializedName("teachers")
+ val teachers: List? = null
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/EvaluationSnapshot.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/EvaluationSnapshot.kt
new file mode 100644
index 000000000..4eff4063d
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/EvaluationSnapshot.kt
@@ -0,0 +1,10 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class EvaluationSnapshot(
+ @SerializedName("teachers")
+ val teachers: List,
+ @SerializedName("disciplines")
+ val disciplines: List
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicDisciplineEvaluationCombinedData.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicDisciplineEvaluationCombinedData.kt
new file mode 100644
index 000000000..5fa4dbfd8
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicDisciplineEvaluationCombinedData.kt
@@ -0,0 +1,55 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class PublicDisciplineEvaluationCombinedData(
+ @SerializedName("disciplineId")
+ val disciplineId: String,
+ @SerializedName("discipline")
+ val discipline: String,
+ @SerializedName("code")
+ val code: String,
+ @SerializedName("departmentName")
+ val departmentName: String,
+ @SerializedName("mean")
+ val mean: Double,
+ @SerializedName("studentCount")
+ val studentCount: Int,
+ @SerializedName("studentCountWeighted")
+ val studentCountWeighted: Int,
+ @SerializedName("participating")
+ val participating: Boolean,
+ @SerializedName("approved")
+ val approved: Int,
+ @SerializedName("failed")
+ val failed: Int,
+ @SerializedName("quit")
+ val quit: Int,
+ @SerializedName("teachers")
+ val teachers: List
+)
+
+data class PublicDisciplineEvaluationData(
+ @SerializedName("semester")
+ val semester: String,
+ @SerializedName("semesterStart")
+ val semesterStart: String,
+ @SerializedName("semesterPlatformId")
+ val semesterPlatformId: Long,
+ @SerializedName("teacherId")
+ val teacherId: String,
+ @SerializedName("teacherName")
+ val teacherName: String,
+ @SerializedName("mean")
+ val mean: Double,
+ @SerializedName("studentCountWeighted")
+ val studentCountWeighted: Int,
+ @SerializedName("studentsCount")
+ val studentsCount: Int,
+ @SerializedName("approved")
+ val approved: Int,
+ @SerializedName("failed")
+ val failed: Int,
+ @SerializedName("quit")
+ val quit: Int
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicDisciplineSnapshot.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicDisciplineSnapshot.kt
new file mode 100644
index 000000000..e087a6227
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicDisciplineSnapshot.kt
@@ -0,0 +1,14 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class PublicDisciplineSnapshot(
+ @SerializedName("id")
+ val id: String,
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("code")
+ val code: String,
+ @SerializedName("department")
+ val department: String
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicHotEvaluationDiscipline.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicHotEvaluationDiscipline.kt
new file mode 100644
index 000000000..45d51a79d
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicHotEvaluationDiscipline.kt
@@ -0,0 +1,20 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class PublicHotEvaluationDiscipline(
+ @SerializedName("id")
+ val id: String,
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("code")
+ val code: String,
+ @SerializedName("departmentName")
+ val departmentName: String,
+ @SerializedName("departmentCode")
+ val departmentCode: String,
+ @SerializedName("mean")
+ val mean: Double,
+ @SerializedName("studentCount")
+ val studentCount: Int
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicHotEvaluationTeacher.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicHotEvaluationTeacher.kt
new file mode 100644
index 000000000..b260f4b84
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicHotEvaluationTeacher.kt
@@ -0,0 +1,14 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class PublicHotEvaluationTeacher(
+ @SerializedName("id")
+ val id: String,
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("mean")
+ val mean: Double,
+ @SerializedName("studentCount")
+ val studentCount: Int
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicTeacherEvaluationData.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicTeacherEvaluationData.kt
new file mode 100644
index 000000000..1d55f1d21
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicTeacherEvaluationData.kt
@@ -0,0 +1,49 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class PublicTeacherEvaluationData(
+ @SerializedName("disciplineId")
+ val disciplineId: String,
+ @SerializedName("departmentCode")
+ val departmentCode: String,
+ @SerializedName("departmentName")
+ val departmentName: String,
+ @SerializedName("code")
+ val code: String,
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("mean")
+ val mean: Double,
+ @SerializedName("studentCountWeighted")
+ val studentCountWeighted: Int,
+ @SerializedName("studentCount")
+ val studentCount: Int
+)
+
+data class PublicTeacherEvaluationCombinedData(
+ @SerializedName("teacherId")
+ val teacherId: String,
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("mean")
+ val mean: Double,
+ @SerializedName("studentCountWeighted")
+ val studentCountWeighted: Int,
+ @SerializedName("studentCount")
+ val studentCount: Int,
+ @SerializedName("approved")
+ val approved: Int,
+ @SerializedName("failed")
+ val failed: Int,
+ @SerializedName("quit")
+ val quit: Int,
+ @SerializedName("firstSeen")
+ val firstSeen: String,
+ @SerializedName("lastSeen")
+ val lastSeen: String,
+ @SerializedName("participant")
+ val participant: Boolean,
+ @SerializedName("disciplines")
+ val disciplines: List
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicTeacherSnapshot.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicTeacherSnapshot.kt
new file mode 100644
index 000000000..f723bceb0
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/paradox/PublicTeacherSnapshot.kt
@@ -0,0 +1,10 @@
+package com.forcetower.uefs.core.model.edge.paradox
+
+import com.google.gson.annotations.SerializedName
+
+data class PublicTeacherSnapshot(
+ @SerializedName("id")
+ val id: String,
+ @SerializedName("name")
+ val name: String
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/sync/PublicDisciplineData.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/sync/PublicDisciplineData.kt
new file mode 100644
index 000000000..4e3f6794a
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/sync/PublicDisciplineData.kt
@@ -0,0 +1,59 @@
+package com.forcetower.uefs.core.model.edge.sync
+
+import com.google.gson.annotations.SerializedName
+import java.time.ZonedDateTime
+
+data class PublicDisciplineData(
+ @SerializedName("semester")
+ val semester: PublicSemesterData,
+ @SerializedName("disciplines")
+ val disciplines: List
+)
+
+data class PublicSemesterData(
+ @SerializedName("platformId")
+ val platformId: Long,
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("codename")
+ val codename: String,
+ @SerializedName("start")
+ val start: ZonedDateTime?,
+ @SerializedName("finish")
+ val finish: ZonedDateTime?
+)
+
+data class PublicStudentDisciplineData(
+ @SerializedName("sequence")
+ val sequence: String,
+ @SerializedName("creditsOverride")
+ val creditsOverride: Int,
+ @SerializedName("discipline")
+ val discipline: PublicDiscipline,
+ @SerializedName("grades")
+ val grades: List
+)
+
+data class PublicDiscipline(
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("code")
+ val code: String,
+ @SerializedName("credits")
+ val credits: Int,
+ @SerializedName("department")
+ val department: String?,
+ @SerializedName("program")
+ val program: String?
+)
+
+data class PublicGrade(
+ @SerializedName("name")
+ val name: String,
+ @SerializedName("groupingName")
+ val groupingName: String?,
+ @SerializedName("date")
+ val date: String?,
+ @SerializedName("grade")
+ val grade: Double?
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/edge/sync/PublicPlatformMessage.kt b/app/src/main/java/com/forcetower/uefs/core/model/edge/sync/PublicPlatformMessage.kt
new file mode 100644
index 000000000..2b690cdb2
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/edge/sync/PublicPlatformMessage.kt
@@ -0,0 +1,31 @@
+package com.forcetower.uefs.core.model.edge.sync
+
+import com.google.gson.annotations.SerializedName
+import java.time.ZonedDateTime
+
+data class PublicPlatformMessage(
+ @SerializedName("id")
+ val id: String,
+ @SerializedName("platformId")
+ val platformId: Long,
+ @SerializedName("content")
+ val content: String,
+ @SerializedName("timestamp")
+ val timestamp: Long,
+ @SerializedName("senderProfile")
+ val senderProfile: Long,
+ @SerializedName("senderName")
+ val senderName: String,
+ @SerializedName("discipline")
+ val discipline: String?,
+ @SerializedName("codeDiscipline")
+ val codeDiscipline: String?,
+ @SerializedName("html")
+ val html: Boolean,
+ @SerializedName("date")
+ val date: ZonedDateTime,
+ @SerializedName("attachmentName")
+ val attachmentName: String?,
+ @SerializedName("attachmentLink")
+ val attachmentLink: String?
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/siecomp/Session.kt b/app/src/main/java/com/forcetower/uefs/core/model/siecomp/Session.kt
index 75521d71c..e5336eda6 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/siecomp/Session.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/siecomp/Session.kt
@@ -56,8 +56,10 @@ data class Session(
@Ignore
val year = startTime.year
+
@Ignore
val duration = endTime.toInstant().toEpochMilli() - startTime.toInstant().toEpochMilli()
+
@Ignore
val sessionType = when (type) {
0 -> SessionType.SPEAK
@@ -80,9 +82,10 @@ data class Session(
override fun compareTo(other: Session): Int {
val value = startTime.compareTo(other.startTime)
- return if (value != 0)
+ return if (value != 0) {
value
- else
+ } else {
duration.compareTo(other.duration)
+ }
}
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/siecomp/SessionType.kt b/app/src/main/java/com/forcetower/uefs/core/model/siecomp/SessionType.kt
index 3c5d16156..be36ffbfc 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/siecomp/SessionType.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/siecomp/SessionType.kt
@@ -21,5 +21,11 @@
package com.forcetower.uefs.core.model.siecomp
enum class SessionType {
- WORKSHOP, SPEAK, TALK, PROJECT, DEBATE, CONCLUSION, UNKNOWN
+ WORKSHOP,
+ SPEAK,
+ TALK,
+ PROJECT,
+ DEBATE,
+ CONCLUSION,
+ UNKNOWN
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkComplete.kt b/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkComplete.kt
index 20f363b82..88315178d 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkComplete.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkComplete.kt
@@ -6,4 +6,4 @@ sealed interface EmailLinkComplete {
data object EmailTaken : EmailLinkComplete
data object TooManyTries : EmailLinkComplete
data object ConnectionError : EmailLinkComplete
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkStart.kt b/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkStart.kt
index 37b325fa7..6d8d657ec 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkStart.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/ui/edge/EmailLinkStart.kt
@@ -1,7 +1,7 @@
package com.forcetower.uefs.core.model.ui.edge
sealed interface EmailLinkStart {
- data class CodeSent(val securityCode: String): EmailLinkStart
+ data class CodeSent(val securityCode: String) : EmailLinkStart
data object InvalidInfo : EmailLinkStart
data object ConnectionError : EmailLinkStart
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/unes/ClassGroupTeacher.kt b/app/src/main/java/com/forcetower/uefs/core/model/unes/ClassGroupTeacher.kt
index eb2fc1bc5..3761f9877 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/unes/ClassGroupTeacher.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/unes/ClassGroupTeacher.kt
@@ -5,17 +5,20 @@ import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
-@Entity(indices = [
- Index(value = ["classGroupId", "teacherId"], unique = true),
- Index(value = ["teacherId"], unique = false),
- Index(value = ["classGroupId"], unique = false),
-], foreignKeys = [
- ForeignKey(entity = ClassGroup::class, parentColumns = ["uid"], childColumns = ["classGroupId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE),
- ForeignKey(entity = Teacher::class, parentColumns = ["uid"], childColumns = ["teacherId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)
-])
+@Entity(
+ indices = [
+ Index(value = ["classGroupId", "teacherId"], unique = true),
+ Index(value = ["teacherId"], unique = false),
+ Index(value = ["classGroupId"], unique = false)
+ ],
+ foreignKeys = [
+ ForeignKey(entity = ClassGroup::class, parentColumns = ["uid"], childColumns = ["classGroupId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE),
+ ForeignKey(entity = Teacher::class, parentColumns = ["uid"], childColumns = ["teacherId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)
+ ]
+)
data class ClassGroupTeacher(
@PrimaryKey(autoGenerate = true)
val uid: Int,
val classGroupId: Long,
val teacherId: Long
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeAccessToken.kt b/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeAccessToken.kt
index 4937f140b..d50e11eb5 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeAccessToken.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeAccessToken.kt
@@ -8,4 +8,4 @@ data class EdgeAccessToken(
val accessToken: String,
@PrimaryKey(autoGenerate = false)
val id: Int = 1
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeParadoxSearchableItem.kt b/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeParadoxSearchableItem.kt
new file mode 100644
index 000000000..0ffc47bda
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/model/unes/EdgeParadoxSearchableItem.kt
@@ -0,0 +1,27 @@
+package com.forcetower.uefs.core.model.unes
+
+import androidx.room.Entity
+import androidx.room.Index
+import androidx.room.PrimaryKey
+
+@Entity(
+ indices = [
+ Index(value = ["serviceId", "type"])
+ ]
+)
+data class EdgeParadoxSearchableItem(
+ @PrimaryKey(autoGenerate = true)
+ val id: Long = 0,
+ val serviceId: String,
+ val displayName: String,
+ val subtitle: String?,
+ val displayImage: String?,
+ val type: Int,
+ val searchable: String?,
+ val optionalReference: String?
+) {
+ companion object {
+ const val TEACHER_TYPE = 0
+ const val DISCIPLINE_TYPE = 1
+ }
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/unes/GithubContributor.kt b/app/src/main/java/com/forcetower/uefs/core/model/unes/GithubContributor.kt
index 728d77d84..f6b9a69a7 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/unes/GithubContributor.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/unes/GithubContributor.kt
@@ -34,7 +34,7 @@ data class GithubContributor(
@SerializedName("html_url")
val htmlUrl: String,
@SerializedName("url")
- val url: String,
+ val url: String
)
data class GithubUser(
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/unes/Message.kt b/app/src/main/java/com/forcetower/uefs/core/model/unes/Message.kt
index 842cdbade..08ccd10f7 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/unes/Message.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/unes/Message.kt
@@ -27,6 +27,7 @@ import androidx.room.Ignore
import androidx.room.Index
import androidx.room.PrimaryKey
import com.forcetower.sagres.database.model.SagresMessage
+import com.forcetower.uefs.core.model.edge.sync.PublicPlatformMessage
import com.forcetower.uefs.core.storage.database.UDatabase
import com.forcetower.uefs.service.NotificationCreator
import java.time.OffsetDateTime
@@ -104,6 +105,22 @@ data class Message(
codeDiscipline = me.discipline?.code
)
}
+
+ fun fromMessage(me: PublicPlatformMessage, notified: Boolean): Message {
+ return Message(
+ content = me.content,
+ sagresId = me.platformId,
+ senderName = me.senderName,
+ senderProfile = me.senderProfile.toInt(),
+ timestamp = me.timestamp,
+ notified = notified,
+ html = false,
+ processingTime = System.currentTimeMillis(),
+ hashMessage = me.content.lowercase(Locale.getDefault()).trim().hashCode().toLong(),
+ discipline = me.discipline,
+ codeDiscipline = me.codeDiscipline
+ )
+ }
}
}
@@ -111,7 +128,7 @@ fun Message.notify(context: Context) {
NotificationCreator.showSagresMessageNotification(this, context)
}
-fun List?.defineInDatabase(database: UDatabase, notified: Boolean = false) {
+suspend fun List?.defineInDatabase(database: UDatabase, notified: Boolean = false) {
val values = this?.map { Message.fromMessage(it, notified) } ?: emptyList()
database.messageDao().insertIgnoring(values)
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/model/unes/Semester.kt b/app/src/main/java/com/forcetower/uefs/core/model/unes/Semester.kt
index a9f447e2b..af46f509d 100644
--- a/app/src/main/java/com/forcetower/uefs/core/model/unes/Semester.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/model/unes/Semester.kt
@@ -50,8 +50,11 @@ data class Semester(
val str2 = Integer.parseInt(o2.substring(0, 5))
if (str1 == str2) {
- if (o1.length > 5) -1
- else 1
+ if (o1.length > 5) {
+ -1
+ } else {
+ 1
+ }
} else {
str1.compareTo(str2) * -1
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/notification/StatementNotificationProcessor.kt b/app/src/main/java/com/forcetower/uefs/core/notification/StatementNotificationProcessor.kt
index e3382b0ce..294c5e562 100644
--- a/app/src/main/java/com/forcetower/uefs/core/notification/StatementNotificationProcessor.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/notification/StatementNotificationProcessor.kt
@@ -35,8 +35,8 @@ import timber.log.Timber
object StatementNotificationProcessor {
@JvmStatic
- fun openProfileIntent(ctx: Context, userId: Long, profileId: Long): PendingIntent {
- val intent = ProfileActivity.startIntent(ctx, profileId, userId)
+ fun openProfileIntent(ctx: Context, userId: String): PendingIntent {
+ val intent = ProfileActivity.startIntent(ctx, userId)
val concatFlags = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0
return TaskStackBuilder.create(ctx)
.addParentStack(HomeActivity::class.java)
@@ -51,7 +51,7 @@ object StatementNotificationProcessor {
val type = data["service_typed"]
val statement = data["statement"]
val statementId = data["statement_id"]
- val userId = data["receiver_user_id"]?.toLongOrNull()
+ val userId = data["receiver_user_id"]
val profileId = data["receiver_profile_id"]?.toLongOrNull()
Timber.d("Statement Received: $statement, $statementId")
@@ -73,8 +73,8 @@ object StatementNotificationProcessor {
WordUtils.capitalize(senderName)
}
- val intent = if (userId != null && profileId != null) {
- openProfileIntent(context, userId, profileId)
+ val intent = if (userId != null) {
+ openProfileIntent(context, userId)
} else {
null
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/cookies/CachedCookiePersistor.kt b/app/src/main/java/com/forcetower/uefs/core/storage/cookies/CachedCookiePersistor.kt
index a5199c225..5079c19d8 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/cookies/CachedCookiePersistor.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/cookies/CachedCookiePersistor.kt
@@ -24,8 +24,8 @@ import android.content.Context
import android.content.SharedPreferences
import com.forcetower.sagres.cookies.CookiePersistor
import com.forcetower.sagres.cookies.SerializableCookie
-import okhttp3.Cookie
import java.util.ArrayList
+import okhttp3.Cookie
class CachedCookiePersistor(context: Context) : CookiePersistor {
private val sharedPreferences: SharedPreferences =
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/cookies/PrefsCookiePersistor.kt b/app/src/main/java/com/forcetower/uefs/core/storage/cookies/PrefsCookiePersistor.kt
index 97b43ef99..a31f1ce0d 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/cookies/PrefsCookiePersistor.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/cookies/PrefsCookiePersistor.kt
@@ -24,8 +24,8 @@ import android.content.Context
import android.content.SharedPreferences
import com.forcetower.sagres.cookies.CookiePersistor
import com.forcetower.sagres.cookies.SerializableCookie
-import okhttp3.Cookie
import java.util.ArrayList
+import okhttp3.Cookie
class PrefsCookiePersistor(context: Context) : CookiePersistor {
private val sharedPreferences: SharedPreferences =
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/UDatabase.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/UDatabase.kt
index 3320f11dc..2d325b648 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/UDatabase.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/UDatabase.kt
@@ -1,196 +1,201 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.database
-
-import androidx.room.AutoMigration
-import androidx.room.Database
-import androidx.room.RoomDatabase
-import androidx.room.TypeConverters
-import com.forcetower.uefs.core.model.unes.Access
-import com.forcetower.uefs.core.model.unes.AccessToken
-import com.forcetower.uefs.core.model.unes.Account
-import com.forcetower.uefs.core.model.unes.AffinityQuestion
-import com.forcetower.uefs.core.model.unes.AffinityQuestionAlternative
-import com.forcetower.uefs.core.model.unes.CalendarItem
-import com.forcetower.uefs.core.model.unes.Class
-import com.forcetower.uefs.core.model.unes.ClassAbsence
-import com.forcetower.uefs.core.model.unes.ClassGroup
-import com.forcetower.uefs.core.model.unes.ClassGroupTeacher
-import com.forcetower.uefs.core.model.unes.ClassItem
-import com.forcetower.uefs.core.model.unes.ClassLocation
-import com.forcetower.uefs.core.model.unes.ClassMaterial
-import com.forcetower.uefs.core.model.unes.Contributor
-import com.forcetower.uefs.core.model.unes.Course
-import com.forcetower.uefs.core.model.unes.Discipline
-import com.forcetower.uefs.core.model.unes.EdgeAccessToken
-import com.forcetower.uefs.core.model.unes.EdgeServiceAccount
-import com.forcetower.uefs.core.model.unes.EvaluationEntity
-import com.forcetower.uefs.core.model.unes.Event
-import com.forcetower.uefs.core.model.unes.Flowchart
-import com.forcetower.uefs.core.model.unes.FlowchartDiscipline
-import com.forcetower.uefs.core.model.unes.FlowchartRequirement
-import com.forcetower.uefs.core.model.unes.FlowchartSemester
-import com.forcetower.uefs.core.model.unes.Grade
-import com.forcetower.uefs.core.model.unes.Message
-import com.forcetower.uefs.core.model.unes.Profile
-import com.forcetower.uefs.core.model.unes.ProfileStatement
-import com.forcetower.uefs.core.model.unes.SDemandOffer
-import com.forcetower.uefs.core.model.unes.SDiscipline
-import com.forcetower.uefs.core.model.unes.SStudent
-import com.forcetower.uefs.core.model.unes.STeacher
-import com.forcetower.uefs.core.model.unes.SagresDocument
-import com.forcetower.uefs.core.model.unes.SagresFlags
-import com.forcetower.uefs.core.model.unes.Semester
-import com.forcetower.uefs.core.model.unes.ServiceRequest
-import com.forcetower.uefs.core.model.unes.SyncRegistry
-import com.forcetower.uefs.core.model.unes.Teacher
-import com.forcetower.uefs.core.model.unes.UserSession
-import com.forcetower.uefs.core.storage.database.dao.AccessDao
-import com.forcetower.uefs.core.storage.database.dao.AccessTokenDao
-import com.forcetower.uefs.core.storage.database.dao.AccountDao
-import com.forcetower.uefs.core.storage.database.dao.AffinityQuestionDao
-import com.forcetower.uefs.core.storage.database.dao.CalendarDao
-import com.forcetower.uefs.core.storage.database.dao.ClassAbsenceDao
-import com.forcetower.uefs.core.storage.database.dao.ClassDao
-import com.forcetower.uefs.core.storage.database.dao.ClassGroupDao
-import com.forcetower.uefs.core.storage.database.dao.ClassGroupTeacherDao
-import com.forcetower.uefs.core.storage.database.dao.ClassItemDao
-import com.forcetower.uefs.core.storage.database.dao.ClassLocationDao
-import com.forcetower.uefs.core.storage.database.dao.ClassMaterialDao
-import com.forcetower.uefs.core.storage.database.dao.ContributorDao
-import com.forcetower.uefs.core.storage.database.dao.CourseDao
-import com.forcetower.uefs.core.storage.database.dao.DemandOfferDao
-import com.forcetower.uefs.core.storage.database.dao.DisciplineDao
-import com.forcetower.uefs.core.storage.database.dao.DisciplineServiceDao
-import com.forcetower.uefs.core.storage.database.dao.DocumentDao
-import com.forcetower.uefs.core.storage.database.dao.EdgeAccessTokenDao
-import com.forcetower.uefs.core.storage.database.dao.EdgeServiceAccountDao
-import com.forcetower.uefs.core.storage.database.dao.EvaluationEntitiesDao
-import com.forcetower.uefs.core.storage.database.dao.EventDao
-import com.forcetower.uefs.core.storage.database.dao.FlagsDao
-import com.forcetower.uefs.core.storage.database.dao.FlowchartDao
-import com.forcetower.uefs.core.storage.database.dao.FlowchartDisciplineDao
-import com.forcetower.uefs.core.storage.database.dao.FlowchartRequirementDao
-import com.forcetower.uefs.core.storage.database.dao.FlowchartSemesterDao
-import com.forcetower.uefs.core.storage.database.dao.GradeDao
-import com.forcetower.uefs.core.storage.database.dao.MessageDao
-import com.forcetower.uefs.core.storage.database.dao.ProfileDao
-import com.forcetower.uefs.core.storage.database.dao.ProfileStatementDao
-import com.forcetower.uefs.core.storage.database.dao.SemesterDao
-import com.forcetower.uefs.core.storage.database.dao.ServiceRequestDao
-import com.forcetower.uefs.core.storage.database.dao.StudentServiceDao
-import com.forcetower.uefs.core.storage.database.dao.SyncRegistryDao
-import com.forcetower.uefs.core.storage.database.dao.TeacherDao
-import com.forcetower.uefs.core.storage.database.dao.TeacherServiceDao
-import com.forcetower.uefs.core.storage.database.dao.UserSessionDao
-import com.forcetower.uefs.core.util.Converters
-
-@Database(
- entities = [
- AccessToken::class,
- Access::class,
- Profile::class,
- Semester::class,
- Message::class,
- CalendarItem::class,
- Discipline::class,
- Class::class,
- ClassGroup::class,
- ClassAbsence::class,
- ClassLocation::class,
- ClassItem::class,
- ClassMaterial::class,
- Grade::class,
- Course::class,
- SagresDocument::class,
- SyncRegistry::class,
- Teacher::class,
- SDemandOffer::class,
- SagresFlags::class,
- Contributor::class,
- ServiceRequest::class,
- Account::class,
- STeacher::class,
- SDiscipline::class,
- SStudent::class,
- EvaluationEntity::class,
- Flowchart::class,
- FlowchartSemester::class,
- FlowchartDiscipline::class,
- FlowchartRequirement::class,
- ProfileStatement::class,
- UserSession::class,
- AffinityQuestion::class,
- AffinityQuestionAlternative::class,
- Event::class,
- ClassGroupTeacher::class,
- EdgeAccessToken::class,
- EdgeServiceAccount::class
- ],
- version = 55,
- exportSchema = true,
- autoMigrations = [
- AutoMigration(from = 53, to = 54),
- AutoMigration(from = 54, to = 55),
- ]
-)
-@TypeConverters(value = [Converters::class])
-abstract class UDatabase : RoomDatabase() {
- abstract fun accessDao(): AccessDao
- abstract fun accessTokenDao(): AccessTokenDao
- abstract fun profileDao(): ProfileDao
- abstract fun messageDao(): MessageDao
- abstract fun semesterDao(): SemesterDao
- abstract fun calendarDao(): CalendarDao
- abstract fun disciplineDao(): DisciplineDao
- abstract fun classDao(): ClassDao
- abstract fun teacherDao(): TeacherDao
- abstract fun classGroupDao(): ClassGroupDao
- abstract fun classAbsenceDao(): ClassAbsenceDao
- abstract fun classLocationDao(): ClassLocationDao
- abstract fun gradesDao(): GradeDao
- abstract fun courseDao(): CourseDao
- abstract fun documentDao(): DocumentDao
- abstract fun syncRegistryDao(): SyncRegistryDao
- abstract fun classMaterialDao(): ClassMaterialDao
- abstract fun classItemDao(): ClassItemDao
- abstract fun demandOfferDao(): DemandOfferDao
- abstract fun flagsDao(): FlagsDao
- abstract fun contributorDao(): ContributorDao
- abstract fun serviceRequestDao(): ServiceRequestDao
- abstract fun accountDao(): AccountDao
- abstract fun disciplineServiceDao(): DisciplineServiceDao
- abstract fun teacherServiceDao(): TeacherServiceDao
- abstract fun studentServiceDao(): StudentServiceDao
- abstract fun evaluationEntitiesDao(): EvaluationEntitiesDao
- abstract fun flowchartDao(): FlowchartDao
- abstract fun flowchartSemesterDao(): FlowchartSemesterDao
- abstract fun flowchartDisciplineDao(): FlowchartDisciplineDao
- abstract fun flowchartRequirementDao(): FlowchartRequirementDao
- abstract fun statementDao(): ProfileStatementDao
- abstract fun userSessionDao(): UserSessionDao
- abstract fun affinityQuestion(): AffinityQuestionDao
- abstract fun eventDao(): EventDao
- abstract fun classGroupTeacher(): ClassGroupTeacherDao
-
- abstract val edgeAccessToken: EdgeAccessTokenDao
- abstract val edgeServiceAccount: EdgeServiceAccountDao
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.database
+
+import androidx.room.AutoMigration
+import androidx.room.Database
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+import com.forcetower.uefs.core.model.unes.Access
+import com.forcetower.uefs.core.model.unes.AccessToken
+import com.forcetower.uefs.core.model.unes.Account
+import com.forcetower.uefs.core.model.unes.AffinityQuestion
+import com.forcetower.uefs.core.model.unes.AffinityQuestionAlternative
+import com.forcetower.uefs.core.model.unes.CalendarItem
+import com.forcetower.uefs.core.model.unes.Class
+import com.forcetower.uefs.core.model.unes.ClassAbsence
+import com.forcetower.uefs.core.model.unes.ClassGroup
+import com.forcetower.uefs.core.model.unes.ClassGroupTeacher
+import com.forcetower.uefs.core.model.unes.ClassItem
+import com.forcetower.uefs.core.model.unes.ClassLocation
+import com.forcetower.uefs.core.model.unes.ClassMaterial
+import com.forcetower.uefs.core.model.unes.Contributor
+import com.forcetower.uefs.core.model.unes.Course
+import com.forcetower.uefs.core.model.unes.Discipline
+import com.forcetower.uefs.core.model.unes.EdgeAccessToken
+import com.forcetower.uefs.core.model.unes.EdgeParadoxSearchableItem
+import com.forcetower.uefs.core.model.unes.EdgeServiceAccount
+import com.forcetower.uefs.core.model.unes.EvaluationEntity
+import com.forcetower.uefs.core.model.unes.Event
+import com.forcetower.uefs.core.model.unes.Flowchart
+import com.forcetower.uefs.core.model.unes.FlowchartDiscipline
+import com.forcetower.uefs.core.model.unes.FlowchartRequirement
+import com.forcetower.uefs.core.model.unes.FlowchartSemester
+import com.forcetower.uefs.core.model.unes.Grade
+import com.forcetower.uefs.core.model.unes.Message
+import com.forcetower.uefs.core.model.unes.Profile
+import com.forcetower.uefs.core.model.unes.ProfileStatement
+import com.forcetower.uefs.core.model.unes.SDemandOffer
+import com.forcetower.uefs.core.model.unes.SDiscipline
+import com.forcetower.uefs.core.model.unes.SStudent
+import com.forcetower.uefs.core.model.unes.STeacher
+import com.forcetower.uefs.core.model.unes.SagresDocument
+import com.forcetower.uefs.core.model.unes.SagresFlags
+import com.forcetower.uefs.core.model.unes.Semester
+import com.forcetower.uefs.core.model.unes.ServiceRequest
+import com.forcetower.uefs.core.model.unes.SyncRegistry
+import com.forcetower.uefs.core.model.unes.Teacher
+import com.forcetower.uefs.core.model.unes.UserSession
+import com.forcetower.uefs.core.storage.database.dao.AccessDao
+import com.forcetower.uefs.core.storage.database.dao.AccessTokenDao
+import com.forcetower.uefs.core.storage.database.dao.AccountDao
+import com.forcetower.uefs.core.storage.database.dao.AffinityQuestionDao
+import com.forcetower.uefs.core.storage.database.dao.CalendarDao
+import com.forcetower.uefs.core.storage.database.dao.ClassAbsenceDao
+import com.forcetower.uefs.core.storage.database.dao.ClassDao
+import com.forcetower.uefs.core.storage.database.dao.ClassGroupDao
+import com.forcetower.uefs.core.storage.database.dao.ClassGroupTeacherDao
+import com.forcetower.uefs.core.storage.database.dao.ClassItemDao
+import com.forcetower.uefs.core.storage.database.dao.ClassLocationDao
+import com.forcetower.uefs.core.storage.database.dao.ClassMaterialDao
+import com.forcetower.uefs.core.storage.database.dao.ContributorDao
+import com.forcetower.uefs.core.storage.database.dao.CourseDao
+import com.forcetower.uefs.core.storage.database.dao.DemandOfferDao
+import com.forcetower.uefs.core.storage.database.dao.DisciplineDao
+import com.forcetower.uefs.core.storage.database.dao.DisciplineServiceDao
+import com.forcetower.uefs.core.storage.database.dao.DocumentDao
+import com.forcetower.uefs.core.storage.database.dao.EdgeAccessTokenDao
+import com.forcetower.uefs.core.storage.database.dao.EdgeParadoxSearchableItemDao
+import com.forcetower.uefs.core.storage.database.dao.EdgeServiceAccountDao
+import com.forcetower.uefs.core.storage.database.dao.EvaluationEntitiesDao
+import com.forcetower.uefs.core.storage.database.dao.EventDao
+import com.forcetower.uefs.core.storage.database.dao.FlagsDao
+import com.forcetower.uefs.core.storage.database.dao.FlowchartDao
+import com.forcetower.uefs.core.storage.database.dao.FlowchartDisciplineDao
+import com.forcetower.uefs.core.storage.database.dao.FlowchartRequirementDao
+import com.forcetower.uefs.core.storage.database.dao.FlowchartSemesterDao
+import com.forcetower.uefs.core.storage.database.dao.GradeDao
+import com.forcetower.uefs.core.storage.database.dao.MessageDao
+import com.forcetower.uefs.core.storage.database.dao.ProfileDao
+import com.forcetower.uefs.core.storage.database.dao.ProfileStatementDao
+import com.forcetower.uefs.core.storage.database.dao.SemesterDao
+import com.forcetower.uefs.core.storage.database.dao.ServiceRequestDao
+import com.forcetower.uefs.core.storage.database.dao.StudentServiceDao
+import com.forcetower.uefs.core.storage.database.dao.SyncRegistryDao
+import com.forcetower.uefs.core.storage.database.dao.TeacherDao
+import com.forcetower.uefs.core.storage.database.dao.TeacherServiceDao
+import com.forcetower.uefs.core.storage.database.dao.UserSessionDao
+import com.forcetower.uefs.core.util.Converters
+
+@Database(
+ entities = [
+ AccessToken::class,
+ Access::class,
+ Profile::class,
+ Semester::class,
+ Message::class,
+ CalendarItem::class,
+ Discipline::class,
+ Class::class,
+ ClassGroup::class,
+ ClassAbsence::class,
+ ClassLocation::class,
+ ClassItem::class,
+ ClassMaterial::class,
+ Grade::class,
+ Course::class,
+ SagresDocument::class,
+ SyncRegistry::class,
+ Teacher::class,
+ SDemandOffer::class,
+ SagresFlags::class,
+ Contributor::class,
+ ServiceRequest::class,
+ Account::class,
+ STeacher::class,
+ SDiscipline::class,
+ SStudent::class,
+ EvaluationEntity::class,
+ Flowchart::class,
+ FlowchartSemester::class,
+ FlowchartDiscipline::class,
+ FlowchartRequirement::class,
+ ProfileStatement::class,
+ UserSession::class,
+ AffinityQuestion::class,
+ AffinityQuestionAlternative::class,
+ Event::class,
+ ClassGroupTeacher::class,
+ EdgeAccessToken::class,
+ EdgeServiceAccount::class,
+ EdgeParadoxSearchableItem::class
+ ],
+ version = 56,
+ exportSchema = true,
+ autoMigrations = [
+ AutoMigration(from = 53, to = 54),
+ AutoMigration(from = 54, to = 55),
+ AutoMigration(from = 55, to = 56)
+ ]
+)
+@TypeConverters(value = [Converters::class])
+abstract class UDatabase : RoomDatabase() {
+ abstract fun accessDao(): AccessDao
+ abstract fun accessTokenDao(): AccessTokenDao
+ abstract fun profileDao(): ProfileDao
+ abstract fun messageDao(): MessageDao
+ abstract fun semesterDao(): SemesterDao
+ abstract fun calendarDao(): CalendarDao
+ abstract fun disciplineDao(): DisciplineDao
+ abstract fun classDao(): ClassDao
+ abstract fun teacherDao(): TeacherDao
+ abstract fun classGroupDao(): ClassGroupDao
+ abstract fun classAbsenceDao(): ClassAbsenceDao
+ abstract fun classLocationDao(): ClassLocationDao
+ abstract fun gradesDao(): GradeDao
+ abstract fun courseDao(): CourseDao
+ abstract fun documentDao(): DocumentDao
+ abstract fun syncRegistryDao(): SyncRegistryDao
+ abstract fun classMaterialDao(): ClassMaterialDao
+ abstract fun classItemDao(): ClassItemDao
+ abstract fun demandOfferDao(): DemandOfferDao
+ abstract fun flagsDao(): FlagsDao
+ abstract fun contributorDao(): ContributorDao
+ abstract fun serviceRequestDao(): ServiceRequestDao
+ abstract fun accountDao(): AccountDao
+ abstract fun disciplineServiceDao(): DisciplineServiceDao
+ abstract fun teacherServiceDao(): TeacherServiceDao
+ abstract fun studentServiceDao(): StudentServiceDao
+ abstract fun evaluationEntitiesDao(): EvaluationEntitiesDao
+ abstract fun flowchartDao(): FlowchartDao
+ abstract fun flowchartSemesterDao(): FlowchartSemesterDao
+ abstract fun flowchartDisciplineDao(): FlowchartDisciplineDao
+ abstract fun flowchartRequirementDao(): FlowchartRequirementDao
+ abstract fun statementDao(): ProfileStatementDao
+ abstract fun userSessionDao(): UserSessionDao
+ abstract fun affinityQuestion(): AffinityQuestionDao
+ abstract fun eventDao(): EventDao
+ abstract fun classGroupTeacher(): ClassGroupTeacherDao
+
+ abstract val edgeAccessToken: EdgeAccessTokenDao
+ abstract val edgeServiceAccount: EdgeServiceAccountDao
+ abstract val edgeParadoxSearchableItem: EdgeParadoxSearchableItemDao
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/aggregation/ClassGroupWithTeachers.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/aggregation/ClassGroupWithTeachers.kt
index 009347ef6..6f102b16a 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/aggregation/ClassGroupWithTeachers.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/aggregation/ClassGroupWithTeachers.kt
@@ -17,4 +17,4 @@ data class ClassGroupWithTeachers(
associateBy = Junction(value = AffinityQuestionAlternative::class, parentColumn = "classGroupId", entityColumn = "teacherId")
)
val teachers: List
-)
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ClassGroupTeacherDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ClassGroupTeacherDao.kt
index e851badf5..1f0d762f6 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ClassGroupTeacherDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ClassGroupTeacherDao.kt
@@ -9,4 +9,4 @@ import com.forcetower.uefs.core.model.unes.ClassGroupTeacher
abstract class ClassGroupTeacherDao : BaseDao() {
@Query("DELETE FROM ClassGroupTeacher WHERE classGroupId = :classGroupId")
abstract suspend fun deleteAllFromClassGroup(classGroupId: Long)
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeAccessTokenDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeAccessTokenDao.kt
index d8750ed90..764c30cd0 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeAccessTokenDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeAccessTokenDao.kt
@@ -4,12 +4,16 @@ import androidx.room.Dao
import androidx.room.Query
import com.forcetower.core.database.BaseDao
import com.forcetower.uefs.core.model.unes.EdgeAccessToken
+import kotlinx.coroutines.flow.Flow
@Dao
abstract class EdgeAccessTokenDao : BaseDao() {
@Query("SELECT * FROM EdgeAccessToken LIMIT 1")
abstract suspend fun require(): EdgeAccessToken?
+ @Query("SELECT * FROM EdgeAccessToken LIMIT 1")
+ abstract fun get(): Flow
+
@Query("DELETE FROM EdgeAccessToken")
abstract suspend fun deleteAll()
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeParadoxSearchableItemDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeParadoxSearchableItemDao.kt
new file mode 100644
index 000000000..804705e46
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/EdgeParadoxSearchableItemDao.kt
@@ -0,0 +1,71 @@
+package com.forcetower.uefs.core.storage.database.dao
+
+import androidx.paging.PagingSource
+import androidx.room.Dao
+import androidx.room.Query
+import androidx.room.Transaction
+import com.forcetower.core.database.BaseDao
+import com.forcetower.uefs.core.model.edge.paradox.EvaluationSnapshot
+import com.forcetower.uefs.core.model.unes.EdgeParadoxSearchableItem
+import com.forcetower.uefs.core.model.unes.EdgeParadoxSearchableItem.Companion.DISCIPLINE_TYPE
+import com.forcetower.uefs.core.model.unes.EdgeParadoxSearchableItem.Companion.TEACHER_TYPE
+import com.forcetower.uefs.core.util.unaccent
+import java.util.Locale
+
+@Dao
+abstract class EdgeParadoxSearchableItemDao : BaseDao() {
+ @Transaction
+ open suspend fun recreate(snapshot: EvaluationSnapshot) {
+ deleteAll()
+ val disciplines = snapshot.disciplines.map {
+ val coded = it.code
+ val search = "$coded ${it.name}".lowercase().unaccent()
+ EdgeParadoxSearchableItem(
+ serviceId = it.id,
+ displayName = it.name,
+ subtitle = it.code,
+ displayImage = null,
+ type = DISCIPLINE_TYPE,
+ searchable = search,
+ optionalReference = null
+ )
+ }
+
+ val teachers = snapshot.teachers.map {
+ val searchable = it.name.lowercase().unaccent()
+ EdgeParadoxSearchableItem(
+ serviceId = it.id,
+ displayName = it.name,
+ subtitle = null,
+ displayImage = null,
+ type = TEACHER_TYPE,
+ searchable = searchable,
+ optionalReference = null
+ )
+ }
+
+ insertAllIgnore(disciplines)
+ insertAllIgnore(teachers)
+ }
+
+ @Query("DELETE FROM EdgeParadoxSearchableItem")
+ abstract suspend fun deleteAll()
+
+ open fun query(query: String): PagingSource {
+ return if (query.isBlank()) {
+ doQueryEmpty()
+ } else {
+ val realQuery = query.lowercase(Locale.getDefault())
+ .unaccent()
+ .split(" ")
+ .joinToString("%", "%", "%")
+ doQuery(realQuery)
+ }
+ }
+
+ @Query("SELECT * FROM EdgeParadoxSearchableItem WHERE LOWER(searchable) LIKE :query ORDER BY displayName")
+ abstract fun doQuery(query: String): PagingSource
+
+ @Query("SELECT * FROM EdgeParadoxSearchableItem WHERE 0")
+ abstract fun doQueryEmpty(): PagingSource
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDao.kt
index 94989f1e2..900c30031 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDao.kt
@@ -32,8 +32,8 @@ import com.forcetower.uefs.core.model.unes.Flowchart
import com.forcetower.uefs.core.model.unes.FlowchartDiscipline
import com.forcetower.uefs.core.model.unes.FlowchartRequirement
import com.forcetower.uefs.core.model.unes.FlowchartSemester
-import timber.log.Timber
import java.util.Calendar
+import timber.log.Timber
@Dao
abstract class FlowchartDao {
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDisciplineDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDisciplineDao.kt
index e9a691399..0f9a31c10 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDisciplineDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/FlowchartDisciplineDao.kt
@@ -30,8 +30,10 @@ import com.forcetower.uefs.core.model.unes.FlowchartSemester
interface FlowchartDisciplineDao {
@Query("SELECT fd.id AS id, fd.type AS type, fd.mandatory AS mandatory, fd.completed AS completed, fd.participating AS participating, d.name AS name, d.code AS code, d.credits AS credits, d.department AS department, d.resume AS program FROM FlowchartDiscipline fd INNER JOIN Discipline d ON d.uid = fd.disciplineId WHERE fd.semesterId = :semesterId")
fun getDecoratedList(semesterId: Long): LiveData>
+
@Query("SELECT fd.id AS id, fd.type AS type, fd.mandatory AS mandatory, fd.completed AS completed, fd.participating AS participating, d.name AS name, d.code AS code, d.credits AS credits, d.department AS department, d.resume AS program FROM FlowchartDiscipline fd INNER JOIN Discipline d ON d.uid = fd.disciplineId WHERE fd.id = :disciplineId")
fun getDecorated(disciplineId: Long): LiveData
+
@Query("SELECT s.* FROM FlowchartSemester s INNER JOIN FlowchartDiscipline d ON d.semesterId = s.id WHERE d.id = :disciplineId GROUP BY s.name LIMIT 1")
fun getSemesterFromDiscipline(disciplineId: Long): LiveData
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/GradeDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/GradeDao.kt
index a4ae0ee2e..f167c7ae1 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/GradeDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/GradeDao.kt
@@ -28,6 +28,7 @@ import androidx.room.Transaction
import androidx.room.Update
import com.forcetower.sagres.database.model.SagresGrade
import com.forcetower.sagres.database.model.SagresGradeInfo
+import com.forcetower.uefs.core.model.edge.sync.PublicGrade
import com.forcetower.uefs.core.model.unes.Class
import com.forcetower.uefs.core.model.unes.Discipline
import com.forcetower.uefs.core.model.unes.Grade
@@ -35,8 +36,8 @@ import com.forcetower.uefs.core.model.unes.Profile
import com.forcetower.uefs.core.model.unes.Semester
import com.forcetower.uefs.core.storage.database.aggregation.GradeWithClassStudent
import dev.forcetower.breaker.model.ClassEvaluation
-import timber.log.Timber
import java.time.ZonedDateTime
+import timber.log.Timber
@Dao
abstract class GradeDao {
@@ -130,10 +131,12 @@ abstract class GradeDao {
clazz.uid = id
}
if (clazz.uid > 0) {
- if (score != null)
+ if (score != null) {
updateClassScore(clazz.uid, score)
- if (partialScore != null)
+ }
+ if (partialScore != null) {
updateClassPartialScore(clazz.uid, partialScore)
+ }
prepareInsertion(clazz, it, notify)
}
@@ -163,9 +166,13 @@ abstract class GradeDao {
if (grade == null) {
grade = g
} else {
- if (g.hasGrade()) grade = g
- else if (g.hasDate() && grade.hasDate() && g.date != grade.date) grade = g
- else Timber.d("This grade was ignored ${g.name}_${g.grade}")
+ if (g.hasGrade()) {
+ grade = g
+ } else if (g.hasDate() && grade.hasDate() && g.date != grade.date) {
+ grade = g
+ } else {
+ Timber.d("This grade was ignored ${g.name}_${g.grade}")
+ }
}
values["${g.grouping}<><>${g.name}"] = grade
}
@@ -324,4 +331,52 @@ abstract class GradeDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
protected abstract fun insertClass(clazz: Class): Long
+
+ @Transaction
+ open suspend fun putEdgeGrades(grades: List, classId: Long) {
+ grades.forEach { grade ->
+ val current = getNamedGradeDirect(classId, grade.name, grade.groupingName?.trim().hashCode())
+ if (current == null) {
+ insert(
+ Grade(
+ classId = classId,
+ name = grade.name,
+ notified = 0,
+ grade = grade.grade?.toString(),
+ grouping = grade.groupingName?.trim().hashCode(),
+ groupingName = grade.groupingName?.trim() ?: "Notas",
+ date = grade.date?.trim()
+ )
+ )
+ } else {
+ var shouldUpdate = true
+ val score = grade.grade?.toString() ?: ""
+ var next = current
+ if (current.hasGrade() && grade.grade != null && score != current.grade) {
+ next = current.copy(
+ grade = score,
+ date = grade.date?.trim()
+ )
+ } else if (!current.hasGrade() && grade.grade != null) {
+ next = current.copy(
+ grade = score,
+ date = grade.date?.trim()
+ )
+ } else if (!current.hasGrade() && grade.grade == null && current.date != grade.date) {
+ next = current.copy(
+ date = grade.date?.trim()
+ )
+ } else {
+ shouldUpdate = false
+ }
+
+ if (current.groupingName != grade.groupingName?.trim()) {
+ shouldUpdate = true
+ next = next.copy(groupingName = grade.groupingName?.trim() ?: "Notas")
+ }
+
+ if (shouldUpdate) update(next)
+ }
+ }
+ }
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/MessageDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/MessageDao.kt
index 7a51062c1..0d6782e0e 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/MessageDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/MessageDao.kt
@@ -1,189 +1,192 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.database.dao
-
-import androidx.lifecycle.LiveData
-import androidx.paging.PagingSource
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-import androidx.room.Transaction
-import com.forcetower.uefs.core.model.unes.Message
-import timber.log.Timber
-import java.util.Locale
-
-@Dao
-abstract class MessageDao {
- @Query("DELETE FROM Message")
- abstract suspend fun deleteAllSuspend()
-
- @Transaction
- open fun insertIgnoring(messages: List) {
- updateOldMessages()
- for (message in messages) {
- val direct = if (message.html) {
- getMessageByHashDirect(message.hashMessage)
- } else {
- getMessageDirect(message.sagresId)
- }
- if (direct != null) {
- if (message.senderName != null) {
- if (direct.senderName.isNullOrBlank()) {
- updateSenderName(message.sagresId, message.senderName)
- }
- }
-
- // mark message as edited?
- if (!message.html && message.content.isNotBlank()) {
- updateContent(message.sagresId, message.content)
- }
-
- if (message.discipline != null) {
- updateDisciplineName(message.sagresId, message.discipline)
- }
-
- if (message.codeDiscipline != null) {
- updateDisciplineCode(direct.sagresId, message.codeDiscipline)
- }
-
- if (message.attachmentLink != null) {
- updateAttachmentLink(message.sagresId, message.attachmentLink)
- }
-
- if (message.attachmentName != null) {
- updateAttachmentName(message.sagresId, message.attachmentName)
- }
-
- if (message.html && direct.html) {
- updateDateString(message.sagresId, message.dateString)
- }
-
- if (direct.html && !message.html) {
- Timber.d("Is this really happening?")
- updateTimestamp(direct.sagresId, message.timestamp)
- updateSenderProfile(direct.sagresId, message.senderProfile)
- updateHtmlParseStatus(direct.sagresId, false)
-
- if (message.senderName != null)
- updateSenderName(direct.sagresId, message.senderName)
- if (message.discipline != null)
- updateDisciplineName(direct.sagresId, message.discipline)
- }
- }
- val resume = message.disciplineResume?.trim()
- val code = message.codeDiscipline?.trim()
- if (!resume.isNullOrBlank() && !code.isNullOrBlank()) {
- updateDisciplineResume(code, resume)
- }
- }
-
- insertIgnore(messages)
- }
-
- @Query("SELECT * FROM Message WHERE hash_message = :hashMessage")
- protected abstract fun getMessageByHashDirect(hashMessage: Long?): Message?
-
- private fun updateOldMessages() {
- val messages = getAllUndefinedMessages()
- messages.forEach { message ->
- val hash = message.content.lowercase(Locale.getDefault()).trim().hashCode().toLong()
- val existing = getMessageByHashDirect(hash)
- if (existing == null) setMessageHash(message.uid, hash)
- else {
- deleteMessage(message.uid)
- Timber.e("Collision of messages ${existing.senderName} and ${message.codeDiscipline}")
- }
- }
- }
-
- @Query("DELETE FROM Message WHERE uid = :uid")
- protected abstract fun deleteMessage(uid: Long)
-
- @Query("UPDATE Message SET hash_message = :hash WHERE uid = :uid")
- protected abstract fun setMessageHash(uid: Long, hash: Long)
-
- @Query("SELECT * FROM Message WHERE hash_message IS NULL")
- protected abstract fun getAllUndefinedMessages(): List
-
- @Query("UPDATE Message SET date_string = :dateString WHERE sagres_id = :sagresId")
- protected abstract fun updateDateString(sagresId: Long, dateString: String?)
-
- @Query("UPDATE Discipline SET resume = :resume WHERE LOWER(code) = LOWER(:code)")
- protected abstract fun updateDisciplineResume(code: String, resume: String)
-
- @Query("UPDATE Message SET discipline = :discipline WHERE sagres_id = :sagresId")
- protected abstract fun updateDisciplineName(sagresId: Long, discipline: String)
-
- @Query("UPDATE Message SET sender_name = :senderName WHERE sagres_id = :sagresId")
- protected abstract fun updateSenderName(sagresId: Long, senderName: String)
-
- @Query("UPDATE Message SET attachmentLink = :attachmentLink WHERE sagres_id = :sagresId")
- protected abstract fun updateAttachmentLink(sagresId: Long, attachmentLink: String)
-
- @Query("UPDATE Message SET attachmentName = :attachmentName WHERE sagres_id = :sagresId")
- protected abstract fun updateAttachmentName(sagresId: Long, attachmentName: String)
-
- @Query("UPDATE Message SET code_discipline = :codeDiscipline WHERE sagres_id = :sagresId")
- protected abstract fun updateDisciplineCode(sagresId: Long, codeDiscipline: String)
-
- @Query("UPDATE Message SET html = :html WHERE sagres_id = :sagresId")
- protected abstract fun updateHtmlParseStatus(sagresId: Long, html: Boolean)
-
- @Query("UPDATE Message SET sender_profile = :senderProfile WHERE sagres_id = :sagresId")
- protected abstract fun updateSenderProfile(sagresId: Long, senderProfile: Int)
-
- @Query("UPDATE Message SET timestamp = :timestamp WHERE sagres_id = :sagresId")
- protected abstract fun updateTimestamp(sagresId: Long, timestamp: Long)
-
- @Query("UPDATE Message SET content = :content WHERE sagres_id = :sagresId")
- protected abstract fun updateContent(sagresId: Long, content: String)
-
- @Insert(onConflict = OnConflictStrategy.IGNORE)
- protected abstract fun insertIgnore(messages: List)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- protected abstract fun insertReplace(messages: List)
-
- @Query("SELECT * FROM Message WHERE sagres_id = :sagresId")
- abstract fun getMessageDirect(sagresId: Long): Message?
-
- @Query("SELECT * FROM Message ORDER BY timestamp DESC")
- abstract fun getAllMessages(): LiveData>
-
- @Query("SELECT * FROM Message ORDER BY timestamp DESC LIMIT 1")
- abstract fun getLastMessage(): LiveData
-
- @Query("SELECT * FROM Message ORDER BY timestamp DESC")
- abstract fun getAllMessagesPaged(): PagingSource
-
- @Query("SELECT * FROM Message WHERE notified = 0")
- abstract fun getNewMessages(): List
-
- @Query("UPDATE Message SET notified = 1")
- abstract fun setAllNotified()
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- abstract fun insert(message: Message): Long
-
- @Query("DELETE FROM Message")
- abstract fun deleteAll()
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.database.dao
+
+import androidx.lifecycle.LiveData
+import androidx.paging.PagingSource
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import com.forcetower.uefs.core.model.unes.Message
+import java.util.Locale
+import timber.log.Timber
+
+@Dao
+abstract class MessageDao {
+ @Query("DELETE FROM Message")
+ abstract suspend fun deleteAllSuspend()
+
+ @Transaction
+ open fun insertIgnoring(messages: List) {
+ updateOldMessages()
+ for (message in messages) {
+ val direct = if (message.html) {
+ getMessageByHashDirect(message.hashMessage)
+ } else {
+ getMessageDirect(message.sagresId)
+ }
+ if (direct != null) {
+ if (message.senderName != null) {
+ if (direct.senderName.isNullOrBlank()) {
+ updateSenderName(message.sagresId, message.senderName)
+ }
+ }
+
+ // mark message as edited?
+ if (!message.html && message.content.isNotBlank()) {
+ updateContent(message.sagresId, message.content)
+ }
+
+ if (message.discipline != null) {
+ updateDisciplineName(message.sagresId, message.discipline)
+ }
+
+ if (message.codeDiscipline != null) {
+ updateDisciplineCode(direct.sagresId, message.codeDiscipline)
+ }
+
+ if (message.attachmentLink != null) {
+ updateAttachmentLink(message.sagresId, message.attachmentLink)
+ }
+
+ if (message.attachmentName != null) {
+ updateAttachmentName(message.sagresId, message.attachmentName)
+ }
+
+ if (message.html && direct.html) {
+ updateDateString(message.sagresId, message.dateString)
+ }
+
+ if (direct.html && !message.html) {
+ Timber.d("Is this really happening?")
+ updateTimestamp(direct.sagresId, message.timestamp)
+ updateSenderProfile(direct.sagresId, message.senderProfile)
+ updateHtmlParseStatus(direct.sagresId, false)
+
+ if (message.senderName != null) {
+ updateSenderName(direct.sagresId, message.senderName)
+ }
+ if (message.discipline != null) {
+ updateDisciplineName(direct.sagresId, message.discipline)
+ }
+ }
+ }
+ val resume = message.disciplineResume?.trim()
+ val code = message.codeDiscipline?.trim()
+ if (!resume.isNullOrBlank() && !code.isNullOrBlank()) {
+ updateDisciplineResume(code, resume)
+ }
+ }
+
+ insertIgnore(messages)
+ }
+
+ @Query("SELECT * FROM Message WHERE hash_message = :hashMessage")
+ protected abstract fun getMessageByHashDirect(hashMessage: Long?): Message?
+
+ private fun updateOldMessages() {
+ val messages = getAllUndefinedMessages()
+ messages.forEach { message ->
+ val hash = message.content.lowercase(Locale.getDefault()).trim().hashCode().toLong()
+ val existing = getMessageByHashDirect(hash)
+ if (existing == null) {
+ setMessageHash(message.uid, hash)
+ } else {
+ deleteMessage(message.uid)
+ Timber.e("Collision of messages ${existing.senderName} and ${message.codeDiscipline}")
+ }
+ }
+ }
+
+ @Query("DELETE FROM Message WHERE uid = :uid")
+ protected abstract fun deleteMessage(uid: Long)
+
+ @Query("UPDATE Message SET hash_message = :hash WHERE uid = :uid")
+ protected abstract fun setMessageHash(uid: Long, hash: Long)
+
+ @Query("SELECT * FROM Message WHERE hash_message IS NULL")
+ protected abstract fun getAllUndefinedMessages(): List
+
+ @Query("UPDATE Message SET date_string = :dateString WHERE sagres_id = :sagresId")
+ protected abstract fun updateDateString(sagresId: Long, dateString: String?)
+
+ @Query("UPDATE Discipline SET resume = :resume WHERE LOWER(code) = LOWER(:code)")
+ protected abstract fun updateDisciplineResume(code: String, resume: String)
+
+ @Query("UPDATE Message SET discipline = :discipline WHERE sagres_id = :sagresId")
+ protected abstract fun updateDisciplineName(sagresId: Long, discipline: String)
+
+ @Query("UPDATE Message SET sender_name = :senderName WHERE sagres_id = :sagresId")
+ protected abstract fun updateSenderName(sagresId: Long, senderName: String)
+
+ @Query("UPDATE Message SET attachmentLink = :attachmentLink WHERE sagres_id = :sagresId")
+ protected abstract fun updateAttachmentLink(sagresId: Long, attachmentLink: String)
+
+ @Query("UPDATE Message SET attachmentName = :attachmentName WHERE sagres_id = :sagresId")
+ protected abstract fun updateAttachmentName(sagresId: Long, attachmentName: String)
+
+ @Query("UPDATE Message SET code_discipline = :codeDiscipline WHERE sagres_id = :sagresId")
+ protected abstract fun updateDisciplineCode(sagresId: Long, codeDiscipline: String)
+
+ @Query("UPDATE Message SET html = :html WHERE sagres_id = :sagresId")
+ protected abstract fun updateHtmlParseStatus(sagresId: Long, html: Boolean)
+
+ @Query("UPDATE Message SET sender_profile = :senderProfile WHERE sagres_id = :sagresId")
+ protected abstract fun updateSenderProfile(sagresId: Long, senderProfile: Int)
+
+ @Query("UPDATE Message SET timestamp = :timestamp WHERE sagres_id = :sagresId")
+ protected abstract fun updateTimestamp(sagresId: Long, timestamp: Long)
+
+ @Query("UPDATE Message SET content = :content WHERE sagres_id = :sagresId")
+ protected abstract fun updateContent(sagresId: Long, content: String)
+
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ protected abstract fun insertIgnore(messages: List)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ protected abstract fun insertReplace(messages: List)
+
+ @Query("SELECT * FROM Message WHERE sagres_id = :sagresId")
+ abstract fun getMessageDirect(sagresId: Long): Message?
+
+ @Query("SELECT * FROM Message ORDER BY timestamp DESC")
+ abstract fun getAllMessages(): LiveData>
+
+ @Query("SELECT * FROM Message ORDER BY timestamp DESC LIMIT 1")
+ abstract fun getLastMessage(): LiveData
+
+ @Query("SELECT * FROM Message ORDER BY timestamp DESC")
+ abstract fun getAllMessagesPaged(): PagingSource
+
+ @Query("SELECT * FROM Message WHERE notified = 0")
+ abstract fun getNewMessages(): List
+
+ @Query("UPDATE Message SET notified = 1")
+ abstract fun setAllNotified()
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ abstract fun insert(message: Message): Long
+
+ @Query("DELETE FROM Message")
+ abstract fun deleteAll()
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ProfileDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ProfileDao.kt
index 3b0fd4f31..23748023d 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ProfileDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/ProfileDao.kt
@@ -1,126 +1,126 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.database.dao
-
-import androidx.lifecycle.LiveData
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-import androidx.room.Transaction
-import com.forcetower.core.utils.WordUtils
-import com.forcetower.sagres.database.model.SagresPerson
-import com.forcetower.uefs.core.model.unes.Profile
-import dev.forcetower.breaker.model.Person
-import kotlinx.coroutines.flow.Flow
-import timber.log.Timber
-import java.util.Locale
-
-@Dao
-abstract class ProfileDao {
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- abstract fun insert(profile: Profile): Long
-
- @Query("SELECT * FROM Profile WHERE me = 1 LIMIT 1")
- abstract fun selectMeDirect(): Profile?
-
- @Query("SELECT * FROM Profile WHERE me = 1 LIMIT 1")
- abstract fun selectMe(): LiveData
-
- @Query("SELECT * FROM Profile WHERE me = 1 LIMIT 1")
- abstract fun me(): Flow
-
- @Transaction
- open fun insert(person: SagresPerson, score: Double = -1.0) {
- val name = WordUtils.toTitleCase(person.name?.trim()) ?: ""
- var profile = selectMeDirect()
- if (profile != null) {
- updateProfileName(name)
- updateProfileMockStatus(person.isMocked)
- if (!person.isMocked) {
- updateProfileEmail(person.email?.trim() ?: "")
- Timber.d("Updating profile sagres id to ${person.id} ${person.sagresId}")
- updateProfileSagresId(person.id)
- }
- if (score >= 0) updateScore(score)
- } else {
- profile = Profile(name = name, email = person.email?.trim(), sagresId = person.id, me = true, score = score)
- insert(profile)
- }
- }
-
- @Transaction
- open suspend fun insert(person: Person): Long {
- val name = WordUtils.toTitleCase(person.name) ?: ""
- val me = selectMeDirect()
- if (me != null) {
- updateProfileName(name)
- updateProfileMockStatus(false)
- updateProfileSagresId(person.id)
- person.email?.lowercase(Locale.getDefault())?.let {
- updateProfileEmail(it)
- }
- return me.uid
- } else {
- return insert(
- Profile(
- name = name,
- email = person.email,
- sagresId = person.id,
- me = true
- )
- )
- }
- }
-
- @Query("SELECT c.name FROM Profile p, Course c WHERE p.course IS NOT NULL AND p.course = c.id LIMIT 1")
- abstract fun getProfileCourse(): LiveData
-
- @Query("SELECT c.name FROM Profile p, Course c WHERE p.course IS NOT NULL AND p.course = c.id LIMIT 1")
- abstract fun getProfileCourseDirect(): String?
-
- @Query("UPDATE Profile SET score = :score")
- abstract fun updateScore(score: Double)
-
- @Query("UPDATE Profile SET mocked = :mocked")
- abstract fun updateProfileMockStatus(mocked: Boolean)
-
- @Query("UPDATE Profile SET name = :name")
- abstract fun updateProfileName(name: String)
-
- @Query("UPDATE Profile SET email = :email")
- abstract fun updateProfileEmail(email: String)
-
- @Query("UPDATE Profile SET sagres_id = :sagresId")
- abstract fun updateProfileSagresId(sagresId: Long)
-
- @Query("DELETE FROM Profile WHERE me = 1")
- abstract fun deleteMe()
-
- @Query("SELECT * FROM Profile WHERE uuid = :profileUUID LIMIT 1")
- abstract fun selectProfileByUUID(profileUUID: String): LiveData
-
- @Query("UPDATE Profile SET course = :courseId WHERE me = 1")
- abstract fun updateCourse(courseId: Long)
-
- @Query("UPDATE Profile SET calc_score = :score WHERE me = 1")
- abstract fun updateCalculatedScore(score: Double)
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.database.dao
+
+import androidx.lifecycle.LiveData
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import com.forcetower.core.utils.WordUtils
+import com.forcetower.sagres.database.model.SagresPerson
+import com.forcetower.uefs.core.model.unes.Profile
+import dev.forcetower.breaker.model.Person
+import java.util.Locale
+import kotlinx.coroutines.flow.Flow
+import timber.log.Timber
+
+@Dao
+abstract class ProfileDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ abstract fun insert(profile: Profile): Long
+
+ @Query("SELECT * FROM Profile WHERE me = 1 LIMIT 1")
+ abstract fun selectMeDirect(): Profile?
+
+ @Query("SELECT * FROM Profile WHERE me = 1 LIMIT 1")
+ abstract fun selectMe(): LiveData
+
+ @Query("SELECT * FROM Profile WHERE me = 1 LIMIT 1")
+ abstract fun me(): Flow
+
+ @Transaction
+ open fun insert(person: SagresPerson, score: Double = -1.0) {
+ val name = WordUtils.toTitleCase(person.name?.trim()) ?: ""
+ var profile = selectMeDirect()
+ if (profile != null) {
+ updateProfileName(name)
+ updateProfileMockStatus(person.isMocked)
+ if (!person.isMocked) {
+ updateProfileEmail(person.email?.trim() ?: "")
+ Timber.d("Updating profile sagres id to ${person.id} ${person.sagresId}")
+ updateProfileSagresId(person.id)
+ }
+ if (score >= 0) updateScore(score)
+ } else {
+ profile = Profile(name = name, email = person.email?.trim(), sagresId = person.id, me = true, score = score)
+ insert(profile)
+ }
+ }
+
+ @Transaction
+ open suspend fun insert(person: Person): Long {
+ val name = WordUtils.toTitleCase(person.name) ?: ""
+ val me = selectMeDirect()
+ if (me != null) {
+ updateProfileName(name)
+ updateProfileMockStatus(false)
+ updateProfileSagresId(person.id)
+ person.email?.lowercase(Locale.getDefault())?.let {
+ updateProfileEmail(it)
+ }
+ return me.uid
+ } else {
+ return insert(
+ Profile(
+ name = name,
+ email = person.email,
+ sagresId = person.id,
+ me = true
+ )
+ )
+ }
+ }
+
+ @Query("SELECT c.name FROM Profile p, Course c WHERE p.course IS NOT NULL AND p.course = c.id LIMIT 1")
+ abstract fun getProfileCourse(): LiveData
+
+ @Query("SELECT c.name FROM Profile p, Course c WHERE p.course IS NOT NULL AND p.course = c.id LIMIT 1")
+ abstract fun getProfileCourseDirect(): String?
+
+ @Query("UPDATE Profile SET score = :score")
+ abstract fun updateScore(score: Double)
+
+ @Query("UPDATE Profile SET mocked = :mocked")
+ abstract fun updateProfileMockStatus(mocked: Boolean)
+
+ @Query("UPDATE Profile SET name = :name")
+ abstract fun updateProfileName(name: String)
+
+ @Query("UPDATE Profile SET email = :email")
+ abstract fun updateProfileEmail(email: String)
+
+ @Query("UPDATE Profile SET sagres_id = :sagresId")
+ abstract fun updateProfileSagresId(sagresId: Long)
+
+ @Query("DELETE FROM Profile WHERE me = 1")
+ abstract fun deleteMe()
+
+ @Query("SELECT * FROM Profile WHERE uuid = :profileUUID LIMIT 1")
+ abstract fun selectProfileByUUID(profileUUID: String): LiveData
+
+ @Query("UPDATE Profile SET course = :courseId WHERE me = 1")
+ abstract fun updateCourse(courseId: Long)
+
+ @Query("UPDATE Profile SET calc_score = :score WHERE me = 1")
+ abstract fun updateCalculatedScore(score: Double)
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/SemesterDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/SemesterDao.kt
index 27bcc5809..d8bebfd76 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/SemesterDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/SemesterDao.kt
@@ -1,96 +1,107 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.database.dao
-
-import androidx.lifecycle.LiveData
-import androidx.room.Dao
-import androidx.room.Insert
-import androidx.room.OnConflictStrategy
-import androidx.room.Query
-import androidx.room.Transaction
-import com.forcetower.uefs.core.model.unes.Semester
-
-@Dao
-abstract class SemesterDao {
- @Transaction
- open fun insertIgnoring(semesters: List) {
- val newSemesters = semesters.filter { semester ->
- val current = getSemesterDirect(semester.sagresId)
- if (current != null) {
- if (current.start != semester.start && semester.start != null)
- updateStart(current.sagresId, semester.start)
-
- if (current.end != semester.end && semester.end != null)
- updateEnd(current.sagresId, semester.end)
-
- if (current.startClass != semester.startClass && semester.startClass != null)
- updateStartClass(current.sagresId, semester.startClass)
-
- if (current.endClass != semester.endClass && semester.endClass != null)
- updateEndClass(current.sagresId, semester.endClass)
-
- if (current.name != semester.name)
- updateName(current.sagresId, semester.name)
- }
-
- // keep only the new semesters
- // don't bother try inserting if we just updated above
- current == null
- }
- internalInsertIgnoring(newSemesters)
- }
-
- @Query("UPDATE Semester SET start = :start WHERE sagres_id = :sagresId")
- protected abstract fun updateStart(sagresId: Long, start: Long)
-
- @Query("UPDATE Semester SET `end` = :end WHERE sagres_id = :sagresId")
- protected abstract fun updateEnd(sagresId: Long, end: Long)
-
- @Query("UPDATE Semester SET start_class = :startClass WHERE sagres_id = :sagresId")
- protected abstract fun updateStartClass(sagresId: Long, startClass: Long)
-
- @Query("UPDATE Semester SET end_class = :endClass WHERE sagres_id = :sagresId")
- protected abstract fun updateEndClass(sagresId: Long, endClass: Long)
-
- @Query("UPDATE Semester SET name = :name WHERE sagres_id = :sagresId")
- protected abstract fun updateName(sagresId: Long, name: String)
-
- @Query("SELECT * FROM Semester WHERE sagres_id = :sagresId")
- abstract fun getSemesterDirect(sagresId: Long): Semester?
-
- @Insert(onConflict = OnConflictStrategy.IGNORE)
- protected abstract fun internalInsertIgnoring(semesters: List)
-
- @Insert(onConflict = OnConflictStrategy.IGNORE)
- abstract fun insertIgnoring(semester: Semester)
-
- @Query("SELECT * FROM Semester ORDER BY sagres_id DESC")
- abstract fun getParticipatingSemesters(): LiveData>
-
- @Query("SELECT * FROM Semester ORDER BY sagres_id DESC")
- abstract suspend fun getParticipatingSemestersDirect(): List
-
- @Query("DELETE FROM Semester")
- abstract fun deleteAll()
-
- @Query("SELECT * FROM Semester ORDER BY sagres_id DESC")
- abstract fun getSemestersDirect(): List
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.database.dao
+
+import androidx.lifecycle.LiveData
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import com.forcetower.uefs.core.model.unes.Semester
+
+@Dao
+abstract class SemesterDao {
+ @Transaction
+ open fun insertIgnoring(semesters: List) {
+ val newSemesters = semesters.filter { semester ->
+ val current = getSemesterDirect(semester.sagresId)
+ if (current != null) {
+ if (current.start != semester.start && semester.start != null) {
+ updateStart(current.sagresId, semester.start)
+ }
+
+ if (current.end != semester.end && semester.end != null) {
+ updateEnd(current.sagresId, semester.end)
+ }
+
+ if (current.startClass != semester.startClass && semester.startClass != null) {
+ updateStartClass(current.sagresId, semester.startClass)
+ }
+
+ if (current.endClass != semester.endClass && semester.endClass != null) {
+ updateEndClass(current.sagresId, semester.endClass)
+ }
+
+ if (current.name != semester.name) {
+ updateName(current.sagresId, semester.name)
+ }
+ }
+
+ // keep only the new semesters
+ // don't bother try inserting if we just updated above
+ current == null
+ }
+ internalInsertIgnoring(newSemesters)
+ }
+
+ @Query("UPDATE Semester SET start = :start WHERE sagres_id = :sagresId")
+ protected abstract fun updateStart(sagresId: Long, start: Long)
+
+ @Query("UPDATE Semester SET `end` = :end WHERE sagres_id = :sagresId")
+ protected abstract fun updateEnd(sagresId: Long, end: Long)
+
+ @Query("UPDATE Semester SET start_class = :startClass WHERE sagres_id = :sagresId")
+ protected abstract fun updateStartClass(sagresId: Long, startClass: Long)
+
+ @Query("UPDATE Semester SET end_class = :endClass WHERE sagres_id = :sagresId")
+ protected abstract fun updateEndClass(sagresId: Long, endClass: Long)
+
+ @Query("UPDATE Semester SET name = :name WHERE sagres_id = :sagresId")
+ protected abstract fun updateName(sagresId: Long, name: String)
+
+ @Query("SELECT * FROM Semester WHERE sagres_id = :sagresId")
+ abstract fun getSemesterDirect(sagresId: Long): Semester?
+
+ @Query("SELECT * FROM Semester WHERE sagres_id = :sagresId")
+ abstract suspend fun getSemesterDirectSuspend(sagresId: Long): Semester?
+
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ protected abstract fun internalInsertIgnoring(semesters: List)
+
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ abstract fun insertIgnoring(semester: Semester)
+
+ @Query("SELECT * FROM Semester ORDER BY sagres_id DESC")
+ abstract fun getParticipatingSemesters(): LiveData>
+
+ @Query("SELECT * FROM Semester ORDER BY sagres_id DESC")
+ abstract suspend fun getParticipatingSemestersDirect(): List
+
+ @Query("DELETE FROM Semester")
+ abstract fun deleteAll()
+
+ @Query("SELECT * FROM Semester ORDER BY sagres_id DESC")
+ abstract fun getSemestersDirect(): List
+
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ abstract suspend fun insertIgnoreSuspend(semester: Semester)
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/StudentServiceDao.kt b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/StudentServiceDao.kt
index 761be3a33..77a0aeabf 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/StudentServiceDao.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/database/dao/StudentServiceDao.kt
@@ -40,4 +40,7 @@ interface StudentServiceDao {
@Query("SELECT * FROM SStudent WHERE me = 1")
fun getMeStudent(): LiveData
+
+ @Query("UPDATE SStudent SET me = 0")
+ suspend fun markNoOneAsMe()
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionSpeakerTalker.kt b/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionSpeakerTalker.kt
index c90d4c3aa..3665f5eee 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionSpeakerTalker.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionSpeakerTalker.kt
@@ -28,6 +28,7 @@ import com.forcetower.uefs.core.model.siecomp.Speaker
class SessionSpeakerTalker {
@Embedded
lateinit var data: SessionSpeaker
+
@Relation(entityColumn = "uid", parentColumn = "speaker_id")
lateinit var speakers: List
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionTagged.kt b/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionTagged.kt
index 608e390a6..939715caf 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionTagged.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionTagged.kt
@@ -28,6 +28,7 @@ import com.forcetower.uefs.core.model.siecomp.Tag
class SessionTagged {
@Embedded
lateinit var data: SessionTag
+
@Relation(entityColumn = "uid", parentColumn = "tag_id")
lateinit var tag: List
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionWithData.kt b/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionWithData.kt
index 05becbc50..3ea9e8c61 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionWithData.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/eventdatabase/accessors/SessionWithData.kt
@@ -1,47 +1,50 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.eventdatabase.accessors
-
-import androidx.room.Embedded
-import androidx.room.Relation
-import com.forcetower.uefs.core.model.siecomp.Session
-import com.forcetower.uefs.core.model.siecomp.SessionSpeaker
-import com.forcetower.uefs.core.model.siecomp.SessionStar
-import com.forcetower.uefs.core.model.siecomp.SessionTag
-
-class SessionWithData : Comparable {
- @Embedded
- lateinit var session: Session
- @Relation(entityColumn = "session_id", parentColumn = "uid", entity = SessionSpeaker::class)
- lateinit var speakersRel: List
- @Relation(entityColumn = "session_id", parentColumn = "uid", entity = SessionTag::class)
- lateinit var displayTags: List
- @Relation(entityColumn = "session_id", parentColumn = "uid")
- lateinit var stars: List
-
- fun tags() = displayTags.map { it.singleTag() }.filter { !it.internal }
- fun speakers() = speakersRel.map { it.singleSpeaker() }
- fun isStarred() = stars.isNotEmpty()
-
- override fun compareTo(other: SessionWithData): Int {
- return session.compareTo(other.session)
- }
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.eventdatabase.accessors
+
+import androidx.room.Embedded
+import androidx.room.Relation
+import com.forcetower.uefs.core.model.siecomp.Session
+import com.forcetower.uefs.core.model.siecomp.SessionSpeaker
+import com.forcetower.uefs.core.model.siecomp.SessionStar
+import com.forcetower.uefs.core.model.siecomp.SessionTag
+
+class SessionWithData : Comparable {
+ @Embedded
+ lateinit var session: Session
+
+ @Relation(entityColumn = "session_id", parentColumn = "uid", entity = SessionSpeaker::class)
+ lateinit var speakersRel: List
+
+ @Relation(entityColumn = "session_id", parentColumn = "uid", entity = SessionTag::class)
+ lateinit var displayTags: List
+
+ @Relation(entityColumn = "session_id", parentColumn = "uid")
+ lateinit var stars: List
+
+ fun tags() = displayTags.map { it.singleTag() }.filter { !it.internal }
+ fun speakers() = speakersRel.map { it.singleSpeaker() }
+ fun isStarred() = stars.isNotEmpty()
+
+ override fun compareTo(other: SessionWithData): Int {
+ return session.compareTo(other.session)
+ }
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/imgur/ImageUploader.kt b/app/src/main/java/com/forcetower/uefs/core/storage/imgur/ImageUploader.kt
index 651749dfb..5c177d827 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/imgur/ImageUploader.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/imgur/ImageUploader.kt
@@ -1,60 +1,60 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.imgur
-
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
-import android.net.Uri
-import android.util.Base64
-import com.forcetower.uefs.core.model.api.ImgurUpload
-import com.forcetower.uefs.core.util.ImgurUploader
-import okhttp3.OkHttpClient
-import timber.log.Timber
-import java.io.ByteArrayOutputStream
-import java.io.InputStream
-import java.util.UUID
-
-object ImageUploader {
- fun uploadToImGur(
- uri: Uri,
- context: Context,
- client: OkHttpClient,
- name: String = UUID.randomUUID().toString()
- ): ImgurUpload? {
- val resolver = context.applicationContext.contentResolver
- val stream: InputStream
- try {
- stream = resolver.openInputStream(uri) ?: throw Exception("Failed to load stream")
- } catch (exception: Throwable) {
- Timber.e(exception, "Error uploading image...")
- return null
- }
-
- val bitmap = BitmapFactory.decodeStream(stream)
-
- val baos = ByteArrayOutputStream()
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
- val data = baos.toByteArray()
- val encoded = Base64.encodeToString(data, Base64.DEFAULT)
- return ImgurUploader.upload(client, encoded, name)
- }
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.imgur
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.util.Base64
+import com.forcetower.uefs.core.model.api.ImgurUpload
+import com.forcetower.uefs.core.util.ImgurUploader
+import java.io.ByteArrayOutputStream
+import java.io.InputStream
+import java.util.UUID
+import okhttp3.OkHttpClient
+import timber.log.Timber
+
+object ImageUploader {
+ fun uploadToImGur(
+ uri: Uri,
+ context: Context,
+ client: OkHttpClient,
+ name: String = UUID.randomUUID().toString()
+ ): ImgurUpload? {
+ val resolver = context.applicationContext.contentResolver
+ val stream: InputStream
+ try {
+ stream = resolver.openInputStream(uri) ?: throw Exception("Failed to load stream")
+ } catch (exception: Throwable) {
+ Timber.e(exception, "Error uploading image...")
+ return null
+ }
+
+ val bitmap = BitmapFactory.decodeStream(stream)
+
+ val baos = ByteArrayOutputStream()
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
+ val data = baos.toByteArray()
+ val encoded = Base64.encodeToString(data, Base64.DEFAULT)
+ return ImgurUploader.upload(client, encoded, name)
+ }
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/network/EdgeService.kt b/app/src/main/java/com/forcetower/uefs/core/storage/network/EdgeService.kt
index 65e7f4411..3c8be08e3 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/network/EdgeService.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/network/EdgeService.kt
@@ -1,19 +1,20 @@
package com.forcetower.uefs.core.storage.network
-import com.forcetower.uefs.core.model.edge.AssertionData
-import com.forcetower.uefs.core.model.edge.ChangePictureDTO
-import com.forcetower.uefs.core.model.edge.CompleteAssertionData
-import com.forcetower.uefs.core.model.edge.EdgeAccessTokenDTO
-import com.forcetower.uefs.core.model.edge.EdgeLoginBody
-import com.forcetower.uefs.core.model.edge.EmailLinkBodyDTO
-import com.forcetower.uefs.core.model.edge.EmailLinkConfirmDTO
-import com.forcetower.uefs.core.model.edge.LinkEmailResponseDTO
-import com.forcetower.uefs.core.model.edge.RegisterPasskeyCredential
-import com.forcetower.uefs.core.model.edge.RegisterPasskeyStart
-import com.forcetower.uefs.core.model.edge.SendMessagingTokenDTO
-import com.forcetower.uefs.core.model.edge.ServiceAccountDTO
import com.forcetower.uefs.core.model.edge.ServiceResponseWrapper
-import com.forcetower.uefs.core.model.unes.AccessToken
+import com.forcetower.uefs.core.model.edge.account.ChangePictureDTO
+import com.forcetower.uefs.core.model.edge.account.SendMessagingTokenDTO
+import com.forcetower.uefs.core.model.edge.account.ServiceAccountDTO
+import com.forcetower.uefs.core.model.edge.auth.AssertionData
+import com.forcetower.uefs.core.model.edge.auth.CompleteAssertionData
+import com.forcetower.uefs.core.model.edge.auth.EdgeAccessTokenDTO
+import com.forcetower.uefs.core.model.edge.auth.EdgeLoginBody
+import com.forcetower.uefs.core.model.edge.auth.EmailLinkBodyDTO
+import com.forcetower.uefs.core.model.edge.auth.EmailLinkConfirmDTO
+import com.forcetower.uefs.core.model.edge.auth.LinkEmailResponseDTO
+import com.forcetower.uefs.core.model.edge.auth.RegisterPasskeyCredential
+import com.forcetower.uefs.core.model.edge.auth.RegisterPasskeyStart
+import com.forcetower.uefs.core.model.edge.sync.PublicDisciplineData
+import com.forcetower.uefs.core.model.edge.sync.PublicPlatformMessage
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
@@ -49,4 +50,10 @@ interface EdgeService {
@POST("account/picture")
suspend fun uploadPicture(@Body data: ChangePictureDTO): ServiceResponseWrapper
+
+ @GET("messages/platform")
+ suspend fun messages(): ServiceResponseWrapper>
+
+ @GET("disciplines/current")
+ suspend fun disciplines(): ServiceResponseWrapper
}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/network/ParadoxService.kt b/app/src/main/java/com/forcetower/uefs/core/storage/network/ParadoxService.kt
new file mode 100644
index 000000000..c8d3becae
--- /dev/null
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/network/ParadoxService.kt
@@ -0,0 +1,23 @@
+package com.forcetower.uefs.core.storage.network
+
+import com.forcetower.uefs.core.model.edge.ServiceResponseWrapper
+import com.forcetower.uefs.core.model.edge.paradox.EvaluationHotTopic
+import com.forcetower.uefs.core.model.edge.paradox.EvaluationSnapshot
+import com.forcetower.uefs.core.model.edge.paradox.PublicDisciplineEvaluationCombinedData
+import com.forcetower.uefs.core.model.edge.paradox.PublicTeacherEvaluationCombinedData
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+interface ParadoxService {
+ @GET("evaluation/all")
+ suspend fun all(): ServiceResponseWrapper
+
+ @GET("evaluation/hot")
+ suspend fun hot(): ServiceResponseWrapper>
+
+ @GET("evaluation/teacher")
+ suspend fun teacher(@Query("id") id: String): ServiceResponseWrapper
+
+ @GET("evaluation/discipline")
+ suspend fun discipline(@Query("id") id: String): ServiceResponseWrapper
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/network/UService.kt b/app/src/main/java/com/forcetower/uefs/core/storage/network/UService.kt
index 7310af36f..9eb57c7c4 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/network/UService.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/network/UService.kt
@@ -1,275 +1,275 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.network
-
-import com.forcetower.sagres.SagresNavigator
-import com.forcetower.uefs.core.constants.Constants
-import com.forcetower.uefs.core.model.api.DarkInvite
-import com.forcetower.uefs.core.model.api.DarkUnlock
-import com.forcetower.uefs.core.model.api.EverythingSnippet
-import com.forcetower.uefs.core.model.api.ImgurUpload
-import com.forcetower.uefs.core.model.api.UResponse
-import com.forcetower.uefs.core.model.service.Achievement
-import com.forcetower.uefs.core.model.service.AffinityQuestionAnswer
-import com.forcetower.uefs.core.model.service.AffinityQuestionDTO
-import com.forcetower.uefs.core.model.service.EvaluationDiscipline
-import com.forcetower.uefs.core.model.service.EvaluationHomeTopic
-import com.forcetower.uefs.core.model.service.EvaluationTeacher
-import com.forcetower.uefs.core.model.service.FlowchartDTO
-import com.forcetower.uefs.core.model.service.SavedCookie
-import com.forcetower.uefs.core.model.service.UNESUpdate
-import com.forcetower.uefs.core.model.service.UserSessionDTO
-import com.forcetower.uefs.core.model.service.discipline.DisciplineDetailsData
-import com.forcetower.uefs.core.model.siecomp.ServerSession
-import com.forcetower.uefs.core.model.siecomp.Speaker
-import com.forcetower.uefs.core.model.unes.Access
-import com.forcetower.uefs.core.model.unes.AccessToken
-import com.forcetower.uefs.core.model.unes.Account
-import com.forcetower.uefs.core.model.unes.Course
-import com.forcetower.uefs.core.model.unes.CreateStatementParams
-import com.forcetower.uefs.core.model.unes.Event
-import com.forcetower.uefs.core.model.unes.Flowchart
-import com.forcetower.uefs.core.model.unes.Profile
-import com.forcetower.uefs.core.model.unes.ProfileStatement
-import com.forcetower.uefs.core.model.unes.Question
-import com.forcetower.uefs.core.model.unes.SStudentDTO
-import retrofit2.Call
-import retrofit2.Response
-import retrofit2.http.Body
-import retrofit2.http.Field
-import retrofit2.http.FormUrlEncoded
-import retrofit2.http.GET
-import retrofit2.http.POST
-import retrofit2.http.Query
-import java.util.Locale
-
-interface UService {
- @POST("oauth/token")
- @FormUrlEncoded
- fun loginWithSagres(
- @Field("username") username: String,
- @Field("password") password: String,
- @Field("grant_type") grant: String = "sagres",
- @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
- @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
- @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
- ): Call
-
- @POST("oauth/token")
- @FormUrlEncoded
- fun login(
- @Field("username") username: String,
- @Field("password") password: String,
- @Field("grant_type") grant: String = "password",
- @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
- @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET
- ): Call
-
- @POST("oauth/token")
- @FormUrlEncoded
- fun loginWithBiscuit(
- @Field("username") username: String,
- @Field("password") password: String,
- @Field("auth") auth: String,
- @Field("session_id") session: String,
- @Field("grant_type") grant: String = "biscuit",
- @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
- @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
- @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
- ): Call
-
- @POST("oauth/token")
- @FormUrlEncoded
- suspend fun loginWithSagresSuspend(
- @Field("username") username: String,
- @Field("password") password: String,
- @Field("grant_type") grant: String = "sagres",
- @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
- @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
- @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
- ): AccessToken
-
- @POST("oauth/token")
- @FormUrlEncoded
- suspend fun loginSuspend(
- @Field("username") username: String,
- @Field("password") password: String,
- @Field("grant_type") grant: String = "password",
- @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
- @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET
- ): AccessToken
-
- @POST("oauth/token")
- @FormUrlEncoded
- suspend fun loginWithBiscuitSuspend(
- @Field("username") username: String,
- @Field("password") password: String,
- @Field("auth") auth: String,
- @Field("session_id") session: String,
- @Field("grant_type") grant: String = "biscuit",
- @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
- @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
- @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
- ): AccessToken
-
- @POST("account/credentials")
- fun setupAccount(@Body access: Access): Call>
-
- @POST("account/profile")
- fun setupProfile(@Body profile: Profile): Call>
-
- @POST("account/update_fcm")
- fun sendToken(@Body data: Map): Call>
-
- @POST("account/update_fcm")
- suspend fun sendTokenSuspend(@Body data: Map): UResponse
-
- @GET("account")
- fun getAccount(): Call
-
- @POST("account/image")
- fun updateProfileImage(@Body data: ImgurUpload): Call>
-
- @POST("account/darktheme")
- fun requestDarkThemeUnlock(@Body invites: DarkUnlock): Call>
-
- @POST("account/darktheme/invite")
- fun requestDarkSendTo(@Body invite: DarkInvite): Call>
-
- @GET("account/statements")
- fun getStatements(@Query("profile_id") studentId: Long): Call>>
-
- @POST("account/statements/create")
- fun sendStatement(@Body params: CreateStatementParams): Call
-
- @POST("account/statements/approve")
- fun acceptStatement(@Body body: Map): Call
-
- @POST("account/statements/refuse")
- fun refuseStatement(@Body body: Map): Call
-
- @POST("account/statements/delete")
- fun deleteStatement(@Body body: Map): Call
-
- @POST("account/save_sessions")
- fun saveSessions(@Body session: UserSessionDTO): Call
-
- @GET("courses")
- suspend fun getCourses(): List
-
- @GET("synchronization")
- fun getUpdate(): Call
-
- @POST("grades")
- fun sendGrades(@Body grades: DisciplineDetailsData): Call>
-
- // -------- Evaluation ---------
- @GET("evaluation/hot")
- fun getEvaluationTopics(): Call>
-
- @GET("evaluation/discipline")
- fun getEvaluationDiscipline(@Query("department") department: String, @Query("code") code: String): Call
-
- @GET("evaluation/teacher")
- fun getTeacherById(@Query("id") teacherId: Long): Call
-
- @GET("evaluation/teacher")
- fun getTeacherByName(@Query("name") teacherName: String): Call
-
- @GET("evaluation/question/teacher")
- fun getQuestionsForTeachers(@Query("teacher_id") teacherId: Long): Call>
-
- @GET("evaluation/question/discipline")
- fun getQuestionsForDisciplines(@Query("code") code: String, @Query("department") department: String): Call>
-
- @POST("evaluation/question/answer")
- fun answerQuestion(@Body data: MutableMap): Call>
-
- @GET("evaluation/everythingship")
- fun getEvaluationSnippetData(): Call
-
- // --------- Flowchart ---------
-
- @GET("flowchart")
- fun getFlowcharts(): Call>>
-
- @GET("flowchart")
- fun getFlowchart(@Query("course_id") course: Long): Call>
-
- // --------- Social -------------
-
- @GET("student")
- fun getStudent(@Query("student_id") studentId: Long): Call>
-
- @GET("student/me")
- fun getMeStudent(): Call>
-
- // --------- Achievements ---------
- @GET("adventure/achievement")
- fun getServerAchievements(): Call>>
-
- // ----------- SIECOMP ------------
-
- @GET("siecomp/list_sessions")
- fun siecompSessions(): Call>
-
- @POST("siecomp/speaker")
- fun createSpeaker(@Body speaker: Speaker): Call
-
- @POST("siecomp/edit_speaker")
- fun updateSpeaker(@Body speaker: Speaker): Call
-
- // ---------- Affinity -----------
- @GET("affinity/questions")
- fun affinityQuestions(): Call>>
-
- @POST("affinity/answer")
- fun answerAffinity(@Body answer: AffinityQuestionAnswer): Call>
-
- // --------- General Events ---------
- @GET("events")
- suspend fun events(): UResponse>
-
- @POST("events/create")
- suspend fun sendEvent(@Body event: Event): UResponse
-
- @FormUrlEncoded
- @POST("events/approve")
- suspend fun approveEvent(@Field("id") id: Long): UResponse
-
- @FormUrlEncoded
- @POST("events/delete")
- suspend fun deleteEvent(@Field("id") id: Long): UResponse
-
- // ---------- Cookies for everyone -----------
- @POST("biscuit/save")
- suspend fun prepareSession(@Body cookie: SavedCookie): UResponse
-
- @GET("biscuit/retrieve")
- suspend fun getSession(): UResponse
-
- @POST("biscuit/invalidate")
- suspend fun invalidateSession(): UResponse
-
- // ------------ ping --------------
- @GET("hi")
- suspend fun hi(): Response>
-}
+/*
+ * This file is part of the UNES Open Source Project.
+ * UNES is licensed under the GNU GPLv3.
+ *
+ * Copyright (c) 2020. João Paulo Sena
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.forcetower.uefs.core.storage.network
+
+import com.forcetower.sagres.SagresNavigator
+import com.forcetower.uefs.core.constants.Constants
+import com.forcetower.uefs.core.model.api.DarkInvite
+import com.forcetower.uefs.core.model.api.DarkUnlock
+import com.forcetower.uefs.core.model.api.EverythingSnippet
+import com.forcetower.uefs.core.model.api.ImgurUpload
+import com.forcetower.uefs.core.model.api.UResponse
+import com.forcetower.uefs.core.model.service.Achievement
+import com.forcetower.uefs.core.model.service.AffinityQuestionAnswer
+import com.forcetower.uefs.core.model.service.AffinityQuestionDTO
+import com.forcetower.uefs.core.model.service.EvaluationDiscipline
+import com.forcetower.uefs.core.model.service.EvaluationHomeTopic
+import com.forcetower.uefs.core.model.service.EvaluationTeacher
+import com.forcetower.uefs.core.model.service.FlowchartDTO
+import com.forcetower.uefs.core.model.service.SavedCookie
+import com.forcetower.uefs.core.model.service.UNESUpdate
+import com.forcetower.uefs.core.model.service.UserSessionDTO
+import com.forcetower.uefs.core.model.service.discipline.DisciplineDetailsData
+import com.forcetower.uefs.core.model.siecomp.ServerSession
+import com.forcetower.uefs.core.model.siecomp.Speaker
+import com.forcetower.uefs.core.model.unes.Access
+import com.forcetower.uefs.core.model.unes.AccessToken
+import com.forcetower.uefs.core.model.unes.Account
+import com.forcetower.uefs.core.model.unes.Course
+import com.forcetower.uefs.core.model.unes.CreateStatementParams
+import com.forcetower.uefs.core.model.unes.Event
+import com.forcetower.uefs.core.model.unes.Flowchart
+import com.forcetower.uefs.core.model.unes.Profile
+import com.forcetower.uefs.core.model.unes.ProfileStatement
+import com.forcetower.uefs.core.model.unes.Question
+import com.forcetower.uefs.core.model.unes.SStudentDTO
+import java.util.Locale
+import retrofit2.Call
+import retrofit2.Response
+import retrofit2.http.Body
+import retrofit2.http.Field
+import retrofit2.http.FormUrlEncoded
+import retrofit2.http.GET
+import retrofit2.http.POST
+import retrofit2.http.Query
+
+interface UService {
+ @POST("oauth/token")
+ @FormUrlEncoded
+ fun loginWithSagres(
+ @Field("username") username: String,
+ @Field("password") password: String,
+ @Field("grant_type") grant: String = "sagres",
+ @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
+ @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
+ @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
+ ): Call
+
+ @POST("oauth/token")
+ @FormUrlEncoded
+ fun login(
+ @Field("username") username: String,
+ @Field("password") password: String,
+ @Field("grant_type") grant: String = "password",
+ @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
+ @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET
+ ): Call
+
+ @POST("oauth/token")
+ @FormUrlEncoded
+ fun loginWithBiscuit(
+ @Field("username") username: String,
+ @Field("password") password: String,
+ @Field("auth") auth: String,
+ @Field("session_id") session: String,
+ @Field("grant_type") grant: String = "biscuit",
+ @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
+ @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
+ @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
+ ): Call
+
+ @POST("oauth/token")
+ @FormUrlEncoded
+ suspend fun loginWithSagresSuspend(
+ @Field("username") username: String,
+ @Field("password") password: String,
+ @Field("grant_type") grant: String = "sagres",
+ @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
+ @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
+ @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
+ ): AccessToken
+
+ @POST("oauth/token")
+ @FormUrlEncoded
+ suspend fun loginSuspend(
+ @Field("username") username: String,
+ @Field("password") password: String,
+ @Field("grant_type") grant: String = "password",
+ @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
+ @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET
+ ): AccessToken
+
+ @POST("oauth/token")
+ @FormUrlEncoded
+ suspend fun loginWithBiscuitSuspend(
+ @Field("username") username: String,
+ @Field("password") password: String,
+ @Field("auth") auth: String,
+ @Field("session_id") session: String,
+ @Field("grant_type") grant: String = "biscuit",
+ @Field("client_id") client: String = Constants.SERVICE_CLIENT_ID,
+ @Field("client_secret") secret: String = Constants.SERVICE_CLIENT_SECRET,
+ @Field("institution") institution: String = SagresNavigator.instance.getSelectedInstitution().lowercase(Locale.ROOT)
+ ): AccessToken
+
+ @POST("account/credentials")
+ fun setupAccount(@Body access: Access): Call>
+
+ @POST("account/profile")
+ fun setupProfile(@Body profile: Profile): Call>
+
+ @POST("account/update_fcm")
+ fun sendToken(@Body data: Map): Call>
+
+ @POST("account/update_fcm")
+ suspend fun sendTokenSuspend(@Body data: Map): UResponse
+
+ @GET("account")
+ fun getAccount(): Call
+
+ @POST("account/image")
+ fun updateProfileImage(@Body data: ImgurUpload): Call>
+
+ @POST("account/darktheme")
+ fun requestDarkThemeUnlock(@Body invites: DarkUnlock): Call>
+
+ @POST("account/darktheme/invite")
+ fun requestDarkSendTo(@Body invite: DarkInvite): Call>
+
+ @GET("account/statements")
+ fun getStatements(@Query("profile_id") studentId: Long): Call>>
+
+ @POST("account/statements/create")
+ fun sendStatement(@Body params: CreateStatementParams): Call
+
+ @POST("account/statements/approve")
+ fun acceptStatement(@Body body: Map): Call
+
+ @POST("account/statements/refuse")
+ fun refuseStatement(@Body body: Map): Call
+
+ @POST("account/statements/delete")
+ fun deleteStatement(@Body body: Map): Call
+
+ @POST("account/save_sessions")
+ fun saveSessions(@Body session: UserSessionDTO): Call
+
+ @GET("courses")
+ suspend fun getCourses(): List
+
+ @GET("synchronization")
+ fun getUpdate(): Call
+
+ @POST("grades")
+ fun sendGrades(@Body grades: DisciplineDetailsData): Call>
+
+ // -------- Evaluation ---------
+ @GET("evaluation/hot")
+ fun getEvaluationTopics(): Call>
+
+ @GET("evaluation/discipline")
+ fun getEvaluationDiscipline(@Query("department") department: String, @Query("code") code: String): Call
+
+ @GET("evaluation/teacher")
+ fun getTeacherById(@Query("id") teacherId: Long): Call
+
+ @GET("evaluation/teacher")
+ fun getTeacherByName(@Query("name") teacherName: String): Call
+
+ @GET("evaluation/question/teacher")
+ fun getQuestionsForTeachers(@Query("teacher_id") teacherId: Long): Call>
+
+ @GET("evaluation/question/discipline")
+ fun getQuestionsForDisciplines(@Query("code") code: String, @Query("department") department: String): Call>
+
+ @POST("evaluation/question/answer")
+ fun answerQuestion(@Body data: MutableMap): Call>
+
+ @GET("evaluation/everythingship")
+ fun getEvaluationSnippetData(): Call
+
+ // --------- Flowchart ---------
+
+ @GET("flowchart")
+ fun getFlowcharts(): Call>>
+
+ @GET("flowchart")
+ fun getFlowchart(@Query("course_id") course: Long): Call>
+
+ // --------- Social -------------
+
+ @GET("student")
+ fun getStudent(@Query("student_id") studentId: Long): Call>
+
+ @GET("student/me")
+ fun getMeStudent(): Call>
+
+ // --------- Achievements ---------
+ @GET("adventure/achievement")
+ fun getServerAchievements(): Call>>
+
+ // ----------- SIECOMP ------------
+
+ @GET("siecomp/list_sessions")
+ fun siecompSessions(): Call>
+
+ @POST("siecomp/speaker")
+ fun createSpeaker(@Body speaker: Speaker): Call
+
+ @POST("siecomp/edit_speaker")
+ fun updateSpeaker(@Body speaker: Speaker): Call
+
+ // ---------- Affinity -----------
+ @GET("affinity/questions")
+ fun affinityQuestions(): Call>>
+
+ @POST("affinity/answer")
+ fun answerAffinity(@Body answer: AffinityQuestionAnswer): Call>
+
+ // --------- General Events ---------
+ @GET("events")
+ suspend fun events(): UResponse>
+
+ @POST("events/create")
+ suspend fun sendEvent(@Body event: Event): UResponse
+
+ @FormUrlEncoded
+ @POST("events/approve")
+ suspend fun approveEvent(@Field("id") id: Long): UResponse
+
+ @FormUrlEncoded
+ @POST("events/delete")
+ suspend fun deleteEvent(@Field("id") id: Long): UResponse
+
+ // ---------- Cookies for everyone -----------
+ @POST("biscuit/save")
+ suspend fun prepareSession(@Body cookie: SavedCookie): UResponse
+
+ @GET("biscuit/retrieve")
+ suspend fun getSession(): UResponse
+
+ @POST("biscuit/invalidate")
+ suspend fun invalidateSession(): UResponse
+
+ // ------------ ping --------------
+ @GET("hi")
+ suspend fun hi(): Response>
+}
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/network/adapter/LiveDataCallAdapter.kt b/app/src/main/java/com/forcetower/uefs/core/storage/network/adapter/LiveDataCallAdapter.kt
index a17af4d42..eb85c6f2a 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/network/adapter/LiveDataCallAdapter.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/network/adapter/LiveDataCallAdapter.kt
@@ -20,10 +20,10 @@
package com.forcetower.uefs.core.storage.network.adapter
import androidx.lifecycle.LiveData
+import java.util.concurrent.atomic.AtomicBoolean
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
-import java.util.concurrent.atomic.AtomicBoolean
/**
* A Retrofit adapter that converts the Call into a LiveData of ApiResponse.
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/repository/AccountRepository.kt b/app/src/main/java/com/forcetower/uefs/core/storage/repository/AccountRepository.kt
index d747b3595..aa395d590 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/repository/AccountRepository.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/repository/AccountRepository.kt
@@ -29,8 +29,8 @@ import com.forcetower.uefs.core.storage.network.adapter.ApiResponse
import com.forcetower.uefs.core.storage.network.adapter.asLiveData
import com.forcetower.uefs.core.storage.resource.NetworkBoundResource
import com.forcetower.uefs.core.storage.resource.Resource
-import timber.log.Timber
import javax.inject.Inject
+import timber.log.Timber
class AccountRepository @Inject constructor(
private val database: UDatabase,
diff --git a/app/src/main/java/com/forcetower/uefs/core/storage/repository/AdventureRepository.kt b/app/src/main/java/com/forcetower/uefs/core/storage/repository/AdventureRepository.kt
index 467c8c2d4..a13c9139a 100644
--- a/app/src/main/java/com/forcetower/uefs/core/storage/repository/AdventureRepository.kt
+++ b/app/src/main/java/com/forcetower/uefs/core/storage/repository/AdventureRepository.kt
@@ -1,313 +1,326 @@
-/*
- * This file is part of the UNES Open Source Project.
- * UNES is licensed under the GNU GPLv3.
- *
- * Copyright (c) 2020. João Paulo Sena
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.forcetower.uefs.core.storage.repository
-
-import android.annotation.SuppressLint
-import android.content.SharedPreferences
-import android.location.Location
-import androidx.annotation.AnyThread
-import androidx.annotation.WorkerThread
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import com.forcetower.uefs.AppExecutors
-import com.forcetower.uefs.R
-import com.forcetower.uefs.core.constants.Constants
-import com.forcetower.uefs.core.model.service.AchDistance
-import com.forcetower.uefs.core.model.service.Achievement
-import com.forcetower.uefs.core.model.unes.ClassLocation
-import com.forcetower.uefs.core.model.unes.Semester
-import com.forcetower.uefs.core.storage.database.UDatabase
-import com.forcetower.uefs.core.storage.network.UService
-import com.forcetower.uefs.feature.shared.extensions.generateCalendarFromHour
-import java.util.Calendar
-import java.util.Locale
-import java.util.concurrent.TimeUnit
-import javax.inject.Inject
-import kotlin.collections.set
-
-class AdventureRepository @Inject constructor(
- private val database: UDatabase,
- private val executors: AppExecutors,
- private val preferences: SharedPreferences,
- private val locations: AchLocationsRepository,
- private val service: UService
-) {
-
- @AnyThread
- fun checkServerAchievements(): LiveData> {
- val data = MutableLiveData>()
- executors.networkIO().execute {
- try {
- val response = service.getServerAchievements().execute()
- if (response.isSuccessful) {
- val value = response.body()?.data ?: emptyList()
- data.postValue(value)
- } else {
- data.postValue(emptyList())
- }
- } catch (error: Throwable) {
- data.postValue(emptyList())
- }
- }
- return data
- }
-
- @AnyThread
- fun matchesAnyAchievement(location: Location?): List {
- return locations.onReceiveLocation(location)
- }
-
- @AnyThread
- fun checkAchievements(): LiveData