1
0

Compare commits

..

60 Commits
0.3.1 ... 0.5.0

Author SHA1 Message Date
dab1bd4ac6 Version 0.5.0 2018-06-14 14:45:32 +02:00
11578aa735 Add dark theme (#133) 2018-06-14 11:40:46 +02:00
b63e28f9a9 Separate synchronization from login (#137) 2018-06-13 18:53:42 +02:00
072c504d2b Clean data user on bad user credentials (#138) 2018-06-13 03:07:34 +02:00
7b7be1eef1 API fixes (#136) 2018-06-10 19:46:34 +02:00
81d177c270 Hide actionbar on scroll (#135) 2018-06-09 00:59:39 +02:00
8d014ab7e9 Fix displaying the replacements in widget (#134) 2018-06-07 08:13:49 +02:00
a06d114127 Add logger (#131) 2018-06-06 19:38:54 +02:00
0e16519baf Add a summary of grades (#127) 2018-06-04 21:47:46 +02:00
dde5775a41 Move ticks converter to api (#130) 2018-06-01 12:52:03 +02:00
e2003e2538 Expand current day on startup (#129) 2018-05-31 23:54:59 +02:00
228f680e5d Hide empty fields in summary (#128) 2018-05-31 23:01:52 +02:00
306092ce45 Add mobile access API (#126) 2018-05-30 11:57:29 +02:00
d4b172e022 Version 0.4.5 2018-05-28 11:32:39 +02:00
b4c765b482 [API] Fix timetable endpoint (#125) 2018-05-28 11:29:43 +02:00
3f1fff6d96 Implementation of a new Dagger injection (#103) 2018-05-26 20:44:06 +02:00
b59008a90f Version 0.4.4 2018-05-25 20:33:45 +02:00
74c0dda999 Fix lesson description from warning (#124) 2018-05-25 20:14:16 +02:00
2288ceffb8 Stop refreshing while semester switching window open (#123) 2018-05-25 19:10:34 +02:00
ffe8511e3f Add some fabric answers (#120) 2018-05-25 16:35:12 +02:00
34205e4a8b Fix autofill on api lvl 26 (#122) 2018-05-25 11:49:53 +02:00
ef648c7f8b Clear db before register (#121) 2018-05-24 22:25:24 +02:00
3592946e6f Fix api login(#119) 2018-05-23 19:21:35 +02:00
859f8dc319 Avoid null if cell second div not contain span (#118) 2018-05-23 18:44:04 +02:00
9c97962e89 Version 0.4.3 2018-05-19 23:37:32 +02:00
a4445a8a97 Fix api login error (#115) 2018-05-19 23:02:54 +02:00
3f54d13b6b Add condition to exam query (#116) 2018-05-19 21:11:04 +02:00
5685e73e46 Fix text alignment <= lv l20 (#117) 2018-05-19 19:58:33 +02:00
e9b357e92d Remove the root check (#114) 2018-05-19 12:48:12 +02:00
62bc00cd68 Delete non-existing lessons on sync (#112) 2018-05-19 12:30:17 +02:00
54e6aee82e Stop SyncJob if user is not registered in app (#113) 2018-05-16 20:43:29 +02:00
3000c077c4 Version 0.4.2 2018-05-14 22:20:17 +02:00
7d5072b529 Fix exams sync (#108) 2018-05-14 22:13:08 +02:00
052d5e3911 Stopping job when user not registered in app (#111) 2018-05-14 21:39:09 +02:00
0014b74c6b Fix certificate parsing issues (#109) 2018-05-14 21:12:45 +02:00
08dd316aee Fix adfs login (#110) 2018-05-14 20:56:17 +02:00
95caa21f2a Version 0.4.1 2018-05-13 18:16:39 +02:00
cd6e14b13b [API] Fix first login (#107) 2018-05-13 17:33:31 +02:00
2cf262130e [API] Get rid of NULL in timetable lesson descriptions (#106) 2018-05-13 16:02:51 +02:00
23183c9d7a Call of SyncJob only after user register in app (#105) 2018-05-13 15:25:56 +02:00
be8ee4c835 Fix parsing grade description with symbol containing special chars (#104) 2018-05-11 21:55:38 +02:00
3105e9e53b Version 0.4.0 2018-05-07 19:45:37 +02:00
8e855bd375 Save current tab position in exams (#102) 2018-05-07 18:18:05 +02:00
67f83a4d2f Mark current week (#100) 2018-05-07 17:57:58 +02:00
d7f0fcad30 Remove backup rules (#101) 2018-05-07 17:44:28 +02:00
f29689c6cd Add about section in settings (#99) 2018-05-07 16:05:57 +02:00
dd2c69601a Change description date in exam and fix styles (#98) 2018-05-06 21:16:03 +02:00
bfaa3d196b Fix animations on expand and collapse (#97) 2018-05-06 20:28:24 +02:00
ffd20c94dd Add exams (#87)
* [API/exams] Fix parsing empty list
* [API/exams] Fix date format
* [API/exams] Set day name from api
2018-05-03 19:47:34 +02:00
1740047aea [API] Add support for adfs login (#76) 2018-05-03 14:14:47 +02:00
cb2d4a905d Add option to hide present in attendance (#96) 2018-05-03 12:49:33 +02:00
89350e5793 Update dependencies (#95) 2018-05-03 12:29:10 +02:00
4ef3334bf7 Add semester switch in grades (#94) 2018-05-02 21:51:23 +02:00
cb6d39fe15 Fix widget state change during update (#93) 2018-04-29 19:47:01 +02:00
09a8cc38f9 Refactor model layout (#92) 2018-04-29 12:45:05 +02:00
3443b01b9a Fix grade regex (#91) 2018-04-27 01:36:40 +02:00
7dde13585c Add info about predicted and final ratings (#88) 2018-04-27 00:03:37 +02:00
176d17e1ec Fix notification intent (#89) 2018-04-24 23:52:53 +02:00
119e38254a Refactor entites (#86) 2018-04-24 22:05:46 +02:00
6fcf09e2b7 Add timetable widget (#84) 2018-04-24 21:27:45 +02:00
282 changed files with 7854 additions and 3512 deletions

View File

@ -31,9 +31,18 @@ jobs:
- run: - run:
name: Setup environment name: Setup environment
command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true
- run:
name: Decrypt keys
command: |
openssl aes-256-cbc -d -in ./app/key-encrypted.p12 -k $ENCRYPT_KEY >> ./app/key.p12
openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
- run: - run:
name: Initial build name: Initial build
command: ./gradlew build assembleDebug -x test -x lint -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex command: ./gradlew build assembleDebug -x test -x lint -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
- run:
name: Clear keys
command: |
rm ./app/key.p12 ./app/upload-key.jks
- store_artifacts: - store_artifacts:
path: ./app/build/outputs/apk/ path: ./app/build/outputs/apk/
destination: apks/ destination: apks/
@ -172,30 +181,69 @@ jobs:
name: Run sonarqube runner name: Run sonarqube runner
command: ./gradlew -x test -x lint sonarqube -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=$CIRCLE_BRANCH --no-daemon --stacktrace --console=plain -PdisablePreDex command: ./gradlew -x test -x lint sonarqube -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=$CIRCLE_BRANCH --no-daemon --stacktrace --console=plain -PdisablePreDex
deploy:
<<: *container_config
steps:
- *attach_workspace
- restore_cache:
<<: *general_cache_key
- run:
name: Decrypt keys
command: |
openssl aes-256-cbc -d -in ./app/key-encrypted.p12 -k $ENCRYPT_KEY >> ./app/key.p12
openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
- run:
name: Publish release
command: ./gradlew publishRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
workflows: workflows:
version: 2 version: 2
build_check_tests: build-test-deploy:
jobs: jobs:
- build - build:
filters:
tags:
only: /.*/
- lint: - lint:
filters:
tags:
only: /.*/
requires: requires:
- build - build
- app-test: - app-test:
filters:
tags:
only: /.*/
requires: requires:
- build - build
- api-test: - api-test:
filters:
tags:
only: /.*/
requires: requires:
- build - build
- instrumented: - instrumented:
requires: filters:
- build tags:
only: /.*/
requires: requires:
- build - build
- sonarcube: - sonarcube:
filters:
tags:
only: /.*/
requires: requires:
- build - build
- lint - lint
- app-test - app-test
- api-test - api-test
- instrumented - instrumented
- deploy:
requires:
- instrumented
filters:
tags:
only: /\d+\.\d+\.\d+/
branches:
ignore: /.*/

4
.gitignore vendored
View File

@ -44,3 +44,7 @@ local.properties
.Trashes .Trashes
ehthumbs.db ehthumbs.db
Thumbs.db Thumbs.db
.idea/codeStyles/
.idea/caches/
./app/key.p12
./app/upload-key.jks

View File

@ -4,9 +4,11 @@
[![Bitrise](https://img.shields.io/bitrise/daeff1893f3c8128/master.svg?token=Hjm1ACamk86JDeVVJHOeqQ&style=flat-square)](https://www.bitrise.io/app/daeff1893f3c8128) [![Bitrise](https://img.shields.io/bitrise/daeff1893f3c8128/master.svg?token=Hjm1ACamk86JDeVVJHOeqQ&style=flat-square)](https://www.bitrise.io/app/daeff1893f3c8128)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy) [![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![BCH compliance](https://bettercodehub.com/edge/badge/wulkanowy/wulkanowy?branch=master)](https://bettercodehub.com/) [![BCH compliance](https://bettercodehub.com/edge/badge/wulkanowy/wulkanowy?branch=master)](https://bettercodehub.com/)
[![Scrutinizer](https://img.shields.io/scrutinizer/g/wulkanowy/wulkanowy.svg)](https://scrutinizer-ci.com/g/wulkanowy/wulkanowy/?branch=master) [![Scrutinizer](https://img.shields.io/scrutinizer/g/wulkanowy/wulkanowy.svg?style=flat-square)](https://scrutinizer-ci.com/g/wulkanowy/wulkanowy/?branch=master)
[![Known Vulnerabilities](https://snyk.io/test/github/wulkanowy/wulkanowy/badge.svg?targetFile=app%2Fbuild.gradle&style=flat-square)](https://snyk.io/test/github/wulkanowy/wulkanowy?targetFile=app%2Fbuild.gradle)
[![Bintray](https://img.shields.io/bintray/v/wulkanowy/wulkanowy/api.svg?style=flat-square)](https://bintray.com/wulkanowy/wulkanowy/api) [![Bintray](https://img.shields.io/bintray/v/wulkanowy/wulkanowy/api.svg?style=flat-square)](https://bintray.com/wulkanowy/wulkanowy/api)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[Pobierz wersję beta](https://play.google.com/store/apps/details?id=io.github.wulkanowy&amp;utm_source=vcs)
[Pobierz wersję rozwojową](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/app-debug-bitrise-signed.apk) [Pobierz wersję rozwojową](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/app-debug-bitrise-signed.apk)

View File

@ -1,4 +1,5 @@
apply plugin: 'java-library' apply plugin: 'java-library'
apply plugin: 'kotlin'
apply plugin: 'org.sonarqube' apply plugin: 'org.sonarqube'
apply plugin: 'jacoco' apply plugin: 'jacoco'
apply plugin: 'com.jfrog.bintray' apply plugin: 'com.jfrog.bintray'
@ -31,6 +32,9 @@ dependencies {
implementation "org.jsoup:jsoup:$jsoup" implementation "org.jsoup:jsoup:$jsoup"
implementation "org.apache.commons:commons-lang3:$apacheLang" implementation "org.apache.commons:commons-lang3:$apacheLang"
implementation "com.google.code.gson:gson:$gson" implementation "com.google.code.gson:gson:$gson"
implementation "org.slf4j:slf4j-api:$slf4jApi"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testImplementation "junit:junit:$junit" testImplementation "junit:junit:$junit"
testImplementation "org.mockito:mockito-core:$mockito" testImplementation "org.mockito:mockito-core:$mockito"
@ -115,3 +119,29 @@ artifacts {
archives sourcesJar archives sourcesJar
archives javadocJar archives javadocJar
} }
buildscript {
ext.kotlin_version = '1.2.41'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
repositories {
mavenCentral()
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}

View File

@ -3,6 +3,8 @@ package io.github.wulkanowy.api;
import org.jsoup.Connection; import org.jsoup.Connection;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
@ -23,10 +25,12 @@ public class Client {
private String symbol; private String symbol;
private Date lastSuccessRequest = null; private Date lastSuccessRequest;
private Cookies cookies = new Cookies(); private Cookies cookies = new Cookies();
private static final Logger logger = LoggerFactory.getLogger(Client.class);
Client(String email, String password, String symbol) { Client(String email, String password, String symbol) {
this.email = email; this.email = email;
this.password = password; this.password = password;
@ -44,7 +48,11 @@ public class Client {
String[] url = creds[0].split("://"); String[] url = creds[0].split("://");
protocol = url[0]; protocol = url[0];
host = url[1]; String[] path = url[1].split("/");
host = path[0];
if (path.length > 1) {
symbol = path[1];
}
email = creds[2]; email = creds[2];
} }
} }
@ -54,13 +62,17 @@ public class Client {
return; return;
} }
this.cookies = new Cookies(); clearCookies();
this.symbol = new Login(this).login(email, password, symbol); this.symbol = new Login(this).login(email, password, symbol);
logger.info("Login successful on {} at {}", getHost(), new Date());
} }
private boolean isLoggedIn() { private boolean isLoggedIn() {
logger.debug("Last success request: {}", lastSuccessRequest);
logger.debug("Cookies: {}", getCookies().size());
return getCookies().size() > 0 && lastSuccessRequest != null && return getCookies().size() > 0 && lastSuccessRequest != null &&
29 > TimeUnit.MILLISECONDS.toMinutes(new Date().getTime() - lastSuccessRequest.getTime()); 5 > TimeUnit.MILLISECONDS.toMinutes(new Date().getTime() - lastSuccessRequest.getTime());
} }
@ -72,14 +84,14 @@ public class Client {
this.symbol = symbol; this.symbol = symbol;
} }
public void addCookies(Map<String, String> items) {
cookies.addItems(items);
}
private Map<String, String> getCookies() { private Map<String, String> getCookies() {
return cookies.getItems(); return cookies.getItems();
} }
public void clearCookies() {
cookies = new Cookies();
}
String getHost() { String getHost() {
return host; return host;
} }
@ -99,7 +111,7 @@ public class Client {
return getPageByUrl(url, loginBefore, null); return getPageByUrl(url, loginBefore, null);
} }
public Document getPageByUrl(String url, boolean loginBefore, Map<String, String> cookies) throws IOException, VulcanException { public synchronized Document getPageByUrl(String url, boolean loginBefore, Map<String, String> cookies) throws IOException, VulcanException {
if (loginBefore) { if (loginBefore) {
login(); login();
} }
@ -108,14 +120,18 @@ public class Client {
this.cookies.addItems(cookies); this.cookies.addItems(cookies);
} }
Connection.Response response = Jsoup.connect(getFilledUrl(url)) url = getFilledUrl(url);
logger.debug("GET {}", url);
Connection.Response response = Jsoup.connect(url)
.followRedirects(true) .followRedirects(true)
.cookies(getCookies()) .cookies(getCookies())
.execute(); .execute();
this.cookies.addItems(response.cookies()); this.cookies.addItems(response.cookies());
Document doc = checkForErrors(response.parse()); Document doc = checkForErrors(response.parse(), response.statusCode());
if (loginBefore) { if (loginBefore) {
lastSuccessRequest = new Date(); lastSuccessRequest = new Date();
@ -124,8 +140,12 @@ public class Client {
return doc; return doc;
} }
public Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException { public synchronized Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException {
Connection connection = Jsoup.connect(getFilledUrl(url)); url = getFilledUrl(url);
logger.debug("POST {}", url);
Connection connection = Jsoup.connect(url);
for (String[] data : params) { for (String[] data : params) {
connection.data(data[0], data[1]); connection.data(data[0], data[1]);
@ -139,13 +159,19 @@ public class Client {
this.cookies.addItems(response.cookies()); this.cookies.addItems(response.cookies());
return checkForErrors(response.parse()); response.bufferUp(); // fixes cert parsing issues #109
return checkForErrors(response.parse(), response.statusCode());
} }
public String getJsonStringByUrl(String url) throws IOException, VulcanException { public String getJsonStringByUrl(String url) throws IOException, VulcanException {
login(); login();
Connection.Response response = Jsoup.connect(getFilledUrl(url)) url = getFilledUrl(url);
logger.debug("GET {}", url);
Connection.Response response = Jsoup.connect(url)
.followRedirects(true) .followRedirects(true)
.ignoreContentType(true) .ignoreContentType(true)
.cookies(getCookies()) .cookies(getCookies())
@ -159,7 +185,11 @@ public class Client {
public String postJsonStringByUrl(String url, String[][] params) throws IOException, VulcanException { public String postJsonStringByUrl(String url, String[][] params) throws IOException, VulcanException {
login(); login();
Connection connection = Jsoup.connect(getFilledUrl(url)); url = getFilledUrl(url);
logger.debug("POST {}", url);
Connection connection = Jsoup.connect(url);
for (String[] data : params) { for (String[] data : params) {
connection.data(data[0], data[1]); connection.data(data[0], data[1]);
@ -177,7 +207,7 @@ public class Client {
return response.body(); return response.body();
} }
Document checkForErrors(Document doc) throws VulcanException { Document checkForErrors(Document doc, int code) throws VulcanException {
lastSuccessRequest = null; lastSuccessRequest = null;
String title = doc.select("title").text(); String title = doc.select("title").text();
@ -191,7 +221,7 @@ public class Client {
} }
if ("Błąd strony".equals(title)) { if ("Błąd strony".equals(title)) {
throw new VulcanException("Nieznany błąd"); throw new NotLoggedInErrorException(title + " " + doc.body() + ", status: " + code);
} }
return doc; return doc;

View File

@ -0,0 +1,53 @@
package io.github.wulkanowy.api
import java.text.SimpleDateFormat
import java.util.*
const val LOG_DATE_PATTERN = "dd.MM.yyyy"
const val API_DATE_PATTERN = "yyyy-MM-dd"
const val TICKS_AT_EPOCH = 621355968000000000L
const val TICKS_PER_MILLISECOND = 10000
fun getFormattedDate(date: String): String {
return getFormattedDate(date, API_DATE_PATTERN)
}
fun getFormattedDate(date: String, format: String): String {
return getFormattedDate(date, LOG_DATE_PATTERN, format)
}
fun getFormattedDate(date: String, fromFormat: String, toFormat: String): String {
val sdf = SimpleDateFormat(fromFormat, Locale.ROOT)
val d = sdf.parse(date)
sdf.applyPattern(toFormat)
return sdf.format(d)
}
fun getDateAsTick(dateString: String?): String {
if (dateString.isNullOrEmpty()) {
return ""
}
return getDateAsTick(dateString as String, API_DATE_PATTERN).toString()
}
fun getDateAsTick(dateString: String, dateFormat: String): Long {
val format = SimpleDateFormat(dateFormat, Locale.ROOT)
format.timeZone = TimeZone.getTimeZone("UTC")
val dateObject = format.parse(dateString)
return getDateAsTick(dateObject)
}
fun getDateAsTick(date: Date): Long {
val calendar = Calendar.getInstance()
calendar.time = date
return calendar.timeInMillis * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH
}
fun getDate(netTicks: Long): Date {
return Date((netTicks - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND)
}

View File

@ -6,6 +6,11 @@ import org.jsoup.nodes.Element;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import io.github.wulkanowy.api.generic.Diary;
import io.github.wulkanowy.api.generic.ParamItem;
import io.github.wulkanowy.api.generic.Semester;
import io.github.wulkanowy.api.generic.Student;
public interface SnP { public interface SnP {
String getSchoolID(); String getSchoolID();

View File

@ -3,6 +3,8 @@ package io.github.wulkanowy.api;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
@ -11,6 +13,11 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import io.github.wulkanowy.api.generic.Diary;
import io.github.wulkanowy.api.generic.ParamItem;
import io.github.wulkanowy.api.generic.Semester;
import io.github.wulkanowy.api.generic.Student;
public class StudentAndParent implements SnP { public class StudentAndParent implements SnP {
private static final String START_PAGE_URL = "{schema}://uonetplus.{host}/{symbol}/Start.mvc/Index"; private static final String START_PAGE_URL = "{schema}://uonetplus.{host}/{symbol}/Start.mvc/Index";
@ -27,6 +34,8 @@ public class StudentAndParent implements SnP {
private String diaryID; private String diaryID;
private static final Logger logger = LoggerFactory.getLogger(StudentAndParent.class);
StudentAndParent(Client client, String schoolID, String studentID, String diaryID) { StudentAndParent(Client client, String schoolID, String studentID, String diaryID) {
this.client = client; this.client = client;
this.schoolID = schoolID; this.schoolID = schoolID;
@ -38,6 +47,11 @@ public class StudentAndParent implements SnP {
if (null == getStudentID() || "".equals(getStudentID())) { if (null == getStudentID() || "".equals(getStudentID())) {
Document doc = client.getPageByUrl(getSnpHomePageUrl()); Document doc = client.getPageByUrl(getSnpHomePageUrl());
if (doc.select("#idSection").isEmpty()) {
logger.error("Expected SnP page, got page with title: {} {}", doc.title(), doc.selectFirst("body"));
throw new VulcanException("Nieznany błąd podczas pobierania danych. Strona: " + doc.title());
}
Student student = getCurrent(getStudents(doc)); Student student = getCurrent(getStudents(doc));
studentID = student.getId(); studentID = student.getId();
@ -65,26 +79,29 @@ public class StudentAndParent implements SnP {
return getBaseUrl(); return getBaseUrl();
} }
// get url to uonetplus-opiekun.vulcan.net.pl // get url to uonetplus-opiekun.fakelog.cf
Document startPage = client.getPageByUrl(START_PAGE_URL); Document startPage = client.getPageByUrl(START_PAGE_URL);
Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first(); Elements studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a");
if (null == studentTileLink) { logger.debug("studentTileLink: {}", studentTileLink.size());
throw new NotLoggedInErrorException("You are probably not logged in. Force login");
if (studentTileLink.isEmpty()) {
throw new VulcanException("Na pewno używasz konta z dostępem do Witryny ucznia i rodzica?");
} }
String snpPageUrl = studentTileLink.attr("href"); String snpPageUrl = studentTileLink.last().attr("href");
this.schoolID = getExtractedIdFromUrl(snpPageUrl); this.schoolID = getExtractedIdFromUrl(snpPageUrl);
return snpPageUrl; return snpPageUrl;
} }
String getExtractedIdFromUrl(String snpPageUrl) throws NotLoggedInErrorException { String getExtractedIdFromUrl(String snpPageUrl) throws VulcanException {
String[] path = snpPageUrl.split(client.getHost())[1].split("/"); String[] path = snpPageUrl.split(client.getHost())[1].split("/");
if (5 != path.length) { if (5 != path.length) {
throw new NotLoggedInErrorException("You are probably not logged in"); logger.error("Expected snp url, got {}", snpPageUrl);
throw new VulcanException("Na pewno używasz konta z dostępem do Witryny ucznia i rodzica?");
} }
return path[2]; return path[2];
@ -102,11 +119,15 @@ public class StudentAndParent implements SnP {
Map<String, String> cookies = new HashMap<>(); Map<String, String> cookies = new HashMap<>();
cookies.put("idBiezacyDziennik", diaryID); cookies.put("idBiezacyDziennik", diaryID);
cookies.put("idBiezacyUczen", studentID); cookies.put("idBiezacyUczen", studentID);
client.addCookies(cookies);
Document doc = client.getPageByUrl(getBaseUrl() + url, true, cookies); Document doc = client.getPageByUrl(getBaseUrl() + url, true, cookies);
if ("Witryna ucznia i rodzica Strona główna".equals(doc.select("title").first().text())) { if (!doc.title().startsWith("Witryna ucznia i rodzica")) {
logger.error("Expected SnP page, got page with title: {} {}", doc.title(), doc.selectFirst("body"));
throw new VulcanException("Nieznany błąd podczas pobierania danych. Strona: " + doc.title());
}
if (doc.title().endsWith("Strona główna")) {
throw new VulcanException("Sesja została nieprawidłowo zainicjowana"); throw new VulcanException("Sesja została nieprawidłowo zainicjowana");
} }
@ -140,8 +161,8 @@ public class StudentAndParent implements SnP {
for (Element e : semesterOptions) { for (Element e : semesterOptions) {
Semester semester = new Semester() Semester semester = new Semester()
.setId(e.text()) .setId(e.attr("value"))
.setName(e.attr("value")); .setName(e.text());
if (isCurrent(e)) { if (isCurrent(e)) {
semester.setCurrent(true); semester.setCurrent(true);
@ -167,9 +188,6 @@ public class StudentAndParent implements SnP {
if (isCurrent(e)) { if (isCurrent(e)) {
item.setCurrent(true); item.setCurrent(true);
} }
if (item instanceof Diary) {
item.setStudentId(getStudentID());
}
list.add((T) item); list.add((T) item);
} catch (Exception ex) { } catch (Exception ex) {

View File

@ -1,5 +1,8 @@
package io.github.wulkanowy.api; package io.github.wulkanowy.api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import io.github.wulkanowy.api.attendance.AttendanceStatistics; import io.github.wulkanowy.api.attendance.AttendanceStatistics;
@ -8,6 +11,8 @@ import io.github.wulkanowy.api.exams.ExamsWeek;
import io.github.wulkanowy.api.grades.GradesList; import io.github.wulkanowy.api.grades.GradesList;
import io.github.wulkanowy.api.grades.SubjectsList; import io.github.wulkanowy.api.grades.SubjectsList;
import io.github.wulkanowy.api.messages.Messages; import io.github.wulkanowy.api.messages.Messages;
import io.github.wulkanowy.api.mobile.RegisterDevice;
import io.github.wulkanowy.api.mobile.RegisteredDevices;
import io.github.wulkanowy.api.notes.AchievementsList; import io.github.wulkanowy.api.notes.AchievementsList;
import io.github.wulkanowy.api.notes.NotesList; import io.github.wulkanowy.api.notes.NotesList;
import io.github.wulkanowy.api.school.SchoolInfo; import io.github.wulkanowy.api.school.SchoolInfo;
@ -28,17 +33,21 @@ public class Vulcan {
private String diaryId; private String diaryId;
private static final Logger logger = LoggerFactory.getLogger(Vulcan.class);
public void setCredentials(String email, String password, String symbol, String schoolId, String studentId, String diaryId) { public void setCredentials(String email, String password, String symbol, String schoolId, String studentId, String diaryId) {
this.schoolId = schoolId; this.schoolId = schoolId;
this.studentId = studentId; this.studentId = studentId;
this.diaryId = diaryId; this.diaryId = diaryId;
client = new Client(email, password, symbol); client = new Client(email, password, symbol);
logger.debug("Client created with symbol " + symbol);
} }
public Client getClient() throws NotLoggedInErrorException { public Client getClient() throws NotLoggedInErrorException {
if (null == client) { if (null == client) {
throw new NotLoggedInErrorException("Use setCredentials() method first"); throw new NotLoggedInErrorException("Vulcan must be initialized by calling setCredentials() prior to fetch data");
} }
return client; return client;
@ -108,6 +117,14 @@ public class Vulcan {
return new FamilyInformation(getStudentAndParent()); return new FamilyInformation(getStudentAndParent());
} }
public RegisteredDevices getRegisteredDevices() throws VulcanException, IOException {
return new RegisteredDevices(getStudentAndParent());
}
public RegisterDevice getRegisterDevice() throws VulcanException, IOException {
return new RegisterDevice(getStudentAndParent());
}
public Messages getMessages() throws VulcanException { public Messages getMessages() throws VulcanException {
return new Messages(getClient()); return new Messages(getClient());
} }

View File

@ -2,7 +2,7 @@ package io.github.wulkanowy.api;
public class VulcanException extends Exception { public class VulcanException extends Exception {
protected VulcanException(String message) { public VulcanException(String message) {
super(message); super(message);
} }

View File

@ -4,12 +4,8 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import io.github.wulkanowy.api.SnP; import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.api.VulcanException;
@ -17,6 +13,9 @@ import io.github.wulkanowy.api.generic.Day;
import io.github.wulkanowy.api.generic.Lesson; import io.github.wulkanowy.api.generic.Lesson;
import io.github.wulkanowy.api.generic.Week; import io.github.wulkanowy.api.generic.Week;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getDateAsTick;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
public class AttendanceTable { public class AttendanceTable {
private final static String ATTENDANCE_PAGE_URL = "Frekwencja.mvc?data="; private final static String ATTENDANCE_PAGE_URL = "Frekwencja.mvc?data=";
@ -27,13 +26,12 @@ public class AttendanceTable {
this.snp = snp; this.snp = snp;
} }
public Week<Day> getWeekTable() throws IOException, ParseException, VulcanException { public Week<Day> getWeekTable() throws IOException, VulcanException {
return getWeekTable(""); return getWeekTable("");
} }
public Week<Day> getWeekTable(String tick) throws IOException, ParseException, VulcanException { public Week<Day> getWeekTable(String date) throws IOException, VulcanException {
Element table = snp.getSnPPageDocument(ATTENDANCE_PAGE_URL + tick) Element table = snp.getSnPPageDocument(ATTENDANCE_PAGE_URL + getDateAsTick(date))
.select(".mainContainer .presentData").first(); .select(".mainContainer .presentData").first();
Elements headerCells = table.select("thead th"); Elements headerCells = table.select("thead th");
@ -42,14 +40,10 @@ public class AttendanceTable {
for (int i = 1; i < headerCells.size(); i++) { for (int i = 1; i < headerCells.size(); i++) {
String[] dayHeaderCell = headerCells.get(i).html().split("<br>"); String[] dayHeaderCell = headerCells.get(i).html().split("<br>");
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT); days.add(new Day()
Date d = sdf.parse(dayHeaderCell[1].trim()); .setDayName(dayHeaderCell[0])
sdf.applyPattern("yyyy-MM-dd"); .setDate(getFormattedDate(dayHeaderCell[1].trim()))
);
Day day = new Day();
day.setDayName(dayHeaderCell[0]);
day.setDate(sdf.format(d));
days.add(day);
} }
Elements hoursInDays = table.select("tbody tr"); Elements hoursInDays = table.select("tbody tr");
@ -63,7 +57,7 @@ public class AttendanceTable {
for (int i = 1; i < size; i++) { for (int i = 1; i < size; i++) {
Lesson lesson = new Lesson(); Lesson lesson = new Lesson();
lesson.setDate(days.get(i - 1).getDate()); lesson.setDate(days.get(i - 1).getDate());
lesson.setNumber(hours.get(0).text()); lesson.setNumber(Integer.valueOf(hours.get(0).text()));
addLessonDetails(lesson, hours.get(i)); addLessonDetails(lesson, hours.get(i));

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.api.exams; package io.github.wulkanowy.api.exams;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
@ -12,6 +13,9 @@ import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.api.generic.Week; import io.github.wulkanowy.api.generic.Week;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getDateAsTick;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
public class ExamsWeek { public class ExamsWeek {
private static final String EXAMS_PAGE_URL = "Sprawdziany.mvc/Terminarz?rodzajWidoku=2&data="; private static final String EXAMS_PAGE_URL = "Sprawdziany.mvc/Terminarz?rodzajWidoku=2&data=";
@ -26,8 +30,8 @@ public class ExamsWeek {
return getWeek("", true); return getWeek("", true);
} }
public Week<ExamDay> getWeek(String tick, final boolean onlyNotEmpty) throws IOException, VulcanException { public Week<ExamDay> getWeek(String date, final boolean onlyNotEmpty) throws IOException, VulcanException {
Document examsPage = snp.getSnPPageDocument(EXAMS_PAGE_URL + tick); Document examsPage = snp.getSnPPageDocument(EXAMS_PAGE_URL + getDateAsTick(date));
Elements examsDays = examsPage.select(".mainContainer > div:not(.navigation)"); Elements examsDays = examsPage.select(".mainContainer > div:not(.navigation)");
List<ExamDay> days = new ArrayList<>(); List<ExamDay> days = new ArrayList<>();
@ -41,7 +45,9 @@ public class ExamsWeek {
} }
if (null != dayHeading) { if (null != dayHeading) {
day.setDate(dayHeading.text().split(", ")[1]); String[] dateHeader = dayHeading.text().split(", ");
day.setDayName(StringUtils.capitalize(dateHeader[0]));
day.setDate(getFormattedDate(dateHeader[1]));
} }
Elements exams = item.select("article"); Elements exams = item.select("article");
@ -51,15 +57,17 @@ public class ExamsWeek {
.setType(snp.getRowDataChildValue(e, 2)) .setType(snp.getRowDataChildValue(e, 2))
.setDescription(snp.getRowDataChildValue(e, 3)) .setDescription(snp.getRowDataChildValue(e, 3))
.setTeacher(snp.getRowDataChildValue(e, 4).split(", ")[0]) .setTeacher(snp.getRowDataChildValue(e, 4).split(", ")[0])
.setEntryDate(snp.getRowDataChildValue(e, 4).split(", ")[1]) .setEntryDate(getFormattedDate(snp.getRowDataChildValue(e, 4).split(", ")[1]))
); );
} }
days.add(day); days.add(day);
} }
return new Week<ExamDay>() return new Week<ExamDay>()
.setStartDayDate(examsDays.select("h2").first().text().split(" ")[1]) .setStartDayDate(getFormattedDate(examsPage.select(".mainContainer > h2")
.first().text().split(" ")[1]))
.setDays(days); .setDays(days);
} }
} }

View File

@ -11,10 +11,6 @@ public class Day {
private String dayName = ""; private String dayName = "";
private boolean isFreeDay = false;
private String freeDayName = "";
public Lesson getLesson(int index) { public Lesson getLesson(int index) {
return lessons.get(index); return lessons.get(index);
} }
@ -41,23 +37,8 @@ public class Day {
return dayName; return dayName;
} }
public void setDayName(String dayName) { public Day setDayName(String dayName) {
this.dayName = dayName; this.dayName = dayName;
} return this;
public boolean isFreeDay() {
return isFreeDay;
}
public void setFreeDay(boolean freeDay) {
isFreeDay = freeDay;
}
public String getFreeDayName() {
return freeDayName;
}
public void setFreeDayName(String freeDayName) {
this.freeDayName = freeDayName;
} }
} }

View File

@ -1,11 +1,9 @@
package io.github.wulkanowy.api; package io.github.wulkanowy.api.generic;
public class Diary implements ParamItem { public class Diary implements ParamItem {
private String id = ""; private String id = "";
private String studentId = "";
private String name = ""; private String name = "";
private boolean current = false; private boolean current = false;
@ -19,16 +17,6 @@ public class Diary implements ParamItem {
return this; return this;
} }
public String getStudentId() {
return studentId;
}
@Override
public Diary setStudentId(String studentId) {
this.studentId = studentId;
return this;
}
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -2,7 +2,7 @@ package io.github.wulkanowy.api.generic;
public class Lesson { public class Lesson {
private String number = ""; private int number = 0;
private String subject = ""; private String subject = "";
@ -48,12 +48,13 @@ public class Lesson {
private boolean isExemption = false; private boolean isExemption = false;
public String getNumber() { public int getNumber() {
return number; return number;
} }
public void setNumber(String number) { public Lesson setNumber(int number) {
this.number = number; this.number = number;
return this;
} }
public String getSubject() { public String getSubject() {

View File

@ -1,11 +1,9 @@
package io.github.wulkanowy.api; package io.github.wulkanowy.api.generic;
interface ParamItem { public interface ParamItem {
ParamItem setId(String id); ParamItem setId(String id);
ParamItem setStudentId(String id);
ParamItem setName(String name); ParamItem setName(String name);
ParamItem setCurrent(boolean isCurrent); ParamItem setCurrent(boolean isCurrent);

View File

@ -1,11 +1,9 @@
package io.github.wulkanowy.api; package io.github.wulkanowy.api.generic;
public class Semester implements ParamItem { public class Semester implements ParamItem {
private String id = ""; private String id = "";
private String studentId = "";
private String name = ""; private String name = "";
private boolean current = false; private boolean current = false;
@ -19,16 +17,6 @@ public class Semester implements ParamItem {
return this; return this;
} }
public String getStudentId() {
return studentId;
}
@Override
public Semester setStudentId(String studentId) {
this.studentId = studentId;
return this;
}
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -1,4 +1,4 @@
package io.github.wulkanowy.api; package io.github.wulkanowy.api.generic;
public class Student implements ParamItem { public class Student implements ParamItem {
@ -17,15 +17,6 @@ public class Student implements ParamItem {
return this; return this;
} }
public String getStudentId() {
return getId();
}
@Override
public Student setStudentId(String studentId) {
return setId(studentId);
}
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -18,8 +18,6 @@ public class Grade {
private String teacher = ""; private String teacher = "";
private String semester = "";
public String getSubject() { public String getSubject() {
return subject; return subject;
} }
@ -99,14 +97,4 @@ public class Grade {
return this; return this;
} }
public String getSemester() {
return semester;
}
public Grade setSemester(String semester) {
this.semester = semester;
return this;
}
} }

View File

@ -5,67 +5,50 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import io.github.wulkanowy.api.Semester;
import io.github.wulkanowy.api.SnP; import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.api.VulcanException;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
public class GradesList { public class GradesList {
private static final String GRADES_PAGE_URL = "Oceny/Wszystkie?details=2&okres="; private static final String GRADES_PAGE_URL = "Oceny/Wszystkie?details=2&okres=";
private SnP snp; private SnP snp;
private List<Grade> grades = new ArrayList<>();
public GradesList(SnP snp) { public GradesList(SnP snp) {
this.snp = snp; this.snp = snp;
} }
private String getGradesPageUrl() { public List<Grade> getAll(String semester) throws IOException, VulcanException {
return GRADES_PAGE_URL; Document gradesPage = snp.getSnPPageDocument(GRADES_PAGE_URL + semester);
}
public List<Grade> getAll() throws IOException, ParseException, VulcanException {
return getAll("");
}
public List<Grade> getAll(String semester) throws IOException, ParseException, VulcanException {
Document gradesPage = snp.getSnPPageDocument(getGradesPageUrl() + semester);
Elements gradesRows = gradesPage.select(".ocenySzczegoly-table > tbody > tr"); Elements gradesRows = gradesPage.select(".ocenySzczegoly-table > tbody > tr");
if ("".equals(semester)) { List<Grade> grades = new ArrayList<>();
List<Semester> semesterList = snp.getSemesters(gradesPage);
Semester currentSemester = snp.getCurrent(semesterList);
semester = currentSemester.getName();
}
for (Element row : gradesRows) { for (Element row : gradesRows) {
if ("Brak ocen".equals(row.select("td:nth-child(2)").text())) { if ("Brak ocen".equals(row.select("td:nth-child(2)").text())) {
continue; continue;
} }
grades.add(getGrade(row, semester)); grades.add(getGrade(row));
} }
return grades; return grades;
} }
private Grade getGrade(Element row, String semester) throws ParseException { private Grade getGrade(Element row) {
String descriptions = row.select("td:nth-child(3)").text(); String descriptions = row.select("td:nth-child(3)").text();
String symbol = descriptions.split(", ")[0]; String symbol = descriptions.split(", ")[0];
String description = descriptions.replaceFirst(symbol, "").replaceFirst(", ", ""); String description = descriptions.replaceFirst(Pattern.quote(symbol), "").replaceFirst(", ", "");
String color = getColor(row.select("td:nth-child(2) span.ocenaCzastkowa").attr("style")); String color = getColor(row.select("td:nth-child(2) span.ocenaCzastkowa").attr("style"));
String date = formatDate(row.select("td:nth-child(5)").text()); String date = getFormattedDate(row.select("td:nth-child(5)").text());
return new Grade() return new Grade()
.setSubject(row.select("td:nth-child(1)").text()) .setSubject(row.select("td:nth-child(1)").text())
@ -75,8 +58,7 @@ public class GradesList {
.setDescription(description) .setDescription(description)
.setWeight(row.select("td:nth-child(4)").text()) .setWeight(row.select("td:nth-child(4)").text())
.setDate(date) .setDate(date)
.setTeacher(row.select("td:nth-child(6)").text()) .setTeacher(row.select("td:nth-child(6)").text());
.setSemester(semester);
} }
private String getColor(String styleAttr) { private String getColor(String styleAttr) {
@ -90,12 +72,4 @@ public class GradesList {
return color; return color;
} }
private String formatDate(String date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT);
Date d = sdf.parse(date);
sdf.applyPattern("yyyy-MM-dd");
return sdf.format(d);
}
} }

View File

@ -13,16 +13,21 @@ import io.github.wulkanowy.api.VulcanException;
public class SubjectsList { public class SubjectsList {
private static final String SUBJECTS_PAGE_URL = "Oceny/Wszystkie?details=1"; private static final String SUBJECTS_PAGE_URL = "Oceny/Wszystkie?details=1&okres=";
private SnP snp = null; private SnP snp;
public SubjectsList(SnP snp) { public SubjectsList(SnP snp) {
this.snp = snp; this.snp = snp;
} }
public List<Subject> getAll() throws IOException, VulcanException { public List<Subject> getAll() throws IOException, VulcanException {
Document subjectPage = snp.getSnPPageDocument(SUBJECTS_PAGE_URL); return getAll("");
}
public List<Subject> getAll(String semester) throws IOException, VulcanException {
Document subjectPage = snp.getSnPPageDocument(SUBJECTS_PAGE_URL + semester);
Elements rows = subjectPage.select(".ocenyZwykle-table > tbody > tr"); Elements rows = subjectPage.select(".ocenyZwykle-table > tbody > tr");

View File

@ -5,21 +5,26 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser; import org.jsoup.parser.Parser;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import io.github.wulkanowy.api.Client; import io.github.wulkanowy.api.Client;
import io.github.wulkanowy.api.NotLoggedInErrorException;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.api.VulcanException;
public class Login { public class Login {
private static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn" + static final String LOGIN_PAGE_URL = "{schema}://cufs.{host}/{symbol}/Account/LogOn" +
"?ReturnUrl=%2F{symbol}%2FFS%2FLS%3Fwa%3Dwsignin1.0%26wtrealm%3D" + "?ReturnUrl=%2F{symbol}%2FFS%2FLS%3Fwa%3Dwsignin1.0%26wtrealm%3D" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx%26wctx%3D" + "{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx%26wctx%3D" +
"{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx"; "{schema}%253a%252f%252fuonetplus.{host}%252f{symbol}%252fLoginEndpoint.aspx";
private Client client; private Client client;
private static final Logger logger = LoggerFactory.getLogger(Login.class);
public Login(Client client) { public Login(Client client) {
this.client = client; this.client = client;
} }
@ -27,41 +32,81 @@ public class Login {
public String login(String email, String password, String symbol) throws VulcanException, IOException { public String login(String email, String password, String symbol) throws VulcanException, IOException {
Document certDoc = sendCredentials(email, password); Document certDoc = sendCredentials(email, password);
if ("Błąd".equals(certDoc.title())) {
client.clearCookies();
throw new NotLoggedInErrorException(certDoc.body().text());
}
return sendCertificate(certDoc, symbol); return sendCertificate(certDoc, symbol);
} }
Document sendCredentials(String email, String password) throws IOException, VulcanException { Document sendCredentials(String email, String password) throws IOException, VulcanException {
Document html = client.postPageByUrl(LOGIN_PAGE_URL, new String[][]{ String[][] credentials = new String[][]{
{"LoginName", email}, {"LoginName", email},
{"Password", password} {"Password", password}
}); };
Element errorMessage = html.select(".ErrorMessage").first(); Document nextDoc = sendCredentialsData(credentials, LOGIN_PAGE_URL);
Element errorMessage = nextDoc.selectFirst(".ErrorMessage, #ErrorTextLabel");
if (null != errorMessage) { if (null != errorMessage) {
throw new BadCredentialsException(errorMessage.text()); throw new BadCredentialsException(errorMessage.text());
} }
return html; return nextDoc;
}
private Document sendCredentialsData(String[][] credentials, String nextUrl) throws IOException, VulcanException {
Element formFirst = client.getPageByUrl(nextUrl, false).selectFirst("#form1");
if (null != formFirst) { // only on adfs login
Document formSecond = client.postPageByUrl(
formFirst.attr("abs:action"),
getFormStateParams(formFirst, "", "")
);
credentials = getFormStateParams(formSecond, credentials[0][1], credentials[1][1]);
nextUrl = formSecond.selectFirst("#form1").attr("abs:action");
}
return client.postPageByUrl(nextUrl, credentials);
}
private String[][] getFormStateParams(Element form, String email, String password) {
return new String[][]{
{"__VIEWSTATE", form.select("#__VIEWSTATE").val()},
{"__VIEWSTATEGENERATOR", form.select("#__VIEWSTATEGENERATOR").val()},
{"__EVENTVALIDATION", form.select("#__EVENTVALIDATION").val()},
{"__db", form.select("input[name=__db]").val()},
{"PassiveSignInButton.x", "0"},
{"PassiveSignInButton.y", "0"},
{"SubmitButton.x", "0"},
{"SubmitButton.y", "0"},
{"UsernameTextBox", email},
{"PasswordTextBox", password},
};
} }
String sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException { String sendCertificate(Document doc, String defaultSymbol) throws IOException, VulcanException {
String certificate = doc.select("input[name=wresult]").val(); client.setSymbol(findSymbol(defaultSymbol, doc.select("input[name=wresult]").val()));
String symbol = findSymbol(defaultSymbol, certificate);
client.setSymbol(symbol);
Document targetDoc = sendCertData(doc); Document targetDoc = sendCertData(doc);
String title = targetDoc.select("title").text(); String title = targetDoc.title();
if ("Working...".equals(title)) { // on adfs login
logger.info("ADFS login");
title = sendCertData(targetDoc).title();
}
if ("Logowanie".equals(title)) { if ("Logowanie".equals(title)) {
throw new AccountPermissionException("No account access. Try another symbol"); throw new AccountPermissionException("No account access. Try another symbol");
} }
if (!"Uonet+".equals(title)) { if (!"Uonet+".equals(title)) {
logger.debug("Login failed. Body: {}", targetDoc.body());
throw new LoginErrorException("Expected page title `UONET+`, got " + title); throw new LoginErrorException("Expected page title `UONET+`, got " + title);
} }
return symbol; return client.getSymbol();
} }
private Document sendCertData(Document doc) throws IOException, VulcanException { private Document sendCertData(Document doc) throws IOException, VulcanException {
@ -74,7 +119,7 @@ public class Login {
}); });
} }
private String findSymbol(String symbol, String certificate) { private String findSymbol(String symbol, String certificate) throws AccountPermissionException {
if ("Default".equals(symbol)) { if ("Default".equals(symbol)) {
return findSymbolInCertificate(certificate); return findSymbolInCertificate(certificate);
} }
@ -82,15 +127,19 @@ public class Login {
return symbol; return symbol;
} }
String findSymbolInCertificate(String certificate) { String findSymbolInCertificate(String certificate) throws AccountPermissionException {
Elements instances = Jsoup Elements instances = Jsoup
.parse(certificate.replaceAll(":", ""), "", Parser.xmlParser()) .parse(certificate.replaceAll(":", ""), "", Parser.xmlParser())
.select("[AttributeName=\"UserInstance\"] samlAttributeValue"); .select("[AttributeName=\"UserInstance\"] samlAttributeValue");
if (instances.isEmpty()) { if (instances.isEmpty()) { // on adfs login
return ""; return "";
} }
if (instances.size() < 2) { // 1st index is always `Default`
throw new AccountPermissionException("First login detected, specify symbol");
}
return instances.get(1).text(); return instances.get(1).text();
} }
} }

View File

@ -0,0 +1,33 @@
package io.github.wulkanowy.api.mobile
import io.github.wulkanowy.api.SnP
import org.jsoup.nodes.Element
class RegisterDevice(private val snp: SnP) {
companion object {
const val REGISTER_URL = "DostepMobilny.mvc/Rejestruj"
}
data class Token(
val token: String,
val symbol: String,
val pin: String
)
fun getToken(): Token {
val form = snp.getSnPPageDocument(REGISTER_URL).selectFirst("#rejestracja-formularz")
val fields = form.select(".blockElement")
return Token(
getValue(fields[1]),
getValue(fields[2]),
getValue(fields[3])
)
}
fun getValue(e: Element): String {
return e.text().split(":")[1].trim()
}
}

View File

@ -0,0 +1,38 @@
package io.github.wulkanowy.api.mobile
import io.github.wulkanowy.api.SnP
import io.github.wulkanowy.api.getFormattedDate
class RegisteredDevices(private val snp: SnP) {
companion object {
const val DEVICES_LIST_URL = "DostepMobilny.mvc"
}
data class Device(
val name: String,
val system: String,
val date: String,
val id: Int
)
fun getList(): List<Device> {
val items = snp.getSnPPageDocument(DEVICES_LIST_URL).select("table tbody tr")
val devices: MutableList<Device> = mutableListOf()
for (item in items) {
val cells = item.select("td")
val system = cells[0].text().split("(").last().removeSuffix(")")
devices.add(Device(
cells[0].text().replace(" ($system)", ""),
system,
getFormattedDate(cells[1].text(), "dd.MM.yyyy 'godz:' HH:mm:ss", "yyyy-MM-dd HH:mm:ss"),
cells[2].select("a").attr("href")
.split("/").last().toInt()
))
}
return devices
}
}

View File

@ -14,9 +14,7 @@ public class AchievementsList {
private static final String NOTES_PAGE_URL = "UwagiOsiagniecia.mvc/Wszystkie"; private static final String NOTES_PAGE_URL = "UwagiOsiagniecia.mvc/Wszystkie";
private SnP snp = null; private SnP snp;
private List<String> achievements = new ArrayList<>();
public AchievementsList(SnP snp) { public AchievementsList(SnP snp) {
this.snp = snp; this.snp = snp;
@ -27,6 +25,8 @@ public class AchievementsList {
.select(".mainContainer > div").get(1); .select(".mainContainer > div").get(1);
Elements items = pageFragment.select("article"); Elements items = pageFragment.select("article");
List<String> achievements = new ArrayList<>();
for (Element item : items) { for (Element item : items) {
achievements.add(item.text()); achievements.add(item.text());
} }

View File

@ -10,13 +10,13 @@ import java.util.List;
import io.github.wulkanowy.api.SnP; import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.api.VulcanException;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
public class NotesList { public class NotesList {
private static final String NOTES_PAGE_URL = "UwagiOsiagniecia.mvc/Wszystkie"; private static final String NOTES_PAGE_URL = "UwagiOsiagniecia.mvc/Wszystkie";
private SnP snp = null; private SnP snp;
private List<Note> notes = new ArrayList<>();
public NotesList(SnP snp) { public NotesList(SnP snp) {
this.snp = snp; this.snp = snp;
@ -28,10 +28,12 @@ public class NotesList {
Elements items = pageFragment.select("article"); Elements items = pageFragment.select("article");
Elements dates = pageFragment.select("h2"); Elements dates = pageFragment.select("h2");
List<Note> notes = new ArrayList<>();
int index = 0; int index = 0;
for (Element item : items) { for (Element item : items) {
notes.add(new Note() notes.add(new Note()
.setDate(dates.get(index++).text()) .setDate(getFormattedDate(dates.get(index++).text()))
.setTeacher(snp.getRowDataChildValue(item, 1)) .setTeacher(snp.getRowDataChildValue(item, 1))
.setCategory(snp.getRowDataChildValue(item, 2)) .setCategory(snp.getRowDataChildValue(item, 2))
.setContent(snp.getRowDataChildValue(item, 3)) .setContent(snp.getRowDataChildValue(item, 3))

View File

@ -11,7 +11,7 @@ public class SchoolInfo {
private static final String SCHOOL_PAGE_URL = "Szkola.mvc/Nauczyciele"; private static final String SCHOOL_PAGE_URL = "Szkola.mvc/Nauczyciele";
private SnP snp = null; private SnP snp;
public SchoolInfo(SnP snp) { public SchoolInfo(SnP snp) {
this.snp = snp; this.snp = snp;

View File

@ -15,7 +15,7 @@ public class TeachersInfo {
private static final String SCHOOL_PAGE_URL = "Szkola.mvc/Nauczyciele"; private static final String SCHOOL_PAGE_URL = "Szkola.mvc/Nauczyciele";
private SnP snp = null; private SnP snp;
public TeachersInfo(SnP snp) { public TeachersInfo(SnP snp) {
this.snp = snp; this.snp = snp;

View File

@ -3,61 +3,64 @@ package io.github.wulkanowy.api.timetable;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import io.github.wulkanowy.api.SnP; import io.github.wulkanowy.api.SnP;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.api.generic.Day;
import io.github.wulkanowy.api.generic.Lesson; import io.github.wulkanowy.api.generic.Lesson;
import io.github.wulkanowy.api.generic.Week; import io.github.wulkanowy.api.generic.Week;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getDateAsTick;
import static io.github.wulkanowy.api.DateTimeUtilsKt.getFormattedDate;
public class Timetable { public class Timetable {
private static final String TIMETABLE_PAGE_URL = "Lekcja.mvc/PlanLekcji?data="; private static final String TIMETABLE_PAGE_URL = "Lekcja.mvc/PlanZajec?data=";
private SnP snp; private SnP snp;
private static final Logger logger = LoggerFactory.getLogger(Timetable.class);
public Timetable(SnP snp) { public Timetable(SnP snp) {
this.snp = snp; this.snp = snp;
} }
public Week<Day> getWeekTable() throws IOException, ParseException, VulcanException { public Week<TimetableDay> getWeekTable() throws IOException, VulcanException {
return getWeekTable(""); return getWeekTable("");
} }
public Week<Day> getWeekTable(final String tick) throws IOException, ParseException, VulcanException { public Week<TimetableDay> getWeekTable(final String date) throws IOException, VulcanException {
Element table = snp.getSnPPageDocument(TIMETABLE_PAGE_URL + tick) Element table = snp.getSnPPageDocument(TIMETABLE_PAGE_URL + getDateAsTick(date))
.select(".mainContainer .presentData").first(); .select(".mainContainer .presentData").first();
List<Day> days = getDays(table.select("thead th")); List<TimetableDay> days = getDays(table.select("thead th"));
setLessonToDays(table, days); setLessonToDays(table, days);
return new Week<Day>() return new Week<TimetableDay>()
.setStartDayDate(days.get(0).getDate()) .setStartDayDate(days.get(0).getDate())
.setDays(days); .setDays(days);
} }
private List<Day> getDays(Elements tableHeaderCells) throws ParseException { private List<TimetableDay> getDays(Elements tableHeaderCells) {
List<Day> days = new ArrayList<>(); List<TimetableDay> days = new ArrayList<>();
int numberOfDays = tableHeaderCells.size();
for (int i = 2; i < 7; i++) { if (numberOfDays > 7) {
logger.info("Number of days: {}", numberOfDays);
}
for (int i = 2; i < numberOfDays; i++) {
String[] dayHeaderCell = tableHeaderCells.get(i).html().split("<br>"); String[] dayHeaderCell = tableHeaderCells.get(i).html().split("<br>");
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.ROOT); TimetableDay day = new TimetableDay();
Date d = sdf.parse(dayHeaderCell[1].trim());
sdf.applyPattern("yyyy-MM-dd");
Day day = new Day();
day.setDayName(dayHeaderCell[0]); day.setDayName(dayHeaderCell[0]);
day.setDate(sdf.format(d)); day.setDate(getFormattedDate(dayHeaderCell[1].trim()));
if (tableHeaderCells.get(i).hasClass("free-day")) { if (tableHeaderCells.get(i).hasClass("free-day")) {
day.setFreeDay(true); day.setFreeDay(true);
@ -70,7 +73,7 @@ public class Timetable {
return days; return days;
} }
private void setLessonToDays(Element table, List<Day> days) { private void setLessonToDays(Element table, List<TimetableDay> days) {
for (Element row : table.select("tbody tr")) { for (Element row : table.select("tbody tr")) {
Elements hours = row.select("td"); Elements hours = row.select("td");
@ -82,7 +85,7 @@ public class Timetable {
lesson.setStartTime(startEndEnd[0]); lesson.setStartTime(startEndEnd[0]);
lesson.setEndTime(startEndEnd[1]); lesson.setEndTime(startEndEnd[1]);
lesson.setDate(days.get(i - 2).getDate()); lesson.setDate(days.get(i - 2).getDate());
lesson.setNumber(hours.get(0).text()); lesson.setNumber(Integer.valueOf(hours.get(0).text()));
addLessonDetails(lesson, hours.get(i).select("div")); addLessonDetails(lesson, hours.get(i).select("div"));
@ -99,7 +102,16 @@ public class Timetable {
addLessonInfoFromElement(lesson, e.first()); addLessonInfoFromElement(lesson, e.first());
break; break;
case 2: case 2:
addLessonInfoFromElement(lesson, e.last()); 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());
} else {
addLessonInfoFromElement(lesson, e.last());
}
break; break;
case 3: case 3:
addLessonInfoFromElement(lesson, e.get(1)); addLessonInfoFromElement(lesson, e.get(1));
@ -114,7 +126,9 @@ public class Timetable {
Elements warn = e.select(".uwaga-panel"); Elements warn = e.select(".uwaga-panel");
if (!warn.isEmpty()) { 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); e.remove(1);
} }
} }
@ -122,6 +136,11 @@ public class Timetable {
private void addLessonInfoFromElement(Lesson lesson, Element e) { private void addLessonInfoFromElement(Lesson lesson, Element e) {
Elements spans = e.select("span"); Elements spans = e.select("span");
if (spans.isEmpty()) {
logger.warn("Lesson span is empty");
return;
}
addTypeInfo(lesson, spans); addTypeInfo(lesson, spans);
addNormalLessonInfo(lesson, spans); addNormalLessonInfo(lesson, spans);
addChangesInfo(lesson, spans); addChangesInfo(lesson, spans);
@ -165,7 +184,8 @@ public class Timetable {
lesson.setRoom(spans.get(5).text()); lesson.setRoom(spans.get(5).text());
lesson.setMovedOrCanceled(false); lesson.setMovedOrCanceled(false);
lesson.setNewMovedInOrChanged(true); lesson.setNewMovedInOrChanged(true);
lesson.setDescription(StringUtils.substringBetween(spans.last().text(), "(", ")") lesson.setDescription(StringUtils.defaultString(StringUtils.substringBetween(
spans.last().text(), "(", ")"), spans.last().text())
+ " (poprzednio: " + spans.get(0).text() + ")"); + " (poprzednio: " + spans.get(0).text() + ")");
} else if (9 == spans.size()) { } else if (9 == spans.size()) {
String[] subjectAndGroupInfo = getLessonAndGroupInfoFromSpan(spans.get(4)); String[] subjectAndGroupInfo = getLessonAndGroupInfoFromSpan(spans.get(4));
@ -176,13 +196,15 @@ public class Timetable {
lesson.setMovedOrCanceled(false); lesson.setMovedOrCanceled(false);
lesson.setNewMovedInOrChanged(true); lesson.setNewMovedInOrChanged(true);
lesson.setDivisionIntoGroups(true); lesson.setDivisionIntoGroups(true);
lesson.setDescription(StringUtils.substringBetween(spans.last().text(), "(", ")") lesson.setDescription(StringUtils.defaultString(StringUtils.substringBetween(
spans.last().text(), "(", ")"), spans.last().text())
+ " (poprzednio: " + getLessonAndGroupInfoFromSpan(spans.get(0))[0] + ")"); + " (poprzednio: " + getLessonAndGroupInfoFromSpan(spans.get(0))[0] + ")");
} else if (4 <= spans.size()) { } else if (4 <= spans.size()) {
lesson.setSubject(spans.get(0).text()); lesson.setSubject(spans.get(0).text());
lesson.setTeacher(spans.get(1).text()); lesson.setTeacher(spans.get(1).text());
lesson.setRoom(spans.get(2).text()); lesson.setRoom(spans.get(2).text());
lesson.setDescription(StringUtils.substringBetween(spans.last().text(), "(", ")")); lesson.setDescription(StringUtils.defaultString(StringUtils.substringBetween(
spans.last().text(), "(", ")"), spans.last().text()));
} }
} }
@ -205,12 +227,17 @@ public class Timetable {
} }
private String[] getLessonAndGroupInfoFromSpan(Element span) { private String[] getLessonAndGroupInfoFromSpan(Element span) {
if (!span.text().contains("[")) {
return new String[] {span.text(), ""};
}
String[] subjectNameArray = span.text().split(" "); String[] subjectNameArray = span.text().split(" ");
String groupName = subjectNameArray[subjectNameArray.length - 1]; String groupName = subjectNameArray[subjectNameArray.length - 1];
return new String[]{ return new String[]{
span.text().replace(" " + groupName, ""), span.text().replace(" " + groupName, ""),
StringUtils.substringBetween(groupName, "[", "]") StringUtils.defaultString(StringUtils.substringBetween(
groupName, "[", "]"), groupName)
}; };
} }
} }

View File

@ -0,0 +1,26 @@
package io.github.wulkanowy.api.timetable;
import io.github.wulkanowy.api.generic.Day;
public class TimetableDay extends Day {
private boolean isFreeDay = false;
private String freeDayName = "";
public boolean isFreeDay() {
return isFreeDay;
}
public void setFreeDay(boolean freeDay) {
isFreeDay = freeDay;
}
public String getFreeDayName() {
return freeDayName;
}
public void setFreeDayName(String freeDayName) {
this.freeDayName = freeDayName;
}
}

View File

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

View File

@ -0,0 +1,53 @@
package io.github.wulkanowy.api
import org.junit.Assert
import org.junit.Test
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
class DateTimeUtilsTest {
@Test
fun getTicksDateObjectTest() {
val format = SimpleDateFormat("dd.MM.yyyy", Locale.ROOT)
format.timeZone = TimeZone.getTimeZone("UTC")
val date = format.parse("31.07.2017")
Assert.assertEquals(636370560000000000L, getDateAsTick(date))
val calendar = Calendar.getInstance()
calendar.time = date
calendar.add(Calendar.DAY_OF_YEAR, -14)
val dateTwoWeekBefore = calendar.time
Assert.assertEquals(636358464000000000L, getDateAsTick(dateTwoWeekBefore))
}
@Test(expected = ParseException::class)
fun getTicsStringInvalidFormatTest() {
Assert.assertEquals(636370560000000000L, getDateAsTick("31.07.2017", "dd.MMM.yyyy"))
}
@Test
fun getTicsStringFormatTest() {
Assert.assertEquals(636370560000000000L, getDateAsTick("31.07.2017", "dd.MM.yyyy"))
}
@Test
fun getTicsStringTest() {
Assert.assertEquals("636370560000000000", getDateAsTick("2017-07-31"))
Assert.assertEquals("636334272000000000", getDateAsTick("2017-06-19"))
Assert.assertEquals("636189120000000000", getDateAsTick("2017-01-02"))
Assert.assertEquals("636080256000000000", getDateAsTick("2016-08-29"))
}
@Test
fun getDateTest() {
val format = SimpleDateFormat("dd.MM.yyyy", Locale.ROOT)
format.timeZone = TimeZone.getTimeZone("UTC")
val date = format.parse("31.07.2017")
Assert.assertEquals(date, getDate(636370560000000000L))
}
}

View File

@ -11,6 +11,8 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import io.github.wulkanowy.api.generic.Semester;
public class StudentAndParentTest { public class StudentAndParentTest {
private Client client; private Client client;
@ -53,7 +55,7 @@ public class StudentAndParentTest {
snp.getSnpHomePageUrl()); snp.getSnpHomePageUrl());
} }
@Test(expected = NotLoggedInErrorException.class) @Test(expected = VulcanException.class)
public void getSnpPageUrlWithWrongPage() throws Exception { public void getSnpPageUrlWithWrongPage() throws Exception {
Document wrongPageDocument = Jsoup.parse( Document wrongPageDocument = Jsoup.parse(
FixtureHelper.getAsString(getClass().getResourceAsStream("OcenyWszystkie-semester.html")) FixtureHelper.getAsString(getClass().getResourceAsStream("OcenyWszystkie-semester.html"))
@ -81,7 +83,7 @@ public class StudentAndParentTest {
snp.getExtractedIdFromUrl("https://uonetplus-opiekun.vulcan.net.pl/demoupowiat/demo12345/Start/Index/")); snp.getExtractedIdFromUrl("https://uonetplus-opiekun.vulcan.net.pl/demoupowiat/demo12345/Start/Index/"));
} }
@Test(expected = NotLoggedInErrorException.class) @Test(expected = VulcanException.class)
public void getExtractedIDNotLoggedTest() throws Exception { public void getExtractedIDNotLoggedTest() throws Exception {
Mockito.when(client.getHost()).thenReturn("vulcan.net.pl"); Mockito.when(client.getHost()).thenReturn("vulcan.net.pl");
StudentAndParent snp = new StudentAndParent(client, "symbol", null, null); StudentAndParent snp = new StudentAndParent(client, "symbol", null, null);
@ -96,12 +98,12 @@ public class StudentAndParentTest {
Assert.assertEquals(2, semesters.size()); Assert.assertEquals(2, semesters.size());
Assert.assertEquals("1", semesters.get(0).getId()); Assert.assertEquals("1", semesters.get(0).getName());
Assert.assertEquals("1234", semesters.get(0).getName()); Assert.assertEquals("1234", semesters.get(0).getId());
Assert.assertFalse(semesters.get(0).isCurrent()); Assert.assertFalse(semesters.get(0).isCurrent());
Assert.assertEquals("2", semesters.get(1).getId()); Assert.assertEquals("2", semesters.get(1).getName());
Assert.assertEquals("1235", semesters.get(1).getName()); Assert.assertEquals("1235", semesters.get(1).getId());
Assert.assertTrue(semesters.get(1).isCurrent()); Assert.assertTrue(semesters.get(1).isCurrent());
} }
@ -129,8 +131,8 @@ public class StudentAndParentTest {
@Test @Test
public void getDiariesAndStudentTest() throws IOException, VulcanException { public void getDiariesAndStudentTest() throws IOException, VulcanException {
Document snpHome = Jsoup.parse(FixtureHelper.getAsString( String input = FixtureHelper.getAsString(getClass().getResourceAsStream("WitrynaUczniaIRodzica.html"));
getClass().getResourceAsStream("StudentAndParent.html"))); Document snpHome = Jsoup.parse(input);
client = Mockito.mock(Client.class); client = Mockito.mock(Client.class);
Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(snpHome); Mockito.when(client.getPageByUrl(Mockito.anyString())).thenReturn(snpHome);
@ -150,9 +152,7 @@ public class StudentAndParentTest {
Assert.assertFalse(snp.getDiaries().get(1).isCurrent()); Assert.assertFalse(snp.getDiaries().get(1).isCurrent());
Assert.assertFalse(snp.getDiaries().get(2).isCurrent()); Assert.assertFalse(snp.getDiaries().get(2).isCurrent());
Assert.assertEquals("100", snp.getDiaries().get(0).getStudentId());
Assert.assertEquals("Jan Kowal", snp.getStudents().get(0).getName()); Assert.assertEquals("Jan Kowal", snp.getStudents().get(0).getName());
Assert.assertEquals("100", snp.getStudents().get(0).getStudentId()); Assert.assertEquals("100", snp.getStudents().get(0).getId());
} }
} }

View File

@ -5,6 +5,8 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.mockito.Mockito; import org.mockito.Mockito;
import io.github.wulkanowy.api.generic.Semester;
public abstract class StudentAndParentTestCase { public abstract class StudentAndParentTestCase {
protected StudentAndParent getSnp(String fixtureFileName) throws Exception { protected StudentAndParent getSnp(String fixtureFileName) throws Exception {

View File

@ -12,20 +12,25 @@ public class ExamsWeekTest extends StudentAndParentTestCase {
private ExamsWeek onePerDay; private ExamsWeek onePerDay;
private ExamsWeek empty;
@Before @Before
public void getCurrent() throws Exception { public void getCurrent() throws Exception {
onePerDay = new ExamsWeek(getSnp("Sprawdziany-one-per-day.html")); onePerDay = new ExamsWeek(getSnp("Sprawdziany-one-per-day.html"));
empty = new ExamsWeek(getSnp("Sprawdziany-empty.html"));
} }
@Test @Test
public void getWeekTest() throws Exception { public void getWeekTest() throws Exception {
Assert.assertEquals("23.10.2017", onePerDay.getCurrent().getStartDayDate()); Assert.assertEquals("2017-10-23", onePerDay.getCurrent().getStartDayDate());
Assert.assertEquals("2018-04-30", empty.getCurrent().getStartDayDate());
} }
@Test @Test
public void getDaysListTest() throws Exception { public void getDaysListTest() throws Exception {
Assert.assertEquals(3, onePerDay.getCurrent().getDays().size()); Assert.assertEquals(3, onePerDay.getCurrent().getDays().size());
Assert.assertEquals(7, onePerDay.getWeek("", false).getDays().size()); Assert.assertEquals(7, onePerDay.getWeek("", false).getDays().size());
Assert.assertEquals(0, empty.getCurrent().getDays().size());
} }
@Test @Test
@ -45,9 +50,18 @@ public class ExamsWeekTest extends StudentAndParentTestCase {
public void getDayDateTest() throws Exception { public void getDayDateTest() throws Exception {
List<ExamDay> dayList = onePerDay.getCurrent().getDays(); List<ExamDay> dayList = onePerDay.getCurrent().getDays();
Assert.assertEquals("23.10.2017", dayList.get(0).getDate()); Assert.assertEquals("2017-10-23", dayList.get(0).getDate());
Assert.assertEquals("24.10.2017", dayList.get(1).getDate()); Assert.assertEquals("2017-10-24", dayList.get(1).getDate());
Assert.assertEquals("27.10.2017", dayList.get(2).getDate()); Assert.assertEquals("2017-10-27", dayList.get(2).getDate());
}
@Test
public void getDayNameTest() throws Exception {
List<ExamDay> dayList = onePerDay.getCurrent().getDays();
Assert.assertEquals("Poniedziałek", dayList.get(0).getDayName());
Assert.assertEquals("Wtorek", dayList.get(1).getDayName());
Assert.assertEquals("Piątek", dayList.get(2).getDayName());
} }
@Test @Test
@ -90,8 +104,8 @@ public class ExamsWeekTest extends StudentAndParentTestCase {
public void getExamEntryDateTest() throws Exception { public void getExamEntryDateTest() throws Exception {
List<ExamDay> dayList = onePerDay.getCurrent().getDays(); List<ExamDay> dayList = onePerDay.getCurrent().getDays();
Assert.assertEquals("16.10.2017", dayList.get(0).getExamList().get(0).getEntryDate()); Assert.assertEquals("2017-10-16", dayList.get(0).getExamList().get(0).getEntryDate());
Assert.assertEquals("17.10.2017", dayList.get(1).getExamList().get(0).getEntryDate()); Assert.assertEquals("2017-10-17", dayList.get(1).getExamList().get(0).getEntryDate());
Assert.assertEquals("16.10.2017", dayList.get(2).getExamList().get(0).getEntryDate()); Assert.assertEquals("2017-10-16", dayList.get(2).getExamList().get(0).getEntryDate());
} }
} }

View File

@ -19,12 +19,12 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test @Test
public void getAllTest() throws Exception { public void getAllTest() throws Exception {
Assert.assertEquals(6, filled.getAll().size()); // 2 items are skipped Assert.assertEquals(7, filled.getAll("").size()); // 2 items are skipped
} }
@Test @Test
public void getSubjectTest() throws Exception { public void getSubjectTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("Zajęcia z wychowawcą", list.get(0).getSubject()); Assert.assertEquals("Zajęcia z wychowawcą", list.get(0).getSubject());
Assert.assertEquals("Język angielski", list.get(3).getSubject()); Assert.assertEquals("Język angielski", list.get(3).getSubject());
@ -34,7 +34,7 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test @Test
public void getValueTest() throws Exception { public void getValueTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("5", list.get(0).getValue()); Assert.assertEquals("5", list.get(0).getValue());
Assert.assertEquals("5", list.get(3).getValue()); Assert.assertEquals("5", list.get(3).getValue());
@ -44,7 +44,7 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test @Test
public void getColorTest() throws Exception { public void getColorTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("000000", list.get(0).getColor()); Assert.assertEquals("000000", list.get(0).getColor());
Assert.assertEquals("1289F7", list.get(3).getColor()); Assert.assertEquals("1289F7", list.get(3).getColor());
@ -54,27 +54,29 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test @Test
public void getSymbolTest() throws Exception { public void getSymbolTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("A1", list.get(0).getSymbol()); Assert.assertEquals("A1", list.get(0).getSymbol());
Assert.assertEquals("BW3", list.get(3).getSymbol()); Assert.assertEquals("BW3", list.get(3).getSymbol());
Assert.assertEquals("STR", list.get(4).getSymbol()); Assert.assertEquals("STR", list.get(4).getSymbol());
Assert.assertEquals("K", list.get(5).getSymbol()); Assert.assertEquals("K", list.get(5).getSymbol());
Assert.assertEquals("+Odp", list.get(6).getSymbol());
} }
@Test @Test
public void getDescriptionTest() throws Exception { public void getDescriptionTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("Dzień Kobiet w naszej klasie", list.get(0).getDescription()); Assert.assertEquals("Dzień Kobiet w naszej klasie", list.get(0).getDescription());
Assert.assertEquals("Writing", list.get(3).getDescription()); Assert.assertEquals("Writing", list.get(3).getDescription());
Assert.assertEquals("", list.get(4).getDescription()); Assert.assertEquals("", list.get(4).getDescription());
Assert.assertEquals("Kordian", list.get(5).getDescription()); Assert.assertEquals("Kordian", list.get(5).getDescription());
Assert.assertEquals("Kordian", list.get(6).getDescription());
} }
@Test @Test
public void getWeightTest() throws Exception { public void getWeightTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("1,00", list.get(0).getWeight()); Assert.assertEquals("1,00", list.get(0).getWeight());
Assert.assertEquals("3,00", list.get(3).getWeight()); Assert.assertEquals("3,00", list.get(3).getWeight());
@ -84,7 +86,7 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test @Test
public void getDateTest() throws Exception { public void getDateTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("2017-03-21", list.get(0).getDate()); Assert.assertEquals("2017-03-21", list.get(0).getDate());
Assert.assertEquals("2017-06-02", list.get(3).getDate()); Assert.assertEquals("2017-06-02", list.get(3).getDate());
@ -94,21 +96,11 @@ public class GradesListTest extends StudentAndParentTestCase {
@Test @Test
public void getTeacherTest() throws Exception { public void getTeacherTest() throws Exception {
List<Grade> list = filled.getAll(); List<Grade> list = filled.getAll("");
Assert.assertEquals("Patryk Maciejewski", list.get(0).getTeacher()); Assert.assertEquals("Patryk Maciejewski", list.get(0).getTeacher());
Assert.assertEquals("Oliwia Woźniak", list.get(3).getTeacher()); Assert.assertEquals("Oliwia Woźniak", list.get(3).getTeacher());
Assert.assertEquals("Klaudia Dziedzic", list.get(4).getTeacher()); Assert.assertEquals("Klaudia Dziedzic", list.get(4).getTeacher());
Assert.assertEquals("Amelia Stępień", list.get(5).getTeacher()); Assert.assertEquals("Amelia Stępień", list.get(5).getTeacher());
} }
@Test
public void getSemesterTest() throws Exception {
List<Grade> list = filled.getAll();
Assert.assertEquals("7654321", list.get(0).getSemester());
Assert.assertEquals("7654321", list.get(3).getSemester());
Assert.assertEquals("7654321", list.get(4).getSemester());
Assert.assertEquals("7654321", list.get(5).getSemester());
}
} }

View File

@ -24,6 +24,7 @@ public class LoginTest {
Client client = Mockito.mock(Client.class); Client client = Mockito.mock(Client.class);
Mockito.when(client.postPageByUrl(Mockito.anyString(), Mockito.any(String[][].class))).thenReturn(doc); Mockito.when(client.postPageByUrl(Mockito.anyString(), Mockito.any(String[][].class))).thenReturn(doc);
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean())).thenReturn(doc);
return client; return client;
} }
@ -33,6 +34,10 @@ public class LoginTest {
Client client = getClient("Logowanie-success.html"); Client client = getClient("Logowanie-success.html");
Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean())) Mockito.when(client.getPageByUrl(Mockito.anyString(), Mockito.anyBoolean()))
.thenReturn(getFixtureAsDocument("Logowanie-error.html")); .thenReturn(getFixtureAsDocument("Logowanie-error.html"));
Mockito.when(client.postPageByUrl(Mockito.eq(Login.LOGIN_PAGE_URL), Mockito.any(String[][].class)))
.thenReturn(getFixtureAsDocument("Logowanie-certyfikat.html"));
Mockito.doCallRealMethod().when(client).setSymbol(Mockito.anyString());
Mockito.when(client.getSymbol()).thenCallRealMethod();
Login login = new Login(client); Login login = new Login(client);
Assert.assertEquals("d123", login.login("a@a", "pswd", "d123")); Assert.assertEquals("d123", login.login("a@a", "pswd", "d123"));
@ -56,24 +61,31 @@ public class LoginTest {
Login login = new Login(client); Login login = new Login(client);
Assert.assertEquals( Assert.assertEquals(
getFixtureAsString("cert.xml").replaceAll("\\s+",""), getFixtureAsString("cert-stock.xml").replaceAll("\\s+", ""),
login.sendCredentials("a@a", "passwd") login.sendCredentials("a@a", "passwd")
.select("input[name=wresult]").attr("value") .select("input[name=wresult]")
.replaceAll("\\s+","") .attr("value")
.replaceAll("\\s+", "")
); );
} }
@Test @Test
public void sendCertificateNotDefaultSymbolSuccessTest() throws Exception { public void sendCertificateNotDefaultSymbolSuccessTest() throws Exception {
Login login = new Login(getClient("Logowanie-success.html")); Client client = getClient("Logowanie-success.html");
Mockito.doCallRealMethod().when(client).setSymbol(Mockito.anyString());
Mockito.when(client.getSymbol()).thenCallRealMethod();
Login login = new Login(client);
Assert.assertEquals("wulkanowyschool321", Assert.assertEquals("wulkanowyschool321", login.sendCertificate(
login.sendCertificate(new Document(""), "wulkanowyschool321")); getFixtureAsDocument("Logowanie-certyfikat.html"), "wulkanowyschool321"));
} }
@Test @Test
public void sendCertificateDefaultSymbolSuccessTest() throws Exception { public void sendCertificateDefaultSymbolSuccessTest() throws Exception {
Login login = new Login(getClient("Logowanie-success.html")); Client client = getClient("Logowanie-success.html");
Mockito.doCallRealMethod().when(client).setSymbol(Mockito.anyString());
Mockito.when(client.getSymbol()).thenCallRealMethod();
Login login = new Login(client);
Assert.assertEquals("demo12345", Assert.assertEquals("demo12345",
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default")); login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "Default"));
@ -81,31 +93,33 @@ public class LoginTest {
@Test(expected = AccountPermissionException.class) @Test(expected = AccountPermissionException.class)
public void sendCertificateAccountPermissionTest() throws Exception { public void sendCertificateAccountPermissionTest() throws Exception {
Login login = new Login(getClient("Logowanie-brak-dostepu.html")); Client client = getClient("Logowanie-brak-dostepu.html");
login.sendCertificate(getFixtureAsDocument("cert.xml"), "demo123"); Login login = new Login(client);
login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "demo123");
} }
@Test(expected = LoginErrorException.class) @Test(expected = LoginErrorException.class)
public void sendCertificateLoginErrorTest() throws Exception { public void sendCertificateLoginErrorTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html")); // change to other document Login login = new Login(getClient("Logowanie-certyfikat.html")); // change to other document
login.sendCertificate(getFixtureAsDocument("cert.xml"), "demo123"); login.sendCertificate(getFixtureAsDocument("Logowanie-certyfikat.html"), "demo123");
} }
@Test @Test
public void findSymbolInCertificateTest() throws Exception { public void findSymbolInCertificateTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html")); Login login = new Login(getClient("Logowanie-certyfikat.html"));
String certificate = getFixtureAsString("cert.xml"); String certificate = getFixtureAsString("cert-stock.xml");
Assert.assertEquals("demo12345", login.findSymbolInCertificate(certificate)); Assert.assertEquals("demo12345", login.findSymbolInCertificate(certificate));
} }
@Test @Test(expected = AccountPermissionException.class)
public void findSymbolInInvalidCertificateTest() throws Exception { public void findSymbolInCertificateWithoutSecondInstanceTest() throws Exception {
Login login = new Login(getClient("Logowanie-certyfikat.html")); Login login = new Login(getClient("Logowanie-certyfikat.html"));
Assert.assertEquals("", login.findSymbolInCertificate("<xml></xml>")); // change to real cert with empty symbols login.findSymbolInCertificate(getFixtureAsString("cert-no-symbols.xml"));
} }
} }

View File

@ -0,0 +1,17 @@
package io.github.wulkanowy.api.mobile
import io.github.wulkanowy.api.StudentAndParentTestCase
import org.junit.Assert.assertEquals
import org.junit.Test
class RegisterDeviceTest : StudentAndParentTestCase() {
@Test
fun getTokenTest() {
val registration = RegisterDevice(getSnp("Rejestruj.html"))
assertEquals("3S1A1B2C", registration.getToken().token)
assertEquals("Default", registration.getToken().symbol)
assertEquals("1234567", registration.getToken().pin)
}
}

View File

@ -0,0 +1,37 @@
package io.github.wulkanowy.api.mobile
import io.github.wulkanowy.api.StudentAndParentTestCase
import org.junit.Assert.assertEquals
import org.junit.Test
class RegisteredDevicesListTest : StudentAndParentTestCase() {
private val filled = RegisteredDevices(getSnp("DostepMobilny-filled.html"))
@Test
fun getListTest() {
assertEquals(2, filled.getList().size)
}
@Test
fun getNameTest() {
assertEquals("google Android SDK built for x86", filled.getList()[0].name)
assertEquals("google (Android SDK) built for x86", filled.getList()[1].name)
}
@Test
fun getSystemTest() {
assertEquals("Android 8.1.0", filled.getList()[0].system)
assertEquals("Android 8.1.0", filled.getList()[1].system)
}
@Test
fun getDateTest() {
assertEquals("2018-01-20 22:35:30", filled.getList()[0].date)
}
@Test
fun getIdTest() {
assertEquals(321, filled.getList()[0].id)
}
}

View File

@ -30,8 +30,8 @@ public class NotesListTest extends StudentAndParentTestCase {
public void getDateTest() throws Exception { public void getDateTest() throws Exception {
List<Note> filledList = filled.getAllNotes(); List<Note> filledList = filled.getAllNotes();
Assert.assertEquals("06.06.2017", filledList.get(0).getDate()); Assert.assertEquals("2017-06-06", filledList.get(0).getDate());
Assert.assertEquals("01.10.2016", filledList.get(2).getDate()); Assert.assertEquals("2016-10-01", filledList.get(2).getDate());
} }
@Test @Test

View File

@ -83,11 +83,11 @@ public class TimetableTest extends StudentAndParentTestCase {
@Test @Test
public void getLessonNumberTest() throws Exception { public void getLessonNumberTest() throws Exception {
Assert.assertEquals("2", std.getWeekTable().getDay(0).getLesson(1).getNumber()); Assert.assertEquals(2, std.getWeekTable().getDay(0).getLesson(1).getNumber());
Assert.assertEquals("5", std.getWeekTable().getDay(2).getLesson(4).getNumber()); Assert.assertEquals(5, std.getWeekTable().getDay(2).getLesson(4).getNumber());
Assert.assertEquals("0", full.getWeekTable().getDay(0).getLesson(0).getNumber()); Assert.assertEquals(0, full.getWeekTable().getDay(0).getLesson(0).getNumber());
Assert.assertEquals("13", full.getWeekTable().getDay(4).getLesson(13).getNumber()); Assert.assertEquals(13, full.getWeekTable().getDay(4).getLesson(13).getNumber());
Assert.assertEquals("3", holidays.getWeekTable().getDay(3).getLesson(3).getNumber()); Assert.assertEquals(3, holidays.getWeekTable().getDay(3).getLesson(3).getNumber());
} }
@Test @Test
@ -105,11 +105,13 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertEquals("Zajęcia techniczne", std.getWeekTable().getDay(2).getLesson(4).getSubject()); 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("Wychowanie fizyczne", std.getWeekTable().getDay(1).getLesson(1).getSubject());
Assert.assertEquals("Język angielski", full.getWeekTable().getDay(0).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 do życia w rodzinie", full.getWeekTable().getDay(2).getLesson(0).getSubject());
Assert.assertEquals("Wychowanie fizyczne", full.getWeekTable().getDay(3).getLesson(1).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()); Assert.assertEquals("Uroczyste zakończenie roku szkolnego", full.getWeekTable().getDay(4).getLesson(0).getSubject());
Assert.assertEquals("Fizyka", full.getWeekTable().getDay(0).getLesson(0).getSubject()); Assert.assertEquals("Fizyka", full.getWeekTable().getDay(0).getLesson(0).getSubject());
Assert.assertEquals("Metodologia programowania", full.getWeekTable().getDay(1).getLesson(0).getSubject()); Assert.assertEquals("Metodologia programowania", full.getWeekTable().getDay(1).getLesson(0).getSubject());
Assert.assertEquals("Język niemiecki", full.getWeekTable().getDay(4).getLesson(2).getSubject());
Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getSubject()); Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getSubject());
} }
@ -122,6 +124,7 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertEquals("Nowak Jadwiga", full.getWeekTable().getDay(2).getLesson(0).getTeacher()); Assert.assertEquals("Nowak Jadwiga", full.getWeekTable().getDay(2).getLesson(0).getTeacher());
Assert.assertEquals("Nowicka Irena", full.getWeekTable().getDay(3).getLesson(1).getTeacher()); Assert.assertEquals("Nowicka Irena", full.getWeekTable().getDay(3).getLesson(1).getTeacher());
Assert.assertEquals("Baran Małgorzata", full.getWeekTable().getDay(4).getLesson(0).getTeacher()); Assert.assertEquals("Baran Małgorzata", full.getWeekTable().getDay(4).getLesson(0).getTeacher());
Assert.assertEquals("", full.getWeekTable().getDay(4).getLesson(1).getTeacher());
Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getTeacher()); Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getTeacher());
} }
@ -148,7 +151,13 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertEquals("zastępstwo (poprzednio: Religia)", full.getWeekTable().getDay(2).getLesson(0).getDescription()); Assert.assertEquals("zastępstwo (poprzednio: Religia)", full.getWeekTable().getDay(2).getLesson(0).getDescription());
Assert.assertEquals("zastępstwo (poprzednio: Wychowanie fizyczne)", full.getWeekTable().getDay(3).getLesson(1).getDescription()); Assert.assertEquals("zastępstwo (poprzednio: Wychowanie fizyczne)", full.getWeekTable().getDay(3).getLesson(1).getDescription());
Assert.assertEquals("", full.getWeekTable().getDay(4).getLesson(0).getDescription()); Assert.assertEquals("", full.getWeekTable().getDay(4).getLesson(0).getDescription());
Assert.assertEquals("", full.getWeekTable().getDay(4).getLesson(1).getDescription());
Assert.assertEquals("bez nawiasów (poprzednio: Religia)", full.getWeekTable().getDay(4).getLesson(3).getDescription());
Assert.assertEquals("poprzednio: Wychowanie fizyczne", full.getWeekTable().getDay(4).getLesson(2).getDescription());
Assert.assertEquals("egzamin", full.getWeekTable().getDay(3).getLesson(0).getDescription()); Assert.assertEquals("egzamin", full.getWeekTable().getDay(3).getLesson(0).getDescription());
Assert.assertEquals("", full.getWeekTable().getDay(4).getLesson(1).getDescription());
Assert.assertEquals("poprzednio: Zajęcia z wychowawcą", full.getWeekTable().getDay(4).getLesson(5).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()); Assert.assertEquals("", holidays.getWeekTable().getDay(3).getLesson(3).getDescription());
} }
@ -237,6 +246,8 @@ public class TimetableTest extends StudentAndParentTestCase {
Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(2).isNewMovedInOrChanged()); Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(2).isNewMovedInOrChanged());
Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(3).isNewMovedInOrChanged()); Assert.assertTrue(full.getWeekTable().getDay(1).getLesson(3).isNewMovedInOrChanged());
Assert.assertTrue(full.getWeekTable().getDay(3).getLesson(1).isNewMovedInOrChanged()); Assert.assertTrue(full.getWeekTable().getDay(3).getLesson(1).isNewMovedInOrChanged());
Assert.assertFalse(full.getWeekTable().getDay(4).getLesson(1).isNewMovedInOrChanged());
Assert.assertTrue(full.getWeekTable().getDay(4).getLesson(2).isNewMovedInOrChanged());
Assert.assertFalse(holidays.getWeekTable().getDay(3).getLesson(3).isNewMovedInOrChanged()); Assert.assertFalse(holidays.getWeekTable().getDay(3).getLesson(3).isNewMovedInOrChanged());
} }
} }

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica Terminarz sprawdzian&#243;w</title>
</head>
<body>
<main class="mainContainer">
<h1>Sprawdziany</h1>
<h2>Tydzień 30.04.2018 - 06.05.2018</h2>
<h2>Nie zaplanowano żadnych sprawdzian&#243;w na wybrany tydzień</h2>
<div class="navigation">
<a href="/symbol/123456/Sprawdziany.mvc/Terminarz?data=636600384000000000&amp;rokSzkolny=2017&amp;rodzajWidoku=2" class="button-prev">Poprzedni tydzień</a>
<a href="/symbol/123456/Sprawdziany.mvc/Terminarz?data=636612480000000000&amp;rokSzkolny=2017&amp;rodzajWidoku=2" class="button-next">Następny tydzień</a>
</div>
</main>
<footer>wersja: 17.09.0009.26859</footer>
</body>
</html>

View File

@ -100,6 +100,14 @@
<td>06.02.2017</td> <td>06.02.2017</td>
<td>Amelia Stępień</td> <td>Amelia Stępień</td>
</tr> </tr>
<tr>
<td>Język polski</td>
<td class="break-word"><span class="ocenaCzastkowa" style="color:#6ECD07;">5</span></td>
<td class="break-word">+Odp, Kordian</td>
<td>5,00</td>
<td>11.05.2017</td>
<td>Amelia Stępień</td>
</tr>
</tbody> </tbody>
</table> </table>
</main> </main>

View File

@ -3,10 +3,10 @@
<title>Working...</title> <title>Working...</title>
</head> </head>
<body> <body>
<form method="POST" name="hiddenform" action="https://fake-log.com/Default/LoginEndpoint.aspx"> <form method="POST" name="hiddenform" action="https://fakelog.cf/Default/LoginEndpoint.aspx">
<input type="hidden" name="wa" value="wsignin1.0"> <input type="hidden" name="wa" value="wsignin1.0">
<input type="hidden" name="wresult" value="<trust:RequestSecurityTokenResponseCollection xmlns:trust=&quot;http://docs.oasis-open.org/ws-sx/ws-trust/200512&quot;><trust:RequestSecurityTokenResponse Context=&quot;https://uonetplus.fake-log.com/Default/LoginEndpoint.aspx&quot;><trust:RequestedSecurityToken><saml:Assertion AssertionID=&quot;_12345678-1234-1234-1234-1234567890ab&quot; IssueInstant=&quot;2017-10-18T22:00:29.006Z&quot; Issuer=&quot;CUFSTokenService&quot; MajorVersion=&quot;1&quot; MinorVersion=&quot;1&quot; xmlns:saml=&quot;urn:oasis:names:tc:SAML:1.0:assertion&quot;><saml:AttributeStatement><saml:Attribute AttributeName=&quot;UserInstance&quot; AttributeNamespace=&quot;http://schemas.fake-log.com/ws/identity/claims&quot;><saml:AttributeValue>Default</saml:AttributeValue><saml:AttributeValue>demo12345</saml:AttributeValue><saml:AttributeValue>incorrect value</saml:AttributeValue><saml:AttributeValue>warszawa</saml:AttributeValue><saml:AttributeValue>asdf</saml:AttributeValue><saml:AttributeValue>asdfsdf</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></trust:RequestedSecurityToken></trust:RequestSecurityTokenResponse></trust:RequestSecurityTokenResponseCollection>"> <input type="hidden" name="wresult" value="<trust:RequestSecurityTokenResponseCollection xmlns:trust=&quot;http://docs.oasis-open.org/ws-sx/ws-trust/200512&quot;><trust:RequestSecurityTokenResponse Context=&quot;https://uonetplus.fakelog.cf/Default/LoginEndpoint.aspx&quot;><trust:RequestedSecurityToken><saml:Assertion AssertionID=&quot;_12345678-1234-1234-1234-1234567890ab&quot; IssueInstant=&quot;2017-10-18T22:00:29.006Z&quot; Issuer=&quot;CUFSTokenService&quot; MajorVersion=&quot;1&quot; MinorVersion=&quot;1&quot; xmlns:saml=&quot;urn:oasis:names:tc:SAML:1.0:assertion&quot;><saml:AttributeStatement><saml:Attribute AttributeName=&quot;UserInstance&quot; AttributeNamespace=&quot;http://schemas.fakelog.cf/ws/identity/claims&quot;><saml:AttributeValue>Default</saml:AttributeValue><saml:AttributeValue>demo12345</saml:AttributeValue><saml:AttributeValue>incorrect value</saml:AttributeValue><saml:AttributeValue>warszawa</saml:AttributeValue><saml:AttributeValue>asdf</saml:AttributeValue><saml:AttributeValue>asdfsdf</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></trust:RequestedSecurityToken></trust:RequestSecurityTokenResponse></trust:RequestSecurityTokenResponseCollection>">
<input type="hidden" name="wctx" value="https://fake-log.com/Default/LoginEndpoint.aspx"> <input type="hidden" name="wctx" value="https://fakelog.cf/Default/LoginEndpoint.aspx">
<noscript> <noscript>
<p>Script is disabled. Click Submit to continue.</p> <p>Script is disabled. Click Submit to continue.</p>
<input type="submit" value="Submit"> <input type="submit" value="Submit">

View File

@ -6,6 +6,9 @@
<body> <body>
<div id="MainDiv"> <div id="MainDiv">
<form> <form>
<div class="LogOnBoard">
<h1 id="h1Default">Logowanie</h1>
</div>
<div class="ErrorMessage center"> <div class="ErrorMessage center">
Zła nazwa użytkownika lub hasło Zła nazwa użytkownika lub hasło
</div> </div>

View File

@ -0,0 +1,13 @@
<trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:RequestSecurityTokenResponse Context="https://uonetplus.fakelog.cf/Default/LoginEndpoint.aspx">
<trust:RequestedSecurityToken>
<saml:Assertion AssertionID="_12345678-1234-1234-1234-1234567890ab" IssueInstant="2017-10-18T22:00:29.006Z" Issuer="CUFSTokenService" MajorVersion="1" MinorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:AttributeStatement>
<saml:Attribute AttributeName="UserInstance" AttributeNamespace="http://schemas.fakelog.cf/ws/identity/claims">
<saml:AttributeValue>Default</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</trust:RequestedSecurityToken>
</trust:RequestSecurityTokenResponse>
</trust:RequestSecurityTokenResponseCollection>

View File

@ -1,9 +1,9 @@
<trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> <trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:RequestSecurityTokenResponse Context="https://uonetplus.fake-log.com/Default/LoginEndpoint.aspx"> <trust:RequestSecurityTokenResponse Context="https://uonetplus.fakelog.cf/Default/LoginEndpoint.aspx">
<trust:RequestedSecurityToken> <trust:RequestedSecurityToken>
<saml:Assertion AssertionID="_12345678-1234-1234-1234-1234567890ab" IssueInstant="2017-10-18T22:00:29.006Z" Issuer="CUFSTokenService" MajorVersion="1" MinorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> <saml:Assertion AssertionID="_12345678-1234-1234-1234-1234567890ab" IssueInstant="2017-10-18T22:00:29.006Z" Issuer="CUFSTokenService" MajorVersion="1" MinorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:AttributeStatement> <saml:AttributeStatement>
<saml:Attribute AttributeName="UserInstance" AttributeNamespace="http://schemas.fake-log.com/ws/identity/claims"> <saml:Attribute AttributeName="UserInstance" AttributeNamespace="http://schemas.fakelog.cf/ws/identity/claims">
<saml:AttributeValue>Default</saml:AttributeValue> <saml:AttributeValue>Default</saml:AttributeValue>
<saml:AttributeValue>demo12345</saml:AttributeValue> <saml:AttributeValue>demo12345</saml:AttributeValue>
<saml:AttributeValue>incorrect value</saml:AttributeValue> <saml:AttributeValue>incorrect value</saml:AttributeValue>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica dostęp mobilny</title>
</head>
<body>
<main class="mainContainer">
<h1>Dostęp mobilny</h1>
<article>
<h2>Zarejestrowane urządzenia</h2>
</article>
<table>
<thead>
<tr>
<th>Urządzenie</th>
<th>Data rejestracji</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>google Android SDK built for x86 (Android 8.1.0)</td>
<td>20.01.2018 godz: 22:35:30</td>
<td class="cellWithButton">
<a href="/Default/123456/DostepMobilny.mvc/Wyrejestruj/321" class="button">Wyrejestruj</a>
</td>
</tr>
<tr class="text-center">
<td>google (Android SDK) built for x86 (Android 8.1.0)</td>
<td>20.01.2018 godz: 22:35:30</td>
<td class="cellWithButton">
<a href="/Default/123456/DostepMobilny.mvc/Wyrejestruj/213" class="button">Wyrejestruj</a>
</td>
</tr>
</tbody>
</table>
</main>
<footer>wersja: 18.01.0001.27311</footer>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>Witryna ucznia i rodzica Rejestracja urządzenia mobilnego</title>
<style>
.blockElement {
display: block;
}
</style>
</head>
<body>
<main class="mainContainer">
<h1>Rejestracja urządzenia mobilnego</h1>
<article class="text-center" id="rejestracja-formularz">
<span class="blockElement">Za pomocą aplikacji &quot;Dzienniczek+&quot; zeskanuj kod QR.</span>
<img src=" data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gUdCTohm9rlswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAFKklEQVR42u3dYYqDQAyA0abk/lfO/l+6LLZYksx7J3C09SPgaFRVPQDgoqdTAICAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAACAgAAgIAAICAFdltwOKiNUnvKqOXj/4/9y3fhMIACMICAACAoCAACAgAAgIAAgIAJ/IaQfc7Tno3+5+Dr37+sH/p+/6TSAACAgAAgKAgACAgAAgIAAICADj5bYF2YcBuH+YQAAQEAAEBAAEBAABAUBAABAQAAQEAAQEAAEBQEAAEBAABAQABAQAAQFAQAAQEAAEBAAEBAABAUBAABAQAAQEAP6R2xZUVa4q4P5hAgFAQAAQEAAQEAAEBAABAUBAANho3D6QiHDVAPcPEwgAAgKAgACAgAAgIAAICAACAsCJ2u0D8T5+wP3DBAKAgACAgAAgIAAICAACAoCAAMBL7faBeF8/4P7wWrd9LiYQAAQEAAEBQEAAEBAAEBAABASAr8tpB+x9/7DX6f/vaftcTCAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIA4BQAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAICAAICAACAgAAgKAgAAgIAAgIAAICAACAoCAACAgACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAoCAAICAACAgAAgIAAICgIAAgIAAICAACAgAAgKAgACAgAAgIAAICAACAgACAoCAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAACAgAAgIAAICAAICgIAAICAACAgAAgIAAgKAgAAgIAAICAACAgACAoCAANBWTjvgiDj6glWVXy1gAgFAQAAQEAAQEAAEBAABAUBAuOb0x5CBPdrtAzl9n4PAACYQAAQEAAQEAAEBQEAAEBAABAQA/tBuH8j2fRC+5wGYQAAQEAAQEAAEBAABAUBAAEBAAHhTTjvg7vsofM8DMIEAgIAAICAACAgAAgKAgACAgABwk9y2oLv3YfieB4AJBAABAUBAABAQAAQEAAQEAAEBQEAAEBAABAQABAQAAQFAQAAQEAAEBAAEBAABAUBAABAQAAQEAAQEAAEBQEAAGC+3LaiqXFUAEwgAAgKAgACAgAAgIAAICAACAsBG4/aBRMTRF+z09QMmEAAEBAABAQABAUBAABAQAAQEgINF+YAGACYQAAQEAAEBQEAAQEAAEBAABAQAAQFAQABAQAAQEAAEBAABAUBAAEBAABAQAAQEAAEBQEAAQEAAEBAABAQAAQFAQABAQAAQEAAEBAABAUBAAEBAABAQAAQEAAEBQEAAQEAA+IYf8fZKNX0RrMQAAAAASUVORK5CYII="
alt="Kod QR" title="Kod QR" height="400" width="400"/>
<span class="blockElement">Token: 3S1A1B2C</span>
<span class="blockElement">Symbol: Default</span>
<span class="blockElement">PIN: 1234567</span>
</article>
</main>
<footer>wersja: 18.01.0001.27311</footer>
</body>
</html>

View File

@ -3,6 +3,40 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Witryna ucznia i rodzica Plan lekcji</title> <title>Witryna ucznia i rodzica Plan lekcji</title>
<style>
table, th, td {
border: 1px solid;
border-collapse: collapse;
}
table td > div:not(:last-child) {
border-bottom: 5px solid silver;
padding-bottom: 5px;
margin-bottom: 5px;
}
table td div span:nth-child(1) {
display: block;
}
table span {
font-size: smaller;
}
.x-treelabel-ppl {
background: #99f;
font-style: italic;
}
.x-treelabel-rlz {
background: #f3a;
}
.x-treelabel-inv {
background: #f00;
}
.x-treelabel-zas {
background: #0f0;
}
table span:not([class]),
table span[class=""] {
background: #999;
}
</style>
</head> </head>
<body> <body>
<main class="mainContainer"> <main class="mainContainer">
@ -82,13 +116,6 @@
</div> </div>
</td> </td>
<td> <td>
<div>
<span class="x-treelabel-ppl x-treelabel-inv">Metodologia programowania [zaw2]</span>
<span class="x-treelabel-ppl x-treelabel-inv"></span>
<span class="x-treelabel-ppl x-treelabel-inv">Baran Małgorzata</span>
<span class="x-treelabel-ppl x-treelabel-inv">36</span>
<span class="x-treelabel-rlz">(zmiana organizacji zajęć)</span>
</div>
<div> <div>
<span class="x-treelabel-ppl x-treelabel-zas">Wychowanie fizyczne [zaw2]</span> <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>
@ -96,6 +123,13 @@
<span class="x-treelabel-ppl x-treelabel-zas">G3</span> <span class="x-treelabel-ppl x-treelabel-zas">G3</span>
<span class="x-treelabel-rlz">(przeniesiona z lekcji 7, 01.12.2017)</span> <span class="x-treelabel-rlz">(przeniesiona z lekcji 7, 01.12.2017)</span>
</div> </div>
<div>
<span class="x-treelabel-ppl x-treelabel-inv">Metodologia programowania [zaw2]</span>
<span class="x-treelabel-ppl x-treelabel-inv"></span>
<span class="x-treelabel-ppl x-treelabel-inv">Baran Małgorzata</span>
<span class="x-treelabel-ppl x-treelabel-inv">36</span>
<span class="x-treelabel-rlz">(zmiana organizacji zajęć)</span>
</div>
</td> </td>
<td> <td>
<div> <div>
@ -118,7 +152,18 @@
<span class="x-treelabel-rlz">(zastępstwo)</span> <span class="x-treelabel-rlz">(zastępstwo)</span>
</div> </div>
</td> </td>
<td></td> <td>
<div>
<span class="">Uroczyste rozpoczecie roku szkolnego 2017/2018</span>
<span class=""></span>
<span class=""></span>
</div>
<div>
<span class="x-treelabel-ppl">Uroczyste rozpoczecie roku szkolnego 2017/2018</span>
<span class="x-treelabel-ppl"></span>
<span class="x-treelabel-ppl"></span>
</div>
</td>
</tr> </tr>
<tr> <tr>
<td>2</td> <td>2</td>
@ -165,7 +210,20 @@
<span></span> <span></span>
</div> </div>
</td> </td>
<td></td> <td>
<div>
<span class="">Język niemiecki [wf_grupa_2]</span>
<span class=""></span>
<span class=""></span>
<span class=""></span>
</div>
<div>
<span class="x-treelabel-ppl x-treelabel-inv">Wychowanie fizyczne [wf_grupa_2]</span>
<span class="x-treelabel-ppl x-treelabel-inv"></span>
<span class="x-treelabel-ppl x-treelabel-inv">Nauczycielel</span>
<span class="x-treelabel-ppl x-treelabel-inv">106</span>
</div>
</td>
</tr> </tr>
<tr> <tr>
<td>3</td> <td>3</td>
@ -214,7 +272,17 @@
<span></span> <span></span>
</div> </div>
</td> </td>
<td></td> <td>
<div>
<span class="x-treelabel-inv">Religia</span>
<span class="x-treelabel-inv">Cyranka Krystian</span>
<span class="x-treelabel-inv">3</span>
<span class="x-treelabel-ppl x-treelabel-zas">Wychowanie do życia w rodzinie</span>
<span class="x-treelabel-ppl x-treelabel-zas">Nowak Jadwiga</span>
<span class="x-treelabel-ppl x-treelabel-zas">3</span>
<span class="x-treelabel-rlz">bez nawiasów</span>
</div>
</td>
</tr> </tr>
<tr> <tr>
<td>4</td> <td>4</td>
@ -251,7 +319,16 @@
<span></span> <span></span>
</div> </div>
</td> </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>
<tr> <tr>
<td>5</td> <td>5</td>
@ -287,7 +364,20 @@
<span></span> <span></span>
</div> </div>
</td> </td>
<td></td> <td>
<div>
<span class="">Tworzenie i administrowanie bazami danych [zaw2]</span>
<span class=""></span>
<span class=""></span>
<span class=""></span>
</div>
<div>
<span class="x-treelabel-ppl x-treelabel-inv">Zajęcia z wychowawcą</span>
<span class="x-treelabel-ppl x-treelabel-inv">Małgorzata Kowal</span>
<span class="x-treelabel-ppl x-treelabel-inv">43</span>
<span class="x-treelabel-rlz">(zmiana organizacji zajęć)</span>
</div>
</td>
</tr> </tr>
<tr> <tr>
<td>6</td> <td>6</td>
@ -393,7 +483,18 @@
<tr> <tr>
<td>9</td> <td>9</td>
<td>14:50 15:35</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> <td>
<div> <div>
<span class="x-treelabel-ppl x-treelabel-inv">Język niemiecki [J1]</span> <span class="x-treelabel-ppl x-treelabel-inv">Język niemiecki [J1]</span>

View File

@ -2,11 +2,14 @@ buildscript {
repositories { repositories {
maven { url "https://plugins.gradle.org/m2/" } maven { url "https://plugins.gradle.org/m2/" }
maven { url 'https://maven.fabric.io/public' } maven { url 'https://maven.fabric.io/public' }
google()
} }
dependencies { dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' classpath "org.greenrobot:greendao-gradle-plugin:$greenDaoGradle"
classpath 'io.fabric.tools:gradle:1.25.1' classpath "io.fabric.tools:gradle:$fabricGradle"
classpath "com.google.gms:oss-licenses:0.9.2"
classpath "com.github.triplet.gradle:play-publisher:$playPublisher"
} }
} }
@ -19,28 +22,49 @@ apply plugin: 'org.greenrobot.greendao'
apply plugin: 'io.fabric' apply plugin: 'io.fabric'
apply from: '../jacoco.gradle' apply from: '../jacoco.gradle'
apply from: '../android-sonarqube.gradle' apply from: '../android-sonarqube.gradle'
apply plugin: 'com.google.gms.oss.licenses.plugin'
apply plugin: 'com.github.triplet.play'
android { android {
compileSdkVersion 26 compileSdkVersion 26
buildToolsVersion '27.0.3' buildToolsVersion '27.0.3'
playAccountConfigs {
defaultAccountConfig {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL")
pk12File = file('key.p12')
}
}
defaultConfig { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15 minSdkVersion 15
targetSdkVersion 26 targetSdkVersion 26
versionCode 7 versionCode 14
versionName "0.3.1" versionName "0.5.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
playAccountConfig = playAccountConfigs.defaultAccountConfig
manifestPlaceholders = [ manifestPlaceholders = [
fabricApiKey: System.getenv("FABRIC_API_KEY") ?: "null" fabricApiKey: System.getenv("FABRIC_API_KEY") ?: "null"
] ]
} }
signingConfigs {
release {
storeFile file("upload-key.jks")
storePassword System.getenv("PLAY_STORE_PASSWORD")
keyAlias System.getenv("PLAY_KEY_ALIAS")
keyPassword System.getenv("PLAY_KEY_PASSWORD")
}
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
} }
debug { debug {
applicationIdSuffix ".dev" applicationIdSuffix ".dev"
@ -61,11 +85,20 @@ android {
} }
} }
play {
track = 'alpha'
uploadImages = true
}
greendao { greendao {
schemaVersion 23 schemaVersion 28
generateTests = true generateTests = true
} }
configurations.all {
resolutionStrategy.force "com.android.support:support-annotations:$supportVersion"
}
dependencies { dependencies {
implementation project(':api') implementation project(':api')
implementation "com.android.support:support-v4:$supportVersion" implementation "com.android.support:support-v4:$supportVersion"
@ -83,6 +116,10 @@ dependencies {
implementation "com.google.dagger:dagger-android-support:$dagger2" implementation "com.google.dagger:dagger-android-support:$dagger2"
implementation "com.aurelhubert:ahbottomnavigation:$ahbottom" implementation "com.aurelhubert:ahbottomnavigation:$ahbottom"
implementation "com.jakewharton.threetenabp:threetenabp:$threeTenABP" implementation "com.jakewharton.threetenabp:threetenabp:$threeTenABP"
implementation "com.google.android.gms:play-services-oss-licenses:$ossLicenses"
implementation "com.jakewharton.timber:timber:$timber"
implementation "at.favre.lib:slf4j-timber:$slf4jTimber"
implementation("com.crashlytics.sdk.android:crashlytics:$crashlyticsSdk@aar") { implementation("com.crashlytics.sdk.android:crashlytics:$crashlyticsSdk@aar") {
transitive = true transitive = true

BIN
app/key-encrypted.p12 Normal file

Binary file not shown.

View File

@ -12,13 +12,13 @@ public class AttendanceLessonTest extends AbstractDaoTestLongPk<AttendanceLesson
protected AttendanceLesson createEntity(Long key) { protected AttendanceLesson createEntity(Long key) {
AttendanceLesson entity = new AttendanceLesson(); AttendanceLesson entity = new AttendanceLesson();
entity.setId(key); entity.setId(key);
entity.setIsPresence(false); entity.setPresence(false);
entity.setIsAbsenceUnexcused(false); entity.setAbsenceUnexcused(false);
entity.setIsAbsenceExcused(false); entity.setAbsenceExcused(false);
entity.setIsUnexcusedLateness(false); entity.setUnexcusedLateness(false);
entity.setIsAbsenceForSchoolReasons(false); entity.setAbsenceForSchoolReasons(false);
entity.setIsExcusedLateness(false); entity.setExcusedLateness(false);
entity.setIsExemption(false); entity.setExemption(false);
return entity; return entity;
} }

View File

@ -12,7 +12,7 @@ public class DayTest extends AbstractDaoTestLongPk<DayDao, Day> {
protected Day createEntity(Long key) { protected Day createEntity(Long key) {
Day entity = new Day(); Day entity = new Day();
entity.setId(key); entity.setId(key);
entity.setIsFreeDay(false); entity.setFreeDay(false);
return entity; return entity;
} }

View File

@ -12,7 +12,7 @@ public class DiaryTest extends AbstractDaoTestLongPk<DiaryDao, Diary> {
protected Diary createEntity(Long key) { protected Diary createEntity(Long key) {
Diary entity = new Diary(); Diary entity = new Diary();
entity.setId(key); entity.setId(key);
entity.setIsCurrent(false); entity.setCurrent(false);
return entity; return entity;
} }

View File

@ -0,0 +1,18 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
public class ExamTest extends AbstractDaoTestLongPk<ExamDao, Exam> {
public ExamTest() {
super(ExamDao.class);
}
@Override
protected Exam createEntity(Long key) {
Exam entity = new Exam();
entity.setId(key);
return entity;
}
}

View File

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
import io.github.wulkanowy.data.db.dao.entities.Semester;
import io.github.wulkanowy.data.db.dao.entities.SemesterDao;
public class SemesterTest extends AbstractDaoTestLongPk<SemesterDao, Semester> {
public SemesterTest() {
super(SemesterDao.class);
}
@Override
protected Semester createEntity(Long key) {
Semester entity = new Semester();
entity.setId(key);
return entity;
}
}

View File

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
import io.github.wulkanowy.data.db.dao.entities.Student;
import io.github.wulkanowy.data.db.dao.entities.StudentDao;
public class StudentTest extends AbstractDaoTestLongPk<StudentDao, Student> {
public StudentTest() {
super(StudentDao.class);
}
@Override
protected Student createEntity(Long key) {
Student entity = new Student();
entity.setId(key);
return entity;
}
}

View File

@ -0,0 +1,21 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
import io.github.wulkanowy.data.db.dao.entities.Symbol;
import io.github.wulkanowy.data.db.dao.entities.SymbolDao;
public class SymbolTest extends AbstractDaoTestLongPk<SymbolDao, Symbol> {
public SymbolTest() {
super(SymbolDao.class);
}
@Override
protected Symbol createEntity(Long key) {
Symbol entity = new Symbol();
entity.setId(key);
return entity;
}
}

View File

@ -12,12 +12,12 @@ public class TimetableLessonTest extends AbstractDaoTestLongPk<TimetableLessonDa
protected TimetableLesson createEntity(Long key) { protected TimetableLesson createEntity(Long key) {
TimetableLesson entity = new TimetableLesson(); TimetableLesson entity = new TimetableLesson();
entity.setId(key); entity.setId(key);
entity.setIsEmpty(false); entity.setEmpty(false);
entity.setIsDivisionIntoGroups(false); entity.setDivisionIntoGroups(false);
entity.setIsPlanning(false); entity.setPlanning(false);
entity.setIsRealized(false); entity.setRealized(false);
entity.setIsMovedOrCanceled(false); entity.setMovedOrCanceled(false);
entity.setIsNewMovedInOrChanged(false); entity.setNewMovedInOrChanged(false);
return entity; return entity;
} }

View File

@ -10,12 +10,10 @@
<application <application
android:name=".WulkanowyApp" android:name=".WulkanowyApp"
android:allowBackup="true" android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/WulkanowyTheme"> android:theme="@style/WulkanowyTheme">
<activity <activity
android:name=".ui.splash.SplashActivity" android:name=".ui.splash.SplashActivity"
@ -32,19 +30,40 @@
android:name=".ui.login.LoginActivity" android:name=".ui.login.LoginActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/title_activity_login" android:label="@string/title_activity_login"
android:theme="@style/WulkanowyTheme.DarkActionBar"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity <activity
android:name=".ui.main.MainActivity" android:name=".ui.main.MainActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/activity_dashboard_text" /> android:label="@string/activity_dashboard_text"
android:launchMode="singleTop"
/>
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
android:theme="@style/WulkanowyTheme.DarkActionBar" />
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/WulkanowyTheme.DarkActionBar" />
<service <service
android:name=".services.SyncJob" android:name=".services.jobs.SyncJob"
android:exported="false"> android:exported="false">
<intent-filter> <intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" /> <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter> </intent-filter>
</service> </service>
<service
android:name=".services.widgets.TimetableWidgetServices"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<receiver android:name=".ui.widgets.TimetableWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_provider" />
</receiver>
<meta-data <meta-data
android:name="io.fabric.ApiKey" android:name="io.fabric.ApiKey"

View File

@ -1,8 +1,7 @@
package io.github.wulkanowy; package io.github.wulkanowy;
import android.app.Application;
import com.crashlytics.android.Crashlytics; import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.core.CrashlyticsCore; import com.crashlytics.android.core.CrashlyticsCore;
import com.jakewharton.threetenabp.AndroidThreeTen; import com.jakewharton.threetenabp.AndroidThreeTen;
@ -10,18 +9,17 @@ import org.greenrobot.greendao.query.QueryBuilder;
import javax.inject.Inject; import javax.inject.Inject;
import dagger.android.AndroidInjector;
import dagger.android.support.DaggerApplication;
import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.utils.Log;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.di.component.ApplicationComponent; import io.github.wulkanowy.di.DaggerAppComponent;
import io.github.wulkanowy.di.component.DaggerApplicationComponent; import io.github.wulkanowy.utils.FabricUtils;
import io.github.wulkanowy.di.modules.ApplicationModule; import io.github.wulkanowy.utils.LoggerUtils;
import io.github.wulkanowy.utils.LogUtils; import timber.log.Timber;
public class WulkanowyApp extends Application { public class WulkanowyApp extends DaggerApplication {
protected ApplicationComponent applicationComponent;
@Inject @Inject
RepositoryContract repository; RepositoryContract repository;
@ -31,12 +29,6 @@ public class WulkanowyApp extends Application {
super.onCreate(); super.onCreate();
AndroidThreeTen.init(this); AndroidThreeTen.init(this);
applicationComponent = DaggerApplicationComponent
.builder()
.applicationModule(new ApplicationModule(this))
.build();
applicationComponent.inject(this);
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
enableDebugLog(); enableDebugLog();
} }
@ -45,30 +37,38 @@ public class WulkanowyApp extends Application {
} }
private void initializeUserSession() { private void initializeUserSession() {
if (repository.getCurrentUserId() != 0) { if (repository.getSharedRepo().isUserLoggedIn()) {
try { try {
repository.initLastUser(); repository.getSyncRepo().initLastUser();
FabricUtils.logLogin("Open app", true);
} catch (Exception e) { } catch (Exception e) {
LogUtils.error("An error occurred when the application was started", e); FabricUtils.logLogin("Open app", false);
Timber.e(e, "An error occurred when the application was started");
} }
} }
} }
private void enableDebugLog() { private void enableDebugLog() {
QueryBuilder.LOG_VALUES = true; QueryBuilder.LOG_VALUES = true;
FlexibleAdapter.enableLogs(Log.Level.DEBUG); FlexibleAdapter.enableLogs(eu.davidea.flexibleadapter.utils.Log.Level.DEBUG);
Timber.plant(new LoggerUtils.DebugLogTree());
} }
private void initializeFabric() { private void initializeFabric() {
Fabric.with(new Fabric.Builder(this) Fabric.with(new Fabric.Builder(this)
.kits(new Crashlytics.Builder() .kits(
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()) new Crashlytics.Builder()
.build()) .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build(),
new Answers()
)
.debuggable(BuildConfig.DEBUG) .debuggable(BuildConfig.DEBUG)
.build()); .build());
Timber.plant(new LoggerUtils.CrashlyticsTree());
} }
public ApplicationComponent getApplicationComponent() { @Override
return applicationComponent; protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder().create(this);
} }
} }

View File

@ -1,184 +1,56 @@
package io.github.wulkanowy.data; package io.github.wulkanowy.data;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.data.db.dao.DbContract;
import io.github.wulkanowy.data.db.dao.entities.Account;
import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.GradeDao;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.data.db.dao.entities.WeekDao;
import io.github.wulkanowy.data.db.resources.ResourcesContract; import io.github.wulkanowy.data.db.resources.ResourcesContract;
import io.github.wulkanowy.data.db.shared.SharedPrefContract; import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.data.sync.SyncContract; import io.github.wulkanowy.data.sync.SyncContract;
import io.github.wulkanowy.data.sync.account.AccountSyncContract;
import io.github.wulkanowy.data.sync.attendance.AttendanceSyncContract;
import io.github.wulkanowy.data.sync.timetable.TimetableSyncContract;
import io.github.wulkanowy.di.annotations.SyncGrades;
import io.github.wulkanowy.di.annotations.SyncSubjects;
import io.github.wulkanowy.utils.security.CryptoException;
@Singleton @Singleton
public class Repository implements RepositoryContract { public class Repository implements RepositoryContract {
private final SharedPrefContract sharedPref; private final DbContract database;
private final ResourcesContract resources; private final ResourcesContract resources;
private final DaoSession daoSession; private final SharedPrefContract sharedPref;
private final AccountSyncContract accountSync; private final SyncContract synchronization;
private final AttendanceSyncContract attendanceSync;
private final TimetableSyncContract timetableSync;
private final SyncContract gradeSync;
private final SyncContract subjectSync;
@Inject @Inject
Repository(SharedPrefContract sharedPref, Repository(DbContract database, ResourcesContract resources, SharedPrefContract sharedPref,
ResourcesContract resources, SyncContract synchronization) {
DaoSession daoSession, this.database = database;
AccountSyncContract accountSync,
AttendanceSyncContract attendanceSync,
TimetableSyncContract timetableSync,
@SyncGrades SyncContract gradeSync,
@SyncSubjects SyncContract subjectSync) {
this.sharedPref = sharedPref;
this.resources = resources; this.resources = resources;
this.daoSession = daoSession; this.sharedPref = sharedPref;
this.accountSync = accountSync; this.synchronization = synchronization;
this.attendanceSync = attendanceSync;
this.timetableSync = timetableSync;
this.gradeSync = gradeSync;
this.subjectSync = subjectSync;
} }
@Override @Override
public long getCurrentUserId() { public SharedPrefContract getSharedRepo() {
return sharedPref.getCurrentUserId(); return sharedPref;
} }
@Override @Override
public int getStartupTab() { public ResourcesContract getResRepo() {
return sharedPref.getStartupTab(); return resources;
} }
@Override @Override
public int getServicesInterval() { public DbContract getDbRepo() {
return sharedPref.getServicesInterval(); return database;
} }
@Override @Override
public boolean isServicesEnable() { public SyncContract getSyncRepo() {
return sharedPref.isServicesEnable(); return synchronization;
} }
@Override @Override
public boolean isNotifyEnable() { public void cleanAllData() {
return sharedPref.isNotifyEnable(); sharedPref.cleanSharedPref();
} database.recreateDatabase();
@Override
public boolean isMobileDisable() {
return sharedPref.isMobileDisable();
}
@Override
public String[] getSymbolsKeysArray() {
return resources.getSymbolsKeysArray();
}
@Override
public String[] getSymbolsValuesArray() {
return resources.getSymbolsValuesArray();
}
@Override
public String getErrorLoginMessage(Exception e) {
return resources.getErrorLoginMessage(e);
}
@Override
public String getAttendanceLessonDescription(AttendanceLesson lesson) {
return resources.getAttendanceLessonDescription(lesson);
}
@Override
public void registerUser(String email, String password, String symbol) throws VulcanException,
IOException, CryptoException {
accountSync.registerUser(email, password, symbol);
}
@Override
public void initLastUser() throws VulcanException, IOException, CryptoException {
accountSync.initLastUser();
}
@Override
public void syncGrades() throws VulcanException, IOException, ParseException {
gradeSync.sync();
}
@Override
public void syncSubjects() throws VulcanException, IOException, ParseException {
subjectSync.sync();
}
@Override
public void syncAttendance() throws ParseException, IOException, VulcanException {
attendanceSync.syncAttendance();
}
@Override
public void syncAttendance(String date) throws ParseException, IOException, VulcanException {
attendanceSync.syncAttendance(date);
}
@Override
public void syncTimetable() throws VulcanException, IOException, ParseException {
timetableSync.syncTimetable();
}
@Override
public void syncTimetable(String date) throws VulcanException, IOException, ParseException {
timetableSync.syncTimetable(date);
}
@Override
public void syncAll() throws VulcanException, IOException, ParseException {
syncSubjects();
syncGrades();
syncAttendance();
syncTimetable();
}
@Override
public Account getCurrentUser() {
return daoSession.getAccountDao().load(sharedPref.getCurrentUserId());
}
@Override
public Week getWeek(String date) {
return daoSession.getWeekDao().queryBuilder()
.where(WeekDao.Properties.StartDayDate.eq(date),
WeekDao.Properties.UserId.eq(getCurrentUserId()))
.unique();
}
@Override
public List<Grade> getNewGrades() {
return daoSession.getGradeDao().queryBuilder()
.where(GradeDao.Properties.IsNew.eq(1))
.list();
} }
} }

View File

@ -1,45 +1,22 @@
package io.github.wulkanowy.data; package io.github.wulkanowy.data;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import javax.inject.Singleton; import javax.inject.Singleton;
import io.github.wulkanowy.api.VulcanException; import io.github.wulkanowy.data.db.dao.DbContract;
import io.github.wulkanowy.data.db.dao.entities.Account;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.data.db.resources.ResourcesContract; import io.github.wulkanowy.data.db.resources.ResourcesContract;
import io.github.wulkanowy.data.sync.account.AccountSyncContract; import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.data.sync.attendance.AttendanceSyncContract; import io.github.wulkanowy.data.sync.SyncContract;
import io.github.wulkanowy.data.sync.timetable.TimetableSyncContract;
@Singleton @Singleton
public interface RepositoryContract extends ResourcesContract, AccountSyncContract, public interface RepositoryContract {
AttendanceSyncContract, TimetableSyncContract {
long getCurrentUserId(); SharedPrefContract getSharedRepo();
int getStartupTab(); ResourcesContract getResRepo();
boolean isServicesEnable(); DbContract getDbRepo();
boolean isNotifyEnable(); SyncContract getSyncRepo();
int getServicesInterval(); void cleanAllData();
boolean isMobileDisable();
void syncGrades() throws VulcanException, IOException, ParseException;
void syncSubjects() throws VulcanException, IOException, ParseException;
void syncAll() throws VulcanException, IOException, ParseException;
Account getCurrentUser();
Week getWeek(String date);
List<Grade> getNewGrades();
} }

View File

@ -0,0 +1,35 @@
package io.github.wulkanowy.data.db.dao;
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 {
Week getWeek(String date);
Week getWeek(long diaryId, String date);
List<Subject> getSubjectList(int semesterName);
List<Grade> getNewGrades(int semesterName);
long getCurrentStudentId();
long getCurrentSymbolId();
Symbol getCurrentSymbol();
long getCurrentDiaryId();
long getSemesterId(int name);
long getCurrentSemesterId();
int getCurrentSemesterName();
void recreateDatabase();
}

View File

@ -12,15 +12,17 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import io.github.wulkanowy.api.Vulcan; import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.entities.DaoMaster; import io.github.wulkanowy.data.db.dao.entities.DaoMaster;
import io.github.wulkanowy.data.db.dao.migrations.Migration23; import io.github.wulkanowy.data.db.dao.migrations.Migration23;
import io.github.wulkanowy.data.db.dao.migrations.Migration26;
import io.github.wulkanowy.data.db.dao.migrations.Migration27;
import io.github.wulkanowy.data.db.dao.migrations.Migration28;
import io.github.wulkanowy.data.db.shared.SharedPrefContract; import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.di.annotations.ApplicationContext; import timber.log.Timber;
import io.github.wulkanowy.di.annotations.DatabaseInfo;
import io.github.wulkanowy.utils.LogUtils;
@Singleton @Singleton
public class DbHelper extends DaoMaster.OpenHelper { public class DbHelper extends DaoMaster.OpenHelper {
@ -30,7 +32,7 @@ public class DbHelper extends DaoMaster.OpenHelper {
private final Vulcan vulcan; private final Vulcan vulcan;
@Inject @Inject
DbHelper(@ApplicationContext Context context, @DatabaseInfo String dbName, DbHelper(Context context, @Named("dbName") String dbName,
SharedPrefContract sharedPref, Vulcan vulcan) { SharedPrefContract sharedPref, Vulcan vulcan) {
super(context, dbName); super(context, dbName);
this.sharedPref = sharedPref; this.sharedPref = sharedPref;
@ -39,11 +41,9 @@ public class DbHelper extends DaoMaster.OpenHelper {
@Override @Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Timber.i("Cleaning user data oldVersion=%s newVersion=%s", oldVersion, newVersion);
Database database = new StandardDatabase(db); Database database = new StandardDatabase(db);
DaoMaster.dropAllTables(database, true); recreateDatabase(database);
onCreate(database);
sharedPref.setCurrentUserId(0);
LogUtils.info("Cleaning user data oldVersion=" + oldVersion + " newVersion=" + newVersion);
} }
@Override @Override
@ -54,22 +54,31 @@ public class DbHelper extends DaoMaster.OpenHelper {
for (Migration migration : migrations) { for (Migration migration : migrations) {
if (oldVersion < migration.getVersion()) { if (oldVersion < migration.getVersion()) {
try { try {
LogUtils.info("Applying migration to db schema v" + migration.getVersion() + "..."); Timber.i("Applying migration to db schema v%s...", migration.getVersion());
migration.runMigration(db, sharedPref, vulcan); migration.runMigration(db, sharedPref, vulcan);
LogUtils.info("Migration " + migration.getVersion() + " complete"); Timber.i("Migration %s complete", migration.getVersion());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Timber.e(e, "Failed to apply migration");
DaoMaster.dropAllTables(db, true); recreateDatabase(db);
sharedPref.setCurrentUserId(0);
break; break;
} }
} }
} }
} }
private void recreateDatabase(Database db) {
Timber.i("Database is recreating...");
sharedPref.setCurrentUserId(0);
DaoMaster.dropAllTables(db, true);
onCreate(db);
}
private List<Migration> getMigrations() { private List<Migration> getMigrations() {
List<Migration> migrations = new ArrayList<>(); List<Migration> migrations = new ArrayList<>();
migrations.add(new Migration23()); migrations.add(new Migration23());
migrations.add(new Migration26());
migrations.add(new Migration27());
migrations.add(new Migration28());
// Sorting just to be safe, in case other people add migrations in the wrong order. // Sorting just to be safe, in case other people add migrations in the wrong order.
Comparator<Migration> migrationComparator = new Comparator<Migration>() { Comparator<Migration> migrationComparator = new Comparator<Migration>() {

View File

@ -0,0 +1,123 @@
package io.github.wulkanowy.data.db.dao;
import org.greenrobot.greendao.database.Database;
import java.util.List;
import javax.inject.Inject;
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.DiaryDao;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.GradeDao;
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;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
public class DbRepository implements DbContract {
private final DaoSession daoSession;
private final SharedPrefContract sharedPref;
@Inject
DbRepository(DaoSession daoSession, SharedPrefContract sharedPrefContract) {
this.daoSession = daoSession;
this.sharedPref = sharedPrefContract;
}
@Override
public Week getWeek(String date) {
return getWeek(getCurrentDiaryId(), date);
}
@Override
public Week getWeek(long diaryId, String date) {
return daoSession.getWeekDao().queryBuilder().where(
WeekDao.Properties.StartDayDate.eq(date),
WeekDao.Properties.DiaryId.eq(diaryId)
).unique();
}
@Override
public List<Subject> getSubjectList(int semesterName) {
return daoSession.getSemesterDao().load(getSemesterId(semesterName)).getSubjectList();
}
@Override
public List<Grade> getNewGrades(int semesterName) {
return daoSession.getGradeDao().queryBuilder().where(
GradeDao.Properties.IsNew.eq(1),
GradeDao.Properties.SemesterId.eq(getSemesterId(semesterName))
).list();
}
@Override
public Symbol getCurrentSymbol() {
return daoSession.getSymbolDao().queryBuilder().where(
SymbolDao.Properties.UserId.eq(sharedPref.getCurrentUserId())
).unique();
}
@Override
public long getCurrentSymbolId() {
return getCurrentSymbol().getId();
}
@Override
public long getCurrentStudentId() {
return daoSession.getStudentDao().queryBuilder().where(
StudentDao.Properties.SymbolId.eq(getCurrentSymbolId()),
StudentDao.Properties.Current.eq(true)
).unique().getId();
}
@Override
public long getCurrentDiaryId() {
return daoSession.getDiaryDao().queryBuilder().where(
DiaryDao.Properties.StudentId.eq(getCurrentStudentId()),
DiaryDao.Properties.Current.eq(true)
).unique().getId();
}
@Override
public long getSemesterId(int name) {
return daoSession.getSemesterDao().queryBuilder().where(
SemesterDao.Properties.DiaryId.eq(getCurrentDiaryId()),
SemesterDao.Properties.Name.eq(String.valueOf(name))
).unique().getId();
}
@Override
public long getCurrentSemesterId() {
return getCurrentSemester().getId();
}
@Override
public int getCurrentSemesterName() {
return Integer.valueOf(getCurrentSemester().getName());
}
private Semester getCurrentSemester() {
return daoSession.getSemesterDao().queryBuilder().where(
SemesterDao.Properties.DiaryId.eq(getCurrentDiaryId()),
SemesterDao.Properties.Current.eq(true)
).unique();
}
@Override
public void recreateDatabase() {
Database database = daoSession.getDatabase();
DaoMaster.dropAllTables(database, true);
DaoMaster.createAllTables(database, true);
}
}

View File

@ -4,10 +4,9 @@ import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity; import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated; import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id; import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Index;
import org.greenrobot.greendao.annotation.JoinProperty;
import org.greenrobot.greendao.annotation.Property; import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany; import org.greenrobot.greendao.annotation.ToMany;
import org.greenrobot.greendao.annotation.Unique;
import java.util.List; import java.util.List;
@ -20,38 +19,15 @@ public class Account {
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Index(unique = true) @Unique
@Property(nameInDb = "REAL_ID") @Property(nameInDb = "email")
private String realId;
@Property(nameInDb = "SYMBOL")
private String symbol;
@Property(nameInDb = "SCHOOL_ID")
private String schoolId;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "E_MAIL")
private String email; private String email;
@Property(nameInDb = "PASSWORD") @Property(nameInDb = "password")
private String password; private String password;
@ToMany(joinProperties = {
@JoinProperty(name = "realId", referencedName = "studentId")
})
private List<Diary> diaryList;
@ToMany(referencedJoinProperty = "userId") @ToMany(referencedJoinProperty = "userId")
private List<Subject> subjectList; private List<Symbol> symbolList;
@ToMany(referencedJoinProperty = "userId")
private List<Grade> gradeList;
@ToMany(referencedJoinProperty = "userId")
private List<Day> dayList;
/** /**
* Used to resolve relations * Used to resolve relations
@ -65,14 +41,9 @@ public class Account {
@Generated(hash = 335469827) @Generated(hash = 335469827)
private transient AccountDao myDao; private transient AccountDao myDao;
@Generated(hash = 727721142) @Generated(hash = 1104194311)
public Account(Long id, String realId, String symbol, String schoolId, String name, public Account(Long id, String email, String password) {
String email, String password) {
this.id = id; this.id = id;
this.realId = realId;
this.symbol = symbol;
this.schoolId = schoolId;
this.name = name;
this.email = email; this.email = email;
this.password = password; this.password = password;
} }
@ -82,34 +53,15 @@ public class Account {
} }
public Long getId() { public Long getId() {
return id; return this.id;
} }
public Account setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
return this;
}
public String getRealId() {
return realId;
}
public Account setRealId(String realId) {
this.realId = realId;
return this;
}
public String getName() {
return name;
}
public Account setName(String name) {
this.name = name;
return this;
} }
public String getEmail() { public String getEmail() {
return email; return this.email;
} }
public Account setEmail(String email) { public Account setEmail(String email) {
@ -118,7 +70,7 @@ public class Account {
} }
public String getPassword() { public String getPassword() {
return password; return this.password;
} }
public Account setPassword(String password) { public Account setPassword(String password) {
@ -126,180 +78,34 @@ public class Account {
return this; return this;
} }
public String getSymbol() {
return symbol;
}
public Account setSymbol(String symbol) {
this.symbol = symbol;
return this;
}
public String getSchoolId() {
return schoolId;
}
public Account setSchoolId(String schoolId) {
this.schoolId = schoolId;
return this;
}
public Account setDiaryList(List<Diary> diaryList) {
this.diaryList = diaryList;
return this;
}
public Account setSubjectList(List<Subject> subjectList) {
this.subjectList = subjectList;
return this;
}
public Account setGradeList(List<Grade> gradeList) {
this.gradeList = gradeList;
return this;
}
public Account setDayList(List<Day> dayList) {
this.dayList = dayList;
return this;
}
public DaoSession getDaoSession() {
return daoSession;
}
public Account setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
return this;
}
public AccountDao getMyDao() {
return myDao;
}
public Account setMyDao(AccountDao myDao) {
this.myDao = myDao;
return this;
}
/** /**
* To-many relationship, resolved on first access (and after reset). * To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity. * Changes to to-many relations are not persisted, make changes to the target entity.
*/ */
@Generated(hash = 1472214466) @Generated(hash = 822972496)
public List<Diary> getDiaryList() { public List<Symbol> getSymbolList() {
if (diaryList == null) { if (symbolList == null) {
final DaoSession daoSession = this.daoSession; final DaoSession daoSession = this.daoSession;
if (daoSession == null) { if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context"); throw new DaoException("Entity is detached from DAO context");
} }
DiaryDao targetDao = daoSession.getDiaryDao(); SymbolDao targetDao = daoSession.getSymbolDao();
List<Diary> diaryListNew = targetDao._queryAccount_DiaryList(realId); List<Symbol> symbolListNew = targetDao._queryAccount_SymbolList(id);
synchronized (this) { synchronized (this) {
if (diaryList == null) { if (symbolList == null) {
diaryList = diaryListNew; symbolList = symbolListNew;
} }
} }
} }
return diaryList; return symbolList;
} }
/** /**
* Resets a to-many relationship, making the next get call to query for a fresh result. * Resets a to-many relationship, making the next get call to query for a fresh result.
*/ */
@Generated(hash = 1078514341) @Generated(hash = 1716801695)
public synchronized void resetDiaryList() { public synchronized void resetSymbolList() {
diaryList = null; symbolList = null;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1800750450)
public List<Subject> getSubjectList() {
if (subjectList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
SubjectDao targetDao = daoSession.getSubjectDao();
List<Subject> subjectListNew = targetDao._queryAccount_SubjectList(id);
synchronized (this) {
if (subjectList == null) {
subjectList = subjectListNew;
}
}
}
return subjectList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 594294258)
public synchronized void resetSubjectList() {
subjectList = null;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1040074549)
public List<Grade> getGradeList() {
if (gradeList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
GradeDao targetDao = daoSession.getGradeDao();
List<Grade> gradeListNew = targetDao._queryAccount_GradeList(id);
synchronized (this) {
if (gradeList == null) {
gradeList = gradeListNew;
}
}
}
return gradeList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1939990047)
public synchronized void resetGradeList() {
gradeList = null;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 300459794)
public List<Day> getDayList() {
if (dayList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
DayDao targetDao = daoSession.getDayDao();
List<Day> dayListNew = targetDao._queryAccount_DayList(id);
synchronized (this) {
if (dayList == null) {
dayList = dayListNew;
}
}
}
return dayList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1010399236)
public synchronized void resetDayList() {
dayList = null;
} }
/** /**

View File

@ -20,38 +20,38 @@ public class AttendanceLesson implements Serializable {
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Property(nameInDb = "DAY_ID") @Property(nameInDb = "day_id")
private Long dayId; private Long dayId;
@Property(nameInDb = "DATE") @Property(nameInDb = "date")
private String date = ""; private String date = "";
@Property(nameInDb = "NUMBER_OF_LESSON") @Property(nameInDb = "number_of_lesson")
private int number = 0; private int number = 0;
@Property(nameInDb = "SUBJECT_NAME") @Property(nameInDb = "subject")
private String subject = ""; private String subject = "";
@Property(nameInDb = "IS_PRESENCE") @Property(nameInDb = "presence")
private boolean isPresence = false; private boolean presence = false;
@Property(nameInDb = "IS_ABSENCE_UNEXCUSED") @Property(nameInDb = "absence_unexcused")
private boolean isAbsenceUnexcused = false; private boolean absenceUnexcused = false;
@Property(nameInDb = "IS_ABSENCE_EXCUSED") @Property(nameInDb = "absence_excused")
private boolean isAbsenceExcused = false; private boolean absenceExcused = false;
@Property(nameInDb = "IS_UNEXCUSED_LATENESS") @Property(nameInDb = "unexcused_lateness")
private boolean isUnexcusedLateness = false; private boolean unexcusedLateness = false;
@Property(nameInDb = "IS_ABSENCE_FOR_SCHOOL_REASONS") @Property(nameInDb = "absence_for_school_reasons")
private boolean isAbsenceForSchoolReasons = false; private boolean absenceForSchoolReasons = false;
@Property(nameInDb = "IS_EXCUSED_LATENESS") @Property(nameInDb = "excused_lateness")
private boolean isExcusedLateness = false; private boolean excusedLateness = false;
@Property(nameInDb = "IS_EXEMPTION") @Property(nameInDb = "exemption")
private boolean isExemption = false; private boolean exemption = false;
@Transient @Transient
private String description = ""; private String description = "";
@ -70,24 +70,24 @@ public class AttendanceLesson implements Serializable {
@Generated(hash = 1936953859) @Generated(hash = 1936953859)
private transient AttendanceLessonDao myDao; private transient AttendanceLessonDao myDao;
@Generated(hash = 1428129046) @Generated(hash = 1741231228)
public AttendanceLesson(Long id, Long dayId, String date, int number, public AttendanceLesson(Long id, Long dayId, String date, int number,
String subject, boolean isPresence, boolean isAbsenceUnexcused, String subject, boolean presence, boolean absenceUnexcused,
boolean isAbsenceExcused, boolean isUnexcusedLateness, boolean absenceExcused, boolean unexcusedLateness,
boolean isAbsenceForSchoolReasons, boolean isExcusedLateness, boolean absenceForSchoolReasons, boolean excusedLateness,
boolean isExemption) { boolean exemption) {
this.id = id; this.id = id;
this.dayId = dayId; this.dayId = dayId;
this.date = date; this.date = date;
this.number = number; this.number = number;
this.subject = subject; this.subject = subject;
this.isPresence = isPresence; this.presence = presence;
this.isAbsenceUnexcused = isAbsenceUnexcused; this.absenceUnexcused = absenceUnexcused;
this.isAbsenceExcused = isAbsenceExcused; this.absenceExcused = absenceExcused;
this.isUnexcusedLateness = isUnexcusedLateness; this.unexcusedLateness = unexcusedLateness;
this.isAbsenceForSchoolReasons = isAbsenceForSchoolReasons; this.absenceForSchoolReasons = absenceForSchoolReasons;
this.isExcusedLateness = isExcusedLateness; this.excusedLateness = excusedLateness;
this.isExemption = isExemption; this.exemption = exemption;
} }
@Generated(hash = 921806575) @Generated(hash = 921806575)
@ -137,66 +137,66 @@ public class AttendanceLesson implements Serializable {
return this; return this;
} }
public boolean getIsPresence() { public boolean getPresence() {
return this.isPresence; return this.presence;
} }
public AttendanceLesson setIsPresence(boolean isPresence) { public AttendanceLesson setPresence(boolean presence) {
this.isPresence = isPresence; this.presence = presence;
return this; return this;
} }
public boolean getIsAbsenceUnexcused() { public boolean getAbsenceUnexcused() {
return this.isAbsenceUnexcused; return this.absenceUnexcused;
} }
public AttendanceLesson setIsAbsenceUnexcused(boolean isAbsenceUnexcused) { public AttendanceLesson setAbsenceUnexcused(boolean absenceUnexcused) {
this.isAbsenceUnexcused = isAbsenceUnexcused; this.absenceUnexcused = absenceUnexcused;
return this; return this;
} }
public boolean getIsAbsenceExcused() { public boolean getAbsenceExcused() {
return this.isAbsenceExcused; return this.absenceExcused;
} }
public AttendanceLesson setIsAbsenceExcused(boolean isAbsenceExcused) { public AttendanceLesson setAbsenceExcused(boolean absenceExcused) {
this.isAbsenceExcused = isAbsenceExcused; this.absenceExcused = absenceExcused;
return this; return this;
} }
public boolean getIsUnexcusedLateness() { public boolean getUnexcusedLateness() {
return this.isUnexcusedLateness; return this.unexcusedLateness;
} }
public AttendanceLesson setIsUnexcusedLateness(boolean isUnexcusedLateness) { public AttendanceLesson setUnexcusedLateness(boolean unexcusedLateness) {
this.isUnexcusedLateness = isUnexcusedLateness; this.unexcusedLateness = unexcusedLateness;
return this; return this;
} }
public boolean getIsAbsenceForSchoolReasons() { public boolean getAbsenceForSchoolReasons() {
return this.isAbsenceForSchoolReasons; return this.absenceForSchoolReasons;
} }
public AttendanceLesson setIsAbsenceForSchoolReasons(boolean isAbsenceForSchoolReasons) { public AttendanceLesson setAbsenceForSchoolReasons(boolean absenceForSchoolReasons) {
this.isAbsenceForSchoolReasons = isAbsenceForSchoolReasons; this.absenceForSchoolReasons = absenceForSchoolReasons;
return this; return this;
} }
public boolean getIsExcusedLateness() { public boolean getExcusedLateness() {
return this.isExcusedLateness; return this.excusedLateness;
} }
public AttendanceLesson setIsExcusedLateness(boolean isExcusedLateness) { public AttendanceLesson setExcusedLateness(boolean excusedLateness) {
this.isExcusedLateness = isExcusedLateness; this.excusedLateness = excusedLateness;
return this; return this;
} }
public boolean getIsExemption() { public boolean getExemption() {
return this.isExemption; return this.exemption;
} }
public AttendanceLesson setIsExemption(boolean isExemption) { public AttendanceLesson setExemption(boolean exemption) {
this.isExemption = isExemption; this.exemption = exemption;
return this; return this;
} }

View File

@ -14,59 +14,57 @@ import java.util.List;
@Entity( @Entity(
nameInDb = "Days", nameInDb = "Days",
active = true, active = true,
indexes = {@Index(value = "userId,weekId,date", unique = true)} indexes = {@Index(value = "weekId,date", unique = true)}
) )
public class Day { public class Day {
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Property(nameInDb = "USER_ID") @Property(nameInDb = "week_id")
private Long userId;
@Property(nameInDb = "WEEK_ID")
private Long weekId; private Long weekId;
@Property(nameInDb = "DATE") @Property(nameInDb = "date")
private String date = ""; private String date = "";
@Property(nameInDb = "DAY_NAME") @Property(nameInDb = "day_name")
private String dayName = ""; private String dayName = "";
@Property(nameInDb = "IS_FREE_DAY") @Property(nameInDb = "free_day")
private boolean isFreeDay = false; private boolean freeDay = false;
@Property(nameInDb = "FREE_DAY_NAME") @Property(nameInDb = "free_day_name")
private String freeDayName = ""; private String freeDayName = "";
@OrderBy("number ASC")
@ToMany(referencedJoinProperty = "dayId") @ToMany(referencedJoinProperty = "dayId")
private List<TimetableLesson> timetableLessons; private List<TimetableLesson> timetableLessons;
@ToMany(referencedJoinProperty = "dayId")
@OrderBy("number ASC") @OrderBy("number ASC")
@ToMany(referencedJoinProperty = "dayId")
private List<AttendanceLesson> attendanceLessons; private List<AttendanceLesson> attendanceLessons;
@ToMany(referencedJoinProperty = "dayId")
private List<Exam> exams;
/** /**
* Used to resolve relations * Used to resolve relations
*/ */
@Generated(hash = 2040040024) @Generated(hash = 2040040024)
private transient DaoSession daoSession; private transient DaoSession daoSession;
/** /** Used for active entity operations. */
* Used for active entity operations.
*/
@Generated(hash = 312167767) @Generated(hash = 312167767)
private transient DayDao myDao; private transient DayDao myDao;
@Generated(hash = 723729681) @Generated(hash = 523139020)
public Day(Long id, Long userId, Long weekId, String date, String dayName, public Day(Long id, Long weekId, String date, String dayName, boolean freeDay,
boolean isFreeDay, String freeDayName) { String freeDayName) {
this.id = id; this.id = id;
this.userId = userId;
this.weekId = weekId; this.weekId = weekId;
this.date = date; this.date = date;
this.dayName = dayName; this.dayName = dayName;
this.isFreeDay = isFreeDay; this.freeDay = freeDay;
this.freeDayName = freeDayName; this.freeDayName = freeDayName;
} }
@ -82,26 +80,16 @@ public class Day {
this.id = id; this.id = id;
} }
public Long getUserId() {
return userId;
}
public Long getWeekId() { public Long getWeekId() {
return weekId; return this.weekId;
} }
public Day setWeekId(Long weekId) { public void setWeekId(Long weekId) {
this.weekId = weekId; this.weekId = weekId;
return this;
}
public Day setUserId(Long userId) {
this.userId = userId;
return this;
} }
public String getDate() { public String getDate() {
return date; return this.date;
} }
public Day setDate(String date) { public Day setDate(String date) {
@ -110,7 +98,7 @@ public class Day {
} }
public String getDayName() { public String getDayName() {
return dayName; return this.dayName;
} }
public Day setDayName(String dayName) { public Day setDayName(String dayName) {
@ -118,17 +106,17 @@ public class Day {
return this; return this;
} }
public boolean getIsFreeDay() { public boolean getFreeDay() {
return this.isFreeDay; return this.freeDay;
} }
public Day setIsFreeDay(boolean isFreeDay) { public Day setFreeDay(boolean freeDay) {
this.isFreeDay = isFreeDay; this.freeDay = freeDay;
return this; return this;
} }
public String getFreeDayName() { public String getFreeDayName() {
return freeDayName; return this.freeDayName;
} }
public Day setFreeDayName(String freeDayName) { public Day setFreeDayName(String freeDayName) {
@ -159,7 +147,9 @@ public class Day {
return timetableLessons; return timetableLessons;
} }
/** Resets a to-many relationship, making the next get call to query for a fresh result. */ /**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1687683740) @Generated(hash = 1687683740)
public synchronized void resetTimetableLessons() { public synchronized void resetTimetableLessons() {
timetableLessons = null; timetableLessons = null;
@ -188,12 +178,44 @@ public class Day {
return attendanceLessons; return attendanceLessons;
} }
/** Resets a to-many relationship, making the next get call to query for a fresh result. */ /**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1343075564) @Generated(hash = 1343075564)
public synchronized void resetAttendanceLessons() { public synchronized void resetAttendanceLessons() {
attendanceLessons = null; attendanceLessons = null;
} }
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1231531946)
public List<Exam> getExams() {
if (exams == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
ExamDao targetDao = daoSession.getExamDao();
List<Exam> examsNew = targetDao._queryDay_Exams(id);
synchronized (this) {
if (exams == null) {
exams = examsNew;
}
}
}
return exams;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 841969952)
public synchronized void resetExams() {
exams = null;
}
/** /**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context. * Entity must attached to an entity context.
@ -236,4 +258,6 @@ public class Day {
this.daoSession = daoSession; this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getDayDao() : null; myDao = daoSession != null ? daoSession.getDayDao() : null;
} }
} }

View File

@ -5,6 +5,9 @@ import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated; import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id; import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property; import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity( @Entity(
nameInDb = "Diaries", nameInDb = "Diaries",
@ -15,17 +18,20 @@ public class Diary {
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Property(nameInDb = "STUDENT_ID") @Property(nameInDb = "student_id")
private String studentId; private Long studentId;
@Property(nameInDb = "NAME") @Property(nameInDb = "current")
private boolean current;
@Property(nameInDb = "name")
private String name; private String name;
@Property(nameInDb = "VALUE") @Property(nameInDb = "value")
private String value; private String value;
@Property(nameInDb = "IS_CURRENT") @ToMany(referencedJoinProperty = "diaryId")
private boolean isCurrent; private List<Semester> semesterList;
/** /**
* Used to resolve relations * Used to resolve relations
@ -39,14 +45,13 @@ public class Diary {
@Generated(hash = 21166549) @Generated(hash = 21166549)
private transient DiaryDao myDao; private transient DiaryDao myDao;
@Generated(hash = 459332202) @Generated(hash = 277096196)
public Diary(Long id, String studentId, String name, String value, public Diary(Long id, Long studentId, boolean current, String name, String value) {
boolean isCurrent) {
this.id = id; this.id = id;
this.studentId = studentId; this.studentId = studentId;
this.current = current;
this.name = name; this.name = name;
this.value = value; this.value = value;
this.isCurrent = isCurrent;
} }
@Generated(hash = 112123061) @Generated(hash = 112123061)
@ -54,25 +59,24 @@ public class Diary {
} }
public Long getId() { public Long getId() {
return id; return this.id;
} }
public Diary setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
return this;
} }
public String getStudentId() { public Long getStudentId() {
return studentId; return this.studentId;
} }
public Diary setStudentId(String studentId) { public Diary setStudentId(Long studentId) {
this.studentId = studentId; this.studentId = studentId;
return this; return this;
} }
public String getName() { public String getName() {
return name; return this.name;
} }
public Diary setName(String name) { public Diary setName(String name) {
@ -81,7 +85,7 @@ public class Diary {
} }
public String getValue() { public String getValue() {
return value; return this.value;
} }
public Diary setValue(String value) { public Diary setValue(String value) {
@ -89,31 +93,43 @@ public class Diary {
return this; return this;
} }
public boolean getIsCurrent() { public boolean getCurrent() {
return isCurrent; return this.current;
} }
public Diary setIsCurrent(boolean current) { public Diary setCurrent(boolean current) {
isCurrent = current; this.current = current;
return this; return this;
} }
public DaoSession getDaoSession() { /**
return daoSession; * To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1738383053)
public List<Semester> getSemesterList() {
if (semesterList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
SemesterDao targetDao = daoSession.getSemesterDao();
List<Semester> semesterListNew = targetDao._queryDiary_SemesterList(id);
synchronized (this) {
if (semesterList == null) {
semesterList = semesterListNew;
}
}
}
return semesterList;
} }
public Diary setDaoSession(DaoSession daoSession) { /**
this.daoSession = daoSession; * Resets a to-many relationship, making the next get call to query for a fresh result.
return this; */
} @Generated(hash = 995060657)
public synchronized void resetSemesterList() {
public DiaryDao getMyDao() { semesterList = null;
return myDao;
}
public Diary setMyDao(DiaryDao myDao) {
this.myDao = myDao;
return this;
} }
/** /**

View File

@ -0,0 +1,177 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Index;
import org.greenrobot.greendao.annotation.Property;
import java.io.Serializable;
@Entity(
nameInDb = "Exams",
active = true,
indexes = {@Index(value = "dayId,entryDate,subjectAndGroup,type,teacher", unique = true)}
)
public class Exam implements Serializable {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "day_id")
private Long dayId;
@Property(nameInDb = "subject_and_group")
private String subjectAndGroup = "";
@Property(nameInDb = "type")
private String type = "";
@Property(nameInDb = "description")
private String description = "";
@Property(nameInDb = "teacher")
private String teacher = "";
@Property(nameInDb = "entry_date")
private String entryDate = "";
private static final long serialVersionUID = 42L;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 973692038)
private transient ExamDao myDao;
@Generated(hash = 998653360)
public Exam(Long id, Long dayId, String subjectAndGroup, String type, String description,
String teacher, String entryDate) {
this.id = id;
this.dayId = dayId;
this.subjectAndGroup = subjectAndGroup;
this.type = type;
this.description = description;
this.teacher = teacher;
this.entryDate = entryDate;
}
@Generated(hash = 945526930)
public Exam() {
}
public Long getId() {
return id;
}
public Exam setId(Long id) {
this.id = id;
return this;
}
public Long getDayId() {
return this.dayId;
}
public Exam setDayId(Long dayId) {
this.dayId = dayId;
return this;
}
public String getSubjectAndGroup() {
return subjectAndGroup;
}
public Exam setSubjectAndGroup(String subjectAndGroup) {
this.subjectAndGroup = subjectAndGroup;
return this;
}
public String getType() {
return type;
}
public Exam setType(String type) {
this.type = type;
return this;
}
public String getDescription() {
return description;
}
public Exam setDescription(String description) {
this.description = description;
return this;
}
public String getTeacher() {
return teacher;
}
public Exam setTeacher(String teacher) {
this.teacher = teacher;
return this;
}
public String getEntryDate() {
return entryDate;
}
public Exam setEntryDate(String entryDate) {
this.entryDate = entryDate;
return this;
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 128553479)
public void delete() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.delete(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 1942392019)
public void refresh() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.refresh(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 713229351)
public void update() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.update(this);
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1730563422)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getExamDao() : null;
}
}

View File

@ -10,8 +10,6 @@ import org.greenrobot.greendao.annotation.Property;
import java.io.Serializable; import java.io.Serializable;
import io.github.wulkanowy.R;
@Entity( @Entity(
nameInDb = "Grades", nameInDb = "Grades",
active = true active = true
@ -21,72 +19,44 @@ public class Grade implements Serializable {
@Id(autoincrement = true) @Id(autoincrement = true)
protected Long id; protected Long id;
@Property(nameInDb = "SUBJECT_ID") @Property(nameInDb = "semester_id")
private Long semesterId;
@Property(nameInDb = "subject_id")
private Long subjectId; private Long subjectId;
@Property(nameInDb = "USER_ID") @Property(nameInDb = "subject")
private Long userId;
@Property(nameInDb = "SUBJECT")
private String subject = ""; private String subject = "";
@Property(nameInDb = "VALUE") @Property(nameInDb = "value")
protected String value = ""; protected String value = "";
@Property(nameInDb = "COLOR") @Property(nameInDb = "weight")
private String color = "";
@Property(nameInDb = "SYMBOL")
private String symbol = "";
@Property(nameInDb = "DESCRIPTION")
private String description = "";
@Property(nameInDb = "WEIGHT")
private String weight = ""; private String weight = "";
@Property(nameInDb = "DATE") @Property(nameInDb = "date")
private String date = ""; private String date = "";
@Property(nameInDb = "TEACHER") @Property(nameInDb = "symbol")
private String symbol = "";
@Property(nameInDb = "color")
private String color = "";
@Property(nameInDb = "description")
private String description = "";
@Property(nameInDb = "teacher")
private String teacher = ""; private String teacher = "";
@Property(nameInDb = "SEMESTER") @Property(nameInDb = "is_new")
private String semester = "";
@Property(nameInDb = "IS_NEW")
private boolean isNew = false; private boolean isNew = false;
@Property(nameInDb = "READ") @Property(nameInDb = "read")
private boolean read = true; private boolean read = true;
private static final long serialVersionUID = 42L; private static final long serialVersionUID = 42L;
@Generated(hash = 568899968)
public Grade(Long id, Long subjectId, Long userId, String subject, String value,
String color, String symbol, String description, String weight,
String date, String teacher, String semester, boolean isNew,
boolean read) {
this.id = id;
this.subjectId = subjectId;
this.userId = userId;
this.subject = subject;
this.value = value;
this.color = color;
this.symbol = symbol;
this.description = description;
this.weight = weight;
this.date = date;
this.teacher = teacher;
this.semester = semester;
this.isNew = isNew;
this.read = read;
}
@Generated(hash = 2042976393)
public Grade() {
}
/** /**
* Used to resolve relations * Used to resolve relations
*/ */
@ -99,29 +69,27 @@ public class Grade implements Serializable {
@Generated(hash = 681281562) @Generated(hash = 681281562)
private transient GradeDao myDao; private transient GradeDao myDao;
public int getValueColor() { @Generated(hash = 2042976393)
public Grade() {
}
String replacedString = value.replaceAll("[^0-9]", ""); @Generated(hash = 619853992)
public Grade(Long id, Long semesterId, Long subjectId, String subject, String value,
if (!"".equals(replacedString)) { String weight, String date, String symbol, String color, String description,
switch (Integer.parseInt(replacedString)) { String teacher, boolean isNew, boolean read) {
case 6: this.id = id;
return R.color.six_grade; this.semesterId = semesterId;
case 5: this.subjectId = subjectId;
return R.color.five_grade; this.subject = subject;
case 4: this.value = value;
return R.color.four_grade; this.weight = weight;
case 3: this.date = date;
return R.color.three_grade; this.symbol = symbol;
case 2: this.color = color;
return R.color.two_grade; this.description = description;
case 1: this.teacher = teacher;
return R.color.one_grade; this.isNew = isNew;
default: this.read = read;
return R.color.default_grade;
}
}
return R.color.default_grade;
} }
@Override @Override
@ -133,6 +101,7 @@ public class Grade implements Serializable {
Grade grade = (Grade) o; Grade grade = (Grade) o;
return new EqualsBuilder() return new EqualsBuilder()
.append(semesterId, grade.semesterId)
.append(subject, grade.subject) .append(subject, grade.subject)
.append(value, grade.value) .append(value, grade.value)
.append(color, grade.color) .append(color, grade.color)
@ -141,13 +110,13 @@ public class Grade implements Serializable {
.append(weight, grade.weight) .append(weight, grade.weight)
.append(date, grade.date) .append(date, grade.date)
.append(teacher, grade.teacher) .append(teacher, grade.teacher)
.append(semester, grade.semester)
.isEquals(); .isEquals();
} }
@Override @Override
public int hashCode() { public int hashCode() {
return new HashCodeBuilder(17, 37) return new HashCodeBuilder(17, 37)
.append(semesterId)
.append(subject) .append(subject)
.append(value) .append(value)
.append(color) .append(color)
@ -156,48 +125,19 @@ public class Grade implements Serializable {
.append(weight) .append(weight)
.append(date) .append(date)
.append(teacher) .append(teacher)
.append(semester)
.toHashCode(); .toHashCode();
} }
public Long getId() { public Long getId() {
return id; return this.id;
} }
public Grade setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
return this;
}
public Long getSubjectId() {
return subjectId;
}
public Grade setSubjectId(Long subjectId) {
this.subjectId = subjectId;
return this;
}
public Long getUserId() {
return userId;
}
public Grade setUserId(Long userId) {
this.userId = userId;
return this;
}
public String getSubject() {
return subject;
}
public Grade setSubject(String subject) {
this.subject = subject;
return this;
} }
public String getValue() { public String getValue() {
return value; return this.value;
} }
public Grade setValue(String value) { public Grade setValue(String value) {
@ -205,8 +145,26 @@ public class Grade implements Serializable {
return this; return this;
} }
public Long getSemesterId() {
return this.semesterId;
}
public Grade setSemesterId(Long semesterId) {
this.semesterId = semesterId;
return this;
}
public String getSubject() {
return this.subject;
}
public Grade setSubject(String subject) {
this.subject = subject;
return this;
}
public String getColor() { public String getColor() {
return color; return this.color;
} }
public Grade setColor(String color) { public Grade setColor(String color) {
@ -215,7 +173,7 @@ public class Grade implements Serializable {
} }
public String getSymbol() { public String getSymbol() {
return symbol; return this.symbol;
} }
public Grade setSymbol(String symbol) { public Grade setSymbol(String symbol) {
@ -224,7 +182,7 @@ public class Grade implements Serializable {
} }
public String getDescription() { public String getDescription() {
return description; return this.description;
} }
public Grade setDescription(String description) { public Grade setDescription(String description) {
@ -233,7 +191,7 @@ public class Grade implements Serializable {
} }
public String getWeight() { public String getWeight() {
return weight; return this.weight;
} }
public Grade setWeight(String weight) { public Grade setWeight(String weight) {
@ -242,7 +200,7 @@ public class Grade implements Serializable {
} }
public String getDate() { public String getDate() {
return date; return this.date;
} }
public Grade setDate(String date) { public Grade setDate(String date) {
@ -251,7 +209,7 @@ public class Grade implements Serializable {
} }
public String getTeacher() { public String getTeacher() {
return teacher; return this.teacher;
} }
public Grade setTeacher(String teacher) { public Grade setTeacher(String teacher) {
@ -259,22 +217,12 @@ public class Grade implements Serializable {
return this; return this;
} }
public String getSemester() {
return semester;
}
public Grade setSemester(String semester) {
this.semester = semester;
return this;
}
public boolean getIsNew() { public boolean getIsNew() {
return this.isNew; return this.isNew;
} }
public Grade setIsNew(boolean isNew) { public void setIsNew(boolean isNew) {
this.isNew = isNew; this.isNew = isNew;
return this;
} }
public boolean getRead() { public boolean getRead() {
@ -286,6 +234,17 @@ public class Grade implements Serializable {
return this; return this;
} }
public Long getSubjectId() {
return this.subjectId;
}
public void setSubjectId(Long subjectId) {
this.subjectId = subjectId;
}
/** /**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context. * Entity must attached to an entity context.
@ -298,6 +257,7 @@ public class Grade implements Serializable {
myDao.delete(this); myDao.delete(this);
} }
/** /**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}. * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
* Entity must attached to an entity context. * Entity must attached to an entity context.
@ -310,6 +270,7 @@ public class Grade implements Serializable {
myDao.refresh(this); myDao.refresh(this);
} }
/** /**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}. * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
* Entity must attached to an entity context. * Entity must attached to an entity context.
@ -322,6 +283,7 @@ public class Grade implements Serializable {
myDao.update(this); myDao.update(this);
} }
/** called by internal mechanisms, do not call yourself. */ /** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1187286414) @Generated(hash = 1187286414)
public void __setDaoSession(DaoSession daoSession) { public void __setDaoSession(DaoSession daoSession) {

View File

@ -0,0 +1,208 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity(
nameInDb = "Semesters",
active = true
)
public class Semester {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "diary_id")
private Long diaryId;
@Property(nameInDb = "current")
private boolean current;
@Property(nameInDb = "name")
private String name;
@Property(nameInDb = "value")
private String value;
@ToMany(referencedJoinProperty = "semesterId")
private List<Subject> subjectList;
@ToMany(referencedJoinProperty = "semesterId")
private List<Grade> gradeList;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 282930393)
private transient SemesterDao myDao;
@Generated(hash = 1661077309)
public Semester(Long id, Long diaryId, boolean current, String name, String value) {
this.id = id;
this.diaryId = diaryId;
this.current = current;
this.name = name;
this.value = value;
}
@Generated(hash = 58335877)
public Semester() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDiaryId() {
return this.diaryId;
}
public Semester setDiaryId(Long diaryId) {
this.diaryId = diaryId;
return this;
}
public String getName() {
return this.name;
}
public Semester setName(String name) {
this.name = name;
return this;
}
public String getValue() {
return this.value;
}
public Semester setValue(String value) {
this.value = value;
return this;
}
public boolean getCurrent() {
return this.current;
}
public Semester setCurrent(boolean current) {
this.current = current;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 723353662)
public List<Subject> getSubjectList() {
if (subjectList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
SubjectDao targetDao = daoSession.getSubjectDao();
List<Subject> subjectListNew = targetDao._querySemester_SubjectList(id);
synchronized (this) {
if (subjectList == null) {
subjectList = subjectListNew;
}
}
}
return subjectList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 594294258)
public synchronized void resetSubjectList() {
subjectList = null;
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 128553479)
public void delete() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.delete(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 1942392019)
public void refresh() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.refresh(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 713229351)
public void update() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.update(this);
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 390330007)
public List<Grade> getGradeList() {
if (gradeList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
GradeDao targetDao = daoSession.getGradeDao();
List<Grade> gradeListNew = targetDao._querySemester_GradeList(id);
synchronized (this) {
if (gradeList == null) {
gradeList = gradeListNew;
}
}
}
return gradeList;
}
/** Resets a to-many relationship, making the next get call to query for a fresh result. */
@Generated(hash = 1939990047)
public synchronized void resetGradeList() {
gradeList = null;
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 676204164)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getSemesterDao() : null;
}
}

View File

@ -0,0 +1,178 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity(
nameInDb = "Students",
active = true
)
public class Student {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "symbol_id")
private Long symbolId;
@Property(nameInDb = "current")
private boolean current;
@Property(nameInDb = "real_id")
private String realId;
@Property(nameInDb = "name")
private String name;
@ToMany(referencedJoinProperty = "studentId")
private List<Diary> diaryList;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 1943931642)
private transient StudentDao myDao;
@Generated(hash = 1334215952)
public Student(Long id, Long symbolId, boolean current, String realId, String name) {
this.id = id;
this.symbolId = symbolId;
this.current = current;
this.realId = realId;
this.name = name;
}
@Generated(hash = 1556870573)
public Student() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSymbolId() {
return this.symbolId;
}
public Student setSymbolId(Long symbolId) {
this.symbolId = symbolId;
return this;
}
public String getRealId() {
return this.realId;
}
public Student setRealId(String realId) {
this.realId = realId;
return this;
}
public String getName() {
return this.name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public boolean getCurrent() {
return this.current;
}
public Student setCurrent(boolean current) {
this.current = current;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 508305571)
public List<Diary> getDiaryList() {
if (diaryList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
DiaryDao targetDao = daoSession.getDiaryDao();
List<Diary> diaryListNew = targetDao._queryStudent_DiaryList(id);
synchronized (this) {
if (diaryList == null) {
diaryList = diaryListNew;
}
}
}
return diaryList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1078514341)
public synchronized void resetDiaryList() {
diaryList = null;
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 128553479)
public void delete() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.delete(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 1942392019)
public void refresh() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.refresh(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 713229351)
public void update() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.update(this);
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1701634981)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getStudentDao() : null;
}
}

View File

@ -18,21 +18,18 @@ public class Subject {
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Property(nameInDb = "USER_ID") @Property(nameInDb = "semester_id")
private Long userId; private Long semesterId;
@Property(nameInDb = "NAME") @Property(nameInDb = "name")
private String name; private String name;
@Property(nameInDb = "PREDICTED_RATING") @Property(nameInDb = "predicted_rating")
private String predictedRating; private String predictedRating;
@Property(nameInDb = "FINAL_RATING") @Property(nameInDb = "final_rating")
private String finalRating; private String finalRating;
@Property(nameInDb = "SEMESTER")
private String semester;
@ToMany(referencedJoinProperty = "subjectId") @ToMany(referencedJoinProperty = "subjectId")
private List<Grade> gradeList; private List<Grade> gradeList;
@ -48,15 +45,14 @@ public class Subject {
@Generated(hash = 1644932788) @Generated(hash = 1644932788)
private transient SubjectDao myDao; private transient SubjectDao myDao;
@Generated(hash = 396325764) @Generated(hash = 1817932538)
public Subject(Long id, Long userId, String name, String predictedRating, public Subject(Long id, Long semesterId, String name, String predictedRating,
String finalRating, String semester) { String finalRating) {
this.id = id; this.id = id;
this.userId = userId; this.semesterId = semesterId;
this.name = name; this.name = name;
this.predictedRating = predictedRating; this.predictedRating = predictedRating;
this.finalRating = finalRating; this.finalRating = finalRating;
this.semester = semester;
} }
@Generated(hash = 1617906264) @Generated(hash = 1617906264)
@ -64,25 +60,24 @@ public class Subject {
} }
public Long getId() { public Long getId() {
return id; return this.id;
} }
public Subject setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
return this;
} }
public Long getUserId() { public Long getSemesterId() {
return userId; return this.semesterId;
} }
public Subject setUserId(Long userId) { public Subject setSemesterId(Long semesterId) {
this.userId = userId; this.semesterId = semesterId;
return this; return this;
} }
public String getName() { public String getName() {
return name; return this.name;
} }
public Subject setName(String name) { public Subject setName(String name) {
@ -91,7 +86,7 @@ public class Subject {
} }
public String getPredictedRating() { public String getPredictedRating() {
return predictedRating; return this.predictedRating;
} }
public Subject setPredictedRating(String predictedRating) { public Subject setPredictedRating(String predictedRating) {
@ -100,7 +95,7 @@ public class Subject {
} }
public String getFinalRating() { public String getFinalRating() {
return finalRating; return this.finalRating;
} }
public Subject setFinalRating(String finalRating) { public Subject setFinalRating(String finalRating) {
@ -108,45 +103,6 @@ public class Subject {
return this; return this;
} }
public String getSemester() {
return semester;
}
public Subject setSemester(String semester) {
this.semester = semester;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1358847893)
public List<Grade> getGradeList() {
if (gradeList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
GradeDao targetDao = daoSession.getGradeDao();
List<Grade> gradeListNew = targetDao._querySubject_GradeList(id);
synchronized (this) {
if (gradeList == null) {
gradeList = gradeListNew;
}
}
}
return gradeList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1939990047)
public synchronized void resetGradeList() {
gradeList = null;
}
/** /**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context. * Entity must attached to an entity context.
@ -183,6 +139,34 @@ public class Subject {
myDao.update(this); myDao.update(this);
} }
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 1358847893)
public List<Grade> getGradeList() {
if (gradeList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
GradeDao targetDao = daoSession.getGradeDao();
List<Grade> gradeListNew = targetDao._querySubject_GradeList(id);
synchronized (this) {
if (gradeList == null) {
gradeList = gradeListNew;
}
}
}
return gradeList;
}
/** Resets a to-many relationship, making the next get call to query for a fresh result. */
@Generated(hash = 1939990047)
public synchronized void resetGradeList() {
gradeList = null;
}
/** called by internal mechanisms, do not call yourself. */ /** called by internal mechanisms, do not call yourself. */
@Generated(hash = 937984622) @Generated(hash = 937984622)
public void __setDaoSession(DaoSession daoSession) { public void __setDaoSession(DaoSession daoSession) {

View File

@ -0,0 +1,191 @@
package io.github.wulkanowy.data.db.dao.entities;
import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.ToMany;
import java.util.List;
@Entity(
nameInDb = "Symbols",
active = true
)
public class Symbol {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "user_id")
private Long userId;
@Property(nameInDb = "host")
private String host;
@Property(nameInDb = "school_id")
private String schoolId;
@Property(nameInDb = "symbol")
private String symbol;
@Property(nameInDb = "type")
private String type;
@ToMany(referencedJoinProperty = "symbolId")
private List<Student> studentList;
/**
* Used to resolve relations
*/
@Generated(hash = 2040040024)
private transient DaoSession daoSession;
/**
* Used for active entity operations.
*/
@Generated(hash = 684907977)
private transient SymbolDao myDao;
@Generated(hash = 242774339)
public Symbol(Long id, Long userId, String host, String schoolId, String symbol,
String type) {
this.id = id;
this.userId = userId;
this.host = host;
this.schoolId = schoolId;
this.symbol = symbol;
this.type = type;
}
@Generated(hash = 460475327)
public Symbol() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUserId() {
return this.userId;
}
public Symbol setUserId(Long userId) {
this.userId = userId;
return this;
}
public String getHost() {
return this.host;
}
public Symbol setHost(String host) {
this.host = host;
return this;
}
public String getSchoolId() {
return this.schoolId;
}
public Symbol setSchoolId(String schoolId) {
this.schoolId = schoolId;
return this;
}
public String getSymbol() {
return this.symbol;
}
public Symbol setSymbol(String symbol) {
this.symbol = symbol;
return this;
}
public String getType() {
return this.type;
}
public Symbol setType(String type) {
this.type = type;
return this;
}
/**
* To-many relationship, resolved on first access (and after reset).
* Changes to to-many relations are not persisted, make changes to the target entity.
*/
@Generated(hash = 604366458)
public List<Student> getStudentList() {
if (studentList == null) {
final DaoSession daoSession = this.daoSession;
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
StudentDao targetDao = daoSession.getStudentDao();
List<Student> studentListNew = targetDao._querySymbol_StudentList(id);
synchronized (this) {
if (studentList == null) {
studentList = studentListNew;
}
}
}
return studentList;
}
/**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1628625923)
public synchronized void resetStudentList() {
studentList = null;
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 128553479)
public void delete() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.delete(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 1942392019)
public void refresh() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.refresh(this);
}
/**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
* Entity must attached to an entity context.
*/
@Generated(hash = 713229351)
public void update() {
if (myDao == null) {
throw new DaoException("Entity is detached from DAO context");
}
myDao.update(this);
}
/** called by internal mechanisms, do not call yourself. */
@Generated(hash = 632145708)
public void __setDaoSession(DaoSession daoSession) {
this.daoSession = daoSession;
myDao = daoSession != null ? daoSession.getSymbolDao() : null;
}
}

View File

@ -1,5 +1,7 @@
package io.github.wulkanowy.data.db.dao.entities; package io.github.wulkanowy.data.db.dao.entities;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.greenrobot.greendao.DaoException; import org.greenrobot.greendao.DaoException;
import org.greenrobot.greendao.annotation.Entity; import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated; import org.greenrobot.greendao.annotation.Generated;
@ -12,62 +14,62 @@ import java.io.Serializable;
@Entity( @Entity(
nameInDb = "TimetableLessons", nameInDb = "TimetableLessons",
active = true, active = true,
indexes = {@Index(value = "dayId,date,startTime,endTime", unique = true)} indexes = {@Index(value = "dayId,date,number,startTime,endTime", unique = true)}
) )
public class TimetableLesson implements Serializable { public class TimetableLesson implements Serializable {
private static final long serialVersionUID = 42L;
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Property(nameInDb = "DAY_ID") @Property(nameInDb = "day_id")
private Long dayId; private Long dayId;
@Property(nameInDb = "NUMBER_OF_LESSON") @Property(nameInDb = "number")
private String number; private int number = 0;
@Property(nameInDb = "SUBJECT_NAME") @Property(nameInDb = "subject")
private String subject = ""; private String subject = "";
@Property(nameInDb = "TEACHER") @Property(nameInDb = "teacher")
private String teacher = ""; private String teacher = "";
@Property(nameInDb = "ROOM") @Property(nameInDb = "room")
private String room = ""; private String room = "";
@Property(nameInDb = "DESCRIPTION") @Property(nameInDb = "description")
private String description = ""; private String description = "";
@Property(nameInDb = "GROUP_NAME") @Property(nameInDb = "group")
private String groupName = ""; private String group = "";
@Property(nameInDb = "START_TIME") @Property(nameInDb = "start_time")
private String startTime = ""; private String startTime = "";
@Property(nameInDb = "END_TIME") @Property(nameInDb = "end_time")
private String endTime = ""; private String endTime = "";
@Property(nameInDb = "DATE") @Property(nameInDb = "date")
private String date = ""; private String date = "";
@Property(nameInDb = "IS_EMPTY") @Property(nameInDb = "empty")
private boolean isEmpty = false; private boolean empty = false;
@Property(nameInDb = "IS_DIVISION_INTO_GROUP") @Property(nameInDb = "division_into_groups")
private boolean isDivisionIntoGroups = false; private boolean divisionIntoGroups = false;
@Property(nameInDb = "IS_PLANNING") @Property(nameInDb = "planning")
private boolean isPlanning = false; private boolean planning = false;
@Property(nameInDb = "IS_REALIZED") @Property(nameInDb = "realized")
private boolean isRealized = false; private boolean realized = false;
@Property(nameInDb = "IS_MOVED_CANCELED") @Property(nameInDb = "moved_canceled")
private boolean isMovedOrCanceled = false; private boolean movedOrCanceled = false;
@Property(nameInDb = "IS_NEW_MOVED_IN_CANCELED") @Property(nameInDb = "new_moved_in_canceled")
private boolean isNewMovedInOrChanged = false; private boolean newMovedInOrChanged = false;
private static final long serialVersionUID = 42L;
/** /**
* Used to resolve relations * Used to resolve relations
@ -75,18 +77,15 @@ public class TimetableLesson implements Serializable {
@Generated(hash = 2040040024) @Generated(hash = 2040040024)
private transient DaoSession daoSession; private transient DaoSession daoSession;
/** /** Used for active entity operations. */
* Used for active entity operations.
*/
@Generated(hash = 1119360138) @Generated(hash = 1119360138)
private transient TimetableLessonDao myDao; private transient TimetableLessonDao myDao;
@Generated(hash = 627457324) @Generated(hash = 1665905034)
public TimetableLesson(Long id, Long dayId, String number, String subject, public TimetableLesson(Long id, Long dayId, int number, String subject, String teacher,
String teacher, String room, String description, String groupName, String room, String description, String group, String startTime, String endTime,
String startTime, String endTime, String date, boolean isEmpty, String date, boolean empty, boolean divisionIntoGroups, boolean planning,
boolean isDivisionIntoGroups, boolean isPlanning, boolean isRealized, boolean realized, boolean movedOrCanceled, boolean newMovedInOrChanged) {
boolean isMovedOrCanceled, boolean isNewMovedInOrChanged) {
this.id = id; this.id = id;
this.dayId = dayId; this.dayId = dayId;
this.number = number; this.number = number;
@ -94,22 +93,22 @@ public class TimetableLesson implements Serializable {
this.teacher = teacher; this.teacher = teacher;
this.room = room; this.room = room;
this.description = description; this.description = description;
this.groupName = groupName; this.group = group;
this.startTime = startTime; this.startTime = startTime;
this.endTime = endTime; this.endTime = endTime;
this.date = date; this.date = date;
this.isEmpty = isEmpty; this.empty = empty;
this.isDivisionIntoGroups = isDivisionIntoGroups; this.divisionIntoGroups = divisionIntoGroups;
this.isPlanning = isPlanning; this.planning = planning;
this.isRealized = isRealized; this.realized = realized;
this.isMovedOrCanceled = isMovedOrCanceled; this.movedOrCanceled = movedOrCanceled;
this.isNewMovedInOrChanged = isNewMovedInOrChanged; this.newMovedInOrChanged = newMovedInOrChanged;
} }
@Generated(hash = 1878030142) @Generated(hash = 1878030142)
public TimetableLesson() { public TimetableLesson() {
} }
public Long getId() { public Long getId() {
return this.id; return this.id;
} }
@ -122,15 +121,16 @@ public class TimetableLesson implements Serializable {
return this.dayId; return this.dayId;
} }
public void setDayId(Long dayId) { public TimetableLesson setDayId(Long dayId) {
this.dayId = dayId; this.dayId = dayId;
return this;
} }
public String getNumber() { public int getNumber() {
return this.number; return this.number;
} }
public TimetableLesson setNumber(String number) { public TimetableLesson setNumber(int number) {
this.number = number; this.number = number;
return this; return this;
} }
@ -171,12 +171,12 @@ public class TimetableLesson implements Serializable {
return this; return this;
} }
public String getGroupName() { public String getGroup() {
return this.groupName; return this.group;
} }
public TimetableLesson setGroupName(String groupName) { public TimetableLesson setGroup(String group) {
this.groupName = groupName; this.group = group;
return this; return this;
} }
@ -207,60 +207,86 @@ public class TimetableLesson implements Serializable {
return this; return this;
} }
public boolean getIsEmpty() { public boolean getEmpty() {
return this.isEmpty; return this.empty;
} }
public TimetableLesson setEmpty(boolean isEmpty) { public TimetableLesson setEmpty(boolean empty) {
this.isEmpty = isEmpty; this.empty = empty;
return this; return this;
} }
public boolean getIsDivisionIntoGroups() { public boolean getDivisionIntoGroups() {
return this.isDivisionIntoGroups; return this.divisionIntoGroups;
} }
public TimetableLesson setDivisionIntoGroups(boolean isDivisionIntoGroups) { public TimetableLesson setDivisionIntoGroups(boolean divisionIntoGroups) {
this.isDivisionIntoGroups = isDivisionIntoGroups; this.divisionIntoGroups = divisionIntoGroups;
return this; return this;
} }
public boolean getIsPlanning() { public boolean getPlanning() {
return this.isPlanning; return this.planning;
} }
public TimetableLesson setPlanning(boolean isPlanning) { public TimetableLesson setPlanning(boolean planning) {
this.isPlanning = isPlanning; this.planning = planning;
return this; return this;
} }
public boolean getIsRealized() { public boolean getRealized() {
return this.isRealized; return this.realized;
} }
public TimetableLesson setRealized(boolean isRealized) { public TimetableLesson setRealized(boolean realized) {
this.isRealized = isRealized; this.realized = realized;
return this; return this;
} }
public boolean getIsMovedOrCanceled() { public boolean getMovedOrCanceled() {
return this.isMovedOrCanceled; return this.movedOrCanceled;
} }
public TimetableLesson setMovedOrCanceled(boolean isMovedOrCanceled) { public TimetableLesson setMovedOrCanceled(boolean movedOrCanceled) {
this.isMovedOrCanceled = isMovedOrCanceled; this.movedOrCanceled = movedOrCanceled;
return this; return this;
} }
public boolean getIsNewMovedInOrChanged() { public boolean getNewMovedInOrChanged() {
return this.isNewMovedInOrChanged; return this.newMovedInOrChanged;
} }
public TimetableLesson setNewMovedInOrChanged(boolean isNewMovedInOrChanged) { public TimetableLesson setNewMovedInOrChanged(boolean newMovedInOrChanged) {
this.isNewMovedInOrChanged = isNewMovedInOrChanged; this.newMovedInOrChanged = newMovedInOrChanged;
return this; return this;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TimetableLesson lesson = (TimetableLesson) o;
return new EqualsBuilder()
.append(number, lesson.number)
.append(startTime, lesson.startTime)
.append(endTime, lesson.endTime)
.append(date, lesson.date)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(number)
.append(startTime)
.append(endTime)
.append(date)
.toHashCode();
}
/** /**
* Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}. * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
* Entity must attached to an entity context. * Entity must attached to an entity context.
@ -297,30 +323,6 @@ public class TimetableLesson implements Serializable {
myDao.update(this); myDao.update(this);
} }
public void setIsEmpty(boolean isEmpty) {
this.isEmpty = isEmpty;
}
public void setIsDivisionIntoGroups(boolean isDivisionIntoGroups) {
this.isDivisionIntoGroups = isDivisionIntoGroups;
}
public void setIsPlanning(boolean isPlanning) {
this.isPlanning = isPlanning;
}
public void setIsRealized(boolean isRealized) {
this.isRealized = isRealized;
}
public void setIsMovedOrCanceled(boolean isMovedOrCanceled) {
this.isMovedOrCanceled = isMovedOrCanceled;
}
public void setIsNewMovedInOrChanged(boolean isNewMovedInOrChanged) {
this.isNewMovedInOrChanged = isNewMovedInOrChanged;
}
/** called by internal mechanisms, do not call yourself. */ /** called by internal mechanisms, do not call yourself. */
@Generated(hash = 1885258429) @Generated(hash = 1885258429)
public void __setDaoSession(DaoSession daoSession) { public void __setDaoSession(DaoSession daoSession) {

View File

@ -13,44 +13,52 @@ import java.util.List;
@Entity( @Entity(
nameInDb = "Weeks", nameInDb = "Weeks",
active = true, active = true,
indexes ={@Index(value = "userId,startDayDate", unique = true)} indexes = {@Index(value = "diaryId,startDayDate", unique = true)}
) )
public class Week { public class Week {
@Id(autoincrement = true) @Id(autoincrement = true)
private Long id; private Long id;
@Property(nameInDb = "USER_ID") @Property(nameInDb = "diary_id")
private Long userId; private Long diaryId;
@Property(nameInDb = "START_DATE") @Property(nameInDb = "start_day_date")
private String startDayDate = ""; private String startDayDate = "";
@Property(nameInDb = "IS_ATTENDANCE_SYNCED") @Property(nameInDb = "attendance_synced")
private boolean isAttendanceSynced = false; private boolean attendanceSynced = false;
@Property(nameInDb = "IS_TIMETABLE_SYNCED") @Property(nameInDb = "timetable_synced")
private boolean isTimetableSynced = false; private boolean timetableSynced = false;
@Property(nameInDb = "exams_synced")
private boolean examsSynced = false;
@ToMany(referencedJoinProperty = "weekId") @ToMany(referencedJoinProperty = "weekId")
private List<Day> dayList; private List<Day> dayList;
/** Used to resolve relations */ /**
* Used to resolve relations
*/
@Generated(hash = 2040040024) @Generated(hash = 2040040024)
private transient DaoSession daoSession; private transient DaoSession daoSession;
/** Used for active entity operations. */ /**
* Used for active entity operations.
*/
@Generated(hash = 1019310398) @Generated(hash = 1019310398)
private transient WeekDao myDao; private transient WeekDao myDao;
@Generated(hash = 1745118398) @Generated(hash = 23357599)
public Week(Long id, Long userId, String startDayDate, boolean isAttendanceSynced, public Week(Long id, Long diaryId, String startDayDate, boolean attendanceSynced,
boolean isTimetableSynced) { boolean timetableSynced, boolean examsSynced) {
this.id = id; this.id = id;
this.userId = userId; this.diaryId = diaryId;
this.startDayDate = startDayDate; this.startDayDate = startDayDate;
this.isAttendanceSynced = isAttendanceSynced; this.attendanceSynced = attendanceSynced;
this.isTimetableSynced = isTimetableSynced; this.timetableSynced = timetableSynced;
this.examsSynced = examsSynced;
} }
@Generated(hash = 2135529658) @Generated(hash = 2135529658)
@ -66,12 +74,12 @@ public class Week {
return this; return this;
} }
public Long getUserId() { public Long getDiaryId() {
return userId; return diaryId;
} }
public Week setUserId(Long userId) { public Week setDiaryId(Long diaryId) {
this.userId = userId; this.diaryId = diaryId;
return this; return this;
} }
@ -84,20 +92,31 @@ public class Week {
return this; return this;
} }
public boolean getIsAttendanceSynced() { public boolean getAttendanceSynced() {
return this.isAttendanceSynced; return this.attendanceSynced;
} }
public void setIsAttendanceSynced(boolean isAttendanceSynced) { public Week setAttendanceSynced(boolean attendanceSynced) {
this.isAttendanceSynced = isAttendanceSynced; this.attendanceSynced = attendanceSynced;
return this;
} }
public boolean getIsTimetableSynced() { public boolean getTimetableSynced() {
return this.isTimetableSynced; return this.timetableSynced;
} }
public void setIsTimetableSynced(boolean isTimetableSynced) { public Week setTimetableSynced(boolean timetableSynced) {
this.isTimetableSynced = isTimetableSynced; this.timetableSynced = timetableSynced;
return this;
}
public Week setExamsSynced(boolean examsSynced) {
this.examsSynced = examsSynced;
return this;
}
public boolean getExamsSynced() {
return examsSynced;
} }
/** /**
@ -122,7 +141,9 @@ public class Week {
return dayList; return dayList;
} }
/** Resets a to-many relationship, making the next get call to query for a fresh result. */ /**
* Resets a to-many relationship, making the next get call to query for a fresh result.
*/
@Generated(hash = 1010399236) @Generated(hash = 1010399236)
public synchronized void resetDayList() { public synchronized void resetDayList() {
dayList = null; dayList = null;

View File

@ -9,8 +9,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import io.github.wulkanowy.api.Diary;
import io.github.wulkanowy.api.Vulcan; import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.generic.Diary;
import io.github.wulkanowy.data.db.dao.DbHelper; import io.github.wulkanowy.data.db.dao.DbHelper;
import io.github.wulkanowy.data.db.shared.SharedPrefContract; import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.utils.security.Scrambler; import io.github.wulkanowy.utils.security.Scrambler;
@ -100,7 +100,7 @@ public class Migration23 implements DbHelper.Migration {
private void insertDiaries(Database db, List<Diary> list) { private void insertDiaries(Database db, List<Diary> list) {
for (Diary diary : list) { for (Diary diary : list) {
db.execSQL("INSERT INTO Diaries(STUDENT_ID, NAME, VALUE, IS_CURRENT) VALUES(" + db.execSQL("INSERT INTO Diaries(STUDENT_ID, NAME, VALUE, IS_CURRENT) VALUES(" +
"\"" + diary.getStudentId() + "\"," + "\"" + diary.getId() + "\"," +
"\"" + diary.getName() + "\"," + "\"" + diary.getName() + "\"," +
"\"" + diary.getId() + "\"," + "\"" + diary.getId() + "\"," +
"\"" + (diary.isCurrent() ? "1" : "0") + "\"" + "\"" + (diary.isCurrent() ? "1" : "0") + "\"" +

View File

@ -0,0 +1,20 @@
package io.github.wulkanowy.data.db.dao.migrations;
import org.greenrobot.greendao.database.Database;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.DbHelper;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
public class Migration26 implements DbHelper.Migration {
@Override
public Integer getVersion() {
return 26;
}
@Override
public void runMigration(final Database db, final SharedPrefContract sharedPref, final Vulcan vulcan) throws Exception {
throw new Exception("No migrations");
}
}

View File

@ -0,0 +1,24 @@
package io.github.wulkanowy.data.db.dao.migrations;
import org.greenrobot.greendao.database.Database;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.DbHelper;
import io.github.wulkanowy.data.db.dao.entities.ExamDao;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
public class Migration27 implements DbHelper.Migration {
@Override
public Integer getVersion() {
return 27;
}
@Override
public void runMigration(Database db, SharedPrefContract sharedPref, Vulcan vulcan) throws Exception {
ExamDao.dropTable(db, true);
ExamDao.createTable(db, true);
db.execSQL("UPDATE Weeks SET exams_synced = 0");
}
}

View File

@ -0,0 +1,20 @@
package io.github.wulkanowy.data.db.dao.migrations;
import org.greenrobot.greendao.database.Database;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.data.db.dao.DbHelper;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
public class Migration28 implements DbHelper.Migration {
@Override
public Integer getVersion() {
return 28;
}
@Override
public void runMigration(final Database db, final SharedPrefContract sharedPref, final Vulcan vulcan) throws Exception {
throw new Exception("No migrations");
}
}

View File

@ -1,7 +1,10 @@
package io.github.wulkanowy.data.db.resources; package io.github.wulkanowy.data.db.resources;
import javax.inject.Singleton;
import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson; import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
@Singleton
public interface ResourcesContract { public interface ResourcesContract {
String[] getSymbolsKeysArray(); String[] getSymbolsKeysArray();

View File

@ -3,8 +3,6 @@ package io.github.wulkanowy.data.db.resources;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import com.crashlytics.android.Crashlytics;
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@ -15,18 +13,17 @@ import javax.inject.Singleton;
import io.github.wulkanowy.R; import io.github.wulkanowy.R;
import io.github.wulkanowy.api.NotLoggedInErrorException; import io.github.wulkanowy.api.NotLoggedInErrorException;
import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson; import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.utils.AppConstant; import io.github.wulkanowy.utils.AppConstant;
import io.github.wulkanowy.utils.LogUtils;
import io.github.wulkanowy.utils.security.CryptoException; import io.github.wulkanowy.utils.security.CryptoException;
import timber.log.Timber;
@Singleton @Singleton
public class AppResources implements ResourcesContract { public class ResourcesRepository implements ResourcesContract {
private Resources resources; private Resources resources;
@Inject @Inject
AppResources(@ApplicationContext Context context) { ResourcesRepository(Context context) {
resources = context.getResources(); resources = context.getResources();
} }
@ -42,8 +39,7 @@ public class AppResources implements ResourcesContract {
@Override @Override
public String getErrorLoginMessage(Exception exception) { public String getErrorLoginMessage(Exception exception) {
LogUtils.error(AppConstant.APP_NAME + " encountered a error", exception); Timber.e(exception,"%s encountered a error", AppConstant.APP_NAME);
Crashlytics.logException(exception);
if (exception instanceof CryptoException) { if (exception instanceof CryptoException) {
return resources.getString(R.string.encrypt_failed_text); return resources.getString(R.string.encrypt_failed_text);
@ -52,7 +48,7 @@ public class AppResources implements ResourcesContract {
} else if (exception instanceof SocketTimeoutException) { } else if (exception instanceof SocketTimeoutException) {
return resources.getString(R.string.generic_timeout_error); return resources.getString(R.string.generic_timeout_error);
} else if (exception instanceof NotLoggedInErrorException || exception instanceof IOException) { } else if (exception instanceof NotLoggedInErrorException || exception instanceof IOException) {
return resources.getString(R.string.login_denied_text); return resources.getString(R.string.login_failed_text);
} else { } else {
return exception.getMessage(); return exception.getMessage();
} }
@ -62,27 +58,27 @@ public class AppResources implements ResourcesContract {
public String getAttendanceLessonDescription(AttendanceLesson lesson) { public String getAttendanceLessonDescription(AttendanceLesson lesson) {
int id = R.string.attendance_present; int id = R.string.attendance_present;
if (lesson.getIsAbsenceForSchoolReasons()) { if (lesson.getAbsenceForSchoolReasons()) {
id = R.string.attendance_absence_for_school_reasons; id = R.string.attendance_absence_for_school_reasons;
} }
if (lesson.getIsAbsenceExcused()) { if (lesson.getAbsenceExcused()) {
id = R.string.attendance_absence_excused; id = R.string.attendance_absence_excused;
} }
if (lesson.getIsAbsenceUnexcused()) { if (lesson.getAbsenceUnexcused()) {
id = R.string.attendance_absence_unexcused; id = R.string.attendance_absence_unexcused;
} }
if (lesson.getIsExemption()) { if (lesson.getExemption()) {
id = R.string.attendance_exemption; id = R.string.attendance_exemption;
} }
if (lesson.getIsExcusedLateness()) { if (lesson.getExcusedLateness()) {
id = R.string.attendance_excused_lateness; id = R.string.attendance_excused_lateness;
} }
if (lesson.getIsUnexcusedLateness()) { if (lesson.getUnexcusedLateness()) {
id = R.string.attendance_unexcused_lateness; id = R.string.attendance_unexcused_lateness;
} }

View File

@ -1,13 +1,28 @@
package io.github.wulkanowy.data.db.shared; package io.github.wulkanowy.data.db.shared;
import javax.inject.Singleton;
@Singleton
public interface SharedPrefContract { public interface SharedPrefContract {
long getCurrentUserId(); long getCurrentUserId();
boolean isUserLoggedIn();
void setCurrentUserId(long userId); void setCurrentUserId(long userId);
void setTimetableWidgetState(boolean nextDay);
boolean getTimetableWidgetState();
int getStartupTab(); int getStartupTab();
boolean isShowGradesSummary();
boolean isShowAttendancePresent();
int getCurrentTheme();
int getServicesInterval(); int getServicesInterval();
boolean isMobileDisable(); boolean isMobileDisable();
@ -15,4 +30,6 @@ public interface SharedPrefContract {
boolean isServicesEnable(); boolean isServicesEnable();
boolean isNotifyEnable(); boolean isNotifyEnable();
void cleanSharedPref();
} }

View File

@ -1,27 +1,29 @@
package io.github.wulkanowy.data.db.shared; package io.github.wulkanowy.data.db.shared;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.di.annotations.SharedPreferencesInfo;
import io.github.wulkanowy.ui.main.settings.SettingsFragment; import io.github.wulkanowy.ui.main.settings.SettingsFragment;
@Singleton @Singleton
public class SharedPref implements SharedPrefContract { public class SharedPrefRepository implements SharedPrefContract {
private static final String SHARED_KEY_USER_ID = "USER_ID"; private static final String SHARED_KEY_USER_ID = "USER_ID";
private static final String SHARED_KEY_TIMETABLE_WIDGET_STATE = "TIMETABLE_WIDGET_STATE";
private final SharedPreferences appSharedPref; private final SharedPreferences appSharedPref;
private final SharedPreferences settingsSharedPref; private final SharedPreferences settingsSharedPref;
@Inject @Inject
SharedPref(@ApplicationContext Context context, @SharedPreferencesInfo String sharedName) { SharedPrefRepository(Context context, @Named("sharedPrefName") String sharedName) {
appSharedPref = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE); appSharedPref = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE);
settingsSharedPref = PreferenceManager.getDefaultSharedPreferences(context); settingsSharedPref = PreferenceManager.getDefaultSharedPreferences(context);
} }
@ -31,14 +33,45 @@ public class SharedPref implements SharedPrefContract {
return appSharedPref.getLong(SHARED_KEY_USER_ID, 0); return appSharedPref.getLong(SHARED_KEY_USER_ID, 0);
} }
@Override
public boolean isUserLoggedIn() {
return getCurrentUserId() != 0;
}
@Override @Override
public void setCurrentUserId(long userId) { public void setCurrentUserId(long userId) {
appSharedPref.edit().putLong(SHARED_KEY_USER_ID, userId).apply(); appSharedPref.edit().putLong(SHARED_KEY_USER_ID, userId).apply();
} }
@SuppressLint("ApplySharedPref")
@Override
public void setTimetableWidgetState(boolean nextDay) {
appSharedPref.edit().putBoolean(SHARED_KEY_TIMETABLE_WIDGET_STATE, nextDay).commit();
}
@Override
public boolean getTimetableWidgetState() {
return appSharedPref.getBoolean(SHARED_KEY_TIMETABLE_WIDGET_STATE, false);
}
@Override @Override
public int getStartupTab() { public int getStartupTab() {
return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_START_TAB, "2")); return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_START_TAB, "0"));
}
@Override
public boolean isShowGradesSummary() {
return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_GRADES_SUMMARY, false);
}
@Override
public boolean isShowAttendancePresent() {
return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_ATTENDANCE_PRESENT, false);
}
@Override
public int getCurrentTheme() {
return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_THEME, "1"));
} }
@Override @Override
@ -60,4 +93,10 @@ public class SharedPref implements SharedPrefContract {
public boolean isMobileDisable() { public boolean isMobileDisable() {
return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_SERVICES_MOBILE_DISABLED, false); return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_SERVICES_MOBILE_DISABLED, false);
} }
@Override
public void cleanSharedPref() {
appSharedPref.edit().clear().apply();
settingsSharedPref.edit().clear().apply();
}
} }

View File

@ -0,0 +1,167 @@
package io.github.wulkanowy.data.sync;
import android.content.Context;
import org.greenrobot.greendao.database.Database;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
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;
import io.github.wulkanowy.data.db.dao.entities.Semester;
import io.github.wulkanowy.data.db.dao.entities.Student;
import io.github.wulkanowy.data.db.dao.entities.StudentDao;
import io.github.wulkanowy.data.db.dao.entities.Symbol;
import io.github.wulkanowy.data.db.dao.entities.SymbolDao;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.utils.DataObjectConverter;
import io.github.wulkanowy.utils.security.CryptoException;
import io.github.wulkanowy.utils.security.Scrambler;
import timber.log.Timber;
@Singleton
public class AccountSync {
private final DaoSession daoSession;
private final SharedPrefContract sharedPref;
private final Vulcan vulcan;
private final Context context;
@Inject
AccountSync(DaoSession daoSession, SharedPrefContract sharedPref,
Vulcan vulcan, Context context) {
this.daoSession = daoSession;
this.sharedPref = sharedPref;
this.vulcan = vulcan;
this.context = context;
}
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();
try {
Account account = insertAccount(email, password);
Symbol symbolEntity = insertSymbol(account);
insertStudents(symbolEntity);
insertDiaries(symbolEntity);
insertSemesters();
sharedPref.setCurrentUserId(account.getId());
daoSession.getDatabase().setTransactionSuccessful();
} finally {
daoSession.getDatabase().endTransaction();
}
}
private Account insertAccount(String email, String password) throws CryptoException {
Timber.d("Register account");
Account account = new Account()
.setEmail(email)
.setPassword(Scrambler.encrypt(email, password, context));
daoSession.getAccountDao().insert(account);
return account;
}
private Symbol insertSymbol(Account account) throws VulcanException, IOException {
String schoolId = vulcan.getStudentAndParent().getSchoolID();
Timber.d("Register symbol %s", vulcan.getSymbol());
Symbol symbol = new Symbol()
.setUserId(account.getId())
.setSchoolId(schoolId)
.setSymbol(vulcan.getSymbol());
daoSession.getSymbolDao().insert(symbol);
return symbol;
}
private void insertStudents(Symbol symbol) throws VulcanException, IOException {
List<Student> studentList = DataObjectConverter.studentsToStudentEntities(
vulcan.getStudentAndParent().getStudents(),
symbol.getId()
);
Timber.d("Register students %s", studentList.size());
daoSession.getStudentDao().insertInTx(studentList);
}
private void insertDiaries(Symbol symbolEntity) throws VulcanException, IOException {
List<Diary> diaryList = DataObjectConverter.diariesToDiaryEntities(
vulcan.getStudentAndParent().getDiaries(),
daoSession.getStudentDao().queryBuilder().where(
StudentDao.Properties.SymbolId.eq(symbolEntity.getId()),
StudentDao.Properties.Current.eq(true)
).unique().getId());
Timber.d("Register diaries %s", diaryList.size());
daoSession.getDiaryDao().insertInTx(diaryList);
}
private void insertSemesters() throws VulcanException, IOException {
List<Semester> semesterList = DataObjectConverter.semestersToSemesterEntities(
vulcan.getStudentAndParent().getSemesters(),
daoSession.getDiaryDao().queryBuilder().where(
DiaryDao.Properties.Current.eq(true)
).unique().getId());
Timber.d("Register semesters %s", semesterList.size());
daoSession.getSemesterDao().insertInTx(semesterList);
}
public void initLastUser() throws CryptoException {
long userId = sharedPref.getCurrentUserId();
if (userId == 0) {
throw new NotRegisteredUserException("Can't find user id in SharedPreferences");
}
Timber.d("Init current user (%s)", userId);
Account account = daoSession.getAccountDao().load(userId);
Symbol symbol = daoSession.getSymbolDao().queryBuilder().where(
SymbolDao.Properties.UserId.eq(account.getId())).unique();
Student student = daoSession.getStudentDao().queryBuilder().where(
StudentDao.Properties.SymbolId.eq(symbol.getId()),
StudentDao.Properties.Current.eq(true)
).unique();
Diary diary = daoSession.getDiaryDao().queryBuilder().where(
DiaryDao.Properties.StudentId.eq(student.getId()),
DiaryDao.Properties.Current.eq(true)
).unique();
vulcan.setCredentials(
account.getEmail(),
Scrambler.decrypt(account.getEmail(), account.getPassword()),
symbol.getSymbol(),
symbol.getSchoolId(),
student.getRealId(),
diary.getValue()
);
}
private void clearUserData() {
Database database = daoSession.getDatabase();
DaoMaster.dropAllTables(database, true);
DaoMaster.createAllTables(database, true);
sharedPref.setCurrentUserId(0);
}
}

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.data.sync.attendance; package io.github.wulkanowy.data.sync;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -18,39 +17,28 @@ import io.github.wulkanowy.data.db.dao.entities.Day;
import io.github.wulkanowy.data.db.dao.entities.DayDao; import io.github.wulkanowy.data.db.dao.entities.DayDao;
import io.github.wulkanowy.data.db.dao.entities.Week; import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.data.db.dao.entities.WeekDao; import io.github.wulkanowy.data.db.dao.entities.WeekDao;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.utils.DataObjectConverter; import io.github.wulkanowy.utils.DataObjectConverter;
import io.github.wulkanowy.utils.LogUtils; import timber.log.Timber;
import io.github.wulkanowy.utils.TimeUtils;
@Singleton @Singleton
public class AttendanceSync implements AttendanceSyncContract { public class AttendanceSync {
private final DaoSession daoSession; private final DaoSession daoSession;
private final SharedPrefContract sharedPref;
private final Vulcan vulcan; private final Vulcan vulcan;
private long userId; private long diaryId;
@Inject @Inject
AttendanceSync(DaoSession daoSession, SharedPrefContract sharedPref, Vulcan vulcan) { AttendanceSync(DaoSession daoSession, Vulcan vulcan) {
this.daoSession = daoSession; this.daoSession = daoSession;
this.sharedPref = sharedPref;
this.vulcan = vulcan; this.vulcan = vulcan;
} }
@Override public void syncAttendance(long diaryId, String date) throws IOException, VulcanException {
public void syncAttendance() throws IOException, ParseException, VulcanException { this.diaryId = diaryId;
syncAttendance(null);
}
@Override io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.generic.Day> weekApi = getWeekFromApi(date);
public void syncAttendance(String date) throws IOException, ParseException, VulcanException {
this.userId = sharedPref.getCurrentUserId();
io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.generic.Day> weekApi = getWeekFromApi(getNormalizedDate(date));
Week weekDb = getWeekFromDb(weekApi.getStartDayDate()); Week weekDb = getWeekFromDb(weekApi.getStartDayDate());
long weekId = updateWeekInDb(weekDb, weekApi); long weekId = updateWeekInDb(weekDb, weekApi);
@ -59,35 +47,31 @@ public class AttendanceSync implements AttendanceSyncContract {
daoSession.getAttendanceLessonDao().saveInTx(lessonList); daoSession.getAttendanceLessonDao().saveInTx(lessonList);
LogUtils.debug("Synchronization attendance lessons (amount = " + lessonList.size() + ")"); Timber.d("Attendance synchronization complete (%s)", lessonList.size());
}
private String getNormalizedDate(String date) throws ParseException {
return null != date ? String.valueOf(TimeUtils.getNetTicks(date)) : "";
} }
private io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.generic.Day> getWeekFromApi(String date) private io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.generic.Day> getWeekFromApi(String date)
throws IOException, ParseException, VulcanException { throws IOException, VulcanException {
return vulcan.getAttendanceTable().getWeekTable(date); return vulcan.getAttendanceTable().getWeekTable(date);
} }
private Week getWeekFromDb(String date) { private Week getWeekFromDb(String date) {
return daoSession.getWeekDao() return daoSession.getWeekDao().queryBuilder().where(
.queryBuilder() WeekDao.Properties.DiaryId.eq(diaryId),
.where(WeekDao.Properties.UserId.eq(userId), WeekDao.Properties.StartDayDate.eq(date)) WeekDao.Properties.StartDayDate.eq(date)
.unique(); ).unique();
} }
private Long updateWeekInDb(Week dbWeekEntity, io.github.wulkanowy.api.generic.Week fromApi) { private Long updateWeekInDb(Week dbWeekEntity, io.github.wulkanowy.api.generic.Week fromApi) {
if (dbWeekEntity != null) { if (dbWeekEntity != null) {
dbWeekEntity.setIsAttendanceSynced(true); dbWeekEntity.setAttendanceSynced(true);
dbWeekEntity.update(); dbWeekEntity.update();
return dbWeekEntity.getId(); return dbWeekEntity.getId();
} }
Week apiWeekEntity = DataObjectConverter.weekToWeekEntity(fromApi).setUserId(userId); Week apiWeekEntity = DataObjectConverter.weekToWeekEntity(fromApi).setDiaryId(diaryId);
apiWeekEntity.setIsAttendanceSynced(true); apiWeekEntity.setAttendanceSynced(true);
return daoSession.getWeekDao().insert(apiWeekEntity); return daoSession.getWeekDao().insert(apiWeekEntity);
} }
@ -97,7 +81,7 @@ public class AttendanceSync implements AttendanceSyncContract {
for (io.github.wulkanowy.api.generic.Day dayFromApi : dayListFromApi) { for (io.github.wulkanowy.api.generic.Day dayFromApi : dayListFromApi) {
Day dbDayEntity = getDayFromDb(dayFromApi.getDate()); Day dbDayEntity = getDayFromDb(dayFromApi.getDate(), weekId);
Day apiDayEntity = DataObjectConverter.dayToDayEntity(dayFromApi); Day apiDayEntity = DataObjectConverter.dayToDayEntity(dayFromApi);
@ -109,11 +93,12 @@ public class AttendanceSync implements AttendanceSyncContract {
return updatedLessonList; return updatedLessonList;
} }
private Day getDayFromDb(String date) { private Day getDayFromDb(String date, long weekId) {
return daoSession.getDayDao() return daoSession.getDayDao().queryBuilder()
.queryBuilder() .where(
.where(DayDao.Properties.UserId.eq(userId), DayDao.Properties.Date.eq(date)) DayDao.Properties.WeekId.eq(weekId),
.unique(); DayDao.Properties.Date.eq(date)
).unique();
} }
private long updateDay(Day dbDayEntity, Day apiDayEntity, long weekId) { private long updateDay(Day dbDayEntity, Day apiDayEntity, long weekId) {
@ -121,7 +106,6 @@ public class AttendanceSync implements AttendanceSyncContract {
return dbDayEntity.getId(); return dbDayEntity.getId();
} }
apiDayEntity.setUserId(userId);
apiDayEntity.setWeekId(weekId); apiDayEntity.setWeekId(weekId);
return daoSession.getDayDao().insert(apiDayEntity); return daoSession.getDayDao().insert(apiDayEntity);

View File

@ -0,0 +1,135 @@
package io.github.wulkanowy.data.sync;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.api.exams.ExamDay;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Day;
import io.github.wulkanowy.data.db.dao.entities.DayDao;
import io.github.wulkanowy.data.db.dao.entities.Exam;
import io.github.wulkanowy.data.db.dao.entities.ExamDao;
import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.data.db.dao.entities.WeekDao;
import io.github.wulkanowy.utils.DataObjectConverter;
import timber.log.Timber;
public class ExamsSync {
private final DaoSession daoSession;
private final Vulcan vulcan;
private long diaryId;
@Inject
ExamsSync(DaoSession daoSession, Vulcan vulcan) {
this.daoSession = daoSession;
this.vulcan = vulcan;
}
public void syncExams(long diaryId, String date) throws IOException, VulcanException {
this.diaryId = diaryId;
io.github.wulkanowy.api.generic.Week<ExamDay> weekApi = getWeekFromApi(date);
Week weekDb = getWeekFromDb(weekApi.getStartDayDate());
long weekId = updateWeekInDb(weekDb, weekApi);
List<Exam> examList = getPreparedExams(weekApi.getDays(), weekId);
daoSession.getExamDao().saveInTx(examList);
Timber.d("Exams synchronization complete (%s)", examList.size());
}
private Week getWeekFromDb(String date) {
return daoSession.getWeekDao().queryBuilder().where(
WeekDao.Properties.DiaryId.eq(diaryId),
WeekDao.Properties.StartDayDate.eq(date)
).unique();
}
private io.github.wulkanowy.api.generic.Week<ExamDay> getWeekFromApi(String date)
throws VulcanException, IOException {
return vulcan.getExamsList().getWeek(date, true);
}
private Long updateWeekInDb(Week weekDb, io.github.wulkanowy.api.generic.Week weekApi) {
if (weekDb != null) {
weekDb.setExamsSynced(true);
weekDb.update();
return weekDb.getId();
}
Week weekApiEntity = DataObjectConverter.weekToWeekEntity(weekApi).setDiaryId(diaryId);
weekApiEntity.setExamsSynced(true);
return daoSession.getWeekDao().insert(weekApiEntity);
}
private Day getDayFromDb(String date, long weekId) {
return daoSession.getDayDao().queryBuilder().where(
DayDao.Properties.WeekId.eq(weekId),
DayDao.Properties.Date.eq(date)
).unique();
}
private List<Exam> getPreparedExams(List<ExamDay> dayListFromApi,
long weekId) {
List<Exam> preparedExamList = new ArrayList<>();
for (ExamDay dayFromApi : dayListFromApi) {
Day dayDb = getDayFromDb(dayFromApi.getDate(), weekId);
Day dayApiEntity = DataObjectConverter.dayToDayEntity(dayFromApi);
long dayId = updateDayInDb(dayDb, dayApiEntity, weekId);
prepareExam(dayFromApi.getExamList(), preparedExamList, dayId);
}
return preparedExamList;
}
private long updateDayInDb(Day dayDb, Day dayApi, long weekId) {
dayApi.setWeekId(weekId);
if (null != dayDb) {
return dayDb.getId();
}
return daoSession.getDayDao().insert(dayApi);
}
private void prepareExam(List<io.github.wulkanowy.api.exams.Exam> examList,
List<Exam> preparedExams, long dayId) {
List<Exam> examsApiEntity = DataObjectConverter.examsToExamsEntity(examList);
for (Exam examApi : examsApiEntity) {
Exam examDb = getExamFromDb(examApi, dayId);
examApi.setDayId(dayId);
if (examDb != null) {
examApi.setId(examDb.getId());
}
preparedExams.add(examApi);
}
}
private Exam getExamFromDb(Exam examApi, long dayId) {
return daoSession.getExamDao().queryBuilder()
.where(ExamDao.Properties.DayId.eq(dayId),
ExamDao.Properties.EntryDate.eq(examApi.getEntryDate()),
ExamDao.Properties.SubjectAndGroup.eq(examApi.getSubjectAndGroup()),
ExamDao.Properties.Type.eq(examApi.getType()),
ExamDao.Properties.Teacher.eq(examApi.getTeacher()))
.unique();
}
}

View File

@ -0,0 +1,81 @@
package io.github.wulkanowy.data.sync;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Grade;
import io.github.wulkanowy.data.db.dao.entities.Semester;
import io.github.wulkanowy.data.db.dao.entities.SubjectDao;
import io.github.wulkanowy.utils.DataObjectConverter;
import io.github.wulkanowy.utils.EntitiesCompare;
import timber.log.Timber;
@Singleton
public class GradeSync {
private final DaoSession daoSession;
private final Vulcan vulcan;
private long semesterId;
@Inject
GradeSync(DaoSession daoSession, Vulcan vulcan) {
this.daoSession = daoSession;
this.vulcan = vulcan;
}
public void sync(long semesterId) throws IOException, VulcanException {
this.semesterId = semesterId;
Semester semester = daoSession.getSemesterDao().load(semesterId);
resetSemesterRelations(semester);
List<Grade> lastList = getUpdatedList(getComparedList(semester));
daoSession.getGradeDao().deleteInTx(semester.getGradeList());
daoSession.getGradeDao().insertInTx(lastList);
Timber.d("Grades synchronization complete (%s)", lastList.size());
}
private void resetSemesterRelations(Semester semester) {
semester.resetSubjectList();
semester.resetGradeList();
}
private List<Grade> getUpdatedList(List<Grade> comparedList) {
List<Grade> updatedList = new ArrayList<>();
for (Grade grade : comparedList) {
grade.setSemesterId(semesterId);
grade.setSubjectId(getSubjectId(grade.getSubject()));
updatedList.add(grade);
}
return updatedList;
}
private List<Grade> getComparedList(Semester semester) throws IOException, VulcanException {
List<Grade> gradesFromNet = DataObjectConverter.gradesToGradeEntities(
vulcan.getGradesList().getAll(semester.getValue()), semesterId);
List<Grade> gradesFromDb = semester.getGradeList();
return EntitiesCompare.compareGradeList(gradesFromNet, gradesFromDb);
}
private Long getSubjectId(String subjectName) {
return daoSession.getSubjectDao().queryBuilder().where(
SubjectDao.Properties.Name.eq(subjectName),
SubjectDao.Properties.SemesterId.eq(semesterId)
).build().uniqueOrThrow().getId();
}
}

View File

@ -0,0 +1,8 @@
package io.github.wulkanowy.data.sync;
public class NotRegisteredUserException extends RuntimeException {
public NotRegisteredUserException(String message) {
super(message);
}
}

View File

@ -0,0 +1,66 @@
package io.github.wulkanowy.data.sync;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.data.db.dao.entities.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Semester;
import io.github.wulkanowy.data.db.dao.entities.Subject;
import io.github.wulkanowy.utils.DataObjectConverter;
import timber.log.Timber;
@Singleton
public class SubjectSync {
private final DaoSession daoSession;
private final Vulcan vulcan;
private long semesterId;
@Inject
SubjectSync(DaoSession daoSession, Vulcan vulcan) {
this.daoSession = daoSession;
this.vulcan = vulcan;
}
public void sync(long semesterId) throws VulcanException, IOException {
this.semesterId = semesterId;
Semester semester = daoSession.getSemesterDao().load(semesterId);
List<Subject> lastList = getUpdatedList(getSubjectsFromNet(semester));
daoSession.getSubjectDao().deleteInTx(getSubjectsFromDb());
daoSession.getSubjectDao().insertInTx(lastList);
Timber.d("Subjects synchronization complete (%s)", lastList.size());
}
private List<Subject> getSubjectsFromNet(Semester semester) throws VulcanException, IOException {
return DataObjectConverter.subjectsToSubjectEntities(
vulcan.getSubjectsList().getAll(semester.getValue()), semesterId);
}
private List<Subject> getSubjectsFromDb() {
Semester semester = daoSession.getSemesterDao().load(semesterId);
semester.resetSubjectList();
return semester.getSubjectList();
}
private List<Subject> getUpdatedList(List<Subject> subjectsFromNet) {
List<Subject> updatedList = new ArrayList<>();
for (Subject subject : subjectsFromNet) {
subject.setSemesterId(semesterId);
updatedList.add(subject);
}
return updatedList;
}
}

View File

@ -3,9 +3,38 @@ package io.github.wulkanowy.data.sync;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import io.github.wulkanowy.api.VulcanException; import javax.inject.Singleton;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.utils.security.CryptoException;
@Singleton
public interface SyncContract { public interface SyncContract {
void sync() throws VulcanException, IOException, ParseException; void registerUser(String email, String password, String symbol) throws VulcanException,
IOException, CryptoException;
void initLastUser() throws IOException, CryptoException;
void syncGrades(int semesterName) throws VulcanException, IOException, ParseException;
void syncGrades() throws VulcanException, IOException, ParseException;
void syncSubjects(int semesterName) throws VulcanException, IOException;
void syncSubjects() throws VulcanException, IOException;
void syncAttendance() throws ParseException, IOException, VulcanException;
void syncAttendance(long diaryId, String date) throws ParseException, IOException, VulcanException;
void syncTimetable() throws VulcanException, IOException, ParseException;
void syncTimetable(long diaryId, String date) throws VulcanException, IOException, ParseException;
void syncExams() throws VulcanException, IOException, ParseException;
void syncExams(long diaryId, String date) throws VulcanException, IOException, ParseException;
void syncAll() throws VulcanException, IOException, ParseException;
} }

View File

@ -0,0 +1,123 @@
package io.github.wulkanowy.data.sync;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.data.db.dao.DbContract;
import io.github.wulkanowy.utils.security.CryptoException;
@Singleton
public class SyncRepository implements SyncContract {
private final GradeSync gradeSync;
private final SubjectSync subjectSync;
private final AttendanceSync attendanceSync;
private final TimetableSync timetableSync;
private final AccountSync accountSync;
private final ExamsSync examsSync;
private final DbContract database;
@Inject
SyncRepository(GradeSync gradeSync, SubjectSync subjectSync, AttendanceSync attendanceSync,
TimetableSync timetableSync, AccountSync accountSync, ExamsSync examsSync,
DbContract database) {
this.gradeSync = gradeSync;
this.subjectSync = subjectSync;
this.attendanceSync = attendanceSync;
this.timetableSync = timetableSync;
this.accountSync = accountSync;
this.examsSync = examsSync;
this.database = database;
}
@Override
public void registerUser(String email, String password, String symbol) throws VulcanException,
IOException, CryptoException {
accountSync.registerUser(email, password, symbol);
}
@Override
public void initLastUser() throws CryptoException {
accountSync.initLastUser();
}
@Override
public void syncGrades(int semesterName) throws VulcanException, IOException {
gradeSync.sync(semesterName);
}
@Override
public void syncGrades() throws VulcanException, IOException {
gradeSync.sync(database.getCurrentSemesterId());
}
@Override
public void syncSubjects(int semesterName) throws VulcanException, IOException {
subjectSync.sync(semesterName);
}
@Override
public void syncSubjects() throws VulcanException, IOException {
subjectSync.sync(database.getCurrentSemesterId());
}
@Override
public void syncAttendance() throws IOException, VulcanException {
attendanceSync.syncAttendance(database.getCurrentDiaryId(), null);
}
@Override
public void syncAttendance(long diaryId, String date) throws IOException, VulcanException {
if (diaryId != 0) {
attendanceSync.syncAttendance(diaryId, date);
} else {
attendanceSync.syncAttendance(database.getCurrentDiaryId(), date);
}
}
@Override
public void syncTimetable() throws VulcanException, IOException {
timetableSync.syncTimetable(database.getCurrentDiaryId(), null);
}
@Override
public void syncTimetable(long diaryId, String date) throws VulcanException, IOException {
if (diaryId != 0) {
timetableSync.syncTimetable(diaryId, date);
} else {
timetableSync.syncTimetable(database.getCurrentDiaryId(), date);
}
}
@Override
public void syncExams() throws VulcanException, IOException {
examsSync.syncExams(database.getCurrentDiaryId(), null);
}
@Override
public void syncExams(long diaryId, String date) throws VulcanException, IOException {
if (diaryId != 0) {
examsSync.syncExams(diaryId, date);
} else {
examsSync.syncExams(database.getCurrentDiaryId(), date);
}
}
@Override
public void syncAll() throws VulcanException, IOException {
syncSubjects();
syncGrades();
syncAttendance();
syncTimetable();
syncExams();
}
}

View File

@ -1,7 +1,8 @@
package io.github.wulkanowy.data.sync.timetable; package io.github.wulkanowy.data.sync;
import org.apache.commons.collections4.CollectionUtils;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -18,39 +19,28 @@ import io.github.wulkanowy.data.db.dao.entities.TimetableLesson;
import io.github.wulkanowy.data.db.dao.entities.TimetableLessonDao; import io.github.wulkanowy.data.db.dao.entities.TimetableLessonDao;
import io.github.wulkanowy.data.db.dao.entities.Week; import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.data.db.dao.entities.WeekDao; import io.github.wulkanowy.data.db.dao.entities.WeekDao;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.utils.DataObjectConverter; import io.github.wulkanowy.utils.DataObjectConverter;
import io.github.wulkanowy.utils.LogUtils; import timber.log.Timber;
import io.github.wulkanowy.utils.TimeUtils;
@Singleton @Singleton
public class TimetableSync implements TimetableSyncContract { public class TimetableSync {
private final DaoSession daoSession; private final DaoSession daoSession;
private final SharedPrefContract sharedPref;
private final Vulcan vulcan; private final Vulcan vulcan;
private long userId; private long diaryId;
@Inject @Inject
TimetableSync(DaoSession daoSession, SharedPrefContract sharedPref, Vulcan vulcan) { TimetableSync(DaoSession daoSession, Vulcan vulcan) {
this.daoSession = daoSession; this.daoSession = daoSession;
this.sharedPref = sharedPref;
this.vulcan = vulcan; this.vulcan = vulcan;
} }
@Override public void syncTimetable(long diaryId, String date) throws IOException, VulcanException {
public void syncTimetable() throws IOException, ParseException, VulcanException { this.diaryId = diaryId;
syncTimetable(null);
}
@Override io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.timetable.TimetableDay> weekApi = getWeekFromApi(date);
public void syncTimetable(String date) throws IOException, ParseException, VulcanException {
this.userId = sharedPref.getCurrentUserId();
io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.generic.Day> weekApi = getWeekFromApi(getNormalizedDate(date));
Week weekDb = getWeekFromDb(weekApi.getStartDayDate()); Week weekDb = getWeekFromDb(weekApi.getStartDayDate());
long weekId = updateWeekInDb(weekDb, weekApi); long weekId = updateWeekInDb(weekDb, weekApi);
@ -59,47 +49,43 @@ public class TimetableSync implements TimetableSyncContract {
daoSession.getTimetableLessonDao().saveInTx(lessonList); daoSession.getTimetableLessonDao().saveInTx(lessonList);
LogUtils.debug("Synchronization timetable lessons (amount = " + lessonList.size() + ")"); Timber.d("Timetable synchronization complete (%s)", lessonList.size());
} }
private String getNormalizedDate(String date) throws ParseException { private io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.timetable.TimetableDay> getWeekFromApi(String date)
return null != date ? String.valueOf(TimeUtils.getNetTicks(date)) : ""; throws IOException, VulcanException {
}
private io.github.wulkanowy.api.generic.Week<io.github.wulkanowy.api.generic.Day> getWeekFromApi(String date)
throws IOException, VulcanException, ParseException {
return vulcan.getTimetable().getWeekTable(date); return vulcan.getTimetable().getWeekTable(date);
} }
private Week getWeekFromDb(String date) { private Week getWeekFromDb(String date) {
return daoSession.getWeekDao() return daoSession.getWeekDao().queryBuilder().where(
.queryBuilder() WeekDao.Properties.DiaryId.eq(diaryId),
.where(WeekDao.Properties.UserId.eq(userId), WeekDao.Properties.StartDayDate.eq(date)) WeekDao.Properties.StartDayDate.eq(date)
.unique(); ).unique();
} }
private Long updateWeekInDb(Week dbEntity, io.github.wulkanowy.api.generic.Week fromApi) { private Long updateWeekInDb(Week dbEntity, io.github.wulkanowy.api.generic.Week fromApi) {
if (dbEntity != null) { if (dbEntity != null) {
dbEntity.setIsTimetableSynced(true); dbEntity.setTimetableSynced(true);
dbEntity.update(); dbEntity.update();
return dbEntity.getId(); return dbEntity.getId();
} }
Week apiEntity = DataObjectConverter.weekToWeekEntity(fromApi).setUserId(userId); Week apiEntity = DataObjectConverter.weekToWeekEntity(fromApi).setDiaryId(diaryId);
apiEntity.setIsTimetableSynced(true); apiEntity.setTimetableSynced(true);
return daoSession.getWeekDao().insert(apiEntity); return daoSession.getWeekDao().insert(apiEntity);
} }
private List<TimetableLesson> updateDays(List<io.github.wulkanowy.api.generic.Day> dayListFromApi, long weekId) { private List<TimetableLesson> updateDays(List<io.github.wulkanowy.api.timetable.TimetableDay> dayListFromApi, long weekId) {
List<TimetableLesson> updatedLessonList = new ArrayList<>(); List<TimetableLesson> updatedLessonList = new ArrayList<>();
for (io.github.wulkanowy.api.generic.Day dayFromApi : dayListFromApi) { for (io.github.wulkanowy.api.timetable.TimetableDay dayFromApi : dayListFromApi) {
Day dbDayEntity = getDayFromDb(dayFromApi.getDate()); Day dbDayEntity = getDayFromDb(dayFromApi.getDate(), weekId);
Day apiDayEntity = DataObjectConverter.dayToDayEntity(dayFromApi); Day apiDayEntity = DataObjectConverter.timetableDayToDayEntity(dayFromApi);
long dayId = updateDay(dbDayEntity, apiDayEntity, weekId); long dayId = updateDay(dbDayEntity, apiDayEntity, weekId);
@ -109,15 +95,14 @@ public class TimetableSync implements TimetableSyncContract {
return updatedLessonList; return updatedLessonList;
} }
private Day getDayFromDb(String date) { private Day getDayFromDb(String date, long weekId) {
return daoSession.getDayDao() return daoSession.getDayDao().queryBuilder().where(
.queryBuilder() DayDao.Properties.WeekId.eq(weekId),
.where(DayDao.Properties.UserId.eq(userId), DayDao.Properties.Date.eq(date)) DayDao.Properties.Date.eq(date)
.unique(); ).unique();
} }
private long updateDay(Day dayFromDb, Day apiDayEntity, long weekId) { private long updateDay(Day dayFromDb, Day apiDayEntity, long weekId) {
apiDayEntity.setUserId(userId);
apiDayEntity.setWeekId(weekId); apiDayEntity.setWeekId(weekId);
if (null != dayFromDb) { if (null != dayFromDb) {
@ -136,6 +121,16 @@ public class TimetableSync implements TimetableSyncContract {
List<TimetableLesson> lessonsFromApiEntities = DataObjectConverter List<TimetableLesson> lessonsFromApiEntities = DataObjectConverter
.lessonsToTimetableLessonsEntities(lessons); .lessonsToTimetableLessonsEntities(lessons);
List<TimetableLesson> lessonsFromDbEntities = getLessonsFromDb(dayId);
if (!lessonsFromDbEntities.isEmpty()) {
List<TimetableLesson> lessonToRemove = new ArrayList<>(CollectionUtils.removeAll(lessonsFromDbEntities, lessonsFromApiEntities));
for (TimetableLesson timetableLesson : lessonToRemove) {
daoSession.getTimetableLessonDao().delete(timetableLesson);
}
}
for (TimetableLesson apiLessonEntity : lessonsFromApiEntities) { for (TimetableLesson apiLessonEntity : lessonsFromApiEntities) {
TimetableLesson lessonFromDb = getLessonFromDb(apiLessonEntity, dayId); TimetableLesson lessonFromDb = getLessonFromDb(apiLessonEntity, dayId);
@ -159,4 +154,8 @@ public class TimetableSync implements TimetableSyncContract {
TimetableLessonDao.Properties.EndTime.eq(apiEntity.getEndTime())) TimetableLessonDao.Properties.EndTime.eq(apiEntity.getEndTime()))
.unique(); .unique();
} }
private List<TimetableLesson> getLessonsFromDb(long dayId) {
return daoSession.getDayDao().load(dayId).getTimetableLessons();
}
} }

View File

@ -1,91 +0,0 @@
package io.github.wulkanowy.data.sync.account;
import android.content.Context;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
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.DaoSession;
import io.github.wulkanowy.data.db.dao.entities.Diary;
import io.github.wulkanowy.data.db.dao.entities.DiaryDao;
import io.github.wulkanowy.data.db.shared.SharedPrefContract;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.utils.DataObjectConverter;
import io.github.wulkanowy.utils.LogUtils;
import io.github.wulkanowy.utils.security.CryptoException;
import io.github.wulkanowy.utils.security.Scrambler;
@Singleton
public class AccountSync implements AccountSyncContract {
private final DaoSession daoSession;
private final SharedPrefContract sharedPref;
private final Vulcan vulcan;
private final Context context;
@Inject
AccountSync(DaoSession daoSession, SharedPrefContract sharedPref,
Vulcan vulcan, @ApplicationContext Context context) {
this.daoSession = daoSession;
this.sharedPref = sharedPref;
this.vulcan = vulcan;
this.context = context;
}
@Override
public void registerUser(String email, String password, String symbol)
throws VulcanException, IOException, CryptoException {
LogUtils.debug("Register new user email=" + email);
vulcan.setCredentials(email, password, symbol, null, null, null);
Account account = new Account()
.setName(vulcan.getBasicInformation().getPersonalData().getFirstAndLastName())
.setEmail(email)
.setPassword(Scrambler.encrypt(email, password, context))
.setSymbol(vulcan.getSymbol())
.setSchoolId(vulcan.getStudentAndParent().getSchoolID())
.setRealId(vulcan.getStudentAndParent().getStudentID());
List<Diary> diaryList = DataObjectConverter.diariesToDiaryEntities(
vulcan.getStudentAndParent().getDiaries());
daoSession.getAccountDao().insert(account);
daoSession.getDiaryDao().insertInTx(diaryList);
sharedPref.setCurrentUserId(account.getId());
}
@Override
public void initLastUser() throws IOException, CryptoException {
long userId = sharedPref.getCurrentUserId();
if (userId == 0) {
throw new IOException("Can't find saved user");
}
LogUtils.debug("Initialization current user id=" + userId);
Account account = daoSession.getAccountDao().load(userId);
vulcan.setCredentials(account.getEmail(),
Scrambler.decrypt(account.getEmail(), account.getPassword()),
account.getSymbol(),
account.getSchoolId(),
account.getRealId(),
daoSession.getDiaryDao().queryBuilder()
.where(DiaryDao.Properties.IsCurrent.eq(true)).unique().getValue()
);
}
}

View File

@ -1,16 +0,0 @@
package io.github.wulkanowy.data.sync.account;
import java.io.IOException;
import io.github.wulkanowy.api.VulcanException;
import io.github.wulkanowy.utils.security.CryptoException;
public interface AccountSyncContract {
void registerUser(String email, String password, String symbol)
throws VulcanException, IOException,
CryptoException;
void initLastUser() throws VulcanException, IOException,
CryptoException;
}

View File

@ -1,13 +0,0 @@
package io.github.wulkanowy.data.sync.attendance;
import java.io.IOException;
import java.text.ParseException;
import io.github.wulkanowy.api.VulcanException;
public interface AttendanceSyncContract {
void syncAttendance(String date) throws IOException, ParseException, VulcanException;
void syncAttendance() throws IOException, ParseException, VulcanException;
}

Some files were not shown because too many files have changed in this diff Show More