1
0

Compare commits

..

8 Commits
0.4.3 ... 0.4.4

24 changed files with 162 additions and 45 deletions

View File

@ -118,7 +118,7 @@ public class Client {
this.cookies.addItems(response.cookies());
Document doc = checkForErrors(response.parse());
Document doc = checkForErrors(response.parse(), response.statusCode());
if (loginBefore) {
lastSuccessRequest = new Date();
@ -144,7 +144,7 @@ public class Client {
response.bufferUp(); // fixes cert parsing issues #109
return checkForErrors(response.parse());
return checkForErrors(response.parse(), response.statusCode());
}
public String getJsonStringByUrl(String url) throws IOException, VulcanException {
@ -182,7 +182,7 @@ public class Client {
return response.body();
}
Document checkForErrors(Document doc) throws VulcanException {
Document checkForErrors(Document doc, int code) throws VulcanException {
lastSuccessRequest = null;
String title = doc.select("title").text();
@ -195,8 +195,8 @@ public class Client {
throw new NotLoggedInErrorException(singIn);
}
if (title.startsWith("Błąd")) {
throw new NotLoggedInErrorException(title + " " + doc.selectFirst("p, body"));
if ("Błąd strony".equals(title)) {
throw new NotLoggedInErrorException(title + " " + doc.selectFirst("p, body") + ", status: " + code);
}
return doc;

View File

@ -65,12 +65,12 @@ public class StudentAndParent implements SnP {
return getBaseUrl();
}
// get url to uonetplus-opiekun.vulcan.net.pl
// get url to uonetplus-opiekun.fakelog.cf
Document startPage = client.getPageByUrl(START_PAGE_URL);
Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first();
if (null == studentTileLink) {
throw new NotLoggedInErrorException("You are probably not logged in. Force login");
throw new VulcanException("Na pewno używasz konta z dostępem do Witryny ucznia i rodzica?");
}
String snpPageUrl = studentTileLink.attr("href");
@ -84,7 +84,7 @@ public class StudentAndParent implements SnP {
String[] path = snpPageUrl.split(client.getHost())[1].split("/");
if (5 != path.length) {
throw new NotLoggedInErrorException("You are probably not logged in");
throw new NotLoggedInErrorException("You are probably not logged in " + snpPageUrl);
}
return path[2];

View File

@ -9,6 +9,7 @@ import org.jsoup.select.Elements;
import java.io.IOException;
import io.github.wulkanowy.api.Client;
import io.github.wulkanowy.api.NotLoggedInErrorException;
import io.github.wulkanowy.api.VulcanException;
public class Login {
@ -27,6 +28,10 @@ public class Login {
public String login(String email, String password, String symbol) throws VulcanException, IOException {
Document certDoc = sendCredentials(email, password);
if ("Błąd".equals(certDoc.title())) {
throw new NotLoggedInErrorException(certDoc.selectFirst("body").text());
}
return sendCertificate(certDoc, symbol);
}

View File

@ -98,8 +98,10 @@ public class Timetable {
addLessonInfoFromElement(lesson, e.first());
break;
case 2:
Element span = e.last().select("span").first();
if (span.hasClass(LessonTypes.CLASS_MOVED_OR_CANCELED)) {
Element span = e.last().selectFirst("span");
if (null == span) {
addLessonInfoFromElement(lesson, e.first());
} else if (span.hasClass(LessonTypes.CLASS_MOVED_OR_CANCELED)) {
lesson.setNewMovedInOrChanged(true);
lesson.setDescription("poprzednio: " + getLessonAndGroupInfoFromSpan(span)[0]);
addLessonInfoFromElement(lesson, e.first());
@ -120,7 +122,9 @@ public class Timetable {
Elements warn = e.select(".uwaga-panel");
if (!warn.isEmpty()) {
e.select(".x-treelabel-rlz").last().text("(" + warn.text() + ")");
e.select("span").last()
.addClass("x-treelabel-rlz")
.text(warn.text());
e.remove(1);
}
}

View File

@ -25,7 +25,7 @@ public class ClientTest {
Document doc = Jsoup.parse(getFixtureAsString("login/Logowanie-success.html"));
Assert.assertEquals(doc, client.checkForErrors(doc));
Assert.assertEquals(doc, client.checkForErrors(doc, 200));
}
@Test(expected = VulcanOfflineException.class)
@ -34,7 +34,7 @@ public class ClientTest {
Document doc = Jsoup.parse(getFixtureAsString("login/PrzerwaTechniczna.html"));
client.checkForErrors(doc);
client.checkForErrors(doc, 200);
}
@Test(expected = NotLoggedInErrorException.class)
@ -43,7 +43,7 @@ public class ClientTest {
Document doc = Jsoup.parse(getFixtureAsString("login/Logowanie-notLoggedIn.html"));
client.checkForErrors(doc);
client.checkForErrors(doc, 200);
}
@Test

View File

@ -53,7 +53,7 @@ public class StudentAndParentTest {
snp.getSnpHomePageUrl());
}
@Test(expected = NotLoggedInErrorException.class)
@Test(expected = VulcanException.class)
public void getSnpPageUrlWithWrongPage() throws Exception {
Document wrongPageDocument = Jsoup.parse(
FixtureHelper.getAsString(getClass().getResourceAsStream("OcenyWszystkie-semester.html"))

View File

@ -105,6 +105,7 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertEquals("Zajęcia techniczne", std.getWeekTable().getDay(2).getLesson(4).getSubject());
Assert.assertEquals("Wychowanie fizyczne", std.getWeekTable().getDay(1).getLesson(1).getSubject());
Assert.assertEquals("Język angielski", full.getWeekTable().getDay(0).getLesson(1).getSubject());
Assert.assertEquals("Wychowanie fizyczne", full.getWeekTable().getDay(0).getLesson(9).getSubject());
Assert.assertEquals("Wychowanie do życia w rodzinie", full.getWeekTable().getDay(2).getLesson(0).getSubject());
Assert.assertEquals("Wychowanie fizyczne", full.getWeekTable().getDay(3).getLesson(1).getSubject());
Assert.assertEquals("Uroczyste zakończenie roku szkolnego", full.getWeekTable().getDay(4).getLesson(0).getSubject());
@ -155,6 +156,7 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertEquals("poprzednio: Wychowanie fizyczne", full.getWeekTable().getDay(4).getLesson(2).getDescription());
Assert.assertEquals("egzamin", full.getWeekTable().getDay(3).getLesson(0).getDescription());
Assert.assertEquals("", full.getWeekTable().getDay(4).getLesson(1).getDescription());
Assert.assertEquals("opis w uwadze bez klasy w spanie", full.getWeekTable().getDay(4).getLesson(4).getDescription());
Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getDescription());
}

View File

@ -319,7 +319,16 @@
<span></span>
</div>
</td>
<td></td>
<td>
<div>
<span class="x-treelabel-ppl x-treelabel-inv">Język polski</span>
<span class="x-treelabel-ppl x-treelabel-inv"> </span>
<span class="x-treelabel-ppl x-treelabel-inv">16</span>
<span class="random-class">(oddział nieobecny)</span>
</div>
<button type="button" class="uwaga-btn">Uwaga</button>
<div class="uwaga-panel">opis w uwadze bez klasy w spanie</div>
</td>
</tr>
<tr>
<td>5</td>
@ -461,7 +470,18 @@
<tr>
<td>9</td>
<td>14:50 15:35</td>
<td></td>
<td>
<div>
<span class="x-treelabel-ppl x-treelabel-zas">Wychowanie fizyczne [zaw2]</span>
<span class="x-treelabel-ppl x-treelabel-zas"></span>
<span class="x-treelabel-ppl x-treelabel-zas"></span>
<span class="x-treelabel-ppl x-treelabel-zas">G3</span>
<span class="x-treelabel-rlz">(przeniesiona z lekcji 7, 01.12.2017)</span>
</div>
<div>
<!--<span>WTF</span>-->
</div>
</td>
<td>
<div>
<span class="x-treelabel-ppl x-treelabel-inv">Język niemiecki [J1]</span>

View File

@ -9,7 +9,7 @@ buildscript {
classpath "org.greenrobot:greendao-gradle-plugin:$greenDaoGradle"
classpath "io.fabric.tools:gradle:$fabricGradle"
classpath "com.google.gms:oss-licenses:0.9.2"
classpath 'com.github.triplet.gradle:play-publisher:1.2.0'
classpath "com.github.triplet.gradle:play-publisher:$playPublisher"
}
}
@ -41,8 +41,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15
targetSdkVersion 26
versionCode 11
versionName "0.4.3"
versionCode 12
versionName "0.4.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
playAccountConfig = playAccountConfigs.defaultAccountConfig

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy;
import android.app.Application;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.core.CrashlyticsCore;
import com.jakewharton.threetenabp.AndroidThreeTen;
@ -61,9 +62,12 @@ public class WulkanowyApp extends Application {
private void initializeFabric() {
Fabric.with(new Fabric.Builder(this)
.kits(new Crashlytics.Builder()
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build())
.kits(
new Crashlytics.Builder()
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build(),
new Answers()
)
.debuggable(BuildConfig.DEBUG)
.build());
}

View File

@ -4,6 +4,7 @@ import java.util.List;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.Subject;
import io.github.wulkanowy.data.db.dao.entities.Symbol;
import io.github.wulkanowy.data.db.dao.entities.Week;
public interface DbContract {
@ -20,6 +21,8 @@ public interface DbContract {
long getCurrentSymbolId();
Symbol getCurrentSymbol();
long getCurrentDiaryId();
long getSemesterId(int name);

View File

@ -12,6 +12,7 @@ import io.github.wulkanowy.data.db.dao.entities.Semester;
import io.github.wulkanowy.data.db.dao.entities.SemesterDao;
import io.github.wulkanowy.data.db.dao.entities.StudentDao;
import io.github.wulkanowy.data.db.dao.entities.Subject;
import io.github.wulkanowy.data.db.dao.entities.Symbol;
import io.github.wulkanowy.data.db.dao.entities.SymbolDao;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.data.db.dao.entities.WeekDao;
@ -57,10 +58,15 @@ public class DbRepository implements DbContract {
}
@Override
public long getCurrentSymbolId() {
public Symbol getCurrentSymbol() {
return daoSession.getSymbolDao().queryBuilder().where(
SymbolDao.Properties.UserId.eq(sharedPref.getCurrentUserId())
).unique().getId();
).unique();
}
@Override
public long getCurrentSymbolId() {
return getCurrentSymbol().getId();
}
@Override

View File

@ -2,6 +2,8 @@ package io.github.wulkanowy.data.sync;
import android.content.Context;
import org.greenrobot.greendao.database.Database;
import java.io.IOException;
import java.util.List;
@ -11,6 +13,7 @@ import javax.inject.Singleton;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.data.db.dao.entities.Account;
import io.github.wulkanowy.data.db.dao.entities.DaoMaster;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Diary;
import io.github.wulkanowy.data.db.dao.entities.DiaryDao;
@ -49,6 +52,8 @@ public class AccountSync {
public void registerUser(String email, String password, String symbol)
throws VulcanException, IOException, CryptoException {
clearUserData();
vulcan.setCredentials(email, password, symbol, null, null, null);
daoSession.getDatabase().beginTransaction();
@ -152,4 +157,11 @@ public class AccountSync {
diary.getValue()
);
}
private void clearUserData() {
Database database = daoSession.getDatabase();
DaoMaster.dropAllTables(database, true);
DaoMaster.createAllTables(database, true);
sharedPref.setCurrentUserId(0);
}
}

View File

@ -11,6 +11,7 @@ import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.utils.AppConstant;
import io.github.wulkanowy.utils.FabricUtils;
public class LoginPresenter extends BasePresenter<LoginContract.View>
implements LoginContract.Presenter {
@ -84,6 +85,7 @@ public class LoginPresenter extends BasePresenter<LoginContract.View>
@Override
public void onEndAsync(boolean success, Exception exception) {
if (success) {
FabricUtils.logRegister(true, getRepository().getDbRepo().getCurrentSymbol().getSymbol());
getView().openMainActivity();
return;
} else if (exception instanceof BadCredentialsException) {
@ -93,6 +95,7 @@ public class LoginPresenter extends BasePresenter<LoginContract.View>
getView().setErrorSymbolRequired();
getView().showSoftInput();
} else {
FabricUtils.logRegister(false, symbol);
getView().onError(getRepository().getResRepo().getErrorLoginMessage(exception));
}

View File

@ -10,6 +10,7 @@ import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
import io.github.wulkanowy.data.db.dao.entities.Day;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.utils.FabricUtils;
import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners;
@ -88,6 +89,8 @@ public class AttendanceTabPresenter extends BasePresenter<AttendanceTabContract.
getView().onError(getRepository().getResRepo().getErrorLoginMessage(exception));
}
getView().hideRefreshingBar();
FabricUtils.logRefresh("Attendance", result, date);
}
@Override

View File

@ -10,6 +10,7 @@ import io.github.wulkanowy.data.db.dao.entities.Day;
import io.github.wulkanowy.data.db.dao.entities.Exam;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.utils.FabricUtils;
import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners;
@ -93,6 +94,8 @@ public class ExamsTabPresenter extends BasePresenter<ExamsTabContract.View>
getView().onError(getRepository().getResRepo().getErrorLoginMessage(exception));
}
getView().hideRefreshingBar();
FabricUtils.logRefresh("Exams", result, date);
}
@Override

View File

@ -40,5 +40,7 @@ public interface GradesContract {
void onStart(View view, OnFragmentIsReadyListener listener);
void onSemesterChange(int which);
void onSemesterSwitchActive();
}
}

View File

@ -80,6 +80,7 @@ public class GradesFragment extends BaseFragment implements GradesContract.View
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_filter) {
presenter.onSemesterSwitchActive();
CharSequence[] items = new CharSequence[]{
getResources().getString(R.string.semester_text, 1),
getResources().getString(R.string.semester_text, 2),

View File

@ -1,5 +1,10 @@
package io.github.wulkanowy.ui.main.grades;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import org.threeten.bp.LocalDate;
import java.util.ArrayList;
import java.util.List;
@ -10,6 +15,7 @@ import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.Subject;
import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener;
import io.github.wulkanowy.utils.FabricUtils;
import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners;
@ -53,12 +59,19 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
}
}
@Override
public void onSemesterSwitchActive() {
cancelAsyncTasks();
}
@Override
public void onSemesterChange(int which) {
semesterName = which + 1;
getView().setCurrentSemester(which);
reloadGrades();
Answers.getInstance().logCustom(new CustomEvent("Semester change")
.putCustomAttribute("Name", semesterName));
}
private void reloadGrades() {
@ -100,8 +113,8 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
}
@Override
public void onEndRefreshAsync(boolean success, Exception exception) {
if (success) {
public void onEndRefreshAsync(boolean result, Exception exception) {
if (result) {
reloadGrades();
int numberOfNewGrades = getRepository().getDbRepo().getNewGrades(semesterName).size();
@ -115,6 +128,8 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
getView().onError(getRepository().getResRepo().getErrorLoginMessage(exception));
}
getView().hideRefreshingBar();
FabricUtils.logRefresh("Grades", result, LocalDate.now().toString());
}
@Override
@ -156,10 +171,7 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
listener.onFragmentIsReady();
}
@Override
public void onDestroy() {
isFirstSight = false;
private void cancelAsyncTasks() {
if (refreshTask != null) {
refreshTask.cancel(true);
refreshTask = null;
@ -168,6 +180,12 @@ public class GradesPresenter extends BasePresenter<GradesContract.View>
loadingTask.cancel(true);
loadingTask = null;
}
}
@Override
public void onDestroy() {
isFirstSight = false;
cancelAsyncTasks();
super.onDestroy();
}
}

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.main.timetable;
import java.util.ArrayList;
import java.util.List;
@ -11,6 +10,7 @@ import io.github.wulkanowy.data.db.dao.entities.Day;
import io.github.wulkanowy.data.db.dao.entities.TimetableLesson;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.utils.FabricUtils;
import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners;
@ -91,6 +91,8 @@ public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.Vi
getView().onError(getRepository().getResRepo().getErrorLoginMessage(exception));
}
getView().hideRefreshingBar();
FabricUtils.logRefresh("Timetable", result, date);
}
@Override

View File

@ -0,0 +1,27 @@
package io.github.wulkanowy.utils;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.crashlytics.android.answers.SignUpEvent;
public final class FabricUtils {
private FabricUtils() {
throw new IllegalStateException("Utility class");
}
public static void logRegister(boolean result, String symbol) {
Answers.getInstance().logSignUp(new SignUpEvent()
.putMethod("Login activity")
.putSuccess(result)
.putCustomAttribute("symbol", symbol));
}
public static void logRefresh(String name, boolean result, String date) {
Answers.getInstance().logCustom(
new CustomEvent(name + " refresh")
.putCustomAttribute("Success", result ? 1 : 0)
.putCustomAttribute("Date", date)
);
}
}

View File

@ -1,4 +1,5 @@
Wersja 0.4.3:
- naprawiono błąd z pokazywaniem usuniętych lekcji w planie
- naprawiono drobne błędy z wyrównaniem tekstu na starszych urządzeniach
- poprawiono synchronizację w tle spowodowaną błędem w komunikacji z serwerem
Wersja 0.4.4:
- naprawiono błędy w synchronizacji planu lekcji
- naprawiono błędy podczas pierwszego logowania
- naprawiono błąd podczas zmiany semestru
- kolejny raz poprawiono synchronizację w tle

View File

@ -61,13 +61,13 @@
android:id="@+id/login_activity_email_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:layout_marginBottom="12dp">
<EditText
android:id="@+id/login_activity_email_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1" />
@ -76,6 +76,7 @@
<android.support.design.widget.TextInputLayout
android:id="@+id/login_activity_pass_text_input"
android:layout_width="match_parent"
android:hint="@string/prompt_password"
android:layout_height="wrap_content">
<EditText
@ -83,7 +84,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:hint="@string/prompt_password"
android:imeActionLabel="@string/action_sign_in"
android:imeOptions="actionDone"
android:inputType="textPassword"
@ -95,16 +95,15 @@
android:id="@+id/login_activity_symbol_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_symbol"
android:visibility="gone">
<AutoCompleteTextView
android:id="@+id/login_activity_symbol_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_symbol"
android:imeActionLabel="@string/action_sign_in"
android:imeOptions="actionDone"
android:importantForAutofill="noExcludeDescendants"
android:inputType="textAutoComplete"
android:maxLines="1" />

View File

@ -47,7 +47,7 @@ ext {
dagger2 = "2.16"
ahbottom = "2.2.0"
jsoup = "1.11.3"
gson = "2.8.4"
gson = "2.8.5"
ossLicenses = "15.0.1"
debugDb = "1.0.3"
@ -57,9 +57,11 @@ ext {
mockito = "2.18.3"
testRunner = "1.0.2"
fabricGradle = "1.25.3"
crashlyticsSdk = "2.9.2"
crashlyticsAnswers = "1.4.1"
fabricGradle = "1.25.4"
crashlyticsSdk = "2.9.3"
crashlyticsAnswers = "1.4.2"
playPublisher = "1.2.2"
}
allprojects {