Skip to content

Commit

Permalink
1.0.5-beta: fixed fetching grades and refreshing
Browse files Browse the repository at this point in the history
  • Loading branch information
phytal committed May 20, 2022
1 parent 11ea300 commit 872027f
Show file tree
Hide file tree
Showing 53 changed files with 440 additions and 404 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions .idea/runConfigurations.xml

This file was deleted.

6 changes: 6 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# FAQ
## How do I edit an assignment's grade?
- Press and hold on the assignment, from there, you should be prompted with a pop-up to edit the details of the assignment.
# Known Issues
- Settings menu will only work upon launch.
- Refresh button crashing while viewing assignments.
26 changes: 26 additions & 0 deletions PRIVACY POLICY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# PRIVACY POLICY

## SimpleGrade
##### Last updated August 1, 2021
---

SimpleGrade (“we” or “us” or “our”) respects the privacy of our users (“user” or “you”). This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you visit our mobile application (the “Application”). Please read this Privacy Policy carefully. IF YOU DO NOT AGREE WITH THE TERMS OF THIS PRIVACY POLICY, PLEASE DO NOT ACCESS THE APPLICATION.

We reserve the right to make changes to this Privacy Policy at any time and for any reason. We will alert you about any changes by updating the “Last updated” date of this Privacy Policy. You are encouraged to periodically review this Privacy Policy to stay informed of updates. You will be deemed to have been made aware of, will be subject to, and will be deemed to have accepted the changes in any revised Privacy Policy by your continued use of the Application after the date such revised Privacy Policy is posted.

This Privacy Policy does not apply to the third-party online/mobile store from which you install the Application or make payments, including any in-game virtual items, which may also collect and use data about you. We are not responsible for any of the data collected by any such third party.

### **COLLECTION AND USE OF YOUR INFORMATION**
To use the app's features, a student account's gradebook system login credentials must be provided. This information or any other information displayed in the app will be retained on your device only and is not collected or viewable by me in any way. This application uses credentials you supply to retrieve and display grade and class information from your gradebook system server directly.

### **DISCLOSURE OF YOUR INFORMATION**
We do not give your data to any third-party service providers as we do not store any of your personal data.

### **SECURITY OF YOUR INFORMATION**
We use administrative, technical, and physical security measures to help protect your personal information. While we have taken reasonable steps to secure the personal information you provide to us, please be aware that despite our efforts, no security measures are perfect or impenetrable, and no method of data transmission can be guaranteed against any interception or other type of misuse. Any information disclosed online is vulnerable to interception and misuse by unauthorized parties. Therefore, we cannot guarantee complete security if you provide personal information.

### **LINKS TO OTHER SITES**
This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.

### **CONTACT US**
If you have questions or comments about this Privacy Policy, please contact us at [email protected].
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
# Projekt Sarona - SimpleGrade

## Summary
An Android grade-fetching app made with Kotlin. The app fetches student grades from the HomeAccessCenter (HAC) and displays them in a simple format.
An Android grade-fetching app made with Kotlin. The app fetches student grades from the Home Access Center (HAC) and displays them in a clean and simplified format.

