forked from github/wulkanowy-mirror
Add services (#21)
This commit is contained in:
parent
7b087144e9
commit
9dfb0bc729
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ local.properties
|
||||
# User-specific configurations
|
||||
.idea/copyright/profiles_settings.xml
|
||||
.idea/libraries/
|
||||
.idea/inspectionProfiles/
|
||||
.idea/.name
|
||||
.idea/compiler.xml
|
||||
.idea/encodings.xml
|
||||
|
@ -42,6 +42,7 @@ dependencies {
|
||||
compile 'com.thoughtbot:expandablerecyclerview:1.3'
|
||||
compile 'com.android.support:cardview-v7:25.3.1'
|
||||
compile 'com.google.code.gson:gson:2.8.1'
|
||||
compile 'com.firebase:firebase-jobdispatcher:0.8.1'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:2.9.0'
|
||||
|
@ -5,12 +5,13 @@
|
||||
android:installLocation="internalOnly">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.thoughtbot.expandablerecyclerview, com.thoughtbot.expandablecheckrecyclerview" />
|
||||
<uses-sdk tools:overrideLibrary="com.thoughtbot.expandablerecyclerview" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
@ -18,9 +19,9 @@
|
||||
android:theme="@style/WulkanowyTheme">
|
||||
<activity
|
||||
android:name=".activity.started.StartedActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:noHistory="true"
|
||||
android:theme="@style/WulkanowyTheme.noActionBar"
|
||||
android:configChanges="orientation|screenSize">
|
||||
android:theme="@style/WulkanowyTheme.noActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@ -29,13 +30,21 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.main.MainActivity"
|
||||
android:label="@string/login_text"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/login_text"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".activity.dashboard.DashboardActivity"
|
||||
android:label="@string/activity_dashboard_text"
|
||||
android:configChanges="orientation|screenSize"/>
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/activity_dashboard_text" />
|
||||
|
||||
<service
|
||||
android:name=".services.jobs.GradesSync$GradeJob"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -16,8 +16,11 @@ import io.github.wulkanowy.activity.dashboard.lessonplan.LessonPlanFragment;
|
||||
public class DashboardActivity extends AppCompatActivity {
|
||||
|
||||
private GradesFragment gradesFragment = new GradesFragment();
|
||||
|
||||
private AttendanceFragment attendanceFragment = new AttendanceFragment();
|
||||
|
||||
private BoardFragment boardFragment = new BoardFragment();
|
||||
|
||||
private LessonPlanFragment lessonPlanFragment = new LessonPlanFragment();
|
||||
|
||||
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
|
||||
|
@ -10,23 +10,11 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.api.Cookies;
|
||||
import io.github.wulkanowy.api.StudentAndParent;
|
||||
import io.github.wulkanowy.api.grades.GradesList;
|
||||
import io.github.wulkanowy.api.grades.Subject;
|
||||
import io.github.wulkanowy.api.grades.SubjectsList;
|
||||
import io.github.wulkanowy.database.accounts.Account;
|
||||
import io.github.wulkanowy.database.accounts.AccountsDatabase;
|
||||
import io.github.wulkanowy.database.cookies.CookiesDatabase;
|
||||
import io.github.wulkanowy.database.grades.GradesDatabase;
|
||||
import io.github.wulkanowy.database.subjects.SubjectsDatabase;
|
||||
|
||||
@ -63,54 +51,23 @@ public class GradesFragment extends Fragment {
|
||||
|
||||
public class MarksTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private Map<String, String> loginCookies = new HashMap<>();
|
||||
private Context context;
|
||||
|
||||
MarksTask(Context context) {
|
||||
mContext = context;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
long userId = mContext.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0);
|
||||
|
||||
try {
|
||||
Gson gson = new GsonBuilder().enableComplexMapKeySerialization()
|
||||
.setPrettyPrinting().create();
|
||||
CookiesDatabase cookiesDatabase = new CookiesDatabase(mContext);
|
||||
cookiesDatabase.open();
|
||||
loginCookies = gson.fromJson(cookiesDatabase.getCookies(), loginCookies.getClass());
|
||||
cookiesDatabase.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SubjectsDatabase subjectsDatabase = new SubjectsDatabase(context);
|
||||
GradesDatabase gradesDatabase = new GradesDatabase(context);
|
||||
|
||||
try {
|
||||
Cookies cookies = new Cookies();
|
||||
cookies.setItems(loginCookies);
|
||||
|
||||
AccountsDatabase accountsDatabase = new AccountsDatabase(mContext);
|
||||
accountsDatabase.open();
|
||||
Account account = accountsDatabase.getAccount(userId);
|
||||
accountsDatabase.close();
|
||||
|
||||
StudentAndParent snp = new StudentAndParent(cookies, account.getSymbol());
|
||||
SubjectsList subjectsList = new SubjectsList(snp);
|
||||
|
||||
SubjectsDatabase subjectsDatabase = new SubjectsDatabase(mContext);
|
||||
subjectsDatabase.open();
|
||||
subjectsDatabase.put(subjectsList.getAll());
|
||||
subjectsDatabase.close();
|
||||
|
||||
|
||||
GradesList gradesList = new GradesList(snp);
|
||||
GradesDatabase gradesDatabase = new GradesDatabase(mContext);
|
||||
gradesDatabase.open();
|
||||
gradesDatabase.put(gradesList.getAll());
|
||||
|
||||
for (Subject subject : subjectsDatabase.getAllSubjectsNames()) {
|
||||
List<GradeItem> gradeItems = gradesDatabase.getSubjectGrades(userId, SubjectsDatabase.getSubjectId(subject.getName()));
|
||||
List<GradeItem> gradeItems = gradesDatabase.getSubjectGrades(context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0),
|
||||
SubjectsDatabase.getSubjectId(subject.getName()));
|
||||
if (gradeItems.size() > 0) {
|
||||
subjectWithGradesList.add(new SubjectWithGrades(subject.getName(), gradeItems));
|
||||
}
|
||||
@ -118,11 +75,6 @@ public class GradesFragment extends Fragment {
|
||||
|
||||
gradesDatabase.close();
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,137 +1,86 @@
|
||||
package io.github.wulkanowy.activity.main;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.SQLException;
|
||||
import android.os.AsyncTask;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.activity.dashboard.DashboardActivity;
|
||||
import io.github.wulkanowy.api.Cookies;
|
||||
import io.github.wulkanowy.api.StudentAndParent;
|
||||
import io.github.wulkanowy.api.login.AccountPermissionException;
|
||||
import io.github.wulkanowy.api.login.BadCredentialsException;
|
||||
import io.github.wulkanowy.api.login.Login;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.api.user.BasicInformation;
|
||||
import io.github.wulkanowy.api.user.PersonalData;
|
||||
import io.github.wulkanowy.database.accounts.Account;
|
||||
import io.github.wulkanowy.database.accounts.AccountsDatabase;
|
||||
import io.github.wulkanowy.database.cookies.CookiesDatabase;
|
||||
import io.github.wulkanowy.security.CryptoException;
|
||||
import io.github.wulkanowy.security.Safety;
|
||||
import io.github.wulkanowy.services.jobs.GradesSync;
|
||||
import io.github.wulkanowy.services.synchronisation.DataSynchronisation;
|
||||
import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation;
|
||||
import io.github.wulkanowy.utilities.ConnectionUtilities;
|
||||
|
||||
public class LoginTask extends AsyncTask<String, Integer, Integer> {
|
||||
|
||||
private Activity activity;
|
||||
|
||||
private boolean save;
|
||||
private Context context;
|
||||
|
||||
private ProgressDialog progress;
|
||||
|
||||
public LoginTask(Activity activity, boolean save) {
|
||||
this.activity = activity;
|
||||
this.save = save;
|
||||
|
||||
this.progress = new ProgressDialog(activity);
|
||||
public LoginTask(Context context) {
|
||||
this.context = context;
|
||||
this.progress = new ProgressDialog(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
|
||||
progress.setTitle(activity.getText(R.string.login_text));
|
||||
progress.setMessage(activity.getText(R.string.please_wait_text));
|
||||
progress.setTitle(context.getText(R.string.login_text));
|
||||
progress.setMessage(context.getText(R.string.please_wait_text));
|
||||
progress.setCancelable(false);
|
||||
progress.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(String... credentials) {
|
||||
Cookies cookies = new Cookies();
|
||||
Login login = new Login(cookies);
|
||||
|
||||
if (ConnectionUtilities.isOnline(context)) {
|
||||
VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation();
|
||||
try {
|
||||
login.login(credentials[0], credentials[1], credentials[2]);
|
||||
vulcanSynchronisation.loginNewUser(credentials[0], credentials[1], credentials[2], context);
|
||||
} catch (BadCredentialsException e) {
|
||||
return R.string.login_bad_credentials_text;
|
||||
} catch (AccountPermissionException e) {
|
||||
return R.string.login_bad_account_permission_text;
|
||||
} catch (LoginErrorException e) {
|
||||
return R.string.login_denied_text;
|
||||
}
|
||||
try {
|
||||
Gson gson = new GsonBuilder().enableComplexMapKeySerialization()
|
||||
.setPrettyPrinting().create();
|
||||
CookiesDatabase cookiesDatabase = new CookiesDatabase(activity);
|
||||
cookiesDatabase.open();
|
||||
cookiesDatabase.put(gson.toJson(login.getCookies()));
|
||||
cookiesDatabase.close();
|
||||
} catch (SQLException e) {
|
||||
return R.string.login_cookies_save_failed_text;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
try {
|
||||
StudentAndParent snp = new StudentAndParent(login.getCookiesObject(),
|
||||
credentials[2]);
|
||||
BasicInformation userInfo = new BasicInformation(snp);
|
||||
PersonalData personalData = userInfo.getPersonalData();
|
||||
String firstAndLastName = personalData.getFirstAndLastName();
|
||||
|
||||
Safety safety = new Safety(activity);
|
||||
|
||||
Account account = new Account()
|
||||
.setName(firstAndLastName)
|
||||
.setEmail(credentials[0])
|
||||
.setPassword(safety.encrypt(credentials[0], credentials[1]))
|
||||
.setSymbol(credentials[2]);
|
||||
|
||||
AccountsDatabase accountsDatabase = new AccountsDatabase(activity);
|
||||
|
||||
accountsDatabase.open();
|
||||
long idUser = accountsDatabase.put(account);
|
||||
accountsDatabase.close();
|
||||
|
||||
SharedPreferences sharedPreferences = activity.getSharedPreferences("LoginData", activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putLong("isLogin", idUser);
|
||||
editor.apply();
|
||||
|
||||
} catch (SQLException e) {
|
||||
return R.string.SQLite_ioError_text;
|
||||
} catch (IOException | LoginErrorException e) {
|
||||
return R.string.login_denied_text;
|
||||
} catch (CryptoException e) {
|
||||
return R.string.encrypt_failed_text;
|
||||
} catch (UnsupportedOperationException e) {
|
||||
return R.string.root_failed_text;
|
||||
} catch (LoginErrorException | IOException e) {
|
||||
return R.string.login_denied_text;
|
||||
}
|
||||
}
|
||||
//Map<String, String> cookiesList = login.getJar();
|
||||
|
||||
DataSynchronisation dataSynchronisation = new DataSynchronisation(context);
|
||||
dataSynchronisation.syncGradesAndSubjects(vulcanSynchronisation);
|
||||
|
||||
return R.string.login_accepted_text;
|
||||
|
||||
} else {
|
||||
return R.string.noInternet_text;
|
||||
}
|
||||
}
|
||||
|
||||
protected void onPostExecute(Integer messageID) {
|
||||
super.onPostExecute(messageID);
|
||||
|
||||
GradesSync gradesSync = new GradesSync();
|
||||
gradesSync.scheduledJob(context);
|
||||
|
||||
progress.dismiss();
|
||||
|
||||
Toast.makeText(activity, activity.getString(messageID), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(context, context.getString(messageID), Toast.LENGTH_LONG).show();
|
||||
|
||||
if (messageID == R.string.login_accepted_text || messageID == R.string.root_failed_text
|
||||
|| messageID == R.string.encrypt_failed_text) {
|
||||
Intent intent = new Intent(activity, DashboardActivity.class);
|
||||
activity.startActivity(intent);
|
||||
Intent intent = new Intent(context, DashboardActivity.class);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import io.github.wulkanowy.R;
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private float mTouchPosition;
|
||||
|
||||
private float mReleasePosition;
|
||||
|
||||
@Override
|
||||
@ -71,7 +72,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
if (!email.isEmpty() && !password.isEmpty() && !symbol.isEmpty()) {
|
||||
new LoginTask(this, true).execute(email, password, symbol);
|
||||
new LoginTask(this).execute(email, password, symbol);
|
||||
} else {
|
||||
Toast.makeText(this, R.string.data_text, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
@ -1,36 +1,26 @@
|
||||
package io.github.wulkanowy.activity.started;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.SQLException;
|
||||
import android.os.AsyncTask;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
import io.github.wulkanowy.R;
|
||||
import io.github.wulkanowy.activity.main.LoginTask;
|
||||
import io.github.wulkanowy.activity.dashboard.DashboardActivity;
|
||||
import io.github.wulkanowy.activity.main.MainActivity;
|
||||
import io.github.wulkanowy.database.accounts.Account;
|
||||
import io.github.wulkanowy.database.accounts.AccountsDatabase;
|
||||
import io.github.wulkanowy.security.CryptoException;
|
||||
import io.github.wulkanowy.security.Safety;
|
||||
import io.github.wulkanowy.services.jobs.GradesSync;
|
||||
import io.github.wulkanowy.utilities.ConnectionUtilities;
|
||||
|
||||
public class LoadingTask extends AsyncTask<Void, Void, Void> {
|
||||
public class LoadingTask extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
private final boolean SAVE_DATA = true;
|
||||
private Activity activity;
|
||||
private boolean isOnline;
|
||||
private Context context;
|
||||
|
||||
LoadingTask(Activity main) {
|
||||
activity = main;
|
||||
LoadingTask(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
@ -38,74 +28,27 @@ public class LoadingTask extends AsyncTask<Void, Void, Void> {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
isOnline = isOnline();
|
||||
|
||||
return null;
|
||||
return ConnectionUtilities.isOnline(context);
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void result) {
|
||||
protected void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
|
||||
if (isOnline) {
|
||||
signIn();
|
||||
if (!result) {
|
||||
Toast.makeText(context, R.string.noInternet_text, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
if (context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0) == 0) {
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
context.startActivity(intent);
|
||||
} else {
|
||||
Intent intent = new Intent(activity, MainActivity.class);
|
||||
activity.startActivity(intent);
|
||||
GradesSync gradesSync = new GradesSync();
|
||||
gradesSync.scheduledJob(context);
|
||||
|
||||
Toast.makeText(activity, R.string.noInternet_text, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Intent intent = new Intent(context, DashboardActivity.class);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
private boolean isOnline() {
|
||||
try {
|
||||
int timeoutMs = 1500;
|
||||
Socket sock = new Socket();
|
||||
SocketAddress address = new InetSocketAddress("8.8.8.8", 53);
|
||||
|
||||
sock.connect(address, timeoutMs);
|
||||
sock.close();
|
||||
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean signIn() {
|
||||
|
||||
if (SAVE_DATA) {
|
||||
AccountsDatabase accountsDatabase = new AccountsDatabase(activity);
|
||||
accountsDatabase.open();
|
||||
|
||||
if (accountsDatabase.checkExist("accounts")) {
|
||||
try {
|
||||
Account account = accountsDatabase.getAccount(activity.getSharedPreferences("LoginData", activity.MODE_PRIVATE).getLong("isLogin", 0));
|
||||
accountsDatabase.close();
|
||||
|
||||
if (account != null) {
|
||||
|
||||
Safety safety = new Safety(activity);
|
||||
|
||||
new LoginTask(activity, false).execute(
|
||||
account.getEmail(),
|
||||
safety.decrypt(account.getEmail(), account.getPassword()),
|
||||
account.getSymbol()
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Toast.makeText(activity, R.string.SQLite_ioError_text,
|
||||
Toast.LENGTH_LONG).show();
|
||||
} catch (CryptoException e) {
|
||||
Toast.makeText(activity, R.string.decrypt_failed_text, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
accountsDatabase.close();
|
||||
}
|
||||
|
||||
Intent intent = new Intent(activity, MainActivity.class);
|
||||
activity.startActivity(intent);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ public class DatabaseAdapter {
|
||||
|
||||
private final String DATABASE_NAME = "accountdatabase.db";
|
||||
|
||||
private final int DATABASE_VERSION = 5;
|
||||
private final int DATABASE_VERSION = 6;
|
||||
|
||||
public static SQLiteDatabase database;
|
||||
|
||||
@ -44,7 +44,7 @@ public class DatabaseAdapter {
|
||||
Log.d(DatabaseHelper.DEBUG_TAG, "Close database");
|
||||
}
|
||||
|
||||
public boolean checkExist(String tableName, String dbfield, String fieldValue) {
|
||||
protected boolean checkExist(String tableName, String dbfield, String fieldValue) {
|
||||
|
||||
Cursor cursor;
|
||||
|
||||
@ -73,17 +73,16 @@ public class DatabaseAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkExist(String tableName) {
|
||||
protected boolean checkExist(String tableName) {
|
||||
return checkExist(tableName, null, null);
|
||||
}
|
||||
|
||||
public void deleteAndCreate(String tableName) {
|
||||
protected void deleteAndCreate(String tableName) {
|
||||
|
||||
database.execSQL(databaseHelper.DROP_TABLE + tableName);
|
||||
database.execSQL(databaseHelper.SUBJECT_TABLE);
|
||||
database.execSQL(databaseHelper.ACCOUNT_TABLE);
|
||||
database.execSQL(databaseHelper.GRADE_TABLE);
|
||||
database.execSQL(databaseHelper.COOKIES_TABLE);
|
||||
|
||||
Log.d(DatabaseHelper.DEBUG_TAG, "Recreate table " + tableName);
|
||||
|
||||
|
@ -40,10 +40,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
"semester INTEGER, " +
|
||||
"isNew INTEGER );";
|
||||
|
||||
public final String COOKIES_TABLE = "CREATE TABLE IF NOT EXISTS cookies( " +
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
"cookies TEXT );";
|
||||
|
||||
public final String DROP_TABLE = "DROP TABLE IF EXISTS ";
|
||||
|
||||
public DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
|
||||
@ -55,7 +51,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
db.execSQL(ACCOUNT_TABLE);
|
||||
db.execSQL(SUBJECT_TABLE);
|
||||
db.execSQL(GRADE_TABLE);
|
||||
db.execSQL(COOKIES_TABLE);
|
||||
Log.d(DEBUG_TAG, "Create database");
|
||||
}
|
||||
|
||||
@ -64,7 +59,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
db.execSQL(DROP_TABLE + "accounts");
|
||||
db.execSQL(DROP_TABLE + "subjects");
|
||||
db.execSQL(DROP_TABLE + "grades");
|
||||
db.execSQL(DROP_TABLE + "cookies");
|
||||
onCreate(db);
|
||||
Log.d(DEBUG_TAG, "Database upgrade from ver." + oldVersion + " to ver." + newVersion);
|
||||
}
|
||||
|
@ -13,10 +13,15 @@ import io.github.wulkanowy.database.DatabaseHelper;
|
||||
public class AccountsDatabase extends DatabaseAdapter {
|
||||
|
||||
private String name = "name";
|
||||
|
||||
private String email = "email";
|
||||
|
||||
private String password = "password";
|
||||
|
||||
private String symbol = "symbol";
|
||||
|
||||
private String idText = "id";
|
||||
|
||||
private String accounts = "accounts";
|
||||
|
||||
public AccountsDatabase(Context context) {
|
||||
|
@ -1,58 +0,0 @@
|
||||
package io.github.wulkanowy.database.cookies;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.util.Log;
|
||||
|
||||
import io.github.wulkanowy.database.DatabaseAdapter;
|
||||
import io.github.wulkanowy.database.DatabaseHelper;
|
||||
|
||||
public class CookiesDatabase extends DatabaseAdapter {
|
||||
|
||||
private String cookies = "cookies";
|
||||
|
||||
public CookiesDatabase(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public long put(String serializableCookiesMap) {
|
||||
|
||||
ContentValues newCookie = new ContentValues();
|
||||
newCookie.put(cookies, serializableCookiesMap);
|
||||
|
||||
if (!database.isReadOnly()) {
|
||||
if (!checkExist(cookies)) {
|
||||
long newId = database.insertOrThrow(cookies, null, newCookie);
|
||||
Log.d(DatabaseHelper.DEBUG_TAG, "Put cookies into database");
|
||||
return newId;
|
||||
} else {
|
||||
deleteAndCreate(cookies);
|
||||
long newId = database.insertOrThrow(cookies, null, newCookie);
|
||||
Log.d(DatabaseHelper.DEBUG_TAG, "Put cookies into database");
|
||||
return newId;
|
||||
}
|
||||
} else {
|
||||
Log.e(DatabaseHelper.DEBUG_TAG, "Attempt to write on read-only database");
|
||||
throw new SQLException("Attempt to write on read-only database");
|
||||
}
|
||||
}
|
||||
|
||||
public String getCookies() {
|
||||
|
||||
String exec = "SELECT " + cookies + " FROM " + cookies;
|
||||
|
||||
Cursor cursor = database.rawQuery(exec, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
|
||||
String cookie = cursor.getString(0);
|
||||
|
||||
cursor.close();
|
||||
|
||||
Log.d(DatabaseHelper.DEBUG_TAG, "Extract cookies from database");
|
||||
|
||||
return cookie;
|
||||
}
|
||||
}
|
@ -18,11 +18,17 @@ import io.github.wulkanowy.database.DatabaseHelper;
|
||||
public class SubjectsDatabase extends DatabaseAdapter {
|
||||
|
||||
private static String idText = "id";
|
||||
|
||||
private static String name = "name";
|
||||
|
||||
private static String predictedRating1 = "predictedRating1";
|
||||
|
||||
private static String finalRating1 = "finalRating1";
|
||||
|
||||
private static String predictedRating2 = "predictedRating2";
|
||||
|
||||
private static String finalRating2 = "finalRating2";
|
||||
|
||||
private static String subjects = "subjects";
|
||||
|
||||
public SubjectsDatabase(Context context) {
|
||||
|
@ -31,8 +31,11 @@ import javax.security.auth.x500.X500Principal;
|
||||
public class Scrambler {
|
||||
|
||||
private KeyStore keyStore;
|
||||
|
||||
private static final String ANDROID_KEYSTORE = "AndroidKeyStore";
|
||||
|
||||
public final static String DEBUG_TAG = "KeyStoreSecurity";
|
||||
|
||||
public Context context;
|
||||
|
||||
public Scrambler(Context context) {
|
||||
|
@ -0,0 +1,53 @@
|
||||
package io.github.wulkanowy.services.jobs;
|
||||
|
||||
import com.firebase.jobdispatcher.Constraint;
|
||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
|
||||
import com.firebase.jobdispatcher.Job;
|
||||
import com.firebase.jobdispatcher.Lifetime;
|
||||
import com.firebase.jobdispatcher.RetryStrategy;
|
||||
import com.firebase.jobdispatcher.Trigger;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.github.wulkanowy.api.login.AccountPermissionException;
|
||||
import io.github.wulkanowy.api.login.BadCredentialsException;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.security.CryptoException;
|
||||
import io.github.wulkanowy.services.synchronisation.DataSynchronisation;
|
||||
import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation;
|
||||
|
||||
public class GradesSync extends VulcanSync {
|
||||
|
||||
public static final String UNIQUE_TAG = "GradesSync34512";
|
||||
|
||||
public static final int DEFAULT_INTERVAL_START = 60 * 50;
|
||||
|
||||
public static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + (60 * 10);
|
||||
|
||||
@Override
|
||||
protected Job createJob(FirebaseJobDispatcher dispatcher) {
|
||||
return dispatcher.newJobBuilder()
|
||||
.setLifetime(Lifetime.FOREVER)
|
||||
.setService(GradeJob.class)
|
||||
.setTag(UNIQUE_TAG)
|
||||
.setRecurring(true)
|
||||
.setTrigger(Trigger.executionWindow(DEFAULT_INTERVAL_START, DEFAULT_INTERVAL_END))
|
||||
.setConstraints(Constraint.ON_ANY_NETWORK)
|
||||
.setReplaceCurrent(true)
|
||||
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static class GradeJob extends VulcanJob {
|
||||
|
||||
@Override
|
||||
public void workToBePerformed() throws CryptoException, BadCredentialsException,
|
||||
LoginErrorException, AccountPermissionException, IOException {
|
||||
|
||||
VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation();
|
||||
DataSynchronisation dataSynchronisation = new DataSynchronisation(getApplicationContext());
|
||||
vulcanSynchronisation.loginCurrentUser(getApplicationContext());
|
||||
dataSynchronisation.syncGrades(vulcanSynchronisation);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package io.github.wulkanowy.services.jobs;
|
||||
|
||||
import com.firebase.jobdispatcher.Constraint;
|
||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
|
||||
import com.firebase.jobdispatcher.Job;
|
||||
import com.firebase.jobdispatcher.Lifetime;
|
||||
import com.firebase.jobdispatcher.RetryStrategy;
|
||||
import com.firebase.jobdispatcher.Trigger;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.github.wulkanowy.api.login.AccountPermissionException;
|
||||
import io.github.wulkanowy.api.login.BadCredentialsException;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.security.CryptoException;
|
||||
import io.github.wulkanowy.services.synchronisation.DataSynchronisation;
|
||||
import io.github.wulkanowy.services.synchronisation.VulcanSynchronisation;
|
||||
|
||||
public class SubjectsSync extends VulcanSync {
|
||||
|
||||
public static final String UNIQUE_TAG = "SubjectsSync34512";
|
||||
|
||||
public static final int DEFAULT_INTERVAL_START = 0;
|
||||
|
||||
public static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + 10;
|
||||
|
||||
@Override
|
||||
protected Job createJob(FirebaseJobDispatcher dispatcher) {
|
||||
return dispatcher.newJobBuilder()
|
||||
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
|
||||
.setService(SubjectJob.class)
|
||||
.setTag(UNIQUE_TAG)
|
||||
.setRecurring(false)
|
||||
.setTrigger(Trigger.executionWindow(DEFAULT_INTERVAL_START, DEFAULT_INTERVAL_END))
|
||||
.setConstraints(Constraint.ON_ANY_NETWORK)
|
||||
.setReplaceCurrent(true)
|
||||
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
|
||||
.build();
|
||||
}
|
||||
|
||||
private class SubjectJob extends VulcanJob {
|
||||
|
||||
@Override
|
||||
public void workToBePerformed() throws CryptoException, BadCredentialsException,
|
||||
LoginErrorException, AccountPermissionException, IOException {
|
||||
|
||||
VulcanSynchronisation vulcanSynchronisation = new VulcanSynchronisation();
|
||||
DataSynchronisation dataSynchronisation = new DataSynchronisation(getApplicationContext());
|
||||
vulcanSynchronisation.loginCurrentUser(getApplicationContext());
|
||||
dataSynchronisation.syncSubjects(vulcanSynchronisation);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package io.github.wulkanowy.services.jobs;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.firebase.jobdispatcher.JobParameters;
|
||||
import com.firebase.jobdispatcher.JobService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.github.wulkanowy.api.login.AccountPermissionException;
|
||||
import io.github.wulkanowy.api.login.BadCredentialsException;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.security.CryptoException;
|
||||
|
||||
public abstract class VulcanJob extends JobService {
|
||||
|
||||
private SyncTask syncTask = new SyncTask();
|
||||
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
Log.d(VulcanSync.DEBUG_TAG, "Start job");
|
||||
syncTask.execute(params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
Log.d(VulcanSync.DEBUG_TAG, "Stop job");
|
||||
syncTask.cancel(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void workToBePerformed() throws CryptoException, BadCredentialsException,
|
||||
LoginErrorException, AccountPermissionException, IOException;
|
||||
|
||||
private class SyncTask extends AsyncTask<JobParameters, Void, Void> {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(JobParameters... params) {
|
||||
try {
|
||||
workToBePerformed();
|
||||
} catch (Exception e) {
|
||||
Log.e(VulcanSync.DEBUG_TAG, "User logging in the background failed", e);
|
||||
} finally {
|
||||
jobFinished(params[0], false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.github.wulkanowy.services.jobs;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
|
||||
import com.firebase.jobdispatcher.GooglePlayDriver;
|
||||
import com.firebase.jobdispatcher.Job;
|
||||
|
||||
public abstract class VulcanSync {
|
||||
|
||||
public static final String DEBUG_TAG = "SynchronizationService";
|
||||
|
||||
public void scheduledJob(Context context) {
|
||||
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
|
||||
dispatcher.mustSchedule(createJob(dispatcher));
|
||||
}
|
||||
|
||||
protected abstract Job createJob(FirebaseJobDispatcher dispatcher);
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package io.github.wulkanowy.services.synchronisation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import io.github.wulkanowy.services.jobs.VulcanSync;
|
||||
|
||||
public class DataSynchronisation {
|
||||
|
||||
private Context context;
|
||||
|
||||
public DataSynchronisation(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void syncGrades(VulcanSynchronisation vulcanSynchronisation) {
|
||||
GradesSynchronisation gradesSynchronisation = new GradesSynchronisation();
|
||||
|
||||
try {
|
||||
gradesSynchronisation.sync(vulcanSynchronisation, context);
|
||||
} catch (Exception e) {
|
||||
Log.e(VulcanSync.DEBUG_TAG, "Synchronisation of grades failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void syncSubjects(VulcanSynchronisation vulcanSynchronisation) {
|
||||
SubjectsSynchronisation subjectsSynchronisation = new SubjectsSynchronisation();
|
||||
|
||||
try {
|
||||
subjectsSynchronisation.sync(vulcanSynchronisation, context);
|
||||
} catch (Exception e) {
|
||||
Log.e(VulcanSync.DEBUG_TAG, "Synchronisation of subjects failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void syncGradesAndSubjects(VulcanSynchronisation vulcanSynchronisation) {
|
||||
syncSubjects(vulcanSynchronisation);
|
||||
syncGrades(vulcanSynchronisation);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.github.wulkanowy.services.synchronisation;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import io.github.wulkanowy.api.grades.GradesList;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.database.grades.GradesDatabase;
|
||||
|
||||
public class GradesSynchronisation {
|
||||
|
||||
public void sync(VulcanSynchronisation vulcanSynchronisation, Context context) throws IOException, ParseException, LoginErrorException {
|
||||
|
||||
GradesList gradesList = new GradesList(vulcanSynchronisation.getStudentAndParent());
|
||||
|
||||
GradesDatabase gradesDatabase = new GradesDatabase(context);
|
||||
gradesDatabase.open();
|
||||
gradesDatabase.put(gradesList.getAll());
|
||||
gradesDatabase.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.github.wulkanowy.services.synchronisation;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import io.github.wulkanowy.api.grades.SubjectsList;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.database.subjects.SubjectsDatabase;
|
||||
|
||||
public class SubjectsSynchronisation {
|
||||
|
||||
public void sync(VulcanSynchronisation vulcanSynchronisation, Context context) throws IOException, ParseException, LoginErrorException {
|
||||
|
||||
SubjectsList subjectsList = new SubjectsList(vulcanSynchronisation.getStudentAndParent());
|
||||
|
||||
SubjectsDatabase subjectsDatabase = new SubjectsDatabase(context);
|
||||
subjectsDatabase.open();
|
||||
subjectsDatabase.put(subjectsList.getAll());
|
||||
subjectsDatabase.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package io.github.wulkanowy.services.synchronisation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import io.github.wulkanowy.api.Cookies;
|
||||
import io.github.wulkanowy.api.StudentAndParent;
|
||||
import io.github.wulkanowy.api.login.AccountPermissionException;
|
||||
import io.github.wulkanowy.api.login.BadCredentialsException;
|
||||
import io.github.wulkanowy.api.login.Login;
|
||||
import io.github.wulkanowy.api.login.LoginErrorException;
|
||||
import io.github.wulkanowy.api.user.BasicInformation;
|
||||
import io.github.wulkanowy.api.user.PersonalData;
|
||||
import io.github.wulkanowy.database.accounts.Account;
|
||||
import io.github.wulkanowy.database.accounts.AccountsDatabase;
|
||||
import io.github.wulkanowy.security.CryptoException;
|
||||
import io.github.wulkanowy.security.Safety;
|
||||
import io.github.wulkanowy.services.jobs.VulcanSync;
|
||||
|
||||
public class VulcanSynchronisation {
|
||||
|
||||
private StudentAndParent studentAndParent;
|
||||
|
||||
public void loginCurrentUser(Context context) throws CryptoException, BadCredentialsException, LoginErrorException, AccountPermissionException, IOException {
|
||||
|
||||
long userId = context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("isLogin", 0);
|
||||
|
||||
if (userId != 0) {
|
||||
AccountsDatabase accountsDatabase = new AccountsDatabase(context);
|
||||
accountsDatabase.open();
|
||||
Account account = accountsDatabase.getAccount(userId);
|
||||
accountsDatabase.close();
|
||||
Safety safety = new Safety(context);
|
||||
|
||||
Login login = loginUser(
|
||||
account.getEmail(),
|
||||
safety.decrypt(account.getEmail(), account.getPassword()),
|
||||
account.getSymbol());
|
||||
|
||||
getAndSetStudentAndParentFromApi(account.getSymbol(), login.getCookies());
|
||||
} else {
|
||||
Log.wtf(VulcanSync.DEBUG_TAG, "loginCurrentUser - USERID IS EMPTY");
|
||||
}
|
||||
}
|
||||
|
||||
public void loginNewUser(String email, String password, String symbol, Context context) throws BadCredentialsException, LoginErrorException, AccountPermissionException, IOException, CryptoException {
|
||||
|
||||
Login login = loginUser(email, password, symbol);
|
||||
|
||||
Safety safety = new Safety(context);
|
||||
AccountsDatabase accountsDatabase = new AccountsDatabase(context);
|
||||
BasicInformation basicInformation = new BasicInformation(getAndSetStudentAndParentFromApi(symbol, login.getCookies()));
|
||||
PersonalData personalData = basicInformation.getPersonalData();
|
||||
|
||||
Account account = new Account()
|
||||
.setName(personalData.getFirstAndLastName())
|
||||
.setEmail(email)
|
||||
.setPassword(safety.encrypt(email, password))
|
||||
.setSymbol(symbol);
|
||||
|
||||
accountsDatabase.open();
|
||||
long idNewUser = accountsDatabase.put(account);
|
||||
accountsDatabase.close();
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("LoginData", Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putLong("isLogin", idNewUser);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public StudentAndParent getStudentAndParent() {
|
||||
return studentAndParent;
|
||||
}
|
||||
|
||||
private void setStudentAndParent(StudentAndParent studentAndParent) {
|
||||
this.studentAndParent = studentAndParent;
|
||||
}
|
||||
|
||||
private Login loginUser(String email, String password, String symbol) throws BadCredentialsException, LoginErrorException, AccountPermissionException {
|
||||
|
||||
Cookies cookies = new Cookies();
|
||||
Login login = new Login(cookies);
|
||||
login.login(email, password, symbol);
|
||||
return login;
|
||||
|
||||
}
|
||||
|
||||
private StudentAndParent getAndSetStudentAndParentFromApi(String symbol, Map<String, String> cookiesMap) throws IOException, LoginErrorException {
|
||||
|
||||
if (studentAndParent == null) {
|
||||
Cookies cookies = new Cookies();
|
||||
cookies.setItems(cookiesMap);
|
||||
|
||||
StudentAndParent snp = new StudentAndParent(cookies, symbol);
|
||||
|
||||
setStudentAndParent(snp);
|
||||
return snp;
|
||||
} else {
|
||||
return studentAndParent;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.github.wulkanowy.utilities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
public abstract class ConnectionUtilities {
|
||||
|
||||
public static boolean isOnline(Context context) {
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
return networkInfo != null && networkInfo.isConnectedOrConnecting();
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import java.util.TimeZone;
|
||||
abstract public class DateHelper {
|
||||
|
||||
private static final long TICKS_AT_EPOCH = 621355968000000000L;
|
||||
|
||||
private static final long TICKS_PER_MILLISECOND = 10000;
|
||||
|
||||
public static long getTicks(Date date) {
|
||||
|
@ -5,7 +5,7 @@ import android.os.Build;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class RootUtilities {
|
||||
abstract public class RootUtilities {
|
||||
|
||||
public static boolean isRooted() {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user