## Further Details
Data collection is powered by my [HAC API made with Python+Flask](https://github.com/Phytal/HomeAccessCenter-Flask-API) and is stored locally on the device, allowing for offline usage.
- Data collection is powered by my [HAC API made with Python+Flask](https://github.com/Phytal/HomeAccessCenter-Flask-API) and is stored locally on the device, allowing for offline usage.

- Includes a Light and Dark theme design.

- Navigation Fragment Design adapted from Google's [Reply App](https://github.com/material-components/material-components-android-examples/tree/develop/Reply).

## Screenshots
- *To be added*
<img src="screenshots/sc_home.png" height="500"> <img src="screenshots/sc_courseview.png" height="500"> <img src="screenshots/sc_details.png" height="500">
<img src="screenshots/sc_add.png" height="500"> <img src="screenshots/sc_edit.png" height="500">

## Credits
- [William Zhang](https://www.linkedin.com/in/william-zhang-452141191/) ([Phytal](https://github.com/Phytal)) - Creator and Designer
- [William Zhang](https://www.linkedin.com/in/william-zhang-452141191/) ([Phytal](https://github.com/Phytal)) - Creator and Designer

<a href='https://play.google.com/store/apps/details?id=com.phytal.sarona&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' height=80/></a>
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId "com.phytal.sarona"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
versionCode 5
versionName "1.0.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
kapt {
arguments {
Expand Down Expand Up @@ -50,7 +50,7 @@ android {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation 'androidx.preference:preference-ktx:1.1.1'
Expand Down
12 changes: 9 additions & 3 deletions app/schemas/com.phytal.sarona.data.db.MpDatabase/1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "1782f97ab9d3ac4dbbcdae121565ce7f",
"identityHash": "8a8740a960337e044e065c5a3858686b",
"entities": [
{
"tableName": "mp_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mp` INTEGER NOT NULL, `courses` TEXT NOT NULL, PRIMARY KEY(`mp`))",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mp` INTEGER NOT NULL, `current` INTEGER NOT NULL, `courses` TEXT NOT NULL, PRIMARY KEY(`mp`))",
"fields": [
{
"fieldPath": "mp",
"columnName": "mp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "current",
"columnName": "current",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "courses",
"columnName": "courses",
Expand Down Expand Up @@ -43,7 +49,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1782f97ab9d3ac4dbbcdae121565ce7f')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8a8740a960337e044e065c5a3858686b')"
]
}
}
55 changes: 55 additions & 0 deletions app/schemas/com.phytal.sarona.data.db.MpDatabase/2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "8a8740a960337e044e065c5a3858686b",
"entities": [
{
"tableName": "mp_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mp` INTEGER NOT NULL, `current` INTEGER NOT NULL, `courses` TEXT NOT NULL, PRIMARY KEY(`mp`))",
"fields": [
{
"fieldPath": "mp",
"columnName": "mp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "current",
"columnName": "current",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "courses",
"columnName": "courses",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"mp"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_mp_table_mp",
"unique": true,
"columnNames": [
"mp"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_mp_table_mp` ON `${TABLE_NAME}` (`mp`)"
}
],
"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, '8a8740a960337e044e065c5a3858686b')"
]
}
}
Binary file removed app/src/main/ic_launcher-playstore.png
Binary file not shown.
2 changes: 0 additions & 2 deletions app/src/main/java/com/phytal/sarona/SaronaApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.phytal.sarona.internal.helpers.ThemeHelper
import com.phytal.sarona.internal.helpers.ThemeHelper.applyTheme
import com.phytal.sarona.ui.courses.CurrentCourseViewModelFactory
import com.phytal.sarona.ui.courses.MpCourseViewModelFactory
import com.phytal.sarona.ui.courses.PastCourseViewModelFactory
import com.phytal.sarona.ui.welcome.LoginViewModelFactory
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware
Expand All @@ -36,7 +35,6 @@ class SaronaApplication : Application(), KodeinAware {
bind<CourseRepository>() with singleton { CourseRepositoryImpl(instance(), instance()) }
bind<LoginProvider>() with singleton { LoginProviderImpl(instance()) }
bind() from provider { CurrentCourseViewModelFactory(instance(), instance()) }
bind() from provider { PastCourseViewModelFactory(instance(), instance()) }
bind() from provider { MpCourseViewModelFactory(instance(), instance()) }
bind() from provider { LoginViewModelFactory(instance()) }
}
Expand Down
7 changes: 2 additions & 5 deletions app/src/main/java/com/phytal/sarona/data/db/MpDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ interface MpDao {
@Query("SELECT * FROM mp_table")
fun getAllMps(): LiveData<List<MarkingPeriod>>

@Query("SELECT * FROM mp_table WHERE mp LIKE :mp LIMIT 1")
@Query("SELECT * FROM mp_table WHERE mp LIKE :mp+1 LIMIT 1")
fun getMp(mp: Int): LiveData<MarkingPeriod>

@Query("SELECT * FROM mp_table ORDER BY mp DESC LIMIT 1")
@Query("SELECT * FROM mp_table WHERE current IS 1 LIMIT 1")
fun getCurrentMp(): LiveData<MarkingPeriod>

@Query("SELECT * FROM mp_table WHERE mp < (SELECT MAX(mp) FROM mp_table)")
fun getPastMps(): LiveData<List<MarkingPeriod>>
}
3 changes: 1 addition & 2 deletions app/src/main/java/com/phytal/sarona/data/db/MpDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import com.phytal.sarona.data.db.entities.MarkingPeriod
import com.phytal.sarona.data.db.entities.DataConverter
import com.phytal.sarona.internal.helpers.SingletonHolder

@Database(entities = [MarkingPeriod::class], version = 1)
@Database(entities = [MarkingPeriod::class], version = 2)
@TypeConverters(DataConverter::class)
abstract class MpDatabase: RoomDatabase() {

abstract fun mpDao(): MpDao

companion object : SingletonHolder<MpDatabase, Context>({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.room.TypeConverters
data class MarkingPeriod(
@PrimaryKey
val mp: Int,
val current: Boolean,
@TypeConverters(DataConverter::class)
val courses: List<Course>
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.phytal.sarona.data.network.adapter.NetworkResponseAdapterFactory
import com.phytal.sarona.data.network.response.CurrentMpResponse
import com.phytal.sarona.data.network.response.LoginResponse
import com.phytal.sarona.data.network.response.MpResponse
import com.phytal.sarona.data.network.response.PastMpResponse
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
Expand All @@ -17,13 +16,6 @@ import java.util.concurrent.TimeUnit

interface HacApiService {

@GET("pastMp")
fun getPastMps(
@Query("l") hacLink: String,
@Query("u") username: String,
@Query("p") password: String
): Observable<PastMpResponse>

@GET("currentMp")
fun getCurrentMp(
@Query("l") hacLink: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ package com.phytal.sarona.data.network
import androidx.lifecycle.LiveData
import com.phytal.sarona.data.network.response.CurrentMpResponse
import com.phytal.sarona.data.network.response.MpResponse
import com.phytal.sarona.data.network.response.PastMpResponse
import com.phytal.sarona.internal.Event

interface MpNetworkDataSource {
val downloadedPastMps: LiveData<PastMpResponse>
val downloadedCurrentMp: LiveData<CurrentMpResponse>
val downloadedMp: LiveData<MpResponse>

Expand All @@ -16,11 +13,7 @@ interface MpNetworkDataSource {
username: String,
password: String
)
suspend fun fetchPastMps(
hacLink: String,
username: String,
password: String
)

suspend fun fetchMp(
hacLink: String,
username: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.phytal.sarona.data.network.response.CurrentMpResponse
import com.phytal.sarona.data.network.response.MpResponse
import com.phytal.sarona.data.network.response.PastMpResponse
import com.phytal.sarona.internal.Event
import com.phytal.sarona.internal.NoConnectivityException
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
Expand All @@ -17,29 +15,6 @@ class MpNetworkDataSourceImpl(
private val hacApiService: HacApiService
) : MpNetworkDataSource {

private val _downloadedPastMps = MutableLiveData<PastMpResponse>()
override val downloadedPastMps: LiveData<PastMpResponse>
get() = _downloadedPastMps

@SuppressLint("CheckResult")
override suspend fun fetchPastMps(
hacLink: String,
username: String,
password: String
) {
try {
hacApiService.getPastMps(hacLink, username, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ result ->
_downloadedPastMps.postValue(result)
},
{ error -> Log.e("Error", "Could not fetch past marking periods", error) })
} catch (e: NoConnectivityException) {
Log.e("Connectivity", "No internet connection.", e)
}
}

private val _downloadedCurrentMp = MutableLiveData<CurrentMpResponse>()
override val downloadedCurrentMp: LiveData<CurrentMpResponse>
get() = _downloadedCurrentMp
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ import com.phytal.sarona.data.provider.LoginInformation
interface CourseRepository {
suspend fun getCurrentMp(loginInfo: LoginInformation): LiveData<out MarkingPeriod>
suspend fun getMp(loginInfo: LoginInformation, mp: Int): LiveData<out MarkingPeriod>
suspend fun getPastMps(loginInfo: LoginInformation): LiveData<out List<MarkingPeriod>>
suspend fun getAllMps(): LiveData<out List<MarkingPeriod>>
}
Loading

0 comments on commit 872027f

Please sign in to comment